diff options
author | Richard Henderson <rth@twiddle.net> | 2016-07-12 21:01:29 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-10-31 09:46:25 -0600 |
commit | af7a06bac7d3abb2da48ef3277d2a415772d2ae8 (patch) | |
tree | 142792b8eeb3d991b567978fe34283a6d9946ce7 /target-sparc/cpu.h | |
parent | 2f9d35fc4006122bad33f9ae3e2e51d2263e98ee (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.h | 25 |
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; |