diff options
author | Leon Alrae <leon.alrae@imgtec.com> | 2016-03-25 13:49:36 +0000 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2016-03-30 09:14:00 +0100 |
commit | 0d74a222c27e26fc40f4f6120c61c3f9ceaa3776 (patch) | |
tree | c2b00f3e999a86c58ff15eb43ce07421d1b90b25 /target-mips/op_helper.c | |
parent | 40d48212f934d4deab40ffe84a0f9c4c553d4742 (diff) |
target-mips: make ITC Configuration Tags accessible to the CPU
Add CP0.ErrCtl register with WST, SPR and ITC bits. In 34K and interAptiv
processors these bits are used to enable CACHE instruction access to
different arrays. When WST=0, SPR=0 and ITC=1 the CACHE instruction will
access ITC tag values.
Generally we do not model caches and we have been treating the CACHE
instruction as NOP. But since CACHE can operate on ITC Tags new
MIPS_HFLAG_ITC_CACHE hflag is introduced to generate the helper only when
CACHE is in the ITC Access mode.
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r-- | target-mips/op_helper.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 7c5669cc96..dcd44c4e55 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1632,9 +1632,31 @@ void helper_mtc0_performance0(CPUMIPSState *env, target_ulong arg1) env->CP0_Performance0 = arg1 & 0x000007ff; } +void helper_mtc0_errctl(CPUMIPSState *env, target_ulong arg1) +{ + int32_t wst = arg1 & (1 << CP0EC_WST); + int32_t spr = arg1 & (1 << CP0EC_SPR); + int32_t itc = env->itc_tag ? (arg1 & (1 << CP0EC_ITC)) : 0; + + env->CP0_ErrCtl = wst | spr | itc; + + if (itc && !wst && !spr) { + env->hflags |= MIPS_HFLAG_ITC_CACHE; + } else { + env->hflags &= ~MIPS_HFLAG_ITC_CACHE; + } +} + void helper_mtc0_taglo(CPUMIPSState *env, target_ulong arg1) { - env->CP0_TagLo = arg1 & 0xFFFFFCF6; + if (env->hflags & MIPS_HFLAG_ITC_CACHE) { + /* If CACHE instruction is configured for ITC tags then make all + CP0.TagLo bits writable. The actual write to ITC Configuration + Tag will take care of the read-only bits. */ + env->CP0_TagLo = arg1; + } else { + env->CP0_TagLo = arg1 & 0xFFFFFCF6; + } } void helper_mtc0_datalo(CPUMIPSState *env, target_ulong arg1) @@ -3781,3 +3803,19 @@ MSA_ST_DF(DF_HALF, h, cpu_stw_data) MSA_ST_DF(DF_WORD, w, cpu_stl_data) MSA_ST_DF(DF_DOUBLE, d, cpu_stq_data) #endif + +void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op) +{ +#ifndef CONFIG_USER_ONLY + target_ulong index = addr & 0x1fffffff; + if (op == 9) { + /* Index Store Tag */ + memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo, + 8, MEMTXATTRS_UNSPECIFIED); + } else if (op == 5) { + /* Index Load Tag */ + memory_region_dispatch_read(env->itc_tag, index, &env->CP0_TagLo, + 8, MEMTXATTRS_UNSPECIFIED); + } +#endif +} |