diff --git a/trunk/target-ppc/helper.c b/trunk/target-ppc/helper.c index 2bf7650..df37152 100644 --- a/trunk/target-ppc/helper.c +++ b/trunk/target-ppc/helper.c @@ -1141,7 +1141,7 @@ static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx, env->spr[SPR_40x_PID], 0, i) < 0) continue; zsel = (tlb->attr >> 4) & 0xF; - zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3; + 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); /* Check execute enable bit */ @@ -2089,6 +2089,9 @@ static always_inline void powerpc_excp (CPUState *env, new_msr &= ~((target_ulong)1 << MSR_RI); if (lpes1 == 0) new_msr |= (target_ulong)MSR_HVB; + /*Not sure why this isn't the same */ + env->spr[SPR_40x_DEAR] = env->spr[SPR_DAR]; + env->spr[SPR_40x_ESR] = 0x00800000; goto store_next; case POWERPC_EXCP_ISI: /* Instruction storage exception */ LOG_EXCP("ISI exception: msr=" ADDRX ", nip=" ADDRX "\n", diff --git a/trunk/target-ppc/op_helper.c b/trunk/target-ppc/op_helper.c index d531dd8..e165424 100644 --- a/trunk/target-ppc/op_helper.c +++ b/trunk/target-ppc/op_helper.c @@ -3737,12 +3737,11 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val) tlb->prot |= PAGE_VALID; else tlb->prot &= ~PAGE_VALID; - if (val & 0x20) { + if (val & 0x40 && val & 0x20) { /* XXX: TO BE FIXED */ cpu_abort(env, "Little-endian TLB entries are not supported by now\n"); } tlb->PID = env->spr[SPR_40x_PID]; /* PID */ - tlb->attr = val & 0xFF; LOG_SWTLB("%s: set up TLB %d RPN " PADDRX " EPN " ADDRX " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, (int)entry, tlb->RPN, tlb->EPN, tlb->size, @@ -3768,11 +3767,21 @@ void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val) entry &= 0x3F; tlb = &env->tlb[entry].tlbe; tlb->RPN = val & 0xFFFFFC00; - tlb->prot = PAGE_READ; + tlb->attr = val & 0xFF; + tlb->prot &= ~(PAGE_EXEC | PAGE_WRITE); + tlb->prot |= PAGE_READ; if (val & 0x200) tlb->prot |= PAGE_EXEC; if (val & 0x100) tlb->prot |= PAGE_WRITE; + + /* If the page is valid flush it for the prot change */ + if (tlb->prot & PAGE_VALID) { + target_ulong page, end; + end = tlb->EPN + tlb->size; + for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) + tlb_flush_page(env, page); + } LOG_SWTLB("%s: set up TLB %d RPN " PADDRX " EPN " ADDRX " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, (int)entry, tlb->RPN, tlb->EPN, tlb->size,