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/arm64/arm64/support.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 /*-
    2  * Copyright (c) 2014 Andrew Turner
    3  * Copyright (c) 2014-2015 The FreeBSD Foundation
    4  * All rights reserved.
    5  *
    6  * Portions of this software were developed by Andrew Turner
    7  * under sponsorship from the FreeBSD Foundation
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  *
   30  */
   31 
   32 #include <machine/asm.h>
   33 __FBSDID("$FreeBSD: releng/11.2/sys/arm64/arm64/support.S 319202 2017-05-30 12:26:36Z andrew $");
   34 
   35 #include <machine/setjmp.h>
   36 #include <machine/param.h>
   37 #include <machine/vmparam.h>
   38 
   39 #include "assym.s"
   40 
   41 /*
   42  * One of the fu* or su* functions failed, return -1.
   43  */
   44 ENTRY(fsu_fault)
   45         SET_FAULT_HANDLER(xzr, x1)      /* Reset the handler function */
   46         EXIT_USER_ACCESS_CHECK(w0, x1)
   47 fsu_fault_nopcb:
   48         mov     x0, #-1
   49         ret
   50 END(fsu_fault)
   51 
   52 /*
   53  * int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
   54  */
   55 ENTRY(casueword32)
   56         ldr     x4, =(VM_MAXUSER_ADDRESS-3)
   57         cmp     x0, x4
   58         b.cs    fsu_fault_nopcb
   59         adr     x6, fsu_fault           /* Load the fault handler */
   60         SET_FAULT_HANDLER(x6, x4)       /* And set it */
   61         ENTER_USER_ACCESS(w6, x4)
   62 1:      ldxr    w4, [x0]                /* Load-exclusive the data */
   63         cmp     w4, w1                  /* Compare */
   64         b.ne    2f                      /* Not equal, exit */
   65         stxr    w5, w3, [x0]            /* Store the new data */
   66         cbnz    w5, 1b                  /* Retry on failure */
   67         EXIT_USER_ACCESS(w6)
   68 2:      SET_FAULT_HANDLER(xzr, x5)      /* Reset the fault handler */
   69         str     w4, [x2]                /* Store the read data */
   70         mov     x0, #0                  /* Success */
   71         ret                             /* Return */
   72 END(casueword32)
   73 
   74 /*
   75  * int casueword(volatile u_long *, u_long, u_long *, u_long)
   76  */
   77 ENTRY(casueword)
   78         ldr     x4, =(VM_MAXUSER_ADDRESS-7)
   79         cmp     x0, x4
   80         b.cs    fsu_fault_nopcb
   81         adr     x6, fsu_fault           /* Load the fault handler */
   82         SET_FAULT_HANDLER(x6, x4)       /* And set it */
   83         ENTER_USER_ACCESS(w6, x4)
   84 1:      ldxr    x4, [x0]                /* Load-exclusive the data */
   85         cmp     x4, x1                  /* Compare */
   86         b.ne    2f                      /* Not equal, exit */
   87         stxr    w5, x3, [x0]            /* Store the new data */
   88         cbnz    w5, 1b                  /* Retry on failure */
   89         EXIT_USER_ACCESS(w6)
   90 2:      SET_FAULT_HANDLER(xzr, x5)      /* Reset the fault handler */
   91         str     x4, [x2]                /* Store the read data */
   92         mov     x0, #0                  /* Success */
   93         ret                             /* Return */
   94 END(casueword)
   95 
   96 /*
   97  * int fubyte(volatile const void *)
   98  */
   99 ENTRY(fubyte)
  100         ldr     x1, =VM_MAXUSER_ADDRESS
  101         cmp     x0, x1
  102         b.cs    fsu_fault_nopcb
  103         adr     x6, fsu_fault           /* Load the fault handler */
  104         SET_FAULT_HANDLER(x6, x1)       /* And set it */
  105         ldtrb   w0, [x0]                /* Try loading the data */
  106         SET_FAULT_HANDLER(xzr, x1)      /* Reset the fault handler */
  107         ret                             /* Return */
  108 END(fubyte)
  109 
  110 /*
  111  * int fuword(volatile const void *)
  112  */
  113 ENTRY(fuword16)
  114         ldr     x1, =(VM_MAXUSER_ADDRESS-1)
  115         cmp     x0, x1
  116         b.cs    fsu_fault_nopcb
  117         adr     x6, fsu_fault           /* Load the fault handler */
  118         SET_FAULT_HANDLER(x6, x1)       /* And set it */
  119         ldtrh   w0, [x0]                /* Try loading the data */
  120         SET_FAULT_HANDLER(xzr, x1)      /* Reset the fault handler */
  121         ret                             /* Return */
  122 END(fuword16)
  123 
  124 /*
  125  * int32_t fueword32(volatile const void *, int32_t *)
  126  */
  127 ENTRY(fueword32)
  128         ldr     x2, =(VM_MAXUSER_ADDRESS-3)
  129         cmp     x0, x2
  130         b.cs    fsu_fault_nopcb
  131         adr     x6, fsu_fault           /* Load the fault handler */
  132         SET_FAULT_HANDLER(x6, x2)       /* And set it */
  133         ldtr    w0, [x0]                /* Try loading the data */
  134         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
  135         str     w0, [x1]                /* Save the data in kernel space */
  136         mov     w0, #0                  /* Success */
  137         ret                             /* Return */
  138 END(fueword32)
  139 
  140 /*
  141  * long fueword(volatile const void *, int64_t *)
  142  * int64_t fueword64(volatile const void *, int64_t *)
  143  */
  144 ENTRY(fueword)
  145 EENTRY(fueword64)
  146         ldr     x2, =(VM_MAXUSER_ADDRESS-7)
  147         cmp     x0, x2
  148         b.cs    fsu_fault_nopcb
  149         adr     x6, fsu_fault           /* Load the fault handler */
  150         SET_FAULT_HANDLER(x6, x2)       /* And set it */
  151         ldtr    x0, [x0]                /* Try loading the data */
  152         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
  153         str     x0, [x1]                /* Save the data in kernel space */
  154         mov     x0, #0                  /* Success */
  155         ret                             /* Return */
  156 EEND(fueword64)
  157 END(fueword)
  158 
  159 /*
  160  * int subyte(volatile void *, int)
  161  */
  162 ENTRY(subyte)
  163         ldr     x2, =VM_MAXUSER_ADDRESS
  164         cmp     x0, x2
  165         b.cs    fsu_fault_nopcb
  166         adr     x6, fsu_fault           /* Load the fault handler */
  167         SET_FAULT_HANDLER(x6, x2)       /* And set it */
  168         sttrb   w1, [x0]                /* Try storing the data */
  169         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
  170         mov     x0, #0                  /* Success */
  171         ret                             /* Return */
  172 END(subyte)
  173 
  174 /*
  175  * int suword16(volatile void *, int)
  176  */
  177 ENTRY(suword16)
  178         ldr     x2, =(VM_MAXUSER_ADDRESS-1)
  179         cmp     x0, x2
  180         b.cs    fsu_fault_nopcb
  181         adr     x6, fsu_fault           /* Load the fault handler */
  182         SET_FAULT_HANDLER(x6, x2)       /* And set it */
  183         sttrh   w1, [x0]                /* Try storing the data */
  184         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
  185         mov     x0, #0                  /* Success */
  186         ret                             /* Return */
  187 END(suword16)
  188 
  189 /*
  190  * int suword32(volatile void *, int)
  191  */
  192 ENTRY(suword32)
  193         ldr     x2, =(VM_MAXUSER_ADDRESS-3)
  194         cmp     x0, x2
  195         b.cs    fsu_fault_nopcb
  196         adr     x6, fsu_fault           /* Load the fault handler */
  197         SET_FAULT_HANDLER(x6, x2)       /* And set it */
  198         sttr    w1, [x0]                /* Try storing the data */
  199         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
  200         mov     x0, #0                  /* Success */
  201         ret                             /* Return */
  202 END(suword32)
  203 
  204 /*
  205  * int suword(volatile void *, long)
  206  */
  207 ENTRY(suword)
  208 EENTRY(suword64)
  209         ldr     x2, =(VM_MAXUSER_ADDRESS-7)
  210         cmp     x0, x2
  211         b.cs    fsu_fault_nopcb
  212         adr     x6, fsu_fault           /* Load the fault handler */
  213         SET_FAULT_HANDLER(x6, x2)       /* And set it */
  214         sttr    x1, [x0]                /* Try storing the data */
  215         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
  216         mov     x0, #0                  /* Success */
  217         ret                             /* Return */
  218 EEND(suword64)
  219 END(suword)
  220 
  221 /*
  222  * fuswintr and suswintr are just like fusword and susword except that if
  223  * the page is not in memory or would cause a trap, then we return an error.
  224  * The important thing is to prevent sleep() and switch().
  225  */
  226 
  227 /*
  228  * Special handler so the trap code knows not to sleep.
  229  */
  230 ENTRY(fsu_intr_fault)
  231         SET_FAULT_HANDLER(xzr, x1)      /* Reset the handler function */
  232         EXIT_USER_ACCESS_CHECK(w0, x1)
  233         mov     x0, #-1
  234         ret
  235 END(fsu_fault)
  236 
  237 /*
  238  * int fuswintr(void *)
  239  */
  240 ENTRY(fuswintr)
  241         ldr     x1, =(VM_MAXUSER_ADDRESS-3)
  242         cmp     x0, x1
  243         b.cs    fsu_fault_nopcb
  244         adr     x6, fsu_intr_fault      /* Load the fault handler */
  245         SET_FAULT_HANDLER(x6, x1)       /* And set it */
  246         ldtr    w0, [x0]                /* Try loading the data */
  247         SET_FAULT_HANDLER(xzr, x1)      /* Reset the fault handler */
  248         ret                             /* Return */
  249 END(fuswintr)
  250 
  251 /*
  252  * int suswintr(void *base, int word)
  253  */
  254 ENTRY(suswintr)
  255         ldr     x2, =(VM_MAXUSER_ADDRESS-3)
  256         cmp     x0, x2
  257         b.cs    fsu_fault_nopcb
  258         adr     x6, fsu_intr_fault      /* Load the fault handler */
  259         SET_FAULT_HANDLER(x6, x2)       /* And set it */
  260         sttr    w1, [x0]                /* Try storing the data */
  261         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
  262         mov     x0, #0                  /* Success */
  263         ret                             /* Return */
  264 END(suswintr)
  265 
  266 ENTRY(setjmp)
  267         /* Store the stack pointer */
  268         mov     x8, sp
  269         str     x8, [x0], #8
  270 
  271         /* Store the general purpose registers and lr */
  272         stp     x19, x20, [x0], #16
  273         stp     x21, x22, [x0], #16
  274         stp     x23, x24, [x0], #16
  275         stp     x25, x26, [x0], #16
  276         stp     x27, x28, [x0], #16
  277         stp     x29, lr, [x0], #16
  278 
  279         /* Return value */
  280         mov     x0, #0
  281         ret
  282 END(setjmp)
  283 
  284 ENTRY(longjmp)
  285         /* Restore the stack pointer */
  286         ldr     x8, [x0], #8
  287         mov     sp, x8
  288 
  289         /* Restore the general purpose registers and lr */
  290         ldp     x19, x20, [x0], #16
  291         ldp     x21, x22, [x0], #16
  292         ldp     x23, x24, [x0], #16
  293         ldp     x25, x26, [x0], #16
  294         ldp     x27, x28, [x0], #16
  295         ldp     x29, lr, [x0], #16
  296 
  297         /* Load the return value */
  298         mov     x0, x1
  299         ret
  300 END(longjmp)
  301 
  302 /*
  303  * pagezero, simple implementation
  304  */
  305 ENTRY(pagezero_simple)
  306         add     x1, x0, #PAGE_SIZE
  307 
  308 1:
  309         stp     xzr, xzr, [x0], #0x10
  310         stp     xzr, xzr, [x0], #0x10
  311         stp     xzr, xzr, [x0], #0x10
  312         stp     xzr, xzr, [x0], #0x10
  313         cmp     x0, x1
  314         b.ne    1b
  315         ret
  316 
  317 END(pagezero_simple)
  318 
  319 /*
  320  * pagezero, cache assisted
  321  */
  322 ENTRY(pagezero_cache)
  323         add     x1, x0, #PAGE_SIZE
  324 
  325         ldr     x2, =dczva_line_size
  326         ldr     x2, [x2]
  327 
  328 1:
  329         dc      zva, x0
  330         add     x0, x0, x2
  331         cmp     x0, x1
  332         b.ne    1b
  333         ret
  334 
  335 END(pagezero_cache)

Cache object: bb9346439ed31bf55e6d04c3f2b66478


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