diff options
| author | Simon Glass <sjg@chromium.org> | 2013-02-28 19:26:12 +0000 | 
|---|---|---|
| committer | Simon Glass <sjg@chromium.org> | 2013-03-04 15:57:36 -0800 | 
| commit | bc2df1afb92435da6fb16310dac6b722bfaade9f (patch) | |
| tree | cd10c393aba37399a0e80a3045a0543e44176003 | |
| parent | 8937140957eb91060b766781bb3a9e2b191529a5 (diff) | |
| download | olio-uboot-2014.01-bc2df1afb92435da6fb16310dac6b722bfaade9f.tar.xz olio-uboot-2014.01-bc2df1afb92435da6fb16310dac6b722bfaade9f.zip | |
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 <sjg@chromium.org>
| -rw-r--r-- | arch/x86/cpu/coreboot/coreboot.c | 15 | ||||
| -rw-r--r-- | arch/x86/cpu/interrupts.c | 7 | ||||
| -rw-r--r-- | arch/x86/include/asm/global_data.h | 3 | ||||
| -rw-r--r-- | 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 9c9431e0d..f8e28f0c8 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 dd30a05a9..6dc74e34c 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 8a96fc96e..2f84abd78 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 a13424b3e..1f8ce609e 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;  } |