xref: /DragonOS/kernel/src/arch/riscv64/interrupt/entry.rs (revision 0102d69fdd231e472d7bb3d609a41ae56a3799ee)
15c4224e5SLoGin use crate::arch::{
2*0102d69fSLoGin     asm::csr::{CSR_SCAUSE, CSR_SEPC, CSR_SSCRATCH, CSR_SSTATUS, CSR_STVAL, SR_SPP},
35c4224e5SLoGin     cpu::LocalContext,
45c4224e5SLoGin     interrupt::TrapFrame,
55c4224e5SLoGin };
69621ab16SLoGin use asm_macros::{restore_from_x6_to_x31, save_from_x6_to_x31};
75c4224e5SLoGin use core::arch::asm;
85c4224e5SLoGin use kdepends::memoffset::offset_of;
95c4224e5SLoGin 
105c4224e5SLoGin /// Riscv64中断处理入口
115c4224e5SLoGin #[naked]
125c4224e5SLoGin #[no_mangle]
135c4224e5SLoGin #[repr(align(4))]
handle_exception() -> !145c4224e5SLoGin pub unsafe extern "C" fn handle_exception() -> ! {
155c4224e5SLoGin     asm!(
165c4224e5SLoGin         concat!("
175c4224e5SLoGin         /*
185c4224e5SLoGin 	        * If coming from userspace, preserve the user thread pointer and load
195c4224e5SLoGin 	        * the kernel thread pointer.  If we came from the kernel, the scratch
205c4224e5SLoGin 	        * register will contain 0, and we should continue on the current TP.
215c4224e5SLoGin         */
225c4224e5SLoGin 
235c4224e5SLoGin             csrrw tp, {csr_scratch}, tp
245c4224e5SLoGin             bnez tp, _save_context
255c4224e5SLoGin 
265c4224e5SLoGin             /* 从内核态进入中断 */
275c4224e5SLoGin             j {_restore_kernel_tpsp}
285c4224e5SLoGin         "),
295c4224e5SLoGin         csr_scratch = const CSR_SSCRATCH,
305c4224e5SLoGin         _restore_kernel_tpsp = sym _restore_kernel_tpsp,
315c4224e5SLoGin         options(noreturn),
325c4224e5SLoGin     )
335c4224e5SLoGin }
345c4224e5SLoGin 
355c4224e5SLoGin #[naked]
365c4224e5SLoGin #[no_mangle]
_restore_kernel_tpsp() -> !375c4224e5SLoGin unsafe extern "C" fn _restore_kernel_tpsp() -> ! {
385c4224e5SLoGin     asm!(
395c4224e5SLoGin         concat!("
405c4224e5SLoGin             // 这次是从内核态进入中断
415c4224e5SLoGin             // 从sscratch寄存器加载当前cpu的上下文
425c4224e5SLoGin             csrr tp, {csr_scratch}
435c4224e5SLoGin 
445c4224e5SLoGin             // 把当前的sp寄存器的值保存到当前cpu的上下文的kernel_sp字段
455c4224e5SLoGin             sd sp, {lc_off_kernel_sp}(tp)
465c4224e5SLoGin 
475c4224e5SLoGin             j {_save_context}
485c4224e5SLoGin         "),
495c4224e5SLoGin         csr_scratch = const CSR_SSCRATCH,
505c4224e5SLoGin         lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
515c4224e5SLoGin         _save_context = sym _save_context,
525c4224e5SLoGin 
535c4224e5SLoGin         options(noreturn),
545c4224e5SLoGin     )
555c4224e5SLoGin }
565c4224e5SLoGin 
575c4224e5SLoGin #[naked]
585c4224e5SLoGin #[no_mangle]
_save_context() -> !595c4224e5SLoGin unsafe extern "C" fn _save_context() -> ! {
605c4224e5SLoGin     asm!(
615c4224e5SLoGin         concat!("
625c4224e5SLoGin 
635c4224e5SLoGin 
645c4224e5SLoGin             // 保存当前cpu的上下文
655c4224e5SLoGin 
665c4224e5SLoGin             // 保存用户sp
675c4224e5SLoGin             sd sp, {lc_off_user_sp}(tp)
685c4224e5SLoGin             // 加载内核sp
695c4224e5SLoGin             ld sp, {lc_off_kernel_sp}(tp)
705c4224e5SLoGin 
715c4224e5SLoGin             addi sp, sp, -{trap_frame_size_on_stack}
725c4224e5SLoGin             sd x1, {off_ra}(sp)
735c4224e5SLoGin             sd x3, {off_gp}(sp)
745c4224e5SLoGin             sd x5, {off_t0}(sp)
755c4224e5SLoGin         ",
765c4224e5SLoGin         save_from_x6_to_x31!(),
775c4224e5SLoGin         "
785c4224e5SLoGin         /*
795c4224e5SLoGin 	        * Disable user-mode memory access as it should only be set in the
805c4224e5SLoGin 	        * actual user copy routines.
815c4224e5SLoGin 	        *
825c4224e5SLoGin 	        * Disable the FPU/Vector to detect illegal usage of floating point
835c4224e5SLoGin 	        * or vector in kernel space.
845c4224e5SLoGin         */
855c4224e5SLoGin 
865c4224e5SLoGin         li t0, {sr_sum_and_fsvs}
875c4224e5SLoGin 
885c4224e5SLoGin         ld s0, {lc_off_user_sp}(tp)
895c4224e5SLoGin         csrrc s1, {csr_status}, t0
905c4224e5SLoGin         csrr s2, {csr_epc}
915c4224e5SLoGin         csrr s3, {csr_tval}
925c4224e5SLoGin         csrr s4, {csr_cause}
935c4224e5SLoGin         csrr s5, {csr_scratch}
945c4224e5SLoGin         sd s0, {off_sp}(sp)
955c4224e5SLoGin         sd s1, {off_status}(sp)
965c4224e5SLoGin         sd s2, {off_epc}(sp)
975c4224e5SLoGin         sd s3, {off_badaddr}(sp)
985c4224e5SLoGin         sd s4, {off_cause}(sp)
995c4224e5SLoGin         sd s5, {off_tp}(sp)
1005c4224e5SLoGin 
1015c4224e5SLoGin         /*
1025c4224e5SLoGin 	    * Set the scratch register to 0, so that if a recursive exception
1035c4224e5SLoGin 	    * occurs, the exception vector knows it came from the kernel
1045c4224e5SLoGin 	    */
1055c4224e5SLoGin 
1065c4224e5SLoGin         csrw {csr_scratch}, x0
1075c4224e5SLoGin 
1085c4224e5SLoGin         /* Load the global pointer */
1095c4224e5SLoGin         // linux 加载了global pointer,但是我们暂时没有用到
1105c4224e5SLoGin 
1115c4224e5SLoGin         // .option push
1125c4224e5SLoGin         // .option norelax
1135c4224e5SLoGin         //     la gp, __global_pointer$
1145c4224e5SLoGin         // .option pop
1155c4224e5SLoGin 
1165c4224e5SLoGin         mv a0, sp
1175c4224e5SLoGin         la ra, ret_from_exception
1185c4224e5SLoGin 
1195c4224e5SLoGin         tail riscv64_do_irq
1205c4224e5SLoGin         "
1215c4224e5SLoGin     ),
1225c4224e5SLoGin 
1235c4224e5SLoGin         lc_off_user_sp = const offset_of!(LocalContext, user_sp),
1245c4224e5SLoGin         lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
1255c4224e5SLoGin         trap_frame_size_on_stack = const TrapFrame::SIZE_ON_STACK,
1265c4224e5SLoGin         off_ra = const offset_of!(TrapFrame, ra),
1275c4224e5SLoGin         off_gp = const offset_of!(TrapFrame, gp),
1285c4224e5SLoGin         off_t0 = const offset_of!(TrapFrame, t0),
1295c4224e5SLoGin         off_t1 = const offset_of!(TrapFrame, t1),
1305c4224e5SLoGin         off_t2 = const offset_of!(TrapFrame, t2),
1315c4224e5SLoGin         off_s0 = const offset_of!(TrapFrame, s0),
1325c4224e5SLoGin         off_s1 = const offset_of!(TrapFrame, s1),
1335c4224e5SLoGin         off_a0 = const offset_of!(TrapFrame, a0),
1345c4224e5SLoGin         off_a1 = const offset_of!(TrapFrame, a1),
1355c4224e5SLoGin         off_a2 = const offset_of!(TrapFrame, a2),
1365c4224e5SLoGin         off_a3 = const offset_of!(TrapFrame, a3),
1375c4224e5SLoGin         off_a4 = const offset_of!(TrapFrame, a4),
1385c4224e5SLoGin         off_a5 = const offset_of!(TrapFrame, a5),
1395c4224e5SLoGin         off_a6 = const offset_of!(TrapFrame, a6),
1405c4224e5SLoGin         off_a7 = const offset_of!(TrapFrame, a7),
1415c4224e5SLoGin         off_s2 = const offset_of!(TrapFrame, s2),
1425c4224e5SLoGin         off_s3 = const offset_of!(TrapFrame, s3),
1435c4224e5SLoGin         off_s4 = const offset_of!(TrapFrame, s4),
1445c4224e5SLoGin         off_s5 = const offset_of!(TrapFrame, s5),
1455c4224e5SLoGin         off_s6 = const offset_of!(TrapFrame, s6),
1465c4224e5SLoGin         off_s7 = const offset_of!(TrapFrame, s7),
1475c4224e5SLoGin         off_s8 = const offset_of!(TrapFrame, s8),
1485c4224e5SLoGin         off_s9 = const offset_of!(TrapFrame, s9),
1495c4224e5SLoGin         off_s10 = const offset_of!(TrapFrame, s10),
1505c4224e5SLoGin         off_s11 = const offset_of!(TrapFrame, s11),
1515c4224e5SLoGin         off_t3 = const offset_of!(TrapFrame, t3),
1525c4224e5SLoGin         off_t4 = const offset_of!(TrapFrame, t4),
1535c4224e5SLoGin         off_t5 = const offset_of!(TrapFrame, t5),
1545c4224e5SLoGin         off_t6 = const offset_of!(TrapFrame, t6),
1555c4224e5SLoGin         off_sp = const offset_of!(TrapFrame, sp),
1565c4224e5SLoGin         off_status = const offset_of!(TrapFrame, status),
1575c4224e5SLoGin         off_badaddr = const offset_of!(TrapFrame, badaddr),
1585c4224e5SLoGin         off_cause = const offset_of!(TrapFrame, cause),
1595c4224e5SLoGin         off_tp = const offset_of!(TrapFrame, tp),
1605c4224e5SLoGin         off_epc = const offset_of!(TrapFrame, epc),
161471d65cfSLoGin         sr_sum_and_fsvs = const (0), // 暂时在内核中不禁用FPU和Vector,以及不禁用用户内存访问
162471d65cfSLoGin         // sr_sum_and_fsvs = const (SR_FS_VS | SR_SUM),
1635c4224e5SLoGin         csr_status = const CSR_SSTATUS,
1645c4224e5SLoGin         csr_epc = const CSR_SEPC,
1655c4224e5SLoGin         csr_tval = const CSR_STVAL,
1665c4224e5SLoGin         csr_cause = const CSR_SCAUSE,
1675c4224e5SLoGin         csr_scratch = const CSR_SSCRATCH,
1685c4224e5SLoGin         options(noreturn),
1695c4224e5SLoGin     )
1705c4224e5SLoGin }
1715c4224e5SLoGin 
1725c4224e5SLoGin #[naked]
1735c4224e5SLoGin #[no_mangle]
ret_from_exception() -> !174e8eab1acSLoGin pub unsafe extern "C" fn ret_from_exception() -> ! {
1755c4224e5SLoGin     asm!(
1765c4224e5SLoGin         concat!("
1775c4224e5SLoGin             ld s0, {off_status}(sp)
1785c4224e5SLoGin             andi s0, s0, {sr_spp}
1795c4224e5SLoGin 
1805c4224e5SLoGin             bnez s0, 3f
1815c4224e5SLoGin 
1825c4224e5SLoGin             // Save unwound kernel stack pointer in thread_info
1835c4224e5SLoGin             addi s0, sp, {trap_frame_size_on_stack}
1845c4224e5SLoGin             sd s0, {lc_off_kernel_sp}(tp)
1855c4224e5SLoGin 
1865c4224e5SLoGin             /*
1875c4224e5SLoGin 	        * Save TP into the scratch register , so we can find the kernel data
1885c4224e5SLoGin 	        * structures again.
1895c4224e5SLoGin 	        */
1905c4224e5SLoGin             csrw {csr_scratch}, tp
1915c4224e5SLoGin         3:
1925c4224e5SLoGin 
1935c4224e5SLoGin             ld a0, {off_status}(sp)
1945c4224e5SLoGin 
1955c4224e5SLoGin             ld a2, {off_epc}(sp)
1965c4224e5SLoGin             sc.d x0, a2, {off_epc}(sp)
1975c4224e5SLoGin 
1985c4224e5SLoGin             csrw {csr_status}, a0
1995c4224e5SLoGin             csrw {csr_epc}, a2
2005c4224e5SLoGin 
2015c4224e5SLoGin             ld x1, {off_ra}(sp)
2025c4224e5SLoGin             ld x3, {off_gp}(sp)
2035c4224e5SLoGin             ld x4, {off_tp}(sp)
2045c4224e5SLoGin             ld x5, {off_t0}(sp)
2055c4224e5SLoGin 
2065c4224e5SLoGin         ",
2075c4224e5SLoGin         restore_from_x6_to_x31!(),
2085c4224e5SLoGin         "
2095c4224e5SLoGin             ld x2, {off_sp}(sp)
2105c4224e5SLoGin 
2115c4224e5SLoGin             sret
2125c4224e5SLoGin         "
2135c4224e5SLoGin         ),
2145c4224e5SLoGin         off_status = const offset_of!(TrapFrame, status),
2155c4224e5SLoGin         sr_spp = const SR_SPP,
2165c4224e5SLoGin         trap_frame_size_on_stack = const TrapFrame::SIZE_ON_STACK,
2175c4224e5SLoGin         lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
2185c4224e5SLoGin         csr_scratch = const CSR_SSCRATCH,
2195c4224e5SLoGin         csr_status = const CSR_SSTATUS,
2205c4224e5SLoGin         csr_epc = const CSR_SEPC,
2215c4224e5SLoGin         off_ra = const offset_of!(TrapFrame, ra),
2225c4224e5SLoGin         off_gp = const offset_of!(TrapFrame, gp),
2235c4224e5SLoGin         off_t0 = const offset_of!(TrapFrame, t0),
2245c4224e5SLoGin         off_t1 = const offset_of!(TrapFrame, t1),
2255c4224e5SLoGin         off_t2 = const offset_of!(TrapFrame, t2),
2265c4224e5SLoGin         off_s0 = const offset_of!(TrapFrame, s0),
2275c4224e5SLoGin         off_s1 = const offset_of!(TrapFrame, s1),
2285c4224e5SLoGin         off_a0 = const offset_of!(TrapFrame, a0),
2295c4224e5SLoGin         off_a1 = const offset_of!(TrapFrame, a1),
2305c4224e5SLoGin         off_a2 = const offset_of!(TrapFrame, a2),
2315c4224e5SLoGin         off_a3 = const offset_of!(TrapFrame, a3),
2325c4224e5SLoGin         off_a4 = const offset_of!(TrapFrame, a4),
2335c4224e5SLoGin         off_a5 = const offset_of!(TrapFrame, a5),
2345c4224e5SLoGin         off_a6 = const offset_of!(TrapFrame, a6),
2355c4224e5SLoGin         off_a7 = const offset_of!(TrapFrame, a7),
2365c4224e5SLoGin         off_s2 = const offset_of!(TrapFrame, s2),
2375c4224e5SLoGin         off_s3 = const offset_of!(TrapFrame, s3),
2385c4224e5SLoGin         off_s4 = const offset_of!(TrapFrame, s4),
2395c4224e5SLoGin         off_s5 = const offset_of!(TrapFrame, s5),
2405c4224e5SLoGin         off_s6 = const offset_of!(TrapFrame, s6),
2415c4224e5SLoGin         off_s7 = const offset_of!(TrapFrame, s7),
2425c4224e5SLoGin         off_s8 = const offset_of!(TrapFrame, s8),
2435c4224e5SLoGin         off_s9 = const offset_of!(TrapFrame, s9),
2445c4224e5SLoGin         off_s10 = const offset_of!(TrapFrame, s10),
2455c4224e5SLoGin         off_s11 = const offset_of!(TrapFrame, s11),
2465c4224e5SLoGin         off_t3 = const offset_of!(TrapFrame, t3),
2475c4224e5SLoGin         off_t4 = const offset_of!(TrapFrame, t4),
2485c4224e5SLoGin         off_t5 = const offset_of!(TrapFrame, t5),
2495c4224e5SLoGin         off_t6 = const offset_of!(TrapFrame, t6),
2505c4224e5SLoGin         off_sp = const offset_of!(TrapFrame, sp),
2515c4224e5SLoGin         off_tp = const offset_of!(TrapFrame, tp),
2525c4224e5SLoGin         off_epc = const offset_of!(TrapFrame, epc),
2535c4224e5SLoGin 
2545c4224e5SLoGin         options(noreturn),
2555c4224e5SLoGin     )
2565c4224e5SLoGin }
257