summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-ppc/mmu_helper.c98
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",