feat: initial scalable x86_64 microkernel skeleton with Limine, Rust, C HAL, and C++20 IPC
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
//! Interrupt Descriptor Table (IDT) and Exception Handling
|
||||
|
||||
use crate::kprintln;
|
||||
use core::mem::size_of;
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct IdtEntry {
|
||||
offset_low: u16,
|
||||
selector: u16,
|
||||
ist: u8,
|
||||
type_attr: u8,
|
||||
offset_mid: u16,
|
||||
offset_high: u32,
|
||||
_reserved: u32,
|
||||
}
|
||||
|
||||
impl IdtEntry {
|
||||
pub const fn missing() -> Self {
|
||||
Self {
|
||||
offset_low: 0,
|
||||
selector: 0,
|
||||
ist: 0,
|
||||
type_attr: 0,
|
||||
offset_mid: 0,
|
||||
offset_high: 0,
|
||||
_reserved: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_handler(&mut self, handler: u64, ist: u8, dpl: u8) {
|
||||
self.offset_low = (handler & 0xffff) as u16;
|
||||
self.selector = 0x08; // Kernel code segment
|
||||
self.ist = ist & 0x7;
|
||||
self.type_attr = 0x80 | ((dpl & 0x3) << 5) | 0x0E; // 64-bit Interrupt Gate Present
|
||||
self.offset_mid = ((handler >> 16) & 0xffff) as u16;
|
||||
self.offset_high = ((handler >> 32) & 0xffffffff) as u32;
|
||||
self._reserved = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C, packed)]
|
||||
struct IdtDescriptor {
|
||||
limit: u16,
|
||||
base: u64,
|
||||
}
|
||||
|
||||
static mut IDT: [IdtEntry; 256] = [IdtEntry::missing(); 256];
|
||||
|
||||
extern "C" {
|
||||
fn default_isr_stub();
|
||||
}
|
||||
|
||||
// Global assembly ISR stub for default exception handling
|
||||
core::arch::global_asm!(
|
||||
".global default_isr_stub",
|
||||
"default_isr_stub:",
|
||||
"push rax",
|
||||
"push rcx",
|
||||
"push rdx",
|
||||
"push rsi",
|
||||
"push rdi",
|
||||
"push r8",
|
||||
"push r9",
|
||||
"push r10",
|
||||
"push r11",
|
||||
"mov rdi, rsp",
|
||||
"call raw_exception_handler",
|
||||
"pop r11",
|
||||
"pop r10",
|
||||
"pop r9",
|
||||
"pop r8",
|
||||
"pop rdi",
|
||||
"pop rsi",
|
||||
"pop rdx",
|
||||
"pop rcx",
|
||||
"pop rax",
|
||||
"iretq"
|
||||
);
|
||||
|
||||
pub unsafe fn init() {
|
||||
let stub_addr = default_isr_stub as *const () as usize as u64;
|
||||
let idt_ptr = core::ptr::addr_of_mut!(IDT) as *mut IdtEntry;
|
||||
for i in 0..256 {
|
||||
(*idt_ptr.add(i)).set_handler(stub_addr, 0, 0);
|
||||
}
|
||||
|
||||
let descriptor = IdtDescriptor {
|
||||
limit: (size_of::<[IdtEntry; 256]>() - 1) as u16,
|
||||
base: idt_ptr as u64,
|
||||
};
|
||||
|
||||
core::arch::asm!("lidt [{0}]", in(reg) &descriptor, options(preserves_flags));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn raw_exception_handler(stack_ptr: *const u64) {
|
||||
kprintln!("[CPU EXCEPTION] Trap triggered at stack frame: {:p}", stack_ptr);
|
||||
}
|
||||
Reference in New Issue
Block a user