From patchwork Thu Apr 18 02:13:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 237412 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id E3DD22C0195 for ; Thu, 18 Apr 2013 12:17:53 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 150DD4A331; Thu, 18 Apr 2013 04:17:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JFZjZYTNkSuI; Thu, 18 Apr 2013 04:17:07 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BEF084A335; Thu, 18 Apr 2013 04:15:53 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1E6B34A2C8 for ; Thu, 18 Apr 2013 04:15:46 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VxD-dAzBrd95 for ; Thu, 18 Apr 2013 04:15:44 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-qe0-f73.google.com (mail-qe0-f73.google.com [209.85.128.73]) by theia.denx.de (Postfix) with ESMTPS id 2711D4A2D1 for ; Thu, 18 Apr 2013 04:15:05 +0200 (CEST) Received: by mail-qe0-f73.google.com with SMTP id 1so235574qee.4 for ; Wed, 17 Apr 2013 19:15:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=l6z1CFfp5WGQinSZuFysV+U1vEvWBbRtxhsWiNqTkgM=; b=ZsIJiCU3tLDC6uIcqkE9tGX7X5NJqmewP564YJPAyXauLFPqrznqaF2jIKhOcqsKMb wZxF0tex5oFbNduZ7maTDtuMafsoPy5TgNx/u2dfrMPF3hh+SfPg/0cksGLrWV823l45 5sXwfBLeB2r1jlHHs0VXfwRtPeSvUAjD9VRVtPYjyRXgHwYr8aDCpAX320Fxkxxouw+K tV3j/eeVa0yMDb0V2jEahJMU80ZfGmzzQr4aPJ8U9YQXRWvMjX/25XsBqyfGXYujOHfA v5lyZCn73V51uxFXbvdiF/p+nOn0YUekBgKbAjCam7UFoLwxrXkgSSUw1KMr3uMbj7V8 /KzA== X-Received: by 10.236.223.194 with SMTP id v62mr1468499yhp.32.1366251304164; Wed, 17 Apr 2013 19:15:04 -0700 (PDT) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id s80si1875421yhe.6.2013.04.17.19.15.04 (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Wed, 17 Apr 2013 19:15:04 -0700 (PDT) Received: from kaka.mtv.corp.google.com (kaka.mtv.corp.google.com [172.22.83.1]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id 1F8175AF8E3; Wed, 17 Apr 2013 19:14:10 -0700 (PDT) Received: by kaka.mtv.corp.google.com (Postfix, from userid 121222) id 919671606B5; Wed, 17 Apr 2013 19:14:10 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Date: Wed, 17 Apr 2013 19:13:36 -0700 Message-Id: <1366251228-19884-8-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1366251228-19884-1-git-send-email-sjg@chromium.org> References: <1366251228-19884-1-git-send-email-sjg@chromium.org> X-Gm-Message-State: ALoCoQknrlKH0g4jXWoprtRgoicXd4Z6OKf7L35bu0+zDuVOksLQ/6YSx+QeJC6Ue64mMhxjv3uWj60X6ULtV03eo9OZ48iy5EI0XmpyoAQh6fa3UxH9MdMYjFFql10brv7Pu72AKT1X/arTtuqT0IJ0Mhl5vz3eUD9z+V6pkE346mCNEu0ntloIy/n5GZw76lM6q02TX2RX Cc: Graeme Russ , u-boot-review@google.com Subject: [U-Boot] [PATCH 07/19] x86: Add TSC timer X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This timer runs at a rate that can be calculated, well over 100MHz. It is ideal for accurate timing and does not need interrupt servicing. Tidy up some old broken and unneeded implementations at the same time. To provide a consistent view of boot time, we use the same time base as coreboot. Use the base timestamp supplied by coreboot as U-Boot's base time. Signed-off-by: Simon Glass base Signed-off-by: Simon Glass --- arch/x86/cpu/coreboot/timestamp.c | 4 +- arch/x86/cpu/timer.c | 3 ++ arch/x86/include/asm/u-boot-x86.h | 2 + arch/x86/lib/Makefile | 1 + arch/x86/lib/tsc_timer.c | 103 ++++++++++++++++++++++++++++++++++++++ include/configs/coreboot.h | 4 +- 6 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 arch/x86/lib/tsc_timer.c diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c index 2ca7a57..d26718e 100644 --- a/arch/x86/cpu/coreboot/timestamp.c +++ b/arch/x86/cpu/coreboot/timestamp.c @@ -39,7 +39,9 @@ static struct timestamp_table *ts_table __attribute__((section(".data"))); void timestamp_init(void) { ts_table = lib_sysinfo.tstamp_table; - timer_set_tsc_base(ts_table->base_time); +#ifdef CONFIG_SYS_X86_TSC_TIMER + timer_set_base(ts_table->base_time); +#endif timestamp_add_now(TS_U_BOOT_INITTED); } diff --git a/arch/x86/cpu/timer.c b/arch/x86/cpu/timer.c index 149109d..f95fce5 100644 --- a/arch/x86/cpu/timer.c +++ b/arch/x86/cpu/timer.c @@ -10,8 +10,11 @@ #include +/* Temporary patch to maintain bisectability, removed in next commit */ +#ifndef CONFIG_SYS_X86_TSC_TIMER unsigned long timer_get_us(void) { printf("timer_get_us used but not implemented.\n"); return 0; } +#endif diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 5a59db6..bec583f 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -39,6 +39,8 @@ void panic_puts(const char *str); void timer_isr(void *); typedef void (timer_fnc_t) (void); int register_timer_isr (timer_fnc_t *isr_func); +unsigned long get_tbclk_mhz(void); +void timer_set_base(uint64_t base); /* Architecture specific - can be in arch/x86/cpu/, arch/x86/lib/, or $(BOARD)/ */ int dram_init_f(void); diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 962593d..0bc8c2f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -37,6 +37,7 @@ COBJS-y += relocate.o COBJS-y += physmem.o COBJS-y += string.o COBJS-$(CONFIG_SYS_X86_ISR_TIMER) += timer.o +COBJS-$(CONFIG_SYS_X86_TSC_TIMER) += tsc_timer.o COBJS-$(CONFIG_VIDEO_VGA) += video.o COBJS-$(CONFIG_CMD_ZBOOT) += zimage.o diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c new file mode 100644 index 0000000..d931e5f --- /dev/null +++ b/arch/x86/lib/tsc_timer.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void timer_set_base(u64 base) +{ + gd->arch.tsc_base = base; +} + +/* + * Get the number of CPU time counter ticks since it was read first time after + * restart. This yields a free running counter guaranteed to take almost 6 + * years to wrap around even at 100GHz clock rate. + */ +u64 get_ticks(void) +{ + u64 now_tick = rdtsc(); + + /* We assume that 0 means the base hasn't been set yet */ + if (!gd->arch.tsc_base) + panic("No tick base available"); + return now_tick - gd->arch.tsc_base; +} + +#define PLATFORM_INFO_MSR 0xce + +/* Get the speed of the TSC timer in MHz */ +unsigned long get_tbclk_mhz(void) +{ + u32 ratio; + u64 platform_info = native_read_msr(PLATFORM_INFO_MSR); + + /* 100MHz times Max Non Turbo ratio */ + ratio = (platform_info >> 8) & 0xff; + return 100 * ratio; +} + +unsigned long get_tbclk(void) +{ + return get_tbclk_mhz() * 1000 * 1000; +} + +static ulong get_ms_timer(void) +{ + return (get_ticks() * 1000) / get_tbclk(); +} + +ulong get_timer(ulong base) +{ + return get_ms_timer() - base; +} + +ulong timer_get_us(void) +{ + return get_ticks() / get_tbclk_mhz(); +} + +ulong timer_get_boot_us(void) +{ + return timer_get_us(); +} + +void __udelay(unsigned long usec) +{ + u64 now = get_ticks(); + u64 stop; + + stop = now + usec * get_tbclk_mhz(); + + while ((int64_t)(stop - get_ticks()) > 0) + ; +} + +int timer_init(void) +{ + /* Nothing to do here - the timer needs no init */ + return 0; +} diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index 5bacc77..99408dc 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -38,7 +38,6 @@ #define CONFIG_SHOW_BOOT_PROGRESS #define CONFIG_LAST_STAGE_INIT #define CONFIG_SYS_VSNPRINTF -#define CONFIG_INTEL_CORE_ARCH /* Sandy bridge and ivy bridge chipsets. */ #define CONFIG_ZBOOT_32 #define CONFIG_PHYSMEM #define CONFIG_SYS_EARLY_PCI_INIT @@ -218,7 +217,6 @@ #define CONFIG_SYS_MEMTEST_END 0x01000000 #define CONFIG_SYS_LOAD_ADDR 0x100000 #define CONFIG_SYS_HZ 1000 -#define CONFIG_SYS_X86_ISR_TIMER /*----------------------------------------------------------------------- * SDRAM Configuration @@ -235,7 +233,7 @@ * CPU Features */ -#define CONFIG_SYS_GENERIC_TIMER +#define CONFIG_SYS_X86_TSC_TIMER #define CONFIG_SYS_PCAT_INTERRUPTS #define CONFIG_SYS_NUM_IRQS 16