[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/fusu.S

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

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

Cache object: a4e5825b452818b2ebde23a8caa5aae9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.