rustubs/arch/x86_64/interrupt/
idt.rs1use crate::defs::ExternSyms;
2use crate::defs::HWDefs::*;
3use crate::io::*;
4use crate::ExternSyms::{IDT, IDT_DESCR, VECTORS_START};
5use core::arch::asm;
6use core::slice;
7
8#[inline(always)]
13pub fn init() {
14 println!("[init] idt: VECTORS_START: 0x{:x}", VECTORS_START as usize);
15
16 let gate_descriptors: &mut [GateDescriptor64] = unsafe {
17 slice::from_raw_parts_mut(IDT as *mut GateDescriptor64, IDT_CAPACITY)
18 };
19
20 for i in 0..IDT_VALID {
22 let offset = VECTORS_START as usize + (i * VECTOR_SIZE);
23 gate_descriptors[i].set_default_interrupt(offset as u64);
24 }
25 let offset_inv: usize = VECTORS_START as usize + (IDT_VALID * VECTOR_SIZE);
26 for i in IDT_VALID..IDT_CAPACITY {
27 gate_descriptors[i].set_default_interrupt(offset_inv as u64);
28 }
29
30 gate_descriptors[0x80].set_syscall_gate(ExternSyms::VECTOR_128 as u64);
32
33 unsafe { asm! ("lidt [{}]", in(reg) IDT_DESCR) }
35}
36
37#[repr(C)]
52#[repr(packed)]
53struct GateDescriptor64 {
54 pub offset_1: u16,
55 pub selector: u16,
56 pub ist: u8,
57 pub attrs: u8,
58 pub offset_2: u16,
59 pub offset_3: u32,
60 res0: u32, }
62
63impl GateDescriptor64 {
65 #[inline(always)]
66 fn set_offset(&mut self, offset: u64) {
67 self.offset_1 = (offset & 0xffff) as u16;
68 self.offset_2 = ((offset & 0xffff0000) >> 16) as u16;
69 self.offset_3 = ((offset & 0xffffffff00000000) >> 32) as u32;
70 }
71 fn set_default_interrupt(&mut self, offset: u64) {
73 self.set_offset(offset);
74 self.selector = 0x8 * 2;
75 self.attrs = 0x8e;
76 self.ist = 0;
77 self.res0 = 0;
78 }
79 fn set_syscall_gate(&mut self, offset: u64) {
82 self.set_offset(offset);
83 self.selector = crate::defs::HWDefs::SEG_KERNEL_CODE;
84 self.attrs = 0xee;
85 self.ist = 0;
86 self.res0 = 0;
87 }
88}