proka_kernel/interrupts/
gdt.rs1use lazy_static::lazy_static;
2use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
3use x86_64::structures::tss::TaskStateSegment;
4use x86_64::VirtAddr;
5
6pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
7
8lazy_static! {
9 static ref TSS: TaskStateSegment = {
10 let mut tss = TaskStateSegment::new();
11 tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
12 const STACK_SIZE: usize = 8192 * 5;
13 static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
14
15 let stack_start = VirtAddr::from_ptr(&raw const STACK);
16 stack_start + STACK_SIZE as u64
17 };
18 tss
19 };
20}
21
22lazy_static! {
23 static ref GDT: (GlobalDescriptorTable, Selectors) = {
24 let mut gdt = GlobalDescriptorTable::new();
25 let code_selector = gdt.append(Descriptor::kernel_code_segment());
26 let data_selector = gdt.append(Descriptor::kernel_data_segment());
27 let tss_selector = gdt.append(Descriptor::tss_segment(&TSS));
28 (
29 gdt,
30 Selectors {
31 code_selector,
32 data_selector,
33 tss_selector,
34 },
35 )
36 };
37}
38
39struct Selectors {
40 code_selector: SegmentSelector,
41 data_selector: SegmentSelector,
42 tss_selector: SegmentSelector,
43}
44
45pub fn init() {
46 use x86_64::instructions::segmentation::{Segment, CS, DS, ES, SS};
47 use x86_64::instructions::tables::load_tss;
48
49 GDT.0.load();
50 unsafe {
51 CS::set_reg(GDT.1.code_selector);
52 SS::set_reg(GDT.1.data_selector);
53 DS::set_reg(GDT.1.data_selector);
54 ES::set_reg(GDT.1.data_selector);
55 load_tss(GDT.1.tss_selector);
56 }
57}