summaryrefslogtreecommitdiff
path: root/include
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 /include
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 'include')
-rw-r--r--include/nvmem.h7
-rw-r--r--include/tpm_registers.h21
2 files changed, 11 insertions, 17 deletions
diff --git a/include/nvmem.h b/include/nvmem.h
index 354e763c8d..740c845d9d 100644
--- a/include/nvmem.h
+++ b/include/nvmem.h
@@ -177,11 +177,4 @@ int nvmem_setup(uint8_t version);
void nvmem_compute_sha(uint8_t *p_buf, int num_bytes, uint8_t *p_sha,
int sha_len);
-/*
- * Erase and reformat the entire nvmem storage space. This returns only if it
- * was successful. If it fails, we can't be certain of the state of the system,
- * so it should do a hard reboot to be safe.
- */
-void nvmem_wipe_or_reboot(void);
-
#endif /* __CROS_EC_NVMEM_UTILS_H */
diff --git a/include/tpm_registers.h b/include/tpm_registers.h
index dfdfefdc34..887cc163cd 100644
--- a/include/tpm_registers.h
+++ b/include/tpm_registers.h
@@ -31,20 +31,21 @@ typedef void (*interface_restart_func)(void);
void tpm_register_interface(interface_restart_func interface_restart);
/*
- * Reset the TPM. This sends a request to the TPM task, so that the reset can
- * happen when the TPM task finishes whatever it's doing at the moment.
+ * This requests the TPM task to reset itself.
*
- * Returns 0 if the request was made, but we can't wait for it to complete
- * because we're in interrupt context or something similar. Otherwise, it
- * blocks and returns 1 after the TPM has been cleared, or returns -1 if the
- * request timed out.
+ * If wait_until_done is false, it returns EC_SUCCESS immediately. Otherwise it
+ * returns EC_SUCCESS after the reset has completed, or an error code on
+ * failure.
+ *
+ * If wipe_nvmem_first is true, the EC and AP will be forced off and TPM memory
+ * will be erased before the TPM task is reset.
*/
-int tpm_reset(void);
+int tpm_reset(int wait_until_done, int wipe_nvmem_first);
/*
- * Return true if tpm is being reset. Usually this helps to avoid unnecessary
- * extra reset early at startup time, when TPM could be busy installing
- * endorsement certificates.
+ * Return true if the TPM is being reset. Usually this helps to avoid
+ * unnecessary extra reset early at startup time, when TPM could be busy
+ * installing endorsement certificates.
*/
int tpm_is_resetting(void);