aboutsummaryrefslogtreecommitdiff
path: root/src/bits64/task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bits64/task.rs')
-rw-r--r--src/bits64/task.rs44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/bits64/task.rs b/src/bits64/task.rs
new file mode 100644
index 0000000..97d3341
--- /dev/null
+++ b/src/bits64/task.rs
@@ -0,0 +1,44 @@
+//! Helpers to program the task state segment.
+
+use super::segmentation;
+
+pub type TaskStateDescriptorLow = segmentation::SegmentDescriptor;
+pub type TaskStateDescriptorHigh = u64;
+
+/// In 64-bit mode the TSS holds information that is not
+/// directly related to the task-switch mechanism,
+/// but is used for finding kernel level stack
+/// if interrupts arrive while in kernel mode.
+#[derive(Debug)]
+#[repr(C, packed)]
+pub struct TaskStateSegment {
+ pub reserved: u32,
+ /// The full 64-bit canonical forms of the stack pointers (RSP) for privilege levels 0-2.
+ pub rsp: [u64; 3],
+ pub reserved2: u64,
+ /// The full 64-bit canonical forms of the interrupt stack table (IST) pointers.
+ pub ist: [u64; 7],
+ pub reserved3: u64,
+ pub reserved4: u16,
+ /// The 16-bit offset to the I/O permission bit map from the 64-bit TSS base.
+ pub iomap_base: u16,
+}
+
+impl TaskStateSegment {
+ pub fn new() -> TaskStateSegment {
+ TaskStateSegment {
+ reserved: 0,
+ rsp: [0, 0, 0],
+ reserved2: 0,
+ ist: [0, 0, 0, 0, 0, 0, 0],
+ reserved3: 0,
+ reserved4: 0,
+ iomap_base: 0,
+ }
+ }
+}
+
+/// Load the task state register.
+pub unsafe fn load_ltr(sel: segmentation::SegmentSelector) {
+ asm!("ltr $0" :: "r" (sel));
+}