Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial support for ARM CPUs #200

Closed
wants to merge 30 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0796650
Add initial support for ARM CPUs
TheTumultuousUnicornOfDarkness Jun 10, 2024
f189611
Add CPU_FEATURE_AES to whitelist in check-consistency.py
TheTumultuousUnicornOfDarkness Jun 11, 2024
cc064be
CI: update macOS runners
TheTumultuousUnicornOfDarkness Jun 11, 2024
ced4168
Detect ARM CPUs topology
TheTumultuousUnicornOfDarkness Jun 11, 2024
40831eb
Detect ARM CPUs purpose
TheTumultuousUnicornOfDarkness Jun 15, 2024
ded8aa7
Add Armv8.1 architecture extension
TheTumultuousUnicornOfDarkness Jun 20, 2024
5e3b9fa
Add Armv8.2 architecture extension
TheTumultuousUnicornOfDarkness Jun 20, 2024
b967cea
Add Armv8.3 architecture extension
TheTumultuousUnicornOfDarkness Jun 21, 2024
b9882cc
Add Armv8.4 architecture extension
TheTumultuousUnicornOfDarkness Jun 21, 2024
5a4739a
Add Armv8.5 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
09c10f0
Add Armv8.6 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
bac7b0f
Add Armv8.7 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
be5dc9c
Add Armv8.8 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
23ed73b
Add Armv8.9 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
9cb87ff
Add Armv9.0 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
2fd3b24
Add Armv9.2 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
4d5e9ad
Add Armv9.3 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
0dd570f
Add Armv9.4 architecture extension
TheTumultuousUnicornOfDarkness Jun 22, 2024
7778d96
Detect ARM feature level
TheTumultuousUnicornOfDarkness Jun 23, 2024
dde56c7
Merge branch 'master' into arm_cpus
TheTumultuousUnicornOfDarkness Jun 24, 2024
4b7da42
Fix decode_arm_architecture_version()
TheTumultuousUnicornOfDarkness Jun 24, 2024
c2e8aa5
Move ARM specific fields to sub-struct in struct cpu_id_t
TheTumultuousUnicornOfDarkness Jun 24, 2024
76b306f
Move x86 specific fields to sub-struct in struct cpu_id_t
TheTumultuousUnicornOfDarkness Jun 25, 2024
9e17976
Add ARM fields to cpuid_tool
TheTumultuousUnicornOfDarkness Jun 26, 2024
09c2ba0
Add tests for ARM CPUs
TheTumultuousUnicornOfDarkness Jun 26, 2024
787d76a
utils: add script to parse ARM Architecture Reference Manual PDF file
TheTumultuousUnicornOfDarkness Jun 26, 2024
7abe55e
Fix detection for ARMv9-A CPUs
TheTumultuousUnicornOfDarkness Jun 26, 2024
21565a5
Add codenames for some ARM CPUs
TheTumultuousUnicornOfDarkness Jun 26, 2024
f5514f0
Fix run_tests.py for ARM CPUs
TheTumultuousUnicornOfDarkness Jun 26, 2024
7fca7c3
Set LIBCPUID_DEPRECATED macro to deprecate attributes
TheTumultuousUnicornOfDarkness Jun 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add Armv8.4 architecture extension
TheTumultuousUnicornOfDarkness committed Jun 21, 2024
commit b9882cc2fb88f1fe73a71870a119a2161b7f06b8
11 changes: 8 additions & 3 deletions libcpuid/check-consistency.py
Original file line number Diff line number Diff line change
@@ -108,15 +108,20 @@ def checkEnumSize(enumName, constantName):

files_code = {}

rexp = re.compile('.*(CPU_FEATURE_[^ }]+).*')
rexp1 = re.compile('.*flags\[(CPU_FEATURE_[^\]]+)\]\s+=\s+1.*') # e.g. "data->flags[CPU_FEATURE_MPAM] = 1;"
rexp2 = re.compile('.*(CPU_FEATURE_[^ }]+).*') # e.g. "{ 28, CPU_FEATURE_HT },"

for fn in glob.glob("%s/*.c" % sys.argv[1]):
f = open(fn, "rt")
files_code[fn] = []
for s in f.readlines():
if rexp.match(s):
entry = rexp.findall(s)[0]
if rexp1.match(s):
entry = rexp1.findall(s)[0]
files_code[fn].append(entry)
elif rexp2.match(s):
entry = rexp2.findall(s)[0]
files_code[fn].append(entry)

f.close()

features_whitelist = [
21 changes: 21 additions & 0 deletions libcpuid/cpuid_main.c
Original file line number Diff line number Diff line change
@@ -1835,6 +1835,27 @@ const char* cpu_feature_str(cpu_feature_t feature)
{ CPU_FEATURE_PACQARMA5, "pacqarma5" },
{ CPU_FEATURE_PAUTH, "pauth" },
{ CPU_FEATURE_SPEV1P1, "spev1p1" },
{ CPU_FEATURE_AMUV1, "amuv1" },
{ CPU_FEATURE_BBM, "bbm" },
{ CPU_FEATURE_DIT, "dit" },
{ CPU_FEATURE_DEBUGV8P4, "debugv8p4" },
{ CPU_FEATURE_DOTPROD, "dotprod" },
{ CPU_FEATURE_DOUBLEFAULT, "doublefault" },
{ CPU_FEATURE_FHM, "fhm" },
{ CPU_FEATURE_FLAGM, "flagm" },
{ CPU_FEATURE_IDST, "idst" },
{ CPU_FEATURE_LRCPC2, "lrcpc2" },
{ CPU_FEATURE_LSE2, "lse2" },
{ CPU_FEATURE_MPAM, "mpam" },
{ CPU_FEATURE_PMUV3P4, "pmuv3p4" },
{ CPU_FEATURE_RASV1P1, "rasv1p1" },
{ CPU_FEATURE_S2FWB, "s2fwb" },
{ CPU_FEATURE_SEL2, "sel2" },
{ CPU_FEATURE_TLBIOS, "tlbios" },
{ CPU_FEATURE_TLBIRANGE, "tlbirange" },
{ CPU_FEATURE_TRF, "trf" },
{ CPU_FEATURE_TTL, "ttl" },
{ CPU_FEATURE_TTST, "ttst" },
};
unsigned i, n = COUNT_OF(matchtable);
if (n != NUM_CPU_FEATURES) {
21 changes: 21 additions & 0 deletions libcpuid/libcpuid.h
Original file line number Diff line number Diff line change
@@ -785,6 +785,27 @@ typedef enum {
CPU_FEATURE_PACQARMA5, /*!< ARM: Pointer authentication - QARMA5 algorithm */
CPU_FEATURE_PAUTH, /*!< ARM: Pointer authentication */
CPU_FEATURE_SPEV1P1, /*!< ARM: Statistical Profiling Extension version 1 */
CPU_FEATURE_AMUV1, /*!< ARM: Activity Monitors Extension version 1 */
CPU_FEATURE_BBM, /*!< ARM: Translation table break-before-make levels */
CPU_FEATURE_DIT, /*!< ARM: Data Independent Timing instructions */
CPU_FEATURE_DEBUGV8P4, /*!< ARM: Debug v8.4 */
CPU_FEATURE_DOTPROD, /*!< ARM: Advanced SIMD dot product instructions */
CPU_FEATURE_DOUBLEFAULT, /*!< ARM: Double Fault Extension */
CPU_FEATURE_FHM, /*!< ARM: Floating-point half-precision to single-precision multiply-add instructions */
CPU_FEATURE_FLAGM, /*!< ARM: Condition flag manipulation instructions */
CPU_FEATURE_IDST, /*!< ARM: ID space trap handling */
CPU_FEATURE_LRCPC2, /*!< ARM: Load-Acquire RCpc instructions version 2 */
CPU_FEATURE_LSE2, /*!< ARM: Large System Extensions version 2 */
CPU_FEATURE_MPAM, /*!< ARM: Memory Partitioning and Monitoring Extension */
CPU_FEATURE_PMUV3P4, /*!< ARM: Arm8.4 PMU extensions */
CPU_FEATURE_RASV1P1, /*!< ARM: RAS extension v1.1 */
CPU_FEATURE_S2FWB, /*!< ARM: Stage 2 forced Write-Back */
CPU_FEATURE_SEL2, /*!< ARM: Secure EL2 */
CPU_FEATURE_TLBIOS, /*!< ARM: TLB invalidate instructions in Outer Shareable domain */
CPU_FEATURE_TLBIRANGE, /*!< ARM: TLB invalidate range instructions */
CPU_FEATURE_TRF, /*!< ARM: Self-hosted Trace extensions */
CPU_FEATURE_TTL, /*!< ARM: Translation Table Level */
CPU_FEATURE_TTST, /*!< ARM: Small translation tables */
/* termination: */
NUM_CPU_FEATURES,
} cpu_feature_t;
53 changes: 45 additions & 8 deletions libcpuid/recog_arm.c
Original file line number Diff line number Diff line change
@@ -390,30 +390,39 @@ static void match_arm_features(const struct arm_feature_map_t* matchtable, uint3
}
}

#define MAX_ARM_FIELDS_PER_REGISTER 16+1 // Add one extra item at end containing a sentinel value
#define MAX_MATCHTABLE_ITEMS 32
#define MATCH_FEATURES_TABLE_WITH_RAW(reg) match_arm_features(matchtable_id_##reg[i], raw->arm_id_##reg[i], data)
static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
int i;
uint8_t mpam, mpam_frac;

const struct arm_feature_map_t matchtable_id_aa64dfr[MAX_ARM_ID_AA64DFR_REGS][MAX_ARM_FIELDS_PER_REGISTER] = {
const struct arm_feature_map_t matchtable_id_aa64dfr[MAX_ARM_ID_AA64DFR_REGS][MAX_MATCHTABLE_ITEMS] = {
[0] /* ID_AA64DFR0 */ = {
{ 43, 40, 0b0001, CPU_FEATURE_TRF },
{ 39, 36, 0b0000, CPU_FEATURE_DOUBLELOCK },
{ 35, 32, 0b0001, CPU_FEATURE_SPE },
{ 35, 32, 0b0010, CPU_FEATURE_SPEV1P1 },
{ 11, 8, 0b0001, CPU_FEATURE_PMUV3 }, /* Performance Monitors Extension, PMUv3 implemented. */
{ 11, 8, 0b0100, CPU_FEATURE_PMUV3P1 }, /* PMUv3 for Armv8.1 */
{ 11, 8, 0b0101, CPU_FEATURE_PMUV3P4 }, /* PMUv3 for Armv8.4 */
{ 3, 0, 0b1000, CPU_FEATURE_DEBUGV8P2 },
{ 3, 0, 0b1001, CPU_FEATURE_DEBUGV8P4 },
{ -1, -1, -1, -1 }
},
[1] /* ID_AA64DFR1 */ = {
{ -1, -1, -1, -1 }
}
};

const struct arm_feature_map_t matchtable_id_aa64isar[MAX_ARM_ID_AA64ISAR_REGS][MAX_ARM_FIELDS_PER_REGISTER] = {
const struct arm_feature_map_t matchtable_id_aa64isar[MAX_ARM_ID_AA64ISAR_REGS][MAX_MATCHTABLE_ITEMS] = {
[0] /* ID_A64ISAR0 */ = {
{ 55, 52, 0b0001, CPU_FEATURE_I8MM },
{ 59, 56, 0b0001, CPU_FEATURE_TLBIOS }, /* Outer Shareable and TLB range maintenance instructions are not implemented */
{ 59, 56, 0b0010, CPU_FEATURE_TLBIOS }, /* Outer Shareable TLB maintenance instructions are implemented */
{ 59, 56, 0b0010, CPU_FEATURE_TLBIRANGE }, /* Outer Shareable TLB maintenance instructions are implemented */
{ 55, 52, 0b0001, CPU_FEATURE_FLAGM },
{ 51, 48, 0b0001, CPU_FEATURE_FHM },
{ 47, 44, 0b0001, CPU_FEATURE_DOTPROD },
{ 43, 40, 0b0001, CPU_FEATURE_SM4 },
{ 39, 36, 0b0001, CPU_FEATURE_SM3 },
{ 35, 32, 0b0001, CPU_FEATURE_SHA3 },
@@ -428,9 +437,12 @@ static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{ -1, -1, -1, -1 }
},
[1] /* ID_A64ISAR1 */ = {
{ 55, 52, 0b0001, CPU_FEATURE_I8MM },
{ 35, 32, 0b0001, CPU_FEATURE_LSE2 },
{ 31, 28, 0b0001, CPU_FEATURE_PACIMP },
{ 27, 24, 0b0001, CPU_FEATURE_PACQARMA5 },
{ 23, 20, 0b0001, CPU_FEATURE_LRCPC },
{ 23, 20, 0b0010, CPU_FEATURE_LRCPC2 },
{ 19, 16, 0b0001, CPU_FEATURE_FCMA },
{ 15, 12, 0b0001, CPU_FEATURE_JSCVT },
{ 11, 8, 0b0001, CPU_FEATURE_PAUTH },
@@ -458,7 +470,7 @@ static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
}
};

const struct arm_feature_map_t matchtable_id_aa64mmfr[MAX_ARM_ID_AA64MMFR_REGS][MAX_ARM_FIELDS_PER_REGISTER] = {
const struct arm_feature_map_t matchtable_id_aa64mmfr[MAX_ARM_ID_AA64MMFR_REGS][MAX_MATCHTABLE_ITEMS] = {
[0] /* ID_AA64MMFR0 */ = {
{ 19, 16, 0b0001, CPU_FEATURE_MIXEDEND },
{ 7, 4, 0b0010, CPU_FEATURE_ASID16 },
@@ -480,6 +492,13 @@ static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{ -1, -1, -1, -1 }
},
[2] /* ID_AA64MMFR2 */ = {
{ 55, 52, 0b0000, CPU_FEATURE_BBM }, /* Level 0 support for changing block size is supported */
{ 55, 52, 0b0001, CPU_FEATURE_BBM }, /* Level 1 support for changing block size is supported */
{ 55, 52, 0b0010, CPU_FEATURE_BBM }, /* Level 2 support for changing block size is supported */
{ 51, 48, 0b0001, CPU_FEATURE_TTL },
{ 43, 40, 0b0001, CPU_FEATURE_S2FWB },
{ 39, 36, 0b0001, CPU_FEATURE_IDST },
{ 31, 28, 0b0001, CPU_FEATURE_TTST },
{ 23, 20, 0b0001, CPU_FEATURE_CCIDX },
{ 19, 16, 0b0001, CPU_FEATURE_LVA },
{ 15, 12, 0b0001, CPU_FEATURE_IESB },
@@ -496,12 +515,17 @@ static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
}
};

const struct arm_feature_map_t matchtable_id_aa64pfr[MAX_ARM_ID_AA64PFR_REGS][MAX_ARM_FIELDS_PER_REGISTER] = {
const struct arm_feature_map_t matchtable_id_aa64pfr[MAX_ARM_ID_AA64PFR_REGS][MAX_MATCHTABLE_ITEMS] = {
[0] /* ID_AA64PFR0 */ = {
{ 59, 56, 0b0010, CPU_FEATURE_CSV2_2 },
{ 59, 56, 0b0011, CPU_FEATURE_CSV2_3 },
{ 51, 48, 0b0001, CPU_FEATURE_DIT },
{ 47, 44, 0b0001, CPU_FEATURE_AMUV1 },
{ 39, 36, 0b0001, CPU_FEATURE_SEL2 },
{ 35, 32, 0b0001, CPU_FEATURE_SVE },
{ 31, 28, 0b0001, CPU_FEATURE_RAS },
{ 31, 28, 0b0010, CPU_FEATURE_DOUBLEFAULT },
{ 31, 28, 0b0010, CPU_FEATURE_RASV1P1 },
{ 23, 20, 0b0000, CPU_FEATURE_ADVSIMD },
{ 23, 20, 0b0001, CPU_FEATURE_ADVSIMD }, /* as for 0b0000, and also includes support for half-precision floating-point arithmetic */
{ 19, 16, 0b0000, CPU_FEATURE_FP },
@@ -518,7 +542,7 @@ static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
}
};

const struct arm_feature_map_t matchtable_id_aa64zfr[MAX_ARM_ID_AA64ZFR_REGS][MAX_ARM_FIELDS_PER_REGISTER] = {
const struct arm_feature_map_t matchtable_id_aa64zfr[MAX_ARM_ID_AA64ZFR_REGS][MAX_MATCHTABLE_ITEMS] = {
[0] /* ID_AA64ZFR0 */ = {
{ 59, 56, 0b0001, CPU_FEATURE_F64MM },
{ 55, 52, 0b0001, CPU_FEATURE_F32MM },
@@ -552,8 +576,21 @@ static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
- FEAT_PACQARMA3. */
if (data->flags[CPU_FEATURE_PACIMP] || data->flags[CPU_FEATURE_PACQARMA3] || data->flags[CPU_FEATURE_PACQARMA5])
data->flags[CPU_FEATURE_PAUTH] = 1;

/* FEAT_MPAM, Memory Partitioning and Monitoring Extension
MPAM Extension version: MPAM | MPAM_frac
Not implemented: 0b0000 | 0b0000
v0.1 is implemented: 0b0000 | 0b0001
v1.0 is implemented: 0b0001 | 0b0000
v1.1 is implemented: 0b0001 | 0b0001 */
mpam = EXTRACTS_BITS(raw->arm_id_aa64pfr[0], 43, 40);
mpam_frac = EXTRACTS_BITS(raw->arm_id_aa64pfr[1], 19, 16);
if ((mpam != 0b0000) || (mpam_frac != 0b0000)) {
data->flags[CPU_FEATURE_MPAM] = 1;
debugf(2, "MPAM Extension version is %u.%u\n", mpam, mpam_frac);
}
}
#undef MAX_ARM_FIELDS_PER_REGISTER
#undef MAX_MATCHTABLE_ITEMS
#undef MATCH_FEATURES_TABLE_WITH_RAW

int cpuid_identify_arm(struct cpu_raw_data_t* raw, struct cpu_id_t* data)