48 lines
1.7 KiB
Rust
48 lines
1.7 KiB
Rust
// Copyright (c) 2025 shibedrill
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
use crate::format;
|
|
use lazy_static::lazy_static;
|
|
use x86_64::structures::idt::*;
|
|
|
|
lazy_static! {
|
|
pub static ref IDT: InterruptDescriptorTable = {
|
|
let mut idt = InterruptDescriptorTable::new();
|
|
// TODO: Rewrite using our own x86 interrupt wrapper
|
|
// code. The x86_interrupt ABI is always breaking, and this
|
|
// approach will fall apart once multiarch support is re-added.
|
|
idt.double_fault.set_handler_fn(double_fault);
|
|
idt.page_fault.set_handler_fn(page_fault);
|
|
idt
|
|
};
|
|
}
|
|
|
|
// Must do this to avoid unused function warning
|
|
#[allow(dead_code)]
|
|
extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
|
|
crate::interrupt::double_fault(format!("{info:#?}"));
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) {
|
|
if errcode.contains(PageFaultErrorCode::USER_MODE) {
|
|
// Fault occurred in usermode. Non fatal.
|
|
todo!()
|
|
} else {
|
|
// Fault occurred in kernel mode. This is possibly fatal.
|
|
// This is recoverable if we simply hit an unavailable page,
|
|
// but unrecoverable if we hit a nonexistent or invalid page.
|
|
if errcode.contains(PageFaultErrorCode::PROTECTION_VIOLATION)
|
|
| errcode.contains(PageFaultErrorCode::MALFORMED_TABLE)
|
|
{
|
|
let addr = unsafe {
|
|
let a: usize;
|
|
core::arch::asm! {"mov {}, cr2", out(reg) a};
|
|
a
|
|
};
|
|
let info_formatted = format!("{info:#?}");
|
|
crate::interrupt::page_fault(addr, info_formatted)
|
|
}
|
|
}
|
|
}
|