diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2017-06-13 16:08:34 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-16 21:10:54 -0700 |
commit | 12fd77967f9239f462bb66087cf4496f36e16302 (patch) | |
tree | e0970da15c8e86c26478b8ff98deb3d48efbf204 /common | |
parent | 3bb2d756e579be92a87ff6a17f26f78af3350e4b (diff) | |
download | chrome-ec-12fd77967f9239f462bb66087cf4496f36e16302.tar.gz |
cr50: handle board ID mismatch gracefully
If Cr50 happens to start on a chip where Board ID programmed in INFO1
does not match the contents of the RW header, it means that for some
reason the other RW is not operational and the current image is the
only viable one.
In this case the Cr50 starts but operates in limited mode (only
commands for updating the image and reporting state are handled). In
this case the reason for recovery could be seen on the Recovery
screen, and the update could be done once Chrome OS boots in recovery
mode.
BRANCH=none
BUG=b:35586335
TEST=verified the following:
- if an image with wrong board ID is started, it tries to fall back
(sets the counter to a value above threshold and reboots)
- if the fallback fails, the image keeps running in the limited
capabilities mode but the update is possible, observed that the
new image took over worked after powercycling the device.
- observed proper error message on the recovery screen showing where
the error comes from
Change-Id: I46ba75392f8e891bb8503fb15aea2c56b5805e83
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/535978
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/extension.c | 16 | ||||
-rw-r--r-- | common/tpm_registers.c | 22 |
2 files changed, 34 insertions, 4 deletions
diff --git a/common/extension.c b/common/extension.c index 0e9ad5bfca..63d20de365 100644 --- a/common/extension.c +++ b/common/extension.c @@ -22,6 +22,22 @@ static uint32_t extension_route_command(uint16_t command_code, cmd_p = (struct extension_command *)&__extension_cmds; end_p = (struct extension_command *)&__extension_cmds_end; +#ifdef CONFIG_BOARD_ID_SUPPORT + if (board_id_is_mismatched()) { + switch (command_code) { + case EXTENSION_FW_UPGRADE: + case VENDOR_CC_REPORT_TPM_STATE: + case VENDOR_CC_TURN_UPDATE_ON: + case EXTENSION_POST_RESET: + break; + default: + CPRINTF("%s: ignoring command 0x%x " + "due to board ID mismatch\n", + __func__, command_code); + return VENDOR_RC_NO_SUCH_COMMAND; + } + } +#endif while (cmd_p != end_p) { if (cmd_p->command_code == command_code) return cmd_p->handler(command_code, buffer, diff --git a/common/tpm_registers.c b/common/tpm_registers.c index c4353dd566..7d4ecccfbf 100644 --- a/common/tpm_registers.c +++ b/common/tpm_registers.c @@ -850,10 +850,24 @@ void tpm_task(void) } else #endif { - ExecuteCommand(tpm_.fifo_write_index, - tpm_.regs.data_fifo, - &response_size, - &response); + if (board_id_is_mismatched()) { + static const char tpm_broken_response[] = { + 0x80, 0x01, /* TPM_ST_NO_SESSIONS */ + 0, 0, 0, 10, /* Response size. */ + 0, 0, 9, 0x21 /* TPM_RC_LOCKOUT */ + }; + CPRINTF("%s: Ignoring TPM commands\n", + __func__); + response = tpm_.regs.data_fifo; + response_size = sizeof(tpm_broken_response); + memcpy(response, tpm_broken_response, + response_size); + } else { + ExecuteCommand(tpm_.fifo_write_index, + tpm_.regs.data_fifo, + &response_size, + &response); + } } CPRINTF("got %d bytes in response\n", response_size); if (response_size && |