aboutsummaryrefslogtreecommitdiff
path: root/src/shared/mod.rs
blob: 6613f546d798409d7f43e065e861e81f6651a6a8 (plain) (blame)
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");
}