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