diff --git a/src/boot/hardwaremain.c b/src/boot/hardwaremain.c index b08fe79d0a..c90742e190 100644 --- a/src/boot/hardwaremain.c +++ b/src/boot/hardwaremain.c @@ -58,10 +58,8 @@ void hardwaremain(int boot_complete); void hardwaremain(int boot_complete) { struct lb_memory *lb_mem; -#if CONFIG_COLLECT_TIMESTAMPS - tsc_t timestamps[6]; - timestamps[0] = rdtsc(); -#endif + + timestamp_stash(TS_START_RAMSTAGE); post_code(POST_ENTRY_RAMSTAGE); /* console_init() MUST PRECEDE ALL printk()! */ @@ -83,37 +81,27 @@ void hardwaremain(int boot_complete) /* FIXME: Is there a better way to handle this? */ init_timer(); -#if CONFIG_COLLECT_TIMESTAMPS - timestamps[1] = rdtsc(); -#endif + timestamp_stash(TS_DEVICE_ENUMERATE); /* Find the devices we don't have hard coded knowledge about. */ dev_enumerate(); post_code(POST_DEVICE_ENUMERATION_COMPLETE); -#if CONFIG_COLLECT_TIMESTAMPS - timestamps[2] = rdtsc(); -#endif + timestamp_stash(TS_DEVICE_CONFIGURE); /* Now compute and assign the bus resources. */ dev_configure(); post_code(POST_DEVICE_CONFIGURATION_COMPLETE); -#if CONFIG_COLLECT_TIMESTAMPS - timestamps[3] = rdtsc(); -#endif + timestamp_stash(TS_DEVICE_ENABLE); /* Now actually enable devices on the bus */ dev_enable(); post_code(POST_DEVICES_ENABLED); -#if CONFIG_COLLECT_TIMESTAMPS - timestamps[4] = rdtsc(); -#endif + timestamp_stash(TS_DEVICE_INITIALIZE); /* And of course initialize devices on the bus */ dev_initialize(); post_code(POST_DEVICES_INITIALIZED); -#if CONFIG_COLLECT_TIMESTAMPS - timestamps[5] = rdtsc(); -#endif + timestamp_stash(TS_DEVICE_DONE); #if CONFIG_WRITE_HIGH_TABLES cbmem_initialize(); @@ -121,13 +109,7 @@ void hardwaremain(int boot_complete) cbmemc_reinit(); #endif #endif - - timestamp_add(TS_START_RAMSTAGE, timestamps[0]); - timestamp_add(TS_DEVICE_ENUMERATE, timestamps[1]); - timestamp_add(TS_DEVICE_CONFIGURE, timestamps[2]); - timestamp_add(TS_DEVICE_ENABLE, timestamps[3]); - timestamp_add(TS_DEVICE_INITIALIZE, timestamps[4]); - timestamp_add(TS_DEVICE_DONE, timestamps[5]); + timestamp_sync(); #if CONFIG_HAVE_ACPI_RESUME suspend_resume(); diff --git a/src/include/timestamp.h b/src/include/timestamp.h index 8bf5287c69..e76716c608 100644 --- a/src/include/timestamp.h +++ b/src/include/timestamp.h @@ -57,10 +57,14 @@ enum timestamp_id { void timestamp_init(tsc_t base); void timestamp_add(enum timestamp_id id, tsc_t ts_time); void timestamp_add_now(enum timestamp_id id); +void timestamp_stash(enum timestamp_id id); +void timestamp_sync(void); #else #define timestamp_init(base) #define timestamp_add(id, time) #define timestamp_add_now(id) +#define timestamp_stash(id) +#define timestamp_sync() #endif #endif diff --git a/src/lib/timestamp.c b/src/lib/timestamp.c index bbb8197dca..2161d445db 100644 --- a/src/lib/timestamp.c +++ b/src/lib/timestamp.c @@ -21,6 +21,10 @@ #include #include #include +#ifndef __PRE_RAM__ +/* For CAR_GLOBAL... This should move out of x86 specific code */ +#include +#endif #define MAX_TIMESTAMPS 30 @@ -72,3 +76,42 @@ void timestamp_add_now(enum timestamp_id id) { timestamp_add(id, rdtsc()); } + +#ifndef __PRE_RAM__ + +#define MAX_TIMESTAMP_CACHE 8 +struct timestamp_cache { + enum timestamp_id id; + tsc_t time; +} timestamp_cache[MAX_TIMESTAMP_CACHE] CAR_GLOBAL; + +static int timestamp_entries CAR_GLOBAL = 0; + +/** + * timestamp_stash() allows to temporarily cache time stamps. + * This is needed when time stamping before the CBMEM area + * is initialized. The function timestamp_sync() is used to + * write the time stamps to the CBMEM area. This is done in + * hardwaremain() + */ + +void timestamp_stash(enum timestamp_id id) +{ + if (timestamp_entries >= MAX_TIMESTAMP_CACHE) { + printk(BIOS_ERR, "ERROR: failed to add timestamp to cache\n"); + return; + } + timestamp_cache[timestamp_entries].id = id; + timestamp_cache[timestamp_entries].time = rdtsc(); + timestamp_entries++; +} + +void timestamp_sync(void) +{ + int i; + for (i = 0; i < timestamp_entries; i++) + timestamp_add(timestamp_cache[i].id, timestamp_cache[i].time); + timestamp_entries = 0; +} + +#endif