diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2016-09-22 18:52:47 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-09-26 22:16:45 -0700 |
commit | 5a6bb19a889f5b7fa5f4b590aba5893bee9d5452 (patch) | |
tree | adac78be67c57bcde092587fc2ade2d57ca6f5fc /common/tpm_registers.c | |
parent | 75aaabcd9ade5d2a2ad068d2543e8e82011b979f (diff) | |
download | chrome-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.c | 34 |
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; |