summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott <scollyer@chromium.org>2016-07-21 19:17:16 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-07-22 13:36:06 -0700
commit1dc78318ba55ca30285570e2254d182fa4cb693a (patch)
tree0bafce521e13fd01a087d6bbb726e8628fb1e0e2
parentc765bed2ca2479f6490b6171aacf6e7d67cb58d3 (diff)
downloadchrome-ec-1dc78318ba55ca30285570e2254d182fa4cb693a.tar.gz
Cr50: NvMem: Modified nvmem_init to handle 2 corrupt partitions
During initialization the NvMem module looks for either a valid partition or that the NvMem area is fully erased. If neither of these two conditions were found, then it was only returning an error code and logging a message to the console. This CL modifies nvmem_init() so that if the error case as described above is detected, then it will call nvmem_setup() which will create two valid partitions. In addition, the setup function erases all of the existing data in the NvMem space. Enhanced the unit test that deals with both partitions being corrupted so that it verifies the version numbers are correct and that all user buffer data is set to 0xff. BUG=chrome-os-partner:55536 BRANCH=None TEST=Manual Executed make runtests TEST_LIST_HOST=nvmem and verifed that all tests passed. Change-Id: Ib932e02f15bd1aad7811032a12d826c76476e53f Signed-off-by: Scott <scollyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/362448 Commit-Ready: Vadim Bendebury <vbendeb@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--common/nvmem.c26
-rw-r--r--test/nvmem.c49
2 files changed, 57 insertions, 18 deletions
diff --git a/common/nvmem.c b/common/nvmem.c
index 1c7d8d69dc..8cf88909c0 100644
--- a/common/nvmem.c
+++ b/common/nvmem.c
@@ -244,7 +244,7 @@ static int nvmem_find_partition(void)
return EC_SUCCESS;
if (nvmem_is_unitialized()) {
- CPRINTF("NvMem: No Valid Paritions and not fully erased!!\n");
+ CPRINTS("NvMem: No Valid Paritions!");
return EC_ERROR_UNKNOWN;
}
@@ -316,20 +316,18 @@ int nvmem_setup(uint8_t starting_version)
return EC_ERROR_TIMEOUT;
}
- /* Fill in tag info */
+ /* Fill entire partition to 0xFFs */
+ memset(cache.base_ptr, 0xff, NVMEM_PARTITION_SIZE);
+ /* Get pointer to start of partition */
p_part = (struct nvmem_partition *)cache.base_ptr;
/* Commit function will increment version number */
p_part->tag.version = starting_version + part - 1;
+ /* Compute sha for the partition */
nvmem_compute_sha(&cache.base_ptr[NVMEM_SHA_SIZE],
NVMEM_PARTITION_SIZE -
NVMEM_SHA_SIZE,
p_part->tag.sha,
NVMEM_SHA_SIZE);
- /*
- * TODO: Should erase parition area prior to this function being
- * called, or could write all user buffer data to 0xff here
- * before the commit() call.
- */
/* Partition is now ready, write it to flash. */
ret = nvmem_commit();
if (ret != EC_SUCCESS)
@@ -357,10 +355,16 @@ int nvmem_init(void)
ret = nvmem_find_partition();
if (ret != EC_SUCCESS) {
- /* Change error state to non-zero */
- nvmem_error_state = EC_ERROR_UNKNOWN;
- CPRINTF("%s:%d\n", __func__, __LINE__);
- return ret;
+ /* Write NvMem partitions to 0xff and setup new tags */
+ nvmem_setup(0);
+ /* Should find valid partiion now */
+ ret = nvmem_find_partition();
+ if (ret) {
+ /* Change error state to non-zero */
+ nvmem_error_state = EC_ERROR_UNKNOWN;
+ CPRINTF("%s:%d\n", __func__, __LINE__);
+ return ret;
+ }
}
CPRINTS("Active NVram partition set to %d", nvmem_act_partition);
diff --git a/test/nvmem.c b/test/nvmem.c
index d3bc0b99e1..b9dd76c8cf 100644
--- a/test/nvmem.c
+++ b/test/nvmem.c
@@ -169,23 +169,58 @@ static int test_corrupt_nvmem(void)
{
uint32_t offset;
int n;
+ int ret;
+ struct nvmem_tag *p_part;
+ uint8_t *p_data;
/*
* The purpose of this test is to check nvmem_init() in the case when no
* vailid partition exists (not fully erased and no valid sha). In this
- * case, NvMem can't be initialized and should return an error to the
- * calling function.
+ * case, the initialization function will call setup() to create two new
+ * valid partitions.
*/
- /* Overwrite tags of each parition */
- memset(write_buffer, 0, 8);
+ /* Overwrite each partition will all 0s */
+ memset(write_buffer, 0, NVMEM_PARTITION_SIZE);
for (n = 0; n < NVMEM_NUM_PARTITIONS; n++) {
offset = NVMEM_PARTITION_SIZE * n;
- flash_physical_write(CONFIG_FLASH_NVMEM_OFFSET + offset, 8,
+ flash_physical_write(CONFIG_FLASH_NVMEM_OFFSET + offset,
+ NVMEM_PARTITION_SIZE,
(const char *)write_buffer);
}
- /* In this case nvmem_init is expected to fail */
- return !nvmem_init();
+ /*
+ * The initialization function will look for a valid partition and if
+ * none is found, then will call nvmem_setup() which will erase the
+ * paritions and setup new tags.
+ */
+ ret = nvmem_init();
+ if (ret)
+ return ret;
+ /* Fill buffer with 0xffs */
+ memset(write_buffer, 0xff, NVMEM_PARTITION_SIZE);
+ /*
+ * nvmem_setup() will write put version 1 into partition 1 since the
+ * commit() function toggles the active partition. Check here that
+ * partition 0 has a version number of 1 and that all of the user buffer
+ * data has been erased.
+ */
+ p_part = (struct nvmem_tag *)CONFIG_FLASH_NVMEM_BASE;
+ TEST_ASSERT(p_part->version == 1);
+ p_data = (uint8_t *)p_part + sizeof(struct nvmem_tag);
+ /* Verify that partition 0 is fully erased */
+ TEST_ASSERT_ARRAY_EQ(write_buffer, p_data, NVMEM_PARTITION_SIZE -
+ sizeof(struct nvmem_tag));
+
+ /* Run the same test for partition 1 which should have version 0 */
+ p_part = (struct nvmem_tag *)(CONFIG_FLASH_NVMEM_BASE +
+ NVMEM_PARTITION_SIZE);
+ TEST_ASSERT(p_part->version == 0);
+ p_data = (uint8_t *)p_part + sizeof(struct nvmem_tag);
+ ccprintf("Partition Version = %d\n", p_part->version);
+ /* Verify that partition 1 is fully erased */
+ TEST_ASSERT_ARRAY_EQ(write_buffer, p_data, NVMEM_PARTITION_SIZE -
+ sizeof(struct nvmem_tag));
+ return ret;
}
static int test_write_read_sequence(void)