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