diff --git a/libcpuid/check-consistency.py b/libcpuid/check-consistency.py index 804e5abc..3fc0b1a0 100755 --- a/libcpuid/check-consistency.py +++ b/libcpuid/check-consistency.py @@ -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 = [ diff --git a/libcpuid/cpuid_main.c b/libcpuid/cpuid_main.c index 24f90db7..4da8d518 100644 --- a/libcpuid/cpuid_main.c +++ b/libcpuid/cpuid_main.c @@ -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) { diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index aa669ff2..d9f448bb 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -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; diff --git a/libcpuid/recog_arm.c b/libcpuid/recog_arm.c index c8bc210e..f6b10b99 100644 --- a/libcpuid/recog_arm.c +++ b/libcpuid/recog_arm.c @@ -390,20 +390,24 @@ 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 */ = { @@ -411,9 +415,14 @@ static void load_arm_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) } }; - 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)