diff --git a/CHANGELOG.md b/CHANGELOG.md index c8cde2812..a18be3800 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Features: * Improved fish completion scripts to print enum descriptions. (Completion) * Enabled Wayland support on Android. (DisplayServer, Android) * Added DE detection support for ASUS Zenfone. (DE, Android) +* Added new ARM SoCs (CPU, Linux / Android) Bugfixes: * Fixed I/O rate calculation precision in DiskIO and NetIO, and prevented division by zero. (DiskIO / NetIO) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 904533e4d..589d0ac01 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -837,6 +837,46 @@ static const char* detectPhysicalCores(FFCPUResult* cpu) { return nullptr; } +[[maybe_unused]] static bool detectSnapdragonX(FFstrbuf* name, const char* model) { + // 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 + prefix = model[3] == '9' ? "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 { + return false; + } + + 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])); + } + return true; +} + [[maybe_unused]] static void parseIsa(FFstrbuf* cpuIsa) { // Always use the last part of the ISA string. Ref: #590 #1204 ffStrbufSubstrAfterLastC(cpuIsa, ' '); @@ -938,22 +978,19 @@ static const char* detectPhysicalCores(FFCPUResult* cpu) { } #endif else if (ffStrEquals(vendor, "qcom")) { - // https://elixir.bootlin.com/linux/v6.11/source/arch/arm64/boot/dts/qcom - if (ffStrStartsWith(model, "x")) { - ffStrbufSetS(&cpu->name, "Qualcomm Snapdragon X Elite "); - for (const char* p = model + 1; *p; ++p) { - ffStrbufAppendC(&cpu->name, (char) toupper(*p)); + // https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/qcom + if (!detectSnapdragonX(&cpu->name, model)) { + if (ffStrStartsWith(model, "sc")) { + const char* code = model + 2; + uint32_t deviceId = (uint32_t) strtoul(code, nullptr, 10); + ffStrbufSetStatic(&cpu->name, ffCPUQualcommCodeToName(deviceId)); + if (!cpu->name.length) { + ffStrbufAppendS(&cpu->name, "Qualcomm Snapdragon SC"); + ffStrbufAppendS(&cpu->name, code); + } + } else { + ffStrbufSetS(&cpu->name, model); } - } else if (ffStrStartsWith(model, "sc")) { - const char* code = model + 2; - uint32_t deviceId = (uint32_t) strtoul(code, nullptr, 10); - ffStrbufSetStatic(&cpu->name, ffCPUQualcommCodeToName(deviceId)); - if (!cpu->name.length) { - ffStrbufAppendS(&cpu->name, "Qualcomm Snapdragon SC"); - ffStrbufAppendS(&cpu->name, code); - } - } else { - ffStrbufSetS(&cpu->name, model); } ffStrbufSetStatic(&cpu->vendor, "Qualcomm");