diff options
author | Todd Broch <tbroch@chromium.org> | 2014-11-24 10:20:41 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-12-05 10:06:25 +0000 |
commit | bc1690366776fb65d8fa773c2f74c4f71f5059e5 (patch) | |
tree | f0e6643adfcfd146681786d0251adf15da24bc1e | |
parent | b5557217aa7343a565ab172ce22488af5fc1de03 (diff) | |
download | chrome-ec-bc1690366776fb65d8fa773c2f74c4f71f5059e5.tar.gz |
pd: Re-factor common flash vdms.
CL to migrate the flashing VDMs from zinger's custom vdm to
common/usb_pd_flash.c such that other updateable type-C devices can
share.
Additionally adds gaskets to call standard runtime flashing facilities
for USB-PD devices using it.
Signed-off-by: Todd Broch <tbroch@chromium.org>
BRANCH=samus
BUG=chrome-os-partner:31192,chrome-os-partner:31193
TEST=manual,
Try following:
1. From samus_pd console w/ zinger in port 1
pd 1 flash version
pd 1 flash reboot
pd 1 flash info
2. From samus linux prompt w/ zinger in port 1
ectool --name cros_pd flashpd 1 1 <zinger RW payload>
Reading 16384 bytes from
/usr/local/zinger_v1.1.2528-d809e42.ec.RW.bin...
Erasing expected RW hash
Rebooting
Erasing RW flash
Writing RW flash
Rebooting PD into new RW
Complete
3. Repeat 1&2 above on hoho & dingdong.
Change-Id: I018055fa9de128f937c57debdc21dea026137bcf
Reviewed-on: https://chromium-review.googlesource.com/231835
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Tested-by: Todd Broch <tbroch@chromium.org>
Commit-Queue: Todd Broch <tbroch@chromium.org>
-rw-r--r-- | board/dingdong/usb_pd_policy.c | 23 | ||||
-rw-r--r-- | board/hoho/usb_pd_policy.c | 23 | ||||
-rw-r--r-- | board/zinger/board.c | 40 | ||||
-rw-r--r-- | board/zinger/board.h | 7 | ||||
-rw-r--r-- | board/zinger/hardware.c | 15 | ||||
-rw-r--r-- | board/zinger/runtime.c | 4 | ||||
-rw-r--r-- | board/zinger/usb_pd_policy.c | 69 | ||||
-rw-r--r-- | chip/stm32/build.mk | 5 | ||||
-rw-r--r-- | common/usb_pd_policy.c | 100 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 31 | ||||
-rw-r--r-- | include/usb_pd.h | 11 |
11 files changed, 163 insertions, 165 deletions
diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c index a09a432492..2a3c027e61 100644 --- a/board/dingdong/usb_pd_policy.c +++ b/board/dingdong/usb_pd_policy.c @@ -287,23 +287,18 @@ static int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); - int rsize = 1; + int rsize; + + if (PD_VDO_VID(payload[0]) != USB_VID_GOOGLE || !gfu_mode) + return 0; + CPRINTF("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); *rpayload = payload; - switch (cmd) { - case VDO_CMD_VERSION: - memcpy(payload + 1, &version_data.version, 24); - rsize = 7; - break; - case VDO_CMD_READ_INFO: - /* copy info into response */ - pd_get_info(payload + 1); - rsize = 7; - break; - default: - rsize = 0; - } + + rsize = pd_custom_flash_vdm(port, cnt, payload); + if (!rsize) + return 0; CPRINTS("DONE"); /* respond (positively) to the request */ diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c index 50792a0e68..c9525f2ebe 100644 --- a/board/hoho/usb_pd_policy.c +++ b/board/hoho/usb_pd_policy.c @@ -286,23 +286,18 @@ static int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); - int rsize = 1; + int rsize; + + if (PD_VDO_VID(payload[0]) != USB_VID_GOOGLE || !gfu_mode) + return 0; + CPRINTF("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); *rpayload = payload; - switch (cmd) { - case VDO_CMD_VERSION: - memcpy(payload + 1, &version_data.version, 24); - rsize = 7; - break; - case VDO_CMD_READ_INFO: - /* copy info into response */ - pd_get_info(payload + 1); - rsize = 7; - break; - default: - rsize = 0; - } + + rsize = pd_custom_flash_vdm(port, cnt, payload); + if (!rsize) + return 0; CPRINTS("DONE"); /* respond (positively) to the request */ diff --git a/board/zinger/board.c b/board/zinger/board.c index 5dcbef04fb..3ea9850015 100644 --- a/board/zinger/board.c +++ b/board/zinger/board.c @@ -9,6 +9,7 @@ #include "registers.h" #include "rsa.h" #include "sha256.h" +#include "system.h" #include "task.h" #include "usb_pd.h" #include "util.h" @@ -23,10 +24,6 @@ static const void *rw_sig = (void *)CONFIG_FLASH_BASE + CONFIG_FW_RW_OFF /* Large 768-Byte buffer for RSA computation : could be re-use afterwards... */ static uint32_t rsa_workbuf[3 * RSANUMWORDS]; -static uint8_t *rw_hash; -static uint8_t rw_flash_changed; -static uint32_t info_data[6]; - extern void pd_rx_handler(void); /* RW firmware reset vector */ @@ -60,12 +57,16 @@ int is_ro_mode(void) static int check_rw_valid(void) { int good; + void *rw_hash; /* Check if we have a RW firmware flashed */ if (*rw_rst == 0xffffffff) return 0; - good = rsa_verify(&pkey, (void *)rw_sig, (void *)rw_hash, rsa_workbuf); + /* calculate hash of RW */ + rw_hash = flash_hash_rw(); + + good = rsa_verify(&pkey, (void *)rw_sig, rw_hash, rsa_workbuf); if (!good) { debug_printf("RSA verify FAILED\n"); return 0; @@ -74,30 +75,6 @@ static int check_rw_valid(void) return 1; } -uint32_t *board_get_info(void) -{ - if (rw_flash_changed) { - /* re-calculate RW hash */ - rw_hash = flash_hash_rw(); - rw_flash_changed = 0; - } - - /* copy first 20 bytes of RW hash */ - memcpy(info_data, rw_hash, 5 * sizeof(uint32_t)); - - /* copy other info into data msg */ - info_data[5] = VDO_INFO(CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR, - CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR, - ver_get_numcommits(), !is_ro_mode()); - - return info_data; -} - -void board_rw_contents_change(void) -{ - rw_flash_changed = 1; -} - extern void pd_task(void); int main(void) @@ -106,9 +83,6 @@ int main(void) debug_printf("Power supply started ... %s\n", is_ro_mode() ? "RO" : "RW"); - /* calculate hash of RW */ - rw_hash = flash_hash_rw(); - /* Verify RW firmware and use it if valid */ if (is_ro_mode() && check_rw_valid()) jump_to_rw(); @@ -118,6 +92,6 @@ int main(void) debug_printf("background loop exited !\n"); /* we should never reach that point */ - cpu_reset(); + system_reset(0); return 0; } diff --git a/board/zinger/board.h b/board/zinger/board.h index 8d7dcd4268..79d60514eb 100644 --- a/board/zinger/board.h +++ b/board/zinger/board.h @@ -109,13 +109,6 @@ int32_t get_rtc_diff(uint32_t rtc0, uint32_t rtc0ss, uint32_t rtc1, uint32_t rtc1ss); void __enter_hibernate(uint32_t seconds, uint32_t microseconds); -/* Reboot the CPU */ -void cpu_reset(void); - -/* Board version information functions */ -uint32_t *board_get_info(void); -void board_rw_contents_change(void); - #endif /* !__ASSEMBLER__ */ #endif /* __BOARD_H */ diff --git a/board/zinger/hardware.c b/board/zinger/hardware.c index 1238d31a0d..54a92aaccd 100644 --- a/board/zinger/hardware.c +++ b/board/zinger/hardware.c @@ -298,16 +298,12 @@ int adc_disable_watchdog(void) #define STRT (1<<6) #define CR_LOCK (1<<7) -int flash_write_rw(int offset, int size, const char *data) +int flash_physical_write(int offset, int size, const char *data) { - uint16_t *address = (uint16_t *) - (CONFIG_FLASH_BASE + CONFIG_FW_RW_OFF + offset); + uint16_t *address = (uint16_t *)(CONFIG_FLASH_BASE + offset); int res = EC_SUCCESS; int i; - /* notify board of a RW flash contents change */ - board_rw_contents_change(); - if ((uint32_t)address > CONFIG_FLASH_BASE + CONFIG_FLASH_SIZE) return EC_ERROR_INVAL; @@ -353,14 +349,9 @@ exit_wr: return res; } -int flash_erase_rw(void) +int flash_physical_erase(int offset, int size) { int res = EC_SUCCESS; - int offset = CONFIG_FW_RW_OFF; - int size = CONFIG_FW_RW_SIZE; - - /* notify board of a RW flash contents change */ - board_rw_contents_change(); /* unlock CR if needed */ if (STM32_FLASH_CR & CR_LOCK) { diff --git a/board/zinger/runtime.c b/board/zinger/runtime.c index 0724c68c81..171c706bfa 100644 --- a/board/zinger/runtime.c +++ b/board/zinger/runtime.c @@ -205,6 +205,10 @@ void cpu_reset(void) ; } +void system_reset(int flags) +{ + cpu_reset(); +} /** * Default exception handler, which reports a panic. * diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c index e4cb5ea9f4..8442f689d6 100644 --- a/board/zinger/usb_pd_policy.c +++ b/board/zinger/usb_pd_policy.c @@ -14,7 +14,6 @@ #include "timer.h" #include "util.h" #include "usb_pd.h" -#include "version.h" /* ------------------------- Power supply control ------------------------ */ @@ -491,69 +490,33 @@ const struct svdm_response svdm_rsp = { static int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { - static int flash_offset; int cmd = PD_VDO_CMD(payload[0]); - int rsize = 1; + int rsize; if (PD_VDO_VID(payload[0]) != USB_VID_GOOGLE || !gfu_mode) return 0; debug_printf("%T] VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); - *rpayload = payload; - switch (cmd) { - case VDO_CMD_VERSION: - memcpy(payload + 1, &version_data.version, 24); - rsize = 7; - break; - case VDO_CMD_REBOOT: - /* ensure the power supply is in a safe state */ - pd_power_supply_reset(0); - cpu_reset(); - break; - case VDO_CMD_READ_INFO: - /* copy info into response */ - memcpy(payload + 1, board_get_info(), 24); - rsize = 7; - break; - case VDO_CMD_FLASH_ERASE: - /* do not kill the code under our feet */ - if (!is_ro_mode()) + + rsize = pd_custom_flash_vdm(port, cnt, payload); + if (!rsize) { + switch (cmd) { + case VDO_CMD_PING_ENABLE: + pd_ping_enable(0, payload[1]); + rsize = 1; break; - flash_offset = 0; - flash_erase_rw(); - break; - case VDO_CMD_FLASH_WRITE: - /* do not kill the code under our feet */ - if (!is_ro_mode()) + case VDO_CMD_CURRENT: + /* return last measured current */ + payload[1] = ADC_TO_CURR_MA(vbus_amp); + rsize = 2; break; - flash_write_rw(flash_offset, 4*(cnt - 1), - (const char *)(payload+1)); - flash_offset += 4*(cnt - 1); - break; - case VDO_CMD_ERASE_SIG: - /* this is not touching the code area */ - { - uint32_t zero = 0; - int offset; - /* zeroes the area containing the RSA signature */ - for (offset = CONFIG_FW_RW_SIZE - 256; - offset < CONFIG_FW_RW_SIZE; offset += 4) - flash_write_rw(offset, 4, (const char *)&zero); + default: + /* Unknown : do not answer */ + return 0; } - break; - case VDO_CMD_PING_ENABLE: - pd_ping_enable(0, payload[1]); - break; - case VDO_CMD_CURRENT: - /* return last measured current */ - payload[1] = ADC_TO_CURR_MA(vbus_amp); - rsize = 2; - break; - default: - /* Unknown : do not answer */ - return 0; } + debug_printf("%T] DONE\n"); /* respond (positively) to the request */ payload[0] |= VDO_SRC_RESPONDER; diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk index 75f97fb7b2..c2577fe34a 100644 --- a/chip/stm32/build.mk +++ b/chip/stm32/build.mk @@ -26,7 +26,8 @@ endif # Select between 16-bit and 32-bit timer for clock source TIMER_TYPE=$(if $(CONFIG_STM_HWTIMER32),32,) -chip-y=dma.o system.o +chip-y=dma.o +chip-$(CONFIG_COMMON_RUNTIME)+=system.o chip-y+=jtag-$(CHIP_FAMILY).o clock-$(CHIP_FAMILY).o chip-$(CONFIG_SPI)+=spi.o chip-$(CONFIG_SPI_MASTER_PORT)+=spi_master.o @@ -40,9 +41,11 @@ chip-$(HAS_TASK_CONSOLE)+=uart.o chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o chip-$(HAS_TASK_POWERLED)+=power_led.o chip-$(CONFIG_FLASH)+=flash-$(CHIP_FAMILY).o +ifdef CONFIG_FLASH chip-$(CHIP_FAMILY_STM32F)+=flash-f.o chip-$(CHIP_FAMILY_STM32F0)+=flash-f.o chip-$(CHIP_FAMILY_STM32F3)+=flash-f.o +endif chip-$(CONFIG_ADC)+=adc-$(CHIP_FAMILY).o chip-$(CONFIG_PWM)+=pwm.o chip-$(CONFIG_USB)+=usb.o usb-$(CHIP_FAMILY).o usb_endpoints.o diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 5bcb58dd71..118a04fbed 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -6,10 +6,14 @@ #include "atomic.h" #include "common.h" #include "console.h" +#include "flash.h" #include "gpio.h" #include "hooks.h" #include "host_command.h" #include "registers.h" +#include "rsa.h" +#include "sha256.h" +#include "system.h" #include "task.h" #include "timer.h" #include "util.h" @@ -26,6 +30,8 @@ #define CPRINTF(format, args...) #endif +static int rw_flash_changed = 1; + #ifdef CONFIG_USB_PD_ALT_MODE #ifdef CONFIG_USB_PD_ALT_MODE_DFP @@ -475,3 +481,97 @@ DECLARE_HOST_COMMAND(EC_CMD_USB_PD_DISCOVERY, hc_remote_pd_discovery, EC_VER_MASK(0)); #endif + +#define FW_RW_END (CONFIG_FW_RW_OFF + CONFIG_FW_RW_SIZE) + +uint8_t *flash_hash_rw(void) +{ + static struct sha256_ctx ctx; + + /* re-calculate RW hash when changed as its time consuming */ + if (rw_flash_changed) { + rw_flash_changed = 0; + SHA256_init(&ctx); + SHA256_update(&ctx, (void *)CONFIG_FLASH_BASE + + CONFIG_FW_RW_OFF, + CONFIG_FW_RW_SIZE - RSANUMBYTES); + return SHA256_final(&ctx); + } else { + return ctx.buf; + } +} + +void pd_get_info(uint32_t *info_data) +{ + void *rw_hash = flash_hash_rw(); + + /* copy first 20 bytes of RW hash */ + memcpy(info_data, rw_hash, 5 * sizeof(uint32_t)); + /* copy other info into data msg */ +#if defined(CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR) && \ + defined(CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR) + info_data[5] = VDO_INFO(CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR, + CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR, + ver_get_numcommits(), + (system_get_image_copy() != SYSTEM_IMAGE_RO)); +#else + info_data[5] = 0; +#endif +} + +int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload) +{ + static int flash_offset; + int rsize = 1; /* default is just VDM header returned */ + + switch (PD_VDO_CMD(payload[0])) { + case VDO_CMD_VERSION: + memcpy(payload + 1, &version_data.version, 24); + rsize = 7; + break; + case VDO_CMD_REBOOT: + /* ensure the power supply is in a safe state */ + pd_power_supply_reset(0); + system_reset(0); + break; + case VDO_CMD_READ_INFO: + /* copy info into response */ + pd_get_info(payload + 1); + rsize = 7; + break; + case VDO_CMD_FLASH_ERASE: + /* do not kill the code under our feet */ + if (system_get_image_copy() != SYSTEM_IMAGE_RO) + break; + flash_offset = CONFIG_FW_RW_OFF; + flash_physical_erase(CONFIG_FW_RW_OFF, CONFIG_FW_RW_SIZE); + rw_flash_changed = 1; + break; + case VDO_CMD_FLASH_WRITE: + /* do not kill the code under our feet */ + if ((system_get_image_copy() != SYSTEM_IMAGE_RO) || + (flash_offset < CONFIG_FW_RW_OFF)) + break; + flash_physical_write(flash_offset, 4*(cnt - 1), + (const char *)(payload+1)); + flash_offset += 4*(cnt - 1); + rw_flash_changed = 1; + break; + case VDO_CMD_ERASE_SIG: + /* this is not touching the code area */ + { + uint32_t zero = 0; + int offset; + /* zeroes the area containing the RSA signature */ + for (offset = FW_RW_END - RSANUMBYTES; + offset < FW_RW_END; offset += 4) + flash_physical_write(offset, 4, + (const char *)&zero); + } + break; + default: + /* Unknown : do not answer */ + return 0; + } + return rsize; +} diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index d24a8ef524..131a441913 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -15,8 +15,6 @@ #include "hooks.h" #include "host_command.h" #include "registers.h" -#include "rsa.h" -#include "sha256.h" #include "system.h" #include "task.h" #include "timer.h" @@ -1329,35 +1327,6 @@ void pd_dev_store_rw_hash(int port, uint16_t dev_id, uint32_t *rw_hash) pd_dev_dump_info(dev_id, (uint8_t *)rw_hash); } -uint8_t *flash_hash_rw(void) -{ - static struct sha256_ctx ctx; - SHA256_init(&ctx); - SHA256_update(&ctx, (void *)CONFIG_FLASH_BASE + CONFIG_FW_RW_OFF, - CONFIG_FW_RW_SIZE - RSANUMBYTES); - return SHA256_final(&ctx); -} - -void pd_get_info(uint32_t *info_data) -{ - void *hash; - - /* calculate RW hash */ - hash = flash_hash_rw(); - /* copy first 20 bytes of RW hash */ - memcpy(info_data, hash, 5 * sizeof(uint32_t)); - /* copy other info into data msg */ -#if defined(CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR) && \ - defined(CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR) - info_data[5] = VDO_INFO(CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR, - CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR, - ver_get_numcommits(), - (system_get_image_copy() != SYSTEM_IMAGE_RO)); -#else - info_data[5] = 0; -#endif -} - #ifdef CONFIG_USB_PD_DUAL_ROLE void pd_set_dual_role(enum pd_dual_role_states state) { diff --git a/include/usb_pd.h b/include/usb_pd.h index 9b6ddaac83..7418988236 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -821,6 +821,16 @@ int pd_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload); int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload); /** + * Handle Custom VDMs for flashing. + * + * @param port USB-C port number + * @param cnt number of data objects in the payload. + * @param payload payload data. + * @return if >0, number of VDOs to send back. + */ +int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload); + +/** * Exit alternate mode * * @param port USB-C port number @@ -1165,4 +1175,5 @@ void pd_soft_reset(void); * @param port USB-C port number */ void pd_set_new_power_request(int port); + #endif /* __USB_PD_H */ |