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