FreeBSD/Linux Kernel Cross Reference
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
Cache object: bac0a1e613ad5463fbf81c87fe8de3a4
|