PPC64: Fix timebase
authorAlexander Graf <agraf@suse.de>
Mon, 21 Dec 2009 11:24:17 +0000 (12:24 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Mon, 21 Dec 2009 12:42:37 +0000 (13:42 +0100)
On PPC we have a 64-bit time base. Usually (PPC32) this is accessed using
two separate 32 bit SPR accesses to SPR_TBU and SPR_TBL.

On PPC64 the SPR_TBL register acts as 64 bit though, so we get the full
64 bits as return value. If we only take the lower ones, fine. But Linux
wants to see all 64 bits or it breaks.

This patch makes PPC64 Linux work even after TB crossed the 32-bit boundary,
which usually happened a few seconds after bootup.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
darwin-user/main.c
hw/ppc.c
linux-user/main.c
target-ppc/cpu.h
target-ppc/op_helper.c

index 5fd314ecd9ca67836dbbfd81b026c5843ee7a488..2f4a0f827bb07d82475bb2db4e5a246658365719 100644 (file)
@@ -82,9 +82,9 @@ static inline uint64_t cpu_ppc_get_tb (CPUState *env)
     return 0;
 }
 
-uint32_t cpu_ppc_load_tbl (CPUState *env)
+uint64_t cpu_ppc_load_tbl (CPUState *env)
 {
-    return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
+    return cpu_ppc_get_tb(env);
 }
 
 uint32_t cpu_ppc_load_tbu (CPUState *env)
index 52080394fe74fb2d3aaf9ef36445b4755a71e5f7..b4bf2d37a2f56810516376c974a12fae24755ed4 100644 (file)
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -401,7 +401,7 @@ static inline uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk,
     return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset;
 }
 
-uint32_t cpu_ppc_load_tbl (CPUState *env)
+uint64_t cpu_ppc_load_tbl (CPUState *env)
 {
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
@@ -409,7 +409,7 @@ uint32_t cpu_ppc_load_tbl (CPUState *env)
     tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
     LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
 
-    return tb & 0xFFFFFFFF;
+    return tb;
 }
 
 static inline uint32_t _cpu_ppc_load_tbu(CPUState *env)
index 12502ad17325e66cf8f75b1347fa052d02ba7645..5aa9daceb6d35e3fa7f2c4adfa3566768349dd7e 100644 (file)
@@ -1068,9 +1068,9 @@ static inline uint64_t cpu_ppc_get_tb (CPUState *env)
     return 0;
 }
 
-uint32_t cpu_ppc_load_tbl (CPUState *env)
+uint64_t cpu_ppc_load_tbl (CPUState *env)
 {
-    return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
+    return cpu_ppc_get_tb(env);
 }
 
 uint32_t cpu_ppc_load_tbu (CPUState *env)
index 2535cbc0c5a8bc15a18aae0bd3f2263a0669eed2..2dc301d1e32b3354be18e98d949bf7a4a94bf2e4 100644 (file)
@@ -741,7 +741,7 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
 
 /* Time-base and decrementer management */
 #ifndef NO_CPU_IO_DEFS
-uint32_t cpu_ppc_load_tbl (CPUPPCState *env);
+uint64_t cpu_ppc_load_tbl (CPUPPCState *env);
 uint32_t cpu_ppc_load_tbu (CPUPPCState *env);
 void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value);
 void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value);
index e3bd29cc10209c19b43efa1da1365fb70b2c0e6f..e7bcd71f97080fec714be1aa751ff1eb031ef4e9 100644 (file)
@@ -68,7 +68,7 @@ void helper_store_dump_spr (uint32_t sprn)
 
 target_ulong helper_load_tbl (void)
 {
-    return cpu_ppc_load_tbl(env);
+    return (target_ulong)cpu_ppc_load_tbl(env);
 }
 
 target_ulong helper_load_tbu (void)