Skip to content

Commit 611d5f9

Browse files
committed
CPU (Linux): detect Qualcomm Snapdragon SOC
1 parent 536e2fb commit 611d5f9

File tree

3 files changed

+62
-19
lines changed

3 files changed

+62
-19
lines changed

src/detection/cpu/cpu.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ const char* ffCPUAppleCodeToName(uint32_t code)
3737
case 6031:
3838
case 6034: return "Apple M3 Max";
3939
case 8132: return "Apple M4";
40-
default: return "Apple Silicon";
40+
default: return NULL;
41+
}
42+
}
43+
44+
const char* ffCPUQualcommCodeToName(uint32_t code)
45+
{
46+
// https://github.com/AsahiLinux/docs/wiki/Codenames
47+
switch (code)
48+
{
49+
case 7180: return "Qualcomm Snapdragon 7c";
50+
case 7280: return "Qualcomm Snapdragon 7c+ Gen 3";
51+
case 8180: return "Qualcomm Snapdragon 8cx Gen 2 5G";
52+
case 8280: return "Qualcomm Snapdragon 8cx Gen 3";
53+
default: return NULL;
4154
}
4255
}

src/detection/cpu/cpu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ typedef struct FFCPUResult
3030

3131
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
3232
const char* ffCPUAppleCodeToName(uint32_t code);
33-
33+
const char* ffCPUQualcommCodeToName(uint32_t code);
3434

3535
#if defined(__x86_64__) || defined(__i386__)
3636

src/detection/cpu/cpu_linux.c

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -319,25 +319,55 @@ FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
319319
}
320320
}
321321

322-
FF_MAYBE_UNUSED static void detectAsahi(FFCPUResult* cpu)
322+
FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
323323
{
324-
// In Asahi Linux, reading /proc/device-tree/compatible gives
325-
// information on the device model. It consists of 3 NUL terminated
326-
// strings, the second of which gives the actual SoC model. But it
327-
// is not the marketing name, i.e. for M2 there is "apple,t8112" in
328-
// the compatible string.
329-
if (cpu->name.length == 0 && ffStrbufEqualS(&cpu->vendor, "Apple"))
330-
{
331-
char content[32];
332-
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
333-
if (length <= 0) return;
324+
if (cpu->name.length > 0)
325+
return;
326+
327+
char content[64];
328+
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
329+
if (length <= 2) return;
330+
331+
// get the second NUL terminated string
332+
char* modelName = memchr(content, '\0', (size_t) length) + 1;
333+
if (!modelName || modelName - content >= length) return;
334334

335-
// get the second NUL terminated string
336-
char* modelName = memchr(content, '\0', (size_t) length) + 1;
337-
if (modelName - content < length && ffStrStartsWith(modelName, "apple,t"))
335+
if (ffStrStartsWith(modelName, "apple,t"))
336+
{
337+
// https://elixir.bootlin.com/linux/v6.11-rc7/source/arch/arm64/boot/dts/apple
338+
// In Asahi Linux, reading /proc/device-tree/compatible gives
339+
// information on the device model. It consists of 3 NUL terminated
340+
// strings, the second of which gives the actual SoC model. But it
341+
// is not the marketing name, i.e. for M2 there is "apple,t8112" in
342+
// the compatible string.
343+
const char* code = modelName + strlen("qcom,sc");
344+
uint32_t deviceId = (uint32_t) strtoul(code, NULL, 10);
345+
ffStrbufSetStatic(&cpu->name, ffCPUAppleCodeToName(deviceId));
346+
if (!cpu->name.length)
347+
{
348+
ffStrbufAppendS(&cpu->name, "Apple Silicon T");
349+
ffStrbufAppendS(&cpu->name, code);
350+
}
351+
}
352+
else if (ffStrStartsWith(modelName, "qcom,"))
353+
{
354+
// https://elixir.bootlin.com/linux/v6.11-rc7/source/arch/arm64/boot/dts/qcom
355+
if (ffStrStartsWith(modelName + strlen("qcom,"), "x"))
356+
{
357+
ffStrbufSetS(&cpu->name, "Qualcomm Snapdragon X Elite ");
358+
for (const char* p = modelName + strlen("qcom,"); *p; ++p)
359+
ffStrbufAppendC(&cpu->name, (char) toupper(*p));
360+
}
361+
else if (ffStrStartsWith(modelName + strlen("qcom,"), "sc"))
338362
{
339-
uint32_t deviceId = (uint32_t) strtoul(modelName + strlen("apple,t"), NULL, 10);
340-
ffStrbufSetStatic(&cpu->name, ffCPUAppleCodeToName(deviceId));
363+
const char* code = modelName + strlen("qcom,sc");
364+
uint32_t deviceId = (uint32_t) strtoul(code, NULL, 10);
365+
ffStrbufSetStatic(&cpu->name, ffCPUQualcommCodeToName(deviceId));
366+
if (!cpu->name.length)
367+
{
368+
ffStrbufAppendS(&cpu->name, "Qualcomm Snapdragon SC");
369+
ffStrbufAppendS(&cpu->name, code);
370+
}
341371
}
342372
}
343373
}
@@ -392,7 +422,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
392422
#if __ANDROID__
393423
detectAndroid(cpu);
394424
#elif __aarch64__
395-
detectAsahi(cpu);
425+
detectArmSoc(cpu);
396426
#endif
397427

398428
if (cpu->name.length == 0)

0 commit comments

Comments
 (0)