xref: /DragonOS/kernel/src/arch/riscv64/interrupt/handle.rs (revision 23ef2b33d1e3cfd2506eb7449a33df4ec42f11d3)
1*23ef2b33SLoGin //! 处理中断和异常
2*23ef2b33SLoGin //!
3*23ef2b33SLoGin //! 架构相关的处理逻辑参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/traps.c
45c4224e5SLoGin use core::hint::spin_loop;
55c4224e5SLoGin 
65c4224e5SLoGin use system_error::SystemError;
75c4224e5SLoGin 
8*23ef2b33SLoGin use crate::{arch::syscall::syscall_handler, kdebug, kerror};
95c4224e5SLoGin 
105c4224e5SLoGin use super::TrapFrame;
115c4224e5SLoGin 
125c4224e5SLoGin type ExceptionHandler = fn(&mut TrapFrame) -> Result<(), SystemError>;
135c4224e5SLoGin 
145c4224e5SLoGin static EXCEPTION_HANDLERS: [ExceptionHandler; 16] = [
155c4224e5SLoGin     do_trap_insn_misaligned,    // 0
165c4224e5SLoGin     do_trap_insn_access_fault,  // 1
175c4224e5SLoGin     do_trap_insn_illegal,       // 2
185c4224e5SLoGin     do_trap_break,              // 3
195c4224e5SLoGin     do_trap_load_misaligned,    // 4
205c4224e5SLoGin     do_trap_load_access_fault,  // 5
215c4224e5SLoGin     do_trap_store_misaligned,   // 6
225c4224e5SLoGin     do_trap_store_access_fault, // 7
235c4224e5SLoGin     do_trap_user_env_call,      // 8
245c4224e5SLoGin     default_handler,            // 9
255c4224e5SLoGin     default_handler,            // 10
265c4224e5SLoGin     default_handler,            // 11
275c4224e5SLoGin     do_trap_insn_page_fault,    // 12
285c4224e5SLoGin     do_trap_load_page_fault,    // 13
295c4224e5SLoGin     default_handler,            // 14
305c4224e5SLoGin     do_trap_store_page_fault,   // 15
315c4224e5SLoGin ];
325c4224e5SLoGin 
335c4224e5SLoGin #[no_mangle]
345c4224e5SLoGin unsafe extern "C" fn riscv64_do_irq(trap_frame: &mut TrapFrame) {
355c4224e5SLoGin     if trap_frame.cause.is_interrupt() {
365c4224e5SLoGin         riscv64_do_interrupt(trap_frame);
375c4224e5SLoGin     } else if trap_frame.cause.is_exception() {
385c4224e5SLoGin         riscv64_do_exception(trap_frame);
395c4224e5SLoGin     }
405c4224e5SLoGin }
415c4224e5SLoGin 
425c4224e5SLoGin /// 处理中断
435c4224e5SLoGin fn riscv64_do_interrupt(_trap_frame: &mut TrapFrame) {
445c4224e5SLoGin     kdebug!("todo: riscv64_do_irq: interrupt");
455c4224e5SLoGin     loop {
465c4224e5SLoGin         spin_loop();
475c4224e5SLoGin     }
485c4224e5SLoGin }
495c4224e5SLoGin 
505c4224e5SLoGin /// 处理异常
515c4224e5SLoGin fn riscv64_do_exception(trap_frame: &mut TrapFrame) {
525c4224e5SLoGin     kdebug!(
535c4224e5SLoGin         "riscv64_do_exception: from_user: {}",
54b5b571e0SLoGin         trap_frame.is_from_user()
555c4224e5SLoGin     );
565c4224e5SLoGin     let code = trap_frame.cause.code();
575c4224e5SLoGin 
585c4224e5SLoGin     if code < EXCEPTION_HANDLERS.len() {
595c4224e5SLoGin         let handler = EXCEPTION_HANDLERS[code];
605c4224e5SLoGin         handler(trap_frame).ok();
615c4224e5SLoGin     } else {
625c4224e5SLoGin         kerror!("riscv64_do_irq: exception code out of range");
635c4224e5SLoGin         loop {
645c4224e5SLoGin             // kernel die
655c4224e5SLoGin             spin_loop();
665c4224e5SLoGin         }
675c4224e5SLoGin     };
685c4224e5SLoGin }
695c4224e5SLoGin 
705c4224e5SLoGin fn default_handler(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
715c4224e5SLoGin     kerror!("riscv64_do_irq: handler not found");
725c4224e5SLoGin     loop {
735c4224e5SLoGin         spin_loop();
745c4224e5SLoGin     }
755c4224e5SLoGin }
765c4224e5SLoGin 
775c4224e5SLoGin /// 处理指令地址不对齐异常 #0
785c4224e5SLoGin fn do_trap_insn_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
795c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_insn_misaligned");
805c4224e5SLoGin     loop {
815c4224e5SLoGin         spin_loop();
825c4224e5SLoGin     }
835c4224e5SLoGin }
845c4224e5SLoGin 
855c4224e5SLoGin /// 处理指令访问异常 #1
865c4224e5SLoGin fn do_trap_insn_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
875c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_insn_access_fault");
885c4224e5SLoGin     loop {
895c4224e5SLoGin         spin_loop();
905c4224e5SLoGin     }
915c4224e5SLoGin }
925c4224e5SLoGin 
935c4224e5SLoGin /// 处理非法指令异常 #2
945c4224e5SLoGin fn do_trap_insn_illegal(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
955c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_insn_illegal");
965c4224e5SLoGin     loop {
975c4224e5SLoGin         spin_loop();
985c4224e5SLoGin     }
995c4224e5SLoGin }
1005c4224e5SLoGin 
1015c4224e5SLoGin /// 处理断点异常 #3
1025c4224e5SLoGin fn do_trap_break(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
1035c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_break");
1045c4224e5SLoGin     loop {
1055c4224e5SLoGin         spin_loop();
1065c4224e5SLoGin     }
1075c4224e5SLoGin }
1085c4224e5SLoGin 
1095c4224e5SLoGin /// 处理加载地址不对齐异常 #4
1105c4224e5SLoGin fn do_trap_load_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
1115c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_load_misaligned");
1125c4224e5SLoGin     loop {
1135c4224e5SLoGin         spin_loop();
1145c4224e5SLoGin     }
1155c4224e5SLoGin }
1165c4224e5SLoGin 
1175c4224e5SLoGin /// 处理加载访问异常 #5
1185c4224e5SLoGin fn do_trap_load_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
1195c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_load_access_fault");
1205c4224e5SLoGin     loop {
1215c4224e5SLoGin         spin_loop();
1225c4224e5SLoGin     }
1235c4224e5SLoGin }
1245c4224e5SLoGin 
1255c4224e5SLoGin /// 处理存储地址不对齐异常 #6
1265c4224e5SLoGin fn do_trap_store_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
1275c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_store_misaligned");
1285c4224e5SLoGin     loop {
1295c4224e5SLoGin         spin_loop();
1305c4224e5SLoGin     }
1315c4224e5SLoGin }
1325c4224e5SLoGin 
1335c4224e5SLoGin /// 处理存储访问异常 #7
1345c4224e5SLoGin fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
1355c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_store_access_fault");
1365c4224e5SLoGin     loop {
1375c4224e5SLoGin         spin_loop();
1385c4224e5SLoGin     }
1395c4224e5SLoGin }
1405c4224e5SLoGin 
1415c4224e5SLoGin /// 处理环境调用异常 #8
142*23ef2b33SLoGin fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
143*23ef2b33SLoGin     if trap_frame.is_from_user() {
144*23ef2b33SLoGin         let syscall_num = trap_frame.a7;
145*23ef2b33SLoGin         trap_frame.epc += 4;
146*23ef2b33SLoGin         trap_frame.origin_a0 = trap_frame.a0;
147*23ef2b33SLoGin         syscall_handler(syscall_num, trap_frame);
148*23ef2b33SLoGin     } else {
149*23ef2b33SLoGin         panic!("do_trap_user_env_call: not from user mode")
1505c4224e5SLoGin     }
151*23ef2b33SLoGin     Ok(())
1525c4224e5SLoGin }
1535c4224e5SLoGin 
1545c4224e5SLoGin // 9-11 reserved
1555c4224e5SLoGin 
1565c4224e5SLoGin /// 处理指令页错误异常 #12
1575c4224e5SLoGin fn do_trap_insn_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
1585c4224e5SLoGin     kerror!("riscv64_do_irq: do_insn_page_fault");
1595c4224e5SLoGin     loop {
1605c4224e5SLoGin         spin_loop();
1615c4224e5SLoGin     }
1625c4224e5SLoGin }
1635c4224e5SLoGin 
1645c4224e5SLoGin /// 处理页加载错误异常 #13
165*23ef2b33SLoGin fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
166*23ef2b33SLoGin     let vaddr = trap_frame.badaddr;
167*23ef2b33SLoGin     let cause = trap_frame.cause;
168*23ef2b33SLoGin     let epc = trap_frame.epc;
169*23ef2b33SLoGin     kerror!(
170*23ef2b33SLoGin         "riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}",
171*23ef2b33SLoGin         vaddr,
172*23ef2b33SLoGin         cause
173*23ef2b33SLoGin     );
174*23ef2b33SLoGin 
1755c4224e5SLoGin     loop {
1765c4224e5SLoGin         spin_loop();
1775c4224e5SLoGin     }
1785c4224e5SLoGin }
1795c4224e5SLoGin 
1805c4224e5SLoGin // 14 reserved
1815c4224e5SLoGin 
1825c4224e5SLoGin /// 处理页存储错误异常 #15
1835c4224e5SLoGin fn do_trap_store_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
1845c4224e5SLoGin     kerror!("riscv64_do_irq: do_trap_store_page_fault");
1855c4224e5SLoGin     loop {
1865c4224e5SLoGin         spin_loop();
1875c4224e5SLoGin     }
1885c4224e5SLoGin }
189