From 6590a5acfee33bae3ca0431c8af09768248fe405 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 15 Nov 2019 20:21:25 +0100 Subject: Rename interrupt and exception handlers --- kernel/src/interrupts/exception_handlers.rs | 95 +++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 kernel/src/interrupts/exception_handlers.rs (limited to 'kernel/src/interrupts/exception_handlers.rs') diff --git a/kernel/src/interrupts/exception_handlers.rs b/kernel/src/interrupts/exception_handlers.rs new file mode 100644 index 0000000..a3ecf9d --- /dev/null +++ b/kernel/src/interrupts/exception_handlers.rs @@ -0,0 +1,95 @@ +use super::Interrupts; +use crate::io::qemu; +use x86_64::structures::idt::{InterruptStackFrame, PageFaultErrorCode}; + +macro_rules! exception_default { + ($stack_frame: expr) => { + format_args!( + "instruction addr: 0x{:08x}\nstack addr: 0x{:08x}\nflags: 0x{:x}", + $stack_frame.instruction_pointer.as_u64(), + $stack_frame.stack_pointer.as_u64(), + $stack_frame.cpu_flags, + ) + }; +} + +static mut expected_fault: Interrupts = Interrupts::None; + +pub unsafe fn expect_fault(int: Interrupts) { + if expected_fault == Interrupts::None { + expected_fault = int; + } +} + +fn get_expected_fault() -> Interrupts { + unsafe { expected_fault } +} + +pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFrame) { + match get_expected_fault() { + Interrupts::Breakpoint => qemu::exit_qemu(qemu::QemuExitCode::Success), + _ => panic!( + "BREAKPOINT exception thrown\n\n{}", + exception_default!(stack_frame) + ), + } +} + +pub extern "x86-interrupt" fn general_protection_fault_handler( + stack_frame: &mut InterruptStackFrame, + error_code: u64, +) { + match get_expected_fault() { + Interrupts::GeneralProtectionFault => qemu::exit_qemu(qemu::QemuExitCode::Success), + _ => panic!( + "GENERAL PROTECTION exception thrown\nerror code: {:x}\n{}", + error_code, + exception_default!(stack_frame) + ), + } +} + +pub extern "x86-interrupt" fn page_fault_handler( + stack_frame: &mut InterruptStackFrame, + error_code: PageFaultErrorCode, +) { + use x86_64::registers::control::Cr2; + + match get_expected_fault() { + Interrupts::PageFault => qemu::exit_qemu(qemu::QemuExitCode::Success), + _ => panic!( + "PAGE FAULT while accessing address: 0x{:08x}\nerror code: {:?}(0x{:x})\n{}", + Cr2::read().as_u64(), + error_code, + error_code.bits(), + exception_default!(stack_frame) + ), + } +} + +pub extern "x86-interrupt" fn segment_not_present_handler( + stack_frame: &mut InterruptStackFrame, + error_code: u64, +) { + match get_expected_fault() { + Interrupts::NotPresent => qemu::exit_qemu(qemu::QemuExitCode::Success), + _ => panic!( + "SEGMENT NOT PRESENT exception\nerror code: 0x{:x}\n{}", + error_code, + exception_default!(stack_frame) + ), + } +} + +pub extern "x86-interrupt" fn double_fault_handler( + stack_frame: &mut InterruptStackFrame, + _error_code: u64, // code is always zero +) { + match get_expected_fault() { + Interrupts::DoubleFault => qemu::exit_qemu(qemu::QemuExitCode::Success), + _ => panic!( + "DOUBLE FAULT\nthis is a fatal exception\n{}", + exception_default!(stack_frame) + ), + } +} -- cgit v1.2.3-54-g00ecf