summaryrefslogtreecommitdiff
path: root/target-ppc/mmu_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc/mmu_helper.c')
-rw-r--r--target-ppc/mmu_helper.c208
1 files changed, 120 insertions, 88 deletions
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 8e2f8e736a..1771863dff 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;
@@ -1505,29 +1514,29 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
}
ret = get_physical_address(env, &ctx, address, rw, access_type);
if (ret == 0) {
- tlb_set_page(env, address & TARGET_PAGE_MASK,
+ tlb_set_page(cs, address & TARGET_PAGE_MASK,
ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
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,6 +2029,8 @@ 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) {
@@ -2035,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);
}
}
@@ -2053,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)
@@ -2085,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
}
}
@@ -2316,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;
@@ -2329,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)
@@ -2339,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));
}
@@ -2348,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 {
@@ -2368,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);
}
}
}
@@ -2409,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;
@@ -2444,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;
@@ -2544,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);
@@ -2553,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);
@@ -2561,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;
@@ -2621,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];
@@ -2655,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);
}
}
@@ -2764,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) {
@@ -2779,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);
}
}
@@ -2795,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;
@@ -2811,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);
@@ -2851,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)
@@ -2892,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);
}
}