diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2017-03-06 18:51:44 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-03-09 03:24:02 -0800 |
commit | 69fda70a1bfcf144c88fbdb5a335ab8bef276c11 (patch) | |
tree | eb798e30ff59c5f2f9a9b57625f15f86e8a43ebf | |
parent | 855ac132242cab78197463bdd7d11fa57c108d9a (diff) | |
download | chrome-ec-69fda70a1bfcf144c88fbdb5a335ab8bef276c11.tar.gz |
g: add a cli command to erase flash INFO1 space
This command is handy in debug images when rollback protection needs
to be reset.
Manufacturing data stored in the last quarter of the INFO1 space is
preserved across the erase session.
BRANCH=cr50
BUG=b:35774863
TEST=built a non-debug image with the first map location in the
manifest set to zero, booted the new image. Then built and booted
a debug image with this patch included. Using sysinfo command
verified that the info map has one location zeroed, then ran
eraseflashinfo command and checked sysinfo output again. The info
map shows no more zeroed locations, and tpm still reports statues
as "manufacutred"
Change-Id: I58e2a6f6371b6ce656c1d6cc373dfdc6f9d9f5be
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/450906
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r-- | chip/g/flash.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/chip/g/flash.c b/chip/g/flash.c index f1089656a1..2029a0e438 100644 --- a/chip/g/flash.c +++ b/chip/g/flash.c @@ -40,10 +40,12 @@ #include "common.h" #include "console.h" +#include "cryptoc/util.h" #include "flash.h" #include "flash_config.h" #include "flash_info.h" #include "registers.h" +#include "shared_mem.h" #include "timer.h" #include "watchdog.h" @@ -166,10 +168,12 @@ static int do_flash_op(enum flash_op op, int is_info_bank, /* What are we doing? */ switch (op) { case OP_ERASE_BLOCK: +#ifndef CR50_DEV if (is_info_bank) /* Erasing the INFO bank from the RW section is * unsupported. */ return EC_ERROR_INVAL; +#endif opcode = 0x31415927; words = 0; /* don't care, really */ /* This number is based on the TSMC spec Nme=Terase/Tsme */ @@ -446,3 +450,60 @@ int flash_physical_erase(int byte_offset, int num_bytes) return EC_SUCCESS; } + +#ifdef CR50_DEV + +static int command_erase_flash_info(int argc, char **argv) +{ + uint32_t *preserved_manufacture_state; + const size_t manuf_word_count = FLASH_INFO_MANUFACTURE_STATE_SIZE / + sizeof(uint32_t); + int i; + int rv = EC_ERROR_BUSY; + + if (shared_mem_acquire(FLASH_INFO_MANUFACTURE_STATE_SIZE, + (char **)&preserved_manufacture_state) != + EC_SUCCESS) { + ccprintf("Failed to allocate memory for manufacture state!\n"); + return rv; + } + + flash_info_read_enable(0, 2048); + flash_info_write_enable(0, 2048); + + /* Preserve manufacturing information. */ + for (i = 0; i < manuf_word_count; i++) { + if (flash_physical_info_read_word + (FLASH_INFO_MANUFACTURE_STATE_OFFSET + + i * sizeof(uint32_t), + preserved_manufacture_state + i) != EC_SUCCESS) { + ccprintf("Failed to read word %d!\n", i); + goto exit; + } + } + + if (do_flash_op(OP_ERASE_BLOCK, 1, 0, 512) != EC_SUCCESS) { + ccprintf("Failed to erase info space!\n"); + goto exit; + } + + if (flash_info_physical_write + (FLASH_INFO_MANUFACTURE_STATE_OFFSET, + FLASH_INFO_MANUFACTURE_STATE_SIZE, + (char *)preserved_manufacture_state) != EC_SUCCESS) { + ccprintf("Failed to restore manufacture state!\n"); + goto exit; + } + + rv = EC_SUCCESS; + exit: + always_memset(preserved_manufacture_state, 0, + FLASH_INFO_MANUFACTURE_STATE_SIZE); + shared_mem_release(preserved_manufacture_state); + flash_info_write_disable(); + return rv; +} +DECLARE_CONSOLE_COMMAND(eraseflashinfo, command_erase_flash_info, + "", + "Erase INFO1 flash space"); +#endif |