diff options
author | Dennis Kobert <dennis@kobert.dev> | 2019-11-15 20:21:25 +0100 |
---|---|---|
committer | Dennis Kobert <dennis@kobert.dev> | 2019-11-15 20:21:25 +0100 |
commit | 6590a5acfee33bae3ca0431c8af09768248fe405 (patch) | |
tree | 8aeb110464ac6b6f715118ea1d14edf3d04b83a4 /kernel/src/interrupts/exception_handlers.rs | |
parent | c6e0e13db0ba0442018645a1184be50e1ec968e0 (diff) |
Rename interrupt and exception handlers
Diffstat (limited to 'kernel/src/interrupts/exception_handlers.rs')
-rw-r--r-- | kernel/src/interrupts/exception_handlers.rs | 95 |
1 files changed, 95 insertions, 0 deletions
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) + ), + } +} |