Skip to content

Commit

Permalink
Add initial support for ARM CPUs running in AArch32 mode
Browse files Browse the repository at this point in the history
Related to #96
Kernel modules to access AArch32 registers will be added in a separate commit.
  • Loading branch information
TheTumultuousUnicornOfDarkness committed Jul 7, 2024
1 parent 7b0e6ba commit ea9ada7
Show file tree
Hide file tree
Showing 9 changed files with 2,492 additions and 430 deletions.
4 changes: 2 additions & 2 deletions libcpuid/check-consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ def checkEnumSize(enumName, constantName):

files_code = {}

rexp1 = re.compile(r'.*flags\[(CPU_FEATURE_[^\]]+)\]\s*=\s*1.*') # e.g. "data->flags[CPU_FEATURE_MPAM] = 1;"
rexp2 = re.compile(r'.*(CPU_FEATURE_[^ ,]+)\s*,\s*FEATURE_LEVEL_ARM_.*') # e.g. "{ 35, 32, 0b0101, CPU_FEATURE_SPEV1P4, FEATURE_LEVEL_ARM_V8_8_A, -1 },"
rexp1 = re.compile(r'.*\[(CPU_FEATURE_[^ \]]+)\]\s*=\s*{.*') # e.g. "[CPU_FEATURE_SWAP] = {"
rexp2 = re.compile(r'.*(CPU_FEATURE_[^ ,]+),\s*FEATURE_LEVEL_ARM_.*') # e.g. "set_feature_status(data, ext_status, (mte_frac == 0b0000), CPU_FEATURE_MTE_ASYNC, FEATURE_LEVEL_ARM_V8_5_A, -1);"
rexp3 = re.compile(r'.*(CPU_FEATURE_[^ }]+).*') # e.g. "{ 28, CPU_FEATURE_HT },"

for fn in glob.glob("%s/*.c" % sys.argv[1]):
Expand Down
95 changes: 72 additions & 23 deletions libcpuid/cpuid_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,18 @@ static int cpuid_serialize_raw_data_internal(struct cpu_raw_data_t* single_raw,
fprintf(f, "arm_midr=%016" PRIx64 "\n", raw_ptr->arm_midr);
fprintf(f, "arm_mpidr=%016" PRIx64 "\n", raw_ptr->arm_mpidr);
fprintf(f, "arm_revidr=%016" PRIx64 "\n", raw_ptr->arm_revidr);
for (i = 0; i < MAX_ARM_ID_AFR_REGS; i++)
fprintf(f, "arm_id_afr%d=%08" PRIx32 "\n", i, raw_ptr->arm_id_afr[i]);
for (i = 0; i < MAX_ARM_ID_DFR_REGS; i++)
fprintf(f, "arm_id_dfr%d=%08" PRIx32 "\n", i, raw_ptr->arm_id_dfr[i]);
for (i = 0; i < MAX_ARM_ID_ISAR_REGS; i++)
fprintf(f, "arm_id_isar%d=%08" PRIx32 "\n", i, raw_ptr->arm_id_isar[i]);
for (i = 0; i < MAX_ARM_ID_MMFR_REGS; i++)
fprintf(f, "arm_id_mmfr%d=%08" PRIx32 "\n", i, raw_ptr->arm_id_mmfr[i]);
for (i = 0; i < MAX_ARM_ID_PFR_REGS; i++)
fprintf(f, "arm_id_pfr%d=%08" PRIx32 "\n", i, raw_ptr->arm_id_pfr[i]);
for (i = 0; i < MAX_ARM_ID_AA64AFR_REGS; i++)
fprintf(f, "arm_id_aa64afr%d=%016" PRIx64 "\n", i, raw_ptr->arm_id_aa64afr[i]);
for (i = 0; i < MAX_ARM_ID_AA64DFR_REGS; i++)
fprintf(f, "arm_id_aa64dfr%d=%016" PRIx64 "\n", i, raw_ptr->arm_id_aa64dfr[i]);
for (i = 0; i < MAX_ARM_ID_AA64ISAR_REGS; i++)
Expand Down Expand Up @@ -688,7 +700,8 @@ static int cpuid_serialize_raw_data_internal(struct cpu_raw_data_t* single_raw,
}

#define RAW_ASSIGN_LINE_X86(__line) __line[EAX] = eax ; __line[EBX] = ebx ; __line[ECX] = ecx ; __line[EDX] = edx
#define RAW_ASSIGN_LINE_ARM(__line) __line = arm_reg
#define RAW_ASSIGN_LINE_AARCH32(__line) __line = aarch32_reg
#define RAW_ASSIGN_LINE_AARCH64(__line) __line = aarch64_reg
static int cpuid_deserialize_raw_data_internal(struct cpu_raw_data_t* single_raw, struct cpu_raw_data_array_t* raw_array, const char* filename)
{
int i;
Expand All @@ -700,8 +713,8 @@ static int cpuid_deserialize_raw_data_internal(struct cpu_raw_data_t* single_raw
bool is_aida64_dump = false;
const bool use_raw_array = (raw_array != NULL);
logical_cpu_t logical_cpu = 0;
uint32_t addr, eax, ebx, ecx, edx;
uint64_t arm_reg;
uint32_t addr, eax, ebx, ecx, edx, aarch32_reg;
uint64_t aarch64_reg;
char version[8] = "";
char line[100];
struct cpu_raw_data_t* raw_ptr = single_raw;
Expand Down Expand Up @@ -786,32 +799,50 @@ static int cpuid_deserialize_raw_data_internal(struct cpu_raw_data_t* single_raw
else if ((sscanf(line, "amd_fn80000026h[%d]=%" SCNx32 "%" SCNx32 "%" SCNx32 "%" SCNx32, &i, &eax, &ebx, &ecx, &edx) >= 5) && (i >= 0) && (i < MAX_AMDFN80000026H_LEVEL)) {
RAW_ASSIGN_LINE_X86(raw_ptr->amd_fn80000026h[i]);
}
else if ((sscanf(line, "arm_midr=%" SCNx64, &arm_reg) >= 1)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_midr);
else if ((sscanf(line, "arm_midr=%" SCNx64, &aarch64_reg) >= 1)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_midr);
}
else if ((sscanf(line, "arm_mpidr=%" SCNx64, &arm_reg) >= 1)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_mpidr);
else if ((sscanf(line, "arm_mpidr=%" SCNx64, &aarch64_reg) >= 1)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_mpidr);
}
else if ((sscanf(line, "arm_revidr=%" SCNx64, &arm_reg) >= 1)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_revidr);
else if ((sscanf(line, "arm_revidr=%" SCNx64, &aarch64_reg) >= 1)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_revidr);
}
else if ((sscanf(line, "arm_id_aa64dfr%d=%" SCNx64, &i, &arm_reg) >= 2)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_id_aa64dfr[i]);
else if ((sscanf(line, "arm_id_afr%d=%" SCNx32, &i, &aarch32_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH32(raw_ptr->arm_id_afr[i]);
}
else if ((sscanf(line, "arm_id_aa64isar%d=%" SCNx64, &i, &arm_reg) >= 2)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_id_aa64isar[i]);
else if ((sscanf(line, "arm_id_dfr%d=%" SCNx32, &i, &aarch32_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH32(raw_ptr->arm_id_dfr[i]);
}
else if ((sscanf(line, "arm_id_aa64mmfr%d=%" SCNx64, &i, &arm_reg) >= 2)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_id_aa64mmfr[i]);
else if ((sscanf(line, "arm_id_isar%d=%" SCNx32, &i, &aarch32_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH32(raw_ptr->arm_id_isar[i]);
}
else if ((sscanf(line, "arm_id_aa64pfr%d=%" SCNx64, &i, &arm_reg) >= 2)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_id_aa64pfr[i]);
else if ((sscanf(line, "arm_id_mmfr%d=%" SCNx32, &i, &aarch32_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH32(raw_ptr->arm_id_mmfr[i]);
}
else if ((sscanf(line, "arm_id_aa64smfr%d=%" SCNx64, &i, &arm_reg) >= 2)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_id_aa64smfr[i]);
else if ((sscanf(line, "arm_id_pfr%d=%" SCNx32, &i, &aarch32_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH32(raw_ptr->arm_id_pfr[i]);
}
else if ((sscanf(line, "arm_id_aa64zfr%d=%" SCNx64, &i, &arm_reg) >= 2)) {
RAW_ASSIGN_LINE_ARM(raw_ptr->arm_id_aa64zfr[i]);
else if ((sscanf(line, "arm_id_aa64afr%d=%" SCNx64, &i, &aarch64_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_id_aa64afr[i]);
}
else if ((sscanf(line, "arm_id_aa64dfr%d=%" SCNx64, &i, &aarch64_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_id_aa64dfr[i]);
}
else if ((sscanf(line, "arm_id_aa64isar%d=%" SCNx64, &i, &aarch64_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_id_aa64isar[i]);
}
else if ((sscanf(line, "arm_id_aa64mmfr%d=%" SCNx64, &i, &aarch64_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_id_aa64mmfr[i]);
}
else if ((sscanf(line, "arm_id_aa64pfr%d=%" SCNx64, &i, &aarch64_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_id_aa64pfr[i]);
}
else if ((sscanf(line, "arm_id_aa64smfr%d=%" SCNx64, &i, &aarch64_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_id_aa64smfr[i]);
}
else if ((sscanf(line, "arm_id_aa64zfr%d=%" SCNx64, &i, &aarch64_reg) >= 2)) {
RAW_ASSIGN_LINE_AARCH64(raw_ptr->arm_id_aa64zfr[i]);
}
else if (line[0] != '\0') {
warnf("Warning: file '%s', line %d: '%s' not understood!\n", filename, cur_line, line);
Expand Down Expand Up @@ -1876,6 +1907,21 @@ const char* cpu_feature_str(cpu_feature_t feature)
{ CPU_FEATURE_AVX512VBMI, "avx512vbmi" },
{ CPU_FEATURE_AVX512VBMI2, "avx512vbmi2" },
{ CPU_FEATURE_HYPERVISOR, "hypervisor" },
{ CPU_FEATURE_SWAP, "swap" },
{ CPU_FEATURE_THUMB, "thumb" },
{ CPU_FEATURE_ADVMULTU, "advmultu" },
{ CPU_FEATURE_ADVMULTS, "advmults" },
{ CPU_FEATURE_JAZELLE, "jazelle" },
{ CPU_FEATURE_DEBUGV6, "debugv6" },
{ CPU_FEATURE_DEBUGV6P1, "debugv6p1" },
{ CPU_FEATURE_THUMB2, "thumb2" },
{ CPU_FEATURE_DEBUGV7, "debugv7" },
{ CPU_FEATURE_DEBUGV7P1, "debugv7p1" },
{ CPU_FEATURE_THUMBEE, "thumbee" },
{ CPU_FEATURE_DIVIDE, "divide" },
{ CPU_FEATURE_LPAE, "lpae" },
{ CPU_FEATURE_PMUV1, "pmuv1" },
{ CPU_FEATURE_PMUV2, "pmuv2" },
{ CPU_FEATURE_ASID16, "asid16" },
{ CPU_FEATURE_ADVSIMD, "advsimd" },
{ CPU_FEATURE_CRC32, "crc32" },
Expand All @@ -1892,6 +1938,7 @@ const char* cpu_feature_str(cpu_feature_t feature)
{ CPU_FEATURE_PMUV3, "pmuv3" },
{ CPU_FEATURE_SHA1, "sha1" },
{ CPU_FEATURE_SHA256, "sha256" },
{ CPU_FEATURE_NTLBPA, "ntlbpa" },
{ CPU_FEATURE_HAFDBS, "hafdbs" },
{ CPU_FEATURE_HPDS, "hpds" },
{ CPU_FEATURE_LOR, "lor" },
Expand All @@ -1901,8 +1948,8 @@ const char* cpu_feature_str(cpu_feature_t feature)
{ CPU_FEATURE_RDM, "rdm" },
{ CPU_FEATURE_VHE, "vhe" },
{ CPU_FEATURE_VMID16, "vmid16" },
//{ CPU_FEATURE_AA32HPD, "aa32hpd" },
//{ CPU_FEATURE_AA32I8MM, "aa32i8mm" },
{ CPU_FEATURE_AA32HPD, "aa32hpd" },
{ CPU_FEATURE_AA32I8MM, "aa32i8mm" },
{ CPU_FEATURE_DPB, "dpb" },
{ CPU_FEATURE_DEBUGV8P2, "debugv8p2" },
{ CPU_FEATURE_F32MM, "f32mm" },
Expand Down Expand Up @@ -1977,11 +2024,13 @@ const char* cpu_feature_str(cpu_feature_t feature)
{ CPU_FEATURE_SPECRES, "specres" },
{ CPU_FEATURE_SSBS, "ssbs" },
{ CPU_FEATURE_SSBS2, "ssbs2" },
{ CPU_FEATURE_AA32BF16, "aa32bf16" },
{ CPU_FEATURE_AMUV1P1, "amuv1p1" },
{ CPU_FEATURE_BF16, "bf16" },
{ CPU_FEATURE_DGH, "dgh" },
{ CPU_FEATURE_ECV, "ecv" },
{ CPU_FEATURE_FGT, "fgt" },
{ CPU_FEATURE_HPMN0, "hpmn0" },
{ CPU_FEATURE_MPAMV0P1, "mpamv0p1" },
{ CPU_FEATURE_MPAMV1P1, "mpamv1p1" },
{ CPU_FEATURE_MTPMU, "mtpmu" },
Expand Down
46 changes: 44 additions & 2 deletions libcpuid/libcpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,30 @@ struct cpu_raw_data_t {
* (Revision ID Register) */
uint64_t arm_revidr;

/** when then CPU is ARM-based and supports ID_AFR*
* (AArch32 Auxiliary Feature Register) */
uint32_t arm_id_afr[MAX_ARM_ID_AFR_REGS];

/** when then CPU is ARM-based and supports ID_DFR*
* (AArch32 Debug Feature Register) */
uint32_t arm_id_dfr[MAX_ARM_ID_DFR_REGS];

/** when then CPU is ARM-based and supports D_ISAR*
* (AArch32 Instruction Set Attribute Register) */
uint32_t arm_id_isar[MAX_ARM_ID_ISAR_REGS];

/** when then CPU is ARM-based and supports ID_MMFR*
* (AArch32 Memory Model Feature Register) */
uint32_t arm_id_mmfr[MAX_ARM_ID_MMFR_REGS];

/** when then CPU is ARM-based and supports ID_PFR*
* (AArch32 Processor Feature Register) */
uint32_t arm_id_pfr[MAX_ARM_ID_PFR_REGS];

/** when then CPU is ARM-based and supports ID_AA64AFR*
* (AArch64 Auxiliary Feature Register) */
uint64_t arm_id_aa64afr[MAX_ARM_ID_AA64AFR_REGS];

/** when then CPU is ARM-based and supports ID_AA64DFR*
* (AArch64 Debug Feature Register) */
uint64_t arm_id_aa64dfr[MAX_ARM_ID_AA64DFR_REGS];
Expand Down Expand Up @@ -889,6 +913,21 @@ typedef enum {
CPU_FEATURE_AVX512VBMI, /*!< AVX-512 Vector Bit ManipulationInstructions (version 1) */
CPU_FEATURE_AVX512VBMI2, /*!< AVX-512 Vector Bit ManipulationInstructions (version 2) */
CPU_FEATURE_HYPERVISOR, /*!< Hypervisor present (always zero on physical CPUs) */
CPU_FEATURE_SWAP, /*!< ARM: Swap instructions in the ARM instruction set */
CPU_FEATURE_THUMB, /*!< ARM: Thumb instruction set support */
CPU_FEATURE_ADVMULTU, /*!< ARM: Advanced unsigned Multiply instructions */
CPU_FEATURE_ADVMULTS, /*!< ARM: Advanced signed Multiply instructions */
CPU_FEATURE_JAZELLE, /*!< ARM: Jazelle extension support */
CPU_FEATURE_DEBUGV6, /*!< ARM: Support for v6 Debug architecture */
CPU_FEATURE_DEBUGV6P1, /*!< ARM: Support for v6.1 Debug architecture */
CPU_FEATURE_THUMB2, /*!< ARM: Thumb-2, instruction set support */
CPU_FEATURE_DEBUGV7, /*!< ARM: Support for v7 Debug architecture */
CPU_FEATURE_DEBUGV7P1, /*!< ARM: Support for v7.1 Debug architecture */
CPU_FEATURE_THUMBEE, /*!< ARM: ThumbEE instruction set support */
CPU_FEATURE_DIVIDE, /*!< ARM: Divide instructions */
CPU_FEATURE_LPAE, /*!< ARM: Large Physical Address Extension */
CPU_FEATURE_PMUV1, /*!< ARM: PMU extension version 1 */
CPU_FEATURE_PMUV2, /*!< ARM: PMU extension version 2 */
CPU_FEATURE_ASID16, /*!< ARM: 16 bit ASID */
CPU_FEATURE_ADVSIMD, /*!< ARM: Advanced SIMD Extension */
CPU_FEATURE_CRC32, /*!< ARM: CRC32 instructions */
Expand All @@ -905,6 +944,7 @@ typedef enum {
CPU_FEATURE_PMUV3, /*!< ARM: PMU extension version 3 */
CPU_FEATURE_SHA1, /*!< ARM: Advanced SIMD SHA1 instructions */
CPU_FEATURE_SHA256, /*!< ARM: Advanced SIMD SHA256 instructions */
CPU_FEATURE_NTLBPA, /*!< ARM: Intermediate caching of translation table walks */
CPU_FEATURE_HAFDBS, /*!< ARM: Hardware management of the Access flag and dirty state */
CPU_FEATURE_HPDS, /*!< ARM: Hierarchical permission disables in translations tables */
CPU_FEATURE_LOR, /*!< ARM: Limited ordering regions */
Expand All @@ -914,8 +954,8 @@ typedef enum {
CPU_FEATURE_RDM, /*!< ARM: Advanced SIMD rounding double multiply accumulate instructions */
CPU_FEATURE_VHE, /*!< ARM: Virtualization Host Extensions */
CPU_FEATURE_VMID16, /*!< ARM: 16-bit VMID */
//CPU_FEATURE_AA32HPD, /*!< ARM: AArch32 Hierarchical permission disables */
//CPU_FEATURE_AA32I8MM, /*!< ARM: AArch32 Int8 matrix multiplication instructions */
CPU_FEATURE_AA32HPD, /*!< ARM: AArch32 Hierarchical permission disables */
CPU_FEATURE_AA32I8MM, /*!< ARM: AArch32 Int8 matrix multiplication instructions */
CPU_FEATURE_DPB, /*!< ARM: DC CVAP instruction */
CPU_FEATURE_DEBUGV8P2, /*!< ARM: Debug v8.2 */
CPU_FEATURE_F32MM, /*!< ARM: Single-precision Matrix Multiplication */
Expand Down Expand Up @@ -990,11 +1030,13 @@ typedef enum {
CPU_FEATURE_SPECRES, /*!< ARM: Speculation restriction instructions */
CPU_FEATURE_SSBS, /*!< ARM: Speculative Store Bypass Safe */
CPU_FEATURE_SSBS2, /*!< ARM: MRS and MSR instructions for SSBS version 2 */
CPU_FEATURE_AA32BF16, /*!< ARM: AArch32 BFloat16 instructions */
CPU_FEATURE_AMUV1P1, /*!< ARM: Activity Monitors Extension version 1.1 */
CPU_FEATURE_BF16, /*!< ARM: AArch64 BFloat16 instructions */
CPU_FEATURE_DGH, /*!< ARM: Data Gathering Hint */
CPU_FEATURE_ECV, /*!< ARM: Enhanced Counter Virtualization */
CPU_FEATURE_FGT, /*!< ARM: Fine Grain Traps */
CPU_FEATURE_HPMN0, /*!< ARM: Setting of MDCR_EL2.HPMN to zero */
CPU_FEATURE_MPAMV0P1, /*!< ARM: Memory Partitioning and Monitoring version 0.1 */
CPU_FEATURE_MPAMV1P1, /*!< ARM: Memory Partitioning and Monitoring version 1.1 */
CPU_FEATURE_MTPMU, /*!< ARM: Multi-threaded PMU extensions */
Expand Down
6 changes: 6 additions & 0 deletions libcpuid/libcpuid_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
#define MAX_INTELFN14H_LEVEL 4
#define MAX_AMDFN8000001DH_LEVEL 4
#define MAX_AMDFN80000026H_LEVEL 4
#define MAX_ARM_ID_AFR_REGS 1
#define MAX_ARM_ID_DFR_REGS 2
#define MAX_ARM_ID_ISAR_REGS 7
#define MAX_ARM_ID_MMFR_REGS 6
#define MAX_ARM_ID_PFR_REGS 3
#define MAX_ARM_ID_AA64AFR_REGS 2
#define MAX_ARM_ID_AA64DFR_REGS 2
#define MAX_ARM_ID_AA64ISAR_REGS 3
#define MAX_ARM_ID_AA64MMFR_REGS 5
Expand Down
Loading

0 comments on commit ea9ada7

Please sign in to comment.