aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-08-22 17:24:22 +0100
committerPeter Maydell <peter.maydell@linaro.org>2023-08-22 17:24:22 +0100
commit6b8fa0caa316ef7d491c4efd4a83d552f156e8f5 (patch)
tree725568396fc01c97e0d21c18e2a77e66d8153ff7
parent9ece5bab65d739c37dd8ed6e89c05b550ea56ee9 (diff)
target/arm: Adjust PAR_EL1.SH for Device and Normal-NC memory types
The PAR_EL1.SH field documents that for the cases of: * Device memory * Normal memory with both Inner and Outer Non-Cacheable the field should be 0b10 rather than whatever was in the translation table descriptor field. (In the pseudocode this is handled by PAREncodeShareability().) Perform this adjustment when assembling a PAR value. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230807141514.19075-16-peter.maydell@linaro.org
-rw-r--r--target/arm/helper.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8290ca0aaa..da5db6d3ff 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3342,6 +3342,19 @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
}
#ifdef CONFIG_TCG
+static int par_el1_shareability(GetPhysAddrResult *res)
+{
+ /*
+ * The PAR_EL1.SH field must be 0b10 for Device or Normal-NC
+ * memory -- see pseudocode PAREncodeShareability().
+ */
+ if (((res->cacheattrs.attrs & 0xf0) == 0) ||
+ res->cacheattrs.attrs == 0x44 || res->cacheattrs.attrs == 0x40) {
+ return 2;
+ }
+ return res->cacheattrs.shareability;
+}
+
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
bool is_secure)
@@ -3470,7 +3483,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
par64 |= (1 << 9); /* NS */
}
par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */
- par64 |= res.cacheattrs.shareability << 7; /* SH */
+ par64 |= par_el1_shareability(&res) << 7; /* SH */
} else {
uint32_t fsr = arm_fi_to_lfsc(&fi);