Furquan Shaikh (furquan@google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15457
-gerrit
commit b7b2b7654b5e54e483a8c2c6777eb1dc698f78e5 Author: Furquan Shaikh furquan@google.com Date: Mon Jun 27 15:16:42 2016 -0700
vbnv: Flush vbnv cache if it is dirty
Maintain a flag to indicate if the cache is dirty (i.e. if the cache content was updated in vbnv layer). Add a new API to allow caller to update the vbnv cache on storage based on either: 1. Update requested by caller, or 2. Cache is dirty
Change-Id: I239939d5f9731d89a9d53fe662321b93fc1ab113 Signed-off-by: Furquan Shaikh furquan@google.com --- src/vendorcode/google/chromeos/vbnv.c | 22 +++++++++++++++++++++- src/vendorcode/google/chromeos/vbnv.h | 1 + .../google/chromeos/vboot2/vboot_logic.c | 9 ++++----- 3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/vendorcode/google/chromeos/vbnv.c b/src/vendorcode/google/chromeos/vbnv.c index 92f03fb..3f70662 100644 --- a/src/vendorcode/google/chromeos/vbnv.c +++ b/src/vendorcode/google/chromeos/vbnv.c @@ -14,6 +14,7 @@ */
#include <arch/early_variables.h> +#include <console/console.h> #include <string.h> #include <types.h> #include "chromeos.h" @@ -21,6 +22,7 @@ #include "vbnv_layout.h"
static int vbnv_initialized CAR_GLOBAL; +static int vbnv_dirty CAR_GLOBAL; static uint8_t vbnv[VBNV_BLOCK_SIZE] CAR_GLOBAL;
/* Wrappers for accessing the variables marked as CAR_GLOBAL. */ @@ -67,6 +69,7 @@ static void reset_vbnv(uint8_t *vbnv_copy) HEADER_FIRMWARE_SETTINGS_RESET | HEADER_KERNEL_SETTINGS_RESET; vbnv_copy[CRC_OFFSET] = crc8_vbnv(vbnv_copy, CRC_OFFSET); + car_set_var(vbnv_dirty, 1); }
/* Read VBNV data into cache. */ @@ -103,9 +106,17 @@ void read_vbnv(uint8_t *vbnv_copy) /* * Write VBNV data to configured storage backend. * This assumes that the caller has updated the CRC already. + * Checks to see if upper layer requests update or if cache is dirty. If not, + * vbnv is not updated. */ -void save_vbnv(const uint8_t *vbnv_copy) +void save_vbnv_if_needed(const uint8_t *vbnv_copy, bool update) { + /* Bail out if upper layer doesn't require update and cache is clean. */ + if (!update && !car_get_var(vbnv_dirty)) + return; + + printk(BIOS_INFO, "Saving nvdata\n"); + if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)) save_vbnv_cmos(vbnv_copy); else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_EC)) @@ -115,6 +126,15 @@ void save_vbnv(const uint8_t *vbnv_copy)
/* Clear initialized flag to force cached data to be updated */ car_set_var(vbnv_initialized, 0); + + /* Clear dirty flag to indicate that cache was flushed. */ + car_set_var(vbnv_dirty, 0); +} + +/* Wrapper function to force vbnv update. */ +void save_vbnv(const uint8_t *vbnv_copy) +{ + save_vbnv_if_needed(vbnv_copy, true); }
/* Save a recovery reason into VBNV. */ diff --git a/src/vendorcode/google/chromeos/vbnv.h b/src/vendorcode/google/chromeos/vbnv.h index 5d21cc8..b19b11a 100644 --- a/src/vendorcode/google/chromeos/vbnv.h +++ b/src/vendorcode/google/chromeos/vbnv.h @@ -20,6 +20,7 @@
/* Generic functions */ void read_vbnv(uint8_t *vbnv_copy); +void save_vbnv_if_needed(const uint8_t *vbnv_copy, bool update); void save_vbnv(const uint8_t *vbnv_copy); int verify_vbnv(uint8_t *vbnv_copy); int get_recovery_mode_from_vbnv(void); diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c index a81a9c2..a5ff68a 100644 --- a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c +++ b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c @@ -266,11 +266,10 @@ static int locate_firmware(struct vb2_context *ctx, */ static void save_if_needed(struct vb2_context *ctx) { - if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) { - printk(BIOS_INFO, "Saving nvdata\n"); - save_vbnv(ctx->nvdata); - ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED; - } + save_vbnv_if_needed(ctx->nvdata, !!(ctx->flags & + VB2_CONTEXT_NVDATA_CHANGED)); + ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED; + if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) { printk(BIOS_INFO, "Saving secdata\n"); antirollback_write_space_firmware(ctx);