diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 9caf447..722af5e 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -465,7 +465,10 @@ struct CPUMIPSState { uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */ int insn_flags; /* Supported instruction set */ +#if defined(CONFIG_USER_ONLY) target_ulong tls_value; /* For usermode emulation */ +#endif + target_ulong CP0_ulri; CPU_COMMON diff --git a/target-mips/helper.h b/target-mips/helper.h index 1a8b86d..d1bf36b 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -111,6 +111,7 @@ DEF_HELPER_2(mtc0_tcschefback, void, env, tl) DEF_HELPER_2(mttc0_tcschefback, void, env, tl) DEF_HELPER_2(mtc0_entrylo1, void, env, tl) DEF_HELPER_2(mtc0_context, void, env, tl) +DEF_HELPER_2(mtc0_ulri, void, env, tl) DEF_HELPER_2(mtc0_pagemask, void, env, tl) DEF_HELPER_2(mtc0_pagegrain, void, env, tl) DEF_HELPER_2(mtc0_wired, void, env, tl) @@ -294,6 +295,7 @@ DEF_HELPER_1(rdhwr_cpunum, tl, env) DEF_HELPER_1(rdhwr_synci_step, tl, env) DEF_HELPER_1(rdhwr_cc, tl, env) DEF_HELPER_1(rdhwr_ccres, tl, env) +DEF_HELPER_1(rdhwr_ulri, tl, env) DEF_HELPER_2(pmon, void, env, int) DEF_HELPER_1(wait, void, env) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 8e3a6d7..37f5b48 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1253,6 +1253,11 @@ void helper_mtc0_context(CPUMIPSState *env, target_ulong arg1) env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (arg1 & ~0x007FFFFF); } +void helper_mtc0_ulri(CPUMIPSState *env, target_ulong arg1) +{ + env->CP0_ulri = arg1; +} + void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1) { /* 1k pages not implemented */ @@ -1299,7 +1304,7 @@ void helper_mtc0_srsconf4(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1) { - env->CP0_HWREna = arg1 & 0x0000000F; + env->CP0_HWREna = arg1 & 0x2000000F; } void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1) @@ -2068,6 +2073,17 @@ target_ulong helper_rdhwr_ccres(CPUMIPSState *env) return 0; } +target_ulong helper_rdhwr_ulri(CPUMIPSState *env) +{ + if ((env->hflags & MIPS_HFLAG_CP0) || + (env->CP0_HWREna & (1 << 29))) + return env->CP0_ulri; + else + helper_raise_exception(env, EXCP_RI); + + return 0; +} + void helper_pmon(CPUMIPSState *env, int function) { function /= 2; diff --git a/target-mips/translate.c b/target-mips/translate.c index e302734..b814b6d 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -4796,6 +4796,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; + case 2: + gen_helper_mtc0_ulri(cpu_env, arg); + rn = "ULRI"; + break; default: goto die; } @@ -4853,7 +4857,9 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 7: switch (sel) { case 0: +#if 0 check_insn(ctx, ISA_MIPS32R2); +#endif gen_helper_mtc0_hwrena(cpu_env, arg); rn = "HWREna"; break; @@ -5962,6 +5968,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; + case 2: + gen_helper_mtc0_ulri(cpu_env, arg); + rn = "ULRI"; + break; default: goto die; } @@ -9009,11 +9019,13 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd) { TCGv t0; +#if 0 #if !defined(CONFIG_USER_ONLY) /* The Linux kernel will emulate rdhwr if it's not supported natively. Therefore only check the ISA in system mode. */ check_insn(ctx, ISA_MIPS32R2); #endif +#endif t0 = tcg_temp_new(); switch (rd) { @@ -9045,6 +9057,10 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd) #else /* XXX: Some CPUs implement this in hardware. Not supported yet. */ + save_cpu_state(ctx, 1); + gen_helper_rdhwr_ulri(t0, cpu_env); + gen_store_gpr(t0, rt); + break; #endif default: /* Invalid */ MIPS_INVAL("rdhwr");