xref: /DragonOS/kernel/src/arch/riscv64/interrupt/entry.rs (revision 7c28051e8c601312d3d0fd7bcb71bc71450d10c0)
1 use crate::arch::{
2     asm::csr::{CSR_SCAUSE, CSR_SEPC, CSR_SSCRATCH, CSR_SSTATUS, CSR_STVAL, SR_SPP},
3     cpu::LocalContext,
4     interrupt::TrapFrame,
5 };
6 use asm_macros::{restore_from_x6_to_x31, save_from_x6_to_x31};
7 use kdepends::memoffset::offset_of;
8 
9 /// Riscv64中断处理入口
10 #[naked]
11 #[no_mangle]
12 #[repr(align(4))]
handle_exception() -> !13 pub unsafe extern "C" fn handle_exception() -> ! {
14     core::arch::naked_asm!(
15         concat!("
16         /*
17 	        * If coming from userspace, preserve the user thread pointer and load
18 	        * the kernel thread pointer.  If we came from the kernel, the scratch
19 	        * register will contain 0, and we should continue on the current TP.
20         */
21 
22             csrrw tp, {csr_scratch}, tp
23             bnez tp, _save_context
24 
25             /* 从内核态进入中断 */
26             j {_restore_kernel_tpsp}
27         "),
28         csr_scratch = const CSR_SSCRATCH,
29         _restore_kernel_tpsp = sym _restore_kernel_tpsp
30     )
31 }
32 
33 #[naked]
34 #[no_mangle]
_restore_kernel_tpsp() -> !35 unsafe extern "C" fn _restore_kernel_tpsp() -> ! {
36     core::arch::naked_asm!(
37         concat!("
38             // 这次是从内核态进入中断
39             // 从sscratch寄存器加载当前cpu的上下文
40             csrr tp, {csr_scratch}
41 
42             // 把当前的sp寄存器的值保存到当前cpu的上下文的kernel_sp字段
43             sd sp, {lc_off_kernel_sp}(tp)
44 
45             j {_save_context}
46         "),
47         csr_scratch = const CSR_SSCRATCH,
48         lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
49         _save_context = sym _save_context
50     )
51 }
52 
53 #[naked]
54 #[no_mangle]
_save_context() -> !55 unsafe extern "C" fn _save_context() -> ! {
56     core::arch::naked_asm!(
57         concat!("
58 
59 
60             // 保存当前cpu的上下文
61 
62             // 保存用户sp
63             sd sp, {lc_off_user_sp}(tp)
64             // 加载内核sp
65             ld sp, {lc_off_kernel_sp}(tp)
66 
67             addi sp, sp, -{trap_frame_size_on_stack}
68             sd x1, {off_ra}(sp)
69             sd x3, {off_gp}(sp)
70             sd x5, {off_t0}(sp)
71         ",
72         save_from_x6_to_x31!(),
73         "
74         /*
75 	        * Disable user-mode memory access as it should only be set in the
76 	        * actual user copy routines.
77 	        *
78 	        * Disable the FPU/Vector to detect illegal usage of floating point
79 	        * or vector in kernel space.
80         */
81 
82         li t0, {sr_sum_and_fsvs}
83 
84         ld s0, {lc_off_user_sp}(tp)
85         csrrc s1, {csr_status}, t0
86         csrr s2, {csr_epc}
87         csrr s3, {csr_tval}
88         csrr s4, {csr_cause}
89         csrr s5, {csr_scratch}
90         sd s0, {off_sp}(sp)
91         sd s1, {off_status}(sp)
92         sd s2, {off_epc}(sp)
93         sd s3, {off_badaddr}(sp)
94         sd s4, {off_cause}(sp)
95         sd s5, {off_tp}(sp)
96 
97         /*
98 	    * Set the scratch register to 0, so that if a recursive exception
99 	    * occurs, the exception vector knows it came from the kernel
100 	    */
101 
102         csrw {csr_scratch}, x0
103 
104         /* Load the global pointer */
105         // linux 加载了global pointer,但是我们暂时没有用到
106 
107         // .option push
108         // .option norelax
109         //     la gp, __global_pointer$
110         // .option pop
111 
112         mv a0, sp
113         la ra, ret_from_exception
114 
115         tail riscv64_do_irq
116         "
117     ),
118 
119         lc_off_user_sp = const offset_of!(LocalContext, user_sp),
120         lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
121         trap_frame_size_on_stack = const TrapFrame::SIZE_ON_STACK,
122         off_ra = const offset_of!(TrapFrame, ra),
123         off_gp = const offset_of!(TrapFrame, gp),
124         off_t0 = const offset_of!(TrapFrame, t0),
125         off_t1 = const offset_of!(TrapFrame, t1),
126         off_t2 = const offset_of!(TrapFrame, t2),
127         off_s0 = const offset_of!(TrapFrame, s0),
128         off_s1 = const offset_of!(TrapFrame, s1),
129         off_a0 = const offset_of!(TrapFrame, a0),
130         off_a1 = const offset_of!(TrapFrame, a1),
131         off_a2 = const offset_of!(TrapFrame, a2),
132         off_a3 = const offset_of!(TrapFrame, a3),
133         off_a4 = const offset_of!(TrapFrame, a4),
134         off_a5 = const offset_of!(TrapFrame, a5),
135         off_a6 = const offset_of!(TrapFrame, a6),
136         off_a7 = const offset_of!(TrapFrame, a7),
137         off_s2 = const offset_of!(TrapFrame, s2),
138         off_s3 = const offset_of!(TrapFrame, s3),
139         off_s4 = const offset_of!(TrapFrame, s4),
140         off_s5 = const offset_of!(TrapFrame, s5),
141         off_s6 = const offset_of!(TrapFrame, s6),
142         off_s7 = const offset_of!(TrapFrame, s7),
143         off_s8 = const offset_of!(TrapFrame, s8),
144         off_s9 = const offset_of!(TrapFrame, s9),
145         off_s10 = const offset_of!(TrapFrame, s10),
146         off_s11 = const offset_of!(TrapFrame, s11),
147         off_t3 = const offset_of!(TrapFrame, t3),
148         off_t4 = const offset_of!(TrapFrame, t4),
149         off_t5 = const offset_of!(TrapFrame, t5),
150         off_t6 = const offset_of!(TrapFrame, t6),
151         off_sp = const offset_of!(TrapFrame, sp),
152         off_status = const offset_of!(TrapFrame, status),
153         off_badaddr = const offset_of!(TrapFrame, badaddr),
154         off_cause = const offset_of!(TrapFrame, cause),
155         off_tp = const offset_of!(TrapFrame, tp),
156         off_epc = const offset_of!(TrapFrame, epc),
157         sr_sum_and_fsvs = const (0), // 暂时在内核中不禁用FPU和Vector,以及不禁用用户内存访问
158         // sr_sum_and_fsvs = const (SR_FS_VS | SR_SUM),
159         csr_status = const CSR_SSTATUS,
160         csr_epc = const CSR_SEPC,
161         csr_tval = const CSR_STVAL,
162         csr_cause = const CSR_SCAUSE,
163         csr_scratch = const CSR_SSCRATCH
164     )
165 }
166 
167 #[naked]
168 #[no_mangle]
ret_from_exception() -> !169 pub unsafe extern "C" fn ret_from_exception() -> ! {
170     core::arch::naked_asm!(
171         concat!("
172             ld s0, {off_status}(sp)
173             andi s0, s0, {sr_spp}
174 
175             bnez s0, 3f
176 
177             // Save unwound kernel stack pointer in thread_info
178             addi s0, sp, {trap_frame_size_on_stack}
179             sd s0, {lc_off_kernel_sp}(tp)
180 
181             /*
182 	        * Save TP into the scratch register , so we can find the kernel data
183 	        * structures again.
184 	        */
185             csrw {csr_scratch}, tp
186         3:
187 
188             ld a0, {off_status}(sp)
189 
190             ld a2, {off_epc}(sp)
191             sc.d x0, a2, {off_epc}(sp)
192 
193             csrw {csr_status}, a0
194             csrw {csr_epc}, a2
195 
196             ld x1, {off_ra}(sp)
197             ld x3, {off_gp}(sp)
198             ld x4, {off_tp}(sp)
199             ld x5, {off_t0}(sp)
200 
201         ",
202         restore_from_x6_to_x31!(),
203         "
204             ld x2, {off_sp}(sp)
205 
206             sret
207         "
208         ),
209         off_status = const offset_of!(TrapFrame, status),
210         sr_spp = const SR_SPP,
211         trap_frame_size_on_stack = const TrapFrame::SIZE_ON_STACK,
212         lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
213         csr_scratch = const CSR_SSCRATCH,
214         csr_status = const CSR_SSTATUS,
215         csr_epc = const CSR_SEPC,
216         off_ra = const offset_of!(TrapFrame, ra),
217         off_gp = const offset_of!(TrapFrame, gp),
218         off_t0 = const offset_of!(TrapFrame, t0),
219         off_t1 = const offset_of!(TrapFrame, t1),
220         off_t2 = const offset_of!(TrapFrame, t2),
221         off_s0 = const offset_of!(TrapFrame, s0),
222         off_s1 = const offset_of!(TrapFrame, s1),
223         off_a0 = const offset_of!(TrapFrame, a0),
224         off_a1 = const offset_of!(TrapFrame, a1),
225         off_a2 = const offset_of!(TrapFrame, a2),
226         off_a3 = const offset_of!(TrapFrame, a3),
227         off_a4 = const offset_of!(TrapFrame, a4),
228         off_a5 = const offset_of!(TrapFrame, a5),
229         off_a6 = const offset_of!(TrapFrame, a6),
230         off_a7 = const offset_of!(TrapFrame, a7),
231         off_s2 = const offset_of!(TrapFrame, s2),
232         off_s3 = const offset_of!(TrapFrame, s3),
233         off_s4 = const offset_of!(TrapFrame, s4),
234         off_s5 = const offset_of!(TrapFrame, s5),
235         off_s6 = const offset_of!(TrapFrame, s6),
236         off_s7 = const offset_of!(TrapFrame, s7),
237         off_s8 = const offset_of!(TrapFrame, s8),
238         off_s9 = const offset_of!(TrapFrame, s9),
239         off_s10 = const offset_of!(TrapFrame, s10),
240         off_s11 = const offset_of!(TrapFrame, s11),
241         off_t3 = const offset_of!(TrapFrame, t3),
242         off_t4 = const offset_of!(TrapFrame, t4),
243         off_t5 = const offset_of!(TrapFrame, t5),
244         off_t6 = const offset_of!(TrapFrame, t6),
245         off_sp = const offset_of!(TrapFrame, sp),
246         off_tp = const offset_of!(TrapFrame, tp),
247         off_epc = const offset_of!(TrapFrame, epc)
248     )
249 }
250