summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@google.com>2020-03-13 10:58:16 -0700
committerCommit Bot <commit-bot@chromium.org>2020-03-13 22:50:11 +0000
commita89c0928fd0339d12645d6c15f2b3010b1429977 (patch)
treebc307ccba8ee1d56057792be42905dbeb073e0b0
parent708277bd1ebb5d9a4dccc875708c3d5018eebd8f (diff)
downloadchrome-ec-a89c0928fd0339d12645d6c15f2b3010b1429977.tar.gz
remove CONFIG_USB_HID_KEYBOARD and CONFIG_USB_UPDATE
This path removes CONFIG_USB_HID_KEYBOARD support and CONFIG_USB_UPDATE support because they are not used in any cr5X board configuration. Ths patch also removes some subsidiary configs as upload hook script guides. > CONFIG_USB_PAIRING > CONFIG_TOUCHPAD_VIRTUAL_OFF > CONFIG_USB_CONSOLE_READ BUG=none BRANCH=cr50 TEST=make buildall Signed-off-by: Namyoon Woo <namyoon@google.com> Change-Id: Iafa553fdf58772744b1d9a5c7f5460f42264f468 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2103045 Tested-by: Namyoon Woo <namyoon@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org> Commit-Queue: Namyoon Woo <namyoon@chromium.org>
-rw-r--r--chip/g/build.mk1
-rw-r--r--chip/g/usb_hid_keyboard.c159
-rw-r--r--common/build.mk4
-rw-r--r--common/update_fw.c334
-rw-r--r--common/usb_update.c594
-rw-r--r--include/config.h15
6 files changed, 0 insertions, 1107 deletions
diff --git a/chip/g/build.mk b/chip/g/build.mk
index a46a6e8c55..bb28bee410 100644
--- a/chip/g/build.mk
+++ b/chip/g/build.mk
@@ -76,7 +76,6 @@ chip-$(CONFIG_WATCHDOG)+=watchdog.o
chip-$(CONFIG_USB)+=usb.o usb_endpoints.o
chip-$(CONFIG_USB_CONSOLE)+=usb_console.o
-chip-$(CONFIG_USB_HID_KEYBOARD)+=usb_hid_keyboard.o
chip-$(CONFIG_USB_BLOB)+=blob.o
chip-$(CONFIG_USB_SPI)+=usb_spi.o
chip-$(CONFIG_RDD)+=rdd.o
diff --git a/chip/g/usb_hid_keyboard.c b/chip/g/usb_hid_keyboard.c
deleted file mode 100644
index d6b529839f..0000000000
--- a/chip/g/usb_hid_keyboard.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "clock.h"
-#include "common.h"
-#include "config.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "link_defs.h"
-#include "registers.h"
-#include "task.h"
-#include "timer.h"
-#include "util.h"
-#include "usb_descriptor.h"
-#include "usb_hid.h"
-
-/* Console output macro */
-#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
-
-#define HID_REPORT_SIZE 8
-
-/* HID descriptors */
-const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_HID) = {
- .bLength = USB_DT_INTERFACE_SIZE,
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = USB_IFACE_HID_KEYBOARD,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = USB_CLASS_HID,
- .bInterfaceSubClass = USB_HID_SUBCLASS_BOOT,
- .bInterfaceProtocol = USB_HID_PROTOCOL_KEYBOARD,
- .iInterface = USB_STR_HID_KEYBOARD_NAME,
-};
-const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID, 81) = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0x80 | USB_EP_HID_KEYBOARD,
- .bmAttributes = 0x03 /* Interrupt endpoint */,
- .wMaxPacketSize = HID_REPORT_SIZE,
- .bInterval = 32 /* ms polling interval */
-};
-const struct usb_hid_descriptor USB_CUSTOM_DESC(USB_IFACE_HID, hid) = {
- .bLength = 9,
- .bDescriptorType = USB_HID_DT_HID,
- .bcdHID = 0x0100,
- .bCountryCode = 0x00, /* Hardware target country */
- .bNumDescriptors = 1,
- .desc = {
- {.bDescriptorType = USB_HID_DT_REPORT,
- .wDescriptorLength = 45}
- }
-};
-
-/* HID : Report Descriptor */
-static const uint8_t report_desc[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x06, /* Usage (Keyboard) */
- 0xA1, 0x01, /* Collection (Application) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0xE0, /* Usage Minimum (224) */
- 0x29, 0xE7, /* Usage Maximum (231) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x75, 0x01, /* Report Size (1) */
- 0x95, 0x08, /* Report Count (8) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */
-
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x08, /* Report Size (8) */
- 0x81, 0x01, /* Input (Constant), ;Reserved byte */
-
- 0x95, 0x06, /* Report Count (6) */
- 0x75, 0x08, /* Report Size (8) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x65, /* Logical Maximum(101) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0x00, /* Usage Minimum (0) */
- 0x29, 0x65, /* Usage Maximum (101) */
- 0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */
- 0xC0, /* End Collection */
- 0x00 /* Padding */
-};
-
-static uint8_t hid_ep_buf[HID_REPORT_SIZE];
-static struct g_usb_desc hid_ep_desc;
-
-void set_keyboard_report(uint64_t rpt)
-{
- memcpy(hid_ep_buf, &rpt, sizeof(rpt));
- hid_ep_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC |
- DIEPDMA_TXBYTES(HID_REPORT_SIZE);
- /* enable TX */
- GR_USB_DIEPCTL(USB_EP_HID_KEYBOARD) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
-}
-
-static void hid_tx(void)
-{
- /* clear IT */
- GR_USB_DIEPINT(USB_EP_HID_KEYBOARD) = 0xffffffff;
- return;
-}
-
-static void hid_reset(void)
-{
- hid_ep_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_BSY | DIEPDMA_IOC;
- hid_ep_desc.addr = hid_ep_buf;
- GR_USB_DIEPDMA(USB_EP_HID_KEYBOARD) = (uint32_t)&hid_ep_desc;
- GR_USB_DIEPCTL(USB_EP_HID_KEYBOARD) = DXEPCTL_MPS(HID_REPORT_SIZE) |
- DXEPCTL_USBACTEP | DXEPCTL_EPTYPE_INT |
- DXEPCTL_TXFNUM(USB_EP_HID_KEYBOARD);
- GR_USB_DAINTMSK |= DAINT_INEP(USB_EP_HID_KEYBOARD);
-}
-
-USB_DECLARE_EP(USB_EP_HID_KEYBOARD, hid_tx, hid_tx, hid_reset);
-
-static int hid_iface_request(struct usb_setup_packet *req)
-{
- if ((req->bmRequestType & USB_DIR_IN) &&
- req->bRequest == USB_REQ_GET_DESCRIPTOR &&
- req->wValue == (USB_HID_DT_REPORT << 8)) {
- /* Setup : HID specific : Get Report descriptor */
- return load_in_fifo(report_desc,
- MIN(req->wLength,
- sizeof(report_desc)));
- }
-
- /* Anything else we'll stall */
- return -1;
-}
-USB_DECLARE_IFACE(USB_IFACE_HID_KEYBOARD, hid_iface_request);
-
-#ifdef CR50_DEV
-/* Just for debugging */
-static int command_hid(int argc, char **argv)
-{
- uint8_t keycode = 0x0a; /* 'G' key */
-
- if (argc >= 2) {
- char *e;
-
- keycode = strtoi(argv[1], &e, 16);
- if (*e)
- return EC_ERROR_PARAM1;
- }
-
- /* press then release the key */
- set_keyboard_report((uint32_t)keycode << 16);
- udelay(50 * MSEC);
- set_keyboard_report(0x000000);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(hid, command_hid,
- "[<HID keycode>]",
- "test USB HID driver");
-#endif
diff --git a/common/build.mk b/common/build.mk
index 5e803b970b..0032ea069c 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -147,7 +147,6 @@ common-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_protocol.o usb_pd_policy.o
endif
common-$(CONFIG_USB_PD_LOGGING)+=event_log.o pd_log.o
common-$(CONFIG_USB_PD_TCPC)+=usb_pd_tcpc.o
-common-$(CONFIG_USB_UPDATE)+=usb_update.o update_fw.o
common-$(CONFIG_USBC_PPC)+=usbc_ppc.o
common-$(CONFIG_VBOOT_EFS)+=vboot/vboot.o
common-$(CONFIG_VBOOT_HASH)+=sha256.o vboot_hash.o
@@ -215,9 +214,6 @@ endif
endif # CONFIG_BOOTBLOCK
ifneq ($(CONFIG_TOUCHPAD_HASH_FW),)
-$(out)/RO/common/update_fw.o: $(out)/touchpad_fw_hash.h
-$(out)/RW/common/update_fw.o: $(out)/touchpad_fw_hash.h
-
$(out)/touchpad_fw_hash.h: $(out)/util/gen_touchpad_hash $(out)/.touchpad_fw
$(call quiet,tp_hash,TPHASH )
diff --git a/common/update_fw.c b/common/update_fw.c
deleted file mode 100644
index 2501f29934..0000000000
--- a/common/update_fw.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/* Copyright 2016 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "byteorder.h"
-#include "console.h"
-#include "extension.h"
-#include "flash.h"
-#include "hooks.h"
-#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"
-#include "util.h"
-#include "vb21_struct.h"
-
-#if defined(CONFIG_TOUCHPAD_VIRTUAL_OFF) && defined(CONFIG_TOUCHPAD_HASH_FW)
-#define CONFIG_TOUCHPAD_FW_CHUNKS \
- (CONFIG_TOUCHPAD_VIRTUAL_SIZE / CONFIG_UPDATE_PDU_SIZE)
-
-#include "touchpad_fw_hash.h"
-
-BUILD_ASSERT(sizeof(touchpad_fw_hashes) ==
- (CONFIG_TOUCHPAD_FW_CHUNKS * SHA256_DIGEST_SIZE));
-BUILD_ASSERT(sizeof(touchpad_fw_hashes[0]) == SHA256_DIGEST_SIZE);
-
-BUILD_ASSERT(sizeof(touchpad_fw_full_hash) == SHA256_DIGEST_SIZE);
-#endif
-
-#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
-
-/* Section to be updated (i.e. not the current section). */
-struct {
- uint32_t base_offset;
- 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.
- *
- * Return success, or indication of an erase failure or chunk not fitting into
- * valid area.
- *
- * TODO(b/36375666): Each board/chip should be able to re-define this.
- */
-static uint8_t check_update_chunk(uint32_t block_offset, size_t body_size)
-{
- uint32_t base;
- uint32_t size;
-
- /* Is this an RW chunk? */
- if (update_section.base_offset != update_section.top_offset &&
- (block_offset >= update_section.base_offset) &&
- ((block_offset + body_size) <= update_section.top_offset)) {
-
- base = update_section.base_offset;
- size = update_section.top_offset -
- update_section.base_offset;
- /*
- * If this is the first chunk for this section, it needs to
- * be erased.
- */
- if (block_offset == base) {
- if (flash_physical_erase(base, size) != EC_SUCCESS) {
- CPRINTF("%s:%d erase failure of 0x%x..+0x%x\n",
- __func__, __LINE__, base, size);
- return UPDATE_ERASE_FAILURE;
- }
- }
-
- 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,
- update_section.base_offset,
- update_section.top_offset);
-
- return UPDATE_BAD_ADDR;
-
-}
-
-/* TODO(b/36375666): These need to be overridden for chip/g. */
-int update_pdu_valid(struct update_command *cmd_body, size_t cmd_size)
-{
- return 1;
-}
-
-static int chunk_came_too_soon(uint32_t block_offset)
-{
- return 0;
-}
-
-static void new_chunk_written(uint32_t block_offset)
-{
-}
-
-static int contents_allowed(uint32_t block_offset,
- size_t body_size, void *update_data)
-{
-#if defined(CONFIG_TOUCHPAD_VIRTUAL_OFF) && defined(CONFIG_TOUCHPAD_HASH_FW)
- if (is_touchpad_block(block_offset, body_size)) {
- struct sha256_ctx ctx;
- uint8_t *tmp;
- uint32_t fw_offset = block_offset - CONFIG_TOUCHPAD_VIRTUAL_OFF;
- unsigned int chunk = fw_offset / CONFIG_UPDATE_PDU_SIZE;
- int good = 0;
-
- if (chunk >= CONFIG_TOUCHPAD_FW_CHUNKS ||
- (fw_offset % CONFIG_UPDATE_PDU_SIZE) != 0) {
- CPRINTF("%s: TP invalid offset %08x\n",
- __func__, fw_offset);
- return 0;
- }
-
- SHA256_init(&ctx);
- SHA256_update(&ctx, update_data, body_size);
- tmp = SHA256_final(&ctx);
-
- good = !memcmp(tmp, touchpad_fw_hashes[chunk],
- SHA256_DIGEST_SIZE);
-
- CPRINTF("%s: TP %08x %02x..%02x (%s)\n", __func__,
- fw_offset, tmp[0], tmp[31], good ? "GOOD" : "BAD");
-
- return good;
- }
-#endif
- return 1;
-}
-
-/*
- * Setup internal state (e.g. valid sections, and fill first response).
- *
- * Assumes rpdu is already prefilled with 0, and that version has already
- * been set. May set a return_value != 0 on error.
- */
-void fw_update_start(struct first_response_pdu *rpdu)
-{
- const char *version;
-#ifdef CONFIG_RWSIG_TYPE_RWSIG
- const struct vb21_packed_key *vb21_key;
-#endif
-
- rpdu->header_type = htobe16(UPDATE_HEADER_TYPE_COMMON);
-
- /* Determine the valid update section. */
- switch (system_get_image_copy()) {
- case SYSTEM_IMAGE_RO:
- /* RO running, so update RW */
- update_section.base_offset = CONFIG_RW_MEM_OFF;
- update_section.top_offset = CONFIG_RW_MEM_OFF + CONFIG_RW_SIZE;
- version = system_get_version(SYSTEM_IMAGE_RW);
- break;
- case SYSTEM_IMAGE_RW:
- /* RW running, so update RO */
- update_section.base_offset = CONFIG_RO_MEM_OFF;
- update_section.top_offset = CONFIG_RO_MEM_OFF + CONFIG_RO_SIZE;
- version = system_get_version(SYSTEM_IMAGE_RO);
- break;
- default:
- CPRINTF("%s:%d\n", __func__, __LINE__);
- rpdu->return_value = htobe32(UPDATE_GEN_ERROR);
- return;
- }
-
- rpdu->common.maximum_pdu_size = htobe32(CONFIG_UPDATE_PDU_SIZE);
- rpdu->common.flash_protection = htobe32(flash_get_protect());
- rpdu->common.offset = htobe32(update_section.base_offset);
- if (version)
- memcpy(rpdu->common.version, version,
- sizeof(rpdu->common.version));
-
-#ifdef CONFIG_ROLLBACK
- rpdu->common.min_rollback = htobe32(rollback_get_minimum_version());
-#else
- rpdu->common.min_rollback = htobe32(-1);
-#endif
-
-#ifdef CONFIG_RWSIG_TYPE_RWSIG
- vb21_key = (const struct vb21_packed_key *)CONFIG_RO_PUBKEY_ADDR;
- rpdu->common.key_version = htobe32(vb21_key->key_version);
-#endif
-
-#ifdef HAS_TASK_RWSIG
- /* Do not allow the update to start if RWSIG is still running. */
- if (rwsig_get_status() == RWSIG_IN_PROGRESS) {
- CPRINTF("RWSIG in progress\n");
- rpdu->return_value = htobe32(UPDATE_RWSIG_BUSY);
- }
-#endif
-}
-
-void fw_update_command_handler(void *body,
- size_t cmd_size,
- size_t *response_size)
-{
- struct update_command *cmd_body = body;
- void *update_data;
- uint8_t *error_code = body; /* Cache the address for code clarity. */
- size_t body_size;
- uint32_t block_offset;
-
- *response_size = 1; /* One byte response unless this is a start PDU. */
-
- if (cmd_size < sizeof(struct update_command)) {
- CPRINTF("%s:%d\n", __func__, __LINE__);
- *error_code = UPDATE_GEN_ERROR;
- return;
- }
- body_size = cmd_size - sizeof(struct update_command);
-
- if (!cmd_body->block_base && !body_size) {
- struct first_response_pdu *rpdu = body;
-
- /*
- * This is the connection establishment request, the response
- * allows the server to decide what sections of the image to
- * send to program into the flash.
- */
-
- /* First, prepare the response structure. */
- memset(rpdu, 0, sizeof(*rpdu));
- /*
- * TODO(b/36375666): The response size can be shorter depending
- * on which board-specific type of response we provide. This
- * may send trailing 0 bytes, which should be harmless.
- */
- *response_size = sizeof(*rpdu);
- rpdu->protocol_version = htobe16(UPDATE_PROTOCOL_VERSION);
-
- /* Setup internal state (e.g. valid sections, and fill rpdu) */
- fw_update_start(rpdu);
- return;
- }
-
- block_offset = be32toh(cmd_body->block_base);
-
- if (!update_pdu_valid(cmd_body, cmd_size)) {
- *error_code = UPDATE_DATA_ERROR;
- return;
- }
-
- update_data = cmd_body + 1;
- if (!contents_allowed(block_offset, body_size, update_data)) {
- *error_code = UPDATE_ROLLBACK_ERROR;
- return;
- }
-
- /* Check if the block will fit into the valid area. */
- *error_code = check_update_chunk(block_offset, body_size);
- if (*error_code)
- return;
-
- if (chunk_came_too_soon(block_offset)) {
- *error_code = UPDATE_RATE_LIMIT_ERROR;
- return;
- }
-
- /*
- * TODO(b/36375666): chip/g code has some cr50-specific stuff right
- * 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) {
- *error_code = UPDATE_WRITE_FAILURE;
- CPRINTF("%s:%d update write error\n", __func__, __LINE__);
- return;
- }
-
- new_chunk_written(block_offset);
-
- /* Verify that data was written properly. */
- if (memcmp(update_data, (void *)
- (block_offset + CONFIG_PROGRAM_MEMORY_BASE),
- body_size)) {
- *error_code = UPDATE_VERIFY_ERROR;
- CPRINTF("%s:%d update verification error\n",
- __func__, __LINE__);
- return;
- }
-
- *error_code = UPDATE_SUCCESS;
-}
-
-/* TODO(b/36375666): This need to be overridden for chip/g. */
-void fw_update_complete(void)
-{
-}
diff --git a/common/usb_update.c b/common/usb_update.c
deleted file mode 100644
index 64875fd798..0000000000
--- a/common/usb_update.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/* Copyright 2016 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "byteorder.h"
-#include "common.h"
-#include "console.h"
-#include "consumer.h"
-#include "curve25519.h"
-#include "extension.h"
-#include "flash.h"
-#include "queue_policies.h"
-#include "host_command.h"
-#include "rollback.h"
-#include "rwsig.h"
-#include "sha256.h"
-#include "system.h"
-#include "uart.h"
-#include "update_fw.h"
-#include "usb-stream.h"
-#include "util.h"
-
-#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
-
-/*
- * This file is an adaptation layer between the USB interface and the firmware
- * update engine. The engine expects to receive long blocks of data, 1K or so
- * in size, prepended by the offset where the data needs to be programmed into
- * the flash and a 4 byte integrity check value.
- *
- * The USB transfer, on the other hand, operates on much shorter chunks of
- * data, typically 64 bytes in this case. This module reassembles firmware
- * programming blocks from the USB chunks, and invokes the programmer passing
- * it the full block.
- *
- * The programmer reports results by putting the return value into the same
- * buffer where the block was passed in. This wrapper retrieves the
- * programmer's return value, and sends it back to the host. The return value
- * is usually one byte in size, the only exception is the connection
- * establishment phase where the return value is 16 bytes in size.
- *
- * In the end of the successful image transfer and programming, the host sends
- * the reset command, and the device reboots itself.
- */
-
-struct consumer const update_consumer;
-struct usb_stream_config const usb_update;
-
-static struct queue const update_to_usb = QUEUE_DIRECT(64, uint8_t,
- null_producer,
- usb_update.consumer);
-static struct queue const usb_to_update = QUEUE_DIRECT(64, uint8_t,
- usb_update.producer,
- update_consumer);
-
-USB_STREAM_CONFIG_FULL(usb_update,
- USB_IFACE_UPDATE,
- USB_CLASS_VENDOR_SPEC,
- USB_SUBCLASS_GOOGLE_UPDATE,
- USB_PROTOCOL_GOOGLE_UPDATE,
- USB_STR_UPDATE_NAME,
- USB_EP_UPDATE,
- USB_MAX_PACKET_SIZE,
- USB_MAX_PACKET_SIZE,
- usb_to_update,
- update_to_usb)
-
-
-/* The receiver can be in one of the states below. */
-enum rx_state {
- rx_idle, /* Nothing happened yet. */
- rx_inside_block, /* Assembling a block to pass to the programmer. */
- rx_outside_block, /* Waiting for the next block to start or for the
- reset command. */
-};
-
-enum rx_state rx_state_ = rx_idle;
-static uint8_t block_buffer[sizeof(struct update_command) +
- CONFIG_UPDATE_PDU_SIZE];
-static uint32_t block_size;
-static uint32_t block_index;
-
-#ifdef CONFIG_USB_PAIRING
-#define KEY_CONTEXT "device-identity"
-
-static int pair_challenge(struct pair_challenge *challenge)
-{
- uint8_t response;
-
- /* Scratchpad for device secret and x25519 public/shared key. */
- uint8_t tmp[32];
- BUILD_ASSERT(sizeof(tmp) >= X25519_PUBLIC_VALUE_LEN);
- BUILD_ASSERT(sizeof(tmp) >= X25519_PRIVATE_KEY_LEN);
- BUILD_ASSERT(sizeof(tmp) >= CONFIG_ROLLBACK_SECRET_SIZE);
-
- /* Scratchpad for device_private and authenticator. */
- uint8_t tmp2[32];
- BUILD_ASSERT(sizeof(tmp2) >= X25519_PRIVATE_KEY_LEN);
- BUILD_ASSERT(sizeof(tmp2) >= SHA256_DIGEST_SIZE);
-
- /* tmp = device_secret */
- if (rollback_get_secret(tmp) != EC_SUCCESS) {
- response = EC_RES_UNAVAILABLE;
- QUEUE_ADD_UNITS(&update_to_usb, &response, sizeof(response));
- return 1;
- }
-
- /*
- * Nothing can fail from now on, let's push data to the queue as soon as
- * possible to save some temporary variables.
- */
- response = EC_RES_SUCCESS;
- QUEUE_ADD_UNITS(&update_to_usb, &response, sizeof(response));
-
- /*
- * tmp2 = device_private
- * = HMAC_SHA256(device_secret, "device-identity")
- */
- hmac_SHA256(tmp2, tmp, CONFIG_ROLLBACK_SECRET_SIZE,
- KEY_CONTEXT, sizeof(KEY_CONTEXT) - 1);
-
- /* tmp = device_public = x25519(device_private, x25519_base_point) */
- X25519_public_from_private(tmp, tmp2);
- QUEUE_ADD_UNITS(&update_to_usb, tmp, sizeof(tmp));
-
- /* tmp = shared_secret = x25519(device_private, host_public) */
- X25519(tmp, tmp2, challenge->host_public);
-
- /* tmp2 = authenticator = HMAC_SHA256(shared_secret, nonce) */
- hmac_SHA256(tmp2, tmp, sizeof(tmp),
- challenge->nonce, sizeof(challenge->nonce));
- QUEUE_ADD_UNITS(&update_to_usb, tmp2,
- member_size(struct pair_challenge_response, authenticator));
- return 1;
-}
-#endif
-
-/*
- * Fetches a transfer start frame from the queue. This can be either an update
- * start frame (block_size = 0, all of cmd = 0), or the beginning of a frame
- * (block_size > 0, valid block_base in cmd).
- */
-static int fetch_transfer_start(struct consumer const *consumer, size_t count,
- struct update_frame_header *pupfr)
-{
- int i;
-
- /*
- * Let's just make sure we drain the queue no matter what the contents
- * are. This way they won't be in the way during next callback, even
- * if these contents are not what's expected.
- *
- * Note: If count > sizeof(*pupfr), pupfr will be corrupted. This is
- * ok as we will immediately fail after this.
- */
- i = count;
- while (i > 0) {
- QUEUE_REMOVE_UNITS(consumer->queue, pupfr,
- MIN(i, sizeof(*pupfr)));
- i -= sizeof(*pupfr);
- }
-
- if (count != sizeof(struct update_frame_header)) {
- CPRINTS("FW update: wrong first block, size %d", count);
- return 0;
- }
-
- return 1;
-}
-
-static int try_vendor_command(struct consumer const *consumer, size_t count)
-{
- char buffer[USB_MAX_PACKET_SIZE];
- struct update_frame_header *cmd_buffer = (void *)buffer;
- int rv = 0;
-
- /* Validate count (too short, or too long). */
- if (count < sizeof(*cmd_buffer) || count > sizeof(buffer))
- return 0;
-
- /*
- * Let's copy off the queue the update frame header, to see if this
- * is a channeled vendor command.
- */
- queue_peek_units(consumer->queue, cmd_buffer, 0, sizeof(*cmd_buffer));
- if (be32toh(cmd_buffer->cmd.block_base) != UPDATE_EXTRA_CMD)
- return 0;
-
- if (be32toh(cmd_buffer->block_size) != count) {
- CPRINTS("%s: problem: block size and count mismatch (%d != %d)",
- __func__, be32toh(cmd_buffer->block_size), count);
- return 0;
- }
-
- /* Get the entire command, don't remove it from the queue just yet. */
- queue_peek_units(consumer->queue, cmd_buffer, 0, count);
-
- /* Looks like this is a vendor command, let's verify it. */
- if (update_pdu_valid(&cmd_buffer->cmd,
- count - offsetof(struct update_frame_header, cmd))) {
- enum update_extra_command subcommand;
- uint8_t response;
- size_t response_size = sizeof(response);
- int __attribute__((unused)) header_size;
- int __attribute__((unused)) data_count;
-
- /* looks good, let's process it. */
- rv = 1;
-
- /* Now remove it from the queue. */
- queue_advance_head(consumer->queue, count);
-
- subcommand = be16toh(*((uint16_t *)(cmd_buffer + 1)));
-
- /*
- * header size: update frame header + 2 bytes for subcommand
- * data_count: Some commands take in extra data as parameter
- */
- header_size = sizeof(*cmd_buffer) + sizeof(uint16_t);
- data_count = count - header_size;
-
- switch (subcommand) {
- case UPDATE_EXTRA_CMD_IMMEDIATE_RESET:
- CPRINTS("Rebooting!");
- CPRINTF("\n\n");
- cflush();
- system_reset(SYSTEM_RESET_MANUALLY_TRIGGERED);
- /* Unreachable, unless something bad happens. */
- response = EC_RES_ERROR;
- break;
- case UPDATE_EXTRA_CMD_JUMP_TO_RW:
-#ifdef CONFIG_RWSIG
- /*
- * Tell rwsig task to jump to RW. This does nothing if
- * verification failed, and will only jump later on if
- * verification is still in progress.
- */
- rwsig_continue();
-
- switch (rwsig_get_status()) {
- case RWSIG_VALID:
- response = EC_RES_SUCCESS;
- break;
- case RWSIG_INVALID:
- response = EC_RES_INVALID_CHECKSUM;
- break;
- case RWSIG_IN_PROGRESS:
- response = EC_RES_IN_PROGRESS;
- break;
- default:
- response = EC_RES_ERROR;
- }
-#else
- system_run_image_copy(SYSTEM_IMAGE_RW);
-#endif
- break;
-#ifdef CONFIG_RWSIG
- case UPDATE_EXTRA_CMD_STAY_IN_RO:
- rwsig_abort();
- response = EC_RES_SUCCESS;
- break;
-#endif
- case UPDATE_EXTRA_CMD_UNLOCK_RW:
- flash_set_protect(EC_FLASH_PROTECT_RW_AT_BOOT, 0);
- response = EC_RES_SUCCESS;
- break;
-#ifdef CONFIG_ROLLBACK
- case UPDATE_EXTRA_CMD_UNLOCK_ROLLBACK:
- flash_set_protect(EC_FLASH_PROTECT_ROLLBACK_AT_BOOT, 0);
- response = EC_RES_SUCCESS;
- break;
-#ifdef CONFIG_ROLLBACK_SECRET_SIZE
-#ifdef CONFIG_ROLLBACK_UPDATE
- case UPDATE_EXTRA_CMD_INJECT_ENTROPY: {
- if (data_count < CONFIG_ROLLBACK_SECRET_SIZE) {
- CPRINTS("Entropy too short");
- response = EC_RES_INVALID_PARAM;
- break;
- }
-
- CPRINTS("Adding %db of entropy", data_count);
- /* Add the entropy to secret. */
- rollback_add_entropy(buffer + header_size, data_count);
- break;
- }
-#endif /* CONFIG_ROLLBACK_UPDATE */
-#ifdef CONFIG_USB_PAIRING
- case UPDATE_EXTRA_CMD_PAIR_CHALLENGE: {
- if (data_count < sizeof(struct pair_challenge)) {
- CPRINTS("Challenge data too short");
- response = EC_RES_INVALID_PARAM;
- break;
- }
-
- /* pair_challenge takes care of answering */
- return pair_challenge((struct pair_challenge *)
- (buffer + header_size));
- }
-#endif
-#endif /* CONFIG_ROLLBACK_SECRET_SIZE */
-#endif /* CONFIG_ROLLBACK */
-#ifdef CONFIG_TOUCHPAD
- case UPDATE_EXTRA_CMD_TOUCHPAD_INFO: {
- struct touchpad_info tp = { 0 };
-
- if (data_count != 0) {
- response = EC_RES_INVALID_PARAM;
- break;
- }
-
- response_size = touchpad_get_info(&tp);
- if (response_size < 1) {
- response = EC_RES_ERROR;
- break;
- }
-
-#ifdef CONFIG_TOUCHPAD_VIRTUAL_OFF
- tp.fw_address = CONFIG_TOUCHPAD_VIRTUAL_OFF;
- tp.fw_size = CONFIG_TOUCHPAD_VIRTUAL_SIZE;
-
-#ifdef CONFIG_TOUCHPAD_HASH_FW
- memcpy(tp.allowed_fw_hash, touchpad_fw_full_hash,
- sizeof(tp.allowed_fw_hash));
-#endif
-#endif /* CONFIG_TOUCHPAD_VIRTUAL_OFF */
- QUEUE_ADD_UNITS(&update_to_usb,
- &tp, response_size);
- return 1;
- }
- case UPDATE_EXTRA_CMD_TOUCHPAD_DEBUG: {
- uint8_t *data = NULL;
- unsigned int write_count = 0;
-
- /*
- * Let the touchpad driver decide what it wants to do
- * with the payload data, and put the response in data.
- */
- response = touchpad_debug(buffer + header_size,
- data_count, &data, &write_count);
-
- /*
- * On error, or if there is no data to write back, just
- * write back response.
- */
- if (response != EC_RES_SUCCESS || write_count == 0)
- break;
-
- /* Check that we can write all the data to the queue. */
- if (write_count > queue_space(&update_to_usb))
- return EC_RES_BUSY;
-
- QUEUE_ADD_UNITS(&update_to_usb, data, write_count);
- return 1;
- }
-#endif
-#ifdef CONFIG_USB_CONSOLE_READ
- /*
- * TODO(b/112877237): move this to a new interface, so we can
- * support reading log and other commands at the same time?
- */
- case UPDATE_EXTRA_CMD_CONSOLE_READ_INIT:
- response = uart_console_read_buffer_init();
- break;
- case UPDATE_EXTRA_CMD_CONSOLE_READ_NEXT: {
- uint8_t *data = buffer + header_size;
- uint8_t output[64];
- uint16_t write_count = 0;
-
- if (data_count != 1) {
- response = EC_RES_INVALID_PARAM;
- break;
- }
-
- response = uart_console_read_buffer(
- data[0],
- (char *)output,
- MIN(sizeof(output),
- queue_space(&update_to_usb)),
- &write_count);
- if (response != EC_RES_SUCCESS || write_count == 0)
- break;
-
- QUEUE_ADD_UNITS(&update_to_usb, output, write_count);
- return 1;
- }
-#endif
- default:
- response = EC_RES_INVALID_COMMAND;
- }
-
- QUEUE_ADD_UNITS(&update_to_usb, &response, response_size);
- }
-
- return rv;
-}
-
-/*
- * When was last time a USB callback was called, in microseconds, free running
- * timer.
- */
-static uint64_t prev_activity_timestamp;
-
-/*
- * A flag indicating that at least one valid PDU containing flash update block
- * has been received in the current transfer session.
- */
-static uint8_t data_was_transferred;
-
-/* Reply with an error to remote side, reset state. */
-static void send_error_reset(uint8_t resp_value)
-{
- QUEUE_ADD_UNITS(&update_to_usb, &resp_value, 1);
- rx_state_ = rx_idle;
- data_was_transferred = 0;
-}
-
-/* Called to deal with data from the host */
-static void update_out_handler(struct consumer const *consumer, size_t count)
-{
- struct update_frame_header upfr;
- size_t resp_size;
- uint8_t resp_value;
- uint64_t delta_time;
-
- /* How much time since the previous USB callback? */
- delta_time = get_time().val - prev_activity_timestamp;
- prev_activity_timestamp += delta_time;
-
- /* If timeout exceeds 5 seconds - let's start over. */
- if ((delta_time > 5000000) && (rx_state_ != rx_idle)) {
- rx_state_ = rx_idle;
- CPRINTS("FW update: recovering after timeout");
- }
-
- if (rx_state_ == rx_idle) {
- /*
- * The payload must be an update initiating PDU.
- *
- * The size of the response returned in the same buffer will
- * exceed the received frame size; Let's make sure there is
- * enough room for the response in the buffer.
- */
- union {
- struct update_frame_header upfr;
- struct {
- uint32_t unused;
- struct first_response_pdu startup_resp;
- };
- } u;
-
- /* Check is this is a channeled TPM extension command. */
- if (try_vendor_command(consumer, count))
- return;
-
- /*
- * An update start PDU is a command without any payload, with
- * digest = 0, and base = 0.
- */
- if (!fetch_transfer_start(consumer, count, &u.upfr) ||
- be32toh(u.upfr.block_size) !=
- sizeof(struct update_frame_header) ||
- u.upfr.cmd.block_digest != 0 ||
- u.upfr.cmd.block_base != 0) {
- /*
- * Something is wrong, this payload is not a valid
- * update start PDU. Let'w indicate this by returning
- * a single byte error code.
- */
- CPRINTS("FW update: invalid start.");
- send_error_reset(UPDATE_GEN_ERROR);
- return;
- }
-
- CPRINTS("FW update: starting...");
- fw_update_command_handler(&u.upfr.cmd, count -
- offsetof(struct update_frame_header,
- cmd),
- &resp_size);
-
- if (!u.startup_resp.return_value) {
- rx_state_ = rx_outside_block; /* We're in business. */
- data_was_transferred = 0; /* No data received yet. */
- }
-
- /* Let the host know what updater had to say. */
- QUEUE_ADD_UNITS(&update_to_usb, &u.startup_resp, resp_size);
- return;
- }
-
- if (rx_state_ == rx_outside_block) {
- /*
- * Expecting to receive the beginning of the block or the
- * reset command if all data blocks have been processed.
- */
- if (count == 4) {
- uint32_t command;
-
- QUEUE_REMOVE_UNITS(consumer->queue, &command,
- sizeof(command));
- command = be32toh(command);
- if (command == UPDATE_DONE) {
- CPRINTS("FW update: done");
-
- if (data_was_transferred) {
- fw_update_complete();
- data_was_transferred = 0;
- }
-
- resp_value = 0;
- QUEUE_ADD_UNITS(&update_to_usb,
- &resp_value, 1);
- rx_state_ = rx_idle;
- return;
- }
- }
-
- /*
- * At this point we expect a block start message. It is
- * sizeof(upfr) bytes in size.
- */
- if (!fetch_transfer_start(consumer, count, &upfr)) {
- CPRINTS("Invalid block start.");
- send_error_reset(UPDATE_GEN_ERROR);
- return;
- }
-
- /* Let's allocate a large enough buffer. */
- block_size = be32toh(upfr.block_size) -
- offsetof(struct update_frame_header, cmd);
-
- /*
- * Only update start PDU is allowed to have a size 0 payload.
- */
- if (block_size <= sizeof(struct update_command) ||
- block_size > sizeof(block_buffer)) {
- CPRINTS("Invalid block size (%d).", block_size);
- send_error_reset(UPDATE_GEN_ERROR);
- return;
- }
-
- /*
- * Copy the rest of the message into the block buffer to pass
- * to the updater.
- */
- block_index = sizeof(upfr) -
- offsetof(struct update_frame_header, cmd);
- memcpy(block_buffer, &upfr.cmd, block_index);
- block_size -= block_index;
- rx_state_ = rx_inside_block;
- return;
- }
-
- /* Must be inside block. */
- QUEUE_REMOVE_UNITS(consumer->queue, block_buffer + block_index, count);
- block_index += count;
- block_size -= count;
-
- if (block_size) {
- if (count <= sizeof(upfr)) {
- /*
- * A block header size instead of chunk size message
- * has been received, let's abort the transfer.
- */
- CPRINTS("Unexpected header");
- send_error_reset(UPDATE_GEN_ERROR);
- return;
- }
- return; /* More to come. */
- }
-
- /*
- * Ok, the entire block has been received and reassembled, pass it to
- * the updater for verification and programming.
- */
- fw_update_command_handler(block_buffer, block_index, &resp_size);
-
- /*
- * There was at least an attempt to program the flash, set the
- * flag.
- */
- data_was_transferred = 1;
- resp_value = block_buffer[0];
- QUEUE_ADD_UNITS(&update_to_usb, &resp_value, sizeof(resp_value));
- rx_state_ = rx_outside_block;
-}
-
-struct consumer const update_consumer = {
- .queue = &usb_to_update,
- .ops = &((struct consumer_ops const) {
- .written = update_out_handler,
- }),
-};
diff --git a/include/config.h b/include/config.h
index bc51beb4a6..00ea17e4fd 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3566,7 +3566,6 @@
* 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
/*
@@ -4064,12 +4063,6 @@
/* Support USB HID interface. */
#undef CONFIG_USB_HID
-/* Support USB HID keyboard interface. */
-#undef CONFIG_USB_HID_KEYBOARD
-
-/* Support USB HID keyboard backlight. */
-#undef CONFIG_USB_HID_KEYBOARD_BACKLIGHT
-
/* Support USB HID touchpad interface. */
#undef CONFIG_USB_HID_TOUCHPAD
@@ -4332,14 +4325,6 @@
/* Firmware updates using other than HC channel(s). */
#undef CONFIG_NON_HC_FW_UPDATE
#undef CONFIG_USB_FW_UPDATE
-/* A different config for the same update. TODO(vbendeb): dedupe these */
-#undef CONFIG_USB_UPDATE
-
-/* Add support for pairing over the USB update interface. */
-#undef CONFIG_USB_PAIRING
-
-/* Add support for reading UART buffer from USB update interface. */
-#undef CONFIG_USB_CONSOLE_READ
/* PDU size for fw update over USB (or TPM). */
#define CONFIG_UPDATE_PDU_SIZE 1024