target/arm: Handle NSACR.NSASEDIS in HCPTR accesses
In cptr_el2_read() and cptr_el2_write() we have code that implements the "HCPTR.{TCP10,TCP11} behave as RAO/WI from NonSecure when NSACR.cp10 is 0" behaviour. There is a similar requirement for HCPTR.TASE: if NSACR.NSASEDIS is 1 then CPACR.ASEDIS behaves as RAO/WI in NS. This doesn't matter to us yet because we don't currently implement ASEDIS or NSASEDIS. But we're about to do that, so add the handling to cptr_el2_read() and cptr_el2_write(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260817123838.1578060-3-peter.maydell@linaro.org
Peter Maydell committed
Aug 17, 2026 at 13:38 UTC
653311eecdcbeae672bace9039b8c65745d1693c
1 file changed
+18
-5
target/arm/helper.c
+18
-5
@@ -4117,11 +4117,18 @@ static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4117
/*
4118
* For A-profile AArch32 EL3, if NSACR.CP10
4119
* is 0 then HCPTR.{TCP11,TCP10} ignore writes and read as 1.
4120
+ * Similarly, if NSACR.NSASEDIS is 1 then HCPTR.TASE behaves as RAO/WI.
4121
*/
4122
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
4122
- !arm_is_secure(env) && !FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4123
- uint64_t mask = R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4124
- value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
4123
+ !arm_is_secure(env)) {
4124
+ if (!FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4125
+ uint64_t mask = R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4126
+ value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
4127
+ }
4128
+ if (FIELD_EX32(env->cp15.nsacr, NSACR, NSASEDIS)) {
4129
+ uint64_t mask = R_HCPTR_TASE_MASK;
4130
+ value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
4131
+ }
4132
}
4133
env->cp15.cptr_el[2] = value;
4134
}
@@ -4131,12 +4138,18 @@ static uint64_t cptr_el2_read(CPUARMState *env, const ARMCPRegInfo *ri)
4138
/*
4139
* For A-profile AArch32 EL3, if NSACR.CP10
4140
* is 0 then HCPTR.{TCP11,TCP10} ignore writes and read as 1.
4141
+ * Similarly, if NSACR.NSASEDIS is 1 then HCPTR.TASE behaves as RAO/WI.
4142
*/
4143
uint64_t value = env->cp15.cptr_el[2];
4144
4145
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
4138
- !arm_is_secure(env) && !FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4139
- value |= R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4146
+ !arm_is_secure(env)) {
4147
+ if (!FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4148
+ value |= R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4149
+ }
4150
+ if (!FIELD_EX32(env->cp15.nsacr, NSACR, NSASEDIS)) {
4151
+ value |= R_HCPTR_TASE_MASK;
4152
+ }
4153
}
4154
return value;
4155
}