xref: /DragonOS/kernel/src/arch/riscv64/interrupt/handle.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
123ef2b33SLoGin //! 处理中断和异常
223ef2b33SLoGin //!
323ef2b33SLoGin //! 架构相关的处理逻辑参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/traps.c
45c4224e5SLoGin use core::hint::spin_loop;
55c4224e5SLoGin 
6*2eab6dd7S曾俊 use log::error;
75c4224e5SLoGin use system_error::SystemError;
85c4224e5SLoGin 
9*2eab6dd7S曾俊 use crate::{arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq};
105c4224e5SLoGin 
115c4224e5SLoGin use super::TrapFrame;
125c4224e5SLoGin 
135c4224e5SLoGin type ExceptionHandler = fn(&mut TrapFrame) -> Result<(), SystemError>;
145c4224e5SLoGin 
155c4224e5SLoGin static EXCEPTION_HANDLERS: [ExceptionHandler; 16] = [
165c4224e5SLoGin     do_trap_insn_misaligned,    // 0
175c4224e5SLoGin     do_trap_insn_access_fault,  // 1
185c4224e5SLoGin     do_trap_insn_illegal,       // 2
195c4224e5SLoGin     do_trap_break,              // 3
205c4224e5SLoGin     do_trap_load_misaligned,    // 4
215c4224e5SLoGin     do_trap_load_access_fault,  // 5
225c4224e5SLoGin     do_trap_store_misaligned,   // 6
235c4224e5SLoGin     do_trap_store_access_fault, // 7
245c4224e5SLoGin     do_trap_user_env_call,      // 8
255c4224e5SLoGin     default_handler,            // 9
265c4224e5SLoGin     default_handler,            // 10
275c4224e5SLoGin     default_handler,            // 11
285c4224e5SLoGin     do_trap_insn_page_fault,    // 12
295c4224e5SLoGin     do_trap_load_page_fault,    // 13
305c4224e5SLoGin     default_handler,            // 14
315c4224e5SLoGin     do_trap_store_page_fault,   // 15
325c4224e5SLoGin ];
335c4224e5SLoGin 
345c4224e5SLoGin #[no_mangle]
riscv64_do_irq(trap_frame: &mut TrapFrame)355c4224e5SLoGin unsafe extern "C" fn riscv64_do_irq(trap_frame: &mut TrapFrame) {
365c4224e5SLoGin     if trap_frame.cause.is_interrupt() {
375c4224e5SLoGin         riscv64_do_interrupt(trap_frame);
385c4224e5SLoGin     } else if trap_frame.cause.is_exception() {
395c4224e5SLoGin         riscv64_do_exception(trap_frame);
405c4224e5SLoGin     }
415c4224e5SLoGin }
425c4224e5SLoGin 
435c4224e5SLoGin /// 处理中断
riscv64_do_interrupt(trap_frame: &mut TrapFrame)44f049d1afSLoGin fn riscv64_do_interrupt(trap_frame: &mut TrapFrame) {
45f049d1afSLoGin     riscv_intc_irq(trap_frame);
465c4224e5SLoGin }
475c4224e5SLoGin 
485c4224e5SLoGin /// 处理异常
riscv64_do_exception(trap_frame: &mut TrapFrame)495c4224e5SLoGin fn riscv64_do_exception(trap_frame: &mut TrapFrame) {
505c4224e5SLoGin     let code = trap_frame.cause.code();
515c4224e5SLoGin 
525c4224e5SLoGin     if code < EXCEPTION_HANDLERS.len() {
535c4224e5SLoGin         let handler = EXCEPTION_HANDLERS[code];
545c4224e5SLoGin         handler(trap_frame).ok();
555c4224e5SLoGin     } else {
56*2eab6dd7S曾俊         error!("riscv64_do_irq: exception code out of range");
575c4224e5SLoGin         loop {
585c4224e5SLoGin             // kernel die
595c4224e5SLoGin             spin_loop();
605c4224e5SLoGin         }
615c4224e5SLoGin     };
625c4224e5SLoGin }
635c4224e5SLoGin 
default_handler(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>645c4224e5SLoGin fn default_handler(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
65*2eab6dd7S曾俊     error!("riscv64_do_irq: handler not found");
665c4224e5SLoGin     loop {
675c4224e5SLoGin         spin_loop();
685c4224e5SLoGin     }
695c4224e5SLoGin }
705c4224e5SLoGin 
715c4224e5SLoGin /// 处理指令地址不对齐异常 #0
do_trap_insn_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>725c4224e5SLoGin fn do_trap_insn_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
73*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_insn_misaligned");
745c4224e5SLoGin     loop {
755c4224e5SLoGin         spin_loop();
765c4224e5SLoGin     }
775c4224e5SLoGin }
785c4224e5SLoGin 
795c4224e5SLoGin /// 处理指令访问异常 #1
do_trap_insn_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>805c4224e5SLoGin fn do_trap_insn_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
81*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_insn_access_fault");
825c4224e5SLoGin     loop {
835c4224e5SLoGin         spin_loop();
845c4224e5SLoGin     }
855c4224e5SLoGin }
865c4224e5SLoGin 
875c4224e5SLoGin /// 处理非法指令异常 #2
do_trap_insn_illegal(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>885c4224e5SLoGin fn do_trap_insn_illegal(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
89*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_insn_illegal");
905c4224e5SLoGin     loop {
915c4224e5SLoGin         spin_loop();
925c4224e5SLoGin     }
935c4224e5SLoGin }
945c4224e5SLoGin 
955c4224e5SLoGin /// 处理断点异常 #3
do_trap_break(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>965c4224e5SLoGin fn do_trap_break(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
97*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_break");
985c4224e5SLoGin     loop {
995c4224e5SLoGin         spin_loop();
1005c4224e5SLoGin     }
1015c4224e5SLoGin }
1025c4224e5SLoGin 
1035c4224e5SLoGin /// 处理加载地址不对齐异常 #4
do_trap_load_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>1045c4224e5SLoGin fn do_trap_load_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
105*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_load_misaligned");
1065c4224e5SLoGin     loop {
1075c4224e5SLoGin         spin_loop();
1085c4224e5SLoGin     }
1095c4224e5SLoGin }
1105c4224e5SLoGin 
1115c4224e5SLoGin /// 处理加载访问异常 #5
do_trap_load_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>1125c4224e5SLoGin fn do_trap_load_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
113*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_load_access_fault");
1145c4224e5SLoGin     loop {
1155c4224e5SLoGin         spin_loop();
1165c4224e5SLoGin     }
1175c4224e5SLoGin }
1185c4224e5SLoGin 
1195c4224e5SLoGin /// 处理存储地址不对齐异常 #6
do_trap_store_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>1205c4224e5SLoGin fn do_trap_store_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
121*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_store_misaligned");
1225c4224e5SLoGin     loop {
1235c4224e5SLoGin         spin_loop();
1245c4224e5SLoGin     }
1255c4224e5SLoGin }
1265c4224e5SLoGin 
1275c4224e5SLoGin /// 处理存储访问异常 #7
do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError>1285c4224e5SLoGin fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
129*2eab6dd7S曾俊     error!("riscv64_do_irq: do_trap_store_access_fault");
1305c4224e5SLoGin     loop {
1315c4224e5SLoGin         spin_loop();
1325c4224e5SLoGin     }
1335c4224e5SLoGin }
1345c4224e5SLoGin 
1355c4224e5SLoGin /// 处理环境调用异常 #8
do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError>13623ef2b33SLoGin fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
13723ef2b33SLoGin     if trap_frame.is_from_user() {
13823ef2b33SLoGin         let syscall_num = trap_frame.a7;
13923ef2b33SLoGin         trap_frame.epc += 4;
14023ef2b33SLoGin         trap_frame.origin_a0 = trap_frame.a0;
14123ef2b33SLoGin         syscall_handler(syscall_num, trap_frame);
14223ef2b33SLoGin     } else {
14323ef2b33SLoGin         panic!("do_trap_user_env_call: not from user mode")
1445c4224e5SLoGin     }
14523ef2b33SLoGin     Ok(())
1465c4224e5SLoGin }
1475c4224e5SLoGin 
1485c4224e5SLoGin // 9-11 reserved
1495c4224e5SLoGin 
1505c4224e5SLoGin /// 处理指令页错误异常 #12
do_trap_insn_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError>151471d65cfSLoGin fn do_trap_insn_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
152471d65cfSLoGin     let vaddr = trap_frame.badaddr;
153471d65cfSLoGin     let cause = trap_frame.cause;
154471d65cfSLoGin     let epc = trap_frame.epc;
155*2eab6dd7S曾俊     error!(
156471d65cfSLoGin         "riscv64_do_irq: do_insn_page_fault vaddr: {:#x}, cause: {:?} epc: {:#x}",
157*2eab6dd7S曾俊         vaddr, cause, epc
158471d65cfSLoGin     );
1595c4224e5SLoGin     loop {
1605c4224e5SLoGin         spin_loop();
1615c4224e5SLoGin     }
1625c4224e5SLoGin }
1635c4224e5SLoGin 
1645c4224e5SLoGin /// 处理页加载错误异常 #13
do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError>16523ef2b33SLoGin fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
16623ef2b33SLoGin     let vaddr = trap_frame.badaddr;
16723ef2b33SLoGin     let cause = trap_frame.cause;
16823ef2b33SLoGin     let epc = trap_frame.epc;
169*2eab6dd7S曾俊     error!(
17023ef2b33SLoGin         "riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}",
171*2eab6dd7S曾俊         vaddr, cause
17223ef2b33SLoGin     );
17323ef2b33SLoGin 
1745c4224e5SLoGin     loop {
1755c4224e5SLoGin         spin_loop();
1765c4224e5SLoGin     }
1775c4224e5SLoGin }
1785c4224e5SLoGin 
1795c4224e5SLoGin // 14 reserved
1805c4224e5SLoGin 
1815c4224e5SLoGin /// 处理页存储错误异常 #15
do_trap_store_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError>182471d65cfSLoGin fn do_trap_store_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
183*2eab6dd7S曾俊     error!(
184471d65cfSLoGin         "riscv64_do_irq: do_trap_store_page_fault: epc: {:#x}, vaddr={:#x}, cause={:?}",
185*2eab6dd7S曾俊         trap_frame.epc, trap_frame.badaddr, trap_frame.cause
186471d65cfSLoGin     );
1875c4224e5SLoGin     loop {
1885c4224e5SLoGin         spin_loop();
1895c4224e5SLoGin     }
1905c4224e5SLoGin }
191