x86: Permit bootstage and timer data to be used prior to relocation
authorSimon Glass <sjg@chromium.org>
Thu, 28 Feb 2013 19:26:12 +0000 (19:26 +0000)
committerSimon Glass <sjg@chromium.org>
Mon, 4 Mar 2013 23:57:36 +0000 (15:57 -0800)
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@chromium.org>
arch/x86/cpu/coreboot/coreboot.c
arch/x86/cpu/interrupts.c
arch/x86/include/asm/global_data.h
arch/x86/lib/timer.c

index 9c9431e0d9dc3f869884f6b10d2d4c0bd147d4ef..f8e28f0c829de8665963328dd3e2208f38193b68 100644 (file)
@@ -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);
index dd30a05a9ddf54a97d69a62e29aa26c7e3bd0106..6dc74e34c60f81d8ac5d2237a66c93345db852a3 100644 (file)
@@ -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
index 8a96fc96e8d760ebbbd2329d46c0a50c29fd2980..2f84abd7856cfe441a283b657539f99b70068de9 100644 (file)
@@ -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
index a13424b3e378ce14819ca445afb9109c60874359..1f8ce609e2e4b402b4660619d179c4cc516015cb 100644 (file)
@@ -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;
 }