summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-06-26 16:02:02 -0700
committerChromeBot <chrome-bot@google.com>2013-07-01 16:14:16 -0700
commit177dc398d39c1156182cb8e59a4092bd8a18ad93 (patch)
treedcaac91130b259baafa19e9fc26d07c815f0c4ce /util
parent2730daa5679bc0d2a048a60055a7dc89d060076e (diff)
downloadchrome-ec-177dc398d39c1156182cb8e59a4092bd8a18ad93.tar.gz
Allow bigger flash write commands
Version 1 of EC_CMD_FLASH_WRITE will use as big a write as possible given the available command parameter space. Falls back to 64 byte writes on old platforms. BUG=chrome-os-partner:20571 BRANCH=none TEST=Copy burn_my_ec onto a link and run it. Write size should be 64 bytes for the first half of the update (since the old EC doesn't support ver.1 of the write command) and 240 bytes for the second half of the update. Change-Id: I5900de3a5700d7c82a2e0c3cf9921b7ced1c0343 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/60511
Diffstat (limited to 'util')
-rw-r--r--util/burn_my_ec.c21
-rw-r--r--util/ec_flash.c42
-rw-r--r--util/misc_util.c45
-rw-r--r--util/misc_util.h19
4 files changed, 119 insertions, 8 deletions
diff --git a/util/burn_my_ec.c b/util/burn_my_ec.c
index 7d9a2dd2f3..622ab48243 100644
--- a/util/burn_my_ec.c
+++ b/util/burn_my_ec.c
@@ -65,12 +65,29 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload,
}
if (current == part) {
+ printf("Jumping EC to %s partition\n",
+ part == EC_IMAGE_RO ? "RW" : "RO");
rst_req.cmd = part == EC_IMAGE_RO ?
EC_REBOOT_JUMP_RW : EC_REBOOT_JUMP_RO;
ec_command(EC_CMD_REBOOT_EC, 0, &rst_req, sizeof(rst_req),
NULL, 0);
- /* wait EC reboot */
- usleep(1000000);
+
+ /*
+ * Wait for EC to reboot; this may take a while if EC is
+ * flushing large amounts of debug output.
+ */
+ usleep(2000000);
+
+ /* Check partition */
+ res = get_version(&current);
+ if (res < 0) {
+ fprintf(stderr, "Get version failed : %d\n", res);
+ return -1;
+ }
+ if (current == part) {
+ fprintf(stderr, "Jump failed!\n");
+ return -1;
+ }
}
printf("Erasing partition %s : 0x%x bytes at 0x%08x\n",
diff --git a/util/ec_flash.c b/util/ec_flash.c
index 0c9c698600..93705694e3 100644
--- a/util/ec_flash.c
+++ b/util/ec_flash.c
@@ -67,16 +67,46 @@ int ec_flash_verify(const uint8_t *buf, int offset, int size)
int ec_flash_write(const uint8_t *buf, int offset, int size)
{
- struct ec_params_flash_write p;
+ struct ec_params_flash_write *p =
+ (struct ec_params_flash_write *)ec_outbuf;
+ struct ec_response_flash_info info;
+ int pdata_max_size = (int)(ec_max_outsize - sizeof(*p));
+ int step;
int rv;
int i;
+ /*
+ * Determine whether we can use version 1 of the command with more
+ * data, or only version 0.
+ */
+ if (!ec_cmd_version_supported(EC_CMD_FLASH_WRITE, EC_VER_FLASH_WRITE))
+ pdata_max_size = EC_FLASH_WRITE_VER0_SIZE;
+
+ /*
+ * Determine step size. This must be a multiple of the write block
+ * size, and must also fit into the host parameter buffer.
+ */
+ rv = ec_command(EC_CMD_FLASH_INFO, 0, NULL, 0, &info, sizeof(info));
+ if (rv < 0)
+ return rv;
+
+ step = (pdata_max_size / info.write_block_size) * info.write_block_size;
+
+ if (!step) {
+ fprintf(stderr, "Write block size %d > max param size %d\n",
+ info.write_block_size, pdata_max_size);
+ return -1;
+ }
+
/* 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);
+ printf("Write size %d...\n", step);
+
+ for (i = 0; i < size; i += step) {
+ p->offset = offset + i;
+ p->size = MIN(size - i, step);
+ memcpy(p + 1, buf + i, p->size);
+ rv = ec_command(EC_CMD_FLASH_WRITE, 0, p, sizeof(*p) + p->size,
+ NULL, 0);
if (rv < 0) {
fprintf(stderr, "Write error at offset %d\n", i);
return rv;
diff --git a/util/misc_util.c b/util/misc_util.c
index 8410f03cfa..005c84e50c 100644
--- a/util/misc_util.c
+++ b/util/misc_util.c
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
+#include "comm-host.h"
#include "misc_util.h"
int write_file(const char *filename, const char *buf, int size)
@@ -81,3 +82,47 @@ int is_string_printable(const char *buf)
return 1;
}
+
+/**
+ * Get the versions of the command supported by the EC.
+ *
+ * @param cmd Command
+ * @param pmask Destination for version mask; will be set to 0 on
+ * error.
+ * @return 0 if success, <0 if error
+ */
+int ec_get_cmd_versions(int cmd, uint32_t *pmask)
+{
+ struct ec_params_get_cmd_versions pver;
+ struct ec_response_get_cmd_versions rver;
+ int rv;
+
+ *pmask = 0;
+
+ pver.cmd = cmd;
+ rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &pver, sizeof(pver),
+ &rver, sizeof(rver));
+
+ if (rv < 0)
+ return rv;
+
+ *pmask = rver.version_mask;
+ return 0;
+}
+
+/**
+ * Return non-zero if the EC supports the command and version
+ *
+ * @param cmd Command to check
+ * @param ver Version to check
+ * @return non-zero if command version supported; 0 if not.
+ */
+int ec_cmd_version_supported(int cmd, int ver)
+{
+ uint32_t mask = 0;
+
+ if (ec_get_cmd_versions(cmd, &mask))
+ return 0;
+
+ return (mask & EC_VER_MASK(ver)) ? 1 : 0;
+}
diff --git a/util/misc_util.h b/util/misc_util.h
index 2224d84aaf..c54d68fc96 100644
--- a/util/misc_util.h
+++ b/util/misc_util.h
@@ -37,4 +37,23 @@ char *read_file(const char *filename, int *size);
*/
int is_string_printable(const char *buf);
+/**
+ * Get the versions of the command supported by the EC.
+ *
+ * @param cmd Command
+ * @param pmask Destination for version mask; will be set to 0 on
+ * error.
+ * @return 0 if success, <0 if error
+ */
+int ec_get_cmd_versions(int cmd, uint32_t *pmask);
+
+/**
+ * Return non-zero if the EC supports the command and version
+ *
+ * @param cmd Command to check
+ * @param ver Version to check
+ * @return non-zero if command version supported; 0 if not.
+ */
+int ec_cmd_version_supported(int cmd, int ver);
+
#endif