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

Cache object: 871f31a9c3890f1d50b650050d999071


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