lock.h revision 1.10
11.10Sad/*	$NetBSD: lock.h,v 1.10 2007/02/09 21:55:06 ad 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.10Sad#ifndef _KERNEL
501.3Sgmcgarry
511.8Sperrystatic __inline int
521.3Sgmcgarry__cpu_simple_lock_try(__cpu_simple_lock_t *lp)
531.3Sgmcgarry{
541.3Sgmcgarry	unsigned long t0, v0;
551.3Sgmcgarry
561.7Sperry	__asm volatile(
571.3Sgmcgarry		"# -- BEGIN __cpu_simple_lock_try\n"
581.3Sgmcgarry		"	.set push		\n"
591.3Sgmcgarry		"	.set mips2		\n"
601.3Sgmcgarry		"1:	ll	%0, %4		\n"
611.3Sgmcgarry		"	bnez	%0, 2f		\n"
621.3Sgmcgarry		"	nop	       # BDslot	\n"
631.3Sgmcgarry		"	li	%0, %3		\n"
641.3Sgmcgarry		"	sc	%0, %2		\n"
651.3Sgmcgarry		"	beqz	%0, 2f		\n"
661.3Sgmcgarry		"	nop	       # BDslot	\n"
671.3Sgmcgarry		"	li	%1, 1		\n"
681.3Sgmcgarry		"	sync			\n"
691.3Sgmcgarry		"	j	3f		\n"
701.3Sgmcgarry		"	nop			\n"
711.3Sgmcgarry		"	nop			\n"
721.3Sgmcgarry		"2:	li	%1, 0		\n"
731.3Sgmcgarry		"3:				\n"
741.3Sgmcgarry		"	.set pop		\n"
751.3Sgmcgarry		"# -- END __cpu_simple_lock_try	\n"
761.3Sgmcgarry		: "=r" (t0), "=r" (v0), "+m" (*lp)
771.9Ssimonb		: "i" (__SIMPLELOCK_LOCKED), "m" (*lp));
781.3Sgmcgarry
791.3Sgmcgarry	return (v0 != 0);
801.3Sgmcgarry}
811.3Sgmcgarry
821.10Sad#ifdef MIPS1
831.10Sadstatic __inline void
841.10Sadmb_read(void)
851.10Sad{
861.10Sad	__insn_barrier();
871.10Sad}
881.10Sad
891.10Sadstatic __inline void
901.10Sadmb_write(void)
911.10Sad{
921.10Sad	__insn_barrier();
931.10Sad}
941.10Sad
951.10Sadstatic __inline void
961.10Sadmb_memory(void)
971.10Sad{
981.10Sad	__insn_barrier();
991.10Sad}
1001.10Sad#else	/* MIPS1*/
1011.10Sadstatic __inline void
1021.10Sadmb_read(void)
1031.10Sad{
1041.10Sad	___asm volatile("sync" ::: "memory");
1051.10Sad}
1061.10Sad
1071.10Sadstatic __inline void
1081.10Sadmb_write(void)
1091.10Sad{
1101.10Sad	___asm volatile("sync" ::: "memory");
1111.10Sad}
1121.10Sad
1131.10Sadstatic __inline void
1141.10Sadmb_memory(void)
1151.10Sad{
1161.10Sad	___asm volatile("sync" ::: "memory");
1171.10Sad}
1181.10Sad#endif	/* MIPS1 */
1191.10Sad
1201.10Sad#else	/* !_KERNEL */
1211.10Sad
1221.10Sadint	_lock_cas4(volatile uint32_t *, uint32_t, uint32_t);
1231.10Sadvoid	mb_read(void);
1241.10Sadvoid	mb_write(void);
1251.10Sadvoid	mb_memory(void);
1261.10Sad
1271.10Sadstatic __inline int
1281.10Sad__cpu_simple_lock_try(__cpu_simple_lock_t *lp)
1291.10Sad{
1301.10Sad
1311.10Sad	return _lock_cas4((volatile uint32_t *)lp,
1321.10Sad	    __SIMPLELOCK_UNLOCKED, __SIMPLELOCK_LOCKED);
1331.10Sad}
1341.10Sad
1351.10Sad#endif	/* _KERNEL */
1361.10Sad
1371.10Sadstatic __inline void
1381.10Sad__cpu_simple_lock_init(__cpu_simple_lock_t *lp)
1391.10Sad{
1401.10Sad
1411.10Sad	*lp = __SIMPLELOCK_UNLOCKED;
1421.10Sad	mb_memory();
1431.10Sad}
1441.10Sad
1451.10Sadstatic __inline void
1461.10Sad__cpu_simple_lock(__cpu_simple_lock_t *lp)
1471.10Sad{
1481.10Sad
1491.10Sad	while (!__cpu_simple_lock_try(lp))
1501.10Sad		while (*lp == __SIMPLELOCK_LOCKED)
1511.10Sad			/* spin */;
1521.10Sad}
1531.10Sad
1541.8Sperrystatic __inline void
1551.3Sgmcgarry__cpu_simple_unlock(__cpu_simple_lock_t *lp)
1561.3Sgmcgarry{
1571.3Sgmcgarry
1581.10Sad	mb_memory();
1591.10Sad	*lp = __SIMPLELOCK_UNLOCKED;
1601.3Sgmcgarry}
1611.10Sad
1621.1Sthorpej#endif /* _MIPS_LOCK_H_ */
163