vmm/arch/x86_64/
cpu_model.rs1use std::arch::x86_64::__cpuid as host_cpuid;
5use std::cmp::{Eq, PartialEq};
6
7#[derive(Debug, Eq, PartialEq)]
9pub struct CpuModel {
10 pub extended_family: u8,
12 pub extended_model: u8,
14 pub family: u8,
16 pub model: u8,
18 pub stepping: u8,
20}
21
22pub const SKYLAKE_FMS: CpuModel = CpuModel {
24 extended_family: 0x0,
25 extended_model: 0x5,
26 family: 0x6,
27 model: 0x5,
28 stepping: 0x4,
29};
30
31pub const CASCADE_LAKE_FMS: CpuModel = CpuModel {
33 extended_family: 0x0,
34 extended_model: 0x5,
35 family: 0x6,
36 model: 0x5,
37 stepping: 0x7,
38};
39
40pub const ICE_LAKE_FMS: CpuModel = CpuModel {
42 extended_family: 0x0,
43 extended_model: 0x6,
44 family: 0x6,
45 model: 0xa,
46 stepping: 0x6,
47};
48
49pub const MILAN_FMS: CpuModel = CpuModel {
51 extended_family: 0xa,
52 extended_model: 0x0,
53 family: 0xf,
54 model: 0x1,
55 stepping: 0x1,
56};
57
58impl CpuModel {
59 pub fn get_cpu_model() -> Self {
61 let eax = unsafe { host_cpuid(0x1) }.eax;
64 CpuModel::from(&eax)
65 }
66}
67
68impl From<&u32> for CpuModel {
69 fn from(eax: &u32) -> Self {
70 CpuModel {
71 extended_family: ((eax >> 20) & 0xff) as u8,
72 extended_model: ((eax >> 16) & 0xf) as u8,
73 family: ((eax >> 8) & 0xf) as u8,
74 model: ((eax >> 4) & 0xf) as u8,
75 stepping: (eax & 0xf) as u8,
76 }
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn cpu_model_from() {
86 let skylake_eax = 0x00050654;
87 assert_eq!(CpuModel::from(&skylake_eax), SKYLAKE_FMS);
88
89 let cascade_lake_eax = 0x00050657;
90 assert_eq!(CpuModel::from(&cascade_lake_eax), CASCADE_LAKE_FMS);
91
92 let ice_lake_eax = 0x000606a6;
93 assert_eq!(CpuModel::from(&ice_lake_eax), ICE_LAKE_FMS);
94
95 let milan_eax = 0x00a00f11;
96 assert_eq!(CpuModel::from(&milan_eax), MILAN_FMS);
97 }
98}