diff --git a/qemu/header_gen.py b/qemu/header_gen.py index fd12c017..6abcadca 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -4934,6 +4934,7 @@ mips_symbols = ( 'helper_mtc0_pagegrain', 'helper_mtc0_pagemask', 'helper_mtc0_performance0', + 'helper_mtc0_pwctl', 'helper_mtc0_pwfield', 'helper_mtc0_pwsize', 'helper_mtc0_segctl0', diff --git a/qemu/mips.h b/qemu/mips.h index aba177e2..355d9df3 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -3908,6 +3908,7 @@ #define helper_mtc0_pagegrain helper_mtc0_pagegrain_mips #define helper_mtc0_pagemask helper_mtc0_pagemask_mips #define helper_mtc0_performance0 helper_mtc0_performance0_mips +#define helper_mtc0_pwctl helper_mtc0_pwctl_mips #define helper_mtc0_pwfield helper_mtc0_pwfield_mips #define helper_mtc0_pwsize helper_mtc0_pwsize_mips #define helper_mtc0_segctl0 helper_mtc0_segctl0_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 1885c7a2..40dc756f 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -3908,6 +3908,7 @@ #define helper_mtc0_pagegrain helper_mtc0_pagegrain_mips64 #define helper_mtc0_pagemask helper_mtc0_pagemask_mips64 #define helper_mtc0_performance0 helper_mtc0_performance0_mips64 +#define helper_mtc0_pwctl helper_mtc0_pwctl_mips64 #define helper_mtc0_pwfield helper_mtc0_pwfield_mips64 #define helper_mtc0_pwsize helper_mtc0_pwsize_mips64 #define helper_mtc0_segctl0 helper_mtc0_segctl0_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 8905ca22..4cf94d1f 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -3908,6 +3908,7 @@ #define helper_mtc0_pagegrain helper_mtc0_pagegrain_mips64el #define helper_mtc0_pagemask helper_mtc0_pagemask_mips64el #define helper_mtc0_performance0 helper_mtc0_performance0_mips64el +#define helper_mtc0_pwctl helper_mtc0_pwctl_mips64el #define helper_mtc0_pwfield helper_mtc0_pwfield_mips64el #define helper_mtc0_pwsize helper_mtc0_pwsize_mips64el #define helper_mtc0_segctl0 helper_mtc0_segctl0_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 28550a90..2a6b51a2 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -3908,6 +3908,7 @@ #define helper_mtc0_pagegrain helper_mtc0_pagegrain_mipsel #define helper_mtc0_pagemask helper_mtc0_pagemask_mipsel #define helper_mtc0_performance0 helper_mtc0_performance0_mipsel +#define helper_mtc0_pwctl helper_mtc0_pwctl_mipsel #define helper_mtc0_pwfield helper_mtc0_pwfield_mipsel #define helper_mtc0_pwsize helper_mtc0_pwsize_mipsel #define helper_mtc0_segctl0 helper_mtc0_segctl0_mipsel diff --git a/qemu/target/mips/cpu.h b/qemu/target/mips/cpu.h index 35faeb08..c3fb1251 100644 --- a/qemu/target/mips/cpu.h +++ b/qemu/target/mips/cpu.h @@ -447,6 +447,17 @@ struct CPUMIPSState { * CP0 Register 6 */ int32_t CP0_Wired; + int32_t CP0_PWCtl; +#define CP0PC_PWEN 31 +#if defined(TARGET_MIPS64) +#define CP0PC_PWDIREXT 30 +#define CP0PC_XK 28 +#define CP0PC_XS 27 +#define CP0PC_XU 26 +#endif +#define CP0PC_DPH 7 +#define CP0PC_HUGEPG 6 +#define CP0PC_PSN 0 /* 5..0 */ int32_t CP0_SRSConf0_rw_bitmask; int32_t CP0_SRSConf0; #define CP0SRSC0_M 31 diff --git a/qemu/target/mips/helper.h b/qemu/target/mips/helper.h index 6152de36..31a2d164 100644 --- a/qemu/target/mips/helper.h +++ b/qemu/target/mips/helper.h @@ -129,6 +129,7 @@ DEF_HELPER_2(mtc0_srsconf2, void, env, tl) DEF_HELPER_2(mtc0_srsconf3, void, env, tl) DEF_HELPER_2(mtc0_srsconf4, void, env, tl) DEF_HELPER_2(mtc0_hwrena, void, env, tl) +DEF_HELPER_2(mtc0_pwctl, void, env, tl) DEF_HELPER_2(mtc0_count, void, env, tl) DEF_HELPER_2(mtc0_entryhi, void, env, tl) DEF_HELPER_2(mttc0_entryhi, void, env, tl) diff --git a/qemu/target/mips/op_helper.c b/qemu/target/mips/op_helper.c index 08ea5408..1b0d3313 100644 --- a/qemu/target/mips/op_helper.c +++ b/qemu/target/mips/op_helper.c @@ -1517,6 +1517,16 @@ void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1) } } +void helper_mtc0_pwctl(CPUMIPSState *env, target_ulong arg1) +{ +#if defined(TARGET_MIPS64) + /* PWEn = 0. Hardware page table walking is not implemented. */ + env->CP0_PWCtl = (env->CP0_PWCtl & 0x000000C0) | (arg1 & 0x5C00003F); +#else + env->CP0_PWCtl = (arg1 & 0x800000FF); +#endif +} + void helper_mtc0_srsconf0(CPUMIPSState *env, target_ulong arg1) { env->CP0_SRSConf0 |= arg1 & env->CP0_SRSConf0_rw_bitmask; diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 3dcd9dbe..257936b7 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -6240,6 +6240,11 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf4)); rn = "SRSConf4"; break; + case 6: + check_pw(ctx); + gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PWCtl)); + rn = "PWCtl"; + break; default: goto cp0_unimplemented; } @@ -6952,6 +6957,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_helper_mtc0_srsconf4(tcg_ctx, tcg_ctx->cpu_env, arg); rn = "SRSConf4"; break; + case 6: + check_pw(ctx); + gen_helper_mtc0_pwctl(tcg_ctx, tcg_ctx->cpu_env, arg); + rn = "PWCtl"; + break; default: goto cp0_unimplemented; } @@ -7674,6 +7684,11 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSConf4)); rn = "SRSConf4"; break; + case 6: + check_pw(ctx); + gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_PWCtl)); + rn = "PWCtl"; + break; default: goto cp0_unimplemented; } @@ -8368,6 +8383,11 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_helper_mtc0_srsconf4(tcg_ctx, tcg_ctx->cpu_env, arg); rn = "SRSConf4"; break; + case 6: + check_pw(ctx); + gen_helper_mtc0_pwctl(tcg_ctx, tcg_ctx->cpu_env, arg); + rn = "PWCtl"; + break; default: goto cp0_unimplemented; }