summaryrefslogtreecommitdiff
path: root/host
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2018-02-26 17:01:24 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-03-07 16:55:15 -0800
commita80a79f9f5ca0250eb31330d9dfdacf3a250efb0 (patch)
tree8a3bba693db4514e8a8ae5649b94e4c0b7b94605 /host
parent7bb45097af1e8b5f2bcf8e7a8bc6557c6505693b (diff)
downloadvboot-a80a79f9f5ca0250eb31330d9dfdacf3a250efb0.tar.gz
2lib: Add support for 64-byte nvstorage record
The calling firmware can set ctx->flags VB2_CONTEXT_NVDATA_V2 to tell vboot that nvdata is a 64-byte record instead of a 16-byte record, or equivalently, set the VBSD_NVDATA_V2 flag if calling the old vboot1 API. If calling firmware does not (which is the current coreboot and depthcharge default), then the 16-byte record is used, and V2 fields return explicit default values. Added the fw_max_rollforward V2 field, which defaults to 0xfffffffe on V1. This will be used by a subsequent CL. Added unit tests to verify all that. Added crossystem support, though it will only work with the current 16-byte records until firmware sets the VBSD flag and mosys supports larger records. (Note that because coreboot/depthcharge do not yet set the new context flag, this CL should not change ToT firmware behavior.) See go/vboot-nvstorage for design doc. BUG=chromium:789276 BRANCH=none TEST=make runtests Change-Id: I43072ef153dfa016c051f560892af1fbb3508e3a Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/942031
Diffstat (limited to 'host')
-rw-r--r--host/arch/arm/lib/crossystem_arch.c4
-rw-r--r--host/arch/x86/lib/crossystem_arch.c10
-rw-r--r--host/lib/crossystem.c31
3 files changed, 35 insertions, 10 deletions
diff --git a/host/arch/arm/lib/crossystem_arch.c b/host/arch/arm/lib/crossystem_arch.c
index 0a308416..d56f4e2e 100644
--- a/host/arch/arm/lib/crossystem_arch.c
+++ b/host/arch/arm/lib/crossystem_arch.c
@@ -260,7 +260,7 @@ static int vb2_read_nv_storage_disk(struct vb2_context *ctx)
return E_FAIL;
snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev);
- if (size != sizeof(ctx->nvdata) || (size + offset > SECTOR_SIZE))
+ if (size != vb2_nv_get_size(ctx) || (size + offset > SECTOR_SIZE))
return E_FAIL;
nvctx_fd = open(nvctx_path, O_RDONLY);
@@ -303,7 +303,7 @@ static int vb2_write_nv_storage_disk(struct vb2_context *ctx)
return E_FAIL;
snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev);
- if (size != sizeof(ctx->nvdata) || (size + offset > SECTOR_SIZE))
+ if (size != vb2_nv_get_size(ctx) || (size + offset > SECTOR_SIZE))
return E_FAIL;
do {
diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c
index f026a14f..4921119e 100644
--- a/host/arch/x86/lib/crossystem_arch.c
+++ b/host/arch/x86/lib/crossystem_arch.c
@@ -158,16 +158,17 @@ static int VbCmosWrite(unsigned offs, size_t size, const void *ptr)
int vb2_read_nv_storage(struct vb2_context *ctx)
{
unsigned offs, blksz;
+ unsigned expectsz = vb2_nv_get_size(ctx);
/* Get the byte offset from VBNV */
if (ReadFileInt(ACPI_VBNV_PATH ".0", &offs) < 0)
return -1;
if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0)
return -1;
- if (VBNV_BLOCK_SIZE > blksz)
+ if (expectsz > blksz)
return -1; /* NV storage block is too small */
- if (0 != VbCmosRead(offs, sizeof(ctx->nvdata), ctx->nvdata))
+ if (0 != VbCmosRead(offs, expectsz, ctx->nvdata))
return -1;
return 0;
@@ -177,6 +178,7 @@ int vb2_read_nv_storage(struct vb2_context *ctx)
int vb2_write_nv_storage(struct vb2_context *ctx)
{
unsigned offs, blksz;
+ unsigned expectsz = vb2_nv_get_size(ctx);
if (!(ctx->flags & VB2_CONTEXT_NVDATA_CHANGED))
return 0; /* Nothing changed, so no need to write */
@@ -186,10 +188,10 @@ int vb2_write_nv_storage(struct vb2_context *ctx)
return -1;
if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0)
return -1;
- if (VBNV_BLOCK_SIZE > blksz)
+ if (expectsz > blksz)
return -1; /* NV storage block is too small */
- if (0 != VbCmosWrite(offs, sizeof(ctx->nvdata), ctx->nvdata))
+ if (0 != VbCmosWrite(offs, expectsz, ctx->nvdata))
return -1;
/* Also attempt to write using mosys if using vboot2 */
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index 5a758616..38c9ed6e 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -98,11 +98,14 @@ static int vnc_read;
int vb2_get_nv_storage(enum vb2_nv_param param)
{
+ VbSharedDataHeader* sh = VbSharedDataRead();
static struct vb2_context cached_ctx;
/* TODO: locking around NV access */
if (!vnc_read) {
memset(&cached_ctx, 0, sizeof(cached_ctx));
+ if (sh->flags & VBSD_NVDATA_V2)
+ cached_ctx.flags |= VB2_CONTEXT_NVDATA_V2;
if (0 != vb2_read_nv_storage(&cached_ctx))
return -1;
vb2_nv_init(&cached_ctx);
@@ -118,10 +121,13 @@ int vb2_get_nv_storage(enum vb2_nv_param param)
int vb2_set_nv_storage(enum vb2_nv_param param, int value)
{
+ VbSharedDataHeader* sh = VbSharedDataRead();
struct vb2_context ctx;
/* TODO: locking around NV access */
memset(&ctx, 0, sizeof(ctx));
+ if (sh->flags & VBSD_NVDATA_V2)
+ ctx.flags |= VB2_CONTEXT_NVDATA_V2;
if (0 != vb2_read_nv_storage(&ctx))
return -1;
vb2_nv_init(&ctx);
@@ -834,18 +840,34 @@ static int ExecuteMosys(char * const argv[], char *buf, size_t bufsize)
int vb2_read_nv_storage_mosys(struct vb2_context *ctx)
{
- char hexstring[VBNV_BLOCK_SIZE * 2 + 32]; /* Reserve extra 32 bytes */
+ /* Reserve extra 32 bytes */
+ char hexstring[VB2_NVDATA_SIZE_V2 * 2 + 32];
+ /*
+ * TODO(rspangler): mosys doesn't know how to read anything but 16-byte
+ * records yet. When it grows a command line option to do that, call
+ * it here when needed.
+ *
+ * It's possible mosys won't need that. For example, if if examines
+ * the header byte to determine the records size, or if it calls back
+ * to crossystem to read the VBSD flag.
+ */
char * const argv[] = {
InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH,
"nvram", "vboot", "read", NULL
};
char hexdigit[3];
+ const int nvsize = vb2_nv_get_size(ctx);
int i;
if (ExecuteMosys(argv, hexstring, sizeof(hexstring)))
return -1;
+ if (strlen(hexstring) != 2 * nvsize) {
+ fprintf(stderr, "mosys returned hex nvdata size %d"
+ " (expected %d)\n", (int)strlen(hexstring), 2 * nvsize);
+ return -1;
+ }
hexdigit[2] = '\0';
- for (i = 0; i < VBNV_BLOCK_SIZE; i++) {
+ for (i = 0; i < nvsize; i++) {
hexdigit[0] = hexstring[i * 2];
hexdigit[1] = hexstring[i * 2 + 1];
ctx->nvdata[i] = strtol(hexdigit, NULL, 16);
@@ -855,14 +877,15 @@ int vb2_read_nv_storage_mosys(struct vb2_context *ctx)
int vb2_write_nv_storage_mosys(struct vb2_context *ctx)
{
- char hexstring[VBNV_BLOCK_SIZE * 2 + 1];
+ char hexstring[VB2_NVDATA_SIZE_V2 * 2 + 1];
char * const argv[] = {
InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH,
"nvram", "vboot", "write", hexstring, NULL
};
+ const int nvsize = vb2_nv_get_size(ctx);
int i;
- for (i = 0; i < VBNV_BLOCK_SIZE; i++)
+ for (i = 0; i < nvsize; i++)
snprintf(hexstring + i * 2, 3, "%02x", ctx->nvdata[i]);
hexstring[sizeof(hexstring) - 1] = '\0';
if (ExecuteMosys(argv, NULL, 0))