diff --git a/src/mainboard/intel/bayleybay/romstage.c b/src/mainboard/intel/bayleybay/romstage.c index 318fa1d4d1..f8451731b8 100644 --- a/src/mainboard/intel/bayleybay/romstage.c +++ b/src/mainboard/intel/bayleybay/romstage.c @@ -23,7 +23,7 @@ #include #include -void mainboard_romstage_entry(unsigned long bist) +void mainboard_romstage_entry(struct romstage_params *rp) { struct mrc_params mp = { .mainboard = { @@ -32,8 +32,6 @@ void mainboard_romstage_entry(unsigned long bist) .spd_addrs = { 0xa0, 0xa2 }, }, }; - struct romstage_params rp = { - .mrc_params = &mp, - }; - romstage_common(&rp); + rp->mrc_params = ∓ + romstage_common(rp); } diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig index 5a142946ee..327063c3c5 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 397778d208..4707d2b8d9 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 #include #include +#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..f565775ed8 --- /dev/null +++ b/src/soc/intel/baytrail/bootblock/timestamp.inc @@ -0,0 +1,19 @@ +/* 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 8b07f31848..557e123e7b 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 dedbad2317..e09cb106a2 100644 --- a/src/soc/intel/baytrail/romstage/romstage.c +++ b/src/soc/intel/baytrail/romstage/romstage.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -69,17 +70,36 @@ static void program_base_addresses(void) pci_write_config32(lpc_dev, GBASE, reg); } -/* Entry from cache-as-ram.inc. */ -void * asmlinkage romstage_main(unsigned long bist) +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, + 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 +111,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(params->ts.times[0]); + timestamp_add(TS_START_ROMSTAGE, params->ts.times[1]); + timestamp_add(TS_BEFORE_INITRAM, params->ts.times[2]); + timestamp_add(TS_AFTER_INITRAM, params->ts.times[3]); } static void open_up_spi(void) @@ -117,6 +146,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);