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/riscv/riscv/exception.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) 2015-2018 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * Portions of this software were developed by SRI International and the
    6  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
    7  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
    8  *
    9  * Portions of this software were developed by the University of Cambridge
   10  * Computer Laboratory as part of the CTSRD Project, with support from the
   11  * UK Higher Education Innovation Fund (HEIF).
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR 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 #include <machine/asm.h>
   36 __FBSDID("$FreeBSD: releng/12.0/sys/riscv/riscv/exception.S 338467 2018-09-05 11:34:58Z br $");
   37 
   38 #include "assym.inc"
   39 
   40 #include <machine/trap.h>
   41 #include <machine/riscvreg.h>
   42 
   43 .macro save_registers el
   44         addi    sp, sp, -(TF_SIZE)
   45 
   46         sd      ra, (TF_RA)(sp)
   47         sd      tp, (TF_TP)(sp)
   48 
   49 .if \el == 0    /* We came from userspace. Load our pcpu */
   50         sd      gp, (TF_GP)(sp)
   51         ld      gp, (TF_SIZE)(sp)
   52 .endif
   53 
   54         sd      t0, (TF_T + 0 * 8)(sp)
   55         sd      t1, (TF_T + 1 * 8)(sp)
   56         sd      t2, (TF_T + 2 * 8)(sp)
   57         sd      t3, (TF_T + 3 * 8)(sp)
   58         sd      t4, (TF_T + 4 * 8)(sp)
   59         sd      t5, (TF_T + 5 * 8)(sp)
   60         sd      t6, (TF_T + 6 * 8)(sp)
   61 
   62         sd      s0, (TF_S + 0 * 8)(sp)
   63         sd      s1, (TF_S + 1 * 8)(sp)
   64         sd      s2, (TF_S + 2 * 8)(sp)
   65         sd      s3, (TF_S + 3 * 8)(sp)
   66         sd      s4, (TF_S + 4 * 8)(sp)
   67         sd      s5, (TF_S + 5 * 8)(sp)
   68         sd      s6, (TF_S + 6 * 8)(sp)
   69         sd      s7, (TF_S + 7 * 8)(sp)
   70         sd      s8, (TF_S + 8 * 8)(sp)
   71         sd      s9, (TF_S + 9 * 8)(sp)
   72         sd      s10, (TF_S + 10 * 8)(sp)
   73         sd      s11, (TF_S + 11 * 8)(sp)
   74 
   75         sd      a0, (TF_A + 0 * 8)(sp)
   76         sd      a1, (TF_A + 1 * 8)(sp)
   77         sd      a2, (TF_A + 2 * 8)(sp)
   78         sd      a3, (TF_A + 3 * 8)(sp)
   79         sd      a4, (TF_A + 4 * 8)(sp)
   80         sd      a5, (TF_A + 5 * 8)(sp)
   81         sd      a6, (TF_A + 6 * 8)(sp)
   82         sd      a7, (TF_A + 7 * 8)(sp)
   83 
   84 #if 0
   85         /* XXX: temporary test: spin if stack is not kernel one */
   86 .if \el == 1    /* kernel */
   87         mv      t0, sp
   88         srli    t0, t0, 63
   89 1:
   90         beqz    t0, 1b
   91 .endif
   92 #endif
   93 
   94 .if \el == 1
   95         /* Store kernel sp */
   96         li      t1, TF_SIZE
   97         add     t0, sp, t1
   98         sd      t0, (TF_SP)(sp)
   99 .else
  100         /* Store user sp */
  101         csrr    t0, sscratch
  102         sd      t0, (TF_SP)(sp)
  103 .endif
  104         li      t0, 0
  105         csrw    sscratch, t0
  106         csrr    t0, sepc
  107         sd      t0, (TF_SEPC)(sp)
  108         csrr    t0, sstatus
  109         sd      t0, (TF_SSTATUS)(sp)
  110         csrr    t0, sbadaddr
  111         sd      t0, (TF_SBADADDR)(sp)
  112         csrr    t0, scause
  113         sd      t0, (TF_SCAUSE)(sp)
  114 .endm
  115 
  116 .macro load_registers el
  117         ld      t0, (TF_SSTATUS)(sp)
  118 .if \el == 0
  119         /* Ensure user interrupts will be enabled on eret */
  120         li      t1, SSTATUS_SPIE
  121         or      t0, t0, t1
  122 .else
  123         /*
  124          * Disable interrupts for supervisor mode exceptions.
  125          * For user mode exceptions we have already done this
  126          * in do_ast.
  127          */
  128         li      t1, ~SSTATUS_SIE
  129         and     t0, t0, t1
  130 .endif
  131         csrw    sstatus, t0
  132 
  133         ld      t0, (TF_SEPC)(sp)
  134         csrw    sepc, t0
  135 
  136 .if \el == 0
  137         /* We go to userspace. Load user sp */
  138         ld      t0, (TF_SP)(sp)
  139         csrw    sscratch, t0
  140 
  141         /* And store our pcpu */
  142         sd      gp, (TF_SIZE)(sp)
  143         ld      gp, (TF_GP)(sp)
  144 .endif
  145 
  146         ld      ra, (TF_RA)(sp)
  147         ld      tp, (TF_TP)(sp)
  148 
  149         ld      t0, (TF_T + 0 * 8)(sp)
  150         ld      t1, (TF_T + 1 * 8)(sp)
  151         ld      t2, (TF_T + 2 * 8)(sp)
  152         ld      t3, (TF_T + 3 * 8)(sp)
  153         ld      t4, (TF_T + 4 * 8)(sp)
  154         ld      t5, (TF_T + 5 * 8)(sp)
  155         ld      t6, (TF_T + 6 * 8)(sp)
  156 
  157         ld      s0, (TF_S + 0 * 8)(sp)
  158         ld      s1, (TF_S + 1 * 8)(sp)
  159         ld      s2, (TF_S + 2 * 8)(sp)
  160         ld      s3, (TF_S + 3 * 8)(sp)
  161         ld      s4, (TF_S + 4 * 8)(sp)
  162         ld      s5, (TF_S + 5 * 8)(sp)
  163         ld      s6, (TF_S + 6 * 8)(sp)
  164         ld      s7, (TF_S + 7 * 8)(sp)
  165         ld      s8, (TF_S + 8 * 8)(sp)
  166         ld      s9, (TF_S + 9 * 8)(sp)
  167         ld      s10, (TF_S + 10 * 8)(sp)
  168         ld      s11, (TF_S + 11 * 8)(sp)
  169 
  170         ld      a0, (TF_A + 0 * 8)(sp)
  171         ld      a1, (TF_A + 1 * 8)(sp)
  172         ld      a2, (TF_A + 2 * 8)(sp)
  173         ld      a3, (TF_A + 3 * 8)(sp)
  174         ld      a4, (TF_A + 4 * 8)(sp)
  175         ld      a5, (TF_A + 5 * 8)(sp)
  176         ld      a6, (TF_A + 6 * 8)(sp)
  177         ld      a7, (TF_A + 7 * 8)(sp)
  178 
  179         addi    sp, sp, (TF_SIZE)
  180 .endm
  181 
  182 .macro  do_ast
  183         /* Disable interrupts */
  184         csrr    a4, sstatus
  185 1:
  186         csrci   sstatus, (SSTATUS_SIE)
  187 
  188         ld      a1, PC_CURTHREAD(gp)
  189         lw      a2, TD_FLAGS(a1)
  190 
  191         li      a3, (TDF_ASTPENDING|TDF_NEEDRESCHED)
  192         and     a2, a2, a3
  193         beqz    a2, 2f
  194 
  195         /* Restore interrupts */
  196         andi    a4, a4, (SSTATUS_SIE)
  197         csrs    sstatus, a4
  198 
  199         /* Handle the ast */
  200         mv      a0, sp
  201         call    _C_LABEL(ast)
  202 
  203         /* Re-check for new ast scheduled */
  204         j       1b
  205 2:
  206 .endm
  207 
  208 ENTRY(cpu_exception_handler)
  209         csrrw   sp, sscratch, sp
  210         beqz    sp, 1f
  211         /* User mode detected */
  212         csrrw   sp, sscratch, sp
  213         j       cpu_exception_handler_user
  214 1:
  215         /* Supervisor mode detected */
  216         csrrw   sp, sscratch, sp
  217         j       cpu_exception_handler_supervisor
  218 END(cpu_exception_handler)
  219 
  220 ENTRY(cpu_exception_handler_supervisor)
  221         save_registers 1
  222         mv      a0, sp
  223         call    _C_LABEL(do_trap_supervisor)
  224         load_registers 1
  225         sret
  226 END(cpu_exception_handler_supervisor)
  227 
  228 ENTRY(cpu_exception_handler_user)
  229         csrrw   sp, sscratch, sp
  230         save_registers 0
  231         mv      a0, sp
  232         call    _C_LABEL(do_trap_user)
  233         do_ast
  234         load_registers 0
  235         csrrw   sp, sscratch, sp
  236         sret
  237 END(cpu_exception_handler_user)

Cache object: 50009142f3c42ab5b6ad7a31ea8c5004


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