mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-25 16:00:39 +01:00
Compare commits
2 Commits
printer-bu
...
i280
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51dd89b005 | ||
|
|
ef1bfa5cc9 |
@@ -1044,6 +1044,62 @@ struct system_on_chip* guess_soc_from_devtree(struct system_on_chip* soc) {
|
||||
DT_END(dt, len)
|
||||
}
|
||||
|
||||
// This function is different from the rest guess_soc_from_xxx, which try infering
|
||||
// the exact SoC model by matching some string against a list of known values.
|
||||
// On the other hand, this function will just try to infer the SoC vendor first by
|
||||
// matching the device tree vendor name (i.e., the first value, before the comma).
|
||||
// If that is successfull, then it also fills in the SoC name using the string from
|
||||
// the device tree.
|
||||
// The critical difference is that this function does not need a LUT to fill in the
|
||||
// SoC, it just needs to find a known vendor. On the other hand, the detection is
|
||||
// less powerful since we cannot get the manufacturing process, and the SoC name will
|
||||
// come directly from the device tree, meaning that it will likely be less precise.
|
||||
struct system_on_chip* guess_raw_soc_from_devtree(struct system_on_chip* soc) {
|
||||
int num_vendors;
|
||||
struct devtree** dt_vendors = get_devtree_compatible_struct(&num_vendors);
|
||||
if (dt_vendors == NULL) {
|
||||
return soc;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char* compatible;
|
||||
VENDOR soc_vendor;
|
||||
} devtreeToVendor;
|
||||
|
||||
// https://elixir.bootlin.com/linux/v6.10.6/source/arch/arm64/boot/dts
|
||||
// grep -oR --color -E 'compatible = ".*"' <soc_vendor> | cut -d '=' -f2 | cut -d ',' -f1 | tr -d '"' | sort | uniq -c | sort
|
||||
// - The following vendors are not included because they dont seem to be present in dts:
|
||||
// SOC_VENDOR_(KIRIN, KUNPENG, GOOGLE, AMPERE).
|
||||
// - The commented vendors are not included intentionally, because I prefer updating its LUT manually.
|
||||
devtreeToVendor socFromDevtree[] = {
|
||||
// {"qcom", SOC_VENDOR_SNAPDRAGON},
|
||||
// {"samsung", SOC_VENDOR_EXYNOS},
|
||||
// {"brcm", SOC_VENDOR_BROADCOM},
|
||||
// {"apple", SOC_VENDOR_APPLE},
|
||||
// {"rockchip", SOC_VENDOR_ROCKCHIP},
|
||||
// {"nvidia", SOC_VENDOR_NVIDIA},
|
||||
{"mediatek", SOC_VENDOR_MEDIATEK},
|
||||
{"fsl", SOC_VENDOR_NXP },
|
||||
{"nxp", SOC_VENDOR_NXP },
|
||||
{"amlogic", SOC_VENDOR_AMLOGIC },
|
||||
{"marvell", SOC_VENDOR_MARVELL },
|
||||
{NULL, SOC_VENDOR_UNKNOWN }
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
while (socFromDevtree[index].compatible != 0x0) {
|
||||
for (int i=0; i < num_vendors; i++) {
|
||||
if (strcmp(socFromDevtree[index].compatible, dt_vendors[i]->vendor) == 0) {
|
||||
fill_soc_raw(soc, dt_vendors[i]->model, socFromDevtree[index].soc_vendor);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
printWarn("guess_raw_soc_from_devtree: No device matched the list");
|
||||
return soc;
|
||||
}
|
||||
|
||||
struct system_on_chip* guess_soc_from_pci(struct system_on_chip* soc, struct cpuInfo* cpu) {
|
||||
struct pci_devices * pci = get_pci_devices();
|
||||
if (pci == NULL) {
|
||||
@@ -1270,6 +1326,11 @@ struct system_on_chip* get_soc(struct cpuInfo* cpu) {
|
||||
if(soc->vendor == SOC_VENDOR_UNKNOWN) {
|
||||
soc = guess_soc_from_pci(soc, cpu);
|
||||
}
|
||||
if (soc->vendor == SOC_VENDOR_UNKNOWN) {
|
||||
// If we fall here it means all previous functions failed to detect the SoC.
|
||||
// In such case, try with our last resort. If it also fails, we will just give up
|
||||
soc = guess_raw_soc_from_devtree(soc);
|
||||
}
|
||||
}
|
||||
#elif defined __APPLE__ || __MACH__
|
||||
soc = guess_soc_apple(soc);
|
||||
@@ -1295,16 +1356,13 @@ struct system_on_chip* get_soc(struct cpuInfo* cpu) {
|
||||
soc->vendor = try_match_soc_vendor_name(processor_name_string);
|
||||
soc->model = SOC_MODEL_UNKNOWN;
|
||||
soc->process = UNKNOWN;
|
||||
|
||||
#else
|
||||
|
||||
if(soc->model == SOC_MODEL_UNKNOWN) {
|
||||
// raw_name might not be NULL, but if we were unable to find
|
||||
// the exact SoC, just print "Unkwnown"
|
||||
soc->raw_name = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
|
||||
snprintf(soc->raw_name, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return soc;
|
||||
|
||||
@@ -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->name = emalloc(sizeof(char) * len);
|
||||
sprintf(soc->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,49 @@ char* get_devtree_compatible(int *filelen) {
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// Returns a list of strings containing the vendors of the compatible
|
||||
// file from the device tree. In this context, vendor refers to the first
|
||||
// string of every entry. 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 str1,str2.
|
||||
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)+1;
|
||||
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, ",")-1;
|
||||
char* end_ptr = memchr(comma_ptr, '\0', ptrpos - len);
|
||||
|
||||
// TODO check NULL
|
||||
int vendor_str_len = (comma_ptr-ptr)+1;
|
||||
int model_str_len = (end_ptr-comma_ptr)+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, model_str_len);
|
||||
|
||||
ptr = memchr(ptr, '\0', len)+1;
|
||||
}
|
||||
|
||||
*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