Reviewed-by: Peter Maydell <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
---
target/arm/cpregs.h | 1 +
target/arm/cpu-features.h | 5 +++++
target/arm/cpu.h | 2 +-
target/arm/helper.c | 20 ++++++++++++++++++++
4 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
index 391c0e322b..34592679e4 100644
--- a/target/arm/cpregs.h
+++ b/target/arm/cpregs.h
@@ -385,6 +385,7 @@ typedef enum CPAccessResult {
/* Indexes into fgt_write[] */
#define FGTREG_HFGWTR 0
#define FGTREG_HDFGWTR 1
+#define FGTREG_FGWTE3 2
/* Indexes into fgt_exec[] */
#define FGTREG_HFGITR 0
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index fb5ed25ad0..75f0fc4169 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -1467,6 +1467,11 @@ static inline bool isar_feature_aa64_asid2(const
ARMISARegisters *id)
return FIELD_EX64_IDREG(id, ID_AA64MMFR4, ASID2) != 0;
}
+static inline bool isar_feature_aa64_fgwte3(const ARMISARegisters *id)
+{
+ return FIELD_EX64_IDREG(id, ID_AA64MMFR4, FGWTE3) != 0;
+}
+
/*
* Note the E2H0 ID fields is signed, increasingly negative as more
* isn't implemented.
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c0492c8dfb..a471b87aa5 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -553,7 +553,7 @@ typedef struct CPUArchState {
* FEAT_FGT2 will add more elements to these arrays.
*/
uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
- uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
+ uint64_t fgt_write[3]; /* HFGWTR, HDFGWTR, FGWTE3 */
uint64_t fgt_exec[1]; /* HFGITR */
/* RME registers */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index af45234ad2..853daf2e39 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6331,6 +6331,22 @@ static const ARMCPRegInfo fpmr_reginfo[] = {
}
};
+static void fgwte3_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /* All bits are W1S and can only be cleared by cpu reset. */
+ env->cp15.fgt_write[FGTREG_FGWTE3] |= value;
+}
+
+static const ARMCPRegInfo fgwte3_reginfo[] = {
+ { .name = "FGWTE3_EL3", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 5,
+ .access = PL3_RW, .resetvalue = 0,
+ .writefn = fgwte3_write, .raw_writefn = raw_write,
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_FGWTE3])
+ },
+};
+
void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
@@ -7642,6 +7658,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, ccsidr2_reginfo);
}
+ if (cpu_isar_feature(aa64_fgwte3, cpu)) {
+ define_arm_cp_regs(cpu, fgwte3_reginfo);
+ }
+
define_pm_cpregs(cpu);
define_gcs_cpregs(cpu);
}
--
2.43.0