summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJos Dehaes <jos.dehaes@gmail.com>2021-12-21 23:15:02 +0100
committerJos Dehaes <jos.dehaes@gmail.com>2021-12-21 23:15:02 +0100
commit96ac1149d15743d148c51714b496e389a71fe8f4 (patch)
tree6430aad3e2c05d6328e1cf1e75159e037d5fec2c
parentd4f5112d23c8d7b21032f6d6b840f6f1c2a96301 (diff)
fix CPU temp fallback on macOS
-rw-r--r--src/osx/btop_collect.cpp28
-rw-r--r--src/osx/smc.cpp33
-rw-r--r--src/osx/smc.hpp4
3 files changed, 43 insertions, 22 deletions
diff --git a/src/osx/btop_collect.cpp b/src/osx/btop_collect.cpp
index f976a55..ae4411a 100644
--- a/src/osx/btop_collect.cpp
+++ b/src/osx/btop_collect.cpp
@@ -68,6 +68,7 @@ namespace Cpu {
cpu_info current_cpu;
fs::path freq_path = "/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq";
bool got_sensors = false, cpu_temp_only = false;
+ int core_offset = 0;
//* Populate found_sensors map
bool get_sensors();
@@ -241,21 +242,34 @@ namespace Cpu {
}
bool get_sensors() {
+ Logger::debug("get_sensors(): show_coretemp=" + std::to_string(Config::getB("show_coretemp")) + " check_temp=" + std::to_string(Config::getB("check_temp")));
got_sensors = false;
if (Config::getB("show_coretemp") and Config::getB("check_temp")) {
ThermalSensors sensors;
if (sensors.getSensors() > 0) {
+ Logger::debug("M1 sensors found");
got_sensors = true;
cpu_temp_only = true;
macM1 = true;
} else {
// try SMC (intel)
+ Logger::debug("checking intel");
SMCConnection smcCon;
try {
long long t = smcCon.getTemp(-1); // check if we have package T
if (t > -1) {
+ Logger::debug("intel sensors found");
got_sensors = true;
+ t = smcCon.getTemp(0);
+ if (t == -1) {
+ // for some macs the core offset is 1 - check if we get a sane value with 1
+ if (smcCon.getTemp(1) > -1) {
+ Logger::debug("intel sensors with offset 1");
+ core_offset = 1;
+ }
+ }
} else {
+ Logger::debug("no intel sensors found");
got_sensors = false;
}
} catch (std::runtime_error &e) {
@@ -282,14 +296,12 @@ namespace Cpu {
long long packageT = smcCon.getTemp(-1); // -1 returns package T
current_cpu.temp.at(0).push_back(packageT);
- if (Config::getB("show_coretemp") and not cpu_temp_only) {
- for (int core = 0; core < Shared::coreCount; core++) {
- long long temp = smcCon.getTemp(core / threadsPerCore); // same temp for all threads of same physical core
- if (cmp_less(core + 1, current_cpu.temp.size())) {
- current_cpu.temp.at(core + 1).push_back(temp);
- if (current_cpu.temp.at(core + 1).size() > 20)
- current_cpu.temp.at(core + 1).pop_front();
- }
+ for (int core = 0; core < Shared::coreCount; core++) {
+ long long temp = smcCon.getTemp((core / threadsPerCore) + core_offset); // same temp for all threads of same physical core
+ if (cmp_less(core + 1, current_cpu.temp.size())) {
+ current_cpu.temp.at(core + 1).push_back(temp);
+ if (current_cpu.temp.at(core + 1).size() > 20)
+ current_cpu.temp.at(core + 1).pop_front();
}
}
}
diff --git a/src/osx/smc.cpp b/src/osx/smc.cpp
index 7386dbf..54fa422 100644
--- a/src/osx/smc.cpp
+++ b/src/osx/smc.cpp
@@ -50,32 +50,39 @@ namespace Cpu {
IOServiceClose(conn);
}
+ long long SMCConnection::getSMCTemp(char *key) {
+ SMCVal_t val;
+ kern_return_t result;
+ result = SMCReadKey(key, &val);
+ if (result == kIOReturnSuccess) {
+ if (val.dataSize > 0) {
+ if (strcmp(val.dataType, DATATYPE_SP78) == 0) {
+ // convert sp78 value to temperature
+ int intValue = val.bytes[0] * 256 + (unsigned char)val.bytes[1];
+ return static_cast<long long>(intValue / 256.0);
+ }
+ }
+ }
+ return -1;
+ }
+
// core means physical core in SMC, while in core map it's cpu threads :-/ Only an issue on hackintosh?
// this means we can only get the T per physical core
// another issue with the SMC API is that the key is always 4 chars -> what with systems with more than 9 physical cores?
// no Mac models with more than 18 threads are released, so no problem so far
// according to VirtualSMC docs (hackintosh fake SMC) the enumeration follows with alphabetic chars - not implemented yet here (nor in VirtualSMC)
long long SMCConnection::getTemp(int core) {
- SMCVal_t val;
- kern_return_t result;
char key[] = SMC_KEY_CPU_TEMP;
if (core >= 0) {
snprintf(key, 5, "TC%1dc", core);
}
- result = SMCReadKey(key, &val);
- if (result != kIOReturnSuccess) {
+ long long result = getSMCTemp(key);
+ if (result == -1) {
// try again with C
snprintf(key, 5, "TC%1dC", core);
- result = SMCReadKey(key, &val);
+ result = getSMCTemp(key);
}
- if (result == kIOReturnSuccess) {
- if (strcmp(val.dataType, DATATYPE_SP78) == 0) {
- // convert sp78 value to temperature
- int intValue = val.bytes[0] * 256 + (unsigned char)val.bytes[1];
- return static_cast<long long>(intValue / 256.0);
- }
- }
- return -1;
+ return result;
}
kern_return_t SMCConnection::SMCReadKey(UInt32Char_t key, SMCVal_t *val) {
diff --git a/src/osx/smc.hpp b/src/osx/smc.hpp
index 6d65c9c..87ed2ef 100644
--- a/src/osx/smc.hpp
+++ b/src/osx/smc.hpp
@@ -26,7 +26,8 @@
// key values
#define SMC_KEY_CPU_TEMP "TC0P" // proximity temp?
-#define SMC_KEY_CPU_DIE_TEMP "TC0D" // die temp?
+#define SMC_KEY_CPU_DIODE_TEMP "TC0D" // diode temp?
+#define SMC_KEY_CPU_DIE_TEMP "TC0F" // die temp?
#define SMC_KEY_CPU1_TEMP "TC1C"
#define SMC_KEY_CPU2_TEMP "TC2C" // etc
#define SMC_KEY_FAN0_RPM_CUR "F0Ac"
@@ -86,6 +87,7 @@ namespace Cpu {
private:
kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val);
+ long long getSMCTemp(char *key);
kern_return_t SMCCall(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure);
io_connect_t conn;