Fix interrupts
Some checks failed
Continuous Integration / Build (x86_64) (push) Waiting to run
Continuous Integration / Clippy (push) Failing after 6m32s
Continuous Integration / Check (push) Failing after 13m58s
Continuous Integration / Rustfmt (push) Failing after 10m40s

This commit is contained in:
August 2025-09-24 18:38:28 -04:00
parent b6f9889c15
commit d61dd8383b
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2
3 changed files with 36 additions and 28 deletions

View File

@ -3,31 +3,42 @@
use lazy_static::lazy_static;
use x86_64::structures::idt::*;
use crate::format;
lazy_static! {
pub static ref IDT: InterruptDescriptorTable = {
InterruptDescriptorTable::new()
let mut idt = InterruptDescriptorTable::new();
// TODO: Re-implement this once the x86-interrupt ABI is fixed.
// Alternatively: Write our own interrupt handler wrappers.
idt.double_fault.set_handler_fn(double_fault);
idt.page_fault.set_handler_fn(page_fault);
idt
};
}
// For all these handlers, they will be called from a purely naked ASM
// function. That function will first push all registers to the stack.
// It is the responsibility of these functions to recover this info.
extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
crate::interrupt::double_fault(format!("{info:#?}"));
}
// Recoverable exception: Occurs on division failure.
#[unsafe(no_mangle)]
pub extern "C" fn x86_divide_error() {}
// Recoverable exception: Occurs on failure in BOUND instruction.
#[unsafe(no_mangle)]
pub extern "C" fn x86_bound_range() {}
// Recoverable exception: Invalid opcode.
#[unsafe(no_mangle)]
pub extern "C" fn x86_invalid_opcode() {}
// Recoverable exception: FPU not available or enabled.
#[unsafe(no_mangle)]
pub extern "C" fn x86_device_unavailable() {}
#[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)
}
}
}

View File

@ -1,16 +1,12 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
use core::str;
use crate::memory::alloc::string::String;
#[unsafe(no_mangle)]
extern "C" fn double_fault(info: *const u8, info_len: usize) -> ! {
let info_slice = unsafe { &str::from_raw_parts(info, info_len) };
panic!("Double fault: {}", info_slice);
pub fn double_fault(info: String) -> ! {
panic!("Double fault: {}", info);
}
#[unsafe(no_mangle)]
pub extern "C" fn page_fault(addr: usize, info: *const u8, info_len: usize) -> ! {
let info_slice = unsafe { &str::from_raw_parts(info, info_len) };
panic!("Page fault at 0x{:X}: {}", addr, info_slice);
pub fn page_fault(addr: usize, info: String) -> ! {
panic!("Page fault at 0x{:X}: {}", addr, info);
}

View File

@ -5,6 +5,7 @@
#![no_main]
#![feature(allocator_api)]
#![feature(str_from_raw_parts)]
#![feature(abi_x86_interrupt)]
mod arch;
mod boot;