summaryrefslogtreecommitdiff
path: root/common
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 /common
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>
Diffstat (limited to 'common')
-rw-r--r--common/usb_pd_policy.c100
-rw-r--r--common/usb_pd_protocol.c31
2 files changed, 100 insertions, 31 deletions
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)
{