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(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


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