diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2011-10-12 14:06:56 -0700 |
---|---|---|
committer | Vadim Bendebury <vbendeb@chromium.org> | 2011-10-12 16:37:20 -0700 |
commit | b0c9145b37fea4f760a38dd64ff5f14a1b28b894 (patch) | |
tree | 2de69e7d0687a5b09aeb2d17540acbcdfdd36fb6 /board | |
parent | 217decb37c0a7904f08452a82285d44f98ecbb41 (diff) |
[PATCH2/2] mrc cache: Handle MRC cache data.
This change adds a chromebook-x86 platform specific initialization
which does the following:
- find MRC cache in the SPI flash using the FMAP data
- compare the cache contents passed by coreboot through CBMEM with
the contents saved in the SPI flash
- if the two do not match and the new contents would fit into the
FMAP allocated room - update the contents in the SPI flash.
BUG=chrome-os-partner:5808
TEST=manual
. build the new firmware image
. place the updated coreboot/util/cbmem/cbmem.py utility into /var
on a Stumpy (the target) configured for ssh communications
. program the new image on the target
. reboot the target and wait for it to come up to ChromeOS login screen
. run the following from the host:
(host) ssh 172.22.75.233 egrep "'(handle|prepare)_mrc'" /sys/firmware/log
prepare_mrc_cache: MRC cache not initialized?
handle_mrc_cache: cached storage mismatch (-1/2899)
(host) ssh 172.22.75.233 /var/cbmem.py| grep -A1 'time base'
time base 2194240, total entries 3
1:79,373 2:765,726 1000:1,429,038
. reboot the target and repeat the commands once it comes up
(host) ssh 172.22.75.233 /var/cbmem.py| grep -A1 'time base'
time base 2124288, total entries 3
1:48,707 2:112,177 1000:754,652
(host) ssh 172.22.75.233 egrep "'(handle|prepare)_mrc'" /sys/firmware/log
prepare_mrc_cache: at ffbff004, size b53
handle_mrc_cache: cached storage match
Observe that during first startup u-boot detects the MRC cache
mismatch (and presumably saves the new copy). During the second
startup coreboot finds the saved MRC cache blob, and u-boot reports
that the CBMEM and SPI instances are the same.
Also, observe much lower timestamp values on the second run.
Change-Id: I4ab11f9281a7eec777e98fe7a8fd1e0f6abfd859
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: http://gerrit.chromium.org/gerrit/9981
Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'board')
-rw-r--r-- | board/chromebook-x86/coreboot/coreboot.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/board/chromebook-x86/coreboot/coreboot.c b/board/chromebook-x86/coreboot/coreboot.c index c1a5e42a6e0..aae70a4739b 100644 --- a/board/chromebook-x86/coreboot/coreboot.c +++ b/board/chromebook-x86/coreboot/coreboot.c @@ -32,6 +32,8 @@ #include <asm/ic/coreboot/tables.h> #include <asm/ic/coreboot/sysinfo.h> #include <chromeos/power_management.h> +#include <chromeos/fdt_decode.h> +#include <chromeos/firmware_storage.h> #include <chromeos/common.h> #include <asm/io.h> #include <coreboot/timestamp.h> @@ -95,6 +97,87 @@ void setup_pcat_compatibility() { } +struct mrc_data_container { + u32 mrc_data_size; /* Actual total size of this structure */ + u8 mrc_data[0]; /* Variable size, platform/run time dependent */ +}; + +/** + * handle_mrc_cache: + * + * - find MRC cache in the SPI flash using the FMAP data + * - compare the cache contents passed by coreboot through CBMEM with + * the contents saved in the SPI flash + * - if the two do not match and the new contents would fit into the + * FMAP allocated room - update the contents in the SPI flash. + */ +static void handle_mrc_cache(void) +{ + struct fmap_entry fme; + struct mrc_data_container *saved_entry; + struct mrc_data_container *passed_entry; + u32 passed_size; + u32 saved_size; + + firmware_storage_t file; + + if (fdt_get_mrc_cache_base(gd->blob, &fme)) { + printf("%s: MRC cache not found\n", __func__); + return; + } + + passed_entry = (struct mrc_data_container *)lib_sysinfo.mrc_cache; + passed_size = passed_entry->mrc_data_size; + if (passed_size > fme.length) { + printf("%s: passed entry of %d won't fit into %d\n", + __func__, passed_size, fme.length); + return; + } + + /* Open firmware storage device. */ + if (firmware_storage_open_spi(&file)) { + printf("%s: failed to open SPI storage device\n", __func__); + return; + } + + saved_entry = malloc(fme.length); + if (!saved_entry) { + printf("%s: failed to allocate %d bytes\n", + __func__, fme.length); + return; + } + + if (file.read(&file, fme.offset, fme.length, saved_entry)) { + printf("%s: failed to read %d bytes\n", __func__, fme.length); + free(saved_entry); + return; + } + + saved_size = saved_entry->mrc_data_size; + if ((saved_size != passed_size) || + memcmp(passed_entry, saved_entry, passed_size)) { + printf("%s: cached storage mismatch (%d/%d)\n", __func__, + saved_size, passed_size); + if (passed_size <= fme.length) { + if (file.write(&file, fme.offset, + passed_size, passed_entry)) + printf("%s: write failed!\n", __func__); + } else { + printf("%s: passed size too big (%d)\n", + __func__, passed_size); + } + } else { + printf("%s: cached storage match\n", __func__); + } + free(saved_entry); +} + +int misc_init_r(void) +{ + handle_mrc_cache(); + return 0; +} + #ifdef CONFIG_HW_WATCHDOG void hw_watchdog_reset(void) { |