From c197ccfc2502efd650d7b2ffb3fa5e446bce97c3 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Fri, 27 Sep 2013 11:38:36 -0500 Subject: [PATCH] baytrail: start collecting timestamps This commit always selects COLLECT_TIMESTAMPS and starts tracking TSC values from the early stages of bootblock. The initial timestamp value is saved in mm0 and mm1 while in bootlbock. This approach works because romcc is not configured to use mmx registers for its compilation. Additionally, the romstage api with the mainboard was changed to always pass around a pointer to a romstage_params structure as the timestamps are saved in there until ram is up. BUG=chrome-os-partner:22873 BRANCH=None TEST=Built and booted with added code to print out timestamps at and of ramstage. Everything looks legit. Change-Id: Iba8d5fff1654afa6471088c46a357474ba533236 Signed-off-by: Aaron Durbin Reviewed-on: https://chromium-review.googlesource.com/170950 Reviewed-by: Shawn Nematbakhsh --- src/mainboard/intel/bayleybay/romstage.c | 8 ++-- src/soc/intel/baytrail/Kconfig | 1 + src/soc/intel/baytrail/Makefile.inc | 1 + src/soc/intel/baytrail/baytrail/romstage.h | 16 ++++++-- src/soc/intel/baytrail/bootblock/Makefile.inc | 1 + .../intel/baytrail/bootblock/timestamp.inc | 19 +++++++++ .../intel/baytrail/romstage/cache_as_ram.inc | 6 +++ src/soc/intel/baytrail/romstage/romstage.c | 39 +++++++++++++++++-- 8 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 src/soc/intel/baytrail/bootblock/Makefile.inc create mode 100644 src/soc/intel/baytrail/bootblock/timestamp.inc 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);