Skip to content

Commit e8291ec

Browse files
committed
target/ppc: fix timebase register reset state
(H)DEC and PURR get reset before icount does, which causes them to be skewed and not match the init state. This can cause replay to not match the recorded trace exactly. For DEC and HDEC this is usually not noticable since they tend to get programmed before affecting the target machine. PURR has been observed to cause replay bugs when running Linux. Fix this by resetting using a time of 0. Message-ID: <[email protected]> Signed-off-by: Nicholas Piggin <[email protected]>
1 parent 5f7d861 commit e8291ec

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

hw/ppc/ppc.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,16 +1123,21 @@ void cpu_ppc_tb_reset(CPUPPCState *env)
11231123
timer_del(tb_env->hdecr_timer);
11241124
ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0);
11251125
tb_env->hdecr_next = 0;
1126+
_cpu_ppc_store_hdecr(cpu, 0, 0, 0, 64);
11261127
}
11271128

11281129
/*
11291130
* There is a bug in Linux 2.4 kernels:
11301131
* if a decrementer exception is pending when it enables msr_ee at startup,
11311132
* it's not ready to handle it...
1133+
*
1134+
* On machine reset, this is called before icount is reset, so for
1135+
* icount-mode, setting TB registers using now == qemu_clock_get_ns()
1136+
* results in them being garbage after icount is reset. Use an
1137+
* explicit now == 0 to get a consistent reset state.
11321138
*/
1133-
cpu_ppc_store_decr(env, -1);
1134-
cpu_ppc_store_hdecr(env, -1);
1135-
cpu_ppc_store_purr(env, 0x0000000000000000ULL);
1139+
_cpu_ppc_store_decr(cpu, 0, 0, -1, 64);
1140+
_cpu_ppc_store_purr(env, 0, 0);
11361141
}
11371142

11381143
void cpu_ppc_tb_free(CPUPPCState *env)

0 commit comments

Comments
 (0)