diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2018-02-14 18:55:52 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2018-02-20 23:54:43 +0000 |
commit | bde5d3c723d86ec886182cb6aa90f07cf910abd2 (patch) | |
tree | 2c8c2725f2eb920fefd5b19e518af1b286febf91 /common | |
parent | 50fb91d83be03def29485eb32babb9cedb93441a (diff) | |
download | chrome-ec-bde5d3c723d86ec886182cb6aa90f07cf910abd2.tar.gz |
tpm: ccd: allow alternative commands when ap is held in reset
A typical CCD use case is when the DUT is not fully functional, or
even completely dead, including corrupted AP/EC firmware.
We still want to be able to enable CCD in this case, but routing CCD
commands through TPM task context (necessary to ensure the large stack
size some CCD commands require) is blocked if TPM was not reset after
startup.
Let's allow both reset requests and alternative commands when AP is
held in reset after reboot. The only situation when the alternative
command arrives would be the CCD use case of the system not generating
TPM reset pulse at startup and the operator is trying to execute a CCD
or RMA reset command.
BRANCH=cr50, cr50-mp
BUG=b:73292631
TEST=on a reef device: destroyed AP firmware and observed that the
'ccd open' command indeed results in the hung Cr50 console after
Cr50 is reset in this state.
Loaded the new Cr50 image, (which caused another Cr50 reset),
successfully took it through the 'ccd open' sequence resulting in
enabling AP flash write access, restored the AP flash and
observed the DUT boot into Chrome OS.
Change-Id: I4413bc200f5b2be563ba666ff80dd2d889ae5790
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/920924
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
(cherry picked from commit f495e27ce67888cd955bffded589f877ae503897)
Reviewed-on: https://chromium-review.googlesource.com/927781
Diffstat (limited to 'common')
-rw-r--r-- | common/tpm_registers.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/common/tpm_registers.c b/common/tpm_registers.c index 06eb7ee638..06405d4b7e 100644 --- a/common/tpm_registers.c +++ b/common/tpm_registers.c @@ -695,7 +695,7 @@ enum alt_process_result { * The mutex ensures that only one alternative TPM command execution is active * at a time. */ -static struct alt_tpm_interface { +static __preserved struct alt_tpm_interface { struct tpm_cmd_header *alt_hdr; size_t alt_buffer_size; uint32_t process_result; @@ -895,7 +895,7 @@ int tpm_sync_reset(int wipe_first) void tpm_task(void) { - uint32_t evt; + uint32_t evt = 0; if (!chip_factory_mode()) { /* @@ -906,19 +906,27 @@ void tpm_task(void) */ while (!ap_is_on()) { /* - * The only event we should expect at this point would - * be the reset request. + * The only events we should expect at this point + * would be the reset request or a command routed + * through TPM task context to make use of the large + * stack. */ evt = task_wait_event(-1); - if (evt & TPM_EVENT_RESET) + if (evt & (TPM_EVENT_RESET | TPM_EVENT_ALT_EXTENSION)) { + /* + * No need to remember the reset request: tpm + * reset will happen as soon as we break out + * from this while loop, + */ + evt &= TPM_EVENT_ALT_EXTENSION; break; + } cprints(CC_TASK, "%s:%d unexpected event %x", __func__, __LINE__, evt); } } - evt = 0; tpm_reset_now(0); while (1) { uint8_t *response; |