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