Compare commits

...

7 Commits
i183 ... v1.05

8 changed files with 103 additions and 90 deletions

View File

@@ -174,6 +174,7 @@ Thanks to the fellow contributors and interested people in the project. Special
- [bbonev](https://github.com/bbonev) and [stephan-cr](https://github.com/stephan-cr): Reviewed the source code.
- [mdoksa76](https://github.com/mdoksa76) and [exkc](https://github.com/exkc): Excellent ideas and feedback for supporting Allwinner SoCs.
- [Sakura286](https://github.com/Sakura286), [exkc](https://github.com/exkc) and [Patola](https://github.com/Patola): Helped with RISC-V port with ssh access, ideas, testing, etc.
- [ThomasKaiser](https://github.com/ThomasKaiser): Very valuable feedback on improving ARM SoC detection (Apple, Allwinner, Rockchip).
## 8. cpufetch for GPUs (gpufetch)
See [gpufetch](https://github.com/Dr-Noob/gpufetch) project!

View File

@@ -350,97 +350,47 @@ void fill_cpu_info_everest_sawtooth(struct cpuInfo* cpu, uint32_t pcores, uint32
}
struct cpuInfo* get_cpu_info_mach(struct cpuInfo* cpu) {
uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_system_capabilities
uint32_t nperflevels = get_sys_info_by_name("hw.nperflevels");
if((cpu->num_cpus = nperflevels) != 2) {
printBug("Expected to find SoC with 2 perf levels, found: %d", cpu->num_cpus);
return NULL;
}
uint32_t pcores = get_sys_info_by_name("hw.perflevel0.physicalcpu");
uint32_t ecores = get_sys_info_by_name("hw.perflevel1.physicalcpu");
if(ecores <= 0) {
printBug("Expected to find a numer of ecores > 0, found: %d", ecores);
return NULL;
}
if(pcores <= 0) {
printBug("Expected to find a numer of pcores > 0, found: %d", pcores);
return NULL;
}
uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
// Manually fill the cpuInfo assuming that
// the CPU is an Apple M1/M2
// the CPU is an Apple SoC
if(cpu_family == CPUFAMILY_ARM_FIRESTORM_ICESTORM) {
cpu->num_cpus = 2;
// Now detect the M1 version
uint32_t cpu_subfamily = get_sys_info_by_name("hw.cpusubfamily");
if(cpu_subfamily == CPUSUBFAMILY_ARM_HG) {
// Apple M1
fill_cpu_info_firestorm_icestorm(cpu, 4, 4);
}
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HS || cpu_subfamily == CPUSUBFAMILY_ARM_HC_HD) {
// Apple M1 Pro/Max/Ultra. Detect number of cores
uint32_t physicalcpu = get_sys_info_by_name("hw.physicalcpu");
if(physicalcpu == 20) {
// M1 Ultra
fill_cpu_info_firestorm_icestorm(cpu, 16, 4);
}
else if(physicalcpu == 8 || physicalcpu == 10) {
// M1 Pro/Max
fill_cpu_info_firestorm_icestorm(cpu, physicalcpu-2, 2);
}
else {
printBug("Found invalid physical cpu number: %d", physicalcpu);
return NULL;
}
}
else {
printBug("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
return NULL;
}
fill_cpu_info_firestorm_icestorm(cpu, pcores, ecores);
cpu->soc = get_soc();
cpu->peak_performance = get_peak_performance(cpu);
}
else if(cpu_family == CPUFAMILY_ARM_AVALANCHE_BLIZZARD) {
cpu->num_cpus = 2;
// Now detect the M2 version
uint32_t cpu_subfamily = get_sys_info_by_name("hw.cpusubfamily");
if(cpu_subfamily == CPUSUBFAMILY_ARM_HG) {
// Apple M2
fill_cpu_info_avalanche_blizzard(cpu, 4, 4);
}
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HS) {
// Apple M2 Pro/Max/Ultra. Detect number of cores
uint32_t physicalcpu = get_sys_info_by_name("hw.physicalcpu");
if(physicalcpu == 24) {
// M2 Ultra
fill_cpu_info_avalanche_blizzard(cpu, 16, 8);
}
else if(physicalcpu == 10 || physicalcpu == 12) {
// M2 Pro/Max
fill_cpu_info_avalanche_blizzard(cpu, physicalcpu-4, 4);
}
else {
printBug("Found invalid physical cpu number: %d", physicalcpu);
return NULL;
}
}
else {
printBug("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
return NULL;
}
fill_cpu_info_avalanche_blizzard(cpu, pcores, ecores);
cpu->soc = get_soc();
cpu->peak_performance = get_peak_performance(cpu);
}
else if(cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH ||
cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH_PRO ||
cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH_MAX) {
cpu->num_cpus = 2;
// Now detect the M3 version
if(cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH) {
fill_cpu_info_everest_sawtooth(cpu, 4, 4);
}
else if(cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH_PRO) {
uint32_t physicalcpu = get_sys_info_by_name("hw.physicalcpu");
fill_cpu_info_everest_sawtooth(cpu, physicalcpu-6, 6);
}
else if(cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH_MAX) {
uint32_t physicalcpu = get_sys_info_by_name("hw.physicalcpu");
fill_cpu_info_everest_sawtooth(cpu, physicalcpu-4, 4);
}
else {
printBug("Found invalid cpu_family: 0x%.8X", cpu_family);
return NULL;
}
fill_cpu_info_everest_sawtooth(cpu, pcores, ecores);
cpu->soc = get_soc();
cpu->peak_performance = get_peak_performance(cpu);
}
else {
printBug("Found invalid cpu_family: 0x%.8X", cpu_family);
printBugCheckRelease("Found invalid cpu_family: 0x%.8X", cpu_family);
return NULL;
}
@@ -529,7 +479,10 @@ void print_debug(struct cpuInfo* cpu) {
#if defined(__APPLE__) || defined(__MACH__)
printf("hw.cpufamily: 0x%.8X\n", get_sys_info_by_name("hw.cpufamily"));
printf("hw.cpusubfamily: 0x%.8X\n", get_sys_info_by_name("hw.cpusubfamily"));
printf("hw.nperflevels: %d\n", get_sys_info_by_name("hw.nperflevels"));
printf("hw.physicalcpu: %d\n", get_sys_info_by_name("hw.physicalcpu"));
printf("hw.perflevel0.physicalcpu: %d\n", get_sys_info_by_name("hw.perflevel0.physicalcpu"));
printf("hw.perflevel1.physicalcpu: %d\n", get_sys_info_by_name("hw.perflevel1.physicalcpu"));
#endif
}

View File

@@ -50,6 +50,8 @@ uint32_t get_sid_from_nvmem(char* buf) {
// SIDs list:
// - https://linux-sunxi.org/SID_Register_Guide#Currently_known_SID.27s
// - https://github.com/Dr-Noob/cpufetch/issues/173
// - https://github.com/ThomasKaiser/sbc-bench/blob/master/sbc-bench.sh
// - https://linux-sunxi.org/*CHIP_NAME*
bool get_sunxisoc_from_sid(struct system_on_chip* soc, char* raw_name, uint32_t sid) {
typedef struct {
uint32_t sid;
@@ -58,21 +60,39 @@ bool get_sunxisoc_from_sid(struct system_on_chip* soc, char* raw_name, uint32_t
sidToSoC socFromSid[] = {
// --- sun8i Family ---
// A33
{0x0461872a, {SOC_ALLWINNER_A33, SOC_VENDOR_ALLWINNER, 40, "A33", raw_name} },
// A83T
{0x32c00401, {SOC_ALLWINNER_A83T, SOC_VENDOR_ALLWINNER, 28, "A83T", raw_name} },
{0x32c00403, {SOC_ALLWINNER_A83T, SOC_VENDOR_ALLWINNER, 28, "A83T", raw_name} },
// S3
{0x12c00001, {SOC_ALLWINNER_S3, SOC_VENDOR_ALLWINNER, 40, "S3", raw_name} },
// H2+
{0x02c00042, {SOC_ALLWINNER_H2PLUS, SOC_VENDOR_ALLWINNER, 40, "H2+", raw_name} },
{0x02c00142, {SOC_ALLWINNER_H2PLUS, SOC_VENDOR_ALLWINNER, 40, "H2+", raw_name} },
{0x02c00242, {SOC_ALLWINNER_H2PLUS, SOC_VENDOR_ALLWINNER, 40, "H2+", raw_name} },
// H3
{0x02c00181, {SOC_ALLWINNER_H3, SOC_VENDOR_ALLWINNER, 40, "H3", raw_name} },
{0x02c00081, {SOC_ALLWINNER_H3, SOC_VENDOR_ALLWINNER, 40, "H3", raw_name} },
// Others
// R40
{0x12c00017, {SOC_ALLWINNER_R40, SOC_VENDOR_ALLWINNER, 40, "R40", raw_name} },
// V3S
{0x12c00000, {SOC_ALLWINNER_V3S, SOC_VENDOR_ALLWINNER, 40, "V3s", raw_name} }, // 40nm is only my guess, no source
// --- sun50i Family ---
// H5
{0x82800001, {SOC_ALLWINNER_H5, SOC_VENDOR_ALLWINNER, 40, "H5", raw_name} },
// H6
{0x82c00001, {SOC_ALLWINNER_H6, SOC_VENDOR_ALLWINNER, 28, "H6", raw_name} },
{0x82c00007, {SOC_ALLWINNER_H6, SOC_VENDOR_ALLWINNER, 28, "H6", raw_name} },
{0x92c000bb, {SOC_ALLWINNER_H64, SOC_VENDOR_ALLWINNER, 40, "H64", raw_name} }, // Same as A64
// H64
{0x92c000bb, {SOC_ALLWINNER_H64, SOC_VENDOR_ALLWINNER, 40, "H64", raw_name} }, // Same manufacturing process as A64
// H616
{0x32c05000, {SOC_ALLWINNER_H616, SOC_VENDOR_ALLWINNER, 28, "H616", raw_name} },
// H618
{0x33802000, {SOC_ALLWINNER_H618, SOC_VENDOR_ALLWINNER, 28, "H618", raw_name} },
// A64
{0x92c000ba, {SOC_ALLWINNER_A64, SOC_VENDOR_ALLWINNER, 40, "A64", raw_name} },
{0x92c001ba, {SOC_ALLWINNER_A64, SOC_VENDOR_ALLWINNER, 40, "A64", raw_name} },
// Unknown
{0x00000000, {UNKNOWN, SOC_VENDOR_UNKNOWN, -1, "", raw_name} }
};
@@ -858,7 +878,7 @@ struct system_on_chip* guess_soc_apple(struct system_on_chip* soc) {
}
}
else {
printBug("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
printBugCheckRelease("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
}
}
@@ -885,7 +905,7 @@ struct system_on_chip* guess_soc_apple(struct system_on_chip* soc) {
}
}
else {
printBug("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
printBugCheckRelease("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
}
}
@@ -903,12 +923,12 @@ struct system_on_chip* guess_soc_apple(struct system_on_chip* soc) {
fill_soc(soc, "M3 Max", SOC_APPLE_M3_MAX, 3);
}
else {
printBug("Found invalid cpu_family: 0x%.8X", cpu_family);
printBugCheckRelease("Found invalid cpu_family: 0x%.8X", cpu_family);
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
}
}
else {
printBug("Found invalid cpu_family: 0x%.8X", cpu_family);
printBugCheckRelease("Found invalid cpu_family: 0x%.8X", cpu_family);
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
}
return soc;

View File

@@ -329,12 +329,14 @@ enum {
SOC_ALLWINNER_V3S,
SOC_ALLWINNER_HZP,
SOC_ALLWINNER_H2PLUS,
SOC_ALLWINNER_S3,
SOC_ALLWINNER_H3,
SOC_ALLWINNER_H8,
SOC_ALLWINNER_H5,
SOC_ALLWINNER_H6,
SOC_ALLWINNER_H64,
SOC_ALLWINNER_H616,
SOC_ALLWINNER_H618,
SOC_ALLWINNER_R8,
SOC_ALLWINNER_R16,
SOC_ALLWINNER_R40,

View File

@@ -200,8 +200,7 @@ static char* isas_string[] = {
#define UARCH_START if (false) {}
#define CHECK_UARCH(arch, cpu, im_, p_, v_, r_, str, uarch, vendor) \
else if (im_ == im && p_ == p && (v_ == NA || v_ == v) && (r_ == NA || r_ == r)) fill_uarch(arch, cpu, str, uarch, vendor);
#define UARCH_END else { printErr("Unknown microarchitecture detected: IM=0x%X P=0x%X V=0x%X R=0x%X", im, p, v, r); \
fprintf(stderr, "Please see https://github.com/Dr-Noob/cpufetch#61-unknown-microarchitecture-error to know how to report this error\n"); \
#define UARCH_END else { printBugCheckRelease("Unknown microarchitecture detected: IM=0x%X P=0x%X V=0x%X R=0x%X", im, p, v, r); \
fill_uarch(arch, cpu, "Unknown", UARCH_UNKNOWN, CPU_VENDOR_UNKNOWN); }
void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u, VENDOR vendor) {

View File

@@ -51,7 +51,7 @@
#endif
#ifndef GIT_FULL_VERSION
static const char* VERSION = "1.04";
static const char* VERSION = "1.05";
#endif
enum {
@@ -61,6 +61,14 @@ enum {
int LOG_LEVEL;
void printBugMessage(FILE *restrict stream) {
#if defined(ARCH_X86) || defined(ARCH_PPC)
fprintf(stream, "Please, create a new issue with this error message, the output of 'cpufetch' and 'cpufetch --debug' on https://github.com/Dr-Noob/cpufetch/issues\n");
#elif ARCH_ARM
fprintf(stream, "Please, create a new issue with this error message, your smartphone/computer model, the output of 'cpufetch --verbose' and 'cpufetch --debug' on https://github.com/Dr-Noob/cpufetch/issues\n");
#endif
}
void printWarn(const char *fmt, ...) {
if(LOG_LEVEL == LOG_LEVEL_VERBOSE) {
int buffer_size = 4096;
@@ -95,10 +103,40 @@ void printBug(const char *fmt, ...) {
fprintf(stderr,RED "[ERROR]: "RESET "%s\n",buffer);
fprintf(stderr,"[VERSION]: ");
print_version(stderr);
#if defined(ARCH_X86) || defined(ARCH_PPC)
fprintf(stderr, "Please, create a new issue with this error message, the output of 'cpufetch' and 'cpufetch --debug' on https://github.com/Dr-Noob/cpufetch/issues\n");
#elif ARCH_ARM
fprintf(stderr, "Please, create a new issue with this error message, your smartphone/computer model, the output of 'cpufetch --verbose' and 'cpufetch --debug' on https://github.com/Dr-Noob/cpufetch/issues\n");
printBugMessage(stderr);
}
bool isReleaseVersion(char *git_full_version) {
return strstr(git_full_version, "-") == NULL;
}
/// The unknown uarch errors are by far the most common error a user will encounter.
/// Rather than using the generic printBug function, which asks the user to report
/// the problem on the issues webpage, this function will check if the program is
/// the release version. In such case, support for this feature is most likely already
/// in the last version, so just tell the user to compile that one and not report this
/// in github.
void printBugCheckRelease(const char *fmt, ...) {
int buffer_size = 4096;
char buffer[buffer_size];
va_list args;
va_start(args, fmt);
vsnprintf(buffer,buffer_size, fmt, args);
va_end(args);
fprintf(stderr, RED "[ERROR]: "RESET "%s\n", buffer);
fprintf(stderr, "[VERSION]: ");
print_version(stderr);
#ifdef GIT_FULL_VERSION
if (isReleaseVersion(GIT_FULL_VERSION)) {
fprintf(stderr, RED "[ERROR]: "RESET "You are using an outdated version of cpufetch. Please compile cpufetch from source (see https://github.com/Dr-Noob/cpufetch?tab=readme-ov-file#22-building-from-source)");
}
else {
printBugMessage(stderr);
}
#else
printBugMessage(stderr);
#endif
}

View File

@@ -12,6 +12,7 @@ void set_log_level(bool verbose);
void printWarn(const char *fmt, ...);
void printErr(const char *fmt, ...);
void printBug(const char *fmt, ...);
void printBugCheckRelease(const char *fmt, ...);
int min(int a, int b);
int max(int a, int b);
char *strremove(char *str, const char *sub);

View File

@@ -125,8 +125,7 @@ struct uarch {
#define UARCH_START if (false) {}
#define CHECK_UARCH(arch, ef_, f_, em_, m_, s_, str, uarch, process) \
else if (ef_ == ef && f_ == f && (em_ == NA || em_ == em) && (m_ == NA || m_ == m) && (s_ == NA || s_ == s)) fill_uarch(arch, str, uarch, process);
#define UARCH_END else { printErr("Unknown microarchitecture detected: M=0x%X EM=0x%X F=0x%X EF=0x%X S=0x%X", m, em, f, ef, s); \
fprintf(stderr, "Please see https://github.com/Dr-Noob/cpufetch#61-unknown-microarchitecture-error to know how to report this error\n"); \
#define UARCH_END else { printBugCheckRelease("Unknown microarchitecture detected: M=0x%X EM=0x%X F=0x%X EF=0x%X S=0x%X", m, em, f, ef, s); \
fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, UNK); }
void fill_uarch(struct uarch* arch, char* str, MICROARCH u, uint32_t process) {