]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/fusu.S
Remove spurious newline
[FreeBSD/FreeBSD.git] / sys / arm / arm / fusu.S
1 /*      $NetBSD: fusu.S,v 1.10 2003/12/01 13:34:44 rearnsha Exp $       */
2
3 /*-
4  * Copyright (c) 1996-1998 Mark Brinicombe.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Mark Brinicombe
18  * 4. The name of the company nor the name of the author may be used to
19  *    endorse or promote products derived from this software without specific
20  *    prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  */
35
36 #include <machine/asm.h>
37 #include <machine/armreg.h>
38 #include "assym.inc"
39 __FBSDID("$FreeBSD$");
40
41         .syntax unified
42
43 #if __ARM_ARCH >= 6
44 #define GET_PCB(tmp) \
45         mrc p15, 0, tmp, c13, c0, 4; \
46         add     tmp, tmp, #(TD_PCB)
47 #else
48 .Lcurpcb:
49         .word   _C_LABEL(__pcpu) + PC_CURPCB
50 #define GET_PCB(tmp) \
51         ldr     tmp, .Lcurpcb
52 #endif
53
54 /*
55  * casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp,
56  *    uint32_t newval);
57  */
58
59 ENTRY(casueword)
60 EENTRY_NP(casueword32)
61         stmfd   sp!, {r4, r5, r6}
62
63         ldr     r4, =(VM_MAXUSER_ADDRESS-3)
64         cmp     r0, r4
65         mvncs   r0, #0
66         bcs     2f
67
68         GET_PCB(r6)
69         ldr     r6, [r6]
70
71 #ifdef DIAGNOSTIC
72         teq     r6, #0x00000000
73         ldmfdeq sp!, {r4, r5, r6}
74         beq     .Lfusupcbfault
75 #endif
76
77         adr     r4, .Lcasuwordfault
78         str     r4, [r6, #PCB_ONFAULT]
79
80 #if __ARM_ARCH >= 6
81 1:
82         ldrex   r4, [r0]
83         cmp     r4, r1
84         strexeq r5, r3, [r0]
85         cmpeq   r5, #1
86         beq     1b
87 #else
88         ldrt    r4, [r0]
89         cmp     r4, r1
90         strteq  r3, [r0]
91 #endif
92         str     r4, [r2]
93         mov     r0, #0
94         str     r0, [r6, #PCB_ONFAULT]
95 2:
96         ldmfd   sp!, {r4, r5, r6}
97         RET
98 EEND(casueword32)
99 END(casueword)
100
101 /*
102  * Handle faults from casuword.  Clean up and return -1.
103  */
104
105 .Lcasuwordfault:
106         mov     r0, #0x00000000
107         str     r0, [r6, #PCB_ONFAULT]
108         mvn     r0, #0
109         ldmfd   sp!, {r4, r5, r6}
110         RET
111
112 /*
113  * fueword(caddr_t uaddr, long *val);
114  * Fetch an int from the user's address space.
115  */
116
117 ENTRY(fueword)
118 EENTRY_NP(fueword32)
119         ldr     r3, =(VM_MAXUSER_ADDRESS-3)
120         cmp     r0, r3
121         mvncs   r0, #0
122         RETc(cs)
123
124         GET_PCB(r2)
125         ldr     r2, [r2]
126
127 #ifdef DIAGNOSTIC
128         teq     r2, #0x00000000
129         beq     .Lfusupcbfault
130 #endif
131
132         adr     r3, .Lfusufault
133         str     r3, [r2, #PCB_ONFAULT]
134
135         ldrt    r3, [r0]
136         str     r3, [r1]
137
138         mov     r0, #0x00000000
139         str     r0, [r2, #PCB_ONFAULT]
140         RET
141 EEND(fueword32)
142 END(fueword)
143
144 /*
145  * fusword(caddr_t uaddr);
146  * Fetch a short from the user's address space.
147  */
148
149 ENTRY(fusword)
150         ldr     r3, =(VM_MAXUSER_ADDRESS-1)
151         cmp     r0, r3
152         mvncs   r0, #0
153         RETc(cs)
154
155         GET_PCB(r2)
156         ldr     r2, [r2]
157
158 #ifdef DIAGNOSTIC
159         teq     r2, #0x00000000
160         beq     .Lfusupcbfault
161 #endif
162
163         adr     r1, .Lfusufault
164         str     r1, [r2, #PCB_ONFAULT]
165
166         ldrbt   r3, [r0], #1
167         ldrbt   ip, [r0]
168 #ifdef __ARMEB__
169         orr     r0, ip, r3, asl #8
170 #else
171         orr     r0, r3, ip, asl #8
172 #endif
173         mov     r1, #0x00000000
174         str     r1, [r2, #PCB_ONFAULT]
175         RET
176 END(fusword)
177
178 /*
179  * fubyte(caddr_t uaddr);
180  * Fetch a byte from the user's address space.
181  */
182
183 ENTRY(fubyte)
184         ldr     r3, =VM_MAXUSER_ADDRESS
185         cmp     r0, r3
186         mvncs   r0, #0
187         RETc(cs)
188
189         GET_PCB(r2)
190         ldr     r2, [r2]
191
192 #ifdef DIAGNOSTIC
193         teq     r2, #0x00000000
194         beq     .Lfusupcbfault
195 #endif
196
197         adr     r1, .Lfusufault
198         str     r1, [r2, #PCB_ONFAULT]
199
200         ldrbt   r3, [r0]
201
202         mov     r1, #0x00000000
203         str     r1, [r2, #PCB_ONFAULT]
204         mov     r0, r3
205         RET
206 END(fubyte)
207
208 /*
209  * Handle faults from [fs]u*().  Clean up and return -1.
210  */
211
212 .Lfusufault:
213         mov     r0, #0x00000000
214         str     r0, [r2, #PCB_ONFAULT]
215         mvn     r0, #0x00000000
216         RET
217
218 #ifdef DIAGNOSTIC
219 /*
220  * Handle earlier faults from [fs]u*(), due to no pcb
221  */
222
223 .Lfusupcbfault:
224         mov     r1, r0
225         adr     r0, fusupcbfaulttext
226         b       _C_LABEL(panic)
227
228 fusupcbfaulttext:
229         .asciz  "Yikes - no valid PCB during fusuxxx() addr=%08x\n"
230         .align  2
231 #endif
232
233 /*
234  * suword(caddr_t uaddr, int x);
235  * Store an int in the user's address space.
236  */
237
238 ENTRY(suword)
239 EENTRY_NP(suword32)
240         ldr     r3, =(VM_MAXUSER_ADDRESS-3)
241         cmp     r0, r3
242         mvncs   r0, #0
243         RETc(cs)
244
245         GET_PCB(r2)
246         ldr     r2, [r2]
247
248 #ifdef DIAGNOSTIC
249         teq     r2, #0x00000000
250         beq     .Lfusupcbfault
251 #endif
252
253         adr     r3, .Lfusufault
254         str     r3, [r2, #PCB_ONFAULT]
255
256         strt    r1, [r0]
257
258         mov     r0, #0x00000000
259         str     r0, [r2, #PCB_ONFAULT]
260         RET
261 EEND(suword32)
262 END(suword)
263
264 /*
265  * susword(caddr_t uaddr, short x);
266  * Store a short in the user's address space.
267  */
268
269 ENTRY(susword)
270         ldr     r3, =(VM_MAXUSER_ADDRESS-1)
271         cmp     r0, r3
272         mvncs   r0, #0
273         RETc(cs)
274
275         GET_PCB(r2)
276         ldr     r2, [r2]
277
278 #ifdef DIAGNOSTIC
279         teq     r2, #0x00000000
280         beq     .Lfusupcbfault
281 #endif
282
283         adr     r3, .Lfusufault
284         str     r3, [r2, #PCB_ONFAULT]
285
286 #ifdef __ARMEB__
287         mov     ip, r1, lsr #8
288         strbt   ip, [r0], #1
289 #else
290         strbt   r1, [r0], #1
291         mov     r1, r1, lsr #8
292 #endif
293         strbt   r1, [r0]
294
295         mov     r0, #0x00000000
296         str     r0, [r2, #PCB_ONFAULT]
297         RET
298 END(susword)
299
300 /*
301  * subyte(caddr_t uaddr, char x);
302  * Store a byte in the user's address space.
303  */
304
305 ENTRY(subyte)
306         ldr     r3, =VM_MAXUSER_ADDRESS
307         cmp     r0, r3
308         mvncs   r0, #0
309         RETc(cs)
310
311         GET_PCB(r2)
312         ldr     r2, [r2]
313
314
315 #ifdef DIAGNOSTIC
316         teq     r2, #0x00000000
317         beq     .Lfusupcbfault
318 #endif
319
320         adr     r3, .Lfusufault
321         str     r3, [r2, #PCB_ONFAULT]
322
323         strbt   r1, [r0]
324         mov     r0, #0x00000000
325         str     r0, [r2, #PCB_ONFAULT]
326         RET
327 END(subyte)