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};