[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