summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2017-07-31 12:35:32 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-08-10 01:14:59 -0700
commit23b0d417f564619779dfb7c20ec4502d3ca132fe (patch)
tree877bc068a5c3b205a188b8ad403f50017e611443
parent7947687f12b2e802b2ef8cb13f9688ee7c10b746 (diff)
downloadchrome-ec-23b0d417f564619779dfb7c20ec4502d3ca132fe.tar.gz
update_fw: Add support for touchpad update over virtual address
In the field, we want to update touchpad FW using the same USB update protocol as the main EC FW. To distinguish between EC FW update and touchpad FW update, we use a virtual address, defined by CONFIG_TOUCHPAD_VIRTUAL_OFF, that does not map to anything on the EC chip. Also, this will allow us to verify hashes of each block of the flashed touchpad firmware, so that we can ensure its integrity before flashing it into the touchpad. A stub is implemented in update_fw.c:contents_allowed. BRANCH=none BUG=b:63993173 TEST=With follow-up CLs, ./usb_updater2 -p 144.0_2.0.bin Change-Id: I4de1d7d138fc01fe1552a4173c8ef208ecb834a7 Signed-off-by: Nicolas Boichat <drinkcat@google.com> Reviewed-on: https://chromium-review.googlesource.com/593373 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Chun-ta Lin <itspeter@chromium.org>
-rw-r--r--common/update_fw.c54
-rw-r--r--common/usb_update.c5
-rw-r--r--include/config.h7
-rw-r--r--include/update_fw.h10
4 files changed, 76 insertions, 0 deletions
diff --git a/common/update_fw.c b/common/update_fw.c
index c08e8322b5..93206f4066 100644
--- a/common/update_fw.c
+++ b/common/update_fw.c
@@ -11,6 +11,7 @@
#include "include/compile_time_macros.h"
#include "rollback.h"
#include "rwsig.h"
+#include "sha256.h"
#include "system.h"
#include "uart.h"
#include "update_fw.h"
@@ -25,6 +26,20 @@ struct {
uint32_t top_offset;
} update_section;
+#ifdef CONFIG_TOUCHPAD_VIRTUAL_OFF
+/*
+ * Check if a block is within touchpad FW virtual address region, and
+ * is therefore meant to be flashed to the touchpad.
+ */
+static int is_touchpad_block(uint32_t block_offset, size_t body_size)
+{
+ return (block_offset >= CONFIG_TOUCHPAD_VIRTUAL_OFF) &&
+ (block_offset + body_size) <=
+ (CONFIG_TOUCHPAD_VIRTUAL_OFF +
+ CONFIG_TOUCHPAD_VIRTUAL_SIZE);
+}
+#endif
+
/*
* Verify that the passed in block fits into the valid area. If it does, and
* is destined to the base address of the area - erase the area contents.
@@ -62,6 +77,11 @@ static uint8_t check_update_chunk(uint32_t block_offset, size_t body_size)
return UPDATE_SUCCESS;
}
+#ifdef CONFIG_TOUCHPAD_VIRTUAL_OFF
+ if (is_touchpad_block(block_offset, body_size))
+ return UPDATE_SUCCESS;
+#endif
+
CPRINTF("%s:%d %x, %d section base %x top %x\n",
__func__, __LINE__,
block_offset, body_size,
@@ -90,6 +110,22 @@ static void new_chunk_written(uint32_t block_offset)
static int contents_allowed(uint32_t block_offset,
size_t body_size, void *update_data)
{
+#ifdef CONFIG_TOUCHPAD_VIRTUAL_OFF
+ if (is_touchpad_block(block_offset, body_size)) {
+ struct sha256_ctx ctx;
+ uint8_t *tmp;
+
+ SHA256_init(&ctx);
+ SHA256_update(&ctx, update_data, body_size);
+ tmp = SHA256_final(&ctx);
+ /* TODO(b:63993173): Actually validate the SHA. */
+ CPRINTF("%s: SHA %08x %02x..%02x\n", __func__,
+ block_offset - CONFIG_TOUCHPAD_VIRTUAL_OFF,
+ tmp[0], tmp[31]);
+
+ return 1;
+ }
+#endif
return 1;
}
@@ -226,6 +262,24 @@ void fw_update_command_handler(void *body,
* here, which should probably be merged into contents_allowed...
*/
+#ifdef CONFIG_TOUCHPAD_VIRTUAL_OFF
+ if (is_touchpad_block(block_offset, body_size)) {
+ if (touchpad_update_write(
+ block_offset - CONFIG_TOUCHPAD_VIRTUAL_OFF,
+ body_size, update_data) != EC_SUCCESS) {
+ *error_code = UPDATE_WRITE_FAILURE;
+ CPRINTF("%s:%d update write error\n",
+ __func__, __LINE__);
+ return;
+ }
+
+ new_chunk_written(block_offset);
+
+ *error_code = UPDATE_SUCCESS;
+ return;
+ }
+#endif
+
CPRINTF("update: 0x%x\n", block_offset + CONFIG_PROGRAM_MEMORY_BASE);
if (flash_physical_write(block_offset, body_size, update_data)
!= EC_SUCCESS) {
diff --git a/common/usb_update.c b/common/usb_update.c
index 235c94640a..cfbcca9246 100644
--- a/common/usb_update.c
+++ b/common/usb_update.c
@@ -313,6 +313,11 @@ static int try_vendor_command(struct consumer const *consumer, size_t count)
break;
}
+#ifdef CONFIG_TOUCHPAD_VIRTUAL_OFF
+ tp.fw_address = CONFIG_TOUCHPAD_VIRTUAL_OFF;
+ tp.fw_size = CONFIG_TOUCHPAD_VIRTUAL_SIZE;
+#endif
+
QUEUE_ADD_UNITS(&update_to_usb,
&tp, response_size);
return 1;
diff --git a/include/config.h b/include/config.h
index ee4ebf0967..57a1b3312a 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2289,6 +2289,13 @@
#undef CONFIG_TOUCHPAD_I2C_PORT
#undef CONFIG_TOUCHPAD_I2C_ADDR
+/*
+ * Enable touchpad FW update over USB update protocol, and define touchpad
+ * virtual address and size.
+ */
+#undef CONFIG_TOUCHPAD_VIRTUAL_OFF
+#undef CONFIG_TOUCHPAD_VIRTUAL_SIZE
+
/*****************************************************************************/
/* TPM-like configuration */
diff --git a/include/update_fw.h b/include/update_fw.h
index 44c64468f6..58ef453931 100644
--- a/include/update_fw.h
+++ b/include/update_fw.h
@@ -194,6 +194,13 @@ struct touchpad_info {
uint8_t reserved; /* padding */
uint16_t vendor; /* Vendor USB id */
+ /*
+ * Virtual address to write to to update TP FW over USB update protocol,
+ * and FW size. Both are 0 if unsupported.
+ */
+ uint32_t fw_address;
+ uint32_t fw_size;
+
/* Vendor specific data. */
struct {
uint16_t id;
@@ -230,4 +237,7 @@ enum {
/* Obtain touchpad information */
int touchpad_get_info(struct touchpad_info *tp);
+/* Touchpad FW update: Write a FW block. */
+int touchpad_update_write(int offset, int size, const uint8_t *data);
+
#endif /* ! __CROS_EC_UPDATE_FW_H */