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
|
#![allow(non_upper_case_globals)]
pub mod control_regs;
pub mod descriptor;
pub mod dtables;
pub mod io;
pub mod irq;
pub mod msr;
pub mod paging;
pub mod flags;
pub mod segmentation;
pub mod task;
bitflags!(
pub flags Features: u64 {
const Fpu = 1 << 0,
const Virtual8086 = 1 << 1,
const DebugExtension = 1 << 2,
const PageSizeExtension = 1 << 3,
const TimeStampCounter = 1 << 4,
const ModelSpecificRegister = 1 << 5,
const PhysicalAddressExtension = 1 << 6,
const MachineCheckException = 1 << 7,
const Cx8 = 1 << 8, // CMPXCHG8
const Apic = 1 << 9,
const SysEnter = 1 << 11,
const MemoryTypeRange = 1 << 12,
const PageGlobal = 1 << 13,
const MachineCheckArchitecture = 1 << 14,
const CMov = 1 << 15,
const PageAttributeTable = 1 << 16,
const PageSizeExtension36 = 1 << 17,
const ProcessorSerial = 1 << 18,
const CacheFlush = 1 << 19,
const DebugStore = 1 << 21,
const Acpi = 1 << 22,
const Mmx = 1 << 23,
const FxSave = 1 << 24,
const Sse = 1 << 25,
const Sse2 = 1 << 26,
const SelfSnoop = 1 << 27,
const HyperThreading = 1 << 28,
const ThermalMonitor = 1 << 29,
const Ia64 = 1 << 30,
const PendingBreak = 1 << 31,
const Sse3 = 1 << (32 + 0),
const PclMulQdq = 1 << (32 + 1), // what
const DebugStore64 = 1 << (32 + 2),
const Monitor = 1 << (32 + 3),
const CplDebugStore = 1 << (32 + 4),
const Vmx = 1 << (32 + 5),
const SaferMode = 1 << (32 + 6),
const EnhancedSpeedStep = 1 << (32 + 7),
const ThermalMonitor2 = 1 << (32 + 8),
const Ssse3 = 1 << (32 + 9),
const L1ContextId = 1 << (32 + 10),
const Fma = 1 << (32 + 12),
const Cx16 = 1 << (32 + 13), // CMPXCHG16B
const Xtpr = 1 << (32 + 14), // I have no idea what this is
const PerformanceMonitor = 1 << (32 + 15),
const ProcessContextId = 1 << (32 + 17),
const DirectCache = 1 << (32 + 18),
const Sse41 = 1 << (32 + 19),
const Sse42 = 1 << (32 + 20),
const X2Apic = 1 << (32 + 21),
const MovBe = 1 << (32 + 22),
const PopulationCount = 1 << (32 + 23),
const TscDeadline = 1 << (32 + 24),
const AesNi = 1 << (32 + 25),
const XSave = 1 << (32 + 26),
const OsXSave = 1 << (32 + 27),
const Avx = 1 << (32 + 28),
const HalfPrecision = 1 << (32 + 29),
const HwRandom = 1 << (32 + 30)
}
);
#[inline(always)]
pub fn cpuid(function: u32) -> (u32, u32, u32, u32) {
unsafe {
let (eax, ebx, ecx, edx): (u32, u32, u32, u32);
asm!("cpuid" : "={eax}"(eax), "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx) : "{eax}"(function));
(eax, ebx, ecx, edx)
}
}
#[inline(always)]
pub fn supports() -> Features {
let (_, _, feature_ecx, feature_edx) = cpuid(1);
Features {
bits: ((feature_ecx as u64) << 32) | (feature_edx as u64)
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum PrivilegeLevel {
Ring0 = 0,
Ring1 = 1,
Ring2 = 2,
Ring3 = 3,
}
#[inline(always)]
pub unsafe fn halt() {
asm!("hlt" :::: "volatile", "intel");
}
|