aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/x86.rs123
-rw-r--r--src/x86_64.rs14
-rw-r--r--src/x86_shared.rs112
3 files changed, 131 insertions, 118 deletions
diff --git a/src/x86.rs b/src/x86.rs
index 63b6c9c..ff6a126 100644
--- a/src/x86.rs
+++ b/src/x86.rs
@@ -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");
}