diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/x86.rs | 123 | ||||
-rw-r--r-- | src/x86_64.rs | 14 | ||||
-rw-r--r-- | src/x86_shared.rs | 112 |
3 files changed, 131 insertions, 118 deletions
@@ -8,67 +8,6 @@ use core::mem::size_of; mod x86_shared; bitflags! { - flags EFlags: u32 { - const CarryFlag = 1 << 0, - const ParityFlag = 1 << 2, - const AdjustFlag = 1 << 4, - const ZeroFlag = 1 << 6, - const SignFlag = 1 << 7, - const TrapFlag = 1 << 8, - const InterruptFlag = 1 << 9, - const DirectionFlag = 1 << 10, - const OverflowFlag = 1 << 11, - const Iopl1 = 1 << 12, - const Iopl2 = 1 << 13, - const NestedTaskFlag = 1 << 14, - const ResumeFlag = 1 << 16, - const Virtual8086Flag = 1 << 17, - const AlignmentFlag = 1 << 18, - const VirtualInterruptFlag = 1 << 19, - const VirtualInterruptPending = 1 << 20, - const CpuIdFlag = 1 << 21 - } -} - -bitflags! { - flags Cr0Flags: u32 { - const ProtectedMode = 1 << 0, - const MonitorCoprocessor = 1 << 1, - const EmulateCoprocessor = 1 << 2, - const TaskSwitched = 1 << 3, - const ExtensionType = 1 << 4, - const NumericError = 1 << 5, - const WriteProtect = 1 << 16, - const AlignmentMask = 1 << 18, - const NotWriteThrough = 1 << 29, - const CacheDisable = 1 << 30, - const EnablePaging = 1 << 31 - } -} - -bitflags! { - flags Cr4Flags: u32 { - const EnableVme = 1 << 0, - const VirtualInterrupts = 1 << 1, - const TimeStampDisable = 1 << 2, - const DebuggingExtensions = 1 << 3, - const EnablePse = 1 << 4, - const EnablePae = 1 << 5, - const EnableMachineCheck = 1 << 6, - const EnableGlobalPages = 1 << 7, - const EnablePpmc = 1 << 8, - const EnableSse = 1 << 9, - const UnmaskedSse = 1 << 10, - const EnableVmx = 1 << 13, - const EnableSmx = 1 << 14, - const EnablePcid = 1 << 17, - const EnableOsXSave = 1 << 18, - const EnableSmep = 1 << 20, - const EnableSmap = 1 << 21 - } -} - -bitflags! { flags GdtAccess: u8 { const Accessed = 1 << 0, const Writable = 1 << 1, @@ -235,64 +174,17 @@ impl Tss { } #[inline(always)] -pub fn get_cr0() -> Cr0Flags { - unsafe { - let mut r: u32; - asm!("mov $0, cr0" : "=r"(r) ::: "intel"); - Cr0Flags::from_bits_truncate(r) - } -} - -#[inline(always)] -pub fn get_cr2() -> u32 { - unsafe { - let mut r: u32; - asm!("mov $0, cr2" : "=r"(r) ::: "intel"); - r - } -} - -#[inline(always)] -pub fn get_cr3() -> u32 { +pub fn get_flags() -> Flags { unsafe { - let mut r: u32; - asm!("mov $0, cr3" : "=r"(r) ::: "intel"); - r - } -} - -#[inline(always)] -pub fn get_cr4() -> Cr4Flags { - unsafe { - let mut r: u32; - asm!("mov $0, cr4" : "=r"(r) ::: "intel"); - Cr4Flags::from_bits_truncate(r) - } -} - -#[inline(always)] -pub fn get_flags() -> EFlags { - unsafe { - let mut r: u32; + let mut r: usize; asm!("pushfd; pop $0" : "=r"(r) ::: "intel"); - EFlags::from_bits_truncate(r) + Flags::from_bits_truncate(r) } } - -#[inline(always)] -pub unsafe fn set_cr0(flags: Cr0Flags) { - asm!("mov cr0, $0" :: "r"(flags.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_cr3(val: u32) { - asm!("mov cr3, $0" :: "r"(val) :: "volatile", "intel"); -} - #[inline(always)] -pub unsafe fn set_cr4(flags: Cr4Flags) { - asm!("mov cr4, $0" :: "r"(flags.bits()) :: "volatile", "intel"); +pub unsafe fn set_flags(val: Flags) { + asm!("push $0; popfd" :: "r"(val.bits()) : "flags" : "volatile", "intel"); } #[inline(always)] @@ -316,11 +208,6 @@ pub unsafe fn set_idt(idt: &[IdtEntry]) { } #[inline(always)] -pub unsafe fn set_flags(val: EFlags) { - asm!("push $0; popfd" :: "r"(val.bits()) : "flags" : "volatile", "intel"); -} - -#[inline(always)] pub unsafe fn stack_jmp(stack: *mut (), ip: *const ()) -> ! { asm!("mov esp, $0; jmp $1" :: "rg"(stack), "r"(ip) :: "volatile", "intel"); loop { } diff --git a/src/x86_64.rs b/src/x86_64.rs index 3e8bd16..67b7e64 100644 --- a/src/x86_64.rs +++ b/src/x86_64.rs @@ -3,3 +3,17 @@ pub use self::x86_shared::*; mod x86_shared; + +#[inline(always)] +pub fn get_flags() -> Flags { + unsafe { + let mut r: usize; + asm!("pushfq; pop $0" : "=r"(r) ::: "intel"); + Flags::from_bits_truncate(r) + } +} + +#[inline(always)] +pub unsafe fn set_flags(val: Flags) { + asm!("push $0; popfq" :: "r"(val.bits()) : "flags" : "volatile", "intel"); +} diff --git a/src/x86_shared.rs b/src/x86_shared.rs index f82ea42..8cd34df 100644 --- a/src/x86_shared.rs +++ b/src/x86_shared.rs @@ -2,6 +2,67 @@ use core::prelude::*; +bitflags! { + flags Flags: usize { + const CarryFlag = 1 << 0, + const ParityFlag = 1 << 2, + const AdjustFlag = 1 << 4, + const ZeroFlag = 1 << 6, + const SignFlag = 1 << 7, + const TrapFlag = 1 << 8, + const InterruptFlag = 1 << 9, + const DirectionFlag = 1 << 10, + const OverflowFlag = 1 << 11, + const Iopl1 = 1 << 12, + const Iopl2 = 1 << 13, + const NestedTaskFlag = 1 << 14, + const ResumeFlag = 1 << 16, + const Virtual8086Flag = 1 << 17, + const AlignmentFlag = 1 << 18, + const VirtualInterruptFlag = 1 << 19, + const VirtualInterruptPending = 1 << 20, + const CpuIdFlag = 1 << 21 + } +} + +bitflags! { + flags Cr0: usize { + const ProtectedMode = 1 << 0, + const MonitorCoprocessor = 1 << 1, + const EmulateCoprocessor = 1 << 2, + const TaskSwitched = 1 << 3, + const ExtensionType = 1 << 4, + const NumericError = 1 << 5, + const WriteProtect = 1 << 16, + const AlignmentMask = 1 << 18, + const NotWriteThrough = 1 << 29, + const CacheDisable = 1 << 30, + const EnablePaging = 1 << 31 + } +} + +bitflags! { + flags Cr4: usize { + const EnableVme = 1 << 0, + const VirtualInterrupts = 1 << 1, + const TimeStampDisable = 1 << 2, + const DebuggingExtensions = 1 << 3, + const EnablePse = 1 << 4, + const EnablePae = 1 << 5, + const EnableMachineCheck = 1 << 6, + const EnableGlobalPages = 1 << 7, + const EnablePpmc = 1 << 8, + const EnableSse = 1 << 9, + const UnmaskedSse = 1 << 10, + const EnableVmx = 1 << 13, + const EnableSmx = 1 << 14, + const EnablePcid = 1 << 17, + const EnableOsXSave = 1 << 18, + const EnableSmep = 1 << 20, + const EnableSmap = 1 << 21 + } +} + bitflags!( flags Features: u64 { const Fpu = 1 << 0, @@ -217,6 +278,57 @@ pub unsafe fn set_cs(selector: SegmentSelector) { } #[inline(always)] +pub fn get_cr0() -> Cr0 { + unsafe { + let mut r: usize; + asm!("mov $0, cr0" : "=r"(r) ::: "intel"); + Cr0::from_bits_truncate(r) + } +} + +#[inline(always)] +pub fn get_cr2() -> usize { + unsafe { + let mut r: usize; + asm!("mov $0, cr2" : "=r"(r) ::: "intel"); + r + } +} + +#[inline(always)] +pub fn get_cr3() -> usize { + unsafe { + let mut r: usize; + asm!("mov $0, cr3" : "=r"(r) ::: "intel"); + r + } +} + +#[inline(always)] +pub fn get_cr4() -> Cr4 { + unsafe { + let mut r: usize; + asm!("mov $0, cr4" : "=r"(r) ::: "intel"); + Cr4::from_bits_truncate(r) + } +} + +#[inline(always)] +pub unsafe fn set_cr0(flags: Cr0) { + asm!("mov cr0, $0" :: "r"(flags.bits()) :: "volatile", "intel"); +} + +#[inline(always)] +pub unsafe fn set_cr3(val: usize) { + asm!("mov cr3, $0" :: "r"(val) :: "volatile", "intel"); +} + +#[inline(always)] +pub unsafe fn set_cr4(flags: Cr4) { + asm!("mov cr4, $0" :: "r"(flags.bits()) :: "volatile", "intel"); +} + +#[inline(always)] pub unsafe fn enable_interrupts() { asm!("sti" :::: "volatile", "intel"); } |