xref: /netbsd-src/sys/arch/powerpc/powerpc/lock_stubs.S (revision 09ff5f3b480cb7eb269d9eec28950bf196ce206c)
1/*	$NetBSD: lock_stubs.S,v 1.14 2022/04/06 22:47:57 riastradh 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 */
55ENTRY(_lock_cas)
561:
57	lptrarx	%r10,0,%r3
58	cmpptr	%r10,%r4
59	bne-	2f
60	IBM405_ERRATA77_DCBT(0,%r3)
61	stptrcx. %r5,0,%r3
62	bne-	1b
63	SYNC
64	li	%r3,1
65	blr
662:
67	li	%r3,0
68	blr
69
70#if !defined(LOCKDEBUG)
71/*
72 * void mutex_enter(kmutex_t *);
73 */
74ENTRY(mutex_enter)
751:
76	lptrarx	%r10,0,%r3
77	cmpptri	%r10,0
78	bne-	2f
79	IBM405_ERRATA77_DCBT(0,%r3)
80	stptrcx. %r13,0,%r3
81	bne-	1b
82	ISYNC
83	blr
842:
85	b	_C_LABEL(mutex_vector_enter)
86
87/*
88 * void mutex_exit(kmutex_t *);
89 */
90ENTRY(mutex_exit)
91	SYNC
92	li	%r7,0
931:
94	lptrarx	%r10,0,%r3
95	cmpptr	%r10,%r13
96	bne-	2f
97	IBM405_ERRATA77_DCBT(0,%r3)
98	stptrcx. %r7,0,%r3
99	bne-	1b
100	blr
1012:
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
118ENTRY(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
1261:
127	li	%r9,0
128	ori	%r7,%r13,RW_WRITE_LOCKED
129
1302:	lptrarx	%r10,0,%r3
131	cmpptr	%r10,%r9
132	bne-	3f
133	IBM405_ERRATA77_DCBT(0,%r3)
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,5		/* clear low 5 bits */
150	addi	%r7,%r9,RW_READ_INCR
151	b	2f
152
1531:	li	%r9,0
154	ori	%r7,%r13,RW_WRITE_LOCKED
155
1562:	lptrarx	%r10,0,%r3
157	cmpptr	%r10,%r9
158	bne-	3f
159	IBM405_ERRATA77_DCBT(0,%r3)
160	stptrcx. %r7,0,%r3
161	bne-	2b
162
163	ISYNC
164	li	%r3,1
165	blr
166
1673:	li	%r3,0
168	blr
169
170/*
171 * void rw_exit(krwlock_t *krw, krw_t op);
172 */
173ENTRY(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
1841:
185	li	%r7,0
186	ori	%r9,%r13,RW_WRITE_LOCKED
187
1882:	lptrarx	%r10,0,%r3
189	cmpptr	%r10,%r9
190	bne-	3f
191	IBM405_ERRATA77_DCBT(0,%r3)
192	stptrcx. %r7,0,%r3
193	bne-	2b
194
195	blr
196
1973:	b	_C_LABEL(rw_vector_exit)
198
199#endif	/* __HAVE_RW_STUBS */
200
201#endif	/* __HAVE_MUTEX_STUBS */
202