1/* $NetBSD: lock_stubs.S,v 1.7 2011/01/17 08:23:56 matt Exp $ */ 2 3/*- 4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "opt_multiprocessor.h" 33#include "opt_lockdebug.h" 34 35#include <machine/asm.h> 36 37#include "assym.h" 38 39#if defined(MULTIPROCESSOR) 40#define ISYNC isync 41#define SYNC sync 42#else 43#define ISYNC /* nothing */ 44#define SYNC /* nothing */ 45#endif 46 47 .text 48 49#if __HAVE_MUTEX_STUBS 50/* 51 * int _lock_cas(uintptr_t *ptr, uintptr_t old, uintptr_t new); 52 */ 53ENTRY(_lock_cas) 541: 55 lptrarx %r10,0,%r3 56 cmpw %r10,%r4 57 bne- 2f 58 stptrcx. %r5,0,%r3 59 bne- 1b 60 SYNC 61 li %r3,1 62 blr 632: 64 li %r3,0 65 blr 66 67#if !defined(LOCKDEBUG) 68/* 69 * void mutex_enter(kmutex_t *); 70 */ 71ENTRY(mutex_enter) 72 GET_CPUINFO(%r8) 73 ldptr %r9,CI_CURLWP(%r8) 741: 75 lptrarx %r10,0,%r3 76 cmpwi %r10,0 77 bne- 2f 78 stptrcx. %r9,0,%r3 79 bne- 1b 80 ISYNC 81 blr 822: 83 b _C_LABEL(mutex_vector_enter) 84 85/* 86 * void mutex_exit(kmutex_t *); 87 */ 88ENTRY(mutex_exit) 89 GET_CPUINFO(%r8) 90 ldptr %r9,CI_CURLWP(%r8) 91 SYNC 92 li %r7,0 931: 94 lptrarx %r10,0,%r3 95 cmpw %r10,%r9 96 bne- 2f 97 stptrcx. %r7,0,%r3 98 bne- 1b 99 blr 1002: 101 b _C_LABEL(mutex_vector_exit) 102 103#endif /* __HAVE_MUTEX_STUBS */ 104 105/* 106 * void rw_enter(krwlock_t *krw, krw_t op); 107 */ 108#if RW_READ_INCR != 16 109#error RW_READ_INCR != 16, clrrXi need fixing 110#endif 111#if RW_OWNER != 0 112#error RW_OWNER != 0, ldptr should be ldptru 113#endif 114 115#if __HAVE_RW_STUBS 116 117ENTRY(rw_enter) 118 cmpwi %r3,RW_READER 119 bne- 1f 120 121 ldptr %r9,RW_OWNER(%r3) 122 clrrptri %r9,%r9,4 /* clear low 4 bits */ 123 addi %r7,%r9,RW_READ_INCR 124 b 2f 1251: 126 li %r9,0 127 GET_CPUINFO(%r8) 128 ldptr %r7,CI_CURLWP(%r8) 129 ori %r7,%r7,RW_WRITE_LOCKED 130 1312: lptrarx %r10,0,%r3 132 cmpw %r10,%r9 133 bne- 3f 134 stptrcx. %r7,0,%r3 135 bne- 2b 136 ISYNC 137 blr 138 1393: b _C_LABEL(rw_vector_enter) 140 141/* 142 * bool rw_tryenter(krwlock_t *krw, krw_t op); 143 */ 144ENTRY(rw_tryenter) 145 cmpwi %r3,RW_READER 146 bne- 1f 147 148 ldptr %r9,RW_OWNER(%r3) 149 clrrptri %r9,%r9,4 /* clear low 4 bits */ 150 addi %r7,%r9,RW_READ_INCR 151 b 2f 152 1531: li %r9,0 154 GET_CPUINFO(%r8) 155 ldptr %r7,CI_CURLWP(%r8) 156 ori %r7,%r7,RW_WRITE_LOCKED 157 1582: lptrarx %r10,0,%r3 159 cmpw %r10,%r9 160 bne- 3f 161 stptrcx. %r7,0,%r3 162 bne- 2b 163 164 ISYNC 165 li %r3,1 166 blr 167 1683: li %r3,0 169 blr 170 171/* 172 * void rw_exit(krwlock_t *krw, krw_t op); 173 */ 174ENTRY(rw_exit) 175 ldptr %r9,RW_OWNER(%r3) 176 SYNC 177 andi. %r0,%r9,RW_WRITE_LOCKED 178 bne- 1f 179 180 clrrptri. %r9,%r9,4 /* clear low 4 bits */ 181 beq- 3f /* if 0, no reader, go slow */ 182 183 addi %r7,%r9,-RW_READ_INCR 184 b 2f 1851: 186 li %r7,0 187 GET_CPUINFO(%r8) 188 ldptr %r9,CI_CURLWP(%r8) 189 ori %r9,%r9,RW_WRITE_LOCKED 190 1912: lptrarx %r10,0,%r3 192 cmpw %r10,%r9 193 bne- 3f 194 stptrcx. %r7,0,%r3 195 bne- 2b 196 197 blr 198 1993: b _C_LABEL(rw_vector_exit) 200 201#endif /* __HAVE_RW_STUBS */ 202 203#endif /* !LOCKDEBUG */ 204