x86_64/structures/tss.rs
1//! Provides a type for the task state segment structure.
2
3use crate::VirtAddr;
4use core::mem::size_of;
5
6/// In 64-bit mode the TSS holds information that is not
7/// directly related to the task-switch mechanism,
8/// but is used for stack switching when an interrupt or exception occurs.
9#[derive(Debug, Clone, Copy)]
10#[repr(C, packed(4))]
11pub struct TaskStateSegment {
12 reserved_1: u32,
13 /// The full 64-bit canonical forms of the stack pointers (RSP) for privilege levels 0-2.
14 /// The stack pointers used when a privilege level change occurs from a lower privilege level to a higher one.
15 pub privilege_stack_table: [VirtAddr; 3],
16 reserved_2: u64,
17 /// The full 64-bit canonical forms of the interrupt stack table (IST) pointers.
18 /// The stack pointers used when an entry in the Interrupt Descriptor Table has an IST value other than 0.
19 pub interrupt_stack_table: [VirtAddr; 7],
20 reserved_3: u64,
21 reserved_4: u16,
22 /// The 16-bit offset to the I/O permission bit map from the 64-bit TSS base.
23 pub iomap_base: u16,
24}
25
26impl TaskStateSegment {
27 /// Creates a new TSS with zeroed privilege and interrupt stack table and an
28 /// empty I/O-Permission Bitmap.
29 ///
30 /// As we always set the TSS segment limit to
31 /// `size_of::<TaskStateSegment>() - 1`, this means that `iomap_base` is
32 /// initialized to `size_of::<TaskStateSegment>()`.
33 #[inline]
34 pub const fn new() -> TaskStateSegment {
35 TaskStateSegment {
36 privilege_stack_table: [VirtAddr::zero(); 3],
37 interrupt_stack_table: [VirtAddr::zero(); 7],
38 iomap_base: size_of::<TaskStateSegment>() as u16,
39 reserved_1: 0,
40 reserved_2: 0,
41 reserved_3: 0,
42 reserved_4: 0,
43 }
44 }
45}
46
47impl Default for TaskStateSegment {
48 #[inline]
49 fn default() -> Self {
50 Self::new()
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 pub fn check_tss_size() {
60 // Per the SDM, the minimum size of a TSS is 0x68 bytes, giving a
61 // minimum limit of 0x67.
62 assert_eq!(size_of::<TaskStateSegment>(), 0x68);
63 }
64}