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