]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/fusu.S
Remove Lvirtaddr and Lphysaddr, these don't appear to be used.
[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.s"
39 __FBSDID("$FreeBSD$");
40
41 #ifdef _ARM_ARCH_6
42 #define GET_PCB(tmp) \
43         mrc p15, 0, tmp, c13, c0, 4; \
44         add     tmp, tmp, #(TD_PCB)
45 #else
46 .Lcurpcb:
47         .word   _C_LABEL(__pcpu) + PC_CURPCB
48 #define GET_PCB(tmp) \
49         ldr     tmp, .Lcurpcb
50 #endif
51
52 /*
53  * fuword(caddr_t uaddr);
54  * Fetch an int from the user's address space.
55  */
56
57 ENTRY(casuword)
58 EENTRY_NP(casuword32)
59         GET_PCB(r3)
60         ldr     r3, [r3]
61
62 #ifdef DIAGNOSTIC
63         teq     r3, #0x00000000
64         beq     .Lfusupcbfault
65 #endif
66         stmfd   sp!, {r4, r5}
67         adr     r4, .Lcasuwordfault
68         str     r4, [r3, #PCB_ONFAULT]
69 #ifdef _ARM_ARCH_6
70 1:    
71         cmp     r0, #KERNBASE
72         mvnhs   r0, #0
73         bhs     2f
74         
75         ldrex   r5, [r0]
76         cmp     r5, r1
77         movne   r0, r5
78         bne     2f
79         strex   r5, r2, [r0]
80         cmp     r5, #0
81         bne     1b
82 #else
83         ldrt    r5, [r0]
84         cmp     r5, r1
85         movne   r0, r5
86         streqt  r2, [r0]
87 #endif
88         moveq   r0, r1
89 2:
90         ldmfd   sp!, {r4, r5}
91         mov     r1, #0x00000000
92         str     r1, [r3, #PCB_ONFAULT]
93         RET
94 EEND(casuword32)
95 END(casuword)
96
97 /*
98  * Handle faults from casuword.  Clean up and return -1.
99  */
100
101 .Lcasuwordfault:
102         mov     r0, #0x00000000
103         str     r0, [r3, #PCB_ONFAULT]
104         mvn     r0, #0x00000000
105         ldmfd   sp!, {r4, r5}
106         RET     
107
108 /*
109  * fuword(caddr_t uaddr);
110  * Fetch an int from the user's address space.
111  */
112
113 ENTRY(fuword)
114 EENTRY_NP(fuword32)
115         GET_PCB(r2)
116         ldr     r2, [r2]
117
118 #ifdef DIAGNOSTIC
119         teq     r2, #0x00000000
120         beq     .Lfusupcbfault
121 #endif
122
123         adr     r1, .Lfusufault
124         str     r1, [r2, #PCB_ONFAULT]
125
126         ldrt    r3, [r0]
127
128         mov     r1, #0x00000000
129         str     r1, [r2, #PCB_ONFAULT]
130         mov     r0, r3
131         RET
132 END(fuword32)
133 END(fuword)
134
135 /*
136  * fusword(caddr_t uaddr);
137  * Fetch a short from the user's address space.
138  */
139
140 ENTRY(fusword)
141         GET_PCB(r2)
142         ldr     r2, [r2]
143
144 #ifdef DIAGNOSTIC
145         teq     r2, #0x00000000
146         beq     .Lfusupcbfault
147 #endif
148
149         adr     r1, .Lfusufault
150         str     r1, [r2, #PCB_ONFAULT]
151
152         ldrbt   r3, [r0], #1
153         ldrbt   ip, [r0]
154 #ifdef __ARMEB__
155         orr     r0, ip, r3, asl #8
156 #else
157         orr     r0, r3, ip, asl #8
158 #endif
159         mov     r1, #0x00000000
160         str     r1, [r2, #PCB_ONFAULT]
161         RET
162 END(fusword)
163
164 /*
165  * fuswintr(caddr_t uaddr);
166  * Fetch a short from the user's address space.  Can be called during an
167  * interrupt.
168  */
169
170 ENTRY(fuswintr)
171         ldr     r2, Lblock_userspace_access
172         ldr     r2, [r2]
173         teq     r2, #0
174         mvnne   r0, #0x00000000
175         RETne
176
177         GET_PCB(r2)
178         ldr     r2, [r2]
179
180 #ifdef DIAGNOSTIC
181         teq     r2, #0x00000000
182         beq     .Lfusupcbfault
183 #endif
184
185         adr     r1, _C_LABEL(fusubailout)
186         str     r1, [r2, #PCB_ONFAULT]
187
188         ldrbt   r3, [r0], #1
189         ldrbt   ip, [r0]
190 #ifdef __ARMEB__
191         orr     r0, ip, r3, asl #8
192 #else
193         orr     r0, r3, ip, asl #8
194 #endif
195
196         mov     r1, #0x00000000
197         str     r1, [r2, #PCB_ONFAULT]
198         RET
199 END(fuswintr)
200
201 Lblock_userspace_access:
202         .word   _C_LABEL(block_userspace_access)
203
204         .data
205         .align  0
206         .global _C_LABEL(block_userspace_access)
207 _C_LABEL(block_userspace_access):
208         .word   0
209         .text
210
211 /*
212  * fubyte(caddr_t uaddr);
213  * Fetch a byte from the user's address space.
214  */
215
216 ENTRY(fubyte)
217         GET_PCB(r2)
218         ldr     r2, [r2]
219
220 #ifdef DIAGNOSTIC
221         teq     r2, #0x00000000
222         beq     .Lfusupcbfault
223 #endif
224
225         adr     r1, .Lfusufault
226         str     r1, [r2, #PCB_ONFAULT]
227
228         ldrbt   r3, [r0]
229
230         mov     r1, #0x00000000
231         str     r1, [r2, #PCB_ONFAULT]
232         mov     r0, r3
233         RET
234 END(fubyte)
235
236 /*
237  * Handle faults from [fs]u*().  Clean up and return -1.
238  */
239
240 .Lfusufault:
241         mov     r0, #0x00000000
242         str     r0, [r2, #PCB_ONFAULT]
243         mvn     r0, #0x00000000
244         RET
245
246 /*
247  * Handle faults from [fs]u*().  Clean up and return -1.  This differs from
248  * fusufault() in that trap() will recognise it and return immediately rather
249  * than trying to page fault.
250  */
251
252 /* label must be global as fault.c references it */
253         .global _C_LABEL(fusubailout)
254 _C_LABEL(fusubailout):
255         mov     r0, #0x00000000
256         str     r0, [r2, #PCB_ONFAULT]
257         mvn     r0, #0x00000000
258         RET
259
260 #ifdef DIAGNOSTIC
261 /*
262  * Handle earlier faults from [fs]u*(), due to no pcb
263  */
264
265 .Lfusupcbfault:
266         mov     r1, r0
267         adr     r0, fusupcbfaulttext
268         b       _C_LABEL(panic)
269
270 fusupcbfaulttext:
271         .asciz  "Yikes - no valid PCB during fusuxxx() addr=%08x\n"
272         .align  0
273 #endif
274
275 /*
276  * suword(caddr_t uaddr, int x);
277  * Store an int in the user's address space.
278  */
279
280 ENTRY(suword)
281 EENTRY_NP(suword32)
282         GET_PCB(r2)
283         ldr     r2, [r2]
284
285 #ifdef DIAGNOSTIC
286         teq     r2, #0x00000000
287         beq     .Lfusupcbfault
288 #endif
289
290         adr     r3, .Lfusufault
291         str     r3, [r2, #PCB_ONFAULT]
292
293         strt    r1, [r0]
294
295         mov     r0, #0x00000000
296         str     r0, [r2, #PCB_ONFAULT]
297         RET
298 END(suword32)
299 END(suword)
300
301 /*
302  * suswintr(caddr_t uaddr, short x);
303  * Store a short in the user's address space.  Can be called during an
304  * interrupt.
305  */
306
307 ENTRY(suswintr)
308         ldr     r2, Lblock_userspace_access
309         ldr     r2, [r2]
310         teq     r2, #0
311         mvnne   r0, #0x00000000
312         RETne
313
314         GET_PCB(r2)
315         ldr     r2, [r2]
316
317 #ifdef DIAGNOSTIC
318         teq     r2, #0x00000000
319         beq     .Lfusupcbfault
320 #endif
321
322         adr     r3, _C_LABEL(fusubailout)
323         str     r3, [r2, #PCB_ONFAULT]
324
325 #ifdef __ARMEB__
326         mov     ip, r1, lsr #8
327         strbt   ip, [r0], #1
328 #else
329         strbt   r1, [r0], #1
330         mov     r1, r1, lsr #8
331 #endif
332         strbt   r1, [r0]
333
334         mov     r0, #0x00000000
335         str     r0, [r2, #PCB_ONFAULT]
336         RET
337 END(suswintr)
338
339 /*
340  * susword(caddr_t uaddr, short x);
341  * Store a short in the user's address space.
342  */
343
344 ENTRY(susword)
345         GET_PCB(r2)
346         ldr     r2, [r2]
347
348 #ifdef DIAGNOSTIC
349         teq     r2, #0x00000000
350         beq     .Lfusupcbfault
351 #endif
352
353         adr     r3, .Lfusufault
354         str     r3, [r2, #PCB_ONFAULT]
355
356 #ifdef __ARMEB__
357         mov     ip, r1, lsr #8
358         strbt   ip, [r0], #1
359 #else
360         strbt   r1, [r0], #1
361         mov     r1, r1, lsr #8
362 #endif
363         strbt   r1, [r0]
364
365         mov     r0, #0x00000000
366         str     r0, [r2, #PCB_ONFAULT]
367         RET
368 END(susword)
369
370 /*
371  * subyte(caddr_t uaddr, char x);
372  * Store a byte in the user's address space.
373  */
374
375 ENTRY(subyte)
376         GET_PCB(r2)
377         ldr     r2, [r2]
378
379
380 #ifdef DIAGNOSTIC
381         teq     r2, #0x00000000
382         beq     .Lfusupcbfault
383 #endif
384
385         adr     r3, .Lfusufault
386         str     r3, [r2, #PCB_ONFAULT]
387
388         strbt   r1, [r0]
389         mov     r0, #0x00000000
390         str     r0, [r2, #PCB_ONFAULT]
391         RET
392 END(subyte)