1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use bitflags::*;
use crate::Ring;
bitflags! {
pub struct EFlags: u32 {
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;
}
}
impl EFlags {
pub const fn new() -> EFlags {
EFlags::FLAGS_A1
}
pub const fn from_priv(iopl: Ring) -> EFlags {
EFlags {
bits: (iopl as u32) << 12,
}
}
}
#[cfg(target_arch = "x86")]
#[inline(always)]
pub unsafe fn read() -> EFlags {
let r: u32;
llvm_asm!("pushfl; popl $0" : "=r"(r) :: "memory");
EFlags::from_bits_truncate(r)
}
#[cfg(target_arch = "x86")]
#[inline(always)]
pub unsafe fn set(val: EFlags) {
llvm_asm!("pushl $0; popfl" :: "r"(val.bits()) : "memory" "flags");
}
#[inline(always)]
pub unsafe fn clac() {
llvm_asm!("clac" ::: "memory" "flags" : "volatile");
}
#[inline(always)]
pub unsafe fn stac() {
llvm_asm!("stac" ::: "memory" "flags" : "volatile");
}