mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-26 08:20:38 +01:00
[v1.06][ARM] Implement automatic SoC inferring from device tree
This is a major change in the SoC detection methodology. Previous to this commit, the SoC (model, vendor and manufacturing process) would only appear if the exact model was found in the LUT. In other words, every supported SoC must be added manually to the LUT. This would allow to show the precise SoC model and the manufacturing process, which can only be hardcoded (i.e., it cannot be dynamically determined). This commit introduces guess_raw_soc_from_devtree, a new way of inferring the SoC. This simply reads from the compatible file in the device tree and tries to find a matching vendor to that string. If there is a match, then we simply copy the model also from the compatible string and show it directly. This new implementation will show a less "precise" SoC name and no manufacturing process because there would be no hardcoded value for that SoC. However, it improves the scalability of the SoC detection significantly because there is no longer a need to hardcode every single SoC. Lastly, there are some SoC vendors intentionally left outside the scope of this function: For now I prefer to keep updating manually the LUT for those to ensure the highest quality detection (e.g., showing precise SoC name and manufacturing process).
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "../arm/uarch.h"
|
||||
#include "../arm/midr.h"
|
||||
#include "../arm/soc.h"
|
||||
#include "../arm/socs.h"
|
||||
#include "../common/soc.h"
|
||||
#elif ARCH_RISCV
|
||||
#include "../riscv/riscv.h"
|
||||
@@ -892,6 +893,11 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct color** cs, struct
|
||||
// https://github.com/Dr-Noob/cpufetch/pull/273
|
||||
// Hide manufacturing process
|
||||
#if !defined(_WIN32)
|
||||
// In the case that the model is unknown but the vendor isn't (this is, when
|
||||
// guess_raw_soc_from_devtree succeeded), do not show the manufacturing process
|
||||
// (as it will be unknown)
|
||||
if (cpu->soc->model != SOC_MODEL_UNKNOWN ||
|
||||
(cpu->soc->model == SOC_MODEL_UNKNOWN && cpu->soc->vendor == SOC_VENDOR_UNKNOWN))
|
||||
setAttribute(art, ATTRIBUTE_TECHNOLOGY, manufacturing_process);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -79,6 +79,16 @@ void fill_soc(struct system_on_chip* soc, char* soc_name, SOC soc_model, int32_t
|
||||
}
|
||||
}
|
||||
|
||||
void fill_soc_raw(struct system_on_chip* soc, char* soc_name, VENDOR vendor) {
|
||||
soc->model = SOC_MODEL_UNKNOWN;
|
||||
soc->vendor = vendor;
|
||||
soc->process = UNKNOWN;
|
||||
|
||||
int len = strlen(soc_name) + strlen(soc_trademark_string[soc->vendor]) + 1;
|
||||
soc->raw_name = emalloc(sizeof(char) * len);
|
||||
sprintf(soc->raw_name, "%s%s", soc_trademark_string[soc->vendor], soc_name);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
VENDOR try_match_soc_vendor_name(char* vendor_name)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ VENDOR get_soc_vendor(struct system_on_chip* soc);
|
||||
bool match_soc(struct system_on_chip* soc, char* raw_name, char* expected_name, char* soc_name, SOC soc_model, int32_t process);
|
||||
char* get_str_process(struct system_on_chip* soc);
|
||||
void fill_soc(struct system_on_chip* soc, char* soc_name, SOC soc_model, int32_t process);
|
||||
void fill_soc_raw(struct system_on_chip* soc, char* soc_name, VENDOR vendor);
|
||||
#ifdef _WIN32
|
||||
VENDOR try_match_soc_vendor_name(char* vendor_name);
|
||||
#endif
|
||||
|
||||
@@ -361,3 +361,69 @@ char* get_devtree_compatible(int *filelen) {
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Returns a list of structs devtree, each containing both the vendor and the
|
||||
// model, coming from the compatible file from the device tree. In this
|
||||
// context, vendor refers to the first string of every entry and the model to
|
||||
// the second. For instance, given a compatible file with:
|
||||
// "str1,foo1.str2,foo2" (where . denotes the NULL byte, i.e., the separator),
|
||||
// then this function will return a list with two structs, the first one
|
||||
// containing str1 and foo1 and the other containing str2 and foo2.
|
||||
struct devtree** get_devtree_compatible_struct(int *num_vendors_ptr) {
|
||||
int len;
|
||||
char* dt = get_devtree_compatible(&len);
|
||||
if (dt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int num_vendors = 0;
|
||||
char* ptr = dt;
|
||||
|
||||
for (int ptrpos = 0; ptrpos < len; ptrpos = (ptr-dt)) {
|
||||
ptr = memchr(ptr, '\0', len);
|
||||
if (ptr == NULL) {
|
||||
printBug("get_devtree_compatible_struct: Unable to find delimiter (1) (num_vendors=%d)", num_vendors);
|
||||
return NULL;
|
||||
}
|
||||
ptr++;
|
||||
num_vendors++;
|
||||
}
|
||||
|
||||
struct devtree** vendors = emalloc(sizeof(struct devtree *) * num_vendors);
|
||||
ptr = dt;
|
||||
|
||||
for (int ptrpos = 0, i = 0; ptrpos < len; ptrpos = (ptr-dt), i++) {
|
||||
char* comma_ptr = strstr(ptr, ",");
|
||||
if (comma_ptr == NULL) {
|
||||
printBug("get_devtree_compatible_struct: Unable to find comma (num_vendors=%d)", num_vendors);
|
||||
return NULL;
|
||||
}
|
||||
comma_ptr = comma_ptr-1; // Point right before comma
|
||||
|
||||
char* end_ptr = memchr(comma_ptr, '\0', len - ptrpos);
|
||||
if (end_ptr == NULL) {
|
||||
printBug("get_devtree_compatible_struct: Unable to find delimiter (2) (num_vendors=%d)", num_vendors);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int vendor_str_len = (comma_ptr-ptr)+1;
|
||||
int model_str_len = (end_ptr-(comma_ptr+2))+1;
|
||||
|
||||
vendors[i] = emalloc(sizeof(struct devtree));
|
||||
vendors[i]->vendor = ecalloc(vendor_str_len, sizeof(char));
|
||||
vendors[i]->model = ecalloc(model_str_len, sizeof(char));
|
||||
|
||||
strncpy(vendors[i]->vendor, ptr, vendor_str_len);
|
||||
strncpy(vendors[i]->model, comma_ptr+2, model_str_len);
|
||||
|
||||
ptr = memchr(ptr, '\0', len);
|
||||
if (ptr == NULL) {
|
||||
printBug("get_devtree_compatible_struct: Unable to find delimiter (3) (num_vendors=%d)", num_vendors);
|
||||
return NULL;
|
||||
}
|
||||
ptr++; // Point right after delimiter
|
||||
}
|
||||
|
||||
*num_vendors_ptr = num_vendors;
|
||||
return vendors;
|
||||
}
|
||||
@@ -31,6 +31,11 @@
|
||||
#define _PATH_CACHE_MAX_LEN 200
|
||||
#define _PATH_PACKAGE_MAX_LEN 200
|
||||
|
||||
struct devtree {
|
||||
char* vendor;
|
||||
char* model;
|
||||
};
|
||||
|
||||
char* read_file(char* path, int* len);
|
||||
long get_max_freq_from_file(uint32_t core);
|
||||
long get_min_freq_from_file(uint32_t core);
|
||||
@@ -44,5 +49,6 @@ int get_ncores_from_cpuinfo(void);
|
||||
char* get_field_from_cpuinfo(char* CPUINFO_FIELD);
|
||||
bool is_devtree_compatible(char* str);
|
||||
char* get_devtree_compatible(int *filelen);
|
||||
struct devtree** get_devtree_compatible_struct(int *num_vendors);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user