xref: /DragonOS/kernel/src/arch/x86_64/interrupt/trap.rs (revision 4b0170bd6bb374d0e9699a0076cc23b976ad6db7)
1 use system_error::SystemError;
2 
3 use crate::{
4     arch::CurrentIrqArch, exception::InterruptArch, kerror, kwarn, mm::VirtAddr, print,
5     process::ProcessManager, smp::core::smp_get_processor_id,
6 };
7 
8 use super::{
9     entry::{set_intr_gate, set_system_trap_gate},
10     TrapFrame,
11 };
12 
13 extern "C" {
14     fn trap_divide_error();
15     fn trap_debug();
16     fn trap_nmi();
17     fn trap_int3();
18     fn trap_overflow();
19     fn trap_bounds();
20     fn trap_undefined_opcode();
21     fn trap_dev_not_avaliable();
22     fn trap_double_fault();
23     fn trap_coprocessor_segment_overrun();
24     fn trap_invalid_TSS();
25     fn trap_segment_not_exists();
26     fn trap_stack_segment_fault();
27     fn trap_general_protection();
28     fn trap_page_fault();
29     fn trap_x87_FPU_error();
30     fn trap_alignment_check();
31     fn trap_machine_check();
32     fn trap_SIMD_exception();
33     fn trap_virtualization_exception();
34 }
35 
36 #[inline(never)]
37 pub fn arch_trap_init() -> Result<(), SystemError> {
38     unsafe {
39         set_intr_gate(0, 0, VirtAddr::new(trap_divide_error as usize));
40         set_intr_gate(1, 0, VirtAddr::new(trap_debug as usize));
41         set_intr_gate(2, 0, VirtAddr::new(trap_nmi as usize));
42         set_system_trap_gate(3, 0, VirtAddr::new(trap_int3 as usize));
43         set_system_trap_gate(4, 0, VirtAddr::new(trap_overflow as usize));
44         set_system_trap_gate(5, 0, VirtAddr::new(trap_bounds as usize));
45         set_intr_gate(6, 0, VirtAddr::new(trap_undefined_opcode as usize));
46         set_intr_gate(7, 0, VirtAddr::new(trap_dev_not_avaliable as usize));
47         set_intr_gate(8, 0, VirtAddr::new(trap_double_fault as usize));
48         set_intr_gate(
49             9,
50             0,
51             VirtAddr::new(trap_coprocessor_segment_overrun as usize),
52         );
53         set_intr_gate(10, 0, VirtAddr::new(trap_invalid_TSS as usize));
54         set_intr_gate(11, 0, VirtAddr::new(trap_segment_not_exists as usize));
55         set_intr_gate(12, 0, VirtAddr::new(trap_stack_segment_fault as usize));
56         set_intr_gate(13, 0, VirtAddr::new(trap_general_protection as usize));
57         set_intr_gate(14, 0, VirtAddr::new(trap_page_fault as usize));
58         // 中断号15由Intel保留,不能使用
59         set_intr_gate(16, 0, VirtAddr::new(trap_x87_FPU_error as usize));
60         set_intr_gate(17, 0, VirtAddr::new(trap_alignment_check as usize));
61         set_intr_gate(18, 0, VirtAddr::new(trap_machine_check as usize));
62         set_intr_gate(19, 0, VirtAddr::new(trap_SIMD_exception as usize));
63         set_intr_gate(20, 0, VirtAddr::new(trap_virtualization_exception as usize));
64     }
65     return Ok(());
66 }
67 
68 /// 处理除法错误 0 #DE
69 #[no_mangle]
70 unsafe extern "C" fn do_divide_error(regs: &'static TrapFrame, error_code: u64) {
71     kerror!(
72         "do_divide_error(0), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
73         error_code,
74         regs.rsp,
75         regs.rip,
76         smp_get_processor_id().data(),
77         ProcessManager::current_pid()
78     );
79     panic!("Divide Error");
80 }
81 
82 /// 处理调试异常 1 #DB
83 #[no_mangle]
84 unsafe extern "C" fn do_debug(regs: &'static TrapFrame, error_code: u64) {
85     kerror!(
86         "do_debug(1), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
87         error_code,
88         regs.rsp,
89         regs.rip,
90         smp_get_processor_id().data(),
91         ProcessManager::current_pid()
92     );
93     panic!("Debug Exception");
94 }
95 
96 /// 处理NMI中断 2 NMI
97 #[no_mangle]
98 unsafe extern "C" fn do_nmi(regs: &'static TrapFrame, error_code: u64) {
99     kerror!(
100         "do_nmi(2), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
101         error_code,
102         regs.rsp,
103         regs.rip,
104         smp_get_processor_id().data(),
105         ProcessManager::current_pid()
106     );
107     panic!("NMI Interrupt");
108 }
109 
110 /// 处理断点异常 3 #BP
111 #[no_mangle]
112 unsafe extern "C" fn do_int3(regs: &'static TrapFrame, error_code: u64) {
113     kerror!(
114         "do_int3(3), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
115         error_code,
116         regs.rsp,
117         regs.rip,
118         smp_get_processor_id().data(),
119         ProcessManager::current_pid()
120     );
121     panic!("Int3");
122 }
123 
124 /// 处理溢出异常 4 #OF
125 #[no_mangle]
126 unsafe extern "C" fn do_overflow(regs: &'static TrapFrame, error_code: u64) {
127     kerror!(
128         "do_overflow(4), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
129         error_code,
130         regs.rsp,
131         regs.rip,
132         smp_get_processor_id().data(),
133         ProcessManager::current_pid()
134     );
135     panic!("Overflow Exception");
136 }
137 
138 /// 处理BOUND指令检查异常 5 #BR
139 #[no_mangle]
140 unsafe extern "C" fn do_bounds(regs: &'static TrapFrame, error_code: u64) {
141     kerror!(
142         "do_bounds(5), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
143         error_code,
144         regs.rsp,
145         regs.rip,
146         smp_get_processor_id().data(),
147         ProcessManager::current_pid()
148     );
149     panic!("Bounds Check");
150 }
151 
152 /// 处理未定义操作码异常 6 #UD
153 #[no_mangle]
154 unsafe extern "C" fn do_undefined_opcode(regs: &'static TrapFrame, error_code: u64) {
155     kerror!(
156         "do_undefined_opcode(6), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
157         error_code,
158         regs.rsp,
159         regs.rip,
160         smp_get_processor_id().data(),
161         ProcessManager::current_pid()
162     );
163     panic!("Undefined Opcode");
164 }
165 
166 /// 处理设备不可用异常(FPU不存在) 7 #NM
167 #[no_mangle]
168 unsafe extern "C" fn do_dev_not_avaliable(regs: &'static TrapFrame, error_code: u64) {
169     kerror!(
170         "do_dev_not_avaliable(7), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
171         error_code,
172         regs.rsp,
173         regs.rip,
174         smp_get_processor_id().data(),
175         ProcessManager::current_pid()
176     );
177     panic!("Device Not Available");
178 }
179 
180 /// 处理双重错误 8 #DF
181 #[no_mangle]
182 unsafe extern "C" fn do_double_fault(regs: &'static TrapFrame, error_code: u64) {
183     kerror!(
184         "do_double_fault(8), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
185         error_code,
186         regs.rsp,
187         regs.rip,
188         smp_get_processor_id().data(),
189         ProcessManager::current_pid()
190     );
191     panic!("Double Fault");
192 }
193 
194 /// 处理协处理器段越界 9 #MF
195 #[no_mangle]
196 unsafe extern "C" fn do_coprocessor_segment_overrun(regs: &'static TrapFrame, error_code: u64) {
197     kerror!(
198         "do_coprocessor_segment_overrun(9), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
199         error_code,
200         regs.rsp,
201         regs.rip,
202         smp_get_processor_id().data(),
203         ProcessManager::current_pid()
204     );
205     panic!("Coprocessor Segment Overrun");
206 }
207 
208 /// 处理无效TSS 10 #TS
209 #[no_mangle]
210 unsafe extern "C" fn do_invalid_TSS(regs: &'static TrapFrame, error_code: u64) {
211     const ERR_MSG_1: &str =
212         "The exception occurred during delivery of an event external to the program.\n";
213     const ERR_MSG_2: &str = "Refers to a descriptor in the IDT.\n";
214     const ERR_MSG_3: &str = "Refers to a descriptor in the current LDT.\n";
215     const ERR_MSG_4: &str = "Refers to a descriptor in the GDT.\n";
216 
217     let msg1: &str = if (error_code & 0x1) != 0 {
218         ERR_MSG_1
219     } else {
220         ""
221     };
222 
223     let msg2: &str = if (error_code & 0x02) != 0 {
224         ERR_MSG_2
225     } else if (error_code & 0x04) != 0 {
226         ERR_MSG_3
227     } else {
228         ERR_MSG_4
229     };
230 
231     kerror!(
232         "do_invalid_TSS(10), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}\n{}{}",
233         error_code,
234         regs.rsp,
235         regs.rip,
236         smp_get_processor_id().data(),
237         ProcessManager::current_pid(),
238         msg1,
239         msg2
240     );
241     panic!("Invalid TSS");
242 }
243 
244 /// 处理段不存在 11 #NP
245 #[no_mangle]
246 unsafe extern "C" fn do_segment_not_exists(regs: &'static TrapFrame, error_code: u64) {
247     kerror!(
248         "do_segment_not_exists(11), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
249         error_code,
250         regs.rsp,
251         regs.rip,
252         smp_get_processor_id().data(),
253         ProcessManager::current_pid()
254     );
255     panic!("Segment Not Exists");
256 }
257 
258 /// 处理栈段错误 12 #SS
259 #[no_mangle]
260 unsafe extern "C" fn do_stack_segment_fault(regs: &'static TrapFrame, error_code: u64) {
261     kerror!(
262         "do_stack_segment_fault(12), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
263         error_code,
264         regs.rsp,
265         regs.rip,
266         smp_get_processor_id().data(),
267         ProcessManager::current_pid()
268     );
269     panic!("Stack Segment Fault");
270 }
271 
272 /// 处理一般保护异常 13 #GP
273 #[no_mangle]
274 unsafe extern "C" fn do_general_protection(regs: &'static TrapFrame, error_code: u64) {
275     const ERR_MSG_1: &str = "The exception occurred during delivery of an event external to the program, such as an interrupt or an earlier exception.";
276     const ERR_MSG_2: &str = "Refers to a gate descriptor in the IDT;\n";
277     const ERR_MSG_3: &str = "Refers to a descriptor in the GDT or the current LDT;\n";
278     const ERR_MSG_4: &str = "Refers to a segment or gate descriptor in the LDT;\n";
279     const ERR_MSG_5: &str = "Refers to a descriptor in the current GDT;\n";
280 
281     let msg1: &str = if (error_code & 0x1) != 0 {
282         ERR_MSG_1
283     } else {
284         ""
285     };
286 
287     let msg2: &str = if (error_code & 0x02) != 0 {
288         ERR_MSG_2
289     } else {
290         ERR_MSG_3
291     };
292 
293     let msg3: &str = if (error_code & 0x02) == 0 {
294         if (error_code & 0x04) != 0 {
295             ERR_MSG_4
296         } else {
297             ERR_MSG_5
298         }
299     } else {
300         ""
301     };
302     kerror!(
303         "do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}
304 {}{}{}
305 Segment Selector Index: {:#x}\n
306 ",
307         error_code,
308         regs.rsp,
309         regs.rip,
310         smp_get_processor_id().data(),
311         ProcessManager::current_pid(),
312         msg1, msg2, msg3,
313         error_code & 0xfff8
314     );
315     panic!("General Protection");
316 }
317 
318 /// 处理页错误 14 #PF
319 #[no_mangle]
320 unsafe extern "C" fn do_page_fault(regs: &'static TrapFrame, error_code: u64) {
321     kerror!(
322         "do_page_fault(14), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}, \nFault Address: {:#x}",
323         error_code,
324         regs.rsp,
325         regs.rip,
326         smp_get_processor_id().data(),
327         ProcessManager::current_pid(),
328         x86::controlregs::cr2()
329     );
330 
331     if (error_code & 0x01) == 0 {
332         print!("Page Not Present,\t");
333     }
334     if (error_code & 0x02) != 0 {
335         print!("Write Access,\t");
336     } else {
337         print!("Read Access,\t");
338     }
339 
340     if (error_code & 0x04) != 0 {
341         print!("Fault in user(3),\t");
342     } else {
343         print!("Fault in supervisor(0,1,2),\t");
344     }
345 
346     if (error_code & 0x08) != 0 {
347         print!("Reserved bit violation cause fault,\t");
348     }
349 
350     if (error_code & 0x10) != 0 {
351         print!("Instruction fetch cause fault,\t");
352     }
353     print!("\n");
354 
355     CurrentIrqArch::interrupt_enable();
356     panic!("Page Fault");
357 }
358 
359 /// 处理x87 FPU错误 16 #MF
360 #[no_mangle]
361 unsafe extern "C" fn do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64) {
362     kerror!(
363         "do_x87_FPU_error(16), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
364         error_code,
365         regs.rsp,
366         regs.rip,
367         smp_get_processor_id().data(),
368         ProcessManager::current_pid()
369     );
370     panic!("x87 FPU Error");
371 }
372 
373 /// 处理对齐检查 17 #AC
374 #[no_mangle]
375 unsafe extern "C" fn do_alignment_check(regs: &'static TrapFrame, error_code: u64) {
376     kerror!(
377         "do_alignment_check(17), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
378         error_code,
379         regs.rsp,
380         regs.rip,
381         smp_get_processor_id().data(),
382         ProcessManager::current_pid()
383     );
384     panic!("Alignment Check");
385 }
386 
387 /// 处理机器检查 18 #MC
388 #[no_mangle]
389 unsafe extern "C" fn do_machine_check(regs: &'static TrapFrame, error_code: u64) {
390     kerror!(
391         "do_machine_check(18), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
392         error_code,
393         regs.rsp,
394         regs.rip,
395         smp_get_processor_id().data(),
396         ProcessManager::current_pid()
397     );
398     panic!("Machine Check");
399 }
400 
401 /// 处理SIMD异常 19 #XM
402 #[no_mangle]
403 unsafe extern "C" fn do_SIMD_exception(regs: &'static TrapFrame, error_code: u64) {
404     kerror!(
405         "do_SIMD_exception(19), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
406         error_code,
407         regs.rsp,
408         regs.rip,
409         smp_get_processor_id().data(),
410         ProcessManager::current_pid()
411     );
412     panic!("SIMD Exception");
413 }
414 
415 /// 处理虚拟化异常 20 #VE
416 #[no_mangle]
417 unsafe extern "C" fn do_virtualization_exception(regs: &'static TrapFrame, error_code: u64) {
418     kerror!(
419         "do_virtualization_exception(20), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
420         error_code,
421         regs.rsp,
422         regs.rip,
423         smp_get_processor_id().data(),
424         ProcessManager::current_pid()
425     );
426     panic!("Virtualization Exception");
427 }
428 
429 #[no_mangle]
430 unsafe extern "C" fn ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64) {
431     kwarn!("Unknown interrupt.");
432 }
433