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
|