target/arm: Don't do MPU lookups for addresses in M profile PPB region

The M profile PMSAv7 specification says that if the address being looked
up is in the PPB region (0xe0000000 - 0xe00fffff) then we do not use
the MPU regions but always use the default memory map. Implement this
(we were previously behaving like an R profile PMSAv7, which does not
special case this).

Backports commit 38aaa60ca464b48e6feef346709e97335d01b289 from qemu
This commit is contained in:
Peter Maydell 2018-03-04 01:14:20 -05:00 committed by Lioncash
parent 4dc69f4b26
commit 34b9740081
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -7512,6 +7512,13 @@ static bool pmsav7_use_background_region(ARMCPU *cpu,
} }
} }
static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address)
{
/* True if address is in the M profile PPB region 0xe0000000 - 0xe00fffff */
return arm_feature(env, ARM_FEATURE_M) &&
extract32(address, 20, 12) == 0xe00;
}
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
int access_type, ARMMMUIdx mmu_idx, int access_type, ARMMMUIdx mmu_idx,
hwaddr *phys_ptr, int *prot, uint32_t *fsr) hwaddr *phys_ptr, int *prot, uint32_t *fsr)
@ -7523,7 +7530,15 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
*phys_ptr = address; *phys_ptr = address;
*prot = 0; *prot = 0;
if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ if (regime_translation_disabled(env, mmu_idx) ||
m_is_ppb_region(env, address)) {
/* MPU disabled or M profile PPB access: use default memory map.
* The other case which uses the default memory map in the
* v7M ARM ARM pseudocode is exception vector reads from the vector
* table. In QEMU those accesses are done in arm_v7m_load_vector(),
* which always does a direct read using address_space_ldl(), rather
* than going via this function, so we don't need to check that here.
*/
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
} else { /* MPU enabled */ } else { /* MPU enabled */
for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {