1 /* $NetBSD: lock_stubs.S,v 1.15 2026/01/09 22:54:34 jmcneill 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 <machine/asm.h> 33 34 #include "assym.h" 35 36 #ifdef _KERNEL_OPT 37 #include "opt_multiprocessor.h" 38 #include "opt_lockdebug.h" 39 #endif 40 41 #if defined(MULTIPROCESSOR) 42 #define ISYNC isync 43 #define SYNC sync 44 #else 45 #define ISYNC /* nothing */ 46 #define SYNC /* nothing */ 47 #endif 48 49 .text 50 51 #if __HAVE_MUTEX_STUBS 52 /* 53 * int _lock_cas(uintptr_t *ptr, uintptr_t old, uintptr_t new); 54 */ 55 ENTRY(_lock_cas) 56 1: 57 lptrarx %r10,0,%r3 58 cmpptr %r10,%r4 59 bne- 2f 60 POWERPC_STWCX_PRE(0,%r3) 61 stptrcx. %r5,0,%r3 62 bne- 1b 63 SYNC 64 li %r3,1 65 blr 66 2: 67 li %r3,0 68 blr 69 70 #if !defined(LOCKDEBUG) 71 /* 72 * void mutex_enter(kmutex_t *); 73 */ 74 ENTRY(mutex_enter) 75 1: 76 lptrarx %r10,0,%r3 77 cmpptri %r10,0 78 bne- 2f 79 POWERPC_STWCX_PRE(0,%r3) 80 stptrcx. %r13,0,%r3 81 bne- 1b 82 ISYNC 83 blr 84 2: 85 b _C_LABEL(mutex_vector_enter) 86 87 /* 88 * void mutex_exit(kmutex_t *); 89 */ 90 ENTRY(mutex_exit) 91 SYNC 92 li %r7,0 93 1: 94 lptrarx %r10,0,%r3 95 cmpptr %r10,%r13 96 bne- 2f 97 POWERPC_STWCX_PRE(0,%r3) 98 stptrcx. %r7,0,%r3 99 bne- 1b 100 blr 101 2: 102 b _C_LABEL(mutex_vector_exit) 103 104 #endif /* !LOCKDEBUG */ 105 106 /* 107 * void rw_enter(krwlock_t *krw, krw_t op); 108 */ 109 #if RW_READ_INCR != 32 110 #error RW_READ_INCR != 32, clrrXi need fixing 111 #endif 112 #if RW_OWNER != 0 113 #error RW_OWNER != 0, ldptr should be ldptru 114 #endif 115 116 #if __HAVE_RW_STUBS 117 118 ENTRY(rw_enter) 119 cmpwi %r3,RW_READER 120 bne- 1f 121 122 ldptr %r9,RW_OWNER(%r3) 123 clrrptri %r9,%r9,5 /* clear low 5 bits */ 124 addi %r7,%r9,RW_READ_INCR 125 b 2f 126 1: 127 li %r9,0 128 ori %r7,%r13,RW_WRITE_LOCKED 129 130 2: lptrarx %r10,0,%r3 131 cmpptr %r10,%r9 132 bne- 3f 133 POWERPC_STWCX_PRE(0,%r3) 134 stptrcx. %r7,0,%r3 135 bne- 2b 136 ISYNC 137 blr 138 139 3: b _C_LABEL(rw_vector_enter) 140 141 /* 142 * bool rw_tryenter(krwlock_t *krw, krw_t op); 143 */ 144 ENTRY(rw_tryenter) 145 cmpwi %r3,RW_READER 146 bne- 1f 147 148 ldptr %r9,RW_OWNER(%r3) 149 clrrptri %r9,%r9,5 /* clear low 5 bits */ 150 addi %r7,%r9,RW_READ_INCR 151 b 2f 152 153 1: li %r9,0 154 ori %r7,%r13,RW_WRITE_LOCKED 155 156 2: lptrarx %r10,0,%r3 157 cmpptr %r10,%r9 158 bne- 3f 159 POWERPC_STWCX_PRE(0,%r3) 160 stptrcx. %r7,0,%r3 161 bne- 2b 162 163 ISYNC 164 li %r3,1 165 blr 166 167 3: li %r3,0 168 blr 169 170 /* 171 * void rw_exit(krwlock_t *krw, krw_t op); 172 */ 173 ENTRY(rw_exit) 174 ldptr %r9,RW_OWNER(%r3) 175 SYNC 176 andi. %r0,%r9,RW_WRITE_LOCKED 177 bne- 1f 178 179 clrrptri. %r9,%r9,5 /* clear low 5 bits */ 180 beq- 3f /* if 0, no reader, go slow */ 181 182 addi %r7,%r9,-RW_READ_INCR 183 b 2f 184 1: 185 li %r7,0 186 ori %r9,%r13,RW_WRITE_LOCKED 187 188 2: lptrarx %r10,0,%r3 189 cmpptr %r10,%r9 190 bne- 3f 191 POWERPC_STWCX_PRE(0,%r3) 192 stptrcx. %r7,0,%r3 193 bne- 2b 194 195 blr 196 197 3: b _C_LABEL(rw_vector_exit) 198 199 #endif /* __HAVE_RW_STUBS */ 200 201 #endif /* __HAVE_MUTEX_STUBS */ 202