summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/baytrail/Kconfig1
-rw-r--r--src/soc/intel/baytrail/Makefile.inc1
-rw-r--r--src/soc/intel/baytrail/baytrail/romstage.h16
-rw-r--r--src/soc/intel/baytrail/bootblock/Makefile.inc1
-rw-r--r--src/soc/intel/baytrail/bootblock/timestamp.inc18
-rw-r--r--src/soc/intel/baytrail/romstage/cache_as_ram.inc6
-rw-r--r--src/soc/intel/baytrail/romstage/romstage.c51
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);