kernel/arch/x86_64/tables/
tss.rs1use crate::kinfo;
8use crate::types::aligned_stack::AlignedStack;
9use spin::Once;
10use x86_64::structures::tss::TaskStateSegment;
11use x86_64::VirtAddr;
12
13pub const DOUBLE_FAULT_IST_STACK_INDEX: usize = 0;
14pub const DEBUG_IST_STACK_INDEX: usize = 1;
15pub const NMI_IST_STACK_INDEX: usize = 2;
16pub const MACHINE_CHECK_IST_STACK_INDEX: usize = 3;
17
18pub struct Tss {
21 tss: Once<TaskStateSegment>,
22 ist1: AlignedStack<8192>,
23 ist2: AlignedStack<8192>,
24 ist3: AlignedStack<8192>,
25 ist4: AlignedStack<8192>,
26}
27
28impl Tss {
29 pub const fn new() -> Self {
31 Self {
32 tss: Once::new(),
33 ist1: AlignedStack { array: [0u8; 8192] },
34 ist2: AlignedStack { array: [0u8; 8192] },
35 ist3: AlignedStack { array: [0u8; 8192] },
36 ist4: AlignedStack { array: [0u8; 8192] },
37 }
38 }
39
40 pub fn init(&self) {
42 unsafe {
46 let ist1_top = VirtAddr::from_ptr(self.ist1.array.as_ptr().add(self.ist1.array.len()));
47 let ist2_top = VirtAddr::from_ptr(self.ist2.array.as_ptr().add(self.ist2.array.len()));
48 let ist3_top = VirtAddr::from_ptr(self.ist3.array.as_ptr().add(self.ist3.array.len()));
49 let ist4_top = VirtAddr::from_ptr(self.ist4.array.as_ptr().add(self.ist4.array.len()));
50
51 self.tss.call_once(|| {
52 let mut tss = TaskStateSegment::new();
53 tss.interrupt_stack_table[DOUBLE_FAULT_IST_STACK_INDEX] = ist1_top;
54 tss.interrupt_stack_table[DEBUG_IST_STACK_INDEX] = ist2_top;
55 tss.interrupt_stack_table[NMI_IST_STACK_INDEX] = ist3_top;
56 tss.interrupt_stack_table[MACHINE_CHECK_IST_STACK_INDEX] = ist4_top;
57 tss
58 });
59 }
60
61 kinfo!("Initialized TSS");
62 }
63
64 pub fn get(&self) -> &TaskStateSegment {
69 self.tss.get().unwrap()
70 }
71}