summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell2022-07-14 15:23:03 +0200
committerPeter Maydell2022-07-18 14:20:14 +0200
commitf04383e74926180cc56809ec8319115e4cea32b7 (patch)
treebb44dd60a8585a18fd45589363a409d626a92719 /target
parenttarget/arm: Store TCR_EL* registers as uint64_t (diff)
downloadqemu-f04383e74926180cc56809ec8319115e4cea32b7.tar.gz
qemu-f04383e74926180cc56809ec8319115e4cea32b7.tar.xz
qemu-f04383e74926180cc56809ec8319115e4cea32b7.zip
target/arm: Honour VTCR_EL2 bits in Secure EL2
In regime_tcr() we return the appropriate TCR register for the translation regime. For Secure EL2, we return the VSTCR_EL2 value, but in this translation regime some fields that control behaviour are in VTCR_EL2. When this code was originally written (as the comment notes), QEMU didn't care about any of those fields, but we have since added support for features such as LPA2 which do need the values from those fields. Synthesize a TCR value by merging in the relevant VTCR_EL2 fields to the VSTCR_EL2 value. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1103 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220714132303.1287193-8-peter.maydell@linaro.org
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu.h19
-rw-r--r--target/arm/internals.h22
2 files changed, 38 insertions, 3 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index b43083c5ef..e890ee074d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1412,6 +1412,25 @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
#define TTBCR_SH1 (1U << 28)
#define TTBCR_EAE (1U << 31)
+FIELD(VTCR, T0SZ, 0, 6)
+FIELD(VTCR, SL0, 6, 2)
+FIELD(VTCR, IRGN0, 8, 2)
+FIELD(VTCR, ORGN0, 10, 2)
+FIELD(VTCR, SH0, 12, 2)
+FIELD(VTCR, TG0, 14, 2)
+FIELD(VTCR, PS, 16, 3)
+FIELD(VTCR, VS, 19, 1)
+FIELD(VTCR, HA, 21, 1)
+FIELD(VTCR, HD, 22, 1)
+FIELD(VTCR, HWU59, 25, 1)
+FIELD(VTCR, HWU60, 26, 1)
+FIELD(VTCR, HWU61, 27, 1)
+FIELD(VTCR, HWU62, 28, 1)
+FIELD(VTCR, NSW, 29, 1)
+FIELD(VTCR, NSA, 30, 1)
+FIELD(VTCR, DS, 32, 1)
+FIELD(VTCR, SL2, 33, 1)
+
/* Bit definitions for ARMv8 SPSR (PSTATE) format.
* Only these are valid when in AArch64 mode; in
* AArch32 mode SPSRs are basically CPSR-format.
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 742135ef14..b8fefdff67 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -777,6 +777,16 @@ static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
return env->cp15.sctlr_el[regime_el(env, mmu_idx)];
}
+/*
+ * These are the fields in VTCR_EL2 which affect both the Secure stage 2
+ * and the Non-Secure stage 2 translation regimes (and hence which are
+ * not present in VSTCR_EL2).
+ */
+#define VTCR_SHARED_FIELD_MASK \
+ (R_VTCR_IRGN0_MASK | R_VTCR_ORGN0_MASK | R_VTCR_SH0_MASK | \
+ R_VTCR_PS_MASK | R_VTCR_VS_MASK | R_VTCR_HA_MASK | R_VTCR_HD_MASK | \
+ R_VTCR_DS_MASK)
+
/* Return the value of the TCR controlling this translation regime */
static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
{
@@ -785,10 +795,16 @@ static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
}
if (mmu_idx == ARMMMUIdx_Stage2_S) {
/*
- * Note: Secure stage 2 nominally shares fields from VTCR_EL2, but
- * those are not currently used by QEMU, so just return VSTCR_EL2.
+ * Secure stage 2 shares fields from VTCR_EL2. We merge those
+ * in with the VSTCR_EL2 value to synthesize a single VTCR_EL2 format
+ * value so the callers don't need to special case this.
+ *
+ * If a future architecture change defines bits in VSTCR_EL2 that
+ * overlap with these VTCR_EL2 fields we may need to revisit this.
*/
- return env->cp15.vstcr_el2;
+ uint64_t v = env->cp15.vstcr_el2 & ~VTCR_SHARED_FIELD_MASK;
+ v |= env->cp15.vtcr_el2 & VTCR_SHARED_FIELD_MASK;
+ return v;
}
return env->cp15.tcr_el[regime_el(env, mmu_idx)];
}