diff options
-rw-r--r-- | target-ppc/mmu-hash32.c | 98 | ||||
-rw-r--r-- | target-ppc/mmu-hash64.c | 68 |
2 files changed, 83 insertions, 83 deletions
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c index dbde264..d812adb 100644 --- a/target-ppc/mmu-hash32.c +++ b/target-ppc/mmu-hash32.c @@ -466,10 +466,16 @@ static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx, &ctx->raddr, &ctx->prot); } + /* 5. Check for segment level no-execute violation */ + ctx->nx = !!(sr & SR32_NX); + if ((rwx == 2) && ctx->nx) { + return -3; + } + pr = msr_pr; ctx->key = (((sr & SR32_KP) && (pr != 0)) || ((sr & SR32_KS) && (pr == 0))) ? 1 : 0; - ctx->nx = !!(sr & SR32_NX); + vsid = sr & SR32_VSID; target_page_bits = TARGET_PAGE_BITS; LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip=" @@ -485,59 +491,53 @@ static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx, ctx->key, ctx->nx, vsid); ret = -1; - /* Check if instruction fetch is allowed, if needed */ - if (rwx != 2 || ctx->nx == 0) { - /* Page address translation */ - LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx - " hash " TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, hash); - ctx->hash[0] = hash; - ctx->hash[1] = ~hash; - - /* Initialize real address with an invalid value */ - ctx->raddr = (hwaddr)-1ULL; - LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx - " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx - " hash=" TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, vsid, ctx->ptem, - ctx->hash[0]); - /* Primary table lookup */ - ret = find_pte32(env, ctx, eaddr, 0, rwx, target_page_bits); - if (ret < 0) { - /* Secondary table lookup */ - LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx - " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx - " hash=" TARGET_FMT_plx "\n", env->htab_base, - env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); - ret2 = find_pte32(env, ctx, eaddr, 1, rwx, target_page_bits); - if (ret2 != -1) { - ret = ret2; - } + /* Page address translation */ + LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx + " hash " TARGET_FMT_plx "\n", + env->htab_base, env->htab_mask, hash); + ctx->hash[0] = hash; + ctx->hash[1] = ~hash; + + /* Initialize real address with an invalid value */ + ctx->raddr = (hwaddr)-1ULL; + LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx + " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx + " hash=" TARGET_FMT_plx "\n", + env->htab_base, env->htab_mask, vsid, ctx->ptem, + ctx->hash[0]); + /* Primary table lookup */ + ret = find_pte32(env, ctx, eaddr, 0, rwx, target_page_bits); + if (ret < 0) { + /* Secondary table lookup */ + LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx + " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx + " hash=" TARGET_FMT_plx "\n", env->htab_base, + env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); + ret2 = find_pte32(env, ctx, eaddr, 1, rwx, target_page_bits); + if (ret2 != -1) { + ret = ret2; } + } #if defined(DUMP_PAGE_TABLES) - if (qemu_log_enabled()) { - hwaddr curaddr; - uint32_t a0, a1, a2, a3; - - qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx - "\n", sdr, mask + 0x80); - for (curaddr = sdr; curaddr < (sdr + mask + 0x80); - curaddr += 16) { - a0 = ldl_phys(curaddr); - a1 = ldl_phys(curaddr + 4); - a2 = ldl_phys(curaddr + 8); - a3 = ldl_phys(curaddr + 12); - if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { - qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n", - curaddr, a0, a1, a2, a3); - } + if (qemu_log_enabled()) { + hwaddr curaddr; + uint32_t a0, a1, a2, a3; + + qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx + "\n", sdr, mask + 0x80); + for (curaddr = sdr; curaddr < (sdr + mask + 0x80); + curaddr += 16) { + a0 = ldl_phys(curaddr); + a1 = ldl_phys(curaddr + 4); + a2 = ldl_phys(curaddr + 8); + a3 = ldl_phys(curaddr + 12); + if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { + qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n", + curaddr, a0, a1, a2, a3); } } -#endif - } else { - LOG_MMU("No access allowed\n"); - ret = -3; } +#endif return ret; } diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index 9afc418..4fb7ecd 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -454,14 +454,20 @@ static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx, return 0; } - pr = msr_pr; - - LOG_MMU("Check SLBs\n"); + /* 2. Translation is on, so look up the SLB */ slb = slb_lookup(env, eaddr); + if (!slb) { return -5; } + /* 3. Check for segment level no-execute violation */ + if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) { + return -3; + } + + pr = msr_pr; + if (slb->vsid & SLB_VSID_B) { vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T; segment_bits = 40; @@ -490,38 +496,32 @@ static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx, ctx->key, !!(slb->vsid & SLB_VSID_N), vsid); ret = -1; - /* Check if instruction fetch is allowed, if needed */ - if (rwx != 2 || !(slb->vsid & SLB_VSID_N)) { - /* Page address translation */ - LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx - " hash " TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, hash); - ctx->hash[0] = hash; - ctx->hash[1] = ~hash; - - /* Initialize real address with an invalid value */ - ctx->raddr = (hwaddr)-1ULL; - LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx - " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx - " hash=" TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, vsid, ctx->ptem, - ctx->hash[0]); - /* Primary table lookup */ - ret = find_pte64(env, ctx, eaddr, 0, rwx, target_page_bits); - if (ret < 0) { - /* Secondary table lookup */ - LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx - " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx - " hash=" TARGET_FMT_plx "\n", env->htab_base, - env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); - ret2 = find_pte64(env, ctx, eaddr, 1, rwx, target_page_bits); - if (ret2 != -1) { - ret = ret2; - } + /* Page address translation */ + LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx + " hash " TARGET_FMT_plx "\n", + env->htab_base, env->htab_mask, hash); + ctx->hash[0] = hash; + ctx->hash[1] = ~hash; + + /* Initialize real address with an invalid value */ + ctx->raddr = (hwaddr)-1ULL; + LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx + " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx + " hash=" TARGET_FMT_plx "\n", + env->htab_base, env->htab_mask, vsid, ctx->ptem, + ctx->hash[0]); + /* Primary table lookup */ + ret = find_pte64(env, ctx, eaddr, 0, rwx, target_page_bits); + if (ret < 0) { + /* Secondary table lookup */ + LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx + " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx + " hash=" TARGET_FMT_plx "\n", env->htab_base, + env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); + ret2 = find_pte64(env, ctx, eaddr, 1, rwx, target_page_bits); + if (ret2 != -1) { + ret = ret2; } - } else { - LOG_MMU("No access allowed\n"); - ret = -3; } return ret; |