From 36b39b5fc92e4857249372cccec099440ba67c66 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Fri, 7 Oct 2016 11:22:16 -0700 Subject: [PATCH] cr50: provide means of posting reboot request Usually CR50 TPM reset happens when the AP reboots, the CR50 RO does not get a chance to run in this case, so the running RW does not change either, Once the idle RW section was updated, the only way to start it is to reboot the CR50 completely, Rebooting CR50 causes the whole system reset, so it should not be happening at random moments in time. This patch introduces a mechanism to delay reboot to the moment when the TPM is reset. The reboot request would be posted in the end of the update, and then the AP would reboot, triggering a TPM reboot, which in turn would trigger the CR50 reset. The USB update handler now posts the reboot request instead of triggering the reboot immediately. BRANCH=none BUG=chrome-os-partner:58226 TEST=with the rest of the patches applied verified that the system gets reset and the new image version kicks in on both gru (over SPI) and reef (over USB). Change-Id: Iff859f2e7a48c5035a27fffd17aefe7e318af569 Signed-off-by: Vadim Bendebury Reviewed-on: https://chromium-review.googlesource.com/395627 Reviewed-by: Bill Richardson --- board/cr50/board.c | 9 +++++++++ board/cr50/board.h | 1 + chip/g/usb_upgrade.c | 10 ++++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/board/cr50/board.c b/board/cr50/board.c index 7a49649ac1..9a1be332b4 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -71,7 +71,13 @@ uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = { /* Board specific configuration settings */ static uint32_t board_properties; +static uint8_t reboot_request_posted; +void post_reboot_request(void) +{ + /* Reboot the device next time TPM reset is requested. */ + reboot_request_posted = 1; +} /* * There's no way to trigger on both rising and falling edges, so force a * compiler error if we try. The workaround is to use the pinmux to connect @@ -378,6 +384,9 @@ void sys_rst_asserted(enum gpio_signal signal) return; } + if (reboot_request_posted) + system_reset(SYSTEM_RESET_HARD); /* This will never return. */ + /* Re-initialize the TPM software state */ tpm_reset(); } diff --git a/board/cr50/board.h b/board/cr50/board.h index 9eb67991a2..fd59137090 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -139,6 +139,7 @@ void board_configure_deep_sleep_wakepins(void); /* Interrupt handler */ void sys_rst_asserted(enum gpio_signal signal); void device_state_on(enum gpio_signal signal); +void post_reboot_request(void); /* Special controls over EC and AP */ void assert_sys_rst(void); diff --git a/chip/g/usb_upgrade.c b/chip/g/usb_upgrade.c index 7f58f57fc8..493cd7cc92 100644 --- a/chip/g/usb_upgrade.c +++ b/chip/g/usb_upgrade.c @@ -182,14 +182,12 @@ static void upgrade_out_handler(struct consumer const *consumer, size_t count) if (rx_state_ == rx_awaiting_reset) { /* - * Any USB data received in this state triggers reset, no + * Any USB data received in this state should cause a post of + * a system reset request on the next TPM reboot, no USB * response required. */ - CPRINTS("reboot hard"); - cflush(); - system_reset(SYSTEM_RESET_HARD); - while (1) - ; + rx_state_ = rx_idle; + post_reboot_request(); } if (rx_state_ == rx_outside_block) {