lock.h revision 1.3
11.3Sgmcgarry/*	$NetBSD: lock.h,v 1.3 2002/09/16 07:00:43 gmcgarry Exp $	*/
21.1Sthorpej
31.1Sthorpej/*-
41.3Sgmcgarry * Copyright (c) 2001 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.3Sgmcgarry * by Wayne Knowles.
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.3Sgmcgarry * Machine-dependent spin lock operations for MIPS R4000 Processors.
411.3Sgmcgarry *
421.3Sgmcgarry * Note:  R3000 doesn't have any atomic update instructions
431.1Sthorpej */
441.1Sthorpej
451.1Sthorpej#ifndef _MIPS_LOCK_H_
461.1Sthorpej#define	_MIPS_LOCK_H_
471.2Sthorpej
481.2Sthorpejtypedef	__volatile int		__cpu_simple_lock_t;
491.1Sthorpej
501.1Sthorpej#define	__SIMPLELOCK_LOCKED	1
511.1Sthorpej#define	__SIMPLELOCK_UNLOCKED	0
521.3Sgmcgarry
531.3Sgmcgarry#ifndef _KERNEL
541.3Sgmcgarry
551.3Sgmcgarrystatic __inline void
561.3Sgmcgarry__cpu_simple_lock_init(__cpu_simple_lock_t *lp)
571.3Sgmcgarry{
581.3Sgmcgarry
591.3Sgmcgarry	__asm __volatile(
601.3Sgmcgarry		"# -- BEGIN __cpu_simple_lock_init\n"
611.3Sgmcgarry		"	.set push		\n"
621.3Sgmcgarry		"	.set mips2		\n"
631.3Sgmcgarry		"	sw	$0, %0		\n"
641.3Sgmcgarry		"	sync			\n"
651.3Sgmcgarry		"	.set pop		\n"
661.3Sgmcgarry		"# -- END __cpu_simple_lock_init\n"
671.3Sgmcgarry		: "=m" (*lp));
681.3Sgmcgarry}
691.3Sgmcgarry
701.3Sgmcgarrystatic __inline void
711.3Sgmcgarry__cpu_simple_lock(__cpu_simple_lock_t *lp)
721.3Sgmcgarry{
731.3Sgmcgarry	unsigned long t0;
741.3Sgmcgarry
751.3Sgmcgarry	/*
761.3Sgmcgarry	 * Note, if we detect that the lock is held when
771.3Sgmcgarry	 * we do the initial load-locked, we spin using
781.3Sgmcgarry	 * a non-locked load to save the coherency logic
791.3Sgmcgarry	 * some work.
801.3Sgmcgarry	 */
811.3Sgmcgarry
821.3Sgmcgarry	__asm __volatile(
831.3Sgmcgarry		"# -- BEGIN __cpu_simple_lock	\n"
841.3Sgmcgarry		"	.set push		\n"
851.3Sgmcgarry		"	.set mips2		\n"
861.3Sgmcgarry		"1:	ll	%0, %3		\n"
871.3Sgmcgarry		"	bnez	%0, 2f		\n"
881.3Sgmcgarry		"	nop	       # BDslot	\n"
891.3Sgmcgarry		"	li	%0, %2		\n"
901.3Sgmcgarry		"	sc	%0, %1		\n"
911.3Sgmcgarry		"	beqz	%0, 1b		\n"
921.3Sgmcgarry		"	nop	       # BDslot	\n"
931.3Sgmcgarry		"	nop			\n"
941.3Sgmcgarry		"	sync			\n"
951.3Sgmcgarry		"	j	3f		\n"
961.3Sgmcgarry		"	nop			\n"
971.3Sgmcgarry		"	nop			\n"
981.3Sgmcgarry		"2:	lw	%0, %3		\n"
991.3Sgmcgarry		"	bnez	%0, 2b		\n"
1001.3Sgmcgarry		"	nop	       # BDslot	\n"
1011.3Sgmcgarry		"	j	1b		\n"
1021.3Sgmcgarry		"	nop			\n"
1031.3Sgmcgarry		"3:				\n"
1041.3Sgmcgarry		"	.set pop		\n"
1051.3Sgmcgarry		"# -- END __cpu_simple_lock	\n"
1061.3Sgmcgarry		: "=r" (t0), "+m" (*lp)
1071.3Sgmcgarry		: "i" (__SIMPLELOCK_LOCKED), "1" (*lp));
1081.3Sgmcgarry}
1091.3Sgmcgarry
1101.3Sgmcgarrystatic __inline int
1111.3Sgmcgarry__cpu_simple_lock_try(__cpu_simple_lock_t *lp)
1121.3Sgmcgarry{
1131.3Sgmcgarry	unsigned long t0, v0;
1141.3Sgmcgarry
1151.3Sgmcgarry	__asm __volatile(
1161.3Sgmcgarry		"# -- BEGIN __cpu_simple_lock_try\n"
1171.3Sgmcgarry		"	.set push		\n"
1181.3Sgmcgarry		"	.set mips2		\n"
1191.3Sgmcgarry		"1:	ll	%0, %4		\n"
1201.3Sgmcgarry		"	bnez	%0, 2f		\n"
1211.3Sgmcgarry		"	nop	       # BDslot	\n"
1221.3Sgmcgarry		"	li	%0, %3		\n"
1231.3Sgmcgarry		"	sc	%0, %2		\n"
1241.3Sgmcgarry		"	beqz	%0, 2f		\n"
1251.3Sgmcgarry		"	nop	       # BDslot	\n"
1261.3Sgmcgarry		"	li	%1, 1		\n"
1271.3Sgmcgarry		"	sync			\n"
1281.3Sgmcgarry		"	j	3f		\n"
1291.3Sgmcgarry		"	nop			\n"
1301.3Sgmcgarry		"	nop			\n"
1311.3Sgmcgarry		"2:	li	%1, 0		\n"
1321.3Sgmcgarry		"3:				\n"
1331.3Sgmcgarry		"	.set pop		\n"
1341.3Sgmcgarry		"# -- END __cpu_simple_lock_try	\n"
1351.3Sgmcgarry		: "=r" (t0), "=r" (v0), "+m" (*lp)
1361.3Sgmcgarry		: "i" (__SIMPLELOCK_LOCKED), "2" (*lp));
1371.3Sgmcgarry
1381.3Sgmcgarry	return (v0 != 0);
1391.3Sgmcgarry}
1401.3Sgmcgarry
1411.3Sgmcgarrystatic __inline void
1421.3Sgmcgarry__cpu_simple_unlock(__cpu_simple_lock_t *lp)
1431.3Sgmcgarry{
1441.3Sgmcgarry
1451.3Sgmcgarry	__asm __volatile(
1461.3Sgmcgarry		"# -- BEGIN __cpu_simple_unlock \n"
1471.3Sgmcgarry		"	.set push		\n"
1481.3Sgmcgarry		"	.set mips2		\n"
1491.3Sgmcgarry		"	sync			\n"
1501.3Sgmcgarry		"	sw	$0, %0		\n"
1511.3Sgmcgarry		"	.set pop		\n"
1521.3Sgmcgarry		"# -- END __cpu_simple_unlock	\n"
1531.3Sgmcgarry		: "=m" (*lp));
1541.3Sgmcgarry}
1551.3Sgmcgarry
1561.3Sgmcgarry#endif
1571.1Sthorpej
1581.1Sthorpej#endif /* _MIPS_LOCK_H_ */
159