]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/riscv/riscv/exception.S
Copy libevent sources to contrib
[FreeBSD/FreeBSD.git] / sys / riscv / riscv / exception.S
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         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)