57 lines
1.1 KiB
Rust
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 }
|
|
}
|
|
}
|