Skip to content

Commit b95c04a

Browse files
committed
fixup! fixup! fixup! prochot msr
1 parent e6650b6 commit b95c04a

1 file changed

Lines changed: 47 additions & 28 deletions

File tree

framework_lib/src/msr.rs

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const PLR_RING_BITS: &[(u32, &str)] = &[
7676
];
7777

7878
/// Status/log bit pairs shared by IA32_THERM_STATUS and
79-
/// IA32_PACKAGE_THERM_STATUS. Bit 12/13 differs between the two.
79+
/// IA32_PACKAGE_THERM_STATUS. The log bit is always one bit higher.
8080
const THERM_STATUS_BITS: &[(u32, &str)] = &[
8181
(0, "Thermal Monitor"),
8282
(2, "PROCHOT/FORCEPR"),
@@ -85,6 +85,10 @@ const THERM_STATUS_BITS: &[(u32, &str)] = &[
8585
(8, "Threshold #2"),
8686
(10, "Power Limit"),
8787
];
88+
/// Bits above 11 that only exist in the per core IA32_THERM_STATUS
89+
const THERM_STATUS_CORE_BITS: &[(u32, &str)] = &[(12, "Current Limit"), (14, "Cross Domain Limit")];
90+
/// Bits above 11 that only exist in IA32_PACKAGE_THERM_STATUS
91+
const THERM_STATUS_PKG_BITS: &[(u32, &str)] = &[(12, "Pmax Limit")];
8892

8993
fn bit(value: u64, bit: u32) -> bool {
9094
(value >> bit) & 1 == 1
@@ -471,22 +475,7 @@ pub fn print_thermal_msrs() {
471475
);
472476
}
473477
println!(" Package Thermal Status ({:#010X})", pkg.raw);
474-
println!(" {:<24} {:>6} {:>6}", "Condition", "Active", "Logged");
475-
for (b, name) in THERM_STATUS_BITS {
476-
println!(
477-
" {:<24} {:>6} {:>6}",
478-
format!("{}:", name),
479-
yes_no(bit(pkg.raw, *b)),
480-
yes_no(bit(pkg.raw, b + 1))
481-
);
482-
}
483-
// Bit 12/13 is Pmax in the package MSR, Current Limit per core
484-
println!(
485-
" {:<24} {:>6} {:>6}",
486-
"Pmax Limit:",
487-
yes_no(bit(pkg.raw, 12)),
488-
yes_no(bit(pkg.raw, 13))
489-
);
478+
print_therm_status_table(pkg.raw, THERM_STATUS_PKG_BITS);
490479
}
491480
}
492481

@@ -506,16 +495,40 @@ pub fn print_thermal_msrs() {
506495
print_power_ctl();
507496
}
508497

509-
/// Print the hottest core and which cores are currently being throttled
498+
/// Print the Active/Logged table of a THERM_STATUS style MSR
499+
///
500+
/// The bits above 11 differ between the per core and the package register, so
501+
/// the caller passes those in.
502+
fn print_therm_status_table(raw: u64, extra: &[(u32, &str)]) {
503+
println!(" {:<24} {:>6} {:>6}", "Condition", "Active", "Logged");
504+
for (b, name) in THERM_STATUS_BITS.iter().chain(extra) {
505+
println!(
506+
" {:<24} {:>6} {:>6}",
507+
format!("{}:", name),
508+
yes_no(bit(raw, *b)),
509+
yes_no(bit(raw, b + 1))
510+
);
511+
}
512+
}
513+
514+
/// Print the hottest core and the thermal status across all cores
510515
fn print_core_therm_status(ref_temp: u8) {
511516
let cpus = cpu_count();
512517
let mut hottest: Option<(u32, i32)> = None;
513518
let mut throttling = Vec::new();
519+
// The status bits are per core, so OR them together to see whether any
520+
// core ever hit a condition. Reading every core individually is far too
521+
// much output on a system with dozens of them.
522+
let mut any = 0;
523+
let mut read = 0;
514524

515525
for cpu in 0..cpus {
516526
let Some(status) = read_msr(cpu, MSR_IA32_THERM_STATUS).map(ThermStatus::from) else {
517527
continue;
518528
};
529+
read += 1;
530+
// Mask off temperature, resolution and valid, they're not status bits
531+
any |= status.raw & 0xFFFF;
519532
if let Some(temp) = status.temp(ref_temp) {
520533
match hottest {
521534
Some((_, hottest_temp)) if temp <= hottest_temp => {}
@@ -527,19 +540,25 @@ fn print_core_therm_status(ref_temp: u8) {
527540
}
528541
}
529542

543+
if read == 0 {
544+
return;
545+
}
530546
if let Some((cpu, temp)) = hottest {
531547
println!(" Hottest Core Temp: {:>4} C (CPU {})", temp, cpu);
532548
}
533-
if cpus > 0 {
534-
println!(
535-
" Cores Throttling: {:>4}",
536-
if throttling.is_empty() {
537-
"None".to_string()
538-
} else {
539-
throttling.join(", ")
540-
}
541-
);
542-
}
549+
println!(
550+
" Cores Throttling: {:>4}",
551+
if throttling.is_empty() {
552+
"None".to_string()
553+
} else {
554+
throttling.join(", ")
555+
}
556+
);
557+
println!(
558+
" Core Thermal Status, any of {} cores ({:#06X})",
559+
read, any
560+
);
561+
print_therm_status_table(any, THERM_STATUS_CORE_BITS);
543562
}
544563

545564
/// Print which limits are clipping the core, graphics and ring frequency

0 commit comments

Comments
 (0)