kernel/arch/x86_64/cpu/tables/
tss.rs1use crate::kinfo;
8use crate::lib::addr::VirtAddr;
9use crate::lib::types::aligned_stack::AlignedStack;
10use core::cell::UnsafeCell;
11use x86_64::structures::tss::TaskStateSegment;
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: UnsafeCell<TaskStateSegment>,
22 ist1: AlignedStack<8192>,
23 ist2: AlignedStack<8192>,
24 ist3: AlignedStack<8192>,
25 ist4: AlignedStack<8192>,
26}
27
28unsafe impl Sync for Tss {}
31
32impl Tss {
33 pub const fn new() -> Self {
35 Self {
36 tss: UnsafeCell::new(TaskStateSegment::new()),
37 ist1: AlignedStack::new(),
38 ist2: AlignedStack::new(),
39 ist3: AlignedStack::new(),
40 ist4: AlignedStack::new(),
41 }
42 }
43
44 pub unsafe fn init(&'static self) {
50 let ist1_top = self.ist1.get_stack_top();
51 let ist2_top = self.ist2.get_stack_top();
52 let ist3_top = self.ist3.get_stack_top();
53 let ist4_top = self.ist4.get_stack_top();
54
55 let tss = unsafe { &mut *self.tss.get() };
56
57 tss.privilege_stack_table[0] = VirtAddr::null().as_x86_64();
58 tss.interrupt_stack_table[DOUBLE_FAULT_IST_STACK_INDEX] = ist1_top.as_x86_64();
59 tss.interrupt_stack_table[DEBUG_IST_STACK_INDEX] = ist2_top.as_x86_64();
60 tss.interrupt_stack_table[NMI_IST_STACK_INDEX] = ist3_top.as_x86_64();
61 tss.interrupt_stack_table[MACHINE_CHECK_IST_STACK_INDEX] = ist4_top.as_x86_64();
62
63 kinfo!("Initialized TSS");
64 }
65
66 pub unsafe fn tss(&'static self) -> &'static TaskStateSegment {
71 unsafe { &*self.tss.get() }
72 }
73
74 pub unsafe fn set_rsp0(&self, new_rsp0: VirtAddr) {
83 unsafe { (*self.tss.get()).privilege_stack_table[0] = new_rsp0.as_x86_64() };
84 }
85}