Fix interrupts
This commit is contained in:
parent
b6f9889c15
commit
d61dd8383b
@ -3,31 +3,42 @@
|
|||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use x86_64::structures::idt::*;
|
use x86_64::structures::idt::*;
|
||||||
|
use crate::format;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref IDT: InterruptDescriptorTable = {
|
pub static ref IDT: InterruptDescriptorTable = {
|
||||||
InterruptDescriptorTable::new()
|
let mut idt = InterruptDescriptorTable::new();
|
||||||
// TODO: Re-implement this once the x86-interrupt ABI is fixed.
|
// TODO: Re-implement this once the x86-interrupt ABI is fixed.
|
||||||
// Alternatively: Write our own interrupt handler wrappers.
|
// 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
|
extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
|
||||||
// function. That function will first push all registers to the stack.
|
crate::interrupt::double_fault(format!("{info:#?}"));
|
||||||
// It is the responsibility of these functions to recover this info.
|
}
|
||||||
|
|
||||||
// Recoverable exception: Occurs on division failure.
|
#[allow(dead_code)]
|
||||||
#[unsafe(no_mangle)]
|
extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) {
|
||||||
pub extern "C" fn x86_divide_error() {}
|
if errcode.contains(PageFaultErrorCode::USER_MODE) {
|
||||||
|
// Fault occurred in usermode. Non fatal.
|
||||||
// Recoverable exception: Occurs on failure in BOUND instruction.
|
todo!()
|
||||||
#[unsafe(no_mangle)]
|
} else {
|
||||||
pub extern "C" fn x86_bound_range() {}
|
// Fault occurred in kernel mode. This is possibly fatal.
|
||||||
|
// This is recoverable if we simply hit an unavailable page,
|
||||||
// Recoverable exception: Invalid opcode.
|
// but unrecoverable if we hit a nonexistent or invalid page.
|
||||||
#[unsafe(no_mangle)]
|
if errcode.contains(PageFaultErrorCode::PROTECTION_VIOLATION)
|
||||||
pub extern "C" fn x86_invalid_opcode() {}
|
| errcode.contains(PageFaultErrorCode::MALFORMED_TABLE)
|
||||||
|
{
|
||||||
// Recoverable exception: FPU not available or enabled.
|
let addr = unsafe {
|
||||||
#[unsafe(no_mangle)]
|
let a: usize;
|
||||||
pub extern "C" fn x86_device_unavailable() {}
|
core::arch::asm! {"mov {}, cr2", out(reg) a};
|
||||||
|
a
|
||||||
|
};
|
||||||
|
let info_formatted = format!("{info:#?}");
|
||||||
|
crate::interrupt::page_fault(addr, info_formatted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
// Copyright (c) 2025 shibedrill
|
// Copyright (c) 2025 shibedrill
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use core::str;
|
use crate::memory::alloc::string::String;
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
pub fn double_fault(info: String) -> ! {
|
||||||
extern "C" fn double_fault(info: *const u8, info_len: usize) -> ! {
|
panic!("Double fault: {}", info);
|
||||||
let info_slice = unsafe { &str::from_raw_parts(info, info_len) };
|
|
||||||
panic!("Double fault: {}", info_slice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
pub fn page_fault(addr: usize, info: String) -> ! {
|
||||||
pub extern "C" fn page_fault(addr: usize, info: *const u8, info_len: usize) -> ! {
|
panic!("Page fault at 0x{:X}: {}", addr, info);
|
||||||
let info_slice = unsafe { &str::from_raw_parts(info, info_len) };
|
|
||||||
panic!("Page fault at 0x{:X}: {}", addr, info_slice);
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
#![feature(str_from_raw_parts)]
|
#![feature(str_from_raw_parts)]
|
||||||
|
#![feature(abi_x86_interrupt)]
|
||||||
|
|
||||||
mod arch;
|
mod arch;
|
||||||
mod boot;
|
mod boot;
|
||||||
|
Loading…
Reference in New Issue
Block a user