summaryrefslogtreecommitdiff
path: root/board/chromebook-x86
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2011-10-12 14:06:56 -0700
committerVadim Bendebury <vbendeb@chromium.org>2011-10-12 16:37:20 -0700
commitb0c9145b37fea4f760a38dd64ff5f14a1b28b894 (patch)
tree2de69e7d0687a5b09aeb2d17540acbcdfdd36fb6 /board/chromebook-x86
parent217decb37c0a7904f08452a82285d44f98ecbb41 (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/chromebook-x86')
-rw-r--r--board/chromebook-x86/coreboot/coreboot.c83
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)
{