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$");
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
48 .if \el == 0 /* We came from userspace. */
49 sd gp, (TF_GP)(sp)
50 .option push
51 .option norelax
52 /* Load the kernel's global pointer */
53 la gp, __global_pointer$
54 .option pop
55
56 /* Load our pcpu */
57 sd tp, (TF_TP)(sp)
58 ld tp, (TF_SIZE)(sp)
59 .endif
60
61 sd t0, (TF_T + 0 * 8)(sp)
62 sd t1, (TF_T + 1 * 8)(sp)
63 sd t2, (TF_T + 2 * 8)(sp)
64 sd t3, (TF_T + 3 * 8)(sp)
65 sd t4, (TF_T + 4 * 8)(sp)
66 sd t5, (TF_T + 5 * 8)(sp)
67 sd t6, (TF_T + 6 * 8)(sp)
68
69 sd s0, (TF_S + 0 * 8)(sp)
70 sd s1, (TF_S + 1 * 8)(sp)
71 sd s2, (TF_S + 2 * 8)(sp)
72 sd s3, (TF_S + 3 * 8)(sp)
73 sd s4, (TF_S + 4 * 8)(sp)
74 sd s5, (TF_S + 5 * 8)(sp)
75 sd s6, (TF_S + 6 * 8)(sp)
76 sd s7, (TF_S + 7 * 8)(sp)
77 sd s8, (TF_S + 8 * 8)(sp)
78 sd s9, (TF_S + 9 * 8)(sp)
79 sd s10, (TF_S + 10 * 8)(sp)
80 sd s11, (TF_S + 11 * 8)(sp)
81
82 sd a0, (TF_A + 0 * 8)(sp)
83 sd a1, (TF_A + 1 * 8)(sp)
84 sd a2, (TF_A + 2 * 8)(sp)
85 sd a3, (TF_A + 3 * 8)(sp)
86 sd a4, (TF_A + 4 * 8)(sp)
87 sd a5, (TF_A + 5 * 8)(sp)
88 sd a6, (TF_A + 6 * 8)(sp)
89 sd a7, (TF_A + 7 * 8)(sp)
90
91 .if \el == 1
92 /* Store kernel sp */
93 li t1, TF_SIZE
94 add t0, sp, t1
95 sd t0, (TF_SP)(sp)
96 .else
97 /* Store user sp */
98 csrr t0, sscratch
99 sd t0, (TF_SP)(sp)
100 .endif
101 li t0, 0
102 csrw sscratch, t0
103 csrr t0, sepc
104 sd t0, (TF_SEPC)(sp)
105 csrr t0, sstatus
106 sd t0, (TF_SSTATUS)(sp)
107 csrr t0, stval
108 sd t0, (TF_STVAL)(sp)
109 csrr t0, scause
110 sd t0, (TF_SCAUSE)(sp)
111 .endm
112
113 .macro load_registers el
114 ld t0, (TF_SSTATUS)(sp)
115 .if \el == 0
116 /* Ensure user interrupts will be enabled on eret */
117 li t1, SSTATUS_SPIE
118 or t0, t0, t1
119 .else
120 /*
121 * Disable interrupts for supervisor mode exceptions.
122 * For user mode exceptions we have already done this
123 * in do_ast.
124 */
125 li t1, ~SSTATUS_SIE
126 and t0, t0, t1
127 .endif
128 csrw sstatus, t0
129
130 ld t0, (TF_SEPC)(sp)
131 csrw sepc, t0
132
133 .if \el == 0
134 /* We go to userspace. Load user sp */
135 ld t0, (TF_SP)(sp)
136 csrw sscratch, t0
137
138 /* Store our pcpu */
139 sd tp, (TF_SIZE)(sp)
140 ld tp, (TF_TP)(sp)
141
142 /* And restore the user's global pointer */
143 ld gp, (TF_GP)(sp)
144 .endif
145
146 ld ra, (TF_RA)(sp)
147
148 ld t0, (TF_T + 0 * 8)(sp)
149 ld t1, (TF_T + 1 * 8)(sp)
150 ld t2, (TF_T + 2 * 8)(sp)
151 ld t3, (TF_T + 3 * 8)(sp)
152 ld t4, (TF_T + 4 * 8)(sp)
153 ld t5, (TF_T + 5 * 8)(sp)
154 ld t6, (TF_T + 6 * 8)(sp)
155
156 ld s0, (TF_S + 0 * 8)(sp)
157 ld s1, (TF_S + 1 * 8)(sp)
158 ld s2, (TF_S + 2 * 8)(sp)
159 ld s3, (TF_S + 3 * 8)(sp)
160 ld s4, (TF_S + 4 * 8)(sp)
161 ld s5, (TF_S + 5 * 8)(sp)
162 ld s6, (TF_S + 6 * 8)(sp)
163 ld s7, (TF_S + 7 * 8)(sp)
164 ld s8, (TF_S + 8 * 8)(sp)
165 ld s9, (TF_S + 9 * 8)(sp)
166 ld s10, (TF_S + 10 * 8)(sp)
167 ld s11, (TF_S + 11 * 8)(sp)
168
169 ld a0, (TF_A + 0 * 8)(sp)
170 ld a1, (TF_A + 1 * 8)(sp)
171 ld a2, (TF_A + 2 * 8)(sp)
172 ld a3, (TF_A + 3 * 8)(sp)
173 ld a4, (TF_A + 4 * 8)(sp)
174 ld a5, (TF_A + 5 * 8)(sp)
175 ld a6, (TF_A + 6 * 8)(sp)
176 ld a7, (TF_A + 7 * 8)(sp)
177
178 addi sp, sp, (TF_SIZE)
179 .endm
180
181 .macro do_ast
182 /* Disable interrupts */
183 csrr a4, sstatus
184 1:
185 csrci sstatus, (SSTATUS_SIE)
186
187 ld a1, PC_CURTHREAD(tp)
188 lw a2, TD_FLAGS(a1)
189
190 li a3, (TDF_ASTPENDING|TDF_NEEDRESCHED)
191 and a2, a2, a3
192 beqz a2, 2f
193
194 /* Restore interrupts */
195 andi a4, a4, (SSTATUS_SIE)
196 csrs sstatus, a4
197
198 /* Handle the ast */
199 mv a0, sp
200 call _C_LABEL(ast)
201
202 /* Re-check for new ast scheduled */
203 j 1b
204 2:
205 .endm
206
207 ENTRY(cpu_exception_handler)
208 csrrw sp, sscratch, sp
209 beqz sp, 1f
210 /* User mode detected */
211 j cpu_exception_handler_user
212 1:
213 /* Supervisor mode detected */
214 csrrw sp, sscratch, sp
215 j cpu_exception_handler_supervisor
216 END(cpu_exception_handler)
217
218 ENTRY(cpu_exception_handler_supervisor)
219 save_registers 1
220 mv a0, sp
221 call _C_LABEL(do_trap_supervisor)
222 load_registers 1
223 sret
224 END(cpu_exception_handler_supervisor)
225
226 ENTRY(cpu_exception_handler_user)
227 save_registers 0
228 mv a0, sp
229 call _C_LABEL(do_trap_user)
230 do_ast
231 load_registers 0
232 csrrw sp, sscratch, sp
233 sret
234 END(cpu_exception_handler_user)
Cache object: f18c438844189edb74b05dc36f09728c
|