bdb: Add nvmrw_get and nvmrw_set
authorDaisuke Nojiri <dnojiri@chromium.org>
Tue, 28 Jun 2016 21:50:16 +0000 (14:50 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Mon, 11 Jul 2016 21:43:59 +0000 (14:43 -0700)
These internal APIs are used to get and set values in NVM-RW variables.

BUG=chrome-os-partner:51907
BRANCH=tot
TEST=make runtests

Change-Id: Ibae1836cb569fe89dd2c8249f76c66b78b1c2cf4
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/356691
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Makefile
firmware/bdb/nvm.c
firmware/bdb/nvm.h
tests/bdb_nvm_test.c [new file with mode: 0644]

index 2d29bfd..a5460c2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -799,6 +799,7 @@ TEST21_NAMES = \
 
 TESTBDB_NAMES = \
        tests/bdb_test \
+       tests/bdb_nvm_test \
        tests/bdb_sprw_test
 
 TEST_NAMES += ${TEST2X_NAMES} ${TEST20_NAMES} ${TEST21_NAMES} ${TESTBDB_NAMES}
@@ -1277,6 +1278,7 @@ ${BUILD}/tests/vb20_common2_tests: LDLIBS += ${CRYPTO_LIBS}
 ${BUILD}/tests/vb20_common3_tests: LDLIBS += ${CRYPTO_LIBS}
 ${BUILD}/tests/verify_kernel: LDLIBS += ${CRYPTO_LIBS}
 ${BUILD}/tests/bdb_test: LDLIBS += ${CRYPTO_LIBS}
+${BUILD}/tests/bdb_nvm_test: LDLIBS += ${CRYPTO_LIBS}
 ${BUILD}/tests/bdb_sprw_test: LDLIBS += ${CRYPTO_LIBS}
 ${BUILD}/tests/hmac_test: LDLIBS += ${CRYPTO_LIBS}
 
index a7c56b0..9c40ea5 100644 (file)
@@ -265,3 +265,82 @@ int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc)
 
        return BDB_SUCCESS;
 }
+
+int nvmrw_get(struct vba_context *ctx, enum nvmrw_var var, uint32_t *val)
+{
+       struct nvmrw *nvm = &ctx->nvmrw;
+
+       /* No init or verify so that this can be called from futility.
+        * Callers are responsible for init and verify. */
+
+       switch (var) {
+       case NVMRW_VAR_UPDATE_COUNT:
+               *val = nvm->update_count;
+               break;
+       case NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION:
+               *val = nvm->min_kernel_data_key_version;
+               break;
+       case NVMRW_VAR_MIN_KERNEL_VERSION:
+               *val = nvm->min_kernel_version;
+               break;
+       case NVMRW_VAR_BUC_TYPE:
+               *val = nvm->buc_type;
+               break;
+       case NVMRW_VAR_FLAG_BUC_PRESENT:
+               *val = nvm->flags & NVM_RW_FLAG_BUC_PRESENT;
+               break;
+       case NVMRW_VAR_FLAG_DFM_DISABLE:
+               *val = nvm->flags & NVM_RW_FLAG_DFM_DISABLE;
+               break;
+       case NVMRW_VAR_FLAG_DOSM:
+               *val = nvm->flags & NVM_RW_FLAG_DOSM;
+               break;
+       default:
+               return BDB_ERROR_NVM_INVALID_PARAMETER;
+       }
+
+       return BDB_SUCCESS;
+}
+
+#define MAX_8BIT_UINT ((((uint64_t)1) << 8) - 1)
+
+int nvmrw_set(struct vba_context *ctx, enum nvmrw_var var, uint32_t val)
+{
+       struct nvmrw *nvm = &ctx->nvmrw;
+
+       /* No init or verify so that this can be called from futility.
+        * Callers are responsible for init and verify. */
+
+       switch (var) {
+       case NVMRW_VAR_UPDATE_COUNT:
+               nvm->update_count = val;
+               break;
+       case NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION:
+               nvm->min_kernel_data_key_version = val;
+               break;
+       case NVMRW_VAR_MIN_KERNEL_VERSION:
+               nvm->min_kernel_version = val;
+               break;
+       case NVMRW_VAR_BUC_TYPE:
+               if (val > MAX_8BIT_UINT)
+                       return BDB_ERROR_NVM_INVALID_PARAMETER;
+               nvm->buc_type = val;
+               break;
+       case NVMRW_VAR_FLAG_BUC_PRESENT:
+               nvm->flags &= ~NVM_RW_FLAG_BUC_PRESENT;
+               nvm->flags |= val ? NVM_RW_FLAG_BUC_PRESENT : 0;
+               break;
+       case NVMRW_VAR_FLAG_DFM_DISABLE:
+               nvm->flags &= ~NVM_RW_FLAG_DFM_DISABLE;
+               nvm->flags |= val ? NVM_RW_FLAG_DFM_DISABLE : 0;
+               break;
+       case NVMRW_VAR_FLAG_DOSM:
+               nvm->flags &= ~NVM_RW_FLAG_DOSM;
+               nvm->flags |= val ? NVM_RW_FLAG_DOSM : 0;
+               break;
+       default:
+               return BDB_ERROR_NVM_INVALID_PARAMETER;
+       }
+
+       return BDB_SUCCESS;
+}
index 3de1a2d..c0a5540 100644 (file)
@@ -72,6 +72,21 @@ struct nvmrw {
        uint8_t hmac[NVM_HMAC_SIZE];
 } __attribute__((packed));
 
+/*
+ * List of variables stored in NVM-RW. This should be exported and used by
+ * firmware and futility to access data in NVM-RW.
+ */
+enum nvmrw_var {
+       NVMRW_VAR_UPDATE_COUNT,
+       NVMRW_VAR_FLAGS,
+       NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION,
+       NVMRW_VAR_MIN_KERNEL_VERSION,
+       NVMRW_VAR_BUC_TYPE,
+       NVMRW_VAR_FLAG_BUC_PRESENT,
+       NVMRW_VAR_FLAG_DFM_DISABLE,
+       NVMRW_VAR_FLAG_DOSM,
+};
+
 /* Size of the version 1.0 */
 #define NVM_RW_MIN_STRUCT_SIZE         96
 /* 4 Kbit EEPROM divided by 4 regions (RO,RW) x (1st,2nd) = 128 KB */
@@ -97,4 +112,28 @@ int nvmrw_read(struct vba_context *ctx);
  */
 int nvmrw_write(struct vba_context *ctx, enum nvm_type type);
 
+/**
+ * Get a value of NVM-RW variable
+ *
+ * Callers are responsible for init and verify of ctx->nvmrw.
+ *
+ * @param ctx  struct vba_context
+ * @param var  Index of the variable
+ * @param val  Destination where the value is stored
+ * @return     BDB_SUCCESS or BDB_ERROR_NVM_*
+ */
+int nvmrw_get(struct vba_context *ctx, enum nvmrw_var var, uint32_t *val);
+
+/**
+ * Set a value in NVM-RW variable
+ *
+ * Callers are responsible for init and verify of ctx->nvmrw.
+ *
+ * @param ctx  struct vba_context
+ * @param var  Index of the variable
+ * @param val  Value to be set
+ * @return     BDB_SUCCESS or BDB_ERROR_NVM_*
+ */
+int nvmrw_set(struct vba_context *ctx, enum nvmrw_var var, uint32_t val);
+
 #endif
diff --git a/tests/bdb_nvm_test.c b/tests/bdb_nvm_test.c
new file mode 100644 (file)
index 0000000..d69391c
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Unit tests NVM
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bdb_api.h"
+#include "test_common.h"
+
+static void test_nvmrw(void)
+{
+       struct vba_context ctx;
+       uint32_t val;
+
+       memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
+
+       TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_UPDATE_COUNT, 1), NULL);
+       TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_UPDATE_COUNT, &val), NULL);
+       TEST_EQ(val, 1, NULL);
+
+       TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION, 1),
+                 NULL);
+       TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION, &val),
+                 NULL);
+       TEST_EQ(val, 1, NULL);
+
+       TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_MIN_KERNEL_VERSION, 1), NULL);
+       TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_MIN_KERNEL_VERSION, &val), NULL);
+       TEST_EQ(val, 1, NULL);
+
+       TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_BUC_TYPE, 1), NULL);
+       TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_BUC_TYPE, &val), NULL);
+       TEST_EQ(val, 1, NULL);
+
+       TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_FLAG_BUC_PRESENT, 1), NULL);
+       TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_FLAG_BUC_PRESENT, &val), NULL);
+       TEST_TRUE(val, NULL);
+
+       TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_FLAG_DFM_DISABLE, 1), NULL);
+       TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_FLAG_DFM_DISABLE, &val), NULL);
+       TEST_TRUE(val, NULL);
+
+       TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_FLAG_DOSM, 1), NULL);
+       TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_FLAG_DOSM, &val), NULL);
+       TEST_TRUE(val, NULL);
+}
+
+int main(int argc, char *argv[])
+{
+       printf("Running BDB NVM tests...\n");
+
+       test_nvmrw();
+
+       return gTestSuccess ? 0 : 255;
+}