diff options
author | Nicolas Boichat <drinkcat@google.com> | 2017-03-22 10:50:39 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-04-15 04:08:07 -0700 |
commit | 2f5e46cef48ec0671fd014bbdb38b060339db998 (patch) | |
tree | 147061592ddb8fa0ba504b5b1ba93dbdd1b23bd4 /include/update_fw.h | |
parent | 20c439be209a9cc0bb949ad21f289c453126395f (diff) | |
download | chrome-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.h | 145 |
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 */ |