target/arm: Handle NSACR.NSASEDIS in CPACR accesses
In cpacr_read() and cpacr_write() we have code that implements the "CPACR.{cp10,cp11} behave as RAZ/WI from NonSecure when NSACR.cp10 is 0" behaviour. There is a similar requirement for CPACR.ASEDIS: 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 cpacr_read() and cpacr_write(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260817123838.1578060-2-peter.maydell@linaro.org
Peter Maydell committed
Aug 17, 2026 at 13:38 UTC
b3f00f492f8a9e6a750554cb6dcb21bdcfd80db9
1 file changed
+19
-5
target/arm/helper.c
+19
-5
@@ -588,11 +588,19 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
588
/*
589
* For A-profile AArch32 EL3 (but not M-profile secure mode), if NSACR.CP10
590
* is 0 then CPACR.{CP11,CP10} ignore writes and read as 0b00.
591
+ * Similarly, if NSACR.NSASEDIS is 1 then CPACR.ASEDIS ignores writes
592
+ * and reads as 1.
593
*/
594
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
593
- !arm_is_secure(env) && !FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
594
- mask = R_CPACR_CP11_MASK | R_CPACR_CP10_MASK;
595
- value = (value & ~mask) | (env->cp15.cpacr_el1 & mask);
595
+ !arm_is_secure(env)) {
596
+ if (!FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
597
+ mask = R_CPACR_CP11_MASK | R_CPACR_CP10_MASK;
598
+ value = (value & ~mask) | (env->cp15.cpacr_el1 & mask);
599
+ }
600
+ if (FIELD_EX32(env->cp15.nsacr, NSACR, NSASEDIS)) {
601
+ mask = R_CPACR_ASEDIS_MASK;
602
+ value = (value & ~mask) | (env->cp15.cpacr_el1 & mask);
603
+ }
604
}
605
606
env->cp15.cpacr_el1 = value;
@@ -603,12 +611,18 @@ static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
611
/*
612
* For A-profile AArch32 EL3 (but not M-profile secure mode), if NSACR.CP10
613
* is 0 then CPACR.{CP11,CP10} ignore writes and read as 0b00.
614
+ * Similarly NSACR.NSASEDIS makes CPACR.ASEDIS read as 1.
615
*/
616
uint64_t value = env->cp15.cpacr_el1;
617
618
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
610
- !arm_is_secure(env) && !FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
611
- value = ~(R_CPACR_CP11_MASK | R_CPACR_CP10_MASK);
619
+ !arm_is_secure(env)) {
620
+ if (!FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
621
+ value = ~(R_CPACR_CP11_MASK | R_CPACR_CP10_MASK);
622
+ }
623
+ if (FIELD_EX32(env->cp15.nsacr, NSACR, NSASEDIS)) {
624
+ value |= R_CPACR_ASEDIS_MASK;
625
+ }
626
}
627
return value;
628
}