diff options
author | Randall Spangler <rspangler@chromium.org> | 2013-06-27 13:06:19 -0700 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-07-01 16:14:15 -0700 |
commit | 267dbb74d28e4d5d13e892488563ab439398513d (patch) | |
tree | 965efc83f6ae8f15442e4670d4bc35205c99aa97 /util | |
parent | 23dd3f5f9bfa1af12efd1bf2b122647c8d54a1f9 (diff) | |
download | chrome-ec-267dbb74d28e4d5d13e892488563ab439398513d.tar.gz |
Add common interface to EC flash commands
ectool and burn_my_ec need to use the same lower-level interface to
the EC flash commands, rather than duplicating calling the low-level
flash read/write/erase commands.
This is a precursor to refactoring the low-level commands to support
SPI/STM32L in a follow-up CL.
BUG=chrome-os-partner:20571
BRANCH=none
TEST=in a root shell, burn_my_ec flashes both RO and RW EC code
Change-Id: I4c72690100d86dbff03b7dacc2fb248b571d3820
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/60266
Diffstat (limited to 'util')
-rw-r--r-- | util/build.mk | 2 | ||||
-rw-r--r-- | util/burn_my_ec.c | 46 | ||||
-rw-r--r-- | util/ec_flash.c | 99 | ||||
-rw-r--r-- | util/ec_flash.h | 52 | ||||
-rw-r--r-- | util/ectool.c | 57 |
5 files changed, 184 insertions, 72 deletions
diff --git a/util/build.mk b/util/build.mk index 9d2f149241..d4563caa08 100644 --- a/util/build.mk +++ b/util/build.mk @@ -7,7 +7,7 @@ # host-util-bin=ectool lbplay burn_my_ec -host-util-common=ectool_keyscan comm-host comm-dev misc_util +host-util-common=ectool_keyscan comm-host comm-dev misc_util ec_flash ifeq ($(CONFIG_LPC),y) host-util-common+=comm-lpc else diff --git a/util/burn_my_ec.c b/util/burn_my_ec.c index 337abf7e96..1cac34bec5 100644 --- a/util/burn_my_ec.c +++ b/util/burn_my_ec.c @@ -11,6 +11,7 @@ #include <unistd.h> #include "comm-host.h" +#include "ec_flash.h" #define STR0(name) #name #define STR(name) STR0(name) @@ -54,12 +55,7 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload, uint32_t offset, uint32_t size) { struct ec_params_reboot_ec rst_req; - struct ec_params_flash_erase er_req; - struct ec_params_flash_write wr_req; - struct ec_params_flash_read rd_req; - uint8_t rd_resp[EC_HOST_PARAM_SIZE]; int res; - uint32_t i; enum ec_current_image current = EC_IMAGE_UNKNOWN; res = get_version(¤t); @@ -74,15 +70,12 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload, ec_command(EC_CMD_REBOOT_EC, 0, &rst_req, sizeof(rst_req), NULL, 0); /* wait EC reboot */ - usleep(500000); + usleep(1000000); } printf("Erasing partition %s : 0x%x bytes at 0x%08x\n", part_name[part], size, offset); - er_req.size = size; - er_req.offset = offset; - res = ec_command(EC_CMD_FLASH_ERASE, 0, - &er_req, sizeof(er_req), NULL, 0); + res = ec_flash_erase(offset, size); if (res < 0) { fprintf(stderr, "Erase failed : %d\n", res); return -1; @@ -90,35 +83,20 @@ 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 += sizeof(wr_req.data)) { - wr_req.offset = offset + i; - 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, 0, - &wr_req, sizeof(wr_req), NULL, 0); - if (res < 0) { - fprintf(stderr, "Write error at 0x%08x : %d\n", i, res); - return -1; - } + res = ec_flash_write(payload, offset, size); + if (res < 0) { + fprintf(stderr, "Write failed : %d\n", res); + return -1; } 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 += sizeof(rd_resp)) { - rd_req.offset = offset + i; - rd_req.size = MIN(size - i, sizeof(rd_resp)); - res = ec_command(EC_CMD_FLASH_READ, 0, &rd_req, sizeof(rd_req), - &rd_resp, sizeof(rd_resp)); - if (res < 0) { - fprintf(stderr, "Read error at 0x%08x : %d\n", i, res); - return -1; - } - if (memcmp(payload + i, rd_resp, rd_req.size)) - fprintf(stderr, "ERR: @%08x->%08x\n", - offset + i, offset + i + size); + res = ec_flash_verify(payload, offset, size); + if (res < 0) { + fprintf(stderr, "Verify failed : %d\n", res); + return -1; } + printf("Done.\n"); return get_version(NULL); diff --git a/util/ec_flash.c b/util/ec_flash.c new file mode 100644 index 0000000000..f776240e58 --- /dev/null +++ b/util/ec_flash.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "comm-host.h" +#include "misc_util.h" + +int ec_flash_read(uint8_t *buf, int offset, int size) +{ + struct ec_params_flash_read p; + /* TODO(rspangler): need better way to determine max read size */ + uint8_t rdata[EC_HOST_PARAM_SIZE - sizeof(struct ec_host_response)]; + int rv; + int i; + + /* Read data in chunks */ + for (i = 0; i < size; i += sizeof(rdata)) { + p.offset = offset + i; + p.size = MIN(size - i, sizeof(rdata)); + rv = ec_command(EC_CMD_FLASH_READ, 0, + &p, sizeof(p), rdata, sizeof(rdata)); + if (rv < 0) { + fprintf(stderr, "Read error at offset %d\n", i); + return rv; + } + memcpy(buf + i, rdata, p.size); + } + + return 0; +} + +int ec_flash_verify(const uint8_t *buf, int offset, int size) +{ + uint8_t *rbuf = malloc(size); + int rv; + int i; + + if (!rbuf) { + fprintf(stderr, "Unable to allocate buffer.\n"); + return -1; + } + + rv = ec_flash_read(rbuf, offset, size); + if (rv < 0) { + free(rbuf); + return rv; + } + + for (i = 0; i < size; i++) { + if (buf[i] != rbuf[i]) { + fprintf(stderr, "Mismatch at offset 0x%x: " + "want 0x%02x, got 0x%02x\n", + i, buf[i], rbuf[i]); + free(rbuf); + return -1; + } + } + + free(rbuf); + return 0; +} + +int ec_flash_write(const uint8_t *buf, int offset, int size) +{ + struct ec_params_flash_write p; + int rv; + int i; + + /* Write data in chunks */ + for (i = 0; i < size; i += sizeof(p.data)) { + p.offset = offset + i; + p.size = MIN(size - i, sizeof(p.data)); + memcpy(p.data, buf + i, p.size); + rv = ec_command(EC_CMD_FLASH_WRITE, 0, &p, sizeof(p), NULL, 0); + if (rv < 0) { + fprintf(stderr, "Write error at offset %d\n", i); + return rv; + } + } + + return 0; +} + +int ec_flash_erase(int offset, int size) +{ + struct ec_params_flash_erase p; + + p.offset = offset; + p.size = size; + + return ec_command(EC_CMD_FLASH_ERASE, 0, &p, sizeof(p), NULL, 0); +} diff --git a/util/ec_flash.h b/util/ec_flash.h new file mode 100644 index 0000000000..68a40fe466 --- /dev/null +++ b/util/ec_flash.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_EC_FLASH_H +#define __CROS_EC_EC_FLASH_H + +/** + * Read EC flash memory + * + * @param buf Destination buffer + * @param offset Offset in EC flash to read + * @param size Number of bytes to read + * + * @return 0 if success, negative if error. + */ +int ec_flash_read(uint8_t *buf, int offset, int size); + +/** + * Verify EC flash memory + * + * @param buf Source buffer to verify against EC flash + * @param offset Offset in EC flash to check + * @param size Number of bytes to check + * + * @return 0 if success, negative if error. + */ +int ec_flash_verify(const uint8_t *buf, int offset, int size); + +/** + * Write EC flash memory + * + * @param buf Source buffer + * @param offset Offset in EC flash to write + * @param size Number of bytes to write + * + * @return 0 if success, negative if error. + */ +int ec_flash_write(const uint8_t *buf, int offset, int size); + +/** + * Erase EC flash memory + * + * @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(int offset, int size); + +#endif diff --git a/util/ectool.c b/util/ectool.c index c10689a533..3ea88e5260 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -15,6 +15,7 @@ #include "battery.h" #include "comm-host.h" #include "compile_time_macros.h" +#include "ec_flash.h" #include "ectool.h" #include "lightbar.h" #include "lock/gec_lock.h" @@ -487,14 +488,10 @@ int cmd_flash_info(int argc, char *argv[]) return 0; } - int cmd_flash_read(int argc, char *argv[]) { - struct ec_params_flash_read p; - uint8_t rdata[EC_HOST_PARAM_SIZE]; int offset, size; int rv; - int i; char *e; char *buf; @@ -522,17 +519,10 @@ int cmd_flash_read(int argc, char *argv[]) } /* Read data in chunks */ - for (i = 0; i < size; i += sizeof(rdata)) { - p.offset = offset + i; - p.size = MIN(size - i, sizeof(rdata)); - rv = ec_command(EC_CMD_FLASH_READ, 0, - &p, sizeof(p), rdata, sizeof(rdata)); - if (rv < 0) { - fprintf(stderr, "Read error at offset %d\n", i); - free(buf); - return rv; - } - memcpy(buf + i, rdata, p.size); + rv = ec_flash_read(buf, offset, size); + if (rv < 0) { + free(buf); + return rv; } rv = write_file(argv[3], buf, size); @@ -544,13 +534,10 @@ int cmd_flash_read(int argc, char *argv[]) return 0; } - int cmd_flash_write(int argc, char *argv[]) { - struct ec_params_flash_write p; int offset, size; int rv; - int i; char *e; char *buf; @@ -558,6 +545,7 @@ int cmd_flash_write(int argc, char *argv[]) fprintf(stderr, "Usage: %s <offset> <filename>\n", argv[0]); return -1; } + offset = strtol(argv[1], &e, 0); if ((e && *e) || offset < 0 || offset > 0x100000) { fprintf(stderr, "Bad offset.\n"); @@ -572,27 +560,20 @@ 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 += sizeof(p.data)) { - p.offset = offset + i; - p.size = MIN(size - i, sizeof(p.data)); - memcpy(p.data, buf + i, p.size); - rv = ec_command(EC_CMD_FLASH_WRITE, 0, &p, sizeof(p), NULL, 0); - if (rv < 0) { - fprintf(stderr, "Write error at offset %d\n", i); - free(buf); - return rv; - } - } + rv = ec_flash_write(buf, offset, size); free(buf); + + if (rv < 0) + return rv; + printf("done.\n"); return 0; } - int cmd_flash_erase(int argc, char *argv[]) { - struct ec_params_flash_erase p; + int offset, size; char *e; int rv; @@ -600,19 +581,21 @@ int cmd_flash_erase(int argc, char *argv[]) fprintf(stderr, "Usage: %s <offset> <size>\n", argv[0]); return -1; } - p.offset = strtol(argv[1], &e, 0); - if ((e && *e) || p.offset < 0 || p.offset > 0x100000) { + + offset = strtol(argv[1], &e, 0); + if ((e && *e) || offset < 0 || offset > 0x100000) { fprintf(stderr, "Bad offset.\n"); return -1; } - p.size = strtol(argv[2], &e, 0); - if ((e && *e) || p.size <= 0 || p.size > 0x100000) { + + size = strtol(argv[2], &e, 0); + if ((e && *e) || size <= 0 || size > 0x100000) { fprintf(stderr, "Bad size.\n"); return -1; } - printf("Erasing %d bytes at offset %d...\n", p.size, p.offset); - rv = ec_command(EC_CMD_FLASH_ERASE, 0, &p, sizeof(p), NULL, 0); + printf("Erasing %d bytes at offset %d...\n", size, offset); + rv = ec_flash_erase(offset, size); if (rv < 0) return rv; |