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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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(), 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; 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(), 240 ProcessManager::current_pid(), 241 msg1, 242 msg2 243 ); 244 panic!("Invalid TSS"); 245 } 246 247 /// 处理段不存在 11 #NP 248 #[no_mangle] 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(), 256 ProcessManager::current_pid() 257 ); 258 panic!("Segment Not Exists"); 259 } 260 261 /// 处理栈段错误 12 #SS 262 #[no_mangle] 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(), 270 ProcessManager::current_pid() 271 ); 272 panic!("Stack Segment Fault"); 273 } 274 275 /// 处理一般保护异常 13 #GP 276 #[no_mangle] 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(), 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] 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(), 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] 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(), 374 ProcessManager::current_pid() 375 ); 376 panic!("x87 FPU Error"); 377 } 378 379 /// 处理对齐检查 17 #AC 380 #[no_mangle] 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(), 388 ProcessManager::current_pid() 389 ); 390 panic!("Alignment Check"); 391 } 392 393 /// 处理机器检查 18 #MC 394 #[no_mangle] 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(), 402 ProcessManager::current_pid() 403 ); 404 panic!("Machine Check"); 405 } 406 407 /// 处理SIMD异常 19 #XM 408 #[no_mangle] 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(), 416 ProcessManager::current_pid() 417 ); 418 panic!("SIMD Exception"); 419 } 420 421 /// 处理虚拟化异常 20 #VE 422 #[no_mangle] 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(), 430 ProcessManager::current_pid() 431 ); 432 panic!("Virtualization Exception"); 433 } 434 435 #[no_mangle] 436 unsafe extern "C" fn ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64) { 437 kwarn!("Unknown interrupt."); 438 } 439