summaryrefslogtreecommitdiff
path: root/board/cr50/wp.c
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-11-16 15:37:44 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-11-19 00:14:24 -0800
commit93388bc758cf7c2cfc70f63fbe42c25b1ed7fb38 (patch)
tree49310e932f37812d771166b9f3778906f37f232f /board/cr50/wp.c
parent7f8ad649dd1a417a746739e86bce7dc3f0a40c1b (diff)
downloadchrome-ec-93388bc758cf7c2cfc70f63fbe42c25b1ed7fb38.tar.gz
Cr50: Prevent rebooting when unlocking the console
When the console is unlocked, the function nvmem_wipe_or_reboot() is called. This holds the EC in reset, clears nvmem, resets the TPM task, then releases the EC. Nothing about that should cause the Cr50 to reboot, but it was happening anyway. This CL addresses several subtle problems. First, holding the EC in reset invoked the sys_rst_asserted() interrupt handler, triggering extra (and early) calls to tpm_reset(). That should wait until after nvmem is cleared, and only be called once. Second, the intentional call to tpm_reset() caused the current (HOOKS) task to wait for the operation to finish, but it didn't wait long enough (recreating the endorsement certs can take over a second). When the task_wake_event() returned, a timeout was indicated in addition to the completion event. Third, because we checked for the timeout first, we reported an error even though tpm_reset() completed successfully, just slower than we expected. We didn't get the timeout event before it completed because the TPM task runs at a higher priority. This CL addresses all of these cases, and makes wiping nvmem the responsibility of the TPM task as well, so that it can do it when it's ready. Note that the EC (and thus AP too) will be held in reset while nvmem is erased. BUG=chrome-os-partner:59902 BRANCH=none TEST=make buildall, manual tests From the Cr50 console, run the "lock on" and "lock off" commands. Try it both with and without the battery present. Observe that the Cr50 no longer reboots just because the console unlocks. Change-Id: I65a342502718acc5b9bda8c6f28dcd27e8f027f7 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/411379 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'board/cr50/wp.c')
-rw-r--r--board/cr50/wp.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/board/cr50/wp.c b/board/cr50/wp.c
index d667ecc74e..69b88c4a71 100644
--- a/board/cr50/wp.c
+++ b/board/cr50/wp.c
@@ -13,6 +13,7 @@
#include "system.h"
#include "task.h"
#include "timer.h"
+#include "tpm_registers.h"
#define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args)
@@ -58,7 +59,21 @@ static void lock_the_console(void)
static void unlock_the_console(void)
{
- nvmem_wipe_or_reboot();
+ int rc;
+
+ /* Wipe the TPM's memory and reset the TPM task. */
+ rc = tpm_reset(1, 1);
+ if (rc != EC_SUCCESS) {
+ /*
+ * If anything goes wrong (which is unlikely), we REALLY don't
+ * want to unlock the console. It's possible to fail without
+ * the TPM task ever running, so rebooting is probably our best
+ * bet for fixing the problem.
+ */
+ CPRINTS("%s: Couldn't wipe nvmem! (rc %d)", __func__, rc);
+ system_reset(SYSTEM_RESET_HARD);
+ }
+
CPRINTS("TPM is erased, console is unlocked");
console_restricted_state = 0;
}