use crate::VirtAddr;
use core::{
fmt::{self, Display},
mem::size_of,
};
#[derive(Debug, Clone, Copy)]
#[repr(C, packed(4))]
pub struct TaskStateSegment {
reserved_1: u32,
pub privilege_stack_table: [VirtAddr; 3],
reserved_2: u64,
pub interrupt_stack_table: [VirtAddr; 7],
reserved_3: u64,
reserved_4: u16,
pub iomap_base: u16,
}
impl TaskStateSegment {
#[inline]
pub const fn new() -> TaskStateSegment {
TaskStateSegment {
privilege_stack_table: [VirtAddr::zero(); 3],
interrupt_stack_table: [VirtAddr::zero(); 7],
iomap_base: size_of::<TaskStateSegment>() as u16,
reserved_1: 0,
reserved_2: 0,
reserved_3: 0,
reserved_4: 0,
}
}
}
impl Default for TaskStateSegment {
#[inline]
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum InvalidIoMap {
IoMapBeforeTss,
TooFarFromTss {
distance: usize,
},
InvalidTerminatingByte {
byte: u8,
},
TooLong {
len: usize,
},
InvalidBase {
expected: u16,
got: u16,
},
}
impl Display for InvalidIoMap {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
InvalidIoMap::IoMapBeforeTss => {
write!(f, "the IO permissions bitmap is before the TSS")
}
InvalidIoMap::TooFarFromTss { distance } => write!(
f,
"the IO permissions bitmap is too far from the TSS (distance {distance})"
),
InvalidIoMap::InvalidTerminatingByte { byte } => write!(
f,
"The final byte of the IO permissions bitmap was not 0xff ({byte}"
),
InvalidIoMap::TooLong { len } => {
write!(
f,
"The IO permissions bitmap exceeds the maximum length ({len} > 8193)"
)
}
InvalidIoMap::InvalidBase { expected, got } => write!(
f,
"the `iomap_base` in the `TaskStateSegment` struct was not what was expected (expected {expected}, got {got})"
),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
pub fn check_tss_size() {
assert_eq!(size_of::<TaskStateSegment>(), 0x68);
}
}