Skip to content

Instantly share code, notes, and snippets.

@rajesh-s
Created September 30, 2025 16:36
Show Gist options
  • Save rajesh-s/ef21fae687c3ac5074c1938d19fd2996 to your computer and use it in GitHub Desktop.
Save rajesh-s/ef21fae687c3ac5074c1938d19fd2996 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <sys/auxv.h>
#include <numa.h>
// https://developer.arm.com/documentation/ddi0601/2020-12/AArch64-Registers/MIDR-EL1--Main-ID-Register
typedef union
{
struct {
unsigned int revision : 4;
unsigned int part : 12;
unsigned int arch : 4;
unsigned int variant : 4;
unsigned int implementer : 8;
unsigned int _RES0 : 32;
};
unsigned long bits;
} MIDR_EL1;
static MIDR_EL1 read_MIDR_EL1()
{
MIDR_EL1 reg;
asm("mrs %0, MIDR_EL1" : "=r" (reg.bits));
return reg;
}
static const char * get_implementer_name(MIDR_EL1 midr)
{
switch(midr.implementer)
{
case 0xC0: return "Ampere";
case 0x41: return "Arm";
case 0x42: return "Broadcom";
case 0x43: return "Cavium";
case 0x44: return "DEC";
case 0x46: return "Fujitsu";
case 0x48: return "HiSilicon";
case 0x49: return "Infineon";
case 0x4D: return "Motorola";
case 0x4E: return "NVIDIA";
case 0x50: return "Applied Micro";
case 0x51: return "Qualcomm";
case 0x56: return "Marvell";
case 0x69: return "Intel";
default: return "Unknown";
}
}
static const char * get_part_name(MIDR_EL1 midr)
{
switch(midr.implementer)
{
case 0x41: // Arm Ltd.
switch (midr.part) {
case 0xd03: return "Cortex A53";
case 0xd07: return "Cortex A57";
case 0xd08: return "Cortex A72";
case 0xd09: return "Cortex A73";
case 0xd0c: return "Neoverse N1";
case 0xd40: return "Neoverse V1";
case 0xd4f: return "Neoverse V2";
default: return "Unknown";
}
case 0x42: // Broadcom
switch (midr.part) {
case 0x516: return "Vulcan";
default: return "Unknown";
}
case 0x43: // Cavium
switch (midr.part) {
case 0x0a1: return "ThunderX";
case 0x0af: return "ThunderX2";
default: return "Unknown";
}
case 0x46: // Fujitsu
switch (midr.part) {
case 0x001: return "A64FX";
default: return "Unknown";
}
case 0x4E: // NVIDIA
switch (midr.part) {
case 0x000: return "Denver";
case 0x003: return "Denver 2";
case 0x004: return "Carmel";
default: return "Unknown";
}
case 0x50: // Applied Micro
switch (midr.part) {
case 0x000: return "EMAG 8180";
default: return "Unknown";
}
default: return "Unknown";
}
}
int main(void)
{
// Main ID register
MIDR_EL1 midr = read_MIDR_EL1();
// CPU ISA capabilities
unsigned long hwcaps = getauxval(AT_HWCAP);
printf("CPU revision : 0x%x\n", midr.revision);
printf("CPU part number : 0x%x (%s)\n", midr.part, get_part_name(midr));
printf("CPU architecture: 0x%x\n", midr.arch);
printf("CPU variant : 0x%x\n", midr.variant);
printf("CPU implementer : 0x%x (%s)\n", midr.implementer, get_implementer_name(midr));
printf("CPU LSE atomics : %sSupported\n", (hwcaps & HWCAP_ATOMICS) ? "" : "Not ");
printf("CPU NEON SIMD : %sSupported\n", (hwcaps & HWCAP_ASIMD) ? "" : "Not ");
printf("CPU SVE SIMD : %sSupported\n", (hwcaps & HWCAP_SVE) ? "" : "Not ");
printf("CPU Dot-product : %sSupported\n", (hwcaps & HWCAP_ASIMDDP) ? "" : "Not ");
printf("CPU FP16 : %sSupported\n", (hwcaps & HWCAP_FPHP) ? "" : "Not ");
printf("CPU BF16 : %sSupported\n", (hwcaps & HWCAP2_BF16) ? "" : "Not ");
if (numa_available() == -1) {
printf("libnuma not available\n");
}
printf("CPU NUMA nodes : %d\n", numa_num_configured_nodes());
printf("CPU Cores : %d\n", numa_num_configured_cpus());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment