1 //! 处理中断和异常 2 //! 3 //! 架构相关的处理逻辑参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/traps.c 4 use core::hint::spin_loop; 5 6 use log::{error, trace}; 7 use system_error::SystemError; 8 9 use super::TrapFrame; 10 use crate::exception::ebreak::EBreak; 11 use crate::{arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq}; 12 13 type ExceptionHandler = fn(&mut TrapFrame) -> Result<(), SystemError>; 14 15 static EXCEPTION_HANDLERS: [ExceptionHandler; 16] = [ 16 do_trap_insn_misaligned, // 0 17 do_trap_insn_access_fault, // 1 18 do_trap_insn_illegal, // 2 19 do_trap_break, // 3 20 do_trap_load_misaligned, // 4 21 do_trap_load_access_fault, // 5 22 do_trap_store_misaligned, // 6 23 do_trap_store_access_fault, // 7 24 do_trap_user_env_call, // 8 25 default_handler, // 9 26 default_handler, // 10 27 default_handler, // 11 28 do_trap_insn_page_fault, // 12 29 do_trap_load_page_fault, // 13 30 default_handler, // 14 31 do_trap_store_page_fault, // 15 32 ]; 33 34 #[no_mangle] 35 unsafe extern "C" fn riscv64_do_irq(trap_frame: &mut TrapFrame) { 36 if trap_frame.cause.is_interrupt() { 37 riscv64_do_interrupt(trap_frame); 38 } else if trap_frame.cause.is_exception() { 39 riscv64_do_exception(trap_frame); 40 } 41 } 42 43 /// 处理中断 44 fn riscv64_do_interrupt(trap_frame: &mut TrapFrame) { 45 riscv_intc_irq(trap_frame); 46 } 47 48 /// 处理异常 49 fn riscv64_do_exception(trap_frame: &mut TrapFrame) { 50 let code = trap_frame.cause.code(); 51 52 if code < EXCEPTION_HANDLERS.len() { 53 let handler = EXCEPTION_HANDLERS[code]; 54 handler(trap_frame).ok(); 55 } else { 56 error!("riscv64_do_irq: exception code out of range"); 57 loop { 58 // kernel die 59 spin_loop(); 60 } 61 }; 62 } 63 64 fn default_handler(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 65 error!("riscv64_do_irq: handler not found"); 66 loop { 67 spin_loop(); 68 } 69 } 70 71 /// 处理指令地址不对齐异常 #0 72 fn do_trap_insn_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 73 error!("riscv64_do_irq: do_trap_insn_misaligned"); 74 loop { 75 spin_loop(); 76 } 77 } 78 79 /// 处理指令访问异常 #1 80 fn do_trap_insn_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 81 error!("riscv64_do_irq: do_trap_insn_access_fault"); 82 loop { 83 spin_loop(); 84 } 85 } 86 87 /// 处理非法指令异常 #2 88 fn do_trap_insn_illegal(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 89 error!("riscv64_do_irq: do_trap_insn_illegal"); 90 loop { 91 spin_loop(); 92 } 93 } 94 95 /// 处理断点异常 #3 96 fn do_trap_break(trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 97 trace!("riscv64_do_irq: do_trap_break"); 98 // handle breakpoint 99 EBreak::handle(trap_frame) 100 } 101 102 /// 处理加载地址不对齐异常 #4 103 fn do_trap_load_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 104 error!("riscv64_do_irq: do_trap_load_misaligned"); 105 loop { 106 spin_loop(); 107 } 108 } 109 110 /// 处理加载访问异常 #5 111 fn do_trap_load_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 112 error!("riscv64_do_irq: do_trap_load_access_fault"); 113 loop { 114 spin_loop(); 115 } 116 } 117 118 /// 处理存储地址不对齐异常 #6 119 fn do_trap_store_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 120 error!("riscv64_do_irq: do_trap_store_misaligned"); 121 loop { 122 spin_loop(); 123 } 124 } 125 126 /// 处理存储访问异常 #7 127 fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 128 error!("riscv64_do_irq: do_trap_store_access_fault"); 129 loop { 130 spin_loop(); 131 } 132 } 133 134 /// 处理环境调用异常 #8 135 fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 136 if trap_frame.is_from_user() { 137 let syscall_num = trap_frame.a7; 138 trap_frame.epc += 4; 139 trap_frame.origin_a0 = trap_frame.a0; 140 syscall_handler(syscall_num, trap_frame); 141 } else { 142 panic!("do_trap_user_env_call: not from user mode") 143 } 144 Ok(()) 145 } 146 147 // 9-11 reserved 148 149 /// 处理指令页错误异常 #12 150 fn do_trap_insn_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 151 let vaddr = trap_frame.badaddr; 152 let cause = trap_frame.cause; 153 let epc = trap_frame.epc; 154 error!( 155 "riscv64_do_irq: do_insn_page_fault vaddr: {:#x}, cause: {:?} epc: {:#x}", 156 vaddr, cause, epc 157 ); 158 loop { 159 spin_loop(); 160 } 161 } 162 163 /// 处理页加载错误异常 #13 164 fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 165 let vaddr = trap_frame.badaddr; 166 let cause = trap_frame.cause; 167 let epc = trap_frame.epc; 168 error!( 169 "riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}", 170 vaddr, cause 171 ); 172 173 loop { 174 spin_loop(); 175 } 176 } 177 178 // 14 reserved 179 180 /// 处理页存储错误异常 #15 181 fn do_trap_store_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 182 error!( 183 "riscv64_do_irq: do_trap_store_page_fault: epc: {:#x}, vaddr={:#x}, cause={:?}", 184 trap_frame.epc, trap_frame.badaddr, trap_frame.cause 185 ); 186 loop { 187 spin_loop(); 188 } 189 } 190