mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2024-11-27 01:50:20 -06:00
de4f4768fc
Also, remove the no_temperature var to keep only the enable_temperature flag Older Atom still have the enable_temperature flag hard-coded to false until further tests are done
142 lines
4.1 KiB
C
142 lines
4.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
// Copyright (C) 2020-2022 Martin Whitaker.
|
|
// Copyright (C) 2004-2023 Sam Demeulemeester.
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "config.h"
|
|
#include "cpuid.h"
|
|
#include "cpuinfo.h"
|
|
#include "hwquirks.h"
|
|
#include "memctrl.h"
|
|
#include "msr.h"
|
|
#include "pci.h"
|
|
|
|
#include "temperature.h"
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Public Variables
|
|
//------------------------------------------------------------------------------
|
|
|
|
float cpu_temp_offset = 0;
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Public Functions
|
|
//------------------------------------------------------------------------------
|
|
|
|
static int TjMax = 0;
|
|
|
|
void get_specific_TjMax(void)
|
|
{
|
|
// The TjMax value for some Mobile/Embedded CPUs must be read from a fixed
|
|
// table according to their CPUID, PCI Root DID/VID or PNS.
|
|
// Trying to read the MSR 0x1A2 on some of them trigger a reboot.
|
|
|
|
if (cpuid_info.version.raw[0] == 0x6E8) {
|
|
// Yonah C0 Step (Pentium/Core Duo T2000 & Celeron M 200/400)
|
|
TjMax = 100;
|
|
} else if (imc.family == IMC_SLT || imc.family == IMC_CLT || imc.family == IMC_TNC) {
|
|
// Atom Silverthorne / Diamondvile
|
|
// Atom Clover Trail/Cloverview
|
|
// Atom Tunnel Creek / Lincroft
|
|
TjMax = 90;
|
|
} else if (imc.family == IMC_CDT || imc.family == IMC_PNV) {
|
|
// Atom Silverthorne / Diamondvile
|
|
// Atom Cedar Trail/Cedarview
|
|
TjMax = 100;
|
|
}
|
|
}
|
|
|
|
void temperature_init(void)
|
|
{
|
|
uint32_t regl, regh;
|
|
|
|
if (!enable_temperature) {
|
|
return;
|
|
}
|
|
|
|
// Process temperature-related quirks
|
|
if (quirk.type & QUIRK_TYPE_TEMP) {
|
|
quirk.process();
|
|
}
|
|
|
|
// Get TjMax for Intel CPU
|
|
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6 && (cpuid_info.dts_pmp & 1)) {
|
|
|
|
get_specific_TjMax();
|
|
|
|
if (TjMax == 0) {
|
|
// Generic Method using MSR 0x1A2
|
|
rdmsr(MSR_IA32_TEMPERATURE_TARGET, regl, regh);
|
|
TjMax = (regl >> 16) & 0x7F;
|
|
|
|
if (TjMax < 50 || TjMax > 125) {
|
|
TjMax = 100;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int get_cpu_temperature(void)
|
|
{
|
|
uint32_t regl, regh;
|
|
|
|
// Intel CPU
|
|
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6 && (cpuid_info.dts_pmp & 1)) {
|
|
|
|
rdmsr(MSR_IA32_THERM_STATUS, regl, regh);
|
|
int Tabs = (regl >> 16) & 0x7F;
|
|
|
|
return TjMax - Tabs;
|
|
}
|
|
|
|
// AMD CPU
|
|
else if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF) { // Target only K8 & newer
|
|
|
|
if (cpuid_info.version.extendedFamily >= 8) { // Target Zen µarch and newer. Use SMN to get temperature.
|
|
|
|
regl = amd_smn_read(SMN_THM_TCON_CUR_TMP);
|
|
|
|
if ((regl >> 19) & 0x01) {
|
|
cpu_temp_offset = -49.0f;
|
|
}
|
|
|
|
return cpu_temp_offset + 0.125f * (float)((regl >> 21) & 0x7FF);
|
|
|
|
} else if (cpuid_info.version.extendedFamily > 0) { // Target K10 to K15 (Bulldozer)
|
|
|
|
regl = pci_config_read32(0, 24, 3, AMD_TEMP_REG_K10);
|
|
int raw_temp = ((regl >> 21) & 0x7FF) / 8;
|
|
|
|
return (raw_temp > 0) ? raw_temp : 0;
|
|
|
|
} else { // Target K8 (CPUID ExtFamily = 0)
|
|
|
|
regl = pci_config_read32(0, 24, 3, AMD_TEMP_REG_K8);
|
|
int raw_temp = ((regl >> 16) & 0xFF) - 49 + cpu_temp_offset;
|
|
|
|
return (raw_temp > 0) ? raw_temp : 0;
|
|
}
|
|
}
|
|
|
|
// VIA/Centaur/Zhaoxin CPU
|
|
else if (cpuid_info.vendor_id.str[0] == 'C' && cpuid_info.vendor_id.str[1] == 'e'
|
|
&& (cpuid_info.version.family == 6 || cpuid_info.version.family == 7)) {
|
|
|
|
uint32_t msr_temp;
|
|
|
|
if (cpuid_info.version.family == 7 || cpuid_info.version.model == 0xF) {
|
|
msr_temp = MSR_VIA_TEMP_NANO; // Zhaoxin, Nano
|
|
} else if (cpuid_info.version.model == 0xA || cpuid_info.version.model == 0xD) {
|
|
msr_temp = MSR_VIA_TEMP_C7; // C7 A/D
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
rdmsr(msr_temp, regl, regh);
|
|
return (int)(regl & 0xffffff);
|
|
}
|
|
|
|
return 0;
|
|
}
|