#ifdef DEBUG_MMU
# define LOG_MMU(...) qemu_log(__VA_ARGS__)
-# define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+# define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
#else
# define LOG_MMU(...) do { } while (0)
-# define LOG_MMU_STATE(...) do { } while (0)
+# define LOG_MMU_STATE(cpu) do { } while (0)
#endif
#ifdef DEBUG_SOFTWARE_TLB
return ret;
}
-hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
mmu_ctx_t ctx;
switch (env->mmu_model) {
}
if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) {
- return -1;
+
+ /* 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,
+ ACCESS_CODE) != 0)) {
+ return -1;
+ }
}
return ctx.raddr & TARGET_PAGE_MASK;
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;
mmu_idx, TARGET_PAGE_SIZE);
ret = 0;
} else if (ret < 0) {
- LOG_MMU_STATE(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;
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;
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:
(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;
}
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;
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 */
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) {
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;
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) {
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) {
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) {
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;
}
#if 0
printf("%s: set exception to %d %02x\n", __func__,
- env->exception, env->error_code);
+ cs->exception, env->error_code);
#endif
ret = 1;
}
void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
{
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)
" 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) */
/* 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;
/*****************************************************************************/
+#include "exec/softmmu_exec.h"
+
#define MMUSUFFIX _mmu
#define SHIFT 0
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 = 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) {
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);
}
}