123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- use log::{error, warn};
- use system_error::SystemError;
- use crate::{
- arch::{CurrentIrqArch, MMArch},
- exception::InterruptArch,
- mm::VirtAddr,
- process::ProcessManager,
- smp::core::smp_get_processor_id,
- };
- use super::{
- entry::{set_intr_gate, set_system_trap_gate},
- TrapFrame,
- };
- extern "C" {
- fn trap_divide_error();
- fn trap_debug();
- fn trap_nmi();
- fn trap_int3();
- fn trap_overflow();
- fn trap_bounds();
- fn trap_undefined_opcode();
- fn trap_dev_not_avaliable();
- fn trap_double_fault();
- fn trap_coprocessor_segment_overrun();
- fn trap_invalid_TSS();
- fn trap_segment_not_exists();
- fn trap_stack_segment_fault();
- fn trap_general_protection();
- fn trap_page_fault();
- fn trap_x87_FPU_error();
- fn trap_alignment_check();
- fn trap_machine_check();
- fn trap_SIMD_exception();
- fn trap_virtualization_exception();
- }
- bitflags! {
- pub struct TrapNr: u64 {
- const X86_TRAP_DE = 0;
- const X86_TRAP_DB = 1;
- const X86_TRAP_NMI = 2;
- const X86_TRAP_BP = 3;
- const X86_TRAP_OF = 4;
- const X86_TRAP_BR = 5;
- const X86_TRAP_UD = 6;
- const X86_TRAP_NM = 7;
- const X86_TRAP_DF = 8;
- const X86_TRAP_OLD_MF = 9;
- const X86_TRAP_TS = 10;
- const X86_TRAP_NP = 11;
- const X86_TRAP_SS = 12;
- const X86_TRAP_GP = 13;
- const X86_TRAP_PF = 14;
- const X86_TRAP_SPURIOUS = 15;
- const X86_TRAP_MF = 16;
- const X86_TRAP_AC = 17;
- const X86_TRAP_MC = 18;
- const X86_TRAP_XF = 19;
- const X86_TRAP_VE = 20;
- const X86_TRAP_CP = 21;
- const X86_TRAP_VC = 29;
- const X86_TRAP_IRET = 32;
- }
- pub struct X86PfErrorCode : u32{
- const X86_PF_PROT = 1 << 0;
- const X86_PF_WRITE = 1 << 1;
- const X86_PF_USER = 1 << 2;
- const X86_PF_RSVD = 1 << 3;
- const X86_PF_INSTR = 1 << 4;
- const X86_PF_PK = 1 << 5;
- const X86_PF_SHSTK = 1 << 6;
- const X86_PF_SGX = 1 << 15;
- }
- }
- #[inline(never)]
- pub fn arch_trap_init() -> Result<(), SystemError> {
- unsafe {
- set_intr_gate(0, 0, VirtAddr::new(trap_divide_error as usize));
- set_intr_gate(1, 0, VirtAddr::new(trap_debug as usize));
- set_intr_gate(2, 0, VirtAddr::new(trap_nmi as usize));
- set_system_trap_gate(3, 0, VirtAddr::new(trap_int3 as usize));
- set_system_trap_gate(4, 0, VirtAddr::new(trap_overflow as usize));
- set_system_trap_gate(5, 0, VirtAddr::new(trap_bounds as usize));
- set_intr_gate(6, 0, VirtAddr::new(trap_undefined_opcode as usize));
- set_intr_gate(7, 0, VirtAddr::new(trap_dev_not_avaliable as usize));
- set_intr_gate(8, 0, VirtAddr::new(trap_double_fault as usize));
- set_intr_gate(
- 9,
- 0,
- VirtAddr::new(trap_coprocessor_segment_overrun as usize),
- );
- set_intr_gate(10, 0, VirtAddr::new(trap_invalid_TSS as usize));
- set_intr_gate(11, 0, VirtAddr::new(trap_segment_not_exists as usize));
- set_intr_gate(12, 0, VirtAddr::new(trap_stack_segment_fault as usize));
- set_intr_gate(13, 0, VirtAddr::new(trap_general_protection as usize));
- set_intr_gate(14, 0, VirtAddr::new(trap_page_fault as usize));
- // 中断号15由Intel保留,不能使用
- set_intr_gate(16, 0, VirtAddr::new(trap_x87_FPU_error as usize));
- set_intr_gate(17, 0, VirtAddr::new(trap_alignment_check as usize));
- set_intr_gate(18, 0, VirtAddr::new(trap_machine_check as usize));
- set_intr_gate(19, 0, VirtAddr::new(trap_SIMD_exception as usize));
- set_intr_gate(20, 0, VirtAddr::new(trap_virtualization_exception as usize));
- }
- return Ok(());
- }
- /// 处理除法错误 0 #DE
- #[no_mangle]
- unsafe extern "C" fn do_divide_error(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_divide_error(0), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Divide Error");
- }
- /// 处理调试异常 1 #DB
- #[no_mangle]
- unsafe extern "C" fn do_debug(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_debug(1), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Debug Exception");
- }
- /// 处理NMI中断 2 NMI
- #[no_mangle]
- unsafe extern "C" fn do_nmi(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_nmi(2), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("NMI Interrupt");
- }
- /// 处理断点异常 3 #BP
- #[no_mangle]
- unsafe extern "C" fn do_int3(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_int3(3), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Int3");
- }
- /// 处理溢出异常 4 #OF
- #[no_mangle]
- unsafe extern "C" fn do_overflow(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_overflow(4), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Overflow Exception");
- }
- /// 处理BOUND指令检查异常 5 #BR
- #[no_mangle]
- unsafe extern "C" fn do_bounds(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_bounds(5), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Bounds Check");
- }
- /// 处理未定义操作码异常 6 #UD
- #[no_mangle]
- unsafe extern "C" fn do_undefined_opcode(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_undefined_opcode(6), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Undefined Opcode");
- }
- /// 处理设备不可用异常(FPU不存在) 7 #NM
- #[no_mangle]
- unsafe extern "C" fn do_dev_not_avaliable(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_dev_not_avaliable(7), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Device Not Available");
- }
- /// 处理双重错误 8 #DF
- #[no_mangle]
- unsafe extern "C" fn do_double_fault(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_double_fault(8), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Double Fault");
- }
- /// 处理协处理器段越界 9 #MF
- #[no_mangle]
- unsafe extern "C" fn do_coprocessor_segment_overrun(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_coprocessor_segment_overrun(9), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Coprocessor Segment Overrun");
- }
- /// 处理无效TSS 10 #TS
- #[no_mangle]
- unsafe extern "C" fn do_invalid_TSS(regs: &'static TrapFrame, error_code: u64) {
- const ERR_MSG_1: &str =
- "The exception occurred during delivery of an event external to the program.\n";
- const ERR_MSG_2: &str = "Refers to a descriptor in the IDT.\n";
- const ERR_MSG_3: &str = "Refers to a descriptor in the current LDT.\n";
- const ERR_MSG_4: &str = "Refers to a descriptor in the GDT.\n";
- let msg1: &str = if (error_code & 0x1) != 0 {
- ERR_MSG_1
- } else {
- ""
- };
- let msg2: &str = if (error_code & 0x02) != 0 {
- ERR_MSG_2
- } else if (error_code & 0x04) != 0 {
- ERR_MSG_3
- } else {
- ERR_MSG_4
- };
- error!(
- "do_invalid_TSS(10), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}\n{}{}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid(),
- msg1,
- msg2
- );
- panic!("Invalid TSS");
- }
- /// 处理段不存在 11 #NP
- #[no_mangle]
- unsafe extern "C" fn do_segment_not_exists(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_segment_not_exists(11), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Segment Not Exists");
- }
- /// 处理栈段错误 12 #SS
- #[no_mangle]
- unsafe extern "C" fn do_stack_segment_fault(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_stack_segment_fault(12), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Stack Segment Fault");
- }
- /// 处理一般保护异常 13 #GP
- #[no_mangle]
- unsafe extern "C" fn do_general_protection(regs: &'static TrapFrame, error_code: u64) {
- 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.";
- const ERR_MSG_2: &str = "Refers to a gate descriptor in the IDT;\n";
- const ERR_MSG_3: &str = "Refers to a descriptor in the GDT or the current LDT;\n";
- const ERR_MSG_4: &str = "Refers to a segment or gate descriptor in the LDT;\n";
- const ERR_MSG_5: &str = "Refers to a descriptor in the current GDT;\n";
- let msg1: &str = if (error_code & 0x1) != 0 {
- ERR_MSG_1
- } else {
- ""
- };
- let msg2: &str = if (error_code & 0x02) != 0 {
- ERR_MSG_2
- } else {
- ERR_MSG_3
- };
- let msg3: &str = if (error_code & 0x02) == 0 {
- if (error_code & 0x04) != 0 {
- ERR_MSG_4
- } else {
- ERR_MSG_5
- }
- } else {
- ""
- };
- error!(
- "do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t rflags: {:#x}\t CPU: {}, \tpid: {:?}
- {}{}{}
- Segment Selector Index: {:#x}\n
- ",
- error_code,
- regs.rsp,
- regs.rip,
- regs.rflags,
- smp_get_processor_id().data(),
- ProcessManager::current_pid(),
- msg1, msg2, msg3,
- error_code & 0xfff8
- );
- panic!("General Protection");
- }
- /// 处理页错误 14 #PF
- #[no_mangle]
- unsafe extern "C" fn do_page_fault(regs: &'static TrapFrame, error_code: u64) {
- // error!(
- // "do_page_fault(14), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}, \nFault Address: {:#x}",
- // error_code,
- // regs.rsp,
- // regs.rip,
- // smp_get_processor_id().data(),
- // ProcessManager::current_pid(),
- // x86::controlregs::cr2()
- // );
- // if (error_code & 0x01) == 0 {
- // print!("Page Not Present,\t");
- // }
- // if (error_code & 0x02) != 0 {
- // print!("Write Access,\t");
- // } else {
- // print!("Read Access,\t");
- // }
- // if (error_code & 0x04) != 0 {
- // print!("Fault in user(3),\t");
- // } else {
- // print!("Fault in supervisor(0,1,2),\t");
- // }
- // if (error_code & 0x08) != 0 {
- // print!("Reserved bit violation cause fault,\t");
- // }
- // if (error_code & 0x10) != 0 {
- // print!("Instruction fetch cause fault,\t");
- // }
- // print!("\n");
- // CurrentIrqArch::interrupt_enable();
- // panic!("Page Fault");
- CurrentIrqArch::interrupt_disable();
- let address = x86::controlregs::cr2();
- // crate::info!(
- // "fault address: {:#x}, error_code: {:#b}, pid: {}\n",
- // address,
- // error_code,
- // ProcessManager::current_pid().data()
- // );
- let address = VirtAddr::new(address);
- let error_code = X86PfErrorCode::from_bits_truncate(error_code as u32);
- if address.check_user() {
- MMArch::do_user_addr_fault(regs, error_code, address);
- } else {
- MMArch::do_kern_addr_fault(regs, error_code, address);
- }
- CurrentIrqArch::interrupt_enable();
- }
- /// 处理x87 FPU错误 16 #MF
- #[no_mangle]
- unsafe extern "C" fn do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_x87_FPU_error(16), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("x87 FPU Error");
- }
- /// 处理对齐检查 17 #AC
- #[no_mangle]
- unsafe extern "C" fn do_alignment_check(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_alignment_check(17), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Alignment Check");
- }
- /// 处理机器检查 18 #MC
- #[no_mangle]
- unsafe extern "C" fn do_machine_check(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_machine_check(18), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Machine Check");
- }
- /// 处理SIMD异常 19 #XM
- #[no_mangle]
- unsafe extern "C" fn do_SIMD_exception(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_SIMD_exception(19), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("SIMD Exception");
- }
- /// 处理虚拟化异常 20 #VE
- #[no_mangle]
- unsafe extern "C" fn do_virtualization_exception(regs: &'static TrapFrame, error_code: u64) {
- error!(
- "do_virtualization_exception(20), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
- error_code,
- regs.rsp,
- regs.rip,
- smp_get_processor_id().data(),
- ProcessManager::current_pid()
- );
- panic!("Virtualization Exception");
- }
- #[no_mangle]
- unsafe extern "C" fn ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64) {
- warn!("Unknown interrupt.");
- }
|