gila/src/kernel/arch/x86_64/interrupts.rs

43 lines
1.4 KiB
Rust

// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
use lazy_static::lazy_static;
use x86_64::structures::idt::*;
use crate::format;
lazy_static! {
pub static ref IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new();
// TODO: Re-implement this once the x86-interrupt ABI is fixed.
//idt.double_fault.set_handler_fn(double_fault);
idt.page_fault.set_handler_fn(page_fault);
idt
};
}
//extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
// crate::interrupt::double_fault(&format!("{info:#?}"));
//}
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
};
crate::interrupt::page_fault(addr, &format!("{info:#?}"))
}
}
}