summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-11-24 10:20:41 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-05 10:06:25 +0000
commitbc1690366776fb65d8fa773c2f74c4f71f5059e5 (patch)
treef0e6643adfcfd146681786d0251adf15da24bc1e
parentb5557217aa7343a565ab172ce22488af5fc1de03 (diff)
downloadchrome-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.c23
-rw-r--r--board/hoho/usb_pd_policy.c23
-rw-r--r--board/zinger/board.c40
-rw-r--r--board/zinger/board.h7
-rw-r--r--board/zinger/hardware.c15
-rw-r--r--board/zinger/runtime.c4
-rw-r--r--board/zinger/usb_pd_policy.c69
-rw-r--r--chip/stm32/build.mk5
-rw-r--r--common/usb_pd_policy.c100
-rw-r--r--common/usb_pd_protocol.c31
-rw-r--r--include/usb_pd.h11
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 */