static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type) { int ret; #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. */ ret = check_physical(env, ctx, eaddr, rw); } } else { ret = -1; switch (env->mmu_model) { case POWERPC_MMU_32B: case POWERPC_MMU_601: /* Try to find a BAT */ if (env->nb_BATs != 0) { ret = get_bat(env, ctx, eaddr, rw, access_type); } if (ret < 0) { /* We didn't match any BAT entry or don't have BATs */ ret = get_segment32(env, ctx, eaddr, rw, access_type); } break; case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_74xx: /* Try to find a BAT */ if (env->nb_BATs != 0) { ret = get_bat(env, ctx, eaddr, rw, access_type); } if (ret < 0) { /* We didn't match any BAT entry or don't have BATs */ ret = get_segment_6xx_tlb(env, ctx, eaddr, rw, access_type); } break; #if defined(TARGET_PPC64) case POWERPC_MMU_64B: case POWERPC_MMU_2_06: case POWERPC_MMU_2_06d: ret = get_segment64(env, ctx, eaddr, rw, access_type); break; #endif case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: 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, access_type); break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_REAL: 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; } } #if 0 qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n", __func__, eaddr, ret, ctx->raddr); #endif return ret; }