diff options
-rw-r--r-- | src/soc/intel/baytrail/Kconfig | 1 | ||||
-rw-r--r-- | src/soc/intel/baytrail/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/romstage.h | 16 | ||||
-rw-r--r-- | src/soc/intel/baytrail/bootblock/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/baytrail/bootblock/timestamp.inc | 18 | ||||
-rw-r--r-- | src/soc/intel/baytrail/romstage/cache_as_ram.inc | 6 | ||||
-rw-r--r-- | src/soc/intel/baytrail/romstage/romstage.c | 51 |
7 files changed, 88 insertions, 6 deletions
diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig index deee31a708..71a40c1ff4 100644 --- a/src/soc/intel/baytrail/Kconfig +++ b/src/soc/intel/baytrail/Kconfig @@ -25,6 +25,7 @@ config CPU_SPECIFIC_OPTIONS select CACHE_MRC_SETTINGS select CACHE_ROM select SPI_FLASH + select COLLECT_TIMESTAMPS config BOOTBLOCK_CPU_INIT string diff --git a/src/soc/intel/baytrail/Makefile.inc b/src/soc/intel/baytrail/Makefile.inc index ebcda6b93e..b4474c05a3 100644 --- a/src/soc/intel/baytrail/Makefile.inc +++ b/src/soc/intel/baytrail/Makefile.inc @@ -1,3 +1,4 @@ +subdirs-y += bootblock subdirs-y += microcode subdirs-y += romstage subdirs-y += ../../../cpu/x86/lapic diff --git a/src/soc/intel/baytrail/baytrail/romstage.h b/src/soc/intel/baytrail/baytrail/romstage.h index 6c622e19e7..b797e8e82b 100644 --- a/src/soc/intel/baytrail/baytrail/romstage.h +++ b/src/soc/intel/baytrail/baytrail/romstage.h @@ -24,16 +24,26 @@ #error "Don't include romstage.h from a ramstage compilation unit!" #endif +#include <stdint.h> #include <arch/cpu.h> #include <baytrail/mrc_wrapper.h> +#define NUM_ROMSTAGE_TS 4 +struct romstage_timestamps { + uint64_t times[NUM_ROMSTAGE_TS]; + int count; +}; + struct romstage_params { + struct romstage_timestamps ts; + unsigned long bist; struct mrc_params *mrc_params; }; -void mainboard_romstage_entry(unsigned long bist); -void romstage_common(const struct romstage_params *params); -void * asmlinkage romstage_main(unsigned long bist); +void mainboard_romstage_entry(struct romstage_params *params); +void romstage_common(struct romstage_params *params); +void * asmlinkage romstage_main(unsigned long bist, uint32_t tsc_lo, + uint32_t tsc_high); void asmlinkage romstage_after_car(void); void raminit(struct mrc_params *mp, int prev_sleep_state); void gfx_init(void); diff --git a/src/soc/intel/baytrail/bootblock/Makefile.inc b/src/soc/intel/baytrail/bootblock/Makefile.inc new file mode 100644 index 0000000000..3a4025198c --- /dev/null +++ b/src/soc/intel/baytrail/bootblock/Makefile.inc @@ -0,0 +1 @@ +chipset_bootblock_inc += $(src)/soc/intel/baytrail/bootblock/timestamp.inc diff --git a/src/soc/intel/baytrail/bootblock/timestamp.inc b/src/soc/intel/baytrail/bootblock/timestamp.inc new file mode 100644 index 0000000000..3db5c35c4d --- /dev/null +++ b/src/soc/intel/baytrail/bootblock/timestamp.inc @@ -0,0 +1,18 @@ +/* Store the initial timestamp for booting in mmx registers. This works + * because the bootblock isn't being compiled with MMX support so mm0 and + * mm1 will be preserved into romstage. */ + .code32 + +.global stash_timestamp +stash_timestamp: + + /* Save the BIST value */ + movl %eax, %ebp + + finit + rdtsc + movd %eax, %mm0 + movd %edx, %mm1 + + /* Restore the BIST value to %eax */ + movl %ebp, %eax diff --git a/src/soc/intel/baytrail/romstage/cache_as_ram.inc b/src/soc/intel/baytrail/romstage/cache_as_ram.inc index 920fbe4b09..82c77e2b16 100644 --- a/src/soc/intel/baytrail/romstage/cache_as_ram.inc +++ b/src/soc/intel/baytrail/romstage/cache_as_ram.inc @@ -169,6 +169,12 @@ wait_for_sipi: movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax movl %eax, %esp + /* Push the initial TSC value from boot block. The low 32 bits are + * in mm0, and the high 32 bits are in mm1. */ + movd %mm1, %eax + pushl %eax + movd %mm0, %eax + pushl %eax /* Restore the BIST result. */ movl %ebp, %eax movl %esp, %ebp diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c index e4e6fdecee..8a65f06857 100644 --- a/src/soc/intel/baytrail/romstage/romstage.c +++ b/src/soc/intel/baytrail/romstage/romstage.c @@ -26,6 +26,7 @@ #include <cbmem.h> #include <cpu/x86/mtrr.h> #include <romstage_handoff.h> +#include <timestamp.h> #include <baytrail/gpio.h> #include <baytrail/iomap.h> #include <baytrail/iosf.h> @@ -33,6 +34,20 @@ #include <baytrail/pci_devs.h> #include <baytrail/romstage.h> +static inline uint64_t timestamp_get(void) +{ + return rdtscll(); +} + +static inline tsc_t ts64_to_tsc(uint64_t ts) +{ + tsc_t tsc = { + .lo = ts, + .hi = ts >> 32, + }; + return tsc; +} + /* The cache-as-ram assembly file calls romstage_main() after setting up * cache-as-ram. romstage_main() will then call the mainboards's * mainboard_romstage_entry() function. That function then calls @@ -69,17 +84,36 @@ static void program_base_addresses(void) pci_write_config32(lpc_dev, GBASE, reg); } +static inline void mark_ts(struct romstage_params *rp, uint64_t ts) +{ + struct romstage_timestamps *rt = &rp->ts; + + rt->times[rt->count] = ts; + rt->count++; +} + /* Entry from cache-as-ram.inc. */ -void * asmlinkage romstage_main(unsigned long bist) +void * asmlinkage romstage_main(unsigned long bist, + uint32_t tsc_low, uint32_t tsc_hi) { + struct romstage_params rp = { + .bist = bist, + .mrc_params = NULL, + }; + + /* Save initial timestamp from bootblock. */ + mark_ts(&rp, (((uint64_t)tsc_hi) << 32) | (uint64_t)tsc_low); + /* Save romstage begin */ + mark_ts(&rp, timestamp_get()); + /* Call into mainboard. */ - mainboard_romstage_entry(bist); + mainboard_romstage_entry(&rp); return setup_stack_and_mttrs(); } /* Entry from the mainboard. */ -void romstage_common(const struct romstage_params *params) +void romstage_common(struct romstage_params *params) { struct romstage_handoff *handoff; @@ -91,15 +125,24 @@ void romstage_common(const struct romstage_params *params) gfx_init(); + mark_ts(params, timestamp_get()); + /* Initialize RAM */ raminit(params->mrc_params, 5); + mark_ts(params, timestamp_get()); + handoff = romstage_handoff_find_or_add(); if (handoff != NULL) handoff->s3_resume = 0; else printk(BIOS_DEBUG, "Romstage handoff structure not added!\n"); + /* Save timestamp information. */ + timestamp_init(ts64_to_tsc(params->ts.times[0])); + timestamp_add(TS_START_ROMSTAGE, ts64_to_tsc(params->ts.times[1])); + timestamp_add(TS_BEFORE_INITRAM, ts64_to_tsc(params->ts.times[2])); + timestamp_add(TS_AFTER_INITRAM, ts64_to_tsc(params->ts.times[3])); } static void open_up_spi(void) @@ -117,6 +160,8 @@ void asmlinkage romstage_after_car(void) /* Allow BIOS to program SPI part. */ open_up_spi(); + timestamp_add_now(TS_END_ROMSTAGE); + /* Load the ramstage. */ copy_and_run(); while (1); |