X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/b142d79328cd0a0556634b0eeb891a15bfd5a00c..00c8cb0a36f51a6866a83c08962d12a0eb21864b:/target-ppc/mmu_helper.c diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 5dd4e05f78..653e50230e 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -231,6 +231,7 @@ static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); ppc6xx_tlb_t *tlb; int nr, max; @@ -244,7 +245,7 @@ static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env) tlb = &env->tlb.tlb6[nr]; pte_invalidate(&tlb->pte0); } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, @@ -252,6 +253,7 @@ static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, int is_code, int match_epn) { #if !defined(FLUSH_ALL_TLBS) + CPUState *cs = CPU(ppc_env_get_cpu(env)); ppc6xx_tlb_t *tlb; int way, nr; @@ -263,7 +265,7 @@ static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr, env->nb_tlb, eaddr); pte_invalidate(&tlb->pte0); - tlb_flush_page(env, tlb->EPN); + tlb_flush_page(cs, tlb->EPN); } } #else @@ -643,6 +645,7 @@ static int ppcemb_tlb_search(CPUPPCState *env, target_ulong address, /* Helpers specific to PowerPC 40x implementations */ static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); ppcemb_tlb_t *tlb; int i; @@ -650,13 +653,14 @@ static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) tlb = &env->tlb.tlbe[i]; tlb->prot &= ~PAGE_VALID; } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env, target_ulong eaddr, uint32_t pid) { #if !defined(FLUSH_ALL_TLBS) + CPUState *cs = CPU(ppc_env_get_cpu(env)); ppcemb_tlb_t *tlb; hwaddr raddr; target_ulong page, end; @@ -667,7 +671,7 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env, if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) { end = tlb->EPN + tlb->size; for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } tlb->prot &= ~PAGE_VALID; break; @@ -746,9 +750,11 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, void store_40x_sler(CPUPPCState *env, uint32_t val) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + /* XXX: TO BE FIXED */ if (val != 0x00000000) { - cpu_abort(env, "Little-endian regions are not supported by now\n"); + cpu_abort(CPU(cpu), "Little-endian regions are not supported by now\n"); } env->spr[SPR_405_SLER] = val; } @@ -858,6 +864,7 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, static void booke206_flush_tlb(CPUPPCState *env, int flags, const int check_iprot) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int tlb_size; int i, j; ppcmas_tlb_t *tlb = env->tlb.tlbm; @@ -874,7 +881,7 @@ static void booke206_flush_tlb(CPUPPCState *env, int flags, tlb += booke206_tlb_size(env, i); } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } static hwaddr booke206_tlb_to_page_size(CPUPPCState *env, @@ -1344,6 +1351,7 @@ 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) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int ret = -1; bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0) || (access_type != ACCESS_CODE && msr_dr == 0); @@ -1388,17 +1396,17 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "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"); + cpu_abort(CPU(cpu), "PowerPC in real mode do not do any translation\n"); } return -1; default: - cpu_abort(env, "Unknown or invalid MMU model\n"); + cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n"); return -1; } #if 0 @@ -1491,6 +1499,7 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address, static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, int mmu_idx) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); mmu_ctx_t ctx; int access_type; int ret = 0; @@ -1510,24 +1519,24 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, mmu_idx, TARGET_PAGE_SIZE); ret = 0; } else if (ret < 0) { - LOG_MMU_STATE(CPU(ppc_env_get_cpu(env))); + LOG_MMU_STATE(cs); if (access_type == ACCESS_CODE) { switch (ret) { case -1: /* No matches in page tables or TLB */ switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: - env->exception_index = POWERPC_EXCP_IFTLB; + cs->exception_index = POWERPC_EXCP_IFTLB; env->error_code = 1 << 18; env->spr[SPR_IMISS] = address; env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; goto tlb_miss; case POWERPC_MMU_SOFT_74xx: - env->exception_index = POWERPC_EXCP_IFTLB; + cs->exception_index = POWERPC_EXCP_IFTLB; goto tlb_miss_74xx; case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: - env->exception_index = POWERPC_EXCP_ITLB; + cs->exception_index = POWERPC_EXCP_ITLB; env->error_code = 0; env->spr[SPR_40x_DEAR] = address; env->spr[SPR_40x_ESR] = 0x00000000; @@ -1536,26 +1545,26 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, booke206_update_mas_tlb_miss(env, address, rw); /* fall through */ case POWERPC_MMU_BOOKE: - env->exception_index = POWERPC_EXCP_ITLB; + cs->exception_index = POWERPC_EXCP_ITLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; return -1; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_REAL: - cpu_abort(env, "PowerPC in real mode should never raise " + cpu_abort(cs, "PowerPC in real mode should never raise " "any MMU exceptions\n"); return -1; default: - cpu_abort(env, "Unknown or invalid MMU model\n"); + cpu_abort(cs, "Unknown or invalid MMU model\n"); return -1; } break; case -2: /* Access rights violation */ - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x08000000; break; case -3: @@ -1564,13 +1573,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, (env->mmu_model == POWERPC_MMU_BOOKE206)) { env->spr[SPR_BOOKE_ESR] = 0x00000000; } - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; break; case -4: /* Direct store exception */ /* No code fetch is allowed in direct-store areas */ - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; break; } @@ -1581,10 +1590,10 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: if (rw == 1) { - env->exception_index = POWERPC_EXCP_DSTLB; + cs->exception_index = POWERPC_EXCP_DSTLB; env->error_code = 1 << 16; } else { - env->exception_index = POWERPC_EXCP_DLTLB; + cs->exception_index = POWERPC_EXCP_DLTLB; env->error_code = 0; } env->spr[SPR_DMISS] = address; @@ -1598,9 +1607,9 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case POWERPC_MMU_SOFT_74xx: if (rw == 1) { - env->exception_index = POWERPC_EXCP_DSTLB; + cs->exception_index = POWERPC_EXCP_DSTLB; } else { - env->exception_index = POWERPC_EXCP_DLTLB; + cs->exception_index = POWERPC_EXCP_DLTLB; } tlb_miss_74xx: /* Implement LRU algorithm */ @@ -1611,7 +1620,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: - env->exception_index = POWERPC_EXCP_DTLB; + cs->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_40x_DEAR] = address; if (rw) { @@ -1622,29 +1631,29 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE206: booke206_update_mas_tlb_miss(env, address, rw); /* fall through */ case POWERPC_MMU_BOOKE: - env->exception_index = POWERPC_EXCP_DTLB; + cs->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0; return -1; case POWERPC_MMU_REAL: - cpu_abort(env, "PowerPC in real mode should never raise " + cpu_abort(cs, "PowerPC in real mode should never raise " "any MMU exceptions\n"); return -1; default: - cpu_abort(env, "Unknown or invalid MMU model\n"); + cpu_abort(cs, "Unknown or invalid MMU model\n"); return -1; } break; case -2: /* Access rights violation */ - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; if (env->mmu_model == POWERPC_MMU_SOFT_4xx || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) { @@ -1670,13 +1679,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, switch (access_type) { case ACCESS_FLOAT: /* Floating point load/store */ - env->exception_index = POWERPC_EXCP_ALIGN; + cs->exception_index = POWERPC_EXCP_ALIGN; env->error_code = POWERPC_EXCP_ALIGN_FP; env->spr[SPR_DAR] = address; break; case ACCESS_RES: /* lwarx, ldarx or stwcx. */ - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = address; if (rw == 1) { @@ -1687,7 +1696,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case ACCESS_EXT: /* eciwx or ecowx */ - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = address; if (rw == 1) { @@ -1698,7 +1707,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; default: printf("DSI: invalid exception (%d)\n", ret); - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; env->spr[SPR_DAR] = address; @@ -1709,7 +1718,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, } #if 0 printf("%s: set exception to %d %02x\n", __func__, - env->exception, env->error_code); + cs->exception, env->error_code); #endif ret = 1; } @@ -1723,6 +1732,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu, target_ulong mask) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); target_ulong base, end, page; base = BATu & ~0x0001FFFF; @@ -1730,7 +1740,7 @@ static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu, LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", base, end, mask); for (page = base; page != end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } LOG_BATS("Flush done\n"); } @@ -1892,6 +1902,8 @@ void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value) /* TLB management */ void ppc_tlb_invalidate_all(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_74xx: @@ -1902,14 +1914,14 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) ppc4xx_tlb_invalidate_all(env); break; case POWERPC_MMU_REAL: - cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n"); + cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n"); break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE: - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); break; case POWERPC_MMU_BOOKE206: booke206_flush_tlb(env, -1, 0); @@ -1922,11 +1934,11 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) case POWERPC_MMU_2_06a: case POWERPC_MMU_2_06d: #endif /* defined(TARGET_PPC64) */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); break; default: /* XXX: TODO */ - cpu_abort(env, "Unknown MMU model\n"); + cpu_abort(CPU(cpu), "Unknown MMU model\n"); break; } } @@ -1934,6 +1946,9 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) { #if !defined(FLUSH_ALL_TLBS) + PowerPCCPU *cpu = ppc_env_get_cpu(env); + CPUState *cs; + addr &= TARGET_PAGE_MASK; switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: @@ -1948,43 +1963,44 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]); break; case POWERPC_MMU_REAL: - cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n"); + cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n"); break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE: /* XXX: TODO */ - cpu_abort(env, "BookE MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE206: /* XXX: TODO */ - cpu_abort(env, "BookE 2.06 MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "BookE 2.06 MMU model is not implemented\n"); break; case POWERPC_MMU_32B: case POWERPC_MMU_601: /* tlbie invalidate TLBs for all segments */ addr &= ~((target_ulong)-1ULL << 28); + cs = CPU(cpu); /* XXX: this case should be optimized, * giving a mask to tlb_flush_page */ - tlb_flush_page(env, addr | (0x0 << 28)); - tlb_flush_page(env, addr | (0x1 << 28)); - tlb_flush_page(env, addr | (0x2 << 28)); - tlb_flush_page(env, addr | (0x3 << 28)); - tlb_flush_page(env, addr | (0x4 << 28)); - tlb_flush_page(env, addr | (0x5 << 28)); - tlb_flush_page(env, addr | (0x6 << 28)); - tlb_flush_page(env, addr | (0x7 << 28)); - tlb_flush_page(env, addr | (0x8 << 28)); - tlb_flush_page(env, addr | (0x9 << 28)); - tlb_flush_page(env, addr | (0xA << 28)); - tlb_flush_page(env, addr | (0xB << 28)); - tlb_flush_page(env, addr | (0xC << 28)); - tlb_flush_page(env, addr | (0xD << 28)); - tlb_flush_page(env, addr | (0xE << 28)); - tlb_flush_page(env, addr | (0xF << 28)); + tlb_flush_page(cs, addr | (0x0 << 28)); + tlb_flush_page(cs, addr | (0x1 << 28)); + tlb_flush_page(cs, addr | (0x2 << 28)); + tlb_flush_page(cs, addr | (0x3 << 28)); + tlb_flush_page(cs, addr | (0x4 << 28)); + tlb_flush_page(cs, addr | (0x5 << 28)); + tlb_flush_page(cs, addr | (0x6 << 28)); + tlb_flush_page(cs, addr | (0x7 << 28)); + tlb_flush_page(cs, addr | (0x8 << 28)); + tlb_flush_page(cs, addr | (0x9 << 28)); + tlb_flush_page(cs, addr | (0xA << 28)); + tlb_flush_page(cs, addr | (0xB << 28)); + tlb_flush_page(cs, addr | (0xC << 28)); + tlb_flush_page(cs, addr | (0xD << 28)); + tlb_flush_page(cs, addr | (0xE << 28)); + tlb_flush_page(cs, addr | (0xF << 28)); break; #if defined(TARGET_PPC64) case POWERPC_MMU_64B: @@ -1996,12 +2012,12 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) * and we still don't have a tlb_flush_mask(env, n, mask) in QEMU, * we just invalidate all TLBs */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); break; #endif /* defined(TARGET_PPC64) */ default: /* XXX: TODO */ - cpu_abort(env, "Unknown MMU model\n"); + cpu_abort(CPU(cpu), "Unknown MMU model\n"); break; } #else @@ -2013,7 +2029,10 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) /* Special registers manipulation */ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value); + assert(!env->external_htab); if (env->spr[SPR_SDR1] != value) { env->spr[SPR_SDR1] = value; #if defined(TARGET_PPC64) @@ -2025,7 +2044,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) " stored in SDR1\n", htabsize); htabsize = 28; } - env->htab_mask = (1ULL << (htabsize + 18)) - 1; + env->htab_mask = (1ULL << (htabsize + 18 - 7)) - 1; env->htab_base = value & SDR_64_HTABORG; } else #endif /* defined(TARGET_PPC64) */ @@ -2034,7 +2053,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF; env->htab_base = value & SDR_32_HTABORG; } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } } @@ -2052,6 +2071,8 @@ target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num) void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__, (int)srnum, value, env->sr[srnum]); #if defined(TARGET_PPC64) @@ -2061,7 +2082,7 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) /* ESID = srnum */ rb |= ((uint32_t)srnum & 0xf) << 28; /* Set the valid bit */ - rb |= 1 << 27; + rb |= SLB_ESID_V; /* Index = ESID */ rb |= (uint32_t)srnum; @@ -2084,11 +2105,11 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) page = (16 << 20) * srnum; end = page + (16 << 20); for (; page != end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(CPU(cpu), page); } } #else - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); #endif } } @@ -2315,6 +2336,8 @@ target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry) void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, target_ulong val) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + CPUState *cs = CPU(cpu); ppcemb_tlb_t *tlb; target_ulong page, end; @@ -2328,7 +2351,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end " TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } } tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT) @@ -2338,7 +2361,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, * of the ppc or ppc64 one */ if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) { - cpu_abort(env, "TLB size " TARGET_FMT_lu " < %u " + cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u " "are not supported (%d)\n", tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7)); } @@ -2347,7 +2370,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, tlb->prot |= PAGE_VALID; if (val & PPC4XX_TLBHI_E) { /* XXX: TO BE FIXED */ - cpu_abort(env, + cpu_abort(cs, "Little-endian TLB entries are not supported by now\n"); } } else { @@ -2367,7 +2390,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end " TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } } } @@ -2408,6 +2431,7 @@ target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address) void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry, target_ulong value) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); ppcemb_tlb_t *tlb; target_ulong EPN, RPN, size; int do_flush_tlbs; @@ -2443,13 +2467,13 @@ void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry, } tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF; if (do_flush_tlbs) { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } break; case 1: RPN = value & 0xFFFFFC0F; if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } tlb->RPN = RPN; break; @@ -2543,6 +2567,7 @@ target_ulong helper_440_tlbsx(CPUPPCState *env, target_ulong address) static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); uint32_t tlbncfg = 0; int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT; int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK); @@ -2552,7 +2577,7 @@ static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb]; if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) { - cpu_abort(env, "we don't support HES yet\n"); + cpu_abort(CPU(cpu), "we don't support HES yet\n"); } return booke206_get_tlbm(env, tlb, ea, esel); @@ -2560,13 +2585,16 @@ static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) void helper_booke_setpid(CPUPPCState *env, uint32_t pidn, target_ulong pid) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + env->spr[pidn] = pid; /* changing PIDs mean we're in a different address space now */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } void helper_booke206_tlbwe(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); uint32_t tlbncfg, tlbn; ppcmas_tlb_t *tlb; uint32_t size_tlb, size_ps; @@ -2620,7 +2648,7 @@ void helper_booke206_tlbwe(CPUPPCState *env) } if (msr_gs) { - cpu_abort(env, "missing HV implementation\n"); + cpu_abort(CPU(cpu), "missing HV implementation\n"); } tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) | env->spr[SPR_BOOKE_MAS3]; @@ -2654,9 +2682,9 @@ void helper_booke206_tlbwe(CPUPPCState *env) } if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) { - tlb_flush_page(env, tlb->mas2 & MAS2_EPN_MASK); + tlb_flush_page(CPU(cpu), tlb->mas2 & MAS2_EPN_MASK); } else { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } } @@ -2763,6 +2791,8 @@ static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn, void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + if (address & 0x4) { /* flush all entries */ if (address & 0x8) { @@ -2778,11 +2808,11 @@ void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address) if (address & 0x8) { /* flush TLB1 entries */ booke206_invalidate_ea_tlb(env, 1, address); - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } else { /* flush TLB0 entries */ booke206_invalidate_ea_tlb(env, 0, address); - tlb_flush_page(env, address & MAS2_EPN_MASK); + tlb_flush_page(CPU(cpu), address & MAS2_EPN_MASK); } } @@ -2794,6 +2824,7 @@ void helper_booke206_tlbilx0(CPUPPCState *env, target_ulong address) void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int i, j; int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); ppcmas_tlb_t *tlb = env->tlb.tlbm; @@ -2810,11 +2841,12 @@ void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address) } tlb += booke206_tlb_size(env, i); } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int i, j; ppcmas_tlb_t *tlb; int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); @@ -2850,7 +2882,7 @@ void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address) tlb->mas1 &= ~MAS1_VALID; } } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type) @@ -2871,6 +2903,8 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type) /*****************************************************************************/ +#include "exec/softmmu_exec.h" + #define MMUSUFFIX _mmu #define SHIFT 0 @@ -2889,23 +2923,24 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type) NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx, +void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { - CPUState *cpu = CPU(ppc_env_get_cpu(env)); - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + PowerPCCPU *cpu = POWERPC_CPU(cs); + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); + CPUPPCState *env = &cpu->env; int ret; if (pcc->handle_mmu_fault) { - ret = pcc->handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = pcc->handle_mmu_fault(cpu, addr, is_write, mmu_idx); } else { ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx); } if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ - cpu_restore_state(env, retaddr); + cpu_restore_state(cs, retaddr); } - helper_raise_exception_err(env, env->exception_index, env->error_code); + helper_raise_exception_err(env, cs->exception_index, env->error_code); } }