dendrobates-t-azureus/src/interrupts.rs
2020-05-29 16:26:53 +02:00

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();
}