diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-05-04 16:23:20 +0800 |
---|---|---|
committer | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-05-04 22:46:28 +0800 |
commit | 391925a1cbc1d8087e2087781ee01cc2862461fc (patch) | |
tree | 760aa2f3b6ec11b888130c26c2aa585b522ae3b7 | |
parent | 0ad2f9226f9146f2360168eefdf86e09513f91b0 (diff) | |
download | chrome-ec-391925a1cbc1d8087e2087781ee01cc2862461fc.tar.gz |
Implement new write protect for host commands.
Rework to call functions in flash_common.c.
Also fixed a bug in parsing size of parse_offset_size().
Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org>
BUG=chrome-os-partner:8448
TEST=on link
(CONSOLE) flashwp set 0x3d000 0x1000
(CONSOLE) flashwp lock
(HOST) flashrom -p internal:bus=lpc --wp-status
WP: write protect is enabled
WP: write protect range: start=0x0003d000, len=0x00001000
Change-Id: I4a53735c851ebf4bb0c01a55a1d301d5b706ee0c
-rw-r--r-- | common/flash_commands.c | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/common/flash_commands.c b/common/flash_commands.c index 1ef8956db2..715746d787 100644 --- a/common/flash_commands.c +++ b/common/flash_commands.c @@ -35,7 +35,7 @@ static int parse_offset_size(int argc, char **argv, int *offset, int *size) } if (argc >= 2) { - i = (uint32_t)strtoi(argv[1], &e, 1); + i = (uint32_t)strtoi(argv[1], &e, 0); if (e && *e) { ccprintf("Invalid size \"%s\"\n", argv[1]); return EC_ERROR_INVAL; @@ -290,33 +290,12 @@ enum lpc_status flash_command_erase(uint8_t *data) DECLARE_HOST_COMMAND(EC_LPC_COMMAND_FLASH_ERASE, flash_command_erase); -#ifdef REWORK_THESE_TO_USE_NEW_WP_MECHANISM -/* TODO: (crosbug.com/p/8448) rework these to use the new WP mechanism. Note - * that the concept of a single range oversimplifies how WP works; there are - * multiple protected regions, including the persistent WP state (last bank) - * and rollback information (bank before that; will be implemented by - * vboot). */ - -static int shadow_wp_offset; -static int shadow_wp_size; - enum lpc_status flash_command_wp_enable(uint8_t *data) { struct lpc_params_flash_wp_enable *p = (struct lpc_params_flash_wp_enable *)data; - int offset, size; - - if (p->enable_wp) { - offset = shadow_wp_offset; - size = shadow_wp_size; - } else { - offset = 0; - size = 0; - } - if (flash_set_write_protect_range(offset, size)) - return EC_LPC_RESULT_ERROR; - return EC_LPC_RESULT_SUCCESS; + return flash_lock_protect(p->enable_wp ? 1 : 0); } DECLARE_HOST_COMMAND(EC_LPC_COMMAND_FLASH_WP_ENABLE, flash_command_wp_enable); @@ -327,7 +306,7 @@ enum lpc_status flash_command_wp_get_state(uint8_t *data) struct lpc_response_flash_wp_enable *p = (struct lpc_response_flash_wp_enable *)data; - if (flash_get_write_protect_status() & EC_FLASH_WP_RANGE_LOCKED) + if (flash_get_protect_lock() & FLASH_PROTECT_LOCK_SET) p->enable_wp = 1; else p->enable_wp = 0; @@ -342,11 +321,14 @@ enum lpc_status flash_command_wp_set_range(uint8_t *data) { struct lpc_params_flash_wp_range *p = (struct lpc_params_flash_wp_range *)data; + enum lpc_status ret; - if (flash_set_write_protect_range(p->offset, p->size)) - return EC_LPC_RESULT_ERROR; + if (p->size) + ret = flash_set_protect(p->offset, p->size, 1); + else + ret = flash_set_protect(0, flash_get_size(), 0); - return EC_LPC_RESULT_SUCCESS; + return ret; } DECLARE_HOST_COMMAND(EC_LPC_COMMAND_FLASH_WP_SET_RANGE, flash_command_wp_set_range); @@ -356,13 +338,40 @@ enum lpc_status flash_command_wp_get_range(uint8_t *data) { struct lpc_response_flash_wp_range *p = (struct lpc_response_flash_wp_range *)data; + int pbsize = flash_get_protect_block_size(); + int banks = flash_get_size() / pbsize; + const uint8_t *blocks; + int i; + int min = -1, max = banks - 1; /* the enclosed range for protected. */ - if (flash_get_write_protect_range(&p->offset, &p->size)) - return EC_LPC_RESULT_ERROR; + blocks = flash_get_protect_array(); + for (i = 0; i < banks; i++) { + if (min == -1) { + /* Looking for the first protected bank. */ + if (blocks[i] & (FLASH_PROTECT_PERSISTENT | + FLASH_PROTECT_UNTIL_REBOOT)) { + min = i; + } + } else if (i < max) { + /* Looking for the unprotected bank. */ + if (!(blocks[i] & (FLASH_PROTECT_PERSISTENT | + FLASH_PROTECT_UNTIL_REBOOT))) { + max = i - 1; + } + } + } + + /* TODO(crosbug.com/p/9492): return multiple region of ranges(). */ + if (min == -1) { + /* None of bank is protected. */ + p->offset = 0; + p->size = 0; + } else { + p->offset = min * pbsize; + p->size = (max - min + 1) * pbsize; + } return EC_LPC_RESULT_SUCCESS; } DECLARE_HOST_COMMAND(EC_LPC_COMMAND_FLASH_WP_GET_RANGE, flash_command_wp_get_range); - -#endif /* REWORK_THESE_TO_USE_NEW_WP_MECHANISM */ |