aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/mmu-hash32.c34
-rw-r--r--target-ppc/mmu-hash64.c19
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,