summaryrefslogtreecommitdiff
path: root/util/ec_flash.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-06-27 13:06:19 -0700
committerChromeBot <chrome-bot@google.com>2013-07-01 16:14:15 -0700
commit267dbb74d28e4d5d13e892488563ab439398513d (patch)
tree965efc83f6ae8f15442e4670d4bc35205c99aa97 /util/ec_flash.c
parent23dd3f5f9bfa1af12efd1bf2b122647c8d54a1f9 (diff)
downloadchrome-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/ec_flash.c')
-rw-r--r--util/ec_flash.c99
1 files changed, 99 insertions, 0 deletions
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);
+}