Skip to content

Commit

Permalink
target/sparc: Handle bus errors in mmu_probe()
Browse files Browse the repository at this point in the history
Convert the mmu_probe() function to using address_space_ldl()
rather than ldl_phys(), so we can explicitly detect memory
transaction failures.

This makes no practical difference at the moment, because
ldl_phys() will return 0 on a transaction failure, and we
treat transaction failures and 0 PDEs identically. However
the spec says that MMU probe operations are supposed to
update the fault status registers, and if we ever implement
that we'll want to distinguish the difference. For the
moment, just add a TODO comment about the bug.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-id: 20190801183012.17564-6-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Sep 17, 2019
1 parent 3c818df commit d86a9ad
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions target/sparc/mmu_helper.c
Expand Up @@ -288,11 +288,20 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
CPUState *cs = env_cpu(env);
hwaddr pde_ptr;
uint32_t pde;
MemTxResult result;

/*
* TODO: MMU probe operations are supposed to set the fault
* status registers, but we don't do this.
*/

/* Context base + context number */
pde_ptr = (hwaddr)(env->mmuregs[1] << 4) +
(env->mmuregs[2] << 2);
pde = ldl_phys(cs->as, pde_ptr);
pde = address_space_ldl(cs->as, pde_ptr, MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) {
return 0;
}

switch (pde & PTE_ENTRYTYPE_MASK) {
default:
Expand All @@ -305,7 +314,11 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
return pde;
}
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
pde = ldl_phys(cs->as, pde_ptr);
pde = address_space_ldl(cs->as, pde_ptr,
MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) {
return 0;
}

switch (pde & PTE_ENTRYTYPE_MASK) {
default:
Expand All @@ -319,7 +332,11 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
return pde;
}
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
pde = ldl_phys(cs->as, pde_ptr);
pde = address_space_ldl(cs->as, pde_ptr,
MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) {
return 0;
}

switch (pde & PTE_ENTRYTYPE_MASK) {
default:
Expand All @@ -333,7 +350,11 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
return pde;
}
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
pde = ldl_phys(cs->as, pde_ptr);
pde = address_space_ldl(cs->as, pde_ptr,
MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) {
return 0;
}

switch (pde & PTE_ENTRYTYPE_MASK) {
default:
Expand Down

0 comments on commit d86a9ad

Please sign in to comment.