aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-03-05 16:09:14 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-03-05 16:09:14 +0000
commit41a4bf1feab098da4cd5495cd56a99b0339e2275 (patch)
treefa64f9c96a37b17494ca27bea9f21f257668b29f /target
parentce5f4f01116b2002925877930d603690296be519 (diff)
target/arm: Implement (trivially) ARMv8.2-TTCNP
The ARMv8.2-TTCNP extension allows an implementation to optimize by sharing TLB entries between multiple cores, provided that software declares that it's ready to deal with this by setting a CnP bit in the TTBRn_ELx. It is mandatory from ARMv8.2 onward. For QEMU's TLB implementation, sharing TLB entries between different cores would not really benefit us and would be a lot of work to implement. So we implement this extension in the "trivial" manner: we allow the guest to set and read back the CnP bit, but don't change our behaviour (this is an architecturally valid implementation choice). The only code path which looks at the TTBRn_ELx values for the long-descriptor format where the CnP bit is defined is already doing enough masking to not get confused when the CnP bit at the bottom of the register is set, so we can simply add a comment noting why we're relying on that mask. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200225193822.18874-1-peter.maydell@linaro.org
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu.c1
-rw-r--r--target/arm/cpu64.c2
-rw-r--r--target/arm/helper.c4
3 files changed, 7 insertions, 0 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index e6016e33ce..de00a45e90 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2702,6 +2702,7 @@ static void arm_max_initfn(Object *obj)
t = cpu->isar.id_mmfr4;
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
cpu->isar.id_mmfr4 = t;
}
#endif
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index b842e2b664..62d36f9e8d 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -677,6 +677,7 @@ static void aarch64_max_initfn(Object *obj)
t = cpu->isar.id_aa64mmfr2;
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
+ t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
cpu->isar.id_aa64mmfr2 = t;
/* Replicate the same data to the 32-bit id registers. */
@@ -704,6 +705,7 @@ static void aarch64_max_initfn(Object *obj)
u = cpu->isar.id_mmfr4;
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
+ u = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
cpu->isar.id_mmfr4 = u;
u = cpu->isar.id_aa64dfr0;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6be9ffa09e..4eaf7333c7 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10591,6 +10591,10 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
/* Now we can extract the actual base address from the TTBR */
descaddr = extract64(ttbr, 0, 48);
+ /*
+ * We rely on this masking to clear the RES0 bits at the bottom of the TTBR
+ * and also to mask out CnP (bit 0) which could validly be non-zero.
+ */
descaddr &= ~indexmask;
/* The address field in the descriptor goes up to bit 39 for ARMv7