summaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/cpu.h19
-rw-r--r--target-ppc/exec.h2
-rw-r--r--target-ppc/helper.c11
-rw-r--r--target-ppc/op_helper.c4
-rw-r--r--target-ppc/translate.c11
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)