xref: /DragonOS/kernel/src/arch/riscv64/interrupt/handle.rs (revision 7b0ef10895108a0de5ff5ef3d2f93f40cf2e33a5)
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