90 lines
3.0 KiB
Rust
90 lines
3.0 KiB
Rust
use lazy_static::lazy_static;
|
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
|
|
|
use crate::gdt;
|
|
use crate::hlt_loop;
|
|
use polling_serial::serial_println;
|
|
use vga_buffer::println;
|
|
|
|
lazy_static! {
|
|
static ref IDT: InterruptDescriptorTable = {
|
|
let mut idt = InterruptDescriptorTable::new();
|
|
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
|
idt.double_fault.set_handler_fn(double_fault_handler);
|
|
unsafe {
|
|
idt.double_fault
|
|
.set_handler_fn(double_fault_handler)
|
|
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
|
|
}
|
|
idt.page_fault.set_handler_fn(page_fault_handler);
|
|
idt
|
|
};
|
|
}
|
|
|
|
pub fn init_idt() {
|
|
IDT.load();
|
|
}
|
|
|
|
// For now.
|
|
extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFrame) {
|
|
serial_println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
|
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
|
x86_64::instructions::bochs_breakpoint();
|
|
}
|
|
|
|
extern "x86-interrupt" fn double_fault_handler(sf: &mut InterruptStackFrame, e: u64) -> ! {
|
|
// LLVM bug causing misaligned stacks when error codes are present.
|
|
// This code realigns the stack and then grabs the correct values by doing some pointer arithmetic
|
|
let stack_frame: &mut InterruptStackFrame;
|
|
let error_code: u64;
|
|
|
|
unsafe {
|
|
llvm_asm!("push rax" :::: "intel");
|
|
let s = sf as *mut InterruptStackFrame;
|
|
stack_frame = &mut *((s as *mut u64).offset(1) as *mut InterruptStackFrame);
|
|
error_code = *(&e as *const u64).offset(1);
|
|
}
|
|
// End Hack
|
|
|
|
println!(
|
|
"=====\nUNRECOVERABLE EXCEPTION:\nDouble Fault\nError Code {:x?}\n{:#?}\n=====",
|
|
error_code, stack_frame
|
|
);
|
|
serial_println!(
|
|
"=====\nUNRECOVERABLE EXCEPTION:\nDouble Fault\nError Code {:x?}\n{:#?}\n=====",
|
|
error_code,
|
|
stack_frame
|
|
);
|
|
|
|
panic!("Unrecoverable exception");
|
|
}
|
|
|
|
use x86_64::instructions::bochs_breakpoint;
|
|
use x86_64::structures::idt::PageFaultErrorCode;
|
|
|
|
extern "x86-interrupt" fn page_fault_handler(sf: &mut InterruptStackFrame, e: PageFaultErrorCode) {
|
|
// LLVM bug causing misaligned stacks when error codes are present.
|
|
// This code realigns the stack and then grabs the correct values by doing some pointer arithmetic
|
|
let stack_frame: &mut InterruptStackFrame;
|
|
let error_code: PageFaultErrorCode;
|
|
|
|
use x86_64::registers::control::Cr2;
|
|
|
|
unsafe {
|
|
llvm_asm!("push rax" :::: "intel");
|
|
let s = sf as *mut InterruptStackFrame;
|
|
stack_frame = &mut *((s as *mut u64).offset(1) as *mut InterruptStackFrame);
|
|
error_code = *(&e as *const PageFaultErrorCode).offset(1) as PageFaultErrorCode;
|
|
}
|
|
|
|
serial_println!("EXCEPTION: PAGE FAULT");
|
|
serial_println!("Accessed Address: {:?}", Cr2::read());
|
|
serial_println!("Error Code: {:?}", error_code);
|
|
serial_println!("{:#?}", stack_frame);
|
|
|
|
serial_println!("Halting...");
|
|
bochs_breakpoint();
|
|
|
|
hlt_loop();
|
|
}
|