xref: /DragonOS/kernel/src/arch/riscv64/interrupt/handle.rs (revision f049d1af01da7b92f312245ed411b22475b76065)
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 
65c4224e5SLoGin use system_error::SystemError;
75c4224e5SLoGin 
8*f049d1afSLoGin use crate::{
9*f049d1afSLoGin     arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq,
10*f049d1afSLoGin     exception::HardwareIrqNumber, kdebug, kerror,
11*f049d1afSLoGin };
125c4224e5SLoGin 
135c4224e5SLoGin use super::TrapFrame;
145c4224e5SLoGin 
155c4224e5SLoGin type ExceptionHandler = fn(&mut TrapFrame) -> Result<(), SystemError>;
165c4224e5SLoGin 
175c4224e5SLoGin static EXCEPTION_HANDLERS: [ExceptionHandler; 16] = [
185c4224e5SLoGin     do_trap_insn_misaligned,    // 0
195c4224e5SLoGin     do_trap_insn_access_fault,  // 1
205c4224e5SLoGin     do_trap_insn_illegal,       // 2
215c4224e5SLoGin     do_trap_break,              // 3
225c4224e5SLoGin     do_trap_load_misaligned,    // 4
235c4224e5SLoGin     do_trap_load_access_fault,  // 5
245c4224e5SLoGin     do_trap_store_misaligned,   // 6
255c4224e5SLoGin     do_trap_store_access_fault, // 7
265c4224e5SLoGin     do_trap_user_env_call,      // 8
275c4224e5SLoGin     default_handler,            // 9
285c4224e5SLoGin     default_handler,            // 10
295c4224e5SLoGin     default_handler,            // 11
305c4224e5SLoGin     do_trap_insn_page_fault,    // 12
315c4224e5SLoGin     do_trap_load_page_fault,    // 13
325c4224e5SLoGin     default_handler,            // 14
335c4224e5SLoGin     do_trap_store_page_fault,   // 15
345c4224e5SLoGin ];
355c4224e5SLoGin 
365c4224e5SLoGin #[no_mangle]
375c4224e5SLoGin unsafe extern "C" fn riscv64_do_irq(trap_frame: &mut TrapFrame) {
385c4224e5SLoGin     if trap_frame.cause.is_interrupt() {
395c4224e5SLoGin         riscv64_do_interrupt(trap_frame);
405c4224e5SLoGin     } else if trap_frame.cause.is_exception() {
415c4224e5SLoGin         riscv64_do_exception(trap_frame);
425c4224e5SLoGin     }
435c4224e5SLoGin }
445c4224e5SLoGin 
455c4224e5SLoGin /// 处理中断
46*f049d1afSLoGin fn riscv64_do_interrupt(trap_frame: &mut TrapFrame) {
47*f049d1afSLoGin     riscv_intc_irq(trap_frame);
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
14223ef2b33SLoGin fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
14323ef2b33SLoGin     if trap_frame.is_from_user() {
14423ef2b33SLoGin         let syscall_num = trap_frame.a7;
14523ef2b33SLoGin         trap_frame.epc += 4;
14623ef2b33SLoGin         trap_frame.origin_a0 = trap_frame.a0;
14723ef2b33SLoGin         syscall_handler(syscall_num, trap_frame);
14823ef2b33SLoGin     } else {
14923ef2b33SLoGin         panic!("do_trap_user_env_call: not from user mode")
1505c4224e5SLoGin     }
15123ef2b33SLoGin     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
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;
16923ef2b33SLoGin     kerror!(
17023ef2b33SLoGin         "riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}",
17123ef2b33SLoGin         vaddr,
17223ef2b33SLoGin         cause
17323ef2b33SLoGin     );
17423ef2b33SLoGin 
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