aboutsummaryrefslogtreecommitdiff
path: root/target-sparc/cpu.h
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2016-07-12 21:01:29 -0700
committerRichard Henderson <rth@twiddle.net>2016-10-31 09:46:25 -0600
commitaf7a06bac7d3abb2da48ef3277d2a415772d2ae8 (patch)
tree142792b8eeb3d991b567978fe34283a6d9946ce7 /target-sparc/cpu.h
parent2f9d35fc4006122bad33f9ae3e2e51d2263e98ee (diff)
target-sparc: Add MMU_PHYS_IDX
It's handy to have a mmu idx for physical addresses, so that mmu disabled and physical access asis can use the same path as normal accesses. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-sparc/cpu.h')
-rw-r--r--target-sparc/cpu.h25
1 files changed, 18 insertions, 7 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 3ae3a12e19..e94b8f19d6 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -225,9 +225,9 @@ enum {
#define MAX_NWINDOWS 32
#if !defined(TARGET_SPARC64)
-#define NB_MMU_MODES 2
+#define NB_MMU_MODES 3
#else
-#define NB_MMU_MODES 6
+#define NB_MMU_MODES 7
typedef struct trap_state {
uint64_t tpc;
uint64_t tnpc;
@@ -649,11 +649,13 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
#define MMU_MODE4_SUFFIX _nucleus
#define MMU_HYPV_IDX 5
#define MMU_MODE5_SUFFIX _hypv
+#define MMU_PHYS_IDX 6
#else
#define MMU_USER_IDX 0
#define MMU_MODE0_SUFFIX _user
#define MMU_KERNEL_IDX 1
#define MMU_MODE1_SUFFIX _kernel
+#define MMU_PHYS_IDX 2
#endif
#if defined (TARGET_SPARC64)
@@ -673,18 +675,27 @@ static inline int cpu_supervisor_mode(CPUSPARCState *env1)
}
#endif
-static inline int cpu_mmu_index(CPUSPARCState *env1, bool ifetch)
+static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
{
#if defined(CONFIG_USER_ONLY)
return MMU_USER_IDX;
#elif !defined(TARGET_SPARC64)
- return env1->psrs;
+ if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
+ return MMU_PHYS_IDX;
+ } else {
+ return env->psrs;
+ }
#else
- if (env1->tl > 0) {
+ /* IMMU or DMMU disabled. */
+ if (ifetch
+ ? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
+ : (env->lsu & DMMU_E) == 0) {
+ return MMU_PHYS_IDX;
+ } else if (env->tl > 0) {
return MMU_NUCLEUS_IDX;
- } else if (cpu_hypervisor_mode(env1)) {
+ } else if (cpu_hypervisor_mode(env)) {
return MMU_HYPV_IDX;
- } else if (cpu_supervisor_mode(env1)) {
+ } else if (cpu_supervisor_mode(env)) {
return MMU_KERNEL_IDX;
} else {
return MMU_USER_IDX;