50 lines
1.4 KiB
Rust
50 lines
1.4 KiB
Rust
use lazy_static::lazy_static;
|
|
use x86_64::{
|
|
structures::{
|
|
gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector},
|
|
tss::TaskStateSegment,
|
|
},
|
|
VirtAddr, registers::segmentation::{CS, Segment}, instructions::tables::load_tss,
|
|
};
|
|
|
|
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
|
|
|
|
pub fn init() {
|
|
GDT.0.load();
|
|
unsafe {
|
|
CS::set_reg(GDT.1.code);
|
|
load_tss(GDT.1.tss);
|
|
// TODO: properly handle this
|
|
x86_64::registers::segmentation::SS::set_reg(SegmentSelector::NULL);
|
|
}
|
|
}
|
|
|
|
struct Selectors {
|
|
code: SegmentSelector,
|
|
tss: SegmentSelector,
|
|
}
|
|
|
|
lazy_static! {
|
|
static ref GDT: (GlobalDescriptorTable, Selectors) = {
|
|
let mut gdt = GlobalDescriptorTable::new();
|
|
let code = gdt.add_entry(Descriptor::kernel_code_segment());
|
|
let tss = gdt.add_entry(Descriptor::tss_segment(&TSS));
|
|
(gdt, Selectors { code, tss })
|
|
};
|
|
}
|
|
|
|
lazy_static! {
|
|
static ref TSS: TaskStateSegment = {
|
|
let mut tss = TaskStateSegment::new();
|
|
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
|
|
const STACK_SIZE: usize = 4096 * 5;
|
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
|
|
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
|
let stack_end = stack_start + STACK_SIZE;
|
|
stack_end
|
|
};
|
|
tss
|
|
};
|
|
}
|