diff options
-rw-r--r-- | common/usb_pd_protocol.c | 58 | ||||
-rw-r--r-- | include/ec_commands.h | 10 | ||||
-rw-r--r-- | util/ectool.c | 35 |
3 files changed, 102 insertions, 1 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index c4882892ac..ed358dbc56 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -266,6 +266,14 @@ static uint8_t pd_comm_enabled = CONFIG_USB_PD_COMM_ENABLED; struct mutex pd_crc_lock; +/* + * 4 entry rw_hash table of type-C devices that AP has firmware updates for. + */ +#ifdef CONFIG_COMMON_RUNTIME +#define RW_HASH_ENTRIES 4 +static struct ec_params_usb_pd_rw_hash_entry rw_hash_table[RW_HASH_ENTRIES]; +#endif + static inline void set_state_timeout(int port, uint64_t timeout, enum pd_states timeout_state) @@ -1633,10 +1641,24 @@ static int command_pd(int argc, char **argv) int port; char *e; - if (argc < 3) + if (argc < 2) return EC_ERROR_PARAM_COUNT; + if (!strncasecmp(argv[1], "rwhashtable", 3)) { + int i, j; + struct ec_params_usb_pd_rw_hash_entry *p; + for (i = 0; i < RW_HASH_ENTRIES; i++) { + p = &rw_hash_table[i]; + ccprintf("Device:%d Hash:", p->dev_id); + for (j = 0; j < SHA1_DIGEST_SIZE/4; j++) + ccprintf(" 0x%08x", p->dev_rw_hash.w[j]); + ccprintf("\n"); + } + return EC_SUCCESS; + } port = strtoi(argv[1], &e, 10); + if (argc < 3) + return EC_ERROR_PARAM_COUNT; if (*e || port >= PD_PORT_COUNT) return EC_ERROR_PARAM2; @@ -1966,4 +1988,38 @@ DECLARE_HOST_COMMAND(EC_CMD_USB_PD_FW_UPDATE, hc_remote_flash, EC_VER_MASK(0)); +static int hc_remote_rw_hash_entry(struct host_cmd_handler_args *args) +{ + int i, idx = 0, found = 0; + const struct ec_params_usb_pd_rw_hash_entry *p = args->params; + static int rw_hash_next_idx; + + if (!p->dev_id) { + ccprintf("PD RW_HASH - 0 is not a valid device id"); + return EC_RES_INVALID_PARAM; + } + + for (i = 0; i < RW_HASH_ENTRIES; i++) { + if (p->dev_id == rw_hash_table[i].dev_id) { + idx = i; + found = 1; + break; + } + } + if (!found) { + idx = rw_hash_next_idx; + rw_hash_next_idx = rw_hash_next_idx + 1; + if (rw_hash_next_idx == RW_HASH_ENTRIES) + rw_hash_next_idx = 0; + } + memcpy(&rw_hash_table[idx], p, sizeof(*p)); + ccprintf("PD RW_HASH - stored dev_id:%d at index:%d\n", + rw_hash_table[idx].dev_id, idx); + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_USB_PD_RW_HASH_ENTRY, + hc_remote_rw_hash_entry, + EC_VER_MASK(0)); + #endif /* CONFIG_COMMON_RUNTIME */ diff --git a/include/ec_commands.h b/include/ec_commands.h index 64b70909b4..27b3107c16 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -2,6 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "sha1.h" /* Host communication command constants for Chrome EC */ @@ -2626,7 +2627,16 @@ struct ec_params_usb_pd_fw_update { /* Followed by data to write */ } __packed; +/* Write USB-PD Accessory RW_HASH table entry */ +#define EC_CMD_USB_PD_RW_HASH_ENTRY 0x111 +struct ec_params_usb_pd_rw_hash_entry { + uint8_t dev_id; + union { + uint8_t b[SHA1_DIGEST_SIZE]; + uint32_t w[DIV_ROUND_UP(SHA1_DIGEST_SIZE, sizeof(uint32_t))]; + } dev_rw_hash; +} __packed; /*****************************************************************************/ /* * Passthru commands diff --git a/util/ectool.c b/util/ectool.c index 8f722f974d..0d380c0e78 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -160,6 +160,8 @@ const char help_str[] = " Print real-time clock\n" " rtcset <time>\n" " Set real-time clock\n" + " rwhashpd <dev_id> <SHA1[0] ... <SHA1[4]>\n" + " Set entry in PD MCU's device rw_hash table.\n" " sertest\n" " Serial output test for COM2\n" " switches\n" @@ -778,6 +780,38 @@ int cmd_flash_protect(int argc, char *argv[]) return 0; } +int cmd_rw_hash_pd(int argc, char *argv[]) +{ + struct ec_params_usb_pd_rw_hash_entry *p = + (struct ec_params_usb_pd_rw_hash_entry *)ec_outbuf; + int i, rv; + char *e; + + if (argc < 7) { + fprintf(stderr, "Usage: %s <dev_id> <SHA1[0]> ... <SHA1[4]>\n", + argv[0]); + return -1; + } + + p->dev_id = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad device ID\n"); + return -1; + } + + for (i = 2; i < 7; i++) { + p->dev_rw_hash.w[i - 2] = strtol(argv[i], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad SHA1 digest\n"); + return -1; + } + } + rv = ec_command(EC_CMD_USB_PD_RW_HASH_ENTRY, 0, p, sizeof(*p), NULL, 0); + + return rv; +} + + /* PD image size is 16k minus 32 bits for the RW hash */ #define PD_RW_IMAGE_SIZE (16 * 1024 - 32) static struct sha1_ctx ctx; @@ -4729,6 +4763,7 @@ const struct command commands[] = { {"reboot_ec", cmd_reboot_ec}, {"rtcget", cmd_rtc_get}, {"rtcset", cmd_rtc_set}, + {"rwhashpd", cmd_rw_hash_pd}, {"sertest", cmd_serial_test}, {"port80flood", cmd_port_80_flood}, {"switches", cmd_switches}, |