target-mips: update PageGrain and m{t,f}c0 EntryLo{0,1}
PageGrain needs rw bitmask which differs between MIPS architectures. In pre-R6 if RIXI is supported, PageGrain.XIE and PageGrain.RIE are writeable, whereas in R6 they are read-only 1. On MIPS64 mtc0 instruction left shifts bits 31:30 for MIPS32 backward compatiblity, therefore there are separate mtc0 and dmtc0 helpers. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
This commit is contained in:
parent
2fb58b7374
commit
7207c7f9d7
@ -243,7 +243,10 @@ struct CPUMIPSState {
|
|||||||
target_ulong CP0_Context;
|
target_ulong CP0_Context;
|
||||||
target_ulong CP0_KScratch[MIPS_KSCRATCH_NUM];
|
target_ulong CP0_KScratch[MIPS_KSCRATCH_NUM];
|
||||||
int32_t CP0_PageMask;
|
int32_t CP0_PageMask;
|
||||||
|
int32_t CP0_PageGrain_rw_bitmask;
|
||||||
int32_t CP0_PageGrain;
|
int32_t CP0_PageGrain;
|
||||||
|
#define CP0PG_RIE 31
|
||||||
|
#define CP0PG_XIE 30
|
||||||
int32_t CP0_Wired;
|
int32_t CP0_Wired;
|
||||||
int32_t CP0_SRSConf0_rw_bitmask;
|
int32_t CP0_SRSConf0_rw_bitmask;
|
||||||
int32_t CP0_SRSConf0;
|
int32_t CP0_SRSConf0;
|
||||||
@ -377,6 +380,7 @@ struct CPUMIPSState {
|
|||||||
#define CP0C3_M 31
|
#define CP0C3_M 31
|
||||||
#define CP0C3_ISA_ON_EXC 16
|
#define CP0C3_ISA_ON_EXC 16
|
||||||
#define CP0C3_ULRI 13
|
#define CP0C3_ULRI 13
|
||||||
|
#define CP0C3_RXI 12
|
||||||
#define CP0C3_DSPP 10
|
#define CP0C3_DSPP 10
|
||||||
#define CP0C3_LPA 7
|
#define CP0C3_LPA 7
|
||||||
#define CP0C3_VEIC 6
|
#define CP0C3_VEIC 6
|
||||||
|
@ -152,6 +152,11 @@ DEF_HELPER_2(mtc0_datalo, void, env, tl)
|
|||||||
DEF_HELPER_2(mtc0_taghi, void, env, tl)
|
DEF_HELPER_2(mtc0_taghi, void, env, tl)
|
||||||
DEF_HELPER_2(mtc0_datahi, void, env, tl)
|
DEF_HELPER_2(mtc0_datahi, void, env, tl)
|
||||||
|
|
||||||
|
#if defined(TARGET_MIPS64)
|
||||||
|
DEF_HELPER_2(dmtc0_entrylo0, void, env, i64)
|
||||||
|
DEF_HELPER_2(dmtc0_entrylo1, void, env, i64)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* MIPS MT functions */
|
/* MIPS MT functions */
|
||||||
DEF_HELPER_2(mftgpr, tl, env, i32)
|
DEF_HELPER_2(mftgpr, tl, env, i32)
|
||||||
DEF_HELPER_2(mftlo, tl, env, i32)
|
DEF_HELPER_2(mftlo, tl, env, i32)
|
||||||
|
@ -1099,9 +1099,18 @@ void helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1)
|
|||||||
{
|
{
|
||||||
/* Large physaddr (PABITS) not implemented */
|
/* Large physaddr (PABITS) not implemented */
|
||||||
/* 1k pages not implemented */
|
/* 1k pages not implemented */
|
||||||
env->CP0_EntryLo0 = arg1 & 0x3FFFFFFF;
|
target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
|
||||||
|
env->CP0_EntryLo0 = (arg1 & 0x3FFFFFFF) | (rxi << (CP0EnLo_XI - 30));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(TARGET_MIPS64)
|
||||||
|
void helper_dmtc0_entrylo0(CPUMIPSState *env, uint64_t arg1)
|
||||||
|
{
|
||||||
|
uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
|
||||||
|
env->CP0_EntryLo0 = (arg1 & 0x3FFFFFFF) | rxi;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void helper_mtc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
|
void helper_mtc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
|
||||||
{
|
{
|
||||||
uint32_t mask = env->CP0_TCStatus_rw_bitmask;
|
uint32_t mask = env->CP0_TCStatus_rw_bitmask;
|
||||||
@ -1266,9 +1275,18 @@ void helper_mtc0_entrylo1(CPUMIPSState *env, target_ulong arg1)
|
|||||||
{
|
{
|
||||||
/* Large physaddr (PABITS) not implemented */
|
/* Large physaddr (PABITS) not implemented */
|
||||||
/* 1k pages not implemented */
|
/* 1k pages not implemented */
|
||||||
env->CP0_EntryLo1 = arg1 & 0x3FFFFFFF;
|
target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
|
||||||
|
env->CP0_EntryLo1 = (arg1 & 0x3FFFFFFF) | (rxi << (CP0EnLo_XI - 30));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(TARGET_MIPS64)
|
||||||
|
void helper_dmtc0_entrylo1(CPUMIPSState *env, uint64_t arg1)
|
||||||
|
{
|
||||||
|
uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
|
||||||
|
env->CP0_EntryLo1 = (arg1 & 0x3FFFFFFF) | rxi;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void helper_mtc0_context(CPUMIPSState *env, target_ulong arg1)
|
void helper_mtc0_context(CPUMIPSState *env, target_ulong arg1)
|
||||||
{
|
{
|
||||||
env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (arg1 & ~0x007FFFFF);
|
env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (arg1 & ~0x007FFFFF);
|
||||||
@ -1285,7 +1303,8 @@ void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
|
|||||||
/* SmartMIPS not implemented */
|
/* SmartMIPS not implemented */
|
||||||
/* Large physaddr (PABITS) not implemented */
|
/* Large physaddr (PABITS) not implemented */
|
||||||
/* 1k pages not implemented */
|
/* 1k pages not implemented */
|
||||||
env->CP0_PageGrain = 0;
|
env->CP0_PageGrain = (arg1 & env->CP0_PageGrain_rw_bitmask) |
|
||||||
|
(env->CP0_PageGrain & ~env->CP0_PageGrain_rw_bitmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
|
void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
|
||||||
|
@ -1171,6 +1171,7 @@ typedef struct DisasContext {
|
|||||||
target_ulong btarget;
|
target_ulong btarget;
|
||||||
bool ulri;
|
bool ulri;
|
||||||
int kscrexist;
|
int kscrexist;
|
||||||
|
bool rxi;
|
||||||
} DisasContext;
|
} DisasContext;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -4659,6 +4660,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
|
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
|
||||||
|
#if defined(TARGET_MIPS64)
|
||||||
|
if (ctx->rxi) {
|
||||||
|
TCGv tmp = tcg_temp_new();
|
||||||
|
tcg_gen_andi_tl(tmp, arg, (3ull << 62));
|
||||||
|
tcg_gen_shri_tl(tmp, tmp, 32);
|
||||||
|
tcg_gen_or_tl(arg, arg, tmp);
|
||||||
|
tcg_temp_free(tmp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
tcg_gen_ext32s_tl(arg, arg);
|
tcg_gen_ext32s_tl(arg, arg);
|
||||||
rn = "EntryLo0";
|
rn = "EntryLo0";
|
||||||
break;
|
break;
|
||||||
@ -4705,6 +4715,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
|
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
|
||||||
|
#if defined(TARGET_MIPS64)
|
||||||
|
if (ctx->rxi) {
|
||||||
|
TCGv tmp = tcg_temp_new();
|
||||||
|
tcg_gen_andi_tl(tmp, arg, (3ull << 62));
|
||||||
|
tcg_gen_shri_tl(tmp, tmp, 32);
|
||||||
|
tcg_gen_or_tl(arg, arg, tmp);
|
||||||
|
tcg_temp_free(tmp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
tcg_gen_ext32s_tl(arg, arg);
|
tcg_gen_ext32s_tl(arg, arg);
|
||||||
rn = "EntryLo1";
|
rn = "EntryLo1";
|
||||||
break;
|
break;
|
||||||
@ -6480,7 +6499,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|||||||
case 2:
|
case 2:
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
gen_helper_mtc0_entrylo0(cpu_env, arg);
|
gen_helper_dmtc0_entrylo0(cpu_env, arg);
|
||||||
rn = "EntryLo0";
|
rn = "EntryLo0";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -6525,7 +6544,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|||||||
case 3:
|
case 3:
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
gen_helper_mtc0_entrylo1(cpu_env, arg);
|
gen_helper_dmtc0_entrylo1(cpu_env, arg);
|
||||||
rn = "EntryLo1";
|
rn = "EntryLo1";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -17458,6 +17477,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||||||
ctx.tb = tb;
|
ctx.tb = tb;
|
||||||
ctx.bstate = BS_NONE;
|
ctx.bstate = BS_NONE;
|
||||||
ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
|
ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
|
||||||
|
ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
|
||||||
/* Restore delay slot state from the tb context. */
|
/* Restore delay slot state from the tb context. */
|
||||||
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
|
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
|
||||||
ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
|
ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
|
||||||
@ -17840,6 +17860,8 @@ void cpu_state_reset(CPUMIPSState *env)
|
|||||||
env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
|
env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
|
||||||
env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
|
env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
|
||||||
env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
|
env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
|
||||||
|
env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
|
||||||
|
env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
|
||||||
env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
|
env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
|
||||||
env->insn_flags = env->cpu_model->insn_flags;
|
env->insn_flags = env->cpu_model->insn_flags;
|
||||||
|
|
||||||
|
@ -96,6 +96,8 @@ struct mips_def_t {
|
|||||||
int32_t CP0_SRSConf3;
|
int32_t CP0_SRSConf3;
|
||||||
int32_t CP0_SRSConf4_rw_bitmask;
|
int32_t CP0_SRSConf4_rw_bitmask;
|
||||||
int32_t CP0_SRSConf4;
|
int32_t CP0_SRSConf4;
|
||||||
|
int32_t CP0_PageGrain_rw_bitmask;
|
||||||
|
int32_t CP0_PageGrain;
|
||||||
int insn_flags;
|
int insn_flags;
|
||||||
enum mips_mmu_types mmu_type;
|
enum mips_mmu_types mmu_type;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user