diff mbox series

[08/10] target/arm: HCR_EL2.RW should be RAO/WI if EL1 doesn't support AArch32

Message ID 20250306163925.2940297-9-peter.maydell@linaro.org
State New
Headers show
Series [01/10] target/arm: Move A32_BANKED_REG_{GET, SET} macros to cpregs.h | expand

Commit Message

Peter Maydell March 6, 2025, 4:39 p.m. UTC
When EL1 doesn't support AArch32, the HCR_EL2.RW bit is supposed to
be RAO/WI.  We don't enforce this.  This isn't a problem yet because
at the moment all of our CPU types with AArch64 support AArch32 at
all exception levels, but in the future this is likely to no longer
be true. Enforce the RAO/WI behaviour.

Note that we handle "reset value should honour RES1 bits" in the same
way that SCR_EL3 does, via a reset function.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/helper.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Richard Henderson March 6, 2025, 11:01 p.m. UTC | #1
On 3/6/25 08:39, Peter Maydell wrote:
> When EL1 doesn't support AArch32, the HCR_EL2.RW bit is supposed to
> be RAO/WI.  We don't enforce this.  This isn't a problem yet because
> at the moment all of our CPU types with AArch64 support AArch32 at
> all exception levels, but in the future this is likely to no longer
> be true. Enforce the RAO/WI behaviour.
> 
> Note that we handle "reset value should honour RES1 bits" in the same
> way that SCR_EL3 does, via a reset function.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   target/arm/helper.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
diff mbox series

Patch

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1085bff0ec5..6dc6f3858fc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5167,6 +5167,11 @@  static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
     /* Clear RES0 bits.  */
     value &= valid_mask;
 
+    /* RW is RAO/WI if EL1 is AArch64 only */
+    if (!cpu_isar_feature(aa64_aa32_el1, cpu)) {
+        value |= HCR_RW;
+    }
+
     /*
      * These bits change the MMU setup:
      * HCR_VM enables stage 2 translation
@@ -5224,6 +5229,12 @@  static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
     do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
 }
 
+static void hcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    /* hcr_write will set the RES1 bits on an AArch64-only CPU */
+    hcr_write(env, ri, 0);
+}
+
 /*
  * Return the effective value of HCR_EL2, at the given security state.
  * Bits that are not included here:
@@ -5459,6 +5470,7 @@  static const ARMCPRegInfo el2_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
       .nv2_redirect_offset = 0x78,
+      .resetfn = hcr_reset,
       .writefn = hcr_write, .raw_writefn = raw_write },
     { .name = "HCR", .state = ARM_CP_STATE_AA32,
       .type = ARM_CP_ALIAS | ARM_CP_IO,