From bbdc155caf341a4c1cda5784f283f4a299413db6 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Mon, 18 Jun 2012 15:17:48 -0700 Subject: Optimize performance of flash reads/writes 1) Smaller start delay for commands 2) Reads can use the entire 128 byte parameter space This improves read speed from 350ms/64kb to 210ms/64kb. BUG=none TEST=ectool flashread 81920 81920 then compare with ec.A.bin Change-Id: I53d460bace5f21db845a3f8ec681507fca0f7b0e Signed-off-by: Randall Spangler Reviewed-on: https://gerrit.chromium.org/gerrit/25562 Reviewed-by: Bill Richardson --- include/ec_commands.h | 8 +++----- util/burn_my_ec.c | 8 ++++---- util/comm-lpc.c | 11 ++++++----- util/ectool.c | 11 +++++------ 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/ec_commands.h b/include/ec_commands.h index db84020a4d..6690522e88 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -253,9 +253,6 @@ struct ec_params_board_version { /*****************************************************************************/ /* Flash commands */ -/* Maximum bytes that can be read/written in a single command */ -#define EC_FLASH_SIZE_MAX 64 - /* Get flash info */ #define EC_CMD_FLASH_INFO 0x10 struct ec_response_flash_info { @@ -279,7 +276,7 @@ struct ec_params_flash_read { uint32_t size; /* Size to read in bytes */ } __attribute__ ((packed)); struct ec_response_flash_read { - uint8_t data[EC_FLASH_SIZE_MAX]; + uint8_t data[EC_PARAM_SIZE]; } __attribute__ ((packed)); /* Write flash */ @@ -287,7 +284,8 @@ struct ec_response_flash_read { struct ec_params_flash_write { uint32_t offset; /* Byte offset to write */ uint32_t size; /* Size to write in bytes */ - uint8_t data[EC_FLASH_SIZE_MAX]; + uint8_t data[64]; /* Could really use EC_PARAM_SIZE - 8, but tidiest + * to use a power of 2 so writes stay aligned. */ } __attribute__ ((packed)); /* Erase flash */ diff --git a/util/burn_my_ec.c b/util/burn_my_ec.c index 27a921123a..cb8ead87ac 100644 --- a/util/burn_my_ec.c +++ b/util/burn_my_ec.c @@ -87,9 +87,9 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload, printf("Writing partition %s : 0x%x bytes at 0x%08x\n", part_name[part], size, offset); /* Write data in chunks */ - for (i = 0; i < size; i += EC_FLASH_SIZE_MAX) { + for (i = 0; i < size; i += sizeof(wr_req.data)) { wr_req.offset = offset + i; - wr_req.size = MIN(size - i, EC_FLASH_SIZE_MAX); + wr_req.size = MIN(size - i, sizeof(wr_req.data)); memcpy(wr_req.data, payload + i, wr_req.size); res = ec_command(EC_CMD_FLASH_WRITE, &wr_req, sizeof(wr_req), NULL, 0); @@ -102,9 +102,9 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload, printf("Verifying partition %s : 0x%x bytes at 0x%08x\n", part_name[part], size, offset); /* Read data in chunks */ - for (i = 0; i < size; i += EC_FLASH_SIZE_MAX) { + for (i = 0; i < size; i += sizeof(rd_resp.data)) { rd_req.offset = offset + i; - rd_req.size = MIN(size - i, EC_FLASH_SIZE_MAX); + rd_req.size = MIN(size - i, sizeof(rd_resp.data)); res = ec_command(EC_CMD_FLASH_READ, &rd_req, sizeof(rd_req), &rd_resp, sizeof(rd_resp)); if (res) { diff --git a/util/comm-lpc.c b/util/comm-lpc.c index 8b42763753..4f3aae3912 100644 --- a/util/comm-lpc.c +++ b/util/comm-lpc.c @@ -13,7 +13,7 @@ #include "ec_commands.h" -#define INITIAL_UDELAY 10 /* 10 us */ +#define INITIAL_UDELAY 5 /* 5 us */ #define MAXIMUM_UDELAY 10000 /* 10 ms */ int comm_init(void) @@ -31,13 +31,13 @@ int comm_init(void) * If they all are 0xff, then very possible you cannot access GEC. */ byte &= inb(EC_LPC_ADDR_USER_CMD); byte &= inb(EC_LPC_ADDR_USER_DATA); - for (i = 0; i < EC_FLASH_SIZE_MAX /* big enough */; ++i) + for (i = 0; i < EC_PARAM_SIZE && byte == 0xff; ++i) byte &= inb(EC_LPC_ADDR_USER_PARAM + i); if (byte == 0xff) { fprintf(stderr, "Port 0x%x,0x%x,0x%x-0x%x are all 0xFF.\n", EC_LPC_ADDR_USER_CMD, EC_LPC_ADDR_USER_DATA, EC_LPC_ADDR_USER_PARAM, - EC_LPC_ADDR_USER_PARAM + EC_FLASH_SIZE_MAX - 1); + EC_LPC_ADDR_USER_PARAM + EC_PARAM_SIZE - 1); fprintf(stderr, "Very likely this board doesn't have GEC.\n"); return -4; } @@ -64,8 +64,9 @@ static int wait_for_ec(int status_addr, int timeout_usec) if (!(inb(status_addr) & EC_LPC_STATUS_BUSY_MASK)) return 0; - /* Increase the delay interval */ - delay = MIN(delay * 2, MAXIMUM_UDELAY); + /* Increase the delay interval after a few rapid checks */ + if (i > 20) + delay = MIN(delay * 2, MAXIMUM_UDELAY); } return -1; /* Timeout */ } diff --git a/util/ectool.c b/util/ectool.c index 5f10d35b80..6942f9f9ab 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -413,9 +413,9 @@ int cmd_flash_read(int argc, char *argv[]) } /* Read data in chunks */ - for (i = 0; i < size; i += EC_FLASH_SIZE_MAX) { + for (i = 0; i < size; i += sizeof(r.data)) { p.offset = offset + i; - p.size = MIN(size - i, EC_FLASH_SIZE_MAX); + p.size = MIN(size - i, sizeof(r.data)); rv = ec_command(EC_CMD_FLASH_READ, &p, sizeof(p), &r, sizeof(r)); if (rv) { @@ -463,12 +463,11 @@ int cmd_flash_write(int argc, char *argv[]) printf("Writing to offset %d...\n", offset); /* Write data in chunks */ - for (i = 0; i < size; i += EC_FLASH_SIZE_MAX) { + for (i = 0; i < size; i += sizeof(p.data)) { p.offset = offset + i; - p.size = MIN(size - i, EC_FLASH_SIZE_MAX); + p.size = MIN(size - i, sizeof(p.data)); memcpy(p.data, buf + i, p.size); - rv = ec_command(EC_CMD_FLASH_WRITE, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_FLASH_WRITE, &p, sizeof(p), NULL, 0); if (rv) { fprintf(stderr, "Write error at offset %d\n", i); free(buf); -- cgit v1.2.1