diff options
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/mmu-hash32.c | 34 | ||||
-rw-r--r-- | target-ppc/mmu-hash64.c | 19 |
2 files changed, 43 insertions, 10 deletions
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c index 07e9b8c85f..5ec1a0942c 100644 --- a/target-ppc/mmu-hash32.c +++ b/target-ppc/mmu-hash32.c @@ -437,18 +437,38 @@ static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx, return 0; } -hwaddr ppc_hash32_get_phys_page_debug(CPUPPCState *env, target_ulong addr) +hwaddr ppc_hash32_get_phys_page_debug(CPUPPCState *env, target_ulong eaddr) { - struct mmu_ctx_hash32 ctx; + target_ulong sr; + hwaddr pte_offset; + ppc_hash_pte32_t pte; + int prot; + + if (msr_dr == 0) { + /* Translation is off */ + return eaddr; + } + + if (env->nb_BATs != 0) { + hwaddr raddr = ppc_hash32_bat_lookup(env, eaddr, 0, &prot); + if (raddr != -1) { + return raddr; + } + } + + sr = env->sr[eaddr >> 28]; + + if (sr & SR32_T) { + /* FIXME: Add suitable debug support for Direct Store segments */ + return -1; + } - /* FIXME: Will not behave sanely for direct store segments, but - * they're almost never used */ - if (unlikely(ppc_hash32_translate(env, &ctx, addr, 0) - != 0)) { + pte_offset = ppc_hash32_htab_lookup(env, sr, eaddr, &pte); + if (pte_offset == -1) { return -1; } - return ctx.raddr & TARGET_PAGE_MASK; + return ppc_hash32_pte_raddr(sr, pte, eaddr) & TARGET_PAGE_MASK; } int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rwx, diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index d986c0fd57..4a7dbbb95b 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -449,13 +449,26 @@ static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx, hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr) { - struct mmu_ctx_hash64 ctx; + ppc_slb_t *slb; + hwaddr pte_offset; + ppc_hash_pte64_t pte; + + if (msr_dr == 0) { + /* In real mode the top 4 effective address bits are ignored */ + return addr & 0x0FFFFFFFFFFFFFFFULL; + } - if (unlikely(ppc_hash64_translate(env, &ctx, addr, 0) != 0)) { + slb = slb_lookup(env, addr); + if (!slb) { + return -1; + } + + pte_offset = ppc_hash64_htab_lookup(env, slb, addr, &pte); + if (pte_offset == -1) { return -1; } - return ctx.raddr & TARGET_PAGE_MASK; + return ppc_hash64_pte_raddr(slb, pte, addr) & TARGET_PAGE_MASK; } int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rwx, |