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}