summaryrefslogtreecommitdiff
path: root/target/mips/cpu.h
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2017-07-18 12:55:55 +0100
committerYongbok Kim <yongbok.kim@imgtec.com>2017-07-20 22:42:26 +0100
commit42c86612d507c2a8789f2b8d920a244693c4ef7b (patch)
tree4fb67a58c82b9fb3a31b47ff97545dce9d4da58c /target/mips/cpu.h
parentb0fc6003224543d2bdb172eca752656a6223e4a1 (diff)
downloadqemu-42c86612d507c2a8789f2b8d920a244693c4ef7b.tar.gz
target/mips: Add an MMU mode for ERL
The segmentation control feature allows a legacy memory segment to become unmapped uncached at error level (according to CP0_Status.ERL), and in fact the user segment is already treated in this way by QEMU. Add a new MMU mode for this state so that QEMU's mappings don't persist between ERL=0 and ERL=1. Signed-off-by: James Hogan <james.hogan@imgtec.com> Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com> Cc: Aurelien Jarno <aurelien@aurel32.net> [yongbok.kim@imgtec.com: cosmetic changes] Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Diffstat (limited to 'target/mips/cpu.h')
-rw-r--r--target/mips/cpu.h17
1 files changed, 13 insertions, 4 deletions
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3cf1676115..c24b1f64c6 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -134,7 +134,7 @@ struct CPUMIPSFPUContext {
#define FP_UNIMPLEMENTED 32
};
-#define NB_MMU_MODES 3
+#define NB_MMU_MODES 4
#define TARGET_INSN_START_EXTRA_WORDS 2
typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
@@ -551,7 +551,7 @@ struct CPUMIPSState {
#define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
uint32_t hflags; /* CPU State */
/* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK 0xF5807FF
+#define MIPS_HFLAG_TMASK 0x1F5807FF
#define MIPS_HFLAG_MODE 0x00007 /* execution modes */
/* The KSU flags must be the lowest bits in hflags. The flag order
must be the same as defined for CP0 Status. This allows to use
@@ -601,6 +601,7 @@ struct CPUMIPSState {
#define MIPS_HFLAG_FRE 0x2000000 /* FRE enabled */
#define MIPS_HFLAG_ELPA 0x4000000
#define MIPS_HFLAG_ITC_CACHE 0x8000000 /* CACHE instr. operates on ITC tag */
+#define MIPS_HFLAG_ERL 0x10000000 /* error level flag */
target_ulong btarget; /* Jump / branch target */
target_ulong bcond; /* Branch condition (if needed) */
@@ -698,11 +699,16 @@ extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
#define MMU_MODE0_SUFFIX _kernel
#define MMU_MODE1_SUFFIX _super
#define MMU_MODE2_SUFFIX _user
+#define MMU_MODE3_SUFFIX _error
#define MMU_USER_IDX 2
static inline int hflags_mmu_index(uint32_t hflags)
{
- return hflags & MIPS_HFLAG_KSU;
+ if (hflags & MIPS_HFLAG_ERL) {
+ return 3; /* ERL */
+ } else {
+ return hflags & MIPS_HFLAG_KSU;
+ }
}
static inline int cpu_mmu_index (CPUMIPSState *env, bool ifetch)
@@ -971,7 +977,10 @@ static inline void compute_hflags(CPUMIPSState *env)
MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE |
- MIPS_HFLAG_ELPA);
+ MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL);
+ if (env->CP0_Status & (1 << CP0St_ERL)) {
+ env->hflags |= MIPS_HFLAG_ERL;
+ }
if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
!(env->CP0_Status & (1 << CP0St_ERL)) &&
!(env->hflags & MIPS_HFLAG_DM)) {