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" {
trap_divide_error()14 fn trap_divide_error();
trap_debug()15 fn trap_debug();
trap_nmi()16 fn trap_nmi();
trap_int3()17 fn trap_int3();
trap_overflow()18 fn trap_overflow();
trap_bounds()19 fn trap_bounds();
trap_undefined_opcode()20 fn trap_undefined_opcode();
trap_dev_not_avaliable()21 fn trap_dev_not_avaliable();
trap_double_fault()22 fn trap_double_fault();
trap_coprocessor_segment_overrun()23 fn trap_coprocessor_segment_overrun();
trap_invalid_TSS()24 fn trap_invalid_TSS();
trap_segment_not_exists()25 fn trap_segment_not_exists();
trap_stack_segment_fault()26 fn trap_stack_segment_fault();
trap_general_protection()27 fn trap_general_protection();
trap_page_fault()28 fn trap_page_fault();
trap_x87_FPU_error()29 fn trap_x87_FPU_error();
trap_alignment_check()30 fn trap_alignment_check();
trap_machine_check()31 fn trap_machine_check();
trap_SIMD_exception()32 fn trap_SIMD_exception();
trap_virtualization_exception()33 fn trap_virtualization_exception();
34 }
35
36 #[inline(never)]
arch_trap_init() -> Result<(), SystemError>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]
do_divide_error(regs: &'static TrapFrame, error_code: u64)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]
do_debug(regs: &'static TrapFrame, error_code: u64)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]
do_nmi(regs: &'static TrapFrame, error_code: u64)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]
do_int3(regs: &'static TrapFrame, error_code: u64)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]
do_overflow(regs: &'static TrapFrame, error_code: u64)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]
do_bounds(regs: &'static TrapFrame, error_code: u64)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]
do_undefined_opcode(regs: &'static TrapFrame, error_code: u64)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]
do_dev_not_avaliable(regs: &'static TrapFrame, error_code: u64)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]
do_double_fault(regs: &'static TrapFrame, error_code: u64)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]
do_coprocessor_segment_overrun(regs: &'static TrapFrame, error_code: u64)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]
do_invalid_TSS(regs: &'static TrapFrame, error_code: u64)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;
218 if (error_code & 0x1) != 0 {
219 msg1 = ERR_MSG_1;
220 } else {
221 msg1 = "";
222 }
223
224 let msg2: &str;
225 if (error_code & 0x02) != 0 {
226 msg2 = ERR_MSG_2;
227 } else {
228 if (error_code & 0x04) != 0 {
229 msg2 = ERR_MSG_3;
230 } else {
231 msg2 = ERR_MSG_4;
232 }
233 }
234 kerror!(
235 "do_invalid_TSS(10), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}\n{}{}",
236 error_code,
237 regs.rsp,
238 regs.rip,
239 smp_get_processor_id().data(),
240 ProcessManager::current_pid(),
241 msg1,
242 msg2
243 );
244 panic!("Invalid TSS");
245 }
246
247 /// 处理段不存在 11 #NP
248 #[no_mangle]
do_segment_not_exists(regs: &'static TrapFrame, error_code: u64)249 unsafe extern "C" fn do_segment_not_exists(regs: &'static TrapFrame, error_code: u64) {
250 kerror!(
251 "do_segment_not_exists(11), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
252 error_code,
253 regs.rsp,
254 regs.rip,
255 smp_get_processor_id().data(),
256 ProcessManager::current_pid()
257 );
258 panic!("Segment Not Exists");
259 }
260
261 /// 处理栈段错误 12 #SS
262 #[no_mangle]
do_stack_segment_fault(regs: &'static TrapFrame, error_code: u64)263 unsafe extern "C" fn do_stack_segment_fault(regs: &'static TrapFrame, error_code: u64) {
264 kerror!(
265 "do_stack_segment_fault(12), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
266 error_code,
267 regs.rsp,
268 regs.rip,
269 smp_get_processor_id().data(),
270 ProcessManager::current_pid()
271 );
272 panic!("Stack Segment Fault");
273 }
274
275 /// 处理一般保护异常 13 #GP
276 #[no_mangle]
do_general_protection(regs: &'static TrapFrame, error_code: u64)277 unsafe extern "C" fn do_general_protection(regs: &'static TrapFrame, error_code: u64) {
278 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.";
279 const ERR_MSG_2: &str = "Refers to a gate descriptor in the IDT;\n";
280 const ERR_MSG_3: &str = "Refers to a descriptor in the GDT or the current LDT;\n";
281 const ERR_MSG_4: &str = "Refers to a segment or gate descriptor in the LDT;\n";
282 const ERR_MSG_5: &str = "Refers to a descriptor in the current GDT;\n";
283
284 let msg1: &str;
285 if (error_code & 0x1) != 0 {
286 msg1 = ERR_MSG_1;
287 } else {
288 msg1 = "";
289 }
290
291 let msg2: &str;
292 if (error_code & 0x02) != 0 {
293 msg2 = ERR_MSG_2;
294 } else {
295 msg2 = ERR_MSG_3;
296 }
297
298 let msg3: &str;
299 if (error_code & 0x02) == 0 {
300 if (error_code & 0x04) != 0 {
301 msg3 = ERR_MSG_4;
302 } else {
303 msg3 = ERR_MSG_5;
304 }
305 } else {
306 msg3 = "";
307 }
308 kerror!(
309 "do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}
310 {}{}{}
311 Segment Selector Index: {:#x}\n
312 ",
313 error_code,
314 regs.rsp,
315 regs.rip,
316 smp_get_processor_id().data(),
317 ProcessManager::current_pid(),
318 msg1, msg2, msg3,
319 error_code & 0xfff8
320 );
321 panic!("General Protection");
322 }
323
324 /// 处理页错误 14 #PF
325 #[no_mangle]
do_page_fault(regs: &'static TrapFrame, error_code: u64)326 unsafe extern "C" fn do_page_fault(regs: &'static TrapFrame, error_code: u64) {
327 kerror!(
328 "do_page_fault(14), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}, \nFault Address: {:#x}",
329 error_code,
330 regs.rsp,
331 regs.rip,
332 smp_get_processor_id().data(),
333 ProcessManager::current_pid(),
334 x86::controlregs::cr2()
335 );
336
337 if (error_code & 0x01) == 0 {
338 print!("Page Not Present,\t");
339 }
340 if (error_code & 0x02) != 0 {
341 print!("Write Access,\t");
342 } else {
343 print!("Read Access,\t");
344 }
345
346 if (error_code & 0x04) != 0 {
347 print!("Fault in user(3),\t");
348 } else {
349 print!("Fault in supervisor(0,1,2),\t");
350 }
351
352 if (error_code & 0x08) != 0 {
353 print!("Reserved bit violation cause fault,\t");
354 }
355
356 if (error_code & 0x10) != 0 {
357 print!("Instruction fetch cause fault,\t");
358 }
359 print!("\n");
360
361 CurrentIrqArch::interrupt_enable();
362 panic!("Page Fault");
363 }
364
365 /// 处理x87 FPU错误 16 #MF
366 #[no_mangle]
do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64)367 unsafe extern "C" fn do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64) {
368 kerror!(
369 "do_x87_FPU_error(16), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
370 error_code,
371 regs.rsp,
372 regs.rip,
373 smp_get_processor_id().data(),
374 ProcessManager::current_pid()
375 );
376 panic!("x87 FPU Error");
377 }
378
379 /// 处理对齐检查 17 #AC
380 #[no_mangle]
do_alignment_check(regs: &'static TrapFrame, error_code: u64)381 unsafe extern "C" fn do_alignment_check(regs: &'static TrapFrame, error_code: u64) {
382 kerror!(
383 "do_alignment_check(17), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
384 error_code,
385 regs.rsp,
386 regs.rip,
387 smp_get_processor_id().data(),
388 ProcessManager::current_pid()
389 );
390 panic!("Alignment Check");
391 }
392
393 /// 处理机器检查 18 #MC
394 #[no_mangle]
do_machine_check(regs: &'static TrapFrame, error_code: u64)395 unsafe extern "C" fn do_machine_check(regs: &'static TrapFrame, error_code: u64) {
396 kerror!(
397 "do_machine_check(18), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
398 error_code,
399 regs.rsp,
400 regs.rip,
401 smp_get_processor_id().data(),
402 ProcessManager::current_pid()
403 );
404 panic!("Machine Check");
405 }
406
407 /// 处理SIMD异常 19 #XM
408 #[no_mangle]
do_SIMD_exception(regs: &'static TrapFrame, error_code: u64)409 unsafe extern "C" fn do_SIMD_exception(regs: &'static TrapFrame, error_code: u64) {
410 kerror!(
411 "do_SIMD_exception(19), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
412 error_code,
413 regs.rsp,
414 regs.rip,
415 smp_get_processor_id().data(),
416 ProcessManager::current_pid()
417 );
418 panic!("SIMD Exception");
419 }
420
421 /// 处理虚拟化异常 20 #VE
422 #[no_mangle]
do_virtualization_exception(regs: &'static TrapFrame, error_code: u64)423 unsafe extern "C" fn do_virtualization_exception(regs: &'static TrapFrame, error_code: u64) {
424 kerror!(
425 "do_virtualization_exception(20), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
426 error_code,
427 regs.rsp,
428 regs.rip,
429 smp_get_processor_id().data(),
430 ProcessManager::current_pid()
431 );
432 panic!("Virtualization Exception");
433 }
434
435 #[no_mangle]
ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64)436 unsafe extern "C" fn ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64) {
437 kwarn!("Unknown interrupt.");
438 }
439