diff options
Diffstat (limited to 'src/bits64/segmentation.rs')
-rw-r--r-- | src/bits64/segmentation.rs | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/src/bits64/segmentation.rs b/src/bits64/segmentation.rs index bf39a82..11b49e7 100644 --- a/src/bits64/segmentation.rs +++ b/src/bits64/segmentation.rs @@ -1,6 +1,9 @@ #[allow(unused_imports)] -use segmentation::{SegmentSelector}; -use segmentation::{DescriptorBuilder, BuildDescriptor, Descriptor, DescriptorType, GateDescriptorBuilder, LdtDescriptorBuilder, SystemDescriptorTypes64}; +use segmentation::SegmentSelector; +use segmentation::{ + BuildDescriptor, Descriptor, DescriptorBuilder, DescriptorType, GateDescriptorBuilder, + LdtDescriptorBuilder, SystemDescriptorTypes64, +}; /// Entry for IDT, GDT or LDT. /// @@ -11,17 +14,24 @@ use segmentation::{DescriptorBuilder, BuildDescriptor, Descriptor, DescriptorTyp pub struct Descriptor64 { desc32: Descriptor, lower: u32, - upper: u32 + upper: u32, } impl Descriptor64 { - - pub const NULL: Descriptor64 = Descriptor64 { desc32: Descriptor::NULL, lower: 0, upper: 0 }; + pub const NULL: Descriptor64 = Descriptor64 { + desc32: Descriptor::NULL, + lower: 0, + upper: 0, + }; pub(crate) fn apply_builder_settings(&mut self, builder: &DescriptorBuilder) { self.desc32.apply_builder_settings(builder); - builder.base_limit.map(|(base, limit)| self.set_base_limit(base, limit)); - builder.selector_offset.map(|(selector, offset)| self.set_selector_offset(selector, offset)); + builder + .base_limit + .map(|(base, limit)| self.set_base_limit(base, limit)); + builder + .selector_offset + .map(|(selector, offset)| self.set_selector_offset(selector, offset)); } /// Create a new segment, TSS or LDT descriptor @@ -31,7 +41,7 @@ impl Descriptor64 { self.lower = (base >> 32) as u32; } - /// Creates a new descriptor with selector and offset (for IDT Gate descriptors, + /// Creates a new descriptor with selector and offset (for IDT Gate descriptors, /// e.g. Trap, Interrupts and Task gates) pub fn set_selector_offset(&mut self, selector: SegmentSelector, offset: u64) { self.desc32.set_selector_offset(selector, offset as u32); @@ -39,17 +49,15 @@ impl Descriptor64 { } /// Sets the interrupt stack table index. - /// The 3-bit IST index field that provides an offset into the IST section of the TSS. + /// The 3-bit IST index field that provides an offset into the IST section of the TSS. /// Using the IST mechanism, the processor loads the value pointed by an IST pointer into the RSP. pub fn set_ist(&mut self, index: u8) { assert!(index <= 0b111); self.desc32.upper |= index as u32; } - } impl GateDescriptorBuilder<u64> for DescriptorBuilder { - fn tss_descriptor(base: u64, limit: u64, available: bool) -> DescriptorBuilder { let typ = match available { true => DescriptorType::System64(SystemDescriptorTypes64::TssAvailable), @@ -60,21 +68,26 @@ impl GateDescriptorBuilder<u64> for DescriptorBuilder { } fn call_gate_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder { - DescriptorBuilder::with_selector_offset(selector, offset).set_type(DescriptorType::System64(SystemDescriptorTypes64::CallGate)) + DescriptorBuilder::with_selector_offset(selector, offset) + .set_type(DescriptorType::System64(SystemDescriptorTypes64::CallGate)) } fn interrupt_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder { - DescriptorBuilder::with_selector_offset(selector, offset).set_type(DescriptorType::System64(SystemDescriptorTypes64::InterruptGate)) + DescriptorBuilder::with_selector_offset(selector, offset).set_type( + DescriptorType::System64(SystemDescriptorTypes64::InterruptGate), + ) } fn trap_gate_descriptor(selector: SegmentSelector, offset: u64) -> DescriptorBuilder { - DescriptorBuilder::with_selector_offset(selector, offset).set_type(DescriptorType::System64(SystemDescriptorTypes64::TrapGate)) + DescriptorBuilder::with_selector_offset(selector, offset) + .set_type(DescriptorType::System64(SystemDescriptorTypes64::TrapGate)) } } impl LdtDescriptorBuilder<u64> for DescriptorBuilder { fn ldt_descriptor(base: u64, limit: u64) -> DescriptorBuilder { - DescriptorBuilder::with_base_limit(base, limit).set_type(DescriptorType::System64(SystemDescriptorTypes64::LDT)) + DescriptorBuilder::with_base_limit(base, limit) + .set_type(DescriptorType::System64(SystemDescriptorTypes64::LDT)) } } @@ -86,14 +99,23 @@ impl BuildDescriptor<Descriptor64> for DescriptorBuilder { let typ = match self.typ { Some(DescriptorType::System64(typ)) => { assert!(!self.l); - if typ == SystemDescriptorTypes64::LDT || typ == SystemDescriptorTypes64::TssAvailable || typ == SystemDescriptorTypes64::TssBusy { + if typ == SystemDescriptorTypes64::LDT + || typ == SystemDescriptorTypes64::TssAvailable + || typ == SystemDescriptorTypes64::TssBusy + { assert!(!self.db); } typ as u8 - }, - Some(DescriptorType::System32(_typ)) => panic!("Can't build a 64-bit version of this type."), - Some(DescriptorType::Data(_typ)) => panic!("Can't build a 64-bit version of this type."), - Some(DescriptorType::Code(_typ)) => panic!("Can't build a 64-bit version of this type."), + } + Some(DescriptorType::System32(_typ)) => { + panic!("Can't build a 64-bit version of this type.") + } + Some(DescriptorType::Data(_typ)) => { + panic!("Can't build a 64-bit version of this type.") + } + Some(DescriptorType::Code(_typ)) => { + panic!("Can't build a 64-bit version of this type.") + } None => unreachable!("Type not set, this is a library bug in x86."), }; @@ -107,11 +129,11 @@ impl BuildDescriptor<Descriptor64> for DescriptorBuilder { /// to %cs. Instead we push the new segment selector /// and return value on the stack and use lretq /// to reload cs and continue at 1:. -#[cfg(target_arch="x86_64")] +#[cfg(target_arch = "x86_64")] pub unsafe fn load_cs(sel: SegmentSelector) { asm!("pushq $0; \ leaq 1f(%rip), %rax; \ pushq %rax; \ lretq; \ 1:" :: "ri" (sel.bits() as usize) : "rax" "memory"); -}
\ No newline at end of file +} |