Skip to content

Commit

Permalink
target/mips: Amend CP0 WatchHi register implementation
Browse files Browse the repository at this point in the history
WatchHi is extended by the field MemoryMapID with the GINVT instruction.
The field is accessible by MTHC0/MFHC0 in 32-bit architectures and DMTC0/
DMFC0 in 64-bit architectures.

Reviewed-by: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Message-Id: <1579883929-1517-4-git-send-email-aleksandar.markovic@rt-rk.com>
  • Loading branch information
yongbok authored and AMarkovic committed Jan 29, 2020
1 parent 6cdda0f commit feafe82
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 7 deletions.
2 changes: 1 addition & 1 deletion target/mips/cpu.h
Expand Up @@ -961,7 +961,7 @@ struct CPUMIPSState {
/*
* CP0 Register 19
*/
int32_t CP0_WatchHi[8];
uint64_t CP0_WatchHi[8];
#define CP0WH_ASID 16
/*
* CP0 Register 20
Expand Down
3 changes: 3 additions & 0 deletions target/mips/helper.h
Expand Up @@ -78,6 +78,7 @@ DEF_HELPER_1(mfc0_maar, tl, env)
DEF_HELPER_1(mfhc0_maar, tl, env)
DEF_HELPER_2(mfc0_watchlo, tl, env, i32)
DEF_HELPER_2(mfc0_watchhi, tl, env, i32)
DEF_HELPER_2(mfhc0_watchhi, tl, env, i32)
DEF_HELPER_1(mfc0_debug, tl, env)
DEF_HELPER_1(mftc0_debug, tl, env)
#ifdef TARGET_MIPS64
Expand All @@ -89,6 +90,7 @@ DEF_HELPER_1(dmfc0_tcschefback, tl, env)
DEF_HELPER_1(dmfc0_lladdr, tl, env)
DEF_HELPER_1(dmfc0_maar, tl, env)
DEF_HELPER_2(dmfc0_watchlo, tl, env, i32)
DEF_HELPER_2(dmfc0_watchhi, tl, env, i32)
DEF_HELPER_1(dmfc0_saar, tl, env)
#endif /* TARGET_MIPS64 */

Expand Down Expand Up @@ -159,6 +161,7 @@ DEF_HELPER_2(mthc0_maar, void, env, tl)
DEF_HELPER_2(mtc0_maari, void, env, tl)
DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32)
DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32)
DEF_HELPER_3(mthc0_watchhi, void, env, tl, i32)
DEF_HELPER_2(mtc0_xcontext, void, env, tl)
DEF_HELPER_2(mtc0_framemask, void, env, tl)
DEF_HELPER_2(mtc0_debug, void, env, tl)
Expand Down
6 changes: 3 additions & 3 deletions target/mips/machine.c
Expand Up @@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = {

const VMStateDescription vmstate_mips_cpu = {
.name = "cpu",
.version_id = 18,
.minimum_version_id = 18,
.version_id = 19,
.minimum_version_id = 19,
.post_load = cpu_post_load,
.fields = (VMStateField[]) {
/* Active TC */
Expand Down Expand Up @@ -296,7 +296,7 @@ const VMStateDescription vmstate_mips_cpu = {
VMSTATE_INT32(env.CP0_MAARI, MIPSCPU),
VMSTATE_UINTTL(env.lladdr, MIPSCPU),
VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8),
VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
VMSTATE_UINT64_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU),
VMSTATE_INT32(env.CP0_Framemask, MIPSCPU),
VMSTATE_INT32(env.CP0_Debug, MIPSCPU),
Expand Down
23 changes: 21 additions & 2 deletions target/mips/op_helper.c
Expand Up @@ -945,7 +945,12 @@ target_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel)

target_ulong helper_mfc0_watchhi(CPUMIPSState *env, uint32_t sel)
{
return env->CP0_WatchHi[sel];
return (int32_t) env->CP0_WatchHi[sel];
}

target_ulong helper_mfhc0_watchhi(CPUMIPSState *env, uint32_t sel)
{
return env->CP0_WatchHi[sel] >> 32;
}

target_ulong helper_mfc0_debug(CPUMIPSState *env)
Expand Down Expand Up @@ -1016,6 +1021,11 @@ target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel)
return env->CP0_WatchLo[sel];
}

target_ulong helper_dmfc0_watchhi(CPUMIPSState *env, uint32_t sel)
{
return env->CP0_WatchHi[sel];
}

target_ulong helper_dmfc0_saar(CPUMIPSState *env)
{
if ((env->CP0_SAARI & 0x3f) < 2) {
Expand Down Expand Up @@ -1869,11 +1879,20 @@ void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)

void helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
{
int mask = 0x40000FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
uint64_t mask = 0x40000FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
if ((env->CP0_Config5 >> CP0C5_MI) & 1) {
mask |= 0xFFFFFFFF00000000ULL; /* MMID */
}
env->CP0_WatchHi[sel] = arg1 & mask;
env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
}

void helper_mthc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
{
env->CP0_WatchHi[sel] = ((uint64_t) (arg1) << 32) |
(env->CP0_WatchHi[sel] & 0x00000000ffffffffULL);
}

void helper_mtc0_xcontext(CPUMIPSState *env, target_ulong arg1)
{
target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
Expand Down
42 changes: 41 additions & 1 deletion target/mips/translate.c
Expand Up @@ -2547,6 +2547,7 @@ typedef struct DisasContext {
bool nan2008;
bool abs2008;
bool saar;
bool mi;
} DisasContext;

#define DISAS_STOP DISAS_TARGET_0
Expand Down Expand Up @@ -6783,6 +6784,25 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
goto cp0_unimplemented;
}
break;
case CP0_REGISTER_19:
switch (sel) {
case CP0_REG19__WATCHHI0:
case CP0_REG19__WATCHHI1:
case CP0_REG19__WATCHHI2:
case CP0_REG19__WATCHHI3:
case CP0_REG19__WATCHHI4:
case CP0_REG19__WATCHHI5:
case CP0_REG19__WATCHHI6:
case CP0_REG19__WATCHHI7:
/* upper 32 bits are only available when Config5MI != 0 */
CP0_CHECK(ctx->mi);
gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
register_name = "WatchHi";
break;
default:
goto cp0_unimplemented;
}
break;
case CP0_REGISTER_28:
switch (sel) {
case 0:
Expand Down Expand Up @@ -6869,6 +6889,25 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
goto cp0_unimplemented;
}
break;
case CP0_REGISTER_19:
switch (sel) {
case CP0_REG19__WATCHHI0:
case CP0_REG19__WATCHHI1:
case CP0_REG19__WATCHHI2:
case CP0_REG19__WATCHHI3:
case CP0_REG19__WATCHHI4:
case CP0_REG19__WATCHHI5:
case CP0_REG19__WATCHHI6:
case CP0_REG19__WATCHHI7:
/* upper 32 bits are only available when Config5MI != 0 */
CP0_CHECK(ctx->mi);
gen_helper_0e1i(mthc0_watchhi, arg, sel);
register_name = "WatchHi";
break;
default:
goto cp0_unimplemented;
}
break;
case CP0_REGISTER_28:
switch (sel) {
case 0:
Expand Down Expand Up @@ -8922,7 +8961,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case CP0_REG19__WATCHHI6:
case CP0_REG19__WATCHHI7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_1e0i(mfc0_watchhi, arg, sel);
gen_helper_1e0i(dmfc0_watchhi, arg, sel);
register_name = "WatchHi";
break;
default:
Expand Down Expand Up @@ -30727,6 +30766,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
restore_cpu_state(env, ctx);
#ifdef CONFIG_USER_ONLY
ctx->mem_idx = MIPS_HFLAG_UM;
Expand Down

0 comments on commit feafe82

Please sign in to comment.