From 2eafdcc50ecd9de734a1b4e7c2d5794a670c3b44 Mon Sep 17 00:00:00 2001 From: Jami Kettunen Date: Mon, 28 Sep 2026 14:12:06 +0300 Subject: [PATCH] CPU (Linux): make Snapdragon X1/X2 detection more correct Use the previously discussed soc_id which have public values in EDK2. The so far used toplevel devicetree compatible values weren't as precise and some logic (x1, x2p, x2e) simply was dead code. Also drops the CPU test due to reading soc_id sysfs file, could be adapted if still wanted around. --- CMakeLists.txt | 12 ---- src/detection/cpu/cpu_linux.c | 115 ++++++++++++++++++---------------- tests/cpu.c | 47 -------------- 3 files changed, 60 insertions(+), 114 deletions(-) delete mode 100644 tests/cpu.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2acd937c29..27749ccd79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2275,15 +2275,6 @@ if (BUILD_TESTS) PRIVATE libfastfetch ) - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - add_executable(fastfetch-test-cpu - tests/cpu.c - ) - target_link_libraries(fastfetch-test-cpu - PRIVATE libfastfetch - ) - endif() - add_executable(fastfetch-test-strbuf tests/strbuf.c ) @@ -2397,9 +2388,6 @@ if (BUILD_TESTS) ) enable_testing() - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - add_test(NAME test-cpu COMMAND fastfetch-test-cpu) - endif() add_test(NAME test-cache COMMAND fastfetch-test-cache) add_test(NAME test-logo COMMAND fastfetch-test-logo) add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 4786874dd3..c9756a3bf4 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -706,66 +706,71 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options) { return true; } -// Also used in tests/cpu.c -bool ffCPUQualcommSnapdragonToName(FFstrbuf* name, const char* model) { - // X2 device trees use platform codenames rather than exact retail part - // numbers. qcom,glymur is used by X2 Elite Extreme boards, qcom,mahua by - // X2 Elite boards, and qcom,kalambo by X2 Plus boards. Do not append a - // part number from /sys/bus/soc/devices/soc0/soc_id: it contains - // SMEM_HW_SW_BUILD_ID.id (the platform ID), 662 is unnamed in the public - // qcom,ids.h, and one compatible can cover multiple retail SKUs. - // https://github.com/fastfetch-cli/fastfetch/issues/2611 - if (ffStrEquals(model, "glymur")) { - ffStrbufSetS(name, "Qualcomm Snapdragon X2 Elite Extreme"); - return true; - } - if (ffStrEquals(model, "mahua")) { - ffStrbufSetS(name, "Qualcomm Snapdragon X2 Elite"); - return true; - } - if (ffStrEquals(model, "kalambo")) { - ffStrbufSetS(name, "Qualcomm Snapdragon X2 Plus"); - return true; +bool ffCPUQualcommSnapdragonToName(FFstrbuf* name, char* compatibles) { + // While this also would be 555 below split it out as it's only seen on the devkit + for (char* p = compatibles; *p; p += strlen(p) + 1) { + if (strstr(p, "x1e001de") != nullptr) { + ffStrbufSetS(name, "Qualcomm Snapdragon X Elite X1E-00-1DE"); + return true; + } } - // SoC models are enumerated in the form of `x[e|p]`, e.g. `x1e80100`, - // which is marketed as `X1E-80-100`, where `e` stands for Elite and `p` for Plus. - // https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips#Snapdragon_X_series - const char* prefix; - uint32_t prefixLen; - - if (ffStrStartsWith(model, "x1e")) { - prefix = "Qualcomm Snapdragon X Elite"; - prefixLen = 3; - } else if (ffStrStartsWith(model, "x1p")) { - prefix = "Qualcomm Snapdragon X Plus"; - prefixLen = 3; - } else if (ffStrStartsWith(model, "x2e")) { - // Only X2E-94-100 and X2E-96-100 are branded as Extreme - bool extreme = ffStrStartsWith(model, "x2e94") || ffStrStartsWith(model, "x2e96"); - prefix = extreme ? "Qualcomm Snapdragon X2 Elite Extreme" : "Qualcomm Snapdragon X2 Elite"; - prefixLen = 3; - } else if (ffStrStartsWith(model, "x2p")) { - prefix = "Qualcomm Snapdragon X2 Plus"; - prefixLen = 3; - } else if (ffStrStartsWith(model, "x1")) { - prefix = "Qualcomm Snapdragon X"; - prefixLen = 2; - } else { + // https://github.com/tianocore/edk2-platforms/blob/9c2cdde/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Include/ChipInfoDefs.h + char content[16]; + ssize_t length = ffReadFileData("/sys/devices/soc0/soc_id", ARRAY_SIZE(content), content); + if (length < 1) { return false; } + if (content[length - 1] != '\n') { + return false; // must end with \n + } - uint32_t length = (uint32_t) strlen(model); - bool splitCode = length - prefixLen == 5; - - ffStrbufSetF(name, "%s X", prefix); - for (uint32_t i = 1; i < length; ++i) { - if (i == prefixLen || (splitCode && i == length - 3)) { - ffStrbufAppendC(name, '-'); - } - ffStrbufAppendC(name, (char) toupper(model[i])); + unsigned long long soc_id = strtoull(content, nullptr, 10); + const char* soc = nullptr; + switch (soc_id) { + // glymur + case 662: + soc = "X2 Elite Extreme X2E-94/96-100"; + break; + case 698: + soc = "X2 Elite X2E-88/90-100"; + break; + // mahua + case 699: + soc = "X2 Elite X2E-80/84-100"; + break; + case 693: + soc = "X2 Elite X2E-78-100"; + break; + case 728: + soc = "X2 Plus X2P-64-100"; + break; + // kalambo + case 719: + soc = "X2 Plus X2P-42-100"; + break; + // hamoa + case 555: + soc = "X Elite X1E-78/80/84-100"; + break; + case 615: + soc = "X Plus X1P-64/66-100"; + break; + case 616: + soc = "X X1-26-101"; + break; + // purwa + case 635: + soc = "X X1-26-100 / X Plus X1P-42/46-100"; + break; } - return true; + if (soc) { + ffStrbufSetS(name, "Qualcomm Snapdragon "); + ffStrbufAppendS(name, soc); + return true; + } + + return false; } #if __i386__ || __x86_64__ @@ -1004,7 +1009,7 @@ static const char* detectPhysicalCores(FFCPUResult* cpu) { #endif else if (ffStrEquals(vendor, "qcom")) { // https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/qcom - if (!ffCPUQualcommSnapdragonToName(&cpu->name, model)) { + if (!ffCPUQualcommSnapdragonToName(&cpu->name, content)) { if (ffStrStartsWith(model, "sc")) { const char* code = model + 2; uint32_t deviceId = (uint32_t) strtoul(code, nullptr, 10); diff --git a/tests/cpu.c b/tests/cpu.c deleted file mode 100644 index 180380ca24..0000000000 --- a/tests/cpu.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "common/FFstrbuf.h" -#include "common/textModifier.h" - -#include -#include - -bool ffCPUQualcommSnapdragonToName(FFstrbuf* name, const char* model); - - -static void verifyName(const char* model, bool expectedResult, const char* expected) { - FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateS("unchanged"); - const bool returned = ffCPUQualcommSnapdragonToName(&result, model); - - if (returned != expectedResult || !ffStrbufEqualS(&result, expected)) { - fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR - "ffCPUQualcommSnapdragonToName(\"%s\"): expected %s \"%s\", got %s \"%s\"\n" - FASTFETCH_TEXT_MODIFIER_RESET, - model, expectedResult ? "true" : "false", expected, - returned ? "true" : "false", result.chars); - exit(1); - } -} - -#define VERIFY_NAME(model, expectedResult, expected) \ - verifyName((model), (expectedResult), (expected)) - -int main(void) { - // Existing X1 and direct X2 model names - VERIFY_NAME("x1e80100", true, "Qualcomm Snapdragon X Elite X1E-80-100"); - VERIFY_NAME("x1p42100", true, "Qualcomm Snapdragon X Plus X1P-42-100"); - VERIFY_NAME("x2e88100", true, "Qualcomm Snapdragon X2 Elite X2E-88-100"); - VERIFY_NAME("x2e90100", true, "Qualcomm Snapdragon X2 Elite X2E-90-100"); - VERIFY_NAME("x2e94100", true, "Qualcomm Snapdragon X2 Elite Extreme X2E-94-100"); - VERIFY_NAME("x2e96100", true, "Qualcomm Snapdragon X2 Elite Extreme X2E-96-100"); - VERIFY_NAME("x2p42100", true, "Qualcomm Snapdragon X2 Plus X2P-42-100"); - - // X2 platform codenames identify the marketing family, not an exact SKU - VERIFY_NAME("glymur", true, "Qualcomm Snapdragon X2 Elite Extreme"); - VERIFY_NAME("mahua", true, "Qualcomm Snapdragon X2 Elite"); - VERIFY_NAME("kalambo", true, "Qualcomm Snapdragon X2 Plus"); - - // Other Qualcomm platform names are handled by the caller - VERIFY_NAME("sc8280", false, "unchanged"); - - puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET); - return 0; -}