use bitflags::*;
#[cfg(target_arch = "x86_64")]
use core::arch::asm;
bitflags! {
pub struct RFlags: u64 {
const FLAGS_ID = 1 << 21;
const FLAGS_VIP = 1 << 20;
const FLAGS_VIF = 1 << 19;
const FLAGS_AC = 1 << 18;
const FLAGS_VM = 1 << 17;
const FLAGS_RF = 1 << 16;
const FLAGS_NT = 1 << 14;
const FLAGS_IOPL0 = 0b00 << 12;
const FLAGS_IOPL1 = 0b01 << 12;
const FLAGS_IOPL2 = 0b10 << 12;
const FLAGS_IOPL3 = 0b11 << 12;
const FLAGS_OF = 1 << 11;
const FLAGS_DF = 1 << 10;
const FLAGS_IF = 1 << 9;
const FLAGS_TF = 1 << 8;
const FLAGS_SF = 1 << 7;
const FLAGS_ZF = 1 << 6;
const FLAGS_AF = 1 << 4;
const FLAGS_PF = 1 << 2;
const FLAGS_A1 = 1 << 1;
const FLAGS_CF = 1 << 0;
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum Ring {
Ring0 = 0b00,
Ring1 = 0b01,
Ring2 = 0b10,
Ring3 = 0b11,
}
impl RFlags {
pub const fn new() -> RFlags {
RFlags::FLAGS_A1
}
pub const fn from_priv(iopl: Ring) -> RFlags {
RFlags {
bits: (iopl as u64) << 12,
}
}
pub const fn from_raw(bits: u64) -> RFlags {
RFlags { bits }
}
}
#[cfg(target_arch = "x86_64")]
#[inline(always)]
pub fn read() -> RFlags {
let r: u64;
unsafe {
asm!("pushfq; popq {0}", out(reg) r, options(att_syntax));
RFlags::from_bits_truncate(r)
}
}
#[cfg(target_arch = "x86_64")]
#[inline(always)]
pub fn set(val: RFlags) {
unsafe {
asm!("pushq {0}; popfq", in(reg) val.bits(), options(att_syntax));
}
}