summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/usb_pd_protocol.c58
-rw-r--r--include/ec_commands.h10
-rw-r--r--util/ectool.c35
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},