-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcpu.rs
79 lines (70 loc) · 2.31 KB
/
cpu.rs
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
// Certain casts are required only on Windows. Inform Clippy to ignore them.
#![allow(clippy::unnecessary_cast)]
use crate::error::ensure_ptok;
use crate::error::PtError;
use bitflags::bitflags;
use libipt_sys::{
pt_cpu, pt_cpu_errata, pt_cpu_vendor, pt_cpu_vendor_pcv_intel, pt_cpu_vendor_pcv_unknown,
pt_errata,
};
use std::mem::MaybeUninit;
bitflags! {
/// i suppose this is relevant when/if amd finally gets intelpt support?
#[derive(Debug)]
pub struct CpuVendor: u32 {
const INTEL = pt_cpu_vendor_pcv_intel as u32;
const UNKNOWN = pt_cpu_vendor_pcv_unknown as u32;
}
}
/// A Cpu identifier
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct Cpu(pub(super) pt_cpu);
impl Cpu {
pub const fn new(vendor: CpuVendor, family: u16, model: u8, stepping: u8) -> Self {
Cpu(pt_cpu {
vendor: vendor.bits() as pt_cpu_vendor,
family,
model,
stepping,
})
}
/// A shortcut for creating an intel Cpu instance
pub const fn intel(family: u16, model: u8, stepping: u8) -> Self {
Cpu::new(CpuVendor::INTEL, family, model, stepping)
}
/// determines processor specific workarounds
pub(super) fn errata(self) -> Result<pt_errata, PtError> {
let mut errata = MaybeUninit::<pt_errata>::uninit();
ensure_ptok(unsafe { pt_cpu_errata(errata.as_mut_ptr(), &self.0) })?;
Ok(unsafe { errata.assume_init() })
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_cpu_intel_shortcut() {
let cpu1 = Cpu::intel(66, 12, 255);
let cpu2 = Cpu::new(CpuVendor::INTEL, 66, 12, 255);
assert_eq!(cpu1.0.vendor, cpu2.0.vendor);
assert_eq!(cpu1.0.family, cpu2.0.family);
assert_eq!(cpu1.0.model, cpu2.0.model);
assert_eq!(cpu1.0.stepping, cpu2.0.stepping);
}
#[test]
fn test_cpu_errata() {
let cpu = Cpu::intel(0x6, 0x56, 11);
let e = cpu.errata().unwrap();
assert_eq!(e.bdm70(), 1);
assert_eq!(e.bdm64(), 1);
assert_eq!(e.skd007(), 0);
assert_eq!(e.skd022(), 0);
let cpu = Cpu::intel(0x6, 0x9e, 11);
let e = cpu.errata().unwrap();
assert_eq!(e.bdm64(), 0);
assert_eq!(e.bdm70(), 1);
assert_eq!(e.skd007(), 1);
assert_eq!(e.skd022(), 1);
}
}