diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2016-06-28 14:50:16 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-07-11 14:43:59 -0700 |
commit | d5820a79fc1354d68ead43a3bf88bdee8a6a2f3d (patch) | |
tree | 6e29ffa83d1a4f85dd86415008d1127a6a0938b7 | |
parent | ae703f681965ffdbe676fa291d445f765f93e2ab (diff) | |
download | vboot-d5820a79fc1354d68ead43a3bf88bdee8a6a2f3d.tar.gz |
bdb: Add nvmrw_get and nvmrw_set
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>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | firmware/bdb/nvm.c | 79 | ||||
-rw-r--r-- | firmware/bdb/nvm.h | 39 | ||||
-rw-r--r-- | tests/bdb_nvm_test.c | 60 |
4 files changed, 180 insertions, 0 deletions
@@ -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} diff --git a/firmware/bdb/nvm.c b/firmware/bdb/nvm.c index a7c56b0b..9c40ea55 100644 --- a/firmware/bdb/nvm.c +++ b/firmware/bdb/nvm.c @@ -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; +} diff --git a/firmware/bdb/nvm.h b/firmware/bdb/nvm.h index 3de1a2df..c0a55402 100644 --- a/firmware/bdb/nvm.h +++ b/firmware/bdb/nvm.h @@ -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 index 00000000..d69391c0 --- /dev/null +++ b/tests/bdb_nvm_test.c @@ -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; +} |