diff --git a/linux/LibSensors.c b/linux/LibSensors.c index f3f2cf45a..5eface204 100644 --- a/linux/LibSensors.c +++ b/linux/LibSensors.c @@ -152,6 +152,62 @@ static int tempDriverPriority(const sensors_chip_name* chip) { return -1; } +void LibSensors_countCCDs(CPUData* cpus, unsigned int existingCPUs) { + /* For AMD k10temp/zenpower, temperatures are provided for CCDs only, + which is an aggregate of multiple cores. + There's no obvious mapping between hwmon sensors and sockets and CCDs. + Assume both are iterated in order. + Hypothesis: Each CCD has same size N = #Cores/#CCD + and is assigned N coreID in sequence. + Also assume all CPUs have same number of CCDs. */ + + int ccds = 0; + + for (size_t i = 0; i < existingCPUs + 1; i++) { + cpus[i].ccdID = -1; + } + + int n = 0; + for (const sensors_chip_name* chip = sym_sensors_get_detected_chips(NULL, &n); chip; chip = sym_sensors_get_detected_chips(NULL, &n)) { + int m = 0; + for (const sensors_feature* feature = sym_sensors_get_features(chip, &m); feature; feature = sym_sensors_get_features(chip, &m)) { + if (feature->type != SENSORS_FEATURE_TEMP) + continue; + + if (!feature->name || !String_startsWith(feature->name, "temp")) + continue; + + char *label = sym_sensors_get_label(chip, feature); + if (label) { + if (String_startsWith(label, "Tccd")) { + ccds++; + } + free(label); + } + } + } + + if (ccds > 0) { + int ccdsPerCore = existingCPUs / ccds; + + int ccd = 0; + int nc = ccdsPerCore; + for (int p = 0; p < (int)existingCPUs; p++) { + for (int c = 0; c < (int)existingCPUs; c++) { + for (size_t i = 1; i <= existingCPUs; i++) { + if (cpus[i].physicalID == p && cpus[i].coreID == c) { + cpus[i].ccdID = ccd; + if (--nc == 0) { + nc = ccdsPerCore; + ccd++; + } + } + } + } + } + } +} + void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int existingCPUs, unsigned int activeCPUs) { assert(existingCPUs > 0 && existingCPUs < 16384); diff --git a/linux/LibSensors.h b/linux/LibSensors.h index 6f0544897..a30d48a2d 100644 --- a/linux/LibSensors.h +++ b/linux/LibSensors.h @@ -14,6 +14,7 @@ int LibSensors_init(void); void LibSensors_cleanup(void); int LibSensors_reload(void); +void LibSensors_countCCDs(CPUData* cpus, unsigned int existingCPUs); void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int existingCPUs, unsigned int activeCPUs); #endif /* HEADER_LibSensors */ diff --git a/linux/LinuxMachine.h b/linux/LinuxMachine.h index 4f04ff905..25c59fdb8 100644 --- a/linux/LinuxMachine.h +++ b/linux/LinuxMachine.h @@ -55,6 +55,7 @@ typedef struct CPUData_ { int physicalID; /* different for each CPU socket */ int coreID; /* same for hyperthreading */ + int ccdID; /* same for each AMD chiplet */ #endif bool online;