diff options
Diffstat (limited to 'target/ppc/mmu_helper.c')
| -rw-r--r-- | target/ppc/mmu_helper.c | 325 |
1 files changed, 122 insertions, 203 deletions
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index ca88658cba..37986c59ba 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -32,6 +32,7 @@ #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/qemu-print.h" +#include "internal.h" #include "mmu-book3s-v3.h" #include "mmu-radix64.h" @@ -126,36 +127,14 @@ static int pp_check(int key, int pp, int nx) return access; } -static int check_prot(int prot, int rw, int access_type) +static int check_prot(int prot, MMUAccessType access_type) { - int ret; - - if (access_type == ACCESS_CODE) { - if (prot & PAGE_EXEC) { - ret = 0; - } else { - ret = -2; - } - } else if (rw) { - if (prot & PAGE_WRITE) { - ret = 0; - } else { - ret = -2; - } - } else { - if (prot & PAGE_READ) { - ret = 0; - } else { - ret = -2; - } - } - - return ret; + return prot & prot_for_access_type(access_type) ? 0 : -2; } -static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0, - target_ulong pte1, int h, - int rw, int type) +static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0, + target_ulong pte1, int h, + MMUAccessType access_type) { target_ulong ptem, mmask; int access, ret, pteh, ptev, pp; @@ -182,7 +161,7 @@ static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0, /* Keep the matching PTE information */ ctx->raddr = pte1; ctx->prot = access; - ret = check_prot(ctx->prot, rw, type); + ret = check_prot(ctx->prot, access_type); if (ret == 0) { /* Access granted */ qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n"); @@ -197,7 +176,7 @@ static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0, } static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p, - int ret, int rw) + int ret, MMUAccessType access_type) { int store = 0; @@ -208,7 +187,7 @@ static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p, store = 1; } if (!(*pte1p & 0x00000080)) { - if (rw == 1 && ret == 0) { + if (access_type == MMU_DATA_STORE && ret == 0) { /* Update changed flag */ *pte1p |= 0x00000080; store = 1; @@ -308,8 +287,8 @@ static void ppc6xx_tlb_store(CPUPPCState *env, target_ulong EPN, int way, env->last_way = way; } -static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong eaddr, int rw, int access_type) +static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, + target_ulong eaddr, MMUAccessType access_type) { ppc6xx_tlb_t *tlb; int nr, best, way; @@ -318,8 +297,7 @@ static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, best = -1; ret = -1; /* No TLB found */ for (way = 0; way < env->nb_ways; way++) { - nr = ppc6xx_tlb_getnum(env, eaddr, way, - access_type == ACCESS_CODE ? 1 : 0); + nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == MMU_INST_FETCH); tlb = &env->tlb.tlb6[nr]; /* This test "emulates" the PTE index match for hardware TLBs */ if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { @@ -333,9 +311,10 @@ static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb, pte_is_valid(tlb->pte0) ? "valid" : "inval", tlb->EPN, eaddr, tlb->pte1, - rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D'); + access_type == MMU_DATA_STORE ? 'S' : 'L', + access_type == MMU_INST_FETCH ? 'I' : 'D'); switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1, - 0, rw, access_type)) { + 0, access_type)) { case -3: /* TLB inconsistency */ return -1; @@ -366,7 +345,7 @@ static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n", ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret); /* Update page flags */ - pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, rw); + pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type); } return ret; @@ -400,24 +379,22 @@ static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, } static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong virtual, int rw, int type) + target_ulong virtual, MMUAccessType access_type) { target_ulong *BATlt, *BATut, *BATu, *BATl; target_ulong BEPIl, BEPIu, bl; int i, valid, prot; int ret = -1; + bool ifetch = access_type == MMU_INST_FETCH; LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__, - type == ACCESS_CODE ? 'I' : 'D', virtual); - switch (type) { - case ACCESS_CODE: + ifetch ? 'I' : 'D', virtual); + if (ifetch) { BATlt = env->IBAT[1]; BATut = env->IBAT[0]; - break; - default: + } else { BATlt = env->DBAT[1]; BATut = env->DBAT[0]; - break; } for (i = 0; i < env->nb_BATs; i++) { BATu = &BATut[i]; @@ -427,7 +404,7 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, bat_size_prot(env, &bl, &valid, &prot, BATu, BATl); LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__, - type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl); + ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl); if ((virtual & 0xF0000000) == BEPIu && ((virtual & 0x0FFE0000) & ~bl) == BEPIl) { /* BAT matches */ @@ -438,7 +415,7 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, (virtual & 0x0001F000); /* Compute access rights */ ctx->prot = prot; - ret = check_prot(ctx->prot, rw, type); + ret = check_prot(ctx->prot, access_type); if (ret == 0) { LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n", i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-', @@ -461,7 +438,7 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx "\n", - __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual, + __func__, ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl, BEPIu, BEPIl, bl); } } @@ -472,8 +449,9 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, } /* Perform segment based translation */ -static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong eaddr, int rw, int type) +static int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, + target_ulong eaddr, MMUAccessType access_type, + int type) { PowerPCCPU *cpu = env_archcpu(env); hwaddr hash; @@ -497,7 +475,7 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx " ir=%d dr=%d pr=%d %d t=%d\n", eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir, - (int)msr_dr, pr != 0 ? 1 : 0, rw, type); + (int)msr_dr, pr != 0 ? 1 : 0, access_type == MMU_DATA_STORE, type); pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits; hash = vsid ^ pgidx; ctx->ptem = (vsid << 7) | (pgidx >> 10); @@ -520,7 +498,7 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, /* Initialize real address with an invalid value */ ctx->raddr = (hwaddr)-1ULL; /* Software TLB search */ - ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); + ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type); #if defined(DUMP_PAGE_TABLES) if (qemu_loglevel_mask(CPU_LOG_MMU)) { CPUState *cs = env_cpu(env); @@ -603,7 +581,8 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, "address translation\n"); return -4; } - if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) { + if ((access_type == MMU_DATA_STORE || ctx->key != 1) && + (access_type == MMU_DATA_LOAD || ctx->key != 0)) { ctx->raddr = eaddr; ret = 2; } else { @@ -682,8 +661,8 @@ static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) } static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong address, int rw, - int access_type) + target_ulong address, + MMUAccessType access_type) { ppcemb_tlb_t *tlb; hwaddr raddr; @@ -700,8 +679,8 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, } zsel = (tlb->attr >> 4) & 0xF; zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3; - LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n", - __func__, i, zsel, zpr, rw, tlb->attr); + LOG_SWTLB("%s: TLB %d zsel %d zpr %d ty %d attr %08x\n", + __func__, i, zsel, zpr, access_type, tlb->attr); /* Check execute enable bit */ switch (zpr) { case 0x2: @@ -727,7 +706,7 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, check_perms: /* Check from TLB entry */ ctx->prot = tlb->prot; - ret = check_prot(ctx->prot, rw, access_type); + ret = check_prot(ctx->prot, access_type); if (ret == -2) { env->spr[SPR_40x_ESR] = 0; } @@ -757,12 +736,11 @@ void store_40x_sler(CPUPPCState *env, uint32_t val) env->spr[SPR_405_SLER] = val; } -static inline int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb, - hwaddr *raddr, int *prot, - target_ulong address, int rw, - int access_type, int i) +static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb, + hwaddr *raddr, int *prot, target_ulong address, + MMUAccessType access_type, int i) { - int ret, prot2; + int prot2; if (ppcemb_tlb_check(env, tlb, raddr, address, env->spr[SPR_BOOKE_PID], @@ -794,42 +772,24 @@ found_tlb: } /* Check the address space */ - if (access_type == ACCESS_CODE) { - if (msr_ir != (tlb->attr & 1)) { - LOG_SWTLB("%s: AS doesn't match\n", __func__); - return -1; - } - - *prot = prot2; - if (prot2 & PAGE_EXEC) { - LOG_SWTLB("%s: good TLB!\n", __func__); - return 0; - } - - LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2); - ret = -3; - } else { - if (msr_dr != (tlb->attr & 1)) { - LOG_SWTLB("%s: AS doesn't match\n", __func__); - return -1; - } - - *prot = prot2; - if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) { - LOG_SWTLB("%s: found TLB!\n", __func__); - return 0; - } + if ((access_type == MMU_INST_FETCH ? msr_ir : msr_dr) != (tlb->attr & 1)) { + LOG_SWTLB("%s: AS doesn't match\n", __func__); + return -1; + } - LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2); - ret = -2; + *prot = prot2; + if (prot2 & prot_for_access_type(access_type)) { + LOG_SWTLB("%s: good TLB!\n", __func__); + return 0; } - return ret; + LOG_SWTLB("%s: no prot match: %x\n", __func__, prot2); + return access_type == MMU_INST_FETCH ? -3 : -2; } static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong address, int rw, - int access_type) + target_ulong address, + MMUAccessType access_type) { ppcemb_tlb_t *tlb; hwaddr raddr; @@ -839,7 +799,7 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, raddr = (hwaddr)-1ULL; for (i = 0; i < env->nb_tlb; i++) { tlb = &env->tlb.tlbe[i]; - ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw, + ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, access_type, i); if (ret != -1) { break; @@ -938,10 +898,10 @@ static bool is_epid_mmu(int mmu_idx) return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD; } -static uint32_t mmubooke206_esr(int mmu_idx, bool rw) +static uint32_t mmubooke206_esr(int mmu_idx, MMUAccessType access_type) { uint32_t esr = 0; - if (rw) { + if (access_type == MMU_DATA_STORE) { esr |= ESR_ST; } if (is_epid_mmu(mmu_idx)) { @@ -983,10 +943,9 @@ static bool mmubooke206_get_as(CPUPPCState *env, /* Check if the tlb found by hashing really matches */ static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb, hwaddr *raddr, int *prot, - target_ulong address, int rw, - int access_type, int mmu_idx) + target_ulong address, + MMUAccessType access_type, int mmu_idx) { - int ret; int prot2 = 0; uint32_t epid; bool as, pr; @@ -1043,44 +1002,31 @@ found_tlb: } /* Check the address space and permissions */ - if (access_type == ACCESS_CODE) { + if (access_type == MMU_INST_FETCH) { /* There is no way to fetch code using epid load */ assert(!use_epid); - if (msr_ir != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { - LOG_SWTLB("%s: AS doesn't match\n", __func__); - return -1; - } - - *prot = prot2; - if (prot2 & PAGE_EXEC) { - LOG_SWTLB("%s: good TLB!\n", __func__); - return 0; - } - - LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2); - ret = -3; - } else { - if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { - LOG_SWTLB("%s: AS doesn't match\n", __func__); - return -1; - } + as = msr_ir; + } - *prot = prot2; - if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) { - LOG_SWTLB("%s: found TLB!\n", __func__); - return 0; - } + if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { + LOG_SWTLB("%s: AS doesn't match\n", __func__); + return -1; + } - LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2); - ret = -2; + *prot = prot2; + if (prot2 & prot_for_access_type(access_type)) { + LOG_SWTLB("%s: good TLB!\n", __func__); + return 0; } - return ret; + LOG_SWTLB("%s: no prot match: %x\n", __func__, prot2); + return access_type == MMU_INST_FETCH ? -3 : -2; } static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong address, int rw, - int access_type, int mmu_idx) + target_ulong address, + MMUAccessType access_type, + int mmu_idx) { ppcmas_tlb_t *tlb; hwaddr raddr; @@ -1098,7 +1044,7 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, continue; } ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address, - rw, access_type, mmu_idx); + access_type, mmu_idx); if (ret != -1) { goto found_tlb; } @@ -1361,8 +1307,8 @@ void dump_mmu(CPUPPCState *env) } } -static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong eaddr, int rw) +static int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, + MMUAccessType access_type) { int in_plb, ret; @@ -1393,7 +1339,7 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0; if (in_plb ^ msr_px) { /* Access in protected area */ - if (rw == 1) { + if (access_type == MMU_DATA_STORE) { /* Access is not allowed */ ret = -2; } @@ -1413,28 +1359,28 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, return ret; } -static int get_physical_address_wtlb( - CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong eaddr, int rw, int access_type, - int mmu_idx) +static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx, + target_ulong eaddr, + MMUAccessType access_type, int type, + int mmu_idx) { int ret = -1; - bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0) - || (access_type != ACCESS_CODE && msr_dr == 0); + bool real_mode = (type == ACCESS_CODE && msr_ir == 0) + || (type != ACCESS_CODE && msr_dr == 0); switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_74xx: if (real_mode) { - ret = check_physical(env, ctx, eaddr, rw); + ret = check_physical(env, ctx, eaddr, access_type); } else { /* Try to find a BAT */ if (env->nb_BATs != 0) { - ret = get_bat_6xx_tlb(env, ctx, eaddr, rw, access_type); + ret = get_bat_6xx_tlb(env, ctx, eaddr, 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); + ret = get_segment_6xx_tlb(env, ctx, eaddr, access_type, type); } } break; @@ -1442,19 +1388,17 @@ static int get_physical_address_wtlb( case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: if (real_mode) { - ret = check_physical(env, ctx, eaddr, rw); + ret = check_physical(env, ctx, eaddr, access_type); } else { - ret = mmu40x_get_physical_address(env, ctx, eaddr, - rw, access_type); + ret = mmu40x_get_physical_address(env, ctx, eaddr, access_type); } break; case POWERPC_MMU_BOOKE: - ret = mmubooke_get_physical_address(env, ctx, eaddr, - rw, access_type); + ret = mmubooke_get_physical_address(env, ctx, eaddr, access_type); break; case POWERPC_MMU_BOOKE206: - ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, - access_type, mmu_idx); + ret = mmubooke206_get_physical_address(env, ctx, eaddr, access_type, + mmu_idx); break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ @@ -1462,7 +1406,7 @@ static int get_physical_address_wtlb( break; case POWERPC_MMU_REAL: if (real_mode) { - ret = check_physical(env, ctx, eaddr, rw); + ret = check_physical(env, ctx, eaddr, access_type); } else { cpu_abort(env_cpu(env), "PowerPC in real mode do not do any translation\n"); @@ -1476,11 +1420,11 @@ static int get_physical_address_wtlb( return ret; } -static int get_physical_address( - CPUPPCState *env, mmu_ctx_t *ctx, - target_ulong eaddr, int rw, int access_type) +static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, + target_ulong eaddr, MMUAccessType access_type, + int type) { - return get_physical_address_wtlb(env, ctx, eaddr, rw, access_type, 0); + return get_physical_address_wtlb(env, ctx, eaddr, access_type, type, 0); } hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) @@ -1508,14 +1452,15 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) ; } - if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) { + if (unlikely(get_physical_address(env, &ctx, addr, MMU_DATA_LOAD, + ACCESS_INT) != 0)) { /* * Some MMUs have separate TLBs for code and data. If we only * try an ACCESS_INT, we may not be able to read instructions * mapped by code TLBs, so we also try a ACCESS_CODE. */ - if (unlikely(get_physical_address(env, &ctx, addr, 0, + if (unlikely(get_physical_address(env, &ctx, addr, MMU_INST_FETCH, ACCESS_CODE) != 0)) { return -1; } @@ -1525,13 +1470,14 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) } static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address, - int rw, int mmu_idx) + MMUAccessType access_type, int mmu_idx) { uint32_t epid; bool as, pr; uint32_t missed_tid = 0; bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr); - if (rw == 2) { + + if (access_type == MMU_INST_FETCH) { as = msr_ir; } env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; @@ -1579,24 +1525,23 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address, /* Perform address translation */ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, - int rw, int mmu_idx) + MMUAccessType access_type, int mmu_idx) { CPUState *cs = env_cpu(env); PowerPCCPU *cpu = POWERPC_CPU(cs); mmu_ctx_t ctx; - int access_type; + int type; int ret = 0; - if (rw == 2) { + if (access_type == MMU_INST_FETCH) { /* code access */ - rw = 0; - access_type = ACCESS_CODE; + type = ACCESS_CODE; } else { /* data access */ - access_type = env->access_type; + type = env->access_type; } - ret = get_physical_address_wtlb(env, &ctx, address, rw, - access_type, mmu_idx); + ret = get_physical_address_wtlb(env, &ctx, address, access_type, + type, mmu_idx); if (ret == 0) { tlb_set_page(cs, address & TARGET_PAGE_MASK, ctx.raddr & TARGET_PAGE_MASK, ctx.prot, @@ -1604,7 +1549,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, ret = 0; } else if (ret < 0) { LOG_MMU_STATE(cs); - if (access_type == ACCESS_CODE) { + if (type == ACCESS_CODE) { switch (ret) { case -1: /* No matches in page tables or TLB */ @@ -1632,7 +1577,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, cs->exception_index = POWERPC_EXCP_ITLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, 0); + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD); return -1; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ @@ -1674,7 +1619,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, /* No matches in page tables or TLB */ switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: - if (rw == 1) { + if (access_type == MMU_DATA_STORE) { cs->exception_index = POWERPC_EXCP_DSTLB; env->error_code = 1 << 16; } else { @@ -1691,7 +1636,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, get_pteg_offset32(cpu, ctx.hash[1]); break; case POWERPC_MMU_SOFT_74xx: - if (rw == 1) { + if (access_type == MMU_DATA_STORE) { cs->exception_index = POWERPC_EXCP_DSTLB; } else { cs->exception_index = POWERPC_EXCP_DLTLB; @@ -1708,7 +1653,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, cs->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_40x_DEAR] = address; - if (rw) { + if (access_type == MMU_DATA_STORE) { env->spr[SPR_40x_ESR] = 0x00800000; } else { env->spr[SPR_40x_ESR] = 0x00000000; @@ -1719,13 +1664,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE206: - booke206_update_mas_tlb_miss(env, address, rw, mmu_idx); + booke206_update_mas_tlb_miss(env, address, access_type, mmu_idx); /* fall through */ case POWERPC_MMU_BOOKE: cs->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, rw); + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type); return -1; case POWERPC_MMU_REAL: cpu_abort(cs, "PowerPC in real mode should never raise " @@ -1743,16 +1688,16 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, if (env->mmu_model == POWERPC_MMU_SOFT_4xx || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) { env->spr[SPR_40x_DEAR] = address; - if (rw) { + if (access_type == MMU_DATA_STORE) { env->spr[SPR_40x_ESR] |= 0x00800000; } } else if ((env->mmu_model == POWERPC_MMU_BOOKE) || (env->mmu_model == POWERPC_MMU_BOOKE206)) { env->spr[SPR_BOOKE_DEAR] = address; - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, rw); + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type); } else { env->spr[SPR_DAR] = address; - if (rw == 1) { + if (access_type == MMU_DATA_STORE) { env->spr[SPR_DSISR] = 0x0A000000; } else { env->spr[SPR_DSISR] = 0x08000000; @@ -1761,7 +1706,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case -4: /* Direct store exception */ - switch (access_type) { + switch (type) { case ACCESS_FLOAT: /* Floating point load/store */ cs->exception_index = POWERPC_EXCP_ALIGN; @@ -1773,7 +1718,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = address; - if (rw == 1) { + if (access_type == MMU_DATA_STORE) { env->spr[SPR_DSISR] = 0x06000000; } else { env->spr[SPR_DSISR] = 0x04000000; @@ -1784,7 +1729,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = address; - if (rw == 1) { + if (access_type == MMU_DATA_STORE) { env->spr[SPR_DSISR] = 0x06100000; } else { env->spr[SPR_DSISR] = 0x04100000; @@ -2085,32 +2030,6 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) /*****************************************************************************/ /* Special registers manipulation */ -void ppc_store_sdr1(CPUPPCState *env, target_ulong value) -{ - PowerPCCPU *cpu = env_archcpu(env); - qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); - assert(!cpu->vhyp); -#if defined(TARGET_PPC64) - if (mmu_is_64bit(env->mmu_model)) { - target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE; - target_ulong htabsize = value & SDR_64_HTABSIZE; - - if (value & ~sdr_mask) { - error_report("Invalid bits 0x"TARGET_FMT_lx" set in SDR1", - value & ~sdr_mask); - value &= sdr_mask; - } - if (htabsize > 28) { - error_report("Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1", - htabsize); - return; - } - } -#endif /* defined(TARGET_PPC64) */ - /* FIXME: Should check for valid HTABMASK values in 32-bit case */ - env->spr[SPR_SDR1] = value; -} - #if defined(TARGET_PPC64) void ppc_store_ptcr(CPUPPCState *env, target_ulong value) { |