2 * Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
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.
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).
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
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.
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
35 #include <machine/asm.h>
36 __FBSDID("$FreeBSD$");
40 #include <machine/trap.h>
41 #include <machine/riscvreg.h>
43 .macro save_registers el
44 addi sp, sp, -(TF_SIZE)
49 .if \el == 0 /* We came from userspace. Load our pcpu */
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)
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)
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)
85 /* XXX: temporary test: spin if stack is not kernel one */
86 .if \el == 1 /* kernel */
109 sd t0, (TF_SSTATUS)(sp)
111 sd t0, (TF_SBADADDR)(sp)
113 sd t0, (TF_SCAUSE)(sp)
116 .macro load_registers el
117 ld t0, (TF_SSTATUS)(sp)
120 * Ensure user interrupts will be enabled on eret
121 * and supervisor mode can access userspace on trap.
123 li t1, (SSTATUS_SPIE | SSTATUS_SUM)
127 * Disable interrupts for supervisor mode exceptions.
128 * For user mode exceptions we have already done this
140 /* We go to userspace. Load user sp */
144 /* And store our pcpu */
152 ld t0, (TF_T + 0 * 8)(sp)
153 ld t1, (TF_T + 1 * 8)(sp)
154 ld t2, (TF_T + 2 * 8)(sp)
155 ld t3, (TF_T + 3 * 8)(sp)
156 ld t4, (TF_T + 4 * 8)(sp)
157 ld t5, (TF_T + 5 * 8)(sp)
158 ld t6, (TF_T + 6 * 8)(sp)
160 ld s0, (TF_S + 0 * 8)(sp)
161 ld s1, (TF_S + 1 * 8)(sp)
162 ld s2, (TF_S + 2 * 8)(sp)
163 ld s3, (TF_S + 3 * 8)(sp)
164 ld s4, (TF_S + 4 * 8)(sp)
165 ld s5, (TF_S + 5 * 8)(sp)
166 ld s6, (TF_S + 6 * 8)(sp)
167 ld s7, (TF_S + 7 * 8)(sp)
168 ld s8, (TF_S + 8 * 8)(sp)
169 ld s9, (TF_S + 9 * 8)(sp)
170 ld s10, (TF_S + 10 * 8)(sp)
171 ld s11, (TF_S + 11 * 8)(sp)
173 ld a0, (TF_A + 0 * 8)(sp)
174 ld a1, (TF_A + 1 * 8)(sp)
175 ld a2, (TF_A + 2 * 8)(sp)
176 ld a3, (TF_A + 3 * 8)(sp)
177 ld a4, (TF_A + 4 * 8)(sp)
178 ld a5, (TF_A + 5 * 8)(sp)
179 ld a6, (TF_A + 6 * 8)(sp)
180 ld a7, (TF_A + 7 * 8)(sp)
182 addi sp, sp, (TF_SIZE)
186 /* Disable interrupts */
189 csrci sstatus, (SSTATUS_SIE)
191 ld a1, PC_CURTHREAD(gp)
194 li a3, (TDF_ASTPENDING|TDF_NEEDRESCHED)
198 /* Restore interrupts */
199 andi a4, a4, (SSTATUS_SIE)
206 /* Re-check for new ast scheduled */
211 ENTRY(cpu_exception_handler)
212 csrrw sp, sscratch, sp
214 /* User mode detected */
215 csrrw sp, sscratch, sp
216 j cpu_exception_handler_user
218 /* Supervisor mode detected */
219 csrrw sp, sscratch, sp
220 j cpu_exception_handler_supervisor
221 END(cpu_exception_handler)
223 ENTRY(cpu_exception_handler_supervisor)
226 call _C_LABEL(do_trap_supervisor)
229 END(cpu_exception_handler_supervisor)
231 ENTRY(cpu_exception_handler_user)
232 csrrw sp, sscratch, sp
235 call _C_LABEL(do_trap_user)
238 csrrw sp, sscratch, sp
240 END(cpu_exception_handler_user)