summaryrefslogtreecommitdiff
path: root/common/tpm_registers.c
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2016-09-22 18:52:47 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-09-26 22:16:45 -0700
commit5a6bb19a889f5b7fa5f4b590aba5893bee9d5452 (patch)
treeadac78be67c57bcde092587fc2ade2d57ca6f5fc /common/tpm_registers.c
parent75aaabcd9ade5d2a2ad068d2543e8e82011b979f (diff)
downloadchrome-ec-5a6bb19a889f5b7fa5f4b590aba5893bee9d5452.tar.gz
tpm: reset communications channels when resetting TPM
TPM resets happen asynchronously, conceivably there is some interface (i2cs or sps) activity under way when TPM is reset. Sps driver provides a means of disconnecting the client of the driver, while the i2cs driver does not. Come to think of it, there is no real need to provide a special function to disconnect a client, this makes API simpler and allows to add driver initialization to the client registration function. To make tpm_registers.c more flexible - allow to register a callback for interface initialization, this way when TPM is reset, the interface can be also re-initialized and is guaranteed to start from scratch after reset. BRANCH=none BUG=chrome-os-partner:52366 TEST=both firmware_TPMExtend and firmware_TPMKernelVersion autotests pass Change-Id: I212166a23f9cd512d8f75315377d1f5620aea070 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/388886 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Diffstat (limited to 'common/tpm_registers.c')
-rw-r--r--common/tpm_registers.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index dce342ee5f..a2bdec4925 100644
--- a/common/tpm_registers.c
+++ b/common/tpm_registers.c
@@ -46,6 +46,8 @@
#define GOOGLE_DID 0x0028
#define CR50_RID 0 /* No revision ID yet */
+static uint8_t reset_in_progress __attribute__((section(".bss.noreinit")));
+
/* Tpm state machine states. */
enum tpm_states {
tpm_state_idle,
@@ -372,6 +374,9 @@ void tpm_register_put(uint32_t regaddr, const uint8_t *data, uint32_t data_size)
{
uint32_t i;
+ if (reset_in_progress)
+ return;
+
CPRINTF("%s(0x%03x, %d,", __func__, regaddr, data_size);
for (i = 0; i < data_size && i < 4; i++)
CPRINTF(" %02x", data[i]);
@@ -443,6 +448,9 @@ void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size)
{
int i;
+ if (reset_in_progress)
+ return;
+
CPRINTF("%s(0x%06x, %d)", __func__, regaddr, data_size);
switch (regaddr) {
case TPM_DID_VID:
@@ -492,11 +500,23 @@ void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size)
CPRINTF("\n");
}
+static interface_restart_func if_restart
+__attribute__((section(".bss.noreinit")));
+void tpm_register_interface(interface_restart_func interface_restart)
+{
+ if_restart = interface_restart;
+}
+
static void tpm_init(void)
{
/* This is more related to TPM task activity than TPM transactions */
cprints(CC_TASK, "%s", __func__);
+ if (system_rolling_reboot_suspected()) {
+ cprints(CC_TASK, "%s interrupted", __func__);
+ return;
+ }
+
set_tpm_state(tpm_state_idle);
tpm_.regs.access = tpm_reg_valid_sts;
/*
@@ -534,6 +554,9 @@ static void tpm_init(void)
}
_plat__SetNvAvail();
+
+ /* Reinitialize TPM interface. */
+ if_restart();
}
size_t tpm_get_burst_size(void)
@@ -604,11 +627,11 @@ int tpm_reset(void)
static void tpm_reset_now(void)
{
+ reset_in_progress = 1;
+
/* This is more related to TPM task activity than TPM transactions */
cprints(CC_TASK, "%s", __func__);
- sps_tpm_disable();
-
/*
* Clear the TPM library's zero-init data. Note that the linker script
* includes this file's .bss in the same section, so it will be cleared
@@ -626,22 +649,17 @@ static void tpm_reset_now(void)
/* Re-initialize our registers */
tpm_init();
- sps_tpm_enable();
-
if (waiting_for_reset != TASK_ID_INVALID) {
/* Wake the waiting task, if any */
task_set_event(waiting_for_reset, TPM_EVENT_RESET, 0);
waiting_for_reset = TASK_ID_INVALID;
}
+ reset_in_progress = 0;
}
void tpm_task(void)
{
- if (system_rolling_reboot_suspected())
- return;
-
tpm_init();
- sps_tpm_enable();
while (1) {
uint8_t *response;
unsigned response_size;