summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/build.mk2
-rw-r--r--util/burn_my_ec.c46
-rw-r--r--util/ec_flash.c99
-rw-r--r--util/ec_flash.h52
-rw-r--r--util/ectool.c57
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(&current);
@@ -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;