summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-02-14 18:55:52 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-15 21:43:57 -0800
commitf495e27ce67888cd955bffded589f877ae503897 (patch)
tree45f60476dc9677355a37d0bd9e68606caf745ee6
parent5ae1a9915d3c1ce72430e9654839e2a8da1da0bc (diff)
downloadchrome-ec-f495e27ce67888cd955bffded589f877ae503897.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>
-rw-r--r--common/tpm_registers.c20
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;