diff options
author | Leon Alrae <leon.alrae@imgtec.com> | 2014-07-07 11:23:59 +0100 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2014-11-03 11:48:34 +0000 |
commit | 7207c7f9d74816c32783a394d8072d1f978157ac (patch) | |
tree | 05c22755fc89eceee9d23533de96bc06d9abdd97 /target-mips/op_helper.c | |
parent | 2fb58b73746e2f99ac85e82160277b18b18279be (diff) |
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>
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r-- | target-mips/op_helper.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 582c84e1a4..024a6a2b31 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1099,9 +1099,18 @@ void helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1) { /* Large physaddr (PABITS) 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) { 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 */ /* 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) { 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 */ /* Large physaddr (PABITS) 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) |