diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2023-08-22 17:24:22 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-08-22 17:24:22 +0100 |
commit | 6b8fa0caa316ef7d491c4efd4a83d552f156e8f5 (patch) | |
tree | 725568396fc01c97e0d21c18e2a77e66d8153ff7 | |
parent | 9ece5bab65d739c37dd8ed6e89c05b550ea56ee9 (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.c | 15 |
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); |