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>
This commit is contained in:
parent
8937140957
commit
bc2df1afb9
|
@ -68,24 +68,21 @@ int board_early_init_r(void)
|
||||||
void show_boot_progress(int val)
|
void show_boot_progress(int val)
|
||||||
{
|
{
|
||||||
#if MIN_PORT80_KCLOCKS_DELAY
|
#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.
|
* Scale the time counter reading to avoid using 64 bit arithmetics.
|
||||||
* Can't use get_timer() here becuase it could be not yet
|
* Can't use get_timer() here becuase it could be not yet
|
||||||
* initialized or even implemented.
|
* initialized or even implemented.
|
||||||
*/
|
*/
|
||||||
if (!prev_stamp) {
|
if (!gd->arch.tsc_prev) {
|
||||||
base = rdtsc() / 1000;
|
gd->arch.tsc_base_kclocks = rdtsc() / 1000;
|
||||||
prev_stamp = 0;
|
gd->arch.tsc_prev = 0;
|
||||||
} else {
|
} else {
|
||||||
uint32_t now;
|
uint32_t now;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
now = rdtsc() / 1000 - base;
|
now = rdtsc() / 1000 - gd->arch.tsc_base_kclocks;
|
||||||
} while (now < (prev_stamp + MIN_PORT80_KCLOCKS_DELAY));
|
} while (now < (gd->arch.tsc_prev + MIN_PORT80_KCLOCKS_DELAY));
|
||||||
prev_stamp = now;
|
gd->arch.tsc_prev = now;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
outb(val, 0x80);
|
outb(val, 0x80);
|
||||||
|
|
|
@ -626,13 +626,12 @@ asm(".globl irq_common_entry\n" \
|
||||||
*/
|
*/
|
||||||
u64 get_ticks(void)
|
u64 get_ticks(void)
|
||||||
{
|
{
|
||||||
static u64 tick_base;
|
|
||||||
u64 now_tick = rdtsc();
|
u64 now_tick = rdtsc();
|
||||||
|
|
||||||
if (!tick_base)
|
if (!gd->arch.tsc_base)
|
||||||
tick_base = now_tick;
|
gd->arch.tsc_base = now_tick;
|
||||||
|
|
||||||
return now_tick - tick_base;
|
return now_tick - gd->arch.tsc_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PLATFORM_INFO_MSR 0xce
|
#define PLATFORM_INFO_MSR 0xce
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
/* Architecture-specific global data */
|
/* Architecture-specific global data */
|
||||||
struct arch_global_data {
|
struct arch_global_data {
|
||||||
struct global_data *gd_addr; /* Location of 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
|
#endif
|
||||||
|
|
|
@ -37,7 +37,6 @@ struct timer_isr_function {
|
||||||
|
|
||||||
static struct timer_isr_function *first_timer_isr;
|
static struct timer_isr_function *first_timer_isr;
|
||||||
static unsigned long system_ticks;
|
static unsigned long system_ticks;
|
||||||
static uint64_t base_value;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* register_timer_isr() allows multiple architecture and board specific
|
* 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)
|
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)
|
uint64_t timer_get_tsc(void)
|
||||||
|
@ -110,8 +109,8 @@ uint64_t timer_get_tsc(void)
|
||||||
uint64_t time_now;
|
uint64_t time_now;
|
||||||
|
|
||||||
time_now = rdtsc();
|
time_now = rdtsc();
|
||||||
if (!base_value)
|
if (!gd->arch.tsc_base)
|
||||||
base_value = time_now;
|
gd->arch.tsc_base = time_now;
|
||||||
|
|
||||||
return time_now - base_value;
|
return time_now - gd->arch.tsc_base;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue