x86/bits64/
rflags.rs

1//! Processor state stored in the RFLAGS register.
2//!
3//! In 64-bit mode, EFLAGS is extended to 64 bits and called RFLAGS.
4//! The upper 32 bits of RFLAGS register is reserved.
5//! The lower 32 bits of RFLAGS is the same as EFLAGS.
6
7use bitflags::*;
8
9use crate::Ring;
10
11#[cfg(target_arch = "x86_64")]
12use core::arch::asm;
13
14bitflags! {
15    /// The RFLAGS register.
16    /// This is duplicated code from bits32 eflags.rs.
17    pub struct RFlags: u64 {
18        /// ID Flag (ID)
19        const FLAGS_ID = 1 << 21;
20        /// Virtual Interrupt Pending (VIP)
21        const FLAGS_VIP = 1 << 20;
22        /// Virtual Interrupt Flag (VIF)
23        const FLAGS_VIF = 1 << 19;
24        /// Alignment Check (AC)
25        const FLAGS_AC = 1 << 18;
26        /// Virtual-8086 Mode (VM)
27        const FLAGS_VM = 1 << 17;
28        /// Resume Flag (RF)
29        const FLAGS_RF = 1 << 16;
30        /// Nested Task (NT)
31        const FLAGS_NT = 1 << 14;
32        /// I/O Privilege Level (IOPL) 0
33        const FLAGS_IOPL0 = 0b00 << 12;
34        /// I/O Privilege Level (IOPL) 1
35        const FLAGS_IOPL1 = 0b01 << 12;
36        /// I/O Privilege Level (IOPL) 2
37        const FLAGS_IOPL2 = 0b10 << 12;
38        /// I/O Privilege Level (IOPL) 3
39        const FLAGS_IOPL3 = 0b11 << 12;
40        /// Overflow Flag (OF)
41        const FLAGS_OF = 1 << 11;
42        /// Direction Flag (DF)
43        const FLAGS_DF = 1 << 10;
44        /// Interrupt Enable Flag (IF)
45        const FLAGS_IF = 1 << 9;
46        /// Trap Flag (TF)
47        const FLAGS_TF = 1 << 8;
48        /// Sign Flag (SF)
49        const FLAGS_SF = 1 << 7;
50        /// Zero Flag (ZF)
51        const FLAGS_ZF = 1 << 6;
52        /// Auxiliary Carry Flag (AF)
53        const FLAGS_AF = 1 << 4;
54        /// Parity Flag (PF)
55        const FLAGS_PF = 1 << 2;
56        /// Bit 1 is always 1.
57        const FLAGS_A1 = 1 << 1;
58        /// Carry Flag (CF)
59        const FLAGS_CF = 1 << 0;
60    }
61}
62
63impl RFlags {
64    /// Creates a new Flags entry. Ensures bit 1 is set.
65    pub const fn new() -> RFlags {
66        RFlags::FLAGS_A1
67    }
68
69    /// Creates a new Flags with the given I/O privilege level.
70    pub const fn from_priv(iopl: Ring) -> RFlags {
71        RFlags {
72            bits: (iopl as u64) << 12,
73        }
74    }
75
76    pub const fn from_raw(bits: u64) -> RFlags {
77        RFlags { bits }
78    }
79}
80
81#[cfg(target_arch = "x86_64")]
82#[inline(always)]
83pub fn read() -> RFlags {
84    let r: u64;
85    unsafe { asm!("pushfq; popq {0}", out(reg) r, options(att_syntax)) };
86    RFlags::from_bits_truncate(r)
87}
88
89#[cfg(target_arch = "x86_64")]
90#[inline(always)]
91pub fn set(val: RFlags) {
92    unsafe {
93        asm!("pushq {0}; popfq", in(reg) val.bits(), options(att_syntax));
94    }
95}
96
97// clac and stac are also usable in 64-bit mode
98pub use crate::bits32::eflags::{clac, stac};