Files
grug_os/x86_drivers/src/idt.rs

57 lines
1.1 KiB
Rust

use crate::gdt::{DPL, GdtSelector};
#[repr(C, packed)]
pub struct InterruptTableDescriptor {
size: u16,
offset: u64,
}
#[repr(transparent)]
pub struct IdtTableEntry {
inner: u128,
}
pub type ISR = extern "x86-interrupt" fn(InterruptStackFrame) -> ();
#[repr(C)]
pub struct InterruptStackFrame {
ip: usize,
cs: usize,
flags: usize,
sp: usize,
ss: usize,
}
#[repr(u8)]
pub enum Gate {
Interrupt = 0b1110,
Trap = 0b1111,
}
impl IdtTableEntry {
pub fn new(isr: ISR, selector: GdtSelector, ist: u8, gate: Gate, priority: DPL) -> Self {
let mut inner = 0b0;
let offset = (isr as *const ()) as u64;
let bytes = (offset >> 32) as u32;
inner |= (bytes as u128) << 64;
let bytes = (offset as u32) >> 16;
inner |= (bytes as u128) << 48;
let bytes = offset as u16;
inner |= bytes as u128;
inner |= (selector.raw() as u128) << 16;
assert!(ist <= 0b111);
inner |= (ist as u128) << 32;
inner |= (gate as u128) << 40;
inner |= (priority as u128) << 45;
inner |= 1 << 47;
Self { inner }
}
}