gila/src/kernel/arch/x86_64/interrupts.rs
August 65804ef56a
Some checks are pending
Continuous Integration / Rustfmt (push) Waiting to run
Continuous Integration / Clippy (push) Waiting to run
Continuous Integration / Build (x86_64) (push) Waiting to run
Continuous Integration / Check (push) Successful in 5m21s
Docs, linting
2025-09-24 23:40:55 -04:00

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