xref: /DragonOS/kernel/src/arch/riscv64/interrupt/handle.rs (revision 03746da3d9f3ea616cecdb6e581414002075f866)
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;
7 use system_error::SystemError;
8 
9 use crate::{arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq};
10 
11 use super::TrapFrame;
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     error!("riscv64_do_irq: do_trap_break");
98     loop {
99         spin_loop();
100     }
101 }
102 
103 /// 处理加载地址不对齐异常 #4
104 fn do_trap_load_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
105     error!("riscv64_do_irq: do_trap_load_misaligned");
106     loop {
107         spin_loop();
108     }
109 }
110 
111 /// 处理加载访问异常 #5
112 fn do_trap_load_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
113     error!("riscv64_do_irq: do_trap_load_access_fault");
114     loop {
115         spin_loop();
116     }
117 }
118 
119 /// 处理存储地址不对齐异常 #6
120 fn do_trap_store_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
121     error!("riscv64_do_irq: do_trap_store_misaligned");
122     loop {
123         spin_loop();
124     }
125 }
126 
127 /// 处理存储访问异常 #7
128 fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
129     error!("riscv64_do_irq: do_trap_store_access_fault");
130     loop {
131         spin_loop();
132     }
133 }
134 
135 /// 处理环境调用异常 #8
136 fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
137     if trap_frame.is_from_user() {
138         let syscall_num = trap_frame.a7;
139         trap_frame.epc += 4;
140         trap_frame.origin_a0 = trap_frame.a0;
141         syscall_handler(syscall_num, trap_frame);
142     } else {
143         panic!("do_trap_user_env_call: not from user mode")
144     }
145     Ok(())
146 }
147 
148 // 9-11 reserved
149 
150 /// 处理指令页错误异常 #12
151 fn do_trap_insn_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
152     let vaddr = trap_frame.badaddr;
153     let cause = trap_frame.cause;
154     let epc = trap_frame.epc;
155     error!(
156         "riscv64_do_irq: do_insn_page_fault vaddr: {:#x}, cause: {:?} epc: {:#x}",
157         vaddr, cause, epc
158     );
159     loop {
160         spin_loop();
161     }
162 }
163 
164 /// 处理页加载错误异常 #13
165 fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
166     let vaddr = trap_frame.badaddr;
167     let cause = trap_frame.cause;
168     let epc = trap_frame.epc;
169     error!(
170         "riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}",
171         vaddr, cause
172     );
173 
174     loop {
175         spin_loop();
176     }
177 }
178 
179 // 14 reserved
180 
181 /// 处理页存储错误异常 #15
182 fn do_trap_store_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
183     error!(
184         "riscv64_do_irq: do_trap_store_page_fault: epc: {:#x}, vaddr={:#x}, cause={:?}",
185         trap_frame.epc, trap_frame.badaddr, trap_frame.cause
186     );
187     loop {
188         spin_loop();
189     }
190 }
191