diff options
Diffstat (limited to 'target/arm/cpu-features.h')
-rw-r--r-- | target/arm/cpu-features.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index c59ca10..4452e7c 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -21,6 +21,8 @@ #define TARGET_ARM_FEATURES_H #include "hw/registerfields.h" +#include "qemu/host-utils.h" +#include "cpu.h" /* * Naming convention for isar_feature functions: @@ -473,6 +475,11 @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0; } +static inline bool isar_feature_aa64_xs(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, XS) != 0; +} + /* * These are the values from APA/API/APA3. * In general these must be compared '>=', per the normal Arm ARM @@ -556,6 +563,11 @@ static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0; } +static inline bool isar_feature_aa64_ebf16(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) > 1; +} + static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0; @@ -586,6 +598,11 @@ static inline bool isar_feature_aa64_mops(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS); } +static inline bool isar_feature_aa64_rpres(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, RPRES); +} + static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id) { /* We always set the AdvSIMD and FP fields identically. */ @@ -791,11 +808,21 @@ static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0; } +static inline bool isar_feature_aa64_afp(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, AFP) != 0; +} + static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, TIDCP1) != 0; } +static inline bool isar_feature_aa64_cmow(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, CMOW) != 0; +} + static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0; @@ -1022,6 +1049,55 @@ static inline bool isar_feature_any_evt(const ARMISARegisters *id) return isar_feature_aa64_evt(id) || isar_feature_aa32_evt(id); } +typedef enum { + CCSIDR_FORMAT_LEGACY, + CCSIDR_FORMAT_CCIDX, +} CCSIDRFormat; + +static inline uint64_t make_ccsidr(CCSIDRFormat format, unsigned assoc, + unsigned linesize, unsigned cachesize, + uint8_t flags) +{ + unsigned lg_linesize = ctz32(linesize); + unsigned sets; + uint64_t ccsidr = 0; + + assert(assoc != 0); + assert(is_power_of_2(linesize)); + assert(lg_linesize >= 4 && lg_linesize <= 7 + 4); + + /* sets * associativity * linesize == cachesize. */ + sets = cachesize / (assoc * linesize); + assert(cachesize % (assoc * linesize) == 0); + + if (format == CCSIDR_FORMAT_LEGACY) { + /* + * The 32-bit CCSIDR format is: + * [27:13] number of sets - 1 + * [12:3] associativity - 1 + * [2:0] log2(linesize) - 4 + * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc + */ + ccsidr = deposit32(ccsidr, 28, 4, flags); + ccsidr = deposit32(ccsidr, 13, 15, sets - 1); + ccsidr = deposit32(ccsidr, 3, 10, assoc - 1); + ccsidr = deposit32(ccsidr, 0, 3, lg_linesize - 4); + } else { + /* + * The 64-bit CCSIDR_EL1 format is: + * [55:32] number of sets - 1 + * [23:3] associativity - 1 + * [2:0] log2(linesize) - 4 + * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc + */ + ccsidr = deposit64(ccsidr, 32, 24, sets - 1); + ccsidr = deposit64(ccsidr, 3, 21, assoc - 1); + ccsidr = deposit64(ccsidr, 0, 3, lg_linesize - 4); + } + + return ccsidr; +} + /* * Forward to the above feature tests given an ARMCPU pointer. */ |