aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Gerd Zellweger <mail@gerdzellweger.com> 2018-04-20 12:46:08 -0700
committerGravatar Gerd Zellweger <mail@gerdzellweger.com> 2018-04-20 12:46:08 -0700
commita392747da8e3792da6bb74327142d17a5dece265 (patch)
tree96d2a356b24e8c1180ae9052c4a974129f8048fd
parent91583f100ffe4efa343babd15bf3e96d9e405971 (diff)
downloadrust-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.rs73
-rw-r--r--src/bits32/mod.rs1
-rw-r--r--src/bits64/mod.rs1
-rw-r--r--src/bits64/rflags.rs (renamed from src/flags.rs)68
-rw-r--r--src/lib.rs4
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");
}
diff --git a/src/lib.rs b/src/lib.rs
index aff1cfb..1b08585 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;