summaryrefslogtreecommitdiff
path: root/include/update_fw.h
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2017-03-22 10:50:39 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-04-15 04:08:07 -0700
commit2f5e46cef48ec0671fd014bbdb38b060339db998 (patch)
tree147061592ddb8fa0ba504b5b1ba93dbdd1b23bd4 /include/update_fw.h
parent20c439be209a9cc0bb949ad21f289c453126395f (diff)
downloadchrome-ec-2f5e46cef48ec0671fd014bbdb38b060339db998.tar.gz
common/update: Update common code updater to latest chip/g version
Let's move to protocol version 6, which provides most of the new features we want to update generic EC firmware. Note that this matches chip/g version as of commit 0e5497db6, plus the following uncommited chip/g patches (CL:458364): c73af7dd2 chip/g/upgrade: Clarify pdu/frame terminology baea0a8c7 chip/g/upgrade: Rename SIGNED_TRANSFER_SIZE to UPDATE_PDU_SIZE d6e41b75c chip/g/upgrade: Remove cr50-specific upgrade subclass and protocol 3dc0b9a25 chip/g/upgrade: Rename upgrade to update 13436f9b9 chip/g/upgrade: Split rdpu initialization to a separate function fab9a0936 chip/g/upgrade: Minor formatting fixups 8161ef7c0 chip/g/upgrade: Fix valid_transfer_start logic bd6d79434 chip/g/upgrade: Fix logic for short USB packets within frames b09e252ed chip/g/upgrade: Improve error handling Then: diff -u include/update_fw.h chip/g/upgrade_fw.h diff -u common/usb_update.c chip/g/usb_upgrade.c diff -u common/update_fw.c chip/g/upgrade_fw.c Only shows chip/g specific differences. BRANCH=none BUG=b:36375666 BUG=b:35587171 TEST=make buildall -j TEST=Can update hammer over USB using usb_updater2 Change-Id: I5b0f0281d844972dab572955d5495f808127e523 Reviewed-on: https://chromium-review.googlesource.com/458321 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Nick Sanders <nsanders@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'include/update_fw.h')
-rw-r--r--include/update_fw.h145
1 files changed, 140 insertions, 5 deletions
diff --git a/include/update_fw.h b/include/update_fw.h
index f1b76e1033..8f7148f6ed 100644
--- a/include/update_fw.h
+++ b/include/update_fw.h
@@ -8,9 +8,149 @@
#include <stddef.h>
+
+/*
+ * This file contains structures used to facilitate EC firmware updates
+ * over USB (and over TPM for cr50).
+ *
+ * The firmware update protocol consists of two phases: connection
+ * establishment and actual image transfer.
+ *
+ * Image transfer is done in 1K blocks. The host supplying the image
+ * encapsulates blocks in PDUs by prepending a header including the flash
+ * offset where the block is destined and its digest.
+ *
+ * The EC device responds to each PDU with a confirmation which is 1 byte
+ * response. Zero value means success, non zero value is the error code
+ * reported by EC.
+ *
+ * To establish the connection, the host sends a different PDU, which
+ * contains no data and is destined to offset 0. Receiving such a PDU
+ * signals the EC that the host intends to transfer a new image.
+ *
+ * The connection establishment response is described by the
+ * first_response_pdu structure below.
+ */
+
+#define UPDATE_PROTOCOL_VERSION 6
+
+/*
+ * This is the format of the update PDU header.
+ *
+ * block digest: the first four bytes of the sha1 digest of the rest of the
+ * structure (can be 0 on boards where digest is ignored).
+ * block_base: offset of this PDU into the flash SPI.
+ */
+struct update_command {
+ uint32_t block_digest;
+ uint32_t block_base;
+ /* The actual payload goes here. */
+} __packed;
+
+/*
+ * This is the frame format the host uses when sending update PDUs over USB.
+ *
+ * The PDUs are up to 1K bytes in size, they are fragmented into USB chunks of
+ * 64 bytes each and reassembled on the receive side before being passed to
+ * the flash update function.
+ *
+ * The flash update function receives the unframed PDU body (starting at the
+ * cmd field below), and puts its reply into the same buffer the PDU was in.
+ */
+struct update_frame_header {
+ uint32_t block_size; /* Total frame size, including this field. */
+ struct update_command cmd;
+};
+
+/*
+ * A convenience structure which allows to group together various revision
+ * fields of the header created by the signer.
+ *
+ * These fields are compared when deciding if versions of two images are the
+ * same or when deciding which one of the available images to run.
+ */
+struct signed_header_version {
+ uint32_t minor;
+ uint32_t major;
+ uint32_t epoch;
+};
+
+/*
+ * Response to the connection establishment request.
+ *
+ * When responding to the very first packet of the update sequence, the
+ * original USB update implementation was responding with a four byte value,
+ * just as to any other block of the transfer sequence.
+ *
+ * It became clear that there is a need to be able to enhance the update
+ * protocol, while staying backwards compatible.
+ *
+ * All newer protocol versions (starting with version 2) respond to the very
+ * first packet with an 8 byte or larger response, where the first 4 bytes are
+ * a version specific data, and the second 4 bytes - the protocol version
+ * number.
+ *
+ * This way the host receiving of a four byte value in response to the first
+ * packet is considered an indication of the target running the 'legacy'
+ * protocol, version 1. Receiving of an 8 byte or longer response would
+ * communicates the protocol version in the second 4 bytes.
+ */
+struct first_response_pdu {
+ uint32_t return_value;
+
+ /* The below fields are present in versions 2 and up. */
+ uint32_t protocol_version;
+
+ /* The below fields are present in versions 3 and up. */
+ uint32_t backup_ro_offset;
+ uint32_t backup_rw_offset;
+
+ /* The below fields are present in versions 4 and up. */
+ /* Versions of the currently active RO and RW sections. */
+ struct signed_header_version shv[2];
+
+ /* The below fields are present in versions 5 and up */
+ /* keyids of the currently active RO and RW sections. */
+ uint32_t keyid[2];
+};
+
/* TODO: Handle this in update_fw.c, not usb_update.c */
#define UPDATE_DONE 0xB007AB1E
+void fw_update_command_handler(void *body,
+ size_t cmd_size,
+ size_t *response_size);
+
+/* Used to tell fw update the update ran successfully and is finished */
+void fw_update_complete(void);
+
+/* Verify integrity of the PDU received. */
+int update_pdu_valid(struct update_command *cmd_body, size_t cmd_size);
+
+/* Various update command return values. */
+enum {
+ UPDATE_SUCCESS = 0,
+ UPDATE_BAD_ADDR = 1,
+ UPDATE_ERASE_FAILURE = 2,
+ UPDATE_DATA_ERROR = 3,
+ UPDATE_WRITE_FAILURE = 4,
+ UPDATE_VERIFY_ERROR = 5,
+ UPDATE_GEN_ERROR = 6,
+ UPDATE_MALLOC_ERROR = 7,
+ UPDATE_ROLLBACK_ERROR = 8,
+ UPDATE_RATE_LIMIT_ERROR = 9,
+};
+
+/*
+ * This is the size of the update frame payload, unless this is the last chunk
+ * of the image.
+ *
+ * TODO(b/36375666): Some boards may not be able to allocate that much memory.
+ */
+#define UPDATE_PDU_SIZE 1024
+
+/* TODO(b/36375666): The structures below might not belong in this file. */
+
/*
* This array defines possible sections available for the firmare update.
* The section which does not map the current execting code is picked as the
@@ -28,9 +168,4 @@ struct section_descriptor {
extern const struct section_descriptor * const rw_sections;
extern const int num_rw_sections;
-
-void fw_update_command_handler(void *body,
- size_t cmd_size,
- size_t *response_size);
-
#endif /* ! __CROS_EC_UPDATE_FW_H */