From patchwork Mon Dec 21 00:22:12 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 41517 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CEAFAB6F16 for ; Mon, 21 Dec 2009 11:24:36 +1100 (EST) Received: from localhost ([127.0.0.1]:38405 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NMW4Y-0006V4-5Y for incoming@patchwork.ozlabs.org; Sun, 20 Dec 2009 19:24:26 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NMW43-0006Up-4N for qemu-devel@nongnu.org; Sun, 20 Dec 2009 19:23:55 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NMW3y-0006Tf-Aw for qemu-devel@nongnu.org; Sun, 20 Dec 2009 19:23:54 -0500 Received: from [199.232.76.173] (port=60329 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NMW3y-0006Tc-7V for qemu-devel@nongnu.org; Sun, 20 Dec 2009 19:23:50 -0500 Received: from cantor2.suse.de ([195.135.220.15]:56317 helo=mx2.suse.de) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NMW3K-0001SG-Aw for qemu-devel@nongnu.org; Sun, 20 Dec 2009 19:23:50 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id E95CC8672B; Mon, 21 Dec 2009 01:22:12 +0100 (CET) From: Alexander Graf To: qemu-devel@nongnu.org Date: Mon, 21 Dec 2009 01:22:12 +0100 Message-Id: <1261354932-28003-1-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.4-2.6 Cc: Aurelien Jarno Subject: [Qemu-devel] [PATCH] PPC64: Fix timebase X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- To verify my assumptions of the above I used this test program: int main() { unsigned int tbu=0, tbl=0; unsigned long tb=0; asm("mftbu %0" : "=r" (tbu)); asm("mftbl %0" : "=r" (tbl)); asm("mftbl %0" : "=r" (tb)); printf("TB: %#x %#x\n", tbu, tbl); printf("TB64: %#lx\n", tb); } It produces the following output on a 970MP CPU: $ ./mftb TB: 0x238 0xd676bd6 TB64: 0x2380d676f75 --- hw/ppc.c | 4 ++-- target-ppc/cpu.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/ppc.c b/hw/ppc.c index 5208039..b4bf2d3 100644 --- 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) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 2535cbc..2dc301d 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -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);