diff options
author | 2018-04-20 12:46:08 -0700 | |
---|---|---|
committer | 2018-04-20 12:46:08 -0700 | |
commit | a392747da8e3792da6bb74327142d17a5dece265 (patch) | |
tree | 96d2a356b24e8c1180ae9052c4a974129f8048fd | |
parent | 91583f100ffe4efa343babd15bf3e96d9e405971 (diff) | |
download | rust-x86-a392747da8e3792da6bb74327142d17a5dece265.tar.gz rust-x86-a392747da8e3792da6bb74327142d17a5dece265.tar.zst rust-x86-a392747da8e3792da6bb74327142d17a5dece265.zip |
Separate flag codes, make 32bits and 64bits accessible on both 64bit and 32bit platforms.
Signed-off-by: Gerd Zellweger <mail@gerdzellweger.com>
-rw-r--r-- | src/bits32/eflags.rs | 73 | ||||
-rw-r--r-- | src/bits32/mod.rs | 1 | ||||
-rw-r--r-- | src/bits64/mod.rs | 1 | ||||
-rw-r--r-- | src/bits64/rflags.rs (renamed from src/flags.rs) | 68 | ||||
-rw-r--r-- | src/lib.rs | 4 |
5 files changed, 97 insertions, 50 deletions
diff --git a/src/bits32/eflags.rs b/src/bits32/eflags.rs new file mode 100644 index 0000000..d937d25 --- /dev/null +++ b/src/bits32/eflags.rs @@ -0,0 +1,73 @@ +//! Processor state stored in the EFLAGS register. + +use super::PrivilegeLevel; + +/// The EFLAGS register. +bitflags! { + pub flags EFlags: u32 { + /// ID Flag (ID) + const FLAGS_ID = 1 << 21, + /// Virtual Interrupt Pending (VIP) + const FLAGS_VIP = 1 << 20, + /// Virtual Interrupt Flag (VIF) + const FLAGS_VIF = 1 << 19, + /// Alignment Check (AC) + const FLAGS_AC = 1 << 18, + /// Virtual-8086 Mode (VM) + const FLAGS_VM = 1 << 17, + /// Resume Flag (RF) + const FLAGS_RF = 1 << 16, + /// Nested Task (NT) + const FLAGS_NT = 1 << 14, + /// I/O Privilege Level (IOPL) 0 + const FLAGS_IOPL0 = 0b00 << 12, + /// I/O Privilege Level (IOPL) 1 + const FLAGS_IOPL1 = 0b01 << 12, + /// I/O Privilege Level (IOPL) 2 + const FLAGS_IOPL2 = 0b10 << 12, + /// I/O Privilege Level (IOPL) 3 + const FLAGS_IOPL3 = 0b11 << 12, + /// Overflow Flag (OF) + const FLAGS_OF = 1 << 11, + /// Direction Flag (DF) + const FLAGS_DF = 1 << 10, + /// Interrupt Enable Flag (IF) + const FLAGS_IF = 1 << 9, + /// Trap Flag (TF) + const FLAGS_TF = 1 << 8, + /// Sign Flag (SF) + const FLAGS_SF = 1 << 7, + /// Zero Flag (ZF) + const FLAGS_ZF = 1 << 6, + /// Auxiliary Carry Flag (AF) + const FLAGS_AF = 1 << 4, + /// Parity Flag (PF) + const FLAGS_PF = 1 << 2, + /// Bit 1 is always 1. + const FLAGS_A1 = 1 << 1, + /// Carry Flag (CF) + const FLAGS_CF = 1 << 0, + } +} + +impl Flags { + /// Creates a new Flags entry. Ensures bit 1 is set. + pub const fn new() -> EFlags { + FLAGS_A1 + } + + /// Creates a new Flags with the given I/O privilege level. + pub const fn from_priv(iopl: PrivilegeLevel) -> EFlags { + EFlags { bits: (iopl as u32) << 12 } + } +} + +pub unsafe fn read() -> EFlags { + let r: u32; + asm!("pushfl; popl $0" : "=r"(r) :: "memory"); + EFlags::from_bits_truncate(r) +} + +pub unsafe fn set(val: EFlags) { + asm!("pushl $0; popfl" :: "r"(val.bits()) : "memory" "flags"); +} diff --git a/src/bits32/mod.rs b/src/bits32/mod.rs index 2ffe79f..d4f76f6 100644 --- a/src/bits32/mod.rs +++ b/src/bits32/mod.rs @@ -1,4 +1,5 @@ pub mod irq; +pub mod eflags; pub mod segmentation; pub mod task; diff --git a/src/bits64/mod.rs b/src/bits64/mod.rs index 7409435..d72b732 100644 --- a/src/bits64/mod.rs +++ b/src/bits64/mod.rs @@ -16,6 +16,7 @@ macro_rules! check_flag { } pub mod irq; +pub mod rflags; pub mod paging; pub mod segmentation; pub mod task; diff --git a/src/flags.rs b/src/bits64/rflags.rs index 46013a8..69e85ee 100644 --- a/src/flags.rs +++ b/src/bits64/rflags.rs @@ -1,11 +1,15 @@ -//! Processor state stored in the FLAGS, EFLAGS, or RFLAGS register. +//! Processor state stored in the RFLAGS register. +//! +//! In 64-bit mode, EFLAGS is extended to 64 bits and called RFLAGS. +//! The upper 32 bits of RFLAGS register is reserved. +//! The lower 32 bits of RFLAGS is the same as EFLAGS. use ::PrivilegeLevel; -/// The RFLAGS register. All variants are backwards compatable so only one -/// bitflags struct needed. +/// The RFLAGS register. +/// This is duplicated code from bits32 eflags.rs. bitflags! { - pub flags Flags: usize { + pub flags RFlags: u64 { /// ID Flag (ID) const FLAGS_ID = 1 << 21, /// Virtual Interrupt Pending (VIP) @@ -21,13 +25,13 @@ bitflags! { /// Nested Task (NT) const FLAGS_NT = 1 << 14, /// I/O Privilege Level (IOPL) 0 - const FLAGS_IOPL0 = 0 << 12, + const FLAGS_IOPL0 = 0b00 << 12, /// I/O Privilege Level (IOPL) 1 - const FLAGS_IOPL1 = 1 << 12, + const FLAGS_IOPL1 = 0b01 << 12, /// I/O Privilege Level (IOPL) 2 - const FLAGS_IOPL2 = 2 << 12, + const FLAGS_IOPL2 = 0b10 << 12, /// I/O Privilege Level (IOPL) 3 - const FLAGS_IOPL3 = 3 << 12, + const FLAGS_IOPL3 = 0b11 << 12, /// Overflow Flag (OF) const FLAGS_OF = 1 << 11, /// Direction Flag (DF) @@ -51,52 +55,24 @@ bitflags! { } } -impl Flags { +impl RFlags { /// Creates a new Flags entry. Ensures bit 1 is set. - pub const fn new() -> Flags { + pub const fn new() -> RFlags { FLAGS_A1 } /// Creates a new Flags with the given I/O privilege level. - pub const fn from_priv(iopl: PrivilegeLevel) -> Flags { - Flags { bits: (iopl as usize) << 12 } + pub const fn from_priv(iopl: PrivilegeLevel) -> RFlags { + RFlags { bits: (iopl as u64) << 12 } } } -pub fn flags() -> Flags { - - #[cfg(target_arch="x86")] - #[inline(always)] - unsafe fn inner() -> Flags { - let r: usize; - asm!("pushfl; popl $0" : "=r"(r) :: "memory"); - Flags::from_bits_truncate(r) - } - - #[cfg(target_arch="x86_64")] - #[inline(always)] - unsafe fn inner() -> Flags { - let r: usize; - asm!("pushfq; popq $0" : "=r"(r) :: "memory"); - Flags::from_bits_truncate(r) - } - - unsafe { inner() } +pub unsafe fn flags() -> RFlags { + let r: u64; + asm!("pushfq; popq $0" : "=r"(r) :: "memory"); + RFlags::from_bits_truncate(r) } -pub fn set(val: Flags) { - - #[cfg(target_arch="x86")] - #[inline(always)] - unsafe fn inner(val: Flags) { - asm!("pushl $0; popfl" :: "r"(val.bits()) : "memory" "flags"); - } - - #[cfg(target_arch="x86_64")] - #[inline(always)] - unsafe fn inner(val: Flags) { - asm!("pushq $0; popfq" :: "r"(val.bits()) : "memory" "flags"); - } - - unsafe { inner(val) } +pub unsafe fn set(val: RFlags) { + asm!("pushq $0; popfq" :: "r"(val.bits()) : "memory" "flags"); } @@ -12,10 +12,7 @@ extern crate raw_cpuid; #[macro_use] extern crate phf; -#[cfg(target_arch="x86")] pub mod bits32; - -#[cfg(target_arch="x86_64")] pub mod bits64; pub mod control_regs; @@ -25,7 +22,6 @@ pub mod io; pub mod irq; pub mod msr; pub mod paging; -pub mod flags; pub mod segmentation; pub mod task; pub mod tlb; |