@@ -3757,6 +3757,16 @@ static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
}
+static inline bool isar_feature_aa32_half_evt(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 1;
+}
+
+static inline bool isar_feature_aa32_evt(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 2;
+}
+
static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
@@ -4029,6 +4039,16 @@ static inline bool isar_feature_aa64_ids(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, IDS) != 0;
}
+static inline bool isar_feature_aa64_half_evt(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 1;
+}
+
+static inline bool isar_feature_aa64_evt(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2;
+}
+
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
@@ -4313,6 +4333,16 @@ static inline bool isar_feature_any_ras(const ARMISARegisters *id)
return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id);
}
+static inline bool isar_feature_any_half_evt(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_half_evt(id) || isar_feature_aa32_half_evt(id);
+}
+
+static inline bool isar_feature_any_evt(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_evt(id) || isar_feature_aa32_evt(id);
+}
+
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/
@@ -5267,6 +5267,12 @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
}
}
+ if (cpu_isar_feature(any_evt, cpu)) {
+ valid_mask |= HCR_TTLBIS | HCR_TTLBOS | HCR_TICAB | HCR_TOCU | HCR_TID4;
+ } else if (cpu_isar_feature(any_half_evt, cpu)) {
+ valid_mask |= HCR_TICAB | HCR_TOCU | HCR_TID4;
+ }
+
/* Clear RES0 bits. */
value &= valid_mask;