Commit 103be64c authored by Yongbok Kim's avatar Yongbok Kim Committed by Aleksandar Markovic
Browse files

target/mips: Add CP0 PWCtl register



Add PWCtl register (CP0 Register 5, Select 6).

The PWCtl register configures hardware page table walking for TLB
refills.

This register is required for the hardware page walker feature. It
exists only if Config3 PW bit is set to 1. It contains following
fields:

PWEn     (31)   - Hardware Page Table walker enable
PWDirExt (30)   - If 1, 4-th level implemented (MIPS64 only)
XK       (28)   - If 1, walker handles xkseg (MIPS64 only)
XS       (27)   - If 1, walker handles xsseg (MIPS64 only)
XU       (26)   - If 1, walker handles xuseg (MIPS64 only)
DPH      (7)    - Dual Page format of Huge Page support
HugePg   (6)    - Huge Page PTE supported in Directory levels
PSn      (5..0) - Bit position of PTEvld in Huge Page PTE

Reviewed-by: default avatarAleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: default avatarYongbok Kim <yongbok.kim@mips.com>
Signed-off-by: default avatarAleksandar Markovic <amarkovic@wavecomp.com>
parent 20b28ebc
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -446,6 +446,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
+1 −0
Original line number Diff line number Diff line
@@ -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)
+3 −2
Original line number Diff line number Diff line
@@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = {

const VMStateDescription vmstate_mips_cpu = {
    .name = "cpu",
    .version_id = 14,
    .minimum_version_id = 14,
    .version_id = 15,
    .minimum_version_id = 15,
    .post_load = cpu_post_load,
    .fields = (VMStateField[]) {
        /* Active TC */
@@ -260,6 +260,7 @@ const VMStateDescription vmstate_mips_cpu = {
        VMSTATE_UINTTL(env.CP0_PWField, MIPSCPU),
        VMSTATE_UINTTL(env.CP0_PWSize, MIPSCPU),
        VMSTATE_INT32(env.CP0_Wired, MIPSCPU),
        VMSTATE_INT32(env.CP0_PWCtl, MIPSCPU),
        VMSTATE_INT32(env.CP0_SRSConf0, MIPSCPU),
        VMSTATE_INT32(env.CP0_SRSConf1, MIPSCPU),
        VMSTATE_INT32(env.CP0_SRSConf2, MIPSCPU),
+10 −0
Original line number Diff line number Diff line
@@ -1527,6 +1527,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;
+20 −0
Original line number Diff line number Diff line
@@ -6151,6 +6151,11 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
            rn = "SRSConf4";
            break;
        case 6:
            check_pw(ctx);
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
            rn = "PWCtl";
            break;
        default:
            goto cp0_unimplemented;
        }
@@ -6867,6 +6872,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
            gen_helper_mtc0_srsconf4(cpu_env, arg);
            rn = "SRSConf4";
            break;
        case 6:
            check_pw(ctx);
            gen_helper_mtc0_pwctl(cpu_env, arg);
            rn = "PWCtl";
            break;
        default:
            goto cp0_unimplemented;
        }
@@ -7592,6 +7602,11 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
            rn = "SRSConf4";
            break;
        case 6:
            check_pw(ctx);
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
            rn = "PWCtl";
            break;
        default:
            goto cp0_unimplemented;
        }
@@ -8290,6 +8305,11 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
            gen_helper_mtc0_srsconf4(cpu_env, arg);
            rn = "SRSConf4";
            break;
        case 6:
            check_pw(ctx);
            gen_helper_mtc0_pwctl(cpu_env, arg);
            rn = "PWCtl";
            break;
        default:
            goto cp0_unimplemented;
        }