From 3f492b471b215f32f10bdaea37e8b4b7ca6109f3 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Tue, 17 Jul 2012 15:24:26 -0700 Subject: [PATCH] Continue simplifying flash write protect Now that read-only code is protected iff the persistent state is locked, we don't need to track per-block in the persistent state. BUG=chrome-os-partner:11150 TEST=if it builds and boots, it's fine Change-Id: I80e6a85c0c72136b7ed8964ce02c8abdbaafe637 Signed-off-by: Randall Spangler Reviewed-on: https://gerrit.chromium.org/gerrit/27719 --- chip/lm4/config.h | 2 +- common/flash_common.c | 109 ++++++++++++------------------------------ include/flash.h | 29 ++++------- 3 files changed, 39 insertions(+), 101 deletions(-) diff --git a/chip/lm4/config.h b/chip/lm4/config.h index 712b8d8f87..74d7663a6c 100644 --- a/chip/lm4/config.h +++ b/chip/lm4/config.h @@ -45,7 +45,7 @@ * register with persistent state. Put that up at the top. */ #define CONFIG_SECTION_FLASH_PSTATE_SIZE (1 * CONFIG_FLASH_BANK_SIZE) -#define CONFIG_SECTION_FLASH_PSTATE_OFF (CONFIG_FLASH_SIZE \ +#define CONFIG_SECTION_FLASH_PSTATE_OFF (CONFIG_FLASH_PHYSICAL_SIZE \ - CONFIG_SECTION_FLASH_PSTATE_SIZE) /* Then there are the two major sections. */ diff --git a/common/flash_common.c b/common/flash_common.c index a1b0b08be9..c9fb74aebf 100644 --- a/common/flash_common.c +++ b/common/flash_common.c @@ -15,8 +15,9 @@ #include "system.h" #include "util.h" -#define PERSIST_STATE_VERSION 1 +#define PERSIST_STATE_VERSION 2 #define MAX_BANKS (CONFIG_FLASH_SIZE / CONFIG_FLASH_BANK_SIZE) +#define PHYSICAL_BANKS (CONFIG_FLASH_PHYSICAL_SIZE / CONFIG_FLASH_BANK_SIZE) /* Persistent protection state flash offset / size / bank */ #define PSTATE_OFFSET (CONFIG_SECTION_FLASH_PSTATE_OFF - CONFIG_FLASH_BASE) @@ -33,9 +34,10 @@ struct persist_state { uint8_t version; /* Version of this struct */ uint8_t lock; /* Lock flags */ uint8_t reserved[2]; /* Reserved; set 0 */ - uint8_t blocks[MAX_BANKS]; /* Per-block flags */ }; +int stuck_locked; /* Is physical flash stuck protected? */ + static struct persist_state pstate; /* RAM copy of pstate data */ @@ -61,7 +63,6 @@ static int read_pstate(void) memset(&pstate, 0, sizeof(pstate)); pstate.version = PERSIST_STATE_VERSION; #else - int i; int rv = flash_physical_read(PSTATE_OFFSET, sizeof(pstate), (char *)&pstate); if (rv) @@ -75,8 +76,7 @@ static int read_pstate(void) /* Mask off currently-valid flags */ pstate.lock &= FLASH_PROTECT_LOCK_SET; - for (i = 0; i < MAX_BANKS; i++) - pstate.blocks[i] = 0; + #endif /* CHIP_stm32 */ return EC_SUCCESS; } @@ -84,6 +84,9 @@ static int read_pstate(void) /* Write persistent state from pstate, erasing if necessary. */ static int write_pstate(void) { +#ifdef CHIP_stm32 + return EC_SUCCESS; +#else int rv; /* Erase pstate */ @@ -104,6 +107,7 @@ static int write_pstate(void) /* Rewrite the data */ return flash_physical_write(PSTATE_OFFSET, sizeof(pstate), (const char *)&pstate); +#endif } /* Apply write protect based on persistent state. */ @@ -140,11 +144,6 @@ static int is_pstate_lock_applied(void) return flash_physical_get_protect(PSTATE_BANK); } -int flash_get_size(void) -{ - return CONFIG_FLASH_SIZE; -} - int flash_dataptr(int offset, int size_req, int align, char **ptrp) { if (offset < 0 || size_req < 0 || @@ -221,55 +220,6 @@ int flash_lock_protect(int lock) return apply_pstate(); } -const uint8_t *flash_get_protect_array(void) -{ - /* - * Return a copy of the current write protect state. This is an array - * of per-protect-block flags. (This is NOT the actual array, so - * attempting to change it will have no effect.) - */ - int i; - - /* Read the current persist state from flash */ - read_pstate(); - - /* Combine with current block protection state */ - for (i = 0; i < MAX_BANKS; i++) { - if (flash_physical_get_protect(i)) - pstate.blocks[i] |= FLASH_PROTECT_UNTIL_REBOOT; - } - - /* Return the block array */ - return pstate.blocks; -} - -int flash_get_protect(int offset, int size) -{ - int pbsize = flash_get_protect_block_size(); - uint8_t minflags = 0xff; - int i; - - if (flash_dataptr(offset, size, pbsize, NULL) < 0) - return 0; /* Invalid range; assume nothing protected */ - - /* Convert offset and size to blocks */ - offset /= pbsize; - size /= pbsize; - - /* Read the current persist state from flash */ - read_pstate(); - - /* Combine with current block protection state */ - for (i = 0; i < size; i++) { - int f = pstate.blocks[offset + i]; - if (flash_physical_get_protect(offset + i)) - f |= FLASH_PROTECT_UNTIL_REBOOT; - minflags &= f; - } - - return minflags; -} - int flash_get_protect_lock(void) { int flags; @@ -295,13 +245,10 @@ int flash_get_protect_lock(void) int flash_pre_init(void) { /* Initialize the physical flash interface */ - /* - * TODO: track pre-init error so we can report it later. Do at the - * same time as new flash commands to get/set write protect status. - */ - flash_physical_pre_init(); + if (flash_physical_pre_init() == EC_ERROR_ACCESS_DENIED) + stuck_locked = 1; - /* Read pstate and apply write protect to blocks if needed */ + /* Apply write protect to blocks if needed */ return apply_pstate(); } @@ -342,30 +289,35 @@ static int parse_offset_size(int argc, char **argv, int shift, static int command_flash_info(int argc, char **argv) { - const uint8_t *wp; - int banks = flash_get_size() / flash_get_protect_block_size(); int i; - ccprintf("Physical:%4d KB\n", flash_physical_size() / 1024); - ccprintf("Usable: %4d KB\n", flash_get_size() / 1024); + ccprintf("Physical:%4d KB\n", CONFIG_FLASH_PHYSICAL_SIZE / 1024); + if (flash_physical_size() != CONFIG_FLASH_PHYSICAL_SIZE) + ccprintf("But chip claims %d KB!\n", + flash_physical_size() / 1024); + + ccprintf("Usable: %4d KB\n", CONFIG_FLASH_SIZE / 1024); ccprintf("Write: %4d B\n", flash_get_write_block_size()); ccprintf("Erase: %4d B\n", flash_get_erase_block_size()); ccprintf("Protect: %4d B\n", flash_get_protect_block_size()); i = flash_get_protect_lock(); - ccprintf("Lock: %s%s\n", - (i & FLASH_PROTECT_LOCK_SET) ? "LOCKED" : "unlocked", - (i & FLASH_PROTECT_LOCK_APPLIED) ? ",APPLIED" : ""); + ccprintf("Lock: %s", + (i & FLASH_PROTECT_LOCK_SET) ? "LOCKED" : "unlocked"); + if (i & FLASH_PROTECT_LOCK_APPLIED) + ccputs(",APPLIED"); + if (stuck_locked) + ccputs(",STUCK"); + ccputs("\n"); + ccprintf("WP pin: %sasserted\n", (i & FLASH_PROTECT_PIN_ASSERTED) ? "" : "de"); - wp = flash_get_protect_array(); - ccputs("Protected now:"); - for (i = 0; i < banks; i++) { + for (i = 0; i < PHYSICAL_BANKS; i++) { if (!(i & 7)) ccputs(" "); - ccputs(wp[i] & FLASH_PROTECT_UNTIL_REBOOT ? "Y" : "."); + ccputs(flash_physical_get_protect(i) ? "Y" : "."); } ccputs("\n"); @@ -376,7 +328,6 @@ DECLARE_CONSOLE_COMMAND(flashinfo, command_flash_info, "Print flash info", NULL); - static int command_flash_erase(int argc, char **argv) { int offset = -1; @@ -411,7 +362,7 @@ static int command_flash_write(int argc, char **argv) if (size > shared_mem_size()) size = shared_mem_size(); - /* Acquire the shared memory buffer */ + /* Acquire the shared memory buffer */ rv = shared_mem_acquire(size, 0, &data); if (rv) { ccputs("Can't get shared mem\n"); @@ -463,7 +414,7 @@ static int flash_command_get_info(struct host_cmd_handler_args *args) struct ec_response_flash_info *r = (struct ec_response_flash_info *)args->response; - r->flash_size = flash_get_size(); + r->flash_size = CONFIG_FLASH_SIZE; r->write_block_size = flash_get_write_block_size(); r->erase_block_size = flash_get_erase_block_size(); r->protect_block_size = flash_get_protect_block_size(); diff --git a/include/flash.h b/include/flash.h index bd89448c57..ec9407d44e 100644 --- a/include/flash.h +++ b/include/flash.h @@ -151,30 +151,17 @@ int flash_protect_until_reboot(void); * persistently-protected blocks. */ int flash_lock_protect(int lock); -/* Flags for flash_get_protect() and flash_get_protect_array(). */ -/* Protected until reboot. This will be set for persistently-protected blocks - * as soon as the flash module protects them, and for non-persistent protection - * after flash_protect_until_reboot() is called on a block. */ -#define FLASH_PROTECT_UNTIL_REBOOT 0x01 - -/* Return a copy of the current write protect state. This is an array of - * per-protect-block flags. The data is valid until the next call to a flash - * function. */ -const uint8_t *flash_get_protect_array(void); - -/* Return the lowest amount of protection for any flash block in the specified - * range. That is, if any byte in the range is not protected until reboot, - * FLASH_PROTECT_UNTIL_REBOOT will not be set. */ -int flash_get_protect(int offset, int size); - /* Flags for flash_get_protect_lock() */ -/* Flash protection lock has been set. Note that if the write protect pin was +/* + * Flash protection lock has been set. Note that if the write protect pin was * deasserted at boot time, this simply indicates the state of the lock - * setting, and not whether blocks are actually protected. */ + * setting, and not whether blocks are actually protected. + */ #define FLASH_PROTECT_LOCK_SET 0x01 -/* Flash protection lock has actually been applied. All blocks with - FLASH_PROTECT_PERSISTENT have been protected, and flash protection cannot be - unlocked. */ +/* + * Flash protection lock has actually been applied. Read-only firmware is + * protected, and flash protection cannot be unlocked. + */ #define FLASH_PROTECT_LOCK_APPLIED 0x02 /* Write protect pin is currently asserted */ #define FLASH_PROTECT_PIN_ASSERTED 0x04