x86/registers/bits32/
eflags.rs
1use kernel::utilities::registers::register_bitfields;
8use tock_registers::LocalRegisterCopy;
9
10#[cfg(target_arch = "x86")]
11use core::arch::asm;
12
13register_bitfields![u32,
14 pub EFLAGS[
15 FLAGS_CF OFFSET(0) NUMBITS(1),
17 FLAGS_A1 OFFSET(1) NUMBITS(1),
19 FLAGS_PF OFFSET(2) NUMBITS(2),
21 FLAGS_AF OFFSET(4) NUMBITS(2),
23 FLAGS_ZF OFFSET(6) NUMBITS(1),
25 FLAGS_SF OFFSET(7) NUMBITS(1),
27 FLAGS_TF OFFSET(8) NUMBITS(1),
29 FLAGS_IF OFFSET(9) NUMBITS(1),
31 FLAGS_DF OFFSET(10) NUMBITS(1),
33 FLAGS_OF OFFSET(11) NUMBITS(1),
35 FLAGS_IOPL OFFSET(12) NUMBITS(2),
37 FLAGS_NT OFFSET(14) NUMBITS(2),
39 FLAGS_RF OFFSET(16) NUMBITS(1),
41 FLAGS_VM OFFSET(17) NUMBITS(1),
43 FLAGS_AC OFFSET(18) NUMBITS(1),
45 FLAGS_VIF OFFSET(19) NUMBITS(1),
47 FLAGS_VIP OFFSET(20) NUMBITS(1),
49 FLAGS_ID OFFSET(21) NUMBITS(11),
51 ],
52];
53
54#[repr(transparent)]
55#[derive(Copy, Clone, Debug)]
56pub struct EFlags(pub LocalRegisterCopy<u32, EFLAGS::Register>);
57
58impl Default for EFlags {
59 fn default() -> Self {
60 Self::new()
61 }
62}
63
64impl EFlags {
65 pub fn new() -> EFlags {
70 let mut flags = LocalRegisterCopy::new(0);
71 flags.write(EFLAGS::FLAGS_A1::SET);
72 EFlags(flags)
73 }
74}
75
76#[cfg(target_arch = "x86")]
77#[inline(always)]
78pub unsafe fn read() -> EFlags {
79 let r: u32;
80 unsafe {
81 asm!("pushfl; popl {0}", out(reg) r, options(att_syntax));
82 }
83 EFlags(LocalRegisterCopy::new(r))
84}
85
86#[cfg(target_arch = "x86")]
87#[inline(always)]
88pub unsafe fn set(val: EFlags) {
89 unsafe {
90 asm!("pushl {0}; popfl", in(reg) val.0.get(), options(att_syntax));
91 }
92}
93
94#[cfg(not(any(doc, target_arch = "x86")))]
97pub unsafe fn read() -> EFlags {
98 unimplemented!()
99}
100
101#[cfg(not(any(doc, target_arch = "x86")))]
102pub unsafe fn set(_val: EFlags) {
103 unimplemented!()
104}