[coreboot-gerrit] Patch set updated for coreboot: chromeos: Add vbnv wrapper for the different backends

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Mon Feb 8 12:32:03 CET 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13597

-gerrit

commit 61f8cf4415c865f2cb37f729e4e6ea4bebb3c6c7
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Mon Jan 25 17:13:27 2016 -0800

    chromeos: Add vbnv wrapper for the different backends
    
    Add a wrapper around the vbnv implementations and call into the different
    backend functions from there.  Also move some of the common functions to
    the common code and simplify the backend drivers.  This will allow some
    of the code to be re-used so the CMOS backend can backup the data into
    the flash backend.
    
    One side effect of this is that the cache of VBNV was removed from CMOS
    and EC backends and moved into the VBNV wrapper, but the flash backend
    also still has a separate cache because it has more state and complexity
    in the implementation.  The wrapper cached data is not used for normal
    vbnv_read/vbnv_write because some callers need the ability to force a
    write if the backend storage is cleared (i.e. CMOS clear).
    
    BUG=chrome-os-partner:47915
    BRANCH=glados
    TEST=build and boot on chell
    
    Change-Id: I4d2e0e99af7e8a44aec77ad9991507401babcca6
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: c30f60434a64f6c0eb9ede45d48ddafff19dd24f
    Original-Change-Id: Ia97f6607c5ad837b9aa10b45211137221ccb93a0
    Original-Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/324120
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/vendorcode/google/chromeos/Makefile.inc |   5 +
 src/vendorcode/google/chromeos/chromeos.h   |   9 +-
 src/vendorcode/google/chromeos/vbnv.c       | 145 ++++++++++++++++++++++++++++
 src/vendorcode/google/chromeos/vbnv.h       |  41 ++++++++
 src/vendorcode/google/chromeos/vbnv_cmos.c  | 116 +---------------------
 src/vendorcode/google/chromeos/vbnv_ec.c    |  86 +----------------
 src/vendorcode/google/chromeos/vbnv_flash.c |  12 +--
 7 files changed, 201 insertions(+), 213 deletions(-)

diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index b6d49c2..ee8b50d 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -18,6 +18,11 @@ verstage-y += chromeos.c
 romstage-y += chromeos.c
 ramstage-y += chromeos.c
 
+bootblock-y += vbnv.c
+verstage-y += vbnv.c
+romstage-y += vbnv.c
+ramstage-y += vbnv.c
+
 bootblock-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c
 verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c
 romstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index 9dbb681..03f1516 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <bootmode.h>
 #include <rules.h>
+#include "vbnv.h"
 #include "vboot_common.h"
 #include "vboot2/misc.h"
 
@@ -27,14 +28,6 @@
 void save_chromeos_gpios(void);
 #endif
 
-/* functions implemented in vbnv.c: */
-int get_recovery_mode_from_vbnv(void);
-void set_recovery_mode_into_vbnv(int recovery_reason);
-int vboot_wants_oprom(void);
-
-void read_vbnv(uint8_t *vbnv_copy);
-void save_vbnv(const uint8_t *vbnv_copy);
-
 #if CONFIG_CHROMEOS
 /* functions implemented in elog.c */
 void elog_add_boot_reason(void);
diff --git a/src/vendorcode/google/chromeos/vbnv.c b/src/vendorcode/google/chromeos/vbnv.c
new file mode 100644
index 0000000..92f03fb
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vbnv.c
@@ -0,0 +1,145 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/early_variables.h>
+#include <string.h>
+#include <types.h>
+#include "chromeos.h"
+#include "vbnv.h"
+#include "vbnv_layout.h"
+
+static int vbnv_initialized CAR_GLOBAL;
+static uint8_t vbnv[VBNV_BLOCK_SIZE] CAR_GLOBAL;
+
+/* Wrappers for accessing the variables marked as CAR_GLOBAL. */
+static inline int is_vbnv_initialized(void)
+{
+	return car_get_var(vbnv_initialized);
+}
+
+static inline uint8_t *vbnv_data_addr(int index)
+{
+	uint8_t *vbnv_arr = car_get_var_ptr(vbnv);
+
+	return &vbnv_arr[index];
+}
+
+static inline uint8_t vbnv_data(int index)
+{
+	return *vbnv_data_addr(index);
+}
+
+/* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. */
+static uint8_t crc8_vbnv(const uint8_t *data, int len)
+{
+	unsigned crc = 0;
+	int i, j;
+
+	for (j = len; j; j--, data++) {
+		crc ^= (*data << 8);
+		for (i = 8; i; i--) {
+			if (crc & 0x8000)
+				crc ^= (0x1070 << 3);
+			crc <<= 1;
+		}
+	}
+
+	return (uint8_t) (crc >> 8);
+}
+
+/* Reset header and CRC to defaults. */
+static void reset_vbnv(uint8_t *vbnv_copy)
+{
+	memset(vbnv_copy, 0, VBNV_BLOCK_SIZE);
+	vbnv_copy[HEADER_OFFSET] = HEADER_SIGNATURE |
+				   HEADER_FIRMWARE_SETTINGS_RESET |
+				   HEADER_KERNEL_SETTINGS_RESET;
+	vbnv_copy[CRC_OFFSET] = crc8_vbnv(vbnv_copy, CRC_OFFSET);
+}
+
+/* Read VBNV data into cache. */
+static void vbnv_setup(void)
+{
+	if (!is_vbnv_initialized()) {
+		read_vbnv(vbnv_data_addr(0));
+		car_set_var(vbnv_initialized, 1);
+	}
+}
+
+/* Verify VBNV header and checksum. */
+int verify_vbnv(uint8_t *vbnv_copy)
+{
+	return (HEADER_SIGNATURE == (vbnv_copy[HEADER_OFFSET] & HEADER_MASK)) &&
+		(crc8_vbnv(vbnv_copy, CRC_OFFSET) == vbnv_copy[CRC_OFFSET]);
+}
+
+/* Read VBNV data from configured storage backend. */
+void read_vbnv(uint8_t *vbnv_copy)
+{
+	if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS))
+		read_vbnv_cmos(vbnv_copy);
+	else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_EC))
+		read_vbnv_ec(vbnv_copy);
+	else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_FLASH))
+		read_vbnv_flash(vbnv_copy);
+
+	/* Check data for consistency */
+	if (!verify_vbnv(vbnv_copy))
+		reset_vbnv(vbnv_copy);
+}
+
+/*
+ * Write VBNV data to configured storage backend.
+ * This assumes that the caller has updated the CRC already.
+ */
+void save_vbnv(const uint8_t *vbnv_copy)
+{
+	if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS))
+		save_vbnv_cmos(vbnv_copy);
+	else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_EC))
+		save_vbnv_ec(vbnv_copy);
+	else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_FLASH))
+		save_vbnv_flash(vbnv_copy);
+
+	/* Clear initialized flag to force cached data to be updated */
+	car_set_var(vbnv_initialized, 0);
+}
+
+/* Save a recovery reason into VBNV. */
+void set_recovery_mode_into_vbnv(int recovery_reason)
+{
+	uint8_t vbnv_copy[VBNV_BLOCK_SIZE];
+
+	read_vbnv(vbnv_copy);
+
+	vbnv_copy[RECOVERY_OFFSET] = recovery_reason;
+	vbnv_copy[CRC_OFFSET] = crc8_vbnv(vbnv_copy, CRC_OFFSET);
+
+	save_vbnv(vbnv_copy);
+}
+
+/* Read the recovery reason from VBNV. */
+int get_recovery_mode_from_vbnv(void)
+{
+	vbnv_setup();
+	return vbnv_data(RECOVERY_OFFSET);
+}
+
+/* Read the BOOT_OPROM_NEEDED flag from VBNV. */
+int vboot_wants_oprom(void)
+{
+	vbnv_setup();
+	return (vbnv_data(BOOT_OFFSET) & BOOT_OPROM_NEEDED) ? 1 : 0;
+}
diff --git a/src/vendorcode/google/chromeos/vbnv.h b/src/vendorcode/google/chromeos/vbnv.h
new file mode 100644
index 0000000..3d88507
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vbnv.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __CHROMEOS_VBNV_H__
+#define __CHROMEOS_VBNV_H__
+
+#include <types.h>
+
+/* Generic functions */
+void read_vbnv(uint8_t *vbnv_copy);
+void save_vbnv(const uint8_t *vbnv_copy);
+int verify_vbnv(uint8_t *vbnv_copy);
+int get_recovery_mode_from_vbnv(void);
+void set_recovery_mode_into_vbnv(int recovery_reason);
+int vboot_wants_oprom(void);
+
+/* CMOS backend */
+void read_vbnv_cmos(uint8_t *vbnv_copy);
+void save_vbnv_cmos(const uint8_t *vbnv_copy);
+
+/* Flash backend */
+void read_vbnv_flash(uint8_t *vbnv_copy);
+void save_vbnv_flash(const uint8_t *vbnv_copy);
+
+/* EC backend */
+void read_vbnv_ec(uint8_t *vbnv_copy);
+void save_vbnv_ec(const uint8_t *vbnv_copy);
+
+#endif
diff --git a/src/vendorcode/google/chromeos/vbnv_cmos.c b/src/vendorcode/google/chromeos/vbnv_cmos.c
index 27f7f0a..ddcb765 100644
--- a/src/vendorcode/google/chromeos/vbnv_cmos.c
+++ b/src/vendorcode/google/chromeos/vbnv_cmos.c
@@ -14,132 +14,22 @@
  */
 
 #include <types.h>
-#include <string.h>
-#include <cbmem.h>
-#include <console/console.h>
 #include <pc80/mc146818rtc.h>
-#include <arch/early_variables.h>
-#include "chromeos.h"
-#if IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE)
-#include "vboot_handoff.h"
-#endif
+#include "vbnv.h"
 #include "vbnv_layout.h"
 
-static int vbnv_initialized CAR_GLOBAL;
-static uint8_t vbnv[CONFIG_VBNV_SIZE] CAR_GLOBAL;
-
-/* Wrappers for accessing the variables marked as CAR_GLOBAL. */
-static inline int is_vbnv_initialized(void)
-{
-	return car_get_var(vbnv_initialized);
-}
-
-static inline uint8_t *vbnv_data_addr(int index)
-{
-	uint8_t *vbnv_arr = car_get_var_ptr(vbnv);
-
-	return &vbnv_arr[index];
-}
-
-static inline uint8_t vbnv_data(int index)
-{
-	return *vbnv_data_addr(index);
-}
-
-/* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial.  A
- * table-based algorithm would be faster, but for only 15 bytes isn't
- * worth the code size.
- */
-
-static uint8_t crc8(const uint8_t * data, int len)
-{
-	unsigned crc = 0;
-	int i, j;
-
-	for (j = len; j; j--, data++) {
-		crc ^= (*data << 8);
-		for (i = 8; i; i--) {
-			if (crc & 0x8000)
-				crc ^= (0x1070 << 3);
-			crc <<= 1;
-		}
-	}
-
-	return (uint8_t) (crc >> 8);
-}
-
-void read_vbnv(uint8_t *vbnv_copy)
+void read_vbnv_cmos(uint8_t *vbnv_copy)
 {
 	int i;
 
 	for (i = 0; i < CONFIG_VBNV_SIZE; i++)
 		vbnv_copy[i] = cmos_read(CONFIG_VBNV_OFFSET + 14 + i);
-
-	/* Check data for consistency */
-	if ((HEADER_SIGNATURE != (vbnv_copy[HEADER_OFFSET] & HEADER_MASK))
-	    || (crc8(vbnv_copy, CRC_OFFSET) != vbnv_copy[CRC_OFFSET])) {
-
-		/* Data is inconsistent (bad CRC or header),
-		 * so reset to defaults
-		 */
-		memset(vbnv_copy, 0, VBNV_BLOCK_SIZE);
-		vbnv_copy[HEADER_OFFSET] =
-		    (HEADER_SIGNATURE | HEADER_FIRMWARE_SETTINGS_RESET |
-		     HEADER_KERNEL_SETTINGS_RESET);
-	}
 }
 
-void save_vbnv(const uint8_t *vbnv_copy)
+void save_vbnv_cmos(const uint8_t *vbnv_copy)
 {
 	int i;
 
 	for (i = 0; i < CONFIG_VBNV_SIZE; i++)
 		cmos_write(vbnv_copy[i], CONFIG_VBNV_OFFSET + 14 + i);
 }
-
-
-static void vbnv_setup(void)
-{
-	read_vbnv(vbnv_data_addr(0));
-	car_set_var(vbnv_initialized, 1);
-}
-
-void set_recovery_mode_into_vbnv(int recovery_reason)
-{
-	uint8_t vbnv_copy[CONFIG_VBNV_SIZE];
-	uint8_t crc_val;
-
-	read_vbnv(vbnv_copy);
-
-	vbnv_copy[RECOVERY_OFFSET] = recovery_reason;
-
-	crc_val = crc8(vbnv_copy, CRC_OFFSET);
-
-	vbnv_copy[CRC_OFFSET] = crc_val;
-
-	save_vbnv(vbnv_copy);
-}
-
-int get_recovery_mode_from_vbnv(void)
-{
-	if (!is_vbnv_initialized())
-		vbnv_setup();
-	return vbnv_data(RECOVERY_OFFSET);
-}
-
-int vboot_wants_oprom(void)
-{
-#if IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE)
-	struct vboot_handoff *vbho;
-
-	/* First check if handoff structure flag exists and is set. */
-	vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-	if (vbho && vbho->init_params.flags & VB_INIT_FLAG_OPROM_LOADED)
-		return 1;
-#endif
-
-	if (!is_vbnv_initialized())
-		vbnv_setup();
-
-	return (vbnv_data(BOOT_OFFSET) & BOOT_OPROM_NEEDED) ? 1 : 0;
-}
diff --git a/src/vendorcode/google/chromeos/vbnv_ec.c b/src/vendorcode/google/chromeos/vbnv_ec.c
index 6e1b0c5..0b7b7b5 100644
--- a/src/vendorcode/google/chromeos/vbnv_ec.c
+++ b/src/vendorcode/google/chromeos/vbnv_ec.c
@@ -14,96 +14,16 @@
  */
 
 #include <types.h>
-#include <string.h>
-#include <console/console.h>
-#include <arch/early_variables.h>
 #include <ec/google/chromeec/ec.h>
-#include "chromeos.h"
+#include "vbnv.h"
 #include "vbnv_layout.h"
 
-static int vbnv_initialized CAR_GLOBAL;
-static uint8_t vbnv[VBNV_BLOCK_SIZE] CAR_GLOBAL;
-
-/* Wrappers for accessing the variables marked as CAR_GLOBAL. */
-static inline int is_vbnv_initialized(void)
-{
-	return car_get_var(vbnv_initialized);
-}
-
-static inline uint8_t *vbnv_data_addr(int index)
-{
-	uint8_t *vbnv_arr = car_get_var_ptr(vbnv);
-
-	return &vbnv_arr[index];
-}
-
-static inline uint8_t vbnv_data(int index)
-{
-	return *vbnv_data_addr(index);
-}
-
-/* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial.  A
- * table-based algorithm would be faster, but for only 15 bytes isn't
- * worth the code size.
- */
-
-static uint8_t crc8(const uint8_t * data, int len)
-{
-	unsigned crc = 0;
-	int i, j;
-
-	for (j = len; j; j--, data++) {
-		crc ^= (*data << 8);
-		for (i = 8; i; i--) {
-			if (crc & 0x8000)
-				crc ^= (0x1070 << 3);
-			crc <<= 1;
-		}
-	}
-
-	return (uint8_t) (crc >> 8);
-}
-
-void read_vbnv(uint8_t *vbnv_copy)
+void read_vbnv_ec(uint8_t *vbnv_copy)
 {
 	google_chromeec_vbnv_context(1, vbnv_copy, VBNV_BLOCK_SIZE);
-
-	/* Check data for consistency */
-	if ((HEADER_SIGNATURE != (vbnv_copy[HEADER_OFFSET] & HEADER_MASK))
-	    || (crc8(vbnv_copy, CRC_OFFSET) != vbnv_copy[CRC_OFFSET])) {
-
-		/* Data is inconsistent (bad CRC or header),
-		 * so reset to defaults
-		 */
-		memset(vbnv_copy, 0, VBNV_BLOCK_SIZE);
-		vbnv_copy[HEADER_OFFSET] =
-		    (HEADER_SIGNATURE | HEADER_FIRMWARE_SETTINGS_RESET |
-		     HEADER_KERNEL_SETTINGS_RESET);
-	}
 }
 
-void save_vbnv(const uint8_t *vbnv_copy)
+void save_vbnv_ec(const uint8_t *vbnv_copy)
 {
 	google_chromeec_vbnv_context(0, (uint8_t *)vbnv_copy, VBNV_BLOCK_SIZE);
 }
-
-static void vbnv_setup(void)
-{
-	read_vbnv(vbnv_data_addr(0));
-	car_set_var(vbnv_initialized, 1);
-}
-
-int get_recovery_mode_from_vbnv(void)
-{
-	if (!is_vbnv_initialized())
-		vbnv_setup();
-	return vbnv_data(RECOVERY_OFFSET);
-}
-
-int vboot_wants_oprom(void)
-{
-	if (!is_vbnv_initialized())
-		vbnv_setup();
-
-	return (vbnv_data(BOOT_OFFSET) & BOOT_OPROM_NEEDED) ? 1 : 0;
-}
diff --git a/src/vendorcode/google/chromeos/vbnv_flash.c b/src/vendorcode/google/chromeos/vbnv_flash.c
index f8a88cd..ea5d9f3 100644
--- a/src/vendorcode/google/chromeos/vbnv_flash.c
+++ b/src/vendorcode/google/chromeos/vbnv_flash.c
@@ -22,6 +22,7 @@
 #include <vb2_api.h>
 #include <vboot_nvstorage.h>
 #include "chromeos.h"
+#include "vbnv.h"
 #include "vbnv_layout.h"
 
 #define BLOB_SIZE VB2_NVDATA_SIZE
@@ -157,7 +158,7 @@ static int erase_nvram(void)
 	return 0;
 }
 
-void read_vbnv(uint8_t *vbnv_copy)
+void read_vbnv_flash(uint8_t *vbnv_copy)
 {
 	if (!is_initialized())
 		if (init_vbnv())
@@ -165,7 +166,7 @@ void read_vbnv(uint8_t *vbnv_copy)
 	memcpy(vbnv_copy, cache, BLOB_SIZE);
 }
 
-void save_vbnv(const uint8_t *vbnv_copy)
+void save_vbnv_flash(const uint8_t *vbnv_copy)
 {
 	int new_offset;
 	int i;
@@ -205,10 +206,3 @@ void save_vbnv(const uint8_t *vbnv_copy)
 		printk(BIOS_ERR, "failed to save nvdata\n");
 	}
 }
-
-int get_recovery_mode_from_vbnv(void)
-{
-	if (!is_initialized())
-		init_vbnv();
-	return cache[RECOVERY_OFFSET];
-}



More information about the coreboot-gerrit mailing list