[U-Boot] [PATCH v2 3/9] x86: Permit bootstage and timer data to be used prior to relocation

Simon Glass sjg at chromium.org
Fri Mar 1 06:26:12 CET 2013


It is useful to be able to access the timer before U-Boot has relocated
so that we can fully support bootstage.

Add new global_data members to support this.

Signed-off-by: Simon Glass <sjg at chromium.org>
---
Changes in v2:
- Put timer variables in arch_global_data instead of data section

 arch/x86/cpu/coreboot/coreboot.c   | 15 ++++++---------
 arch/x86/cpu/interrupts.c          |  7 +++----
 arch/x86/include/asm/global_data.h |  3 +++
 arch/x86/lib/timer.c               |  9 ++++-----
 4 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index 9c9431e..f8e28f0 100644
--- a/arch/x86/cpu/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -68,24 +68,21 @@ int board_early_init_r(void)
 void show_boot_progress(int val)
 {
 #if MIN_PORT80_KCLOCKS_DELAY
-	static uint32_t prev_stamp;
-	static uint32_t base;
-
 	/*
 	 * Scale the time counter reading to avoid using 64 bit arithmetics.
 	 * Can't use get_timer() here becuase it could be not yet
 	 * initialized or even implemented.
 	 */
-	if (!prev_stamp) {
-		base = rdtsc() / 1000;
-		prev_stamp = 0;
+	if (!gd->arch.tsc_prev) {
+		gd->arch.tsc_base_kclocks = rdtsc() / 1000;
+		gd->arch.tsc_prev = 0;
 	} else {
 		uint32_t now;
 
 		do {
-			now = rdtsc() / 1000 - base;
-		} while (now < (prev_stamp + MIN_PORT80_KCLOCKS_DELAY));
-		prev_stamp = now;
+			now = rdtsc() / 1000 - gd->arch.tsc_base_kclocks;
+		} while (now < (gd->arch.tsc_prev + MIN_PORT80_KCLOCKS_DELAY));
+		gd->arch.tsc_prev = now;
 	}
 #endif
 	outb(val, 0x80);
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index dd30a05..6dc74e3 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -626,13 +626,12 @@ asm(".globl irq_common_entry\n" \
  */
 u64 get_ticks(void)
 {
-	static u64 tick_base;
 	u64 now_tick = rdtsc();
 
-	if (!tick_base)
-		tick_base = now_tick;
+	if (!gd->arch.tsc_base)
+		gd->arch.tsc_base = now_tick;
 
-	return now_tick - tick_base;
+	return now_tick - gd->arch.tsc_base;
 }
 
 #define PLATFORM_INFO_MSR 0xce
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 8a96fc9..2f84abd 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -29,6 +29,9 @@
 /* Architecture-specific global data */
 struct arch_global_data {
 	struct global_data *gd_addr;		/* Location of Global Data */
+	uint64_t tsc_base;		/* Initial value returned by rdtsc() */
+	uint32_t tsc_base_kclocks;	/* Initial tsc as a kclocks value */
+	uint32_t tsc_prev;		/* For show_boot_progress() */
 };
 
 #endif
diff --git a/arch/x86/lib/timer.c b/arch/x86/lib/timer.c
index a13424b..1f8ce60 100644
--- a/arch/x86/lib/timer.c
+++ b/arch/x86/lib/timer.c
@@ -37,7 +37,6 @@ struct timer_isr_function {
 
 static struct timer_isr_function *first_timer_isr;
 static unsigned long system_ticks;
-static uint64_t base_value;
 
 /*
  * register_timer_isr() allows multiple architecture and board specific
@@ -102,7 +101,7 @@ ulong get_timer(ulong base)
 
 void timer_set_tsc_base(uint64_t new_base)
 {
-	base_value = new_base;
+	gd->arch.tsc_base = new_base;
 }
 
 uint64_t timer_get_tsc(void)
@@ -110,8 +109,8 @@ uint64_t timer_get_tsc(void)
 	uint64_t time_now;
 
 	time_now = rdtsc();
-	if (!base_value)
-		base_value = time_now;
+	if (!gd->arch.tsc_base)
+		gd->arch.tsc_base = time_now;
 
-	return time_now - base_value;
+	return time_now - gd->arch.tsc_base;
 }
-- 
1.8.1.3



More information about the U-Boot mailing list