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
     end of ramstage. Everything looks legit.

Change-Id: Iba8d5fff1654afa6471088c46a357474ba533236
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/170950
Reviewed-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: http://review.coreboot.org/4856
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Aaron Durbin 2013-09-27 11:38:36 -05:00 committed by Aaron Durbin
parent 818f369da2
commit 794bddf97c
7 changed files with 89 additions and 7 deletions

View File

@ -25,6 +25,7 @@ config CPU_SPECIFIC_OPTIONS
select CACHE_MRC_SETTINGS select CACHE_MRC_SETTINGS
select CACHE_ROM select CACHE_ROM
select SPI_FLASH select SPI_FLASH
select COLLECT_TIMESTAMPS
config BOOTBLOCK_CPU_INIT config BOOTBLOCK_CPU_INIT
string string

View File

@ -1,3 +1,4 @@
subdirs-y += bootblock
subdirs-y += microcode subdirs-y += microcode
subdirs-y += romstage subdirs-y += romstage
subdirs-y += ../../../cpu/x86/lapic subdirs-y += ../../../cpu/x86/lapic

View File

@ -24,16 +24,26 @@
#error "Don't include romstage.h from a ramstage compilation unit!" #error "Don't include romstage.h from a ramstage compilation unit!"
#endif #endif
#include <stdint.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <baytrail/mrc_wrapper.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_params {
struct romstage_timestamps ts;
unsigned long bist;
struct mrc_params *mrc_params; struct mrc_params *mrc_params;
}; };
void mainboard_romstage_entry(unsigned long bist); void mainboard_romstage_entry(struct romstage_params *params);
void romstage_common(const struct romstage_params *params); void romstage_common(struct romstage_params *params);
void * asmlinkage romstage_main(unsigned long bist); void * asmlinkage romstage_main(unsigned long bist, uint32_t tsc_lo,
uint32_t tsc_high);
void asmlinkage romstage_after_car(void); void asmlinkage romstage_after_car(void);
void raminit(struct mrc_params *mp, int prev_sleep_state); void raminit(struct mrc_params *mp, int prev_sleep_state);
void gfx_init(void); void gfx_init(void);

View File

@ -0,0 +1 @@
chipset_bootblock_inc += $(src)/soc/intel/baytrail/bootblock/timestamp.inc

View File

@ -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

View File

@ -169,6 +169,12 @@ wait_for_sipi:
movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
movl %eax, %esp 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. */ /* Restore the BIST result. */
movl %ebp, %eax movl %ebp, %eax
movl %esp, %ebp movl %esp, %ebp

View File

@ -26,6 +26,7 @@
#include <cbmem.h> #include <cbmem.h>
#include <cpu/x86/mtrr.h> #include <cpu/x86/mtrr.h>
#include <romstage_handoff.h> #include <romstage_handoff.h>
#include <timestamp.h>
#include <baytrail/gpio.h> #include <baytrail/gpio.h>
#include <baytrail/iomap.h> #include <baytrail/iomap.h>
#include <baytrail/iosf.h> #include <baytrail/iosf.h>
@ -33,6 +34,20 @@
#include <baytrail/pci_devs.h> #include <baytrail/pci_devs.h>
#include <baytrail/romstage.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 /* The cache-as-ram assembly file calls romstage_main() after setting up
* cache-as-ram. romstage_main() will then call the mainboards's * cache-as-ram. romstage_main() will then call the mainboards's
* mainboard_romstage_entry() function. That function then calls * 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); pci_write_config32(lpc_dev, GBASE, reg);
} }
/* Entry from cache-as-ram.inc. */ static inline void mark_ts(struct romstage_params *rp, uint64_t ts)
void * asmlinkage romstage_main(unsigned long bist)
{ {
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. */ /* Call into mainboard. */
mainboard_romstage_entry(bist); mainboard_romstage_entry(&rp);
return setup_stack_and_mttrs(); return setup_stack_and_mttrs();
} }
/* Entry from the mainboard. */ /* Entry from the mainboard. */
void romstage_common(const struct romstage_params *params) void romstage_common(struct romstage_params *params)
{ {
struct romstage_handoff *handoff; struct romstage_handoff *handoff;
@ -91,15 +125,24 @@ void romstage_common(const struct romstage_params *params)
gfx_init(); gfx_init();
mark_ts(params, timestamp_get());
/* Initialize RAM */ /* Initialize RAM */
raminit(params->mrc_params, 5); raminit(params->mrc_params, 5);
mark_ts(params, timestamp_get());
handoff = romstage_handoff_find_or_add(); handoff = romstage_handoff_find_or_add();
if (handoff != NULL) if (handoff != NULL)
handoff->s3_resume = 0; handoff->s3_resume = 0;
else else
printk(BIOS_DEBUG, "Romstage handoff structure not added!\n"); 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) static void open_up_spi(void)
@ -117,6 +160,8 @@ void asmlinkage romstage_after_car(void)
/* Allow BIOS to program SPI part. */ /* Allow BIOS to program SPI part. */
open_up_spi(); open_up_spi();
timestamp_add_now(TS_END_ROMSTAGE);
/* Load the ramstage. */ /* Load the ramstage. */
copy_and_run(); copy_and_run();
while (1); while (1);