]> git.ipfire.org Git - pakfire.git/commitdiff
os: Implement some custom CPU model detection for ARM
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 25 Jan 2025 15:12:06 +0000 (15:12 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 25 Jan 2025 15:12:06 +0000 (15:12 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/os.c

index bbc111b16cd721dfd0f1fbb6adac26de0e71e657..e80fe184516ecfd7ad6330b3d44d0161b09ef628 100644 (file)
 
 // 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);