2023-04-26 14:33:40 -05:00
|
|
|
use {
|
|
|
|
spin::Lazy,
|
|
|
|
x86_64::{
|
|
|
|
structures::{
|
|
|
|
gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector},
|
|
|
|
tss::TaskStateSegment,
|
|
|
|
},
|
|
|
|
VirtAddr,
|
2023-03-30 16:43:04 -05:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
pub const DOUBLE_FAULT_IX: u16 = 0;
|
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
const STACK_SIZE: usize = 5 * 1024;
|
2024-09-16 14:15:51 -05:00
|
|
|
const STACK_ALIGNMENT: usize = 1;
|
2024-09-13 16:41:31 -05:00
|
|
|
|
2023-03-30 16:43:04 -05:00
|
|
|
pub unsafe fn init() {
|
2023-04-26 14:33:40 -05:00
|
|
|
use x86_64::instructions::{
|
|
|
|
segmentation::{Segment, CS, SS},
|
|
|
|
tables::load_tss,
|
|
|
|
};
|
2023-03-30 16:43:04 -05:00
|
|
|
|
2023-05-26 06:30:17 -05:00
|
|
|
log::trace!("Initialising GDT");
|
2023-03-30 16:43:04 -05:00
|
|
|
GDT.0.load();
|
|
|
|
CS::set_reg(GDT.1.kcode);
|
|
|
|
SS::set_reg(GDT.1.kdata);
|
|
|
|
load_tss(GDT.1.tss);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Selectors {
|
|
|
|
kcode: SegmentSelector,
|
|
|
|
kdata: SegmentSelector,
|
2023-04-26 14:33:40 -05:00
|
|
|
tss: SegmentSelector,
|
2023-03-30 16:43:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
|
|
|
let mut tss = TaskStateSegment::new();
|
2024-09-13 16:41:31 -05:00
|
|
|
|
|
|
|
let stack_ptr = unsafe {
|
|
|
|
let layout = alloc::alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGNMENT)
|
|
|
|
.expect("Failed to create stack layout");
|
2024-09-16 14:15:51 -05:00
|
|
|
let stack = alloc::alloc::alloc(layout);
|
2024-09-13 16:41:31 -05:00
|
|
|
VirtAddr::from_ptr(stack) + STACK_SIZE as u64
|
2023-03-30 16:43:04 -05:00
|
|
|
};
|
2024-09-13 16:41:31 -05:00
|
|
|
|
|
|
|
tss.interrupt_stack_table[usize::from(DOUBLE_FAULT_IX)] = stack_ptr;
|
2023-03-30 16:43:04 -05:00
|
|
|
tss
|
|
|
|
});
|
|
|
|
|
|
|
|
static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
|
|
|
|
let mut gdt = GlobalDescriptorTable::new();
|
|
|
|
let sels = Selectors {
|
2024-09-13 16:41:31 -05:00
|
|
|
kcode: gdt.append(Descriptor::kernel_code_segment()),
|
|
|
|
kdata: gdt.append(Descriptor::kernel_data_segment()),
|
|
|
|
tss: gdt.append(Descriptor::tss_segment(&TSS)),
|
2023-03-30 16:43:04 -05:00
|
|
|
};
|
|
|
|
(gdt, sels)
|
|
|
|
});
|