lock.h revision 1.13
11.13Sskrll/*	$NetBSD: lock.h,v 1.13 2007/09/10 11:34:09 skrll Exp $	*/
21.1Sthorpej
31.1Sthorpej/*-
41.10Sad * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
51.1Sthorpej * All rights reserved.
61.1Sthorpej *
71.1Sthorpej * This code is derived from software contributed to The NetBSD Foundation
81.10Sad * by Wayne Knowles and Andrew Doran.
91.1Sthorpej *
101.1Sthorpej * Redistribution and use in source and binary forms, with or without
111.1Sthorpej * modification, are permitted provided that the following conditions
121.1Sthorpej * are met:
131.1Sthorpej * 1. Redistributions of source code must retain the above copyright
141.1Sthorpej *    notice, this list of conditions and the following disclaimer.
151.1Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
161.1Sthorpej *    notice, this list of conditions and the following disclaimer in the
171.1Sthorpej *    documentation and/or other materials provided with the distribution.
181.1Sthorpej * 3. All advertising materials mentioning features or use of this software
191.1Sthorpej *    must display the following acknowledgement:
201.1Sthorpej *	This product includes software developed by the NetBSD
211.1Sthorpej *	Foundation, Inc. and its contributors.
221.1Sthorpej * 4. Neither the name of The NetBSD Foundation nor the names of its
231.1Sthorpej *    contributors may be used to endorse or promote products derived
241.1Sthorpej *    from this software without specific prior written permission.
251.1Sthorpej *
261.1Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
271.1Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
281.1Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
291.1Sthorpej * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
301.1Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
311.1Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
321.1Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
331.1Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
341.1Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
351.1Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
361.1Sthorpej * POSSIBILITY OF SUCH DAMAGE.
371.1Sthorpej */
381.1Sthorpej
391.1Sthorpej/*
401.10Sad * Machine-dependent spin lock operations for MIPS processors.
411.3Sgmcgarry *
421.10Sad * Note: R2000/R3000 doesn't have any atomic update instructions; this
431.10Sad * will cause problems for user applications using this header.
441.1Sthorpej */
451.1Sthorpej
461.1Sthorpej#ifndef _MIPS_LOCK_H_
471.1Sthorpej#define	_MIPS_LOCK_H_
481.3Sgmcgarry
491.13Sskrllstatic __inline int
501.13Sskrll__SIMPLELOCK_LOCKED_P(__cpu_simple_lock_t *__ptr)
511.13Sskrll{
521.13Sskrll	return *__ptr == __SIMPLELOCK_LOCKED;
531.13Sskrll}
541.13Sskrll
551.13Sskrllstatic __inline int
561.13Sskrll__SIMPLELOCK_UNLOCKED_P(__cpu_simple_lock_t *__ptr)
571.13Sskrll{
581.13Sskrll	return *__ptr == __SIMPLELOCK_UNLOCKED;
591.13Sskrll}
601.13Sskrll
611.13Sskrllstatic __inline void
621.13Sskrll__cpu_simple_lock_clear(__cpu_simple_lock_t *__ptr)
631.13Sskrll{
641.13Sskrll	*__ptr = __SIMPLELOCK_UNLOCKED;
651.13Sskrll}
661.13Sskrll
671.13Sskrllstatic __inline void
681.13Sskrll__cpu_simple_lock_set(__cpu_simple_lock_t *__ptr)
691.13Sskrll{
701.13Sskrll	*__ptr = __SIMPLELOCK_LOCKED;
711.13Sskrll}
721.13Sskrll
731.10Sad#ifndef _KERNEL
741.3Sgmcgarry
751.8Sperrystatic __inline int
761.3Sgmcgarry__cpu_simple_lock_try(__cpu_simple_lock_t *lp)
771.3Sgmcgarry{
781.3Sgmcgarry	unsigned long t0, v0;
791.3Sgmcgarry
801.7Sperry	__asm volatile(
811.3Sgmcgarry		"# -- BEGIN __cpu_simple_lock_try\n"
821.3Sgmcgarry		"	.set push		\n"
831.3Sgmcgarry		"	.set mips2		\n"
841.3Sgmcgarry		"1:	ll	%0, %4		\n"
851.3Sgmcgarry		"	bnez	%0, 2f		\n"
861.3Sgmcgarry		"	nop	       # BDslot	\n"
871.3Sgmcgarry		"	li	%0, %3		\n"
881.3Sgmcgarry		"	sc	%0, %2		\n"
891.3Sgmcgarry		"	beqz	%0, 2f		\n"
901.3Sgmcgarry		"	nop	       # BDslot	\n"
911.3Sgmcgarry		"	li	%1, 1		\n"
921.3Sgmcgarry		"	sync			\n"
931.3Sgmcgarry		"	j	3f		\n"
941.3Sgmcgarry		"	nop			\n"
951.3Sgmcgarry		"	nop			\n"
961.3Sgmcgarry		"2:	li	%1, 0		\n"
971.3Sgmcgarry		"3:				\n"
981.3Sgmcgarry		"	.set pop		\n"
991.3Sgmcgarry		"# -- END __cpu_simple_lock_try	\n"
1001.3Sgmcgarry		: "=r" (t0), "=r" (v0), "+m" (*lp)
1011.9Ssimonb		: "i" (__SIMPLELOCK_LOCKED), "m" (*lp));
1021.3Sgmcgarry
1031.3Sgmcgarry	return (v0 != 0);
1041.3Sgmcgarry}
1051.3Sgmcgarry
1061.10Sad#ifdef MIPS1
1071.10Sadstatic __inline void
1081.10Sadmb_read(void)
1091.10Sad{
1101.10Sad	__insn_barrier();
1111.10Sad}
1121.10Sad
1131.10Sadstatic __inline void
1141.10Sadmb_write(void)
1151.10Sad{
1161.10Sad	__insn_barrier();
1171.10Sad}
1181.10Sad
1191.10Sadstatic __inline void
1201.10Sadmb_memory(void)
1211.10Sad{
1221.10Sad	__insn_barrier();
1231.10Sad}
1241.10Sad#else	/* MIPS1*/
1251.10Sadstatic __inline void
1261.10Sadmb_read(void)
1271.10Sad{
1281.12Sad	__asm volatile(
1291.12Sad	    "	.set push\n"
1301.12Sad	    "	.set mips2\n"
1311.12Sad	    "	sync\n"
1321.12Sad	    "	.set pop"
1331.12Sad	    ::: "memory"
1341.12Sad	);
1351.10Sad}
1361.10Sad
1371.10Sadstatic __inline void
1381.10Sadmb_write(void)
1391.10Sad{
1401.12Sad	mb_read();
1411.10Sad}
1421.10Sad
1431.10Sadstatic __inline void
1441.10Sadmb_memory(void)
1451.10Sad{
1461.12Sad	mb_read();
1471.10Sad}
1481.10Sad#endif	/* MIPS1 */
1491.10Sad
1501.10Sad#else	/* !_KERNEL */
1511.10Sad
1521.10Sadint	_lock_cas4(volatile uint32_t *, uint32_t, uint32_t);
1531.10Sadvoid	mb_read(void);
1541.10Sadvoid	mb_write(void);
1551.10Sadvoid	mb_memory(void);
1561.10Sad
1571.10Sadstatic __inline int
1581.10Sad__cpu_simple_lock_try(__cpu_simple_lock_t *lp)
1591.10Sad{
1601.10Sad
1611.10Sad	return _lock_cas4((volatile uint32_t *)lp,
1621.10Sad	    __SIMPLELOCK_UNLOCKED, __SIMPLELOCK_LOCKED);
1631.10Sad}
1641.10Sad
1651.10Sad#endif	/* _KERNEL */
1661.10Sad
1671.10Sadstatic __inline void
1681.10Sad__cpu_simple_lock_init(__cpu_simple_lock_t *lp)
1691.10Sad{
1701.10Sad
1711.10Sad	*lp = __SIMPLELOCK_UNLOCKED;
1721.10Sad	mb_memory();
1731.10Sad}
1741.10Sad
1751.10Sadstatic __inline void
1761.10Sad__cpu_simple_lock(__cpu_simple_lock_t *lp)
1771.10Sad{
1781.10Sad
1791.10Sad	while (!__cpu_simple_lock_try(lp))
1801.10Sad		while (*lp == __SIMPLELOCK_LOCKED)
1811.10Sad			/* spin */;
1821.10Sad}
1831.10Sad
1841.8Sperrystatic __inline void
1851.3Sgmcgarry__cpu_simple_unlock(__cpu_simple_lock_t *lp)
1861.3Sgmcgarry{
1871.3Sgmcgarry
1881.10Sad	mb_memory();
1891.10Sad	*lp = __SIMPLELOCK_UNLOCKED;
1901.3Sgmcgarry}
1911.10Sad
1921.1Sthorpej#endif /* _MIPS_LOCK_H_ */
193