aboutsummaryrefslogtreecommitdiff
path: root/target/arm/cpu-features.h
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/cpu-features.h')
-rw-r--r--target/arm/cpu-features.h76
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.
*/