From 92019bbb5ef147b72776ddbea3e2024585ec0d6b Mon Sep 17 00:00:00 2001 From: Miguel Borges de Freitas <92enen@gmail.com> Date: Sat, 26 Aug 2023 10:57:18 +0100 Subject: [PATCH] Add support for Apple M2 --- smctemp.cc | 115 +++++++++++++++++++++++++++++++++++++++++++---------- smctemp.h | 24 ++++++----- 2 files changed, 107 insertions(+), 32 deletions(-) diff --git a/smctemp.cc b/smctemp.cc index 017092d..32f5733 100755 --- a/smctemp.cc +++ b/smctemp.cc @@ -33,6 +33,22 @@ #include "smctemp_string.h" +#if defined(ARCH_TYPE_ARM64) +#include +#include + +namespace { +std::string getCPUModel() { + std::array buffer; + size_t bufferLength = buffer.size(); + sysctlbyname("machdep.cpu.brand_string", buffer.data(), &bufferLength, nullptr, 0); + std::string cpuModel = buffer.data(); + std::transform(cpuModel.begin(), cpuModel.end(), cpuModel.begin(), ::tolower); + return cpuModel; +} +} +#endif + // Cache the keyInfo to lower the energy impact of SmcReadKey() / SmcReadKey2() #define KEY_INFO_CACHE_SIZE 100 namespace smctemp { @@ -388,35 +404,90 @@ double SmcTemp::GetCpuTemp() { return temp; } #elif defined(ARCH_TYPE_ARM64) - std::vector sensors{ - static_cast(kSensorTp01), - static_cast(kSensorTp05), - static_cast(kSensorTp0d), - static_cast(kSensorTp0h), - static_cast(kSensorTp0l), - static_cast(kSensorTp0p), - static_cast(kSensorTp0x), - static_cast(kSensorTp0b), - static_cast(kSensorTp09), - static_cast(kSensorTp0t), - }; + std::vector sensors; + std::vector aux_sensors; + + const std::string cpumodel = getCPUModel(); + if (cpumodel.find("m2") != std::string::npos ) { // Apple M2 + // CPU performance core 1 temperature + sensors.emplace_back(static_cast(kSensorTp01)); + // CPU performance core 2 temperature + sensors.emplace_back(static_cast(kSensorTp09)); + // CPU performance core 3 temperature + sensors.emplace_back(static_cast(kSensorTp0f)); + // CPU performance core 4 temperature + sensors.emplace_back(static_cast(kSensorTp0n)); + // CPU efficient core 1 temperature + sensors.emplace_back(static_cast(kSensorTp05)); + // CPU efficient core 2 temperature + sensors.emplace_back(static_cast(kSensorTp0d)); + // CPU efficient core 3 temperature + sensors.emplace_back(static_cast(kSensorTp0j)); + // CPU efficient core 4 temperature + sensors.emplace_back(static_cast(kSensorTp0r)); + + // TODO: m2 pro, m2 max, m2 ultra have more cpu cores (unknown sensors) + //if (cpumodel.find("pro") != std::string::npos || + // cpumodel.find("max") != std::string::npos || + // cpumodel.find("ultra") != std::string::npos) { + // // TODO: add additional sensors + // } + + } else if (cpumodel.find("m1") != std::string::npos) { // Apple M1 + // CPU performance core 1 temperature + sensors.emplace_back(static_cast(kSensorTp01)); + // CPU performance core 2 temperature + sensors.emplace_back(static_cast(kSensorTp05)); + // CPU performance core 3 temperature + sensors.emplace_back(static_cast(kSensorTp0d)); + // CPU performance core 4 temperature + sensors.emplace_back(static_cast(kSensorTp0h)); + // CPU performance core 5 temperature + sensors.emplace_back(static_cast(kSensorTp0l)); + // CPU performance core 6 temperature + sensors.emplace_back(static_cast(kSensorTp0p)); + // CPU performance core 7 temperature + sensors.emplace_back(static_cast(kSensorTp0x)); + // CPU performance core 8 temperature + sensors.emplace_back(static_cast(kSensorTp0b)); + // CPU efficient core 1 temperature + sensors.emplace_back(static_cast(kSensorTp09)); + // CPU efficient core 2 temperature + sensors.emplace_back(static_cast(kSensorTp0t)); + + aux_sensors.emplace_back(static_cast(kSensorTc0a)); + aux_sensors.emplace_back(static_cast(kSensorTc0b)); + aux_sensors.emplace_back(static_cast(kSensorTc0x)); + aux_sensors.emplace_back(static_cast(kSensorTc0z)); + } else { + // not supported + return temp; + } + + size_t valid_sensor_count = 0; for (auto sensor : sensors) { - temp += smc_accessor_.ReadValue(sensor.c_str()); + auto sensor_value = smc_accessor_.ReadValue(sensor.c_str()); + if (sensor_value > 0.0) { + temp += sensor_value; + valid_sensor_count++; + } } - temp /= sensors.size(); + temp /= valid_sensor_count; if (temp > std::numeric_limits::epsilon()) { return temp; } - std::vector aux_sensors{ - static_cast(kSensorTc0a), - static_cast(kSensorTc0b), - static_cast(kSensorTc0x), - static_cast(kSensorTc0z), - }; + + size_t valid_aux_sensor_count = 0; for (auto sensor : aux_sensors) { - temp += smc_accessor_.ReadValue(sensor.c_str()); + auto sensor_value = smc_accessor_.ReadValue(sensor.c_str()); + if (sensor_value > 0.0) { + temp += sensor_value; + valid_aux_sensor_count++; + } + } + if (valid_aux_sensor_count > 0) { + temp /= valid_aux_sensor_count; } - temp /= aux_sensors.size(); #endif return temp; } diff --git a/smctemp.h b/smctemp.h index 2b0c6f2..b3c3d1e 100755 --- a/smctemp.h +++ b/smctemp.h @@ -54,16 +54,20 @@ constexpr UInt32Char_t kSensorTc0a = "Tc0a"; constexpr UInt32Char_t kSensorTc0b = "Tc0b"; constexpr UInt32Char_t kSensorTc0x = "Tc0x"; constexpr UInt32Char_t kSensorTc0z = "Tc0z"; -constexpr UInt32Char_t kSensorTp01 = "Tp01"; // CPU performance core 1 temperature -constexpr UInt32Char_t kSensorTp05 = "Tp05"; // CPU performance core 2 temperature -constexpr UInt32Char_t kSensorTp0d = "Tp0D"; // CPU performance core 3 temperature -constexpr UInt32Char_t kSensorTp0h = "Tp0H"; // CPU performance core 4 temperature -constexpr UInt32Char_t kSensorTp0l = "Tp0L"; // CPU performance core 5 temperature -constexpr UInt32Char_t kSensorTp0p = "Tp0P"; // CPU performance core 6 temperature -constexpr UInt32Char_t kSensorTp0x = "Tp0X"; // CPU performance core 7 temperature -constexpr UInt32Char_t kSensorTp0b = "Tp0b"; // CPU performance core 8 temperature -constexpr UInt32Char_t kSensorTp09 = "Tp09"; // CPU efficient core 1 temperature -constexpr UInt32Char_t kSensorTp0t = "Tp0T"; // CPU efficient core 2 temperature +constexpr UInt32Char_t kSensorTp01 = "Tp01"; +constexpr UInt32Char_t kSensorTp05 = "Tp05"; +constexpr UInt32Char_t kSensorTp0d = "Tp0D"; +constexpr UInt32Char_t kSensorTp0h = "Tp0H"; +constexpr UInt32Char_t kSensorTp0l = "Tp0L"; +constexpr UInt32Char_t kSensorTp0p = "Tp0P"; +constexpr UInt32Char_t kSensorTp0x = "Tp0X"; +constexpr UInt32Char_t kSensorTp0b = "Tp0b"; +constexpr UInt32Char_t kSensorTp09 = "Tp09"; +constexpr UInt32Char_t kSensorTp0t = "Tp0T"; +constexpr UInt32Char_t kSensorTp0j = "Tp0j"; +constexpr UInt32Char_t kSensorTp0r = "Tp0r"; +constexpr UInt32Char_t kSensorTp0f = "Tp0f"; +constexpr UInt32Char_t kSensorTp0n = "Tp0n"; #endif class SmcAccessor {