The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ 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  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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_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: 0852bf3f5bc73e014747d6360313e90b


[ 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.