tartan_arch/x86_64/
protection.rs

1//! Support for protected mode operation.
2//!
3//! This includes the minimal support for segmented memory and hardware task management
4//! that is required to operate in protected mode with a flat memory model.
5
6use core::mem::size_of;
7
8#[cfg(doc)]
9use crate::x86_common::protection::{GateDescriptorFlags, IOPermissionBitmap};
10
11
12/// Stack and I/O permission map pointers that make up the most significant part of a task
13/// state segment (TSS).
14///
15/// Since 64-bit mode does not support task switching, the name is a historical artifact,
16/// and this does not store any real task state.
17#[repr(C, packed(16))]
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct TaskStateSegmentHeader {
20    _reserved_a: u32,
21
22    /// Stack pointers to use when switching to privilege levels 0–2.
23    pub privileged_stack: [u64; 3],
24
25    _reserved_b: u64,
26
27    /// Stack pointers available for use when handling interrupts. The specific entry
28    /// used is determined by the
29    /// [`interrupt_stack_index`](GateDescriptorFlags::interrupt_stack_index) field of
30    /// the relevant interrupt gate descriptor.
31    pub interrupt_stack: [u64; 7],
32
33    _reserved_c: u64,
34    _reserved_d: u16,
35
36    /// Offset from the start of this structure to start of the [`IOPermissionBitmap`].
37    ///
38    /// The I/O permission map ends at the limit of the containing segment, and must be
39    /// at least two bytes. If this offset is equal to or greater than the limit,
40    /// then the permission map is empty and all ports are assumed to be zero.
41    ///
42    /// Not modified by the processor on a task switch.
43    pub io_permission_map_offset: u16,
44}
45
46impl TaskStateSegmentHeader {
47    /// Create a header with zero-initialized stack pointers and an
48    /// [`io_permission_map_offset`](Self::io_permission_map_offset) that points directly
49    /// after the header.
50    pub const fn new() -> Self {
51        #[allow(clippy::cast_possible_truncation)]
52        Self {
53            privileged_stack: [0; 3],
54            interrupt_stack: [0; 7],
55            io_permission_map_offset: size_of::<Self>() as u16,
56
57            _reserved_a: 0,
58            _reserved_b: 0,
59            _reserved_c: 0,
60            _reserved_d: 0,
61        }
62    }
63}
64
65impl Default for TaskStateSegmentHeader {
66    fn default() -> Self {
67        Self::new()
68    }
69}