// 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;
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);