xref: /netbsd/sys/arch/powerpc/powerpc/lock_stubs.S (revision 6550d01e)
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