From bc2df1afb92435da6fb16310dac6b722bfaade9f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 28 Feb 2013 19:26:12 +0000 Subject: [PATCH] x86: Permit bootstage and timer data to be used prior to relocation 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 --- 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 9c9431e0d9..f8e28f0c82 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 dd30a05a9d..6dc74e34c6 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 8a96fc96e8..2f84abd785 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 a13424b3e3..1f8ce609e2 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; } -- 2.39.5