xref: /DragonOS/kernel/src/arch/x86_64/interrupt/trap.rs (revision 370472f7288b568c7b80815f5b150daf4496446c)
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 rflags: {:#x}\t CPU: {}, \tpid: {:?}
304 {}{}{}
305 Segment Selector Index: {:#x}\n
306 ",
307         error_code,
308         regs.rsp,
309         regs.rip,
310         regs.rflags,
311         smp_get_processor_id().data(),
312         ProcessManager::current_pid(),
313         msg1, msg2, msg3,
314         error_code & 0xfff8
315     );
316     panic!("General Protection");
317 }
318 
319 /// 处理页错误 14 #PF
320 #[no_mangle]
321 unsafe extern "C" fn do_page_fault(regs: &'static TrapFrame, error_code: u64) {
322     kerror!(
323         "do_page_fault(14), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}, \nFault Address: {:#x}",
324         error_code,
325         regs.rsp,
326         regs.rip,
327         smp_get_processor_id().data(),
328         ProcessManager::current_pid(),
329         x86::controlregs::cr2()
330     );
331 
332     if (error_code & 0x01) == 0 {
333         print!("Page Not Present,\t");
334     }
335     if (error_code & 0x02) != 0 {
336         print!("Write Access,\t");
337     } else {
338         print!("Read Access,\t");
339     }
340 
341     if (error_code & 0x04) != 0 {
342         print!("Fault in user(3),\t");
343     } else {
344         print!("Fault in supervisor(0,1,2),\t");
345     }
346 
347     if (error_code & 0x08) != 0 {
348         print!("Reserved bit violation cause fault,\t");
349     }
350 
351     if (error_code & 0x10) != 0 {
352         print!("Instruction fetch cause fault,\t");
353     }
354     print!("\n");
355 
356     CurrentIrqArch::interrupt_enable();
357     panic!("Page Fault");
358 }
359 
360 /// 处理x87 FPU错误 16 #MF
361 #[no_mangle]
362 unsafe extern "C" fn do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64) {
363     kerror!(
364         "do_x87_FPU_error(16), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
365         error_code,
366         regs.rsp,
367         regs.rip,
368         smp_get_processor_id().data(),
369         ProcessManager::current_pid()
370     );
371     panic!("x87 FPU Error");
372 }
373 
374 /// 处理对齐检查 17 #AC
375 #[no_mangle]
376 unsafe extern "C" fn do_alignment_check(regs: &'static TrapFrame, error_code: u64) {
377     kerror!(
378         "do_alignment_check(17), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
379         error_code,
380         regs.rsp,
381         regs.rip,
382         smp_get_processor_id().data(),
383         ProcessManager::current_pid()
384     );
385     panic!("Alignment Check");
386 }
387 
388 /// 处理机器检查 18 #MC
389 #[no_mangle]
390 unsafe extern "C" fn do_machine_check(regs: &'static TrapFrame, error_code: u64) {
391     kerror!(
392         "do_machine_check(18), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
393         error_code,
394         regs.rsp,
395         regs.rip,
396         smp_get_processor_id().data(),
397         ProcessManager::current_pid()
398     );
399     panic!("Machine Check");
400 }
401 
402 /// 处理SIMD异常 19 #XM
403 #[no_mangle]
404 unsafe extern "C" fn do_SIMD_exception(regs: &'static TrapFrame, error_code: u64) {
405     kerror!(
406         "do_SIMD_exception(19), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
407         error_code,
408         regs.rsp,
409         regs.rip,
410         smp_get_processor_id().data(),
411         ProcessManager::current_pid()
412     );
413     panic!("SIMD Exception");
414 }
415 
416 /// 处理虚拟化异常 20 #VE
417 #[no_mangle]
418 unsafe extern "C" fn do_virtualization_exception(regs: &'static TrapFrame, error_code: u64) {
419     kerror!(
420         "do_virtualization_exception(20), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
421         error_code,
422         regs.rsp,
423         regs.rip,
424         smp_get_processor_id().data(),
425         ProcessManager::current_pid()
426     );
427     panic!("Virtualization Exception");
428 }
429 
430 #[no_mangle]
431 unsafe extern "C" fn ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64) {
432     kwarn!("Unknown interrupt.");
433 }
434