242 lines
8.1 KiB
Rust
242 lines
8.1 KiB
Rust
|
use raw_cpuid::CpuId;
|
||
|
use crate::arch::CpuClass::{IntelCore, IntelXeon, IntelXeonSP};
|
||
|
|
||
|
pub(crate) enum CpuClass {
|
||
|
IntelCore,
|
||
|
IntelXeon,
|
||
|
IntelXeonSP,
|
||
|
// Add further CPUs later on
|
||
|
}
|
||
|
|
||
|
pub(crate) fn determine_cpu_class() -> Option<CpuClass> {
|
||
|
let cpuid = CpuId::new();
|
||
|
let info = if let Some(info) = cpuid.get_feature_info() {
|
||
|
info
|
||
|
} else {
|
||
|
return None;
|
||
|
};
|
||
|
|
||
|
// Todo, sift through the documentation to add support for more CPUs
|
||
|
match (info.family_id(), info.model_id()) {
|
||
|
(0x06, 0x4f)
|
||
|
| (0x06, 0x2d)
|
||
|
| (0x06, 0x3e)
|
||
|
| (06, 0x3f)
|
||
|
| (0x06, 0x56) => {
|
||
|
Some(IntelXeon)
|
||
|
}
|
||
|
(0x06, 0x55) => {
|
||
|
Some(IntelXeonSP)
|
||
|
}
|
||
|
// 42, 58, 60, 69, 70, 61, 71, 78, 94, 142, 158
|
||
|
(0x06, 0x2a)
|
||
|
| (0x06, 0x3a)
|
||
|
| (0x06, 0x3c)
|
||
|
| (0x06, 0x45)
|
||
|
| (0x06, 0x46)
|
||
|
| (0x06, 0x3d)
|
||
|
| (0x06, 0x47)
|
||
|
| (0x06, 0x4e)
|
||
|
| (0x06, 0x5e)
|
||
|
| (0x06, 0x8e)
|
||
|
| (0x06, 0x9e) => {
|
||
|
Some(IntelCore)
|
||
|
}
|
||
|
_ => {
|
||
|
None
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub(crate) fn get_performance_counters_xeon() -> Option<&'static XeonPerfCounters> {
|
||
|
let cpuid = CpuId::new();
|
||
|
let info = if let Some(info) = cpuid.get_feature_info() {
|
||
|
info
|
||
|
} else {
|
||
|
return None;
|
||
|
};
|
||
|
if info.family_id() != 6 {
|
||
|
return None;
|
||
|
}
|
||
|
match info.model_id() {
|
||
|
0x2d /* 45 */ => Some(&SANDY_BRIDGE_XEON),
|
||
|
0x3e /* 62 */ => Some(&IVY_BRIDGE_XEON),
|
||
|
0x3f /* 63 */ => Some(&HASWELL_XEON),
|
||
|
0x56 /* 86 */ => Some(&BROADWELL_XEON),
|
||
|
_ => None,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub(crate) fn get_performance_counters_core() -> Option<&'static CorePerfCounters> {
|
||
|
let cpuid = CpuId::new();
|
||
|
let info = if let Some(info) = cpuid.get_feature_info() {
|
||
|
info
|
||
|
} else {
|
||
|
return None;
|
||
|
};
|
||
|
if info.family_id() != 6 {
|
||
|
return None;
|
||
|
}
|
||
|
// TODO, review if the list can be extended to further CPUs
|
||
|
// TODO, add post Cannon Lake stuff
|
||
|
match info.model_id() {
|
||
|
0x2a
|
||
|
| 0x3a
|
||
|
| 0x3c
|
||
|
| 0x45
|
||
|
| 0x46
|
||
|
| 0x3d
|
||
|
| 0x47 => Some(&SANDYBRIDGE_TO_BROADWELL_CORE),
|
||
|
0x4e
|
||
|
| 0x5e
|
||
|
| 0x8e
|
||
|
| 0x9e => Some(&SKYLAKE_KABYLAKE_CORE),
|
||
|
_ => None,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub struct XeonPerfCounters {
|
||
|
pub max_slice: u16,
|
||
|
pub msr_pmon_ctr0: &'static [u64],
|
||
|
pub msr_pmon_box_filter: &'static [u64],
|
||
|
pub msr_pmon_ctl0: &'static [u64],
|
||
|
pub msr_pmon_box_ctl: &'static [u64],
|
||
|
pub val_box_freeze: u64,
|
||
|
pub val_box_reset: u64,
|
||
|
pub val_enable_counting: u64,
|
||
|
pub val_select_event: u64,
|
||
|
pub val_filter: u64,
|
||
|
pub val_box_unfreeze: u64,
|
||
|
}
|
||
|
|
||
|
pub struct CorePerfCounters {
|
||
|
pub max_slice: u16,
|
||
|
pub msr_unc_perf_global_ctr: u64,
|
||
|
pub val_enable_ctrs: u64,
|
||
|
pub msr_unc_cbo_perfevtsel0: &'static [u64],
|
||
|
pub msr_unc_cbo_per_ctr0: &'static [u64],
|
||
|
pub val_disable_ctrs: u64,
|
||
|
pub val_select_evt_core: u64,
|
||
|
pub val_reset_ctrs: u64,
|
||
|
}
|
||
|
|
||
|
const SANDY_BRIDGE_XEON: XeonPerfCounters = XeonPerfCounters {
|
||
|
max_slice: 8,
|
||
|
msr_pmon_ctr0: &[0xd16, 0xd36, 0xd56, 0xd76,
|
||
|
0xd96, 0xdb6, 0xdd6, 0xdf6],
|
||
|
msr_pmon_box_filter: &[0xd14, 0xd34, 0xd54, 0xd74, 0xd94, 0xdb4, 0xdd4, 0xdf4],
|
||
|
msr_pmon_ctl0: &[0xd10, 0xd30, 0xd50, 0xd70,
|
||
|
0xd90, 0xdb0, 0xdd0, 0xdf0],
|
||
|
msr_pmon_box_ctl: &[0xd04, 0xd24, 0xd44, 0xd64, 0xd84, 0xda4, 0xdc4, 0xde4],
|
||
|
val_box_freeze: 0x10100,
|
||
|
val_box_reset: 0x10103,
|
||
|
val_enable_counting: 0x400000,
|
||
|
val_select_event: 0x401134,
|
||
|
val_filter: 0x7c0000,
|
||
|
val_box_unfreeze: 0x10000,
|
||
|
};
|
||
|
|
||
|
const IVY_BRIDGE_XEON: XeonPerfCounters = XeonPerfCounters {
|
||
|
max_slice: 15,
|
||
|
msr_pmon_ctr0: &[0xd16, 0xd36, 0xd56, 0xd76, 0xd96, 0xdb6, 0xdd6, 0xdf6,
|
||
|
0xe16, 0xe36, 0xe56, 0xe76, 0xe96, 0xeb6, 0xed6],
|
||
|
msr_pmon_box_filter: &[0xd14, 0xd34, 0xd54, 0xd74, 0xd94, 0xdb4, 0xdd4, 0xdf4,
|
||
|
0xe14, 0xe34, 0xe54, 0xe74, 0xe94, 0xeb4, 0xed4],
|
||
|
msr_pmon_ctl0: &[0xd10, 0xd30, 0xd50, 0xd70, 0xd90, 0xdb0, 0xdd0, 0xdf0,
|
||
|
0xe10, 0xe30, 0xe50, 0xe70, 0xe90, 0xeb0, 0xed0],
|
||
|
msr_pmon_box_ctl: &[0xd04, 0xd24, 0xd44, 0xd64, 0xd84, 0xda4, 0xdc4, 0xde4,
|
||
|
0xe04, 0xe24, 0xe44, 0xe64, 0xe84, 0xea4, 0xec4],
|
||
|
val_box_freeze: 0x30100,
|
||
|
val_box_reset: 0x30103,
|
||
|
val_enable_counting: 0x400000,
|
||
|
val_select_event: 0x401134,
|
||
|
val_filter: 0x7e0010,
|
||
|
val_box_unfreeze: 0x30000,
|
||
|
};
|
||
|
|
||
|
const HASWELL_XEON: XeonPerfCounters = XeonPerfCounters {
|
||
|
max_slice: 18,
|
||
|
msr_pmon_ctr0: &[0xe08, 0xe18, 0xe28, 0xe38, 0xe48, 0xe58, 0xe68, 0xe78, 0xe88,
|
||
|
0xe98, 0xea8, 0xeb8, 0xec8, 0xed8, 0xee8, 0xef8, 0xf08, 0xf18],
|
||
|
msr_pmon_box_filter: &[0xe05, 0xe15, 0xe25, 0xe35, 0xe45, 0xe55, 0xe65, 0xe75, 0xe85,
|
||
|
0xe95, 0xea5, 0xeb5, 0xec5, 0xed5, 0xee5, 0xef5, 0xf05, 0xf15],
|
||
|
msr_pmon_ctl0: &[0xe01, 0xe11, 0xe21, 0xe31, 0xe41, 0xe51, 0xe61, 0xe71, 0xe81,
|
||
|
0xe91, 0xea1, 0xeb1, 0xec1, 0xed1, 0xee1, 0xef1, 0xf01, 0xf11],
|
||
|
msr_pmon_box_ctl: &[0xe00, 0xe10, 0xe20, 0xe30, 0xe40, 0xe50, 0xe60, 0xe70, 0xe80,
|
||
|
0xe90, 0xea0, 0xeb0, 0xec0, 0xed0, 0xee0, 0xef0, 0xf00, 0xf10],
|
||
|
val_box_freeze: 0x30100,
|
||
|
val_box_reset: 0x30103,
|
||
|
val_enable_counting: 0x400000,
|
||
|
val_select_event: 0x401134,
|
||
|
val_filter: 0x7e0020,
|
||
|
val_box_unfreeze: 0x30000,
|
||
|
};
|
||
|
|
||
|
const BROADWELL_XEON: XeonPerfCounters = XeonPerfCounters {
|
||
|
max_slice: 24,
|
||
|
msr_pmon_ctr0: &[0xe08, 0xe18, 0xe28, 0xe38, 0xe48, 0xe58, 0xe68, 0xe78,
|
||
|
0xe88, 0xe98, 0xea8, 0xeb8, 0xec8, 0xed8, 0xee8, 0xef8,
|
||
|
0xf08, 0xf18, 0xf28, 0xf38, 0xf48, 0xf58, 0xf68, 0xf78],
|
||
|
msr_pmon_box_filter: &[0xe05, 0xe15, 0xe25, 0xe35, 0xe45, 0xe55, 0xe65, 0xe75,
|
||
|
0xe85, 0xe95, 0xea5, 0xeb5, 0xec5, 0xed5, 0xee5, 0xef5,
|
||
|
0xf05, 0xf15, 0xf25, 0xf35, 0xf45, 0xf55, 0xf65, 0xf75],
|
||
|
msr_pmon_ctl0: &[0xe01, 0xe11, 0xe21, 0xe31, 0xe41, 0xe51, 0xe61, 0xe71,
|
||
|
0xe81, 0xe91, 0xea1, 0xeb1, 0xec1, 0xed1, 0xee1, 0xef1,
|
||
|
0xf01, 0xf11, 0xf21, 0xf31, 0xf41, 0xf51, 0xf61, 0xf71],
|
||
|
msr_pmon_box_ctl: &[0xe00, 0xe10, 0xe20, 0xe30, 0xe40, 0xe50, 0xe60, 0xe70,
|
||
|
0xe80, 0xe90, 0xea0, 0xeb0, 0xec0, 0xed0, 0xee0, 0xef0,
|
||
|
0xf00, 0xf10, 0xf20, 0xf30, 0xf40, 0xf50, 0xf60, 0xf70],
|
||
|
val_box_freeze: 0x30100,
|
||
|
val_box_reset: 0x30103,
|
||
|
val_enable_counting: 0x400000,
|
||
|
val_select_event: 0x401134,
|
||
|
val_filter: 0xfe0020,
|
||
|
val_box_unfreeze: 0x30000,
|
||
|
};
|
||
|
|
||
|
// TODO find appropriate values
|
||
|
const ALDER_LAKE_TO_RAPTOR_LAKE_CORE: CorePerfCounters = CorePerfCounters {
|
||
|
max_slice: 10,
|
||
|
msr_unc_perf_global_ctr: 0x2ff0,
|
||
|
val_enable_ctrs: 0, // TODO
|
||
|
msr_unc_cbo_perfevtsel0: &[0x2000, 0x2008, 0x2010, 0x2018, 0x2020, 0x2028, 0x2030, 0x2038, 0x2040, 0x2048],
|
||
|
msr_unc_cbo_per_ctr0: &[0x2002, 0x200a, 0x2012, 0x201a, 0x2022, 0x202a, 0x2032, 0x203a, 0x2042, 0x204a],
|
||
|
val_disable_ctrs: 0, // TODO
|
||
|
val_select_evt_core: 0, // TODO
|
||
|
val_reset_ctrs: 0, // TODO
|
||
|
};
|
||
|
|
||
|
// TODO verify his on ICELAKE, and appropriate values. Also deal with backport Cypress Cove ?
|
||
|
const CANNON_LAKE_TO_TIGER_LAKE_CORE: CorePerfCounters = CorePerfCounters {
|
||
|
max_slice: 8, // TODO
|
||
|
msr_unc_perf_global_ctr: 0xe01,
|
||
|
val_enable_ctrs: 0, // TODO
|
||
|
msr_unc_cbo_perfevtsel0: &[0x700, 0x708, 0x710, 0x718, 0x720, 0x728, 0x730, 0x738],
|
||
|
msr_unc_cbo_per_ctr0: &[0x702, 0x70a, 0x712, 0x71a, 0x722, 0x72a, 0x732, 0x73a],
|
||
|
val_disable_ctrs: 0x0, // TODO
|
||
|
val_select_evt_core: 0, // TODO
|
||
|
val_reset_ctrs: 0x0, // TODO
|
||
|
};
|
||
|
|
||
|
const SKYLAKE_KABYLAKE_CORE: CorePerfCounters = CorePerfCounters {
|
||
|
max_slice: 7,
|
||
|
msr_unc_perf_global_ctr: 0xe01,
|
||
|
val_enable_ctrs: 0x20000000,
|
||
|
msr_unc_cbo_perfevtsel0: &[0x700, 0x710, 0x720, 0x730, 0x740, 0x750, 0x760],
|
||
|
msr_unc_cbo_per_ctr0: &[0x706, 0x716, 0x726, 0x736, 0x746, 0x756, 0x766],
|
||
|
val_disable_ctrs: 0x0,
|
||
|
val_select_evt_core: 0x408f34,
|
||
|
val_reset_ctrs: 0x0,
|
||
|
};
|
||
|
|
||
|
const SANDYBRIDGE_TO_BROADWELL_CORE: CorePerfCounters = CorePerfCounters {
|
||
|
max_slice: 0,
|
||
|
msr_unc_perf_global_ctr: 0x391,
|
||
|
val_enable_ctrs: 0x2000000f,
|
||
|
msr_unc_cbo_perfevtsel0: &[0x700, 0x710, 0x720, 0x730],
|
||
|
msr_unc_cbo_per_ctr0: &[0x706, 0x716, 0x726, 0x736],
|
||
|
val_disable_ctrs: 0x0,
|
||
|
val_select_evt_core: 0x408f34,
|
||
|
val_reset_ctrs: 0x0,
|
||
|
};
|