diff options
author | Tom Hughes <tomhughes@chromium.org> | 2019-05-30 16:59:25 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-06 00:32:29 +0000 |
commit | 9a5e19845eb76e0b10311b4829ab39ba73835fa3 (patch) | |
tree | 02c7c67dd19b8b06df17ea48484e92def3521dbe /util | |
parent | dc5bb3536677fb332c4a3f71d31b57647ff9a7a8 (diff) | |
download | chrome-ec-9a5e19845eb76e0b10311b4829ab39ba73835fa3.tar.gz |
ectool: add async flash erase
BRANCH=none
TEST=ectool --name=cros_fp reboot_ec; sleep 0.5 && \
ectool --name=cros_fp rwsigaction abort; \
ectool --name=cros_fp flasheraseasync 393216 131072
(using hatch EVT fingerprint board: STM32F412)
TEST=make buildall -j
BUG=b:132444384
Change-Id: I4a78c5bf7ef323a14083cc9d5fa3ec2c5218245d
Signed-off-by: Tom Hughes <tomhughes@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1637496
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'util')
-rw-r--r-- | util/ec_flash.c | 39 | ||||
-rw-r--r-- | util/ec_flash.h | 10 | ||||
-rw-r--r-- | util/ectool.c | 13 |
3 files changed, 61 insertions, 1 deletions
diff --git a/util/ec_flash.c b/util/ec_flash.c index 93705694e3..c61720a1c2 100644 --- a/util/ec_flash.c +++ b/util/ec_flash.c @@ -11,6 +11,11 @@ #include "comm-host.h" #include "misc_util.h" +#include "timer.h" + +static const uint32_t ERASE_ASYNC_TIMEOUT = 10 * SECOND; +static const uint32_t ERASE_ASYNC_WAIT = 500 * MSEC; +static const int FLASH_ERASE_BUSY_RV = -EECRESULT - EC_RES_BUSY; int ec_flash_read(uint8_t *buf, int offset, int size) { @@ -125,3 +130,37 @@ int ec_flash_erase(int offset, int size) return ec_command(EC_CMD_FLASH_ERASE, 0, &p, sizeof(p), NULL, 0); } + +int ec_flash_erase_async(int offset, int size) +{ + struct ec_params_flash_erase_v1 p = { 0 }; + uint32_t timeout = 0; + int rv = FLASH_ERASE_BUSY_RV; + + p.cmd = FLASH_ERASE_SECTOR_ASYNC; + p.params.offset = offset; + p.params.size = size; + + rv = ec_command(EC_CMD_FLASH_ERASE, 1, &p, sizeof(p), NULL, 0); + + if (rv < 0) + return rv; + + rv = FLASH_ERASE_BUSY_RV; + + while (rv < 0 && timeout < ERASE_ASYNC_TIMEOUT) { + /* + * The erase is not complete until FLASH_ERASE_GET_RESULT + * returns success. It's important that we retry even when the + * underlying ioctl returns an error (not just + * FLASH_ERASE_BUSY_RV). + * + * See https://crrev.com/c/511805 for details. + */ + usleep(ERASE_ASYNC_WAIT); + timeout += ERASE_ASYNC_WAIT; + p.cmd = FLASH_ERASE_GET_RESULT; + rv = ec_command(EC_CMD_FLASH_ERASE, 1, &p, sizeof(p), NULL, 0); + } + return rv; +} diff --git a/util/ec_flash.h b/util/ec_flash.h index e5b7baef79..45bfeb5f5d 100644 --- a/util/ec_flash.h +++ b/util/ec_flash.h @@ -49,4 +49,14 @@ int ec_flash_write(const uint8_t *buf, int offset, int size); */ int ec_flash_erase(int offset, int size); +/** + * Erase EC flash memory asynchronously + * + * @param offset Offset in EC flash to erase + * @param size Number of bytes to erase + * + * @return 0 if success, negative if error. + */ +int ec_flash_erase_async(int offset, int size); + #endif diff --git a/util/ectool.c b/util/ectool.c index 570a7bf3ba..26d76b8c4f 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -13,6 +13,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <stdbool.h> #include "anx74xx.h" #include "battery.h" @@ -118,6 +119,8 @@ const char help_str[] = " Forces the fan PWM to a constant duty cycle\n" " flasherase <offset> <size>\n" " Erases EC flash\n" + " flasheraseasync <offset> <size>\n" + " Erases EC flash asynchronously\n" " flashinfo\n" " Prints information on the EC flash\n" " flashspiinfo\n" @@ -1211,12 +1214,16 @@ int cmd_flash_erase(int argc, char *argv[]) int offset, size; char *e; int rv; + bool async = false; if (argc < 3) { fprintf(stderr, "Usage: %s <offset> <size>\n", argv[0]); return -1; } + if (strcmp(argv[0], "flasheraseasync") == 0) + async = true; + offset = strtol(argv[1], &e, 0); if ((e && *e) || offset < 0 || offset > MAX_FLASH_SIZE) { fprintf(stderr, "Bad offset.\n"); @@ -1230,7 +1237,10 @@ int cmd_flash_erase(int argc, char *argv[]) } printf("Erasing %d bytes at offset %d...\n", size, offset); - rv = ec_flash_erase(offset, size); + if (async) + rv = ec_flash_erase_async(offset, size); + else + rv = ec_flash_erase(offset, size); if (rv < 0) return rv; @@ -8618,6 +8628,7 @@ const struct command commands[] = { {"extpwrlimit", cmd_ext_power_limit}, {"fanduty", cmd_fanduty}, {"flasherase", cmd_flash_erase}, + {"flasheraseasync", cmd_flash_erase}, {"flashprotect", cmd_flash_protect}, {"flashread", cmd_flash_read}, {"flashwrite", cmd_flash_write}, |