diff options
-rw-r--r-- | target-ppc/mmu_helper.c | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index db5c15a926..5b82731133 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -1316,30 +1316,20 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type) { - int ret; + int ret = -1; + bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0) + || (access_type != ACCESS_CODE && msr_dr == 0); #if 0 qemu_log("%s\n", __func__); #endif - if ((access_type == ACCESS_CODE && msr_ir == 0) || - (access_type != ACCESS_CODE && msr_dr == 0)) { - if (env->mmu_model == POWERPC_MMU_BOOKE) { - /* The BookE MMU always performs address translation. The - IS and DS bits only affect the address space. */ - ret = mmubooke_get_physical_address(env, ctx, eaddr, - rw, access_type); - } else if (env->mmu_model == POWERPC_MMU_BOOKE206) { - ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, - access_type); - } else { - /* No address translation. */ + + switch (env->mmu_model) { + case POWERPC_MMU_32B: + case POWERPC_MMU_601: + if (real_mode) { ret = check_physical(env, ctx, eaddr, rw); - } - } else { - ret = -1; - switch (env->mmu_model) { - case POWERPC_MMU_32B: - case POWERPC_MMU_601: + } else { /* Try to find a BAT */ if (env->nb_BATs != 0) { ret = get_bat(env, ctx, eaddr, rw, access_type); @@ -1348,10 +1338,14 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, /* We didn't match any BAT entry or don't have BATs */ ret = get_segment32(env, ctx, eaddr, rw, access_type); } - break; + } + break; - case POWERPC_MMU_SOFT_6xx: - case POWERPC_MMU_SOFT_74xx: + case POWERPC_MMU_SOFT_6xx: + case POWERPC_MMU_SOFT_74xx: + if (real_mode) { + ret = check_physical(env, ctx, eaddr, rw); + } else { /* Try to find a BAT */ if (env->nb_BATs != 0) { ret = get_bat(env, ctx, eaddr, rw, access_type); @@ -1360,40 +1354,52 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, /* We didn't match any BAT entry or don't have BATs */ ret = get_segment_6xx_tlb(env, ctx, eaddr, rw, access_type); } - break; + } + break; #if defined(TARGET_PPC64) - case POWERPC_MMU_64B: - case POWERPC_MMU_2_06: - case POWERPC_MMU_2_06d: + case POWERPC_MMU_64B: + case POWERPC_MMU_2_06: + case POWERPC_MMU_2_06d: + if (real_mode) { + ret = check_physical(env, ctx, eaddr, rw); + } else { ret = get_segment64(env, ctx, eaddr, rw, access_type); - break; + } + break; #endif - case POWERPC_MMU_SOFT_4xx: - case POWERPC_MMU_SOFT_4xx_Z: + case POWERPC_MMU_SOFT_4xx: + case POWERPC_MMU_SOFT_4xx_Z: + if (real_mode) { + ret = check_physical(env, ctx, eaddr, rw); + } else { ret = mmu40x_get_physical_address(env, ctx, eaddr, rw, access_type); - break; - case POWERPC_MMU_BOOKE: - ret = mmubooke_get_physical_address(env, ctx, eaddr, - rw, access_type); - break; - case POWERPC_MMU_BOOKE206: - ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, + } + break; + case POWERPC_MMU_BOOKE: + ret = mmubooke_get_physical_address(env, ctx, eaddr, + rw, access_type); + break; + case POWERPC_MMU_BOOKE206: + ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, access_type); - break; - case POWERPC_MMU_MPC8xx: - /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); - break; - case POWERPC_MMU_REAL: + break; + case POWERPC_MMU_MPC8xx: + /* XXX: TODO */ + cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + break; + case POWERPC_MMU_REAL: + if (real_mode) { + ret = check_physical(env, ctx, eaddr, rw); + } else { cpu_abort(env, "PowerPC in real mode do not do any translation\n"); - return -1; - default: - cpu_abort(env, "Unknown or invalid MMU model\n"); - return -1; } + return -1; + default: + cpu_abort(env, "Unknown or invalid MMU model\n"); + return -1; } #if 0 qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n", |