diff options
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/cpu.h | 19 | ||||
-rw-r--r-- | target-ppc/exec.h | 2 | ||||
-rw-r--r-- | target-ppc/helper.c | 11 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 4 | ||||
-rw-r--r-- | target-ppc/translate.c | 11 |
5 files changed, 32 insertions, 15 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index b424abcebb..d39bd971a0 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -434,6 +434,12 @@ enum { POWERPC_FLAG_PMM = 0x00000400, }; +#if defined(TARGET_PPC64H) +#define NB_MMU_MODES 3 +#else +#define NB_MMU_MODES 2 +#endif + /*****************************************************************************/ /* The whole PowerPC CPU context */ struct CPUPPCState { @@ -575,6 +581,7 @@ struct CPUPPCState { jmp_buf jmp_env; int user_mode_only; /* user mode only simulation */ target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */ + int mmu_idx; /* precomputed MMU index to speed up mem accesses */ /* Power management */ int power_mode; @@ -699,6 +706,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val); #define cpu_signal_handler cpu_ppc_signal_handler #define cpu_list ppc_cpu_list +/* MMU modes definitions */ +#define MMU_MODE0_SUFFIX _user +#define MMU_MODE1_SUFFIX _kernel +#if defined(TARGET_PPC64H) +#define MMU_MODE2_SUFFIX _hypv +#endif +#define MMU_USER_IDX 0 +static inline int cpu_mmu_index (CPUState *env) +{ + return env->mmu_idx; +} + #include "cpu-all.h" /*****************************************************************************/ diff --git a/target-ppc/exec.h b/target-ppc/exec.h index 3fedf493e3..5685fd7a4b 100644 --- a/target-ppc/exec.h +++ b/target-ppc/exec.h @@ -112,7 +112,7 @@ static always_inline void regs_to_env (void) } int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); static always_inline int cpu_halted (CPUState *env) { diff --git a/target-ppc/helper.c b/target-ppc/helper.c index c4eab18fc8..dd5a07a53f 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -39,7 +39,7 @@ #if defined(CONFIG_USER_ONLY) int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { int exception, error_code; @@ -1349,7 +1349,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) /* Perform address translation */ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { mmu_ctx_t ctx; int access_type; @@ -1370,7 +1370,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, if (ret == 0) { ret = tlb_set_page(env, address & TARGET_PAGE_MASK, ctx.raddr & TARGET_PAGE_MASK, ctx.prot, - is_user, is_softmmu); + mmu_idx, is_softmmu); } else if (ret < 0) { #if defined (DEBUG_MMU) if (loglevel != 0) @@ -2083,7 +2083,12 @@ void do_compute_hflags (CPUPPCState *env) env->hflags |= msr_cm << MSR_CM; env->hflags |= (uint64_t)msr_sf << MSR_SF; env->hflags |= (uint64_t)msr_hv << MSR_HV; + /* Precompute MMU index */ + if (msr_pr == 0 && msr_hv == 1) + env->mmu_idx = 2; + else #endif + env->mmu_idx = 1 - msr_pr; } /*****************************************************************************/ diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 7a758f6c06..38c3a7ff8f 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -2307,7 +2307,7 @@ DO_SPE_OP1(fsctuf); 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 (target_ulong addr, int is_write, int is_user, void *retaddr) +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) { TranslationBlock *tb; CPUState *saved_env; @@ -2318,7 +2318,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index eb795fb6f5..6f2a9721f2 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6693,15 +6693,8 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, ctx.tb = tb; ctx.exception = POWERPC_EXCP_NONE; ctx.spr_cb = env->spr_cb; -#if defined(CONFIG_USER_ONLY) - supervisor = 0; -#else -#if defined(TARGET_PPC64H) - if (msr_pr == 0 && msr_hv == 1) - supervisor = 2; - else -#endif - supervisor = 1 - msr_pr; + supervisor = env->mmu_idx; +#if !defined(CONFIG_USER_ONLY) ctx.supervisor = supervisor; #endif #if defined(TARGET_PPC64) |