diff options
-rw-r--r-- | board/fruitpie/usb_pd_policy.c | 18 | ||||
-rw-r--r-- | board/ryu/board.h | 1 | ||||
-rw-r--r-- | board/samus_pd/board.h | 1 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 18 | ||||
-rw-r--r-- | board/zinger/board.h | 4 | ||||
-rw-r--r-- | board/zinger/usb_pd_policy.c | 10 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 28 | ||||
-rw-r--r-- | include/config.h | 9 | ||||
-rw-r--r-- | include/usb_pd.h | 22 |
9 files changed, 87 insertions, 24 deletions
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c index 3292a80a77..0a4b1be7ee 100644 --- a/board/fruitpie/usb_pd_policy.c +++ b/board/fruitpie/usb_pd_policy.c @@ -139,7 +139,6 @@ int pd_board_checks(void) int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); - int i; ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); /* make sure we have some payload */ @@ -152,12 +151,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) *(payload + cnt - 1) = 0; ccprintf("version: %s\n", (char *)(payload+1)); break; - case VDO_CMD_RW_HASH: - ccprintf("RW Hash: "); - payload++; /* skip cmd */ - for (i = 0; i < cnt - 1; i++) - ccprintf("%08x ", *payload++); - ccprintf("\n"); + case VDO_CMD_READ_INFO: + /* copy hash */ + if (cnt >= 6) + pd_dev_store_rw_hash(port, payload + 1); + + /* if last word is present, it contains lots of info */ + if (cnt == 7) + ccprintf("Dev:%d SW:%d RW:%d\n", + VDO_INFO_HW_DEV_ID(payload[6]), + VDO_INFO_SW_DBG_VER(payload[6]), + VDO_INFO_IS_RW(payload[6])); break; } diff --git a/board/ryu/board.h b/board/ryu/board.h index 768f71fb1e..7d3b9f5fc3 100644 --- a/board/ryu/board.h +++ b/board/ryu/board.h @@ -24,6 +24,7 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_FLASH_ERASE_CHECK #define CONFIG_USB_PD_INTERNAL_COMP +#define CONFIG_USB_PD_READ_INFO_ON_CONNECT #define CONFIG_USBC_SS_MUX #define CONFIG_ADC #define CONFIG_HW_CRC diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h index 87cef022b9..4cc58a56e4 100644 --- a/board/samus_pd/board.h +++ b/board/samus_pd/board.h @@ -25,6 +25,7 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_FLASH_ERASE_CHECK #define CONFIG_USB_PD_INTERNAL_COMP +#define CONFIG_USB_PD_READ_INFO_ON_CONNECT #define CONFIG_USBC_SS_MUX #define CONFIG_ADC #define CONFIG_HW_CRC diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index 7b56d12435..bf24b2eb07 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -154,7 +154,6 @@ int pd_board_checks(void) int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); - int i; ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); /* make sure we have some payload */ @@ -167,12 +166,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) *(payload + cnt - 1) = 0; ccprintf("version: %s\n", (char *)(payload+1)); break; - case VDO_CMD_RW_HASH: - ccprintf("RW Hash: "); - payload++; /* skip cmd */ - for (i = 0; i < cnt - 1; i++) - ccprintf("%08x ", *payload++); - ccprintf("\n"); + case VDO_CMD_READ_INFO: + /* copy hash */ + if (cnt >= 6) + pd_dev_store_rw_hash(port, payload + 1); + + /* if last word is present, it contains lots of info */ + if (cnt == 7) + ccprintf("Dev:%d SW:%d RW:%d\n", + VDO_INFO_HW_DEV_ID(payload[6]), + VDO_INFO_SW_DBG_VER(payload[6]), + VDO_INFO_IS_RW(payload[6])); break; case VDO_CMD_CURRENT: ccprintf("Current: %dmA\n", payload[1]); diff --git a/board/zinger/board.h b/board/zinger/board.h index ead71fb711..f3a0d3dc5f 100644 --- a/board/zinger/board.h +++ b/board/zinger/board.h @@ -42,6 +42,10 @@ #define UARTN CONFIG_UART_CONSOLE #define UARTN_BASE STM32_USART_BASE(CONFIG_UART_CONSOLE) +/* USB PD ChromeOS VDM information */ +#define USB_PD_HARDWARE_DEVICE_ID 1 +#define USB_PD_DBG_SW_VERSION 255 + #ifndef __ASSEMBLER__ #include "common.h" diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c index a4fcc38fe1..591021bb56 100644 --- a/board/zinger/usb_pd_policy.c +++ b/board/zinger/usb_pd_policy.c @@ -369,10 +369,16 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) pd_power_supply_reset(0); cpu_reset(); break; - case VDO_CMD_RW_HASH: + case VDO_CMD_READ_INFO: hash = flash_hash_rw(); + /* copy hash into response */ memcpy(payload + 1, hash, SHA1_DIGEST_SIZE); - rsize = 6; + /* copy other info into response */ + payload[SHA1_DIGEST_SIZE/4 + 1] = VDO_INFO( + USB_PD_HARDWARE_DEVICE_ID, + USB_PD_DBG_SW_VERSION, + !is_ro_mode()); + rsize = 7; break; case VDO_CMD_FLASH_ERASE: /* do not kill the code under our feet */ diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 263c9b63e0..387ea20e82 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -13,6 +13,7 @@ #include "hooks.h" #include "host_command.h" #include "registers.h" +#include "sha1.h" #include "task.h" #include "timer.h" #include "util.h" @@ -220,6 +221,9 @@ static struct pd_protocol { /* next Vendor Defined Message to send */ uint32_t vdo_data[VDO_MAX_SIZE]; uint8_t vdo_count; + + /* Attached ChromeOS device RW hash */ + uint32_t dev_rw_hash[SHA1_DIGEST_SIZE/4]; } pd[PD_PORT_COUNT]; /* @@ -1019,6 +1023,11 @@ static void pd_vdm_send_state_machine(int port) } } +void pd_dev_store_rw_hash(int port, uint32_t *rw_hash) +{ + memcpy(pd[port].dev_rw_hash, rw_hash, SHA1_DIGEST_SIZE); +} + #ifdef CONFIG_USB_PD_DUAL_ROLE void pd_set_dual_role(enum pd_dual_role_states state) { @@ -1276,6 +1285,11 @@ void pd_task(void) !(cc1_volt >= PD_SNK_VA); pd_select_polarity(port, pd[port].polarity); +#ifdef CONFIG_USB_PD_READ_INFO_ON_CONNECT + /* Send google VDM to read info */ + pd_send_vdm(port, USB_VID_GOOGLE, + VDO_CMD_READ_INFO, NULL, 0); +#endif set_state(port, PD_STATE_SNK_DISCOVERY); timeout = 10*MSEC; } @@ -1493,9 +1507,9 @@ static int remote_flashing(int argc, char **argv) cmd = VDO_CMD_FLASH_HASH; cnt = argc; ccprintf("HASH ..."); - } else if (!strcasecmp(argv[3], "rw_hash")) { - cmd = VDO_CMD_RW_HASH; - ccprintf("RW HASH..."); + } else if (!strcasecmp(argv[3], "info")) { + cmd = VDO_CMD_READ_INFO; + ccprintf("INFO..."); } else if (!strcasecmp(argv[3], "version")) { cmd = VDO_CMD_VERSION; ccprintf("VERSION..."); @@ -1602,6 +1616,11 @@ static int command_pd(int argc, char **argv) } else if (!strncasecmp(argv[2], "hard", 4)) { set_state(port, PD_STATE_HARD_RESET); task_wake(PORT_TO_TASK_ID(port)); + } else if (!strncasecmp(argv[2], "hash", 4)) { + int i; + for (i = 0; i < SHA1_DIGEST_SIZE / 4; i++) + ccprintf("%08x ", pd[port].dev_rw_hash[i]); + ccprintf("\n"); } else if (!strncasecmp(argv[2], "soft", 4)) { execute_soft_reset(port); send_control(port, PD_CTRL_SOFT_RESET); @@ -1690,7 +1709,8 @@ static int command_pd(int argc, char **argv) DECLARE_CONSOLE_COMMAND(pd, command_pd, "<port> " "[tx|bist|charger|dev|dump|dualrole|enable" - "|soft|hard|clock|ping|state|vdm [ping | curr]]", + "|soft|hash|hard|clock|ping|state" + "|vdm [ping | curr]]", "USB PD", NULL); diff --git a/include/config.h b/include/config.h index 1221a6f6bc..609d0943b2 100644 --- a/include/config.h +++ b/include/config.h @@ -941,6 +941,9 @@ /* Define if this board can act as a dual-role PD port (source and sink) */ #undef CONFIG_USB_PD_DUAL_ROLE +/* Dynamic USB PD source capability */ +#undef CONFIG_USB_PD_DYNAMIC_SRC_CAP + /* Check whether PD is the sole power source before flash erase operation */ #undef CONFIG_USB_PD_FLASH_ERASE_CHECK @@ -950,12 +953,12 @@ /* Define if using internal comparator for PD receive */ #undef CONFIG_USB_PD_INTERNAL_COMP +/* Define to have PD state machine send read info VDM on connection */ +#undef CONFIG_USB_PD_READ_INFO_ON_CONNECT + /* USB PD transmit uses SPI master */ #undef CONFIG_USB_PD_TX_USES_SPI_MASTER -/* Dynamic USB PD source capability */ -#undef CONFIG_USB_PD_DYNAMIC_SRC_CAP - /* Support for USB type-c superspeed mux */ #undef CONFIG_USBC_SS_MUX diff --git a/include/usb_pd.h b/include/usb_pd.h index 83fee88cf0..4a9376a369 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -122,7 +122,7 @@ enum pd_errors { /* ChromeOS specific commands */ #define VDO_CMD_VERSION VDO_CMD_VENDOR(0) -#define VDO_CMD_RW_HASH VDO_CMD_VENDOR(2) +#define VDO_CMD_READ_INFO VDO_CMD_VENDOR(2) #define VDO_CMD_REBOOT VDO_CMD_VENDOR(5) #define VDO_CMD_FLASH_ERASE VDO_CMD_VENDOR(6) #define VDO_CMD_FLASH_WRITE VDO_CMD_VENDOR(7) @@ -133,6 +133,18 @@ enum pd_errors { #define PD_VDO_VID(vdo) ((vdo) >> 16) #define PD_VDO_CMD(vdo) ((vdo) & 0x1f) +/* + * ChromeOS specific VDO_CMD_READ_INFO responds with device info including: + * RW Hash: sha1 of RW hash (20 bytes) + * HW Device ID: unique descriptor for each ChromeOS model (2 bytes) + * SW Debug Version: Software version useful for debugging (1 byte) + * IS RW: True if currently in RW, False otherwise (1 bit) + */ +#define VDO_INFO(id, ver, is_rw) ((id) << 16 | (ver) << 8 | (is_rw)) +#define VDO_INFO_HW_DEV_ID(x) ((x) >> 16) +#define VDO_INFO_SW_DBG_VER(x) (((x) >> 8) & 0xff) +#define VDO_INFO_IS_RW(x) ((x) & 1) + /* USB Vendor ID assigned to Google Inc. */ #define USB_VID_GOOGLE 0x18d1 @@ -293,6 +305,14 @@ int pd_board_checks(void); int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload); /** + * Store RW hash of device + * + * @param port USB-C port number + * @param rw_hash pointer to sha1 rw_hash + */ +void pd_dev_store_rw_hash(int port, uint32_t *rw_hash); + +/** * Send Vendor Defined Message * * @param port USB-C port number |