From: Michael Tremer Date: Sat, 25 Jan 2025 15:12:06 +0000 (+0000) Subject: os: Implement some custom CPU model detection for ARM X-Git-Tag: 0.9.30~381 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03bb4ba5c2c3b6a0b33c7856addbafc5546bb612;p=pakfire.git os: Implement some custom CPU model detection for ARM Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/os.c b/src/pakfire/os.c index bbc111b1..e80fe184 100644 --- a/src/pakfire/os.c +++ b/src/pakfire/os.c @@ -30,6 +30,88 @@ // CPU Info +#ifdef __aarch64__ +/* + * On aarch64, /proc/cpuinfo is very stripped down and does not give us a lot + * of information about the CPU. This function tries to add some extra stuff. + */ +static int pakfire_cpuinfo_aarch64(struct pakfire_cpuinfo* cpuinfo) { + const char* vendor = NULL; + const char* model = NULL; + uint64_t midr = 0; + int r; + + // Skip this if we already have a CPU vendor and model + if (*cpuinfo->vendor || *cpuinfo->model) + return 0; + + // Read MIDR EL1 + asm volatile("mrs %0, MIDR_EL1" : "=r"(midr)); + + // Decode the register + uint8_t implementer = (midr >> 24) & 0x0ff; + //uint8_t variant = (midr >> 20) & 0x00f; + uint16_t partnum = (midr >> 4) & 0xfff; + //uint8_t revision = (midr >> 0) & 0x00f; + + // Find vendors + switch (implementer) { + // ARM + case 0x41: + vendor = "ARM"; + + // Find models + switch (partnum) { + // Neoverse-N1 + case 0xd0c: + model = "Neoverse-N1"; + break; + + // Neoverse-V1 + case 0xd40: + model = "Neoverse-V1"; + break; + + // Neoverse-N2 + case 0xd49: + model = "Neoverse-N2"; + break; + + // Neoverse-V2 + case 0xd4f: + model = "Neoverse-V2"; + break; + + // Neoverse-V3 + case 0xd84: + model = "Neoverse-V3"; + break; + + // Neoverse-N3 + case 0xd8e: + model = "Neoverse-N3"; + break; + } + } + + // Store vendor (if found) + if (vendor) { + r = pakfire_string_set(cpuinfo->vendor, vendor); + if (r < 0) + return r; + } + + // Store the model (if found) + if (model) { + r = pakfire_string_set(cpuinfo->model, model); + if (r < 0) + return r; + } + + return 0; +} +#endif /* __aarch64__ */ + static int pakfire_parse_cpuinfo(char* line, size_t length, void* data) { struct pakfire_cpuinfo* cpuinfo = data; int r; @@ -71,6 +153,13 @@ int pakfire_cpuinfo(struct pakfire_cpuinfo* cpuinfo) { if (r) return r; + // Run architecture-specific stuff +#ifdef __aarch64__ + r = pakfire_cpuinfo_aarch64(cpuinfo); + if (r) + return r; +#endif /* __aarch64__ */ + // Fetch the number of processors cpuinfo->count = sysconf(_SC_NPROCESSORS_CONF);