diff --git a/src/detection/cpu/cpu.h b/src/detection/cpu/cpu.h index e27a437af..dd2d178ed 100644 --- a/src/detection/cpu/cpu.h +++ b/src/detection/cpu/cpu.h @@ -30,3 +30,30 @@ typedef struct FFCPUResult const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu); const char* ffCPUAppleCodeToName(uint32_t code); + + +#if defined(__x86_64__) || defined(__i386__) + +#include + +// WARNING: CPUID may report frequencies of efficient cores +inline static const char* ffCPUDetectSpeedByCpuid(FFCPUResult* cpu) +{ + uint32_t base = 0, max = 0, bus = 0, unused = 0; + if (!__get_cpuid(0x16, &base, &max, &bus, &unused)) + return "Unsupported instruction"; + + // cpuid returns 0 MHz when hyper-v is enabled + if (base) cpu->frequencyBase = base; + if (max) cpu->frequencyMax = max; + return NULL; +} + +#else + +inline static const char* ffCPUDetectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu) +{ + return "Unsupported platform"; +} + +#endif diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 92773dcdc..0b17d595d 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -39,6 +39,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) } } + ffCPUDetectSpeedByCpuid(cpu); + for (uint16_t i = 0; i < cpu->coresLogical; ++i) { ffStrbufClear(&buffer); diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 2c2334d9f..39efe3fbe 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -340,6 +340,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) cpu->coresOnline = (uint16_t) get_nprocs(); cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical); + // Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252 + ffCPUDetectSpeedByCpuid(cpu); if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0) cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0); diff --git a/src/detection/cpu/cpu_sunos.c b/src/detection/cpu/cpu_sunos.c index 67954ee30..e10dcb898 100644 --- a/src/detection/cpu/cpu_sunos.c +++ b/src/detection/cpu/cpu_sunos.c @@ -29,10 +29,10 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id"); ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn)); } - { - kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz"); + ffCPUDetectSpeedByCpuid(cpu); + kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz"); + if (kn->value.ui32 > cpu->frequencyBase) cpu->frequencyBase = kn->value.ui32; - } ks = kstat_lookup(kc, "unix", -1, "system_misc"); if (ks && kstat_read(kc, ks, NULL) >= 0) diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index fa96bb6ff..411ffe6f7 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -54,31 +54,6 @@ typedef struct FFSmbiosProcessorInfo static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30, "FFSmbiosProcessorInfo: Wrong struct alignment"); -#if defined(__x86_64__) || defined(__i386__) - -#include - -inline static const char* detectSpeedByCpuid(FFCPUResult* cpu) -{ - uint32_t base = 0, max = 0, bus = 0, unused = 0; - if (!__get_cpuid(0x16, &base, &max, &bus, &unused)) - return "Unsupported instruction"; - - // cpuid returns 0 MHz when hyper-v is enabled - if (base) cpu->frequencyBase = base; - if (max) cpu->frequencyMax = max; - return NULL; -} - -#else - -inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu) -{ - return "Unsupported platform"; -} - -#endif - static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu) { const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable(); @@ -193,7 +168,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) if (error) return error; - detectSpeedByCpuid(cpu); + ffCPUDetectSpeedByCpuid(cpu); if (options->showPeCoreCount) detectCoreTypes(cpu); if (cpu->frequencyMax == 0)