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