mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-11 11:25:31 +00:00
target/arm: Convert get_phys_addr_lpae() to not return FSC values
Make get_phys_addr_v6() return a fault type in the ARMMMUFaultInfo structure, which we convert to the FSC at the callsite. Backports commit da909b2c23a68e57bbcb6be98229e40df606f0c8 from qemu
This commit is contained in:
parent
c6496ec00a
commit
013e7873ee
|
@ -26,7 +26,7 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||||
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
||||||
target_ulong *page_size_ptr, uint32_t *fsr,
|
target_ulong *page_size_ptr,
|
||||||
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
|
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
|
||||||
|
|
||||||
/* Security attributes for an address, as returned by v8m_security_lookup. */
|
/* Security attributes for an address, as returned by v8m_security_lookup. */
|
||||||
|
@ -7465,10 +7465,9 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
|
||||||
hwaddr s2pa;
|
hwaddr s2pa;
|
||||||
int s2prot;
|
int s2prot;
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t fsr;
|
|
||||||
|
|
||||||
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
|
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
|
||||||
&txattrs, &s2prot, &s2size, &fsr, fi, NULL);
|
&txattrs, &s2prot, &s2size, fi, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
fi->s2addr = addr;
|
fi->s2addr = addr;
|
||||||
fi->stage2 = true;
|
fi->stage2 = true;
|
||||||
|
@ -7791,15 +7790,6 @@ do_fault:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fault type for long-descriptor MMU fault reporting; this corresponds
|
|
||||||
* to bits [5..2] in the STATUS field in long-format DFSR/IFSR.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
translation_fault = 1,
|
|
||||||
access_fault = 2,
|
|
||||||
permission_fault = 3,
|
|
||||||
} MMUFaultType;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check_s2_mmu_setup
|
* check_s2_mmu_setup
|
||||||
* @cpu: ARMCPU
|
* @cpu: ARMCPU
|
||||||
|
@ -7901,13 +7891,13 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
|
||||||
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
||||||
target_ulong *page_size_ptr, uint32_t *fsr,
|
target_ulong *page_size_ptr,
|
||||||
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
|
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
|
||||||
{
|
{
|
||||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||||
CPUState *cs = CPU(cpu);
|
CPUState *cs = CPU(cpu);
|
||||||
/* Read an LPAE long-descriptor translation table. */
|
/* Read an LPAE long-descriptor translation table. */
|
||||||
MMUFaultType fault_type = translation_fault;
|
ARMFaultType fault_type = ARMFault_Translation;
|
||||||
uint32_t level;
|
uint32_t level;
|
||||||
uint32_t epd = 0;
|
uint32_t epd = 0;
|
||||||
int32_t t0sz, t1sz;
|
int32_t t0sz, t1sz;
|
||||||
|
@ -8017,7 +8007,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
ttbr_select = 1;
|
ttbr_select = 1;
|
||||||
} else {
|
} else {
|
||||||
/* in the gap between the two regions, this is a Translation fault */
|
/* in the gap between the two regions, this is a Translation fault */
|
||||||
fault_type = translation_fault;
|
fault_type = ARMFault_Translation;
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8103,7 +8093,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
|
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
|
||||||
inputsize, stride);
|
inputsize, stride);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
fault_type = translation_fault;
|
fault_type = ARMFault_Translation;
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
level = startlevel;
|
level = startlevel;
|
||||||
|
@ -8188,7 +8178,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
/* Here descaddr is the final physical address, and attributes
|
/* Here descaddr is the final physical address, and attributes
|
||||||
* are all in attrs.
|
* are all in attrs.
|
||||||
*/
|
*/
|
||||||
fault_type = access_fault;
|
fault_type = ARMFault_AccessFlag;
|
||||||
if ((attrs & (1 << 8)) == 0) {
|
if ((attrs & (1 << 8)) == 0) {
|
||||||
/* Access flag */
|
/* Access flag */
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
|
@ -8206,7 +8196,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
|
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
|
||||||
}
|
}
|
||||||
|
|
||||||
fault_type = permission_fault;
|
fault_type = ARMFault_Permission;
|
||||||
if (!(*prot & (1 << access_type))) {
|
if (!(*prot & (1 << access_type))) {
|
||||||
/* Unprivileged access not enabled */
|
/* Unprivileged access not enabled */
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
|
@ -8239,10 +8229,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
do_fault:
|
do_fault:
|
||||||
/* Long-descriptor format IFSR/DFSR value */
|
fi->type = fault_type;
|
||||||
*fsr = (1 << 9) | (fault_type << 2) | level;
|
fi->level = level;
|
||||||
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
|
|
||||||
fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_S2NS);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8961,8 +8949,9 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||||
/* S1 is done. Now do S2 translation. */
|
/* S1 is done. Now do S2 translation. */
|
||||||
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS,
|
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS,
|
||||||
phys_ptr, attrs, &s2_prot,
|
phys_ptr, attrs, &s2_prot,
|
||||||
page_size, fsr, fi,
|
page_size, fi,
|
||||||
cacheattrs != NULL ? &cacheattrs2 : NULL);
|
cacheattrs != NULL ? &cacheattrs2 : NULL);
|
||||||
|
*fsr = arm_fi_to_lfsc(fi);
|
||||||
fi->s2addr = ipa;
|
fi->s2addr = ipa;
|
||||||
/* Combine the S1 and S2 perms. */
|
/* Combine the S1 and S2 perms. */
|
||||||
*prot &= s2_prot;
|
*prot &= s2_prot;
|
||||||
|
@ -9040,8 +9029,12 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regime_using_lpae_format(env, mmu_idx)) {
|
if (regime_using_lpae_format(env, mmu_idx)) {
|
||||||
return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
|
bool ret = get_phys_addr_lpae(env, address, access_type, mmu_idx,
|
||||||
attrs, prot, page_size, fsr, fi, cacheattrs);
|
phys_ptr, attrs, prot, page_size,
|
||||||
|
fi, cacheattrs);
|
||||||
|
|
||||||
|
*fsr = arm_fi_to_lfsc(fi);
|
||||||
|
return ret;
|
||||||
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
|
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
|
||||||
bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
|
bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
|
||||||
phys_ptr, attrs, prot, page_size, fi);
|
phys_ptr, attrs, prot, page_size, fi);
|
||||||
|
|
Loading…
Reference in a new issue