target/arm: Extend PAR format determination

Now that do_ats_write() is entirely in control of whether to
generate a 32-bit PAR or a 64-bit PAR, we can make it use the
correct (complicated) condition for doing so.

Backports commit 1313e2d7e2cd8b21741e0cf542eb09dfc4188f79 from qemu
This commit is contained in:
Edgar E. Iglesias 2018-03-05 14:08:43 -05:00 committed by Lioncash
parent 0dfb84ea50
commit 60136b485c
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 31 additions and 8 deletions

View file

@ -1925,16 +1925,41 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
int prot; int prot;
bool ret; bool ret;
uint64_t par64; uint64_t par64;
bool format64 = false;
MemTxAttrs attrs = {0}; MemTxAttrs attrs = {0};
ARMMMUFaultInfo fi = {0}; ARMMMUFaultInfo fi = {0};
ARMCacheAttrs cacheattrs = {0}; ARMCacheAttrs cacheattrs = {0};
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs, ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
&prot, &page_size, &fi, &cacheattrs); &prot, &page_size, &fi, &cacheattrs);
/* TODO: this is not the correct condition to use to decide whether
* to report a PAR in 64-bit or 32-bit format. if (is_a64(env)) {
*/ format64 = true;
if (arm_s1_regime_using_lpae_format(env, mmu_idx)) { } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
/*
* ATS1Cxx:
* * TTBCR.EAE determines whether the result is returned using the
* 32-bit or the 64-bit PAR format
* * Instructions executed in Hyp mode always use the 64bit format
*
* ATS1S2NSOxx uses the 64bit format if any of the following is true:
* * The Non-secure TTBCR.EAE bit is set to 1
* * The implementation includes EL2, and the value of HCR.VM is 1
*
* ATS1Hx always uses the 64bit format (not supported yet).
*/
format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
if (arm_feature(env, ARM_FEATURE_EL2)) {
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
format64 |= env->cp15.hcr_el2 & HCR_VM;
} else {
format64 |= arm_current_el(env) == 2;
}
}
}
if (format64) {
/* Create a 64-bit PAR */ /* Create a 64-bit PAR */
par64 = (1 << 11); /* LPAE bit always set */ par64 = (1 << 11); /* LPAE bit always set */
if (!ret) { if (!ret) {
@ -9045,7 +9070,6 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
return get_phys_addr_lpae(env, address, access_type, mmu_idx, return get_phys_addr_lpae(env, address, access_type, mmu_idx,
phys_ptr, attrs, prot, page_size, phys_ptr, attrs, prot, page_size,
fi, cacheattrs); fi, cacheattrs);
return ret;
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) { } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
return get_phys_addr_v6(env, address, access_type, mmu_idx, return get_phys_addr_v6(env, address, access_type, mmu_idx,
phys_ptr, attrs, prot, page_size, fi); phys_ptr, attrs, prot, page_size, fi);

View file

@ -692,7 +692,7 @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
/* Do a page table walk and add page to TLB if possible */ /* Do a page table walk and add page to TLB if possible */
bool arm_tlb_fill(CPUState *cpu, vaddr address, bool arm_tlb_fill(CPUState *cpu, vaddr address,
MMUAccessType access_type, int mmu_idx, MMUAccessType access_type, int mmu_idx,
uint32_t *fsr, ARMMMUFaultInfo *fi); ARMMMUFaultInfo *fi);
/* Return true if the stage 1 translation regime is using LPAE format page /* Return true if the stage 1 translation regime is using LPAE format page
* tables */ * tables */

View file

@ -175,10 +175,9 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr) int mmu_idx, uintptr_t retaddr)
{ {
bool ret; bool ret;
uint32_t fsr = 0;
ARMMMUFaultInfo fi = {0}; ARMMMUFaultInfo fi = {0};
ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi); ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fi);
if (unlikely(ret)) { if (unlikely(ret)) {
ARMCPU *cpu = ARM_CPU(cs->uc, cs); ARMCPU *cpu = ARM_CPU(cs->uc, cs);