]> xenbits.xensource.com Git - qemu-xen.git/commitdiff
target/mips: Fix WatchHi.M handling
authorMarcin Nowakowski <marcin.nowakowski@fungible.com>
Wed, 26 May 2021 09:35:06 +0000 (11:35 +0200)
committerPhilippe Mathieu-Daudé <f4bug@amsat.org>
Sat, 11 Jun 2022 09:34:12 +0000 (11:34 +0200)
bit 31 (M) of WatchHiN register is a read-only register indicating
whether the next WatchHi register is present. It must not be reset
during user writes to the register.

Signed-off-by: Marcin Nowakowski <marcin.nowakowski@fungible.com>
Reviewed-by: David Daney <david.daney@fungible.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@fungible.com>
Message-Id: <20220511212953.74738-1-philmd@fungible.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
target/mips/cpu.c
target/mips/cpu.h
target/mips/tcg/sysemu/cp0_helper.c

index ad74fbe636af4346031795c7b902ff9e2760a7db..c15c9553670dea09bc960c156a7bab6b3de3d3c9 100644 (file)
@@ -305,7 +305,7 @@ static void mips_cpu_reset(DeviceState *dev)
 
         for (i = 0; i < 7; i++) {
             env->CP0_WatchLo[i] = 0;
-            env->CP0_WatchHi[i] = 0x80000000;
+            env->CP0_WatchHi[i] = 1 << CP0WH_M;
         }
         env->CP0_WatchLo[7] = 0;
         env->CP0_WatchHi[7] = 0;
index 5335ac10a3dc3b844a8d9b535ee89290f93ceb7f..6b6b8776d19cca0506fae9d98fa7b4905a2c5844 100644 (file)
@@ -1005,6 +1005,7 @@ typedef struct CPUArchState {
  */
     uint64_t CP0_WatchHi[8];
 #define CP0WH_ASID 16
+#define CP0WH_M    31
 /*
  * CP0 Register 20
  */
index aae2af6eccc68cb4c1c67ae491574138e4621538..5da11245892873cf454823e9a2075b676b6ce726 100644 (file)
@@ -1396,10 +1396,11 @@ void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
 void helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
 {
     uint64_t mask = 0x40000FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
+    uint64_t m_bit = env->CP0_WatchHi[sel] & (1 << CP0WH_M); /* read-only */
     if ((env->CP0_Config5 >> CP0C5_MI) & 1) {
         mask |= 0xFFFFFFFF00000000ULL; /* MMID */
     }
-    env->CP0_WatchHi[sel] = arg1 & mask;
+    env->CP0_WatchHi[sel] = m_bit | (arg1 & mask);
     env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
 }