summaryrefslogtreecommitdiffstats
path: root/target-mips/op_helper.c
diff options
context:
space:
mode:
authorYongbok Kim2016-03-24 16:49:58 +0100
committerLeon Alrae2016-03-30 10:14:00 +0200
commitf6d4dd810983fdf3d1c9fb81838167efef63d1c8 (patch)
treef38749caeb52b4c6e6360a6c0bf8ff9bf7325a15 /target-mips/op_helper.c
parenttarget-mips: use CP0_CHECK for gen_m{f|t}hc0 (diff)
downloadqemu-f6d4dd810983fdf3d1c9fb81838167efef63d1c8.tar.gz
qemu-f6d4dd810983fdf3d1c9fb81838167efef63d1c8.tar.xz
qemu-f6d4dd810983fdf3d1c9fb81838167efef63d1c8.zip
target-mips: add MAAR, MAARI register
The MAAR register is a read/write register included in Release 5 of the architecture that defines the accessibility attributes of physical address regions. In particular, MAAR defines whether an instruction fetch or data load can speculatively access a memory region within the physical address bounds specified by MAAR. As QEMU doesn't do speculative access, hence this patch only provides ability to access the registers. Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r--target-mips/op_helper.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index dcd44c4e55..8ec1bef7d0 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -889,6 +889,16 @@ target_ulong helper_mfc0_lladdr(CPUMIPSState *env)
return (int32_t)(env->lladdr >> env->CP0_LLAddr_shift);
}
+target_ulong helper_mfc0_maar(CPUMIPSState *env)
+{
+ return (int32_t) env->CP0_MAAR[env->CP0_MAARI];
+}
+
+target_ulong helper_mfhc0_maar(CPUMIPSState *env)
+{
+ return env->CP0_MAAR[env->CP0_MAARI] >> 32;
+}
+
target_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel)
{
return (int32_t)env->CP0_WatchLo[sel];
@@ -955,6 +965,11 @@ target_ulong helper_dmfc0_lladdr(CPUMIPSState *env)
return env->lladdr >> env->CP0_LLAddr_shift;
}
+target_ulong helper_dmfc0_maar(CPUMIPSState *env)
+{
+ return env->CP0_MAAR[env->CP0_MAARI];
+}
+
target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel)
{
return env->CP0_WatchLo[sel];
@@ -1578,6 +1593,36 @@ void helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1)
env->lladdr = (env->lladdr & ~mask) | (arg1 & mask);
}
+#define MTC0_MAAR_MASK(env) \
+ ((0x1ULL << 63) | ((env->PAMask >> 4) & ~0xFFFull) | 0x3)
+
+void helper_mtc0_maar(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_MAAR[env->CP0_MAARI] = arg1 & MTC0_MAAR_MASK(env);
+}
+
+void helper_mthc0_maar(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_MAAR[env->CP0_MAARI] =
+ (((uint64_t) arg1 << 32) & MTC0_MAAR_MASK(env)) |
+ (env->CP0_MAAR[env->CP0_MAARI] & 0x00000000ffffffffULL);
+}
+
+void helper_mtc0_maari(CPUMIPSState *env, target_ulong arg1)
+{
+ int index = arg1 & 0x3f;
+ if (index == 0x3f) {
+ /* Software may write all ones to INDEX to determine the
+ maximum value supported. */
+ env->CP0_MAARI = MIPS_MAAR_MAX - 1;
+ } else if (index < MIPS_MAAR_MAX) {
+ env->CP0_MAARI = index;
+ }
+ /* Other than the all ones, if the
+ value written is not supported, then INDEX is unchanged
+ from its previous value. */
+}
+
void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
{
/* Watch exceptions for instructions, data loads, data stores