diff options
Diffstat (limited to 'target/sparc/mmu_helper.c')
-rw-r--r-- | target/sparc/mmu_helper.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c index 77dc86ac5c..e99ed6d3b2 100644 --- a/target/sparc/mmu_helper.c +++ b/target/sparc/mmu_helper.c @@ -98,6 +98,7 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical, int error_code = 0, is_dirty, is_user; unsigned long page_offset; CPUState *cs = env_cpu(env); + MemTxResult result; is_user = mmu_idx == MMU_USER_IDX; @@ -120,7 +121,10 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical, /* SPARC reference MMU table walk: Context table->L1->L2->PTE */ /* Context base + context number */ pde_ptr = (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 4 << 2; /* Translation fault, L = 0 */ + } /* Ctx pde */ switch (pde & PTE_ENTRYTYPE_MASK) { @@ -132,7 +136,11 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical, return 4 << 2; case 1: /* L0 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 (1 << 8) | (4 << 2); /* Translation fault, L = 1 */ + } switch (pde & PTE_ENTRYTYPE_MASK) { default: @@ -142,7 +150,11 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical, return (1 << 8) | (4 << 2); case 1: /* L1 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 (2 << 8) | (4 << 2); /* Translation fault, L = 2 */ + } switch (pde & PTE_ENTRYTYPE_MASK) { default: @@ -152,7 +164,11 @@ static int get_physical_address(CPUSPARCState *env, hwaddr *physical, return (2 << 8) | (4 << 2); case 1: /* L2 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 (3 << 8) | (4 << 2); /* Translation fault, L = 3 */ + } switch (pde & PTE_ENTRYTYPE_MASK) { default: |