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