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

Cache object: 5072765cc302281599a23e478b13ac8b


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