diff --git a/src/interrupts/mod.rs b/src/interrupts/mod.rs index 5f905702..ed8a060f 100644 --- a/src/interrupts/mod.rs +++ b/src/interrupts/mod.rs @@ -18,12 +18,32 @@ macro_rules! handler { }} } +macro_rules! handler_with_error_code { + ($name: ident) => {{ + #[naked] + extern "C" fn wrapper() -> ! { + unsafe { + asm!("pop rsi // pop error code into rsi + mov rdi, rsp + sub rsp, 8 // align the stack pointer + call $0" + :: "i"($name as extern "C" fn( + *const ExceptionStackFrame, u64) -> !) + : "rdi" : "intel"); + ::core::intrinsics::unreachable(); + } + } + wrapper + }} +} + lazy_static! { static ref IDT: idt::Idt = { let mut idt = idt::Idt::new(); idt.set_handler(0, handler!(divide_by_zero_handler)); idt.set_handler(6, handler!(invalid_opcode_handler)); + idt.set_handler(14, handler_with_error_code!(page_fault_handler)); idt }; @@ -64,3 +84,14 @@ extern "C" fn invalid_opcode_handler(stack_frame: *const ExceptionStackFrame) } loop {} } + +extern "C" fn page_fault_handler(stack_frame: *const ExceptionStackFrame, + error_code: u64) -> ! +{ + unsafe { + print_error(format_args!( + "EXCEPTION: PAGE FAULT with error code {:?}\n{:#?}", + error_code, *stack_frame)); + } + loop {} +} diff --git a/src/lib.rs b/src/lib.rs index e51322a1..79d4025c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,8 +52,9 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) { // initialize our IDT interrupts::init(); - // provoke a invalid opcode exception - unsafe { asm!("ud2") }; + // provoke a page fault + unsafe { *(0xdeadbeaf as *mut u64) = 42 }; + println!("It did not crash!"); loop {}