Home | History | Annotate | Line # | Download | only in powerpc
      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