1use crate::{cpu, segment, VAddr};
2use core::mem;
3use mycelium_util::fmt;
4
5#[derive(Clone, Copy)]
7#[repr(C, packed(4))]
8pub struct StateSegment {
9 _reserved_1: u32,
10 pub privilege_stacks: [VAddr; 3],
14 _reserved_2: u64,
15 pub interrupt_stacks: [VAddr; 7],
17 _reserved_3: u64,
18 _reserved_4: u16,
19 pub iomap_offset: u16,
21}
22
23impl StateSegment {
24 pub const fn empty() -> Self {
26 Self {
27 privilege_stacks: [VAddr::zero(); 3],
28 interrupt_stacks: [VAddr::zero(); 7],
29 iomap_offset: mem::size_of::<Self>() as u16,
30 _reserved_1: 0,
31 _reserved_2: 0,
32 _reserved_3: 0,
33 _reserved_4: 0,
34 }
35 }
36
37 #[inline]
39 pub fn iomap_addr(&self) -> VAddr {
40 VAddr::of(self).offset(self.iomap_offset as isize)
41 }
42
43 pub unsafe fn load_tss(selector: segment::Selector) {
56 tracing::trace!(?selector, "setting TSS...");
57 cpu::intrinsics::ltr(selector);
58 tracing::debug!(?selector, "TSS set");
59 }
60}
61
62impl Default for StateSegment {
63 fn default() -> Self {
64 Self::empty()
65 }
66}
67
68impl fmt::Debug for StateSegment {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 let Self {
71 privilege_stacks,
72 interrupt_stacks,
73 iomap_offset,
74 _reserved_1: _,
75 _reserved_2: _,
76 _reserved_3: _,
77 _reserved_4: _,
78 } = *self;
79 f.debug_struct("task::StateSegment")
80 .field("privilege_stacks", &privilege_stacks)
81 .field("interrupt_stacks", &interrupt_stacks)
82 .field("iomap_offset", &fmt::hex(iomap_offset))
83 .field("iomap_addr", &self.iomap_addr())
84 .finish()
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn sizeof_tss() {
94 assert_eq!(mem::size_of::<StateSegment>(), 0x68)
95 }
96}