| /* Copyright 2016 The ChromiumOS Authors |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef __EC_CHIP_G_UPGRADE_FW_H |
| #define __EC_CHIP_G_UPGRADE_FW_H |
| |
| #include <stddef.h> |
| |
| #include "common.h" /* For __packed. */ |
| |
| /* |
| * This file contains structures used to facilitate cr50 firmware updates, |
| * which can be used on any g chip. |
| * |
| * 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 frames by prepending a header including the flash |
| * offset where the block is destined and its digest. |
| * |
| * The CR50 device responds to each frame with a confirmation which is 1 byte |
| * response. Zero value means success, non zero value is the error code |
| * reported by CR50. |
| * |
| * To establish the connection, the host sends a different frame, which |
| * contains no data and is destined to offset 0. Receiving such a frame |
| * signals the CR50 that the host intends to transfer a new image. |
| * |
| * The connection establishment response is described by the |
| * first_response_pdu structure below. |
| */ |
| |
| #define UPGRADE_PROTOCOL_VERSION 6 |
| |
| /* This is the format of the update frame header. */ |
| struct upgrade_command { |
| uint32_t block_digest; /* first 4 bytes of sha1 of the rest of the |
| * frame. |
| */ |
| uint32_t block_base; /* Offset of this frame into the flash SPI. */ |
| /* 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 size of the block, including this |
| * field. |
| */ |
| struct upgrade_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 upgrade 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 upgrade |
| * 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]; |
| }; |
| |
| #define UPGRADE_DONE 0xB007AB1E |
| |
| void fw_upgrade_command_handler(void *body, |
| size_t cmd_size, |
| size_t *response_size); |
| |
| /* Used to tell fw upgrade the update ran successfully and is finished */ |
| void fw_upgrade_complete(void); |
| |
| /* Verify integrity of the PDU received over USB. */ |
| int usb_pdu_valid(struct upgrade_command *cmd_body, |
| size_t cmd_size); |
| |
| /* Various upgrade command return values. */ |
| enum return_value { |
| UPGRADE_SUCCESS = 0, |
| UPGRADE_BAD_ADDR = 1, |
| UPGRADE_ERASE_FAILURE = 2, |
| UPGRADE_DATA_ERROR = 3, |
| UPGRADE_WRITE_FAILURE = 4, |
| UPGRADE_VERIFY_ERROR = 5, |
| UPGRADE_GEN_ERROR = 6, |
| UPGRADE_MALLOC_ERROR = 7, |
| UPGRADE_ROLLBACK_ERROR = 8, |
| UPGRADE_RATE_LIMIT_ERROR = 9, |
| UPGRADE_UNALIGNED_BLOCK_ERROR = 10, |
| UPGRADE_TRUNCATED_HEADER_ERROR = 11, |
| UPGRADE_BOARD_ID_ERROR = 12, |
| UPGRADE_BOARD_FLAGS_ERROR = 13, |
| UPGRADE_DEV_ID_MISMATCH_ERROR = 14, |
| }; |
| |
| /* |
| * This is the size of the update frame payload, unless this is the last chunk |
| * of the image. |
| */ |
| #define SIGNED_TRANSFER_SIZE 1024 |
| |
| #endif /* ! __EC_CHIP_G_UPGRADE_FW_H */ |