From 8e95828fb1edb89ded79b23e23d191afd4a8f6fb Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Thu, 4 May 2023 19:01:55 +0200 Subject: [PATCH] [v1.03][PPC] Read frequency from cpuinfo if the default method fails --- src/arm/udev.c | 21 --------------------- src/common/udev.c | 21 +++++++++++++++++++++ src/common/udev.h | 2 ++ src/ppc/ppc.c | 6 ++++++ src/ppc/udev.c | 31 +++++++++++++++++++++++++++++++ src/ppc/udev.h | 1 + 6 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/arm/udev.c b/src/arm/udev.c index 1fe0a1b..4a2ea40 100644 --- a/src/arm/udev.c +++ b/src/arm/udev.c @@ -108,27 +108,6 @@ uint32_t get_midr_from_cpuinfo(uint32_t core, bool* success) { return midr; } -char* get_field_from_cpuinfo(char* CPUINFO_FIELD) { - int filelen; - char* buf; - if((buf = read_file(_PATH_CPUINFO, &filelen)) == NULL) { - printWarn("read_file: %s: %s:\n", _PATH_CPUINFO, strerror(errno)); - return NULL; - } - - char* tmp1 = strstr(buf, CPUINFO_FIELD); - if(tmp1 == NULL) return NULL; - tmp1 = tmp1 + strlen(CPUINFO_FIELD); - char* tmp2 = strstr(tmp1, "\n"); - - int strlen = (1 + (tmp2-tmp1)); - char* hardware = emalloc(sizeof(char) * strlen); - memset(hardware, 0, sizeof(char) * strlen); - strncpy(hardware, tmp1, tmp2-tmp1); - - return hardware; -} - char* get_hardware_from_cpuinfo(void) { return get_field_from_cpuinfo(CPUINFO_HARDWARE_STR); } diff --git a/src/common/udev.c b/src/common/udev.c index ce35e5a..8b4efa8 100644 --- a/src/common/udev.c +++ b/src/common/udev.c @@ -129,6 +129,27 @@ long get_cache_size_from_file(char* path) { return ret * 1024; } +char* get_field_from_cpuinfo(char* CPUINFO_FIELD) { + int filelen; + char* buf; + if((buf = read_file(_PATH_CPUINFO, &filelen)) == NULL) { + printWarn("read_file: %s: %s:\n", _PATH_CPUINFO, strerror(errno)); + return NULL; + } + + char* tmp1 = strstr(buf, CPUINFO_FIELD); + if(tmp1 == NULL) return NULL; + tmp1 = tmp1 + strlen(CPUINFO_FIELD); + char* tmp2 = strstr(tmp1, "\n"); + + int strlen = (1 + (tmp2-tmp1)); + char* hardware = emalloc(sizeof(char) * strlen); + memset(hardware, 0, sizeof(char) * strlen); + strncpy(hardware, tmp1, tmp2-tmp1); + + return hardware; +} + long get_max_freq_from_file(uint32_t core) { char path[_PATH_FREQUENCY_MAX_LEN]; sprintf(path, "%s%s/cpu%d%s%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_FREQUENCY, _PATH_FREQUENCY_MAX); diff --git a/src/common/udev.h b/src/common/udev.h index b9e1491..f2c4c2e 100644 --- a/src/common/udev.h +++ b/src/common/udev.h @@ -12,6 +12,7 @@ #include "cpu.h" +#define _PATH_CPUINFO "/proc/cpuinfo" #define _PATH_SYS_SYSTEM "/sys/devices/system" #define _PATH_SYS_CPU "/cpu" #define _PATH_FREQUENCY "/cpufreq" @@ -40,6 +41,7 @@ long get_l3_cache_size(uint32_t core); int get_num_caches_by_level(struct cpuInfo* cpu, uint32_t level); int get_num_sockets_package_cpus(struct topology* topo); int get_ncores_from_cpuinfo(void); +char* get_field_from_cpuinfo(char* CPUINFO_FIELD); bool is_devtree_compatible(char* str); #endif diff --git a/src/ppc/ppc.c b/src/ppc/ppc.c index 0b3b939..83d9053 100644 --- a/src/ppc/ppc.c +++ b/src/ppc/ppc.c @@ -146,6 +146,12 @@ struct frequency* get_frequency_info(void) { freq->max = get_max_freq_from_file(0); freq->base = get_min_freq_from_file(0); + if(freq->max == UNKNOWN_DATA) { + // If we are unable to find it in the + // standard path, try /proc/cpuinfo + freq->max = get_frequency_from_cpuinfo(); + } + return freq; } diff --git a/src/ppc/udev.c b/src/ppc/udev.c index 3313e64..601a0b1 100644 --- a/src/ppc/udev.c +++ b/src/ppc/udev.c @@ -6,6 +6,7 @@ #define _PATH_TOPO_CORE_ID "topology/core_id" #define _PATH_TOPO_PACKAGE_ID "topology/physical_package_id" +#define CPUINFO_FREQUENCY_STR "clock\t\t: " bool fill_array_from_sys(int *core_ids, int total_cores, char* SYS_PATH) { int filelen; @@ -57,3 +58,33 @@ bool fill_package_ids_from_sys(int* package_ids, int total_cores) { } return false; } + +long get_frequency_from_cpuinfo(void) { + char* freq_str = get_field_from_cpuinfo(CPUINFO_FREQUENCY_STR); + if(freq_str == NULL) { + return UNKNOWN_DATA; + } + else { + // freq_str should be in the form XXXX.YYYYYYMHz + char* dot = strstr(freq_str, "."); + freq_str[dot-freq_str] = '\0'; + + char* end; + errno = 0; + long ret = strtol(freq_str, &end, 10); + if(errno != 0) { + printBug("strtol: %s", strerror(errno)); + free(freq_str); + return UNKNOWN_DATA; + } + + // We consider it an error if frequency is + // greater than 10 GHz or less than 100 MHz + if(ret > 10000 || ret < 100) { + printBug("Invalid data was read from file '%s': %ld\n", CPUINFO_FREQUENCY_STR, ret); + return UNKNOWN_DATA; + } + + return ret; + } +} diff --git a/src/ppc/udev.h b/src/ppc/udev.h index 2d0f9cc..b4157fa 100644 --- a/src/ppc/udev.h +++ b/src/ppc/udev.h @@ -11,5 +11,6 @@ bool fill_core_ids_from_sys(int *core_ids, int total_cores); bool fill_package_ids_from_sys(int* package_ids, int total_cores); int get_num_sockets_package_cpus(struct topology* topo); +long get_frequency_from_cpuinfo(void); #endif