@@ -416,6 +416,7 @@ struct CPUMIPSState {
#define CP0SC2_XR 56
#define CP0SC2_XR_MASK (0xFFULL << CP0SC2_XR)
#define CP0SC2_MASK (CP0SC_1GMASK | (CP0SC_1GMASK << 16) | CP0SC2_XR_MASK)
+ target_ulong CP0_PWBase;
/*
* CP0 Register 6
*/
@@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = {
const VMStateDescription vmstate_mips_cpu = {
.name = "cpu",
- .version_id = 11,
- .minimum_version_id = 11,
+ .version_id = 12,
+ .minimum_version_id = 12,
.post_load = cpu_post_load,
.fields = (VMStateField[]) {
/* Active TC */
@@ -256,6 +256,7 @@ const VMStateDescription vmstate_mips_cpu = {
VMSTATE_UINTTL(env.CP0_SegCtl0, MIPSCPU),
VMSTATE_UINTTL(env.CP0_SegCtl1, MIPSCPU),
VMSTATE_UINTTL(env.CP0_SegCtl2, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_PWBase, MIPSCPU),
VMSTATE_INT32(env.CP0_Wired, MIPSCPU),
VMSTATE_INT32(env.CP0_SRSConf0, MIPSCPU),
VMSTATE_INT32(env.CP0_SRSConf1, MIPSCPU),
@@ -2478,6 +2478,19 @@ static inline void check_xnp(DisasContext *ctx)
}
}
+#ifndef CONFIG_USER_ONLY
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config3 PW bit is NOT set.
+ */
+static inline void check_pw(DisasContext *ctx)
+{
+ if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
+ generate_exception_end(ctx, EXCP_RI);
+ }
+}
+#endif
+
/*
* This code generates a "reserved instruction" exception if the
* Config3 MT bit is NOT set.
@@ -6088,6 +6101,11 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
tcg_gen_ext32s_tl(arg, arg);
rn = "SegCtl2";
break;
+ case 5:
+ check_pw(ctx);
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
+ rn = "PWBase";
+ break;
default:
goto cp0_unimplemented;
}
@@ -6789,6 +6807,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
gen_helper_mtc0_segctl2(cpu_env, arg);
rn = "SegCtl2";
break;
+ case 5:
+ check_pw(ctx);
+ gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
+ rn = "PWBase";
+ break;
default:
goto cp0_unimplemented;
}
@@ -7499,6 +7522,11 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
rn = "SegCtl2";
break;
+ case 5:
+ check_pw(ctx);
+ tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
+ rn = "PWBase";
+ break;
default:
goto cp0_unimplemented;
}
@@ -8182,6 +8210,11 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
gen_helper_mtc0_segctl2(cpu_env, arg);
rn = "SegCtl2";
break;
+ case 5:
+ check_pw(ctx);
+ tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
+ rn = "PWBase";
+ break;
default:
goto cp0_unimplemented;
}