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
This commit is contained in:
Peter Maydell 2023-08-22 17:31:10 +01:00
parent a729d63642
commit b17d86eb5e

View File

@ -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);