diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2017-10-31 18:51:51 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2017-11-13 18:58:44 +0000 |
commit | b9783a70c645fb2043a1f63a9056201f8f7649eb (patch) | |
tree | b4efdba9926648361a23226d6b39d506ecd94c55 /common | |
parent | 0a3a60ec48b086f51dec542f40c6d0f54a5893e8 (diff) | |
download | chrome-ec-b9783a70c645fb2043a1f63a9056201f8f7649eb.tar.gz |
tpm: provide means of shutting down comms layer while in reset
Currently the Cr50 code resets TPM communications layer at a certain
point during TPM reset process.
It turns out that this is not sufficient - the comms layer keeps
receiving and trying to invoke TPM layer, which does not mesh well
with TPM reset.
Let's provide two callbacks for each comms layer - to shut it down and
to bring it back up. We shut down the comms when starting TPM reset
and bring them back up when reset is completed.
BRANCH=cr50
BUG=b:68012381
TEST=ran AP firmware test suite on both SPI and I2C based devices.
Change-Id: I7caf4a09b9a5c6e5fc6bfe60eae1c0d64ab24904
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/754502
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
(cherry picked from commit 3919001a390f593ba8e022f223bf1e43b7dbc0a2)
Reviewed-on: https://chromium-review.googlesource.com/766076
Diffstat (limited to 'common')
-rw-r--r-- | common/i2cs_tpm.c | 9 | ||||
-rw-r--r-- | common/tpm_registers.c | 25 |
2 files changed, 25 insertions, 9 deletions
diff --git a/common/i2cs_tpm.c b/common/i2cs_tpm.c index 42089681dd..4518eddbb9 100644 --- a/common/i2cs_tpm.c +++ b/common/i2cs_tpm.c @@ -211,7 +211,12 @@ static void wr_complete_handler(void *i2cs_data, size_t i2cs_data_size) gpio_set_level(GPIO_INT_AP_L, 1); } -static void i2cs_tpm_enable(void) +static void i2cs_if_stop(void) +{ + i2cs_register_write_complete_handler(NULL); +} + +static void i2cs_if_start(void) { i2cs_register_write_complete_handler(wr_complete_handler); } @@ -221,7 +226,7 @@ static void i2cs_if_register(void) if (!board_tpm_uses_i2c()) return; - tpm_register_interface(i2cs_tpm_enable); + tpm_register_interface(i2cs_if_start, i2cs_if_stop); i2cs_fifo_adjust_count = 0; i2cs_write_error_count = 0; } diff --git a/common/tpm_registers.c b/common/tpm_registers.c index 46d2b7fdf1..71f0fb4a28 100644 --- a/common/tpm_registers.c +++ b/common/tpm_registers.c @@ -536,10 +536,13 @@ void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size) CPRINTF("\n"); } -static __preserved interface_restart_func if_restart; -void tpm_register_interface(interface_restart_func interface_restart) +static __preserved interface_control_func if_start; +static __preserved interface_control_func if_stop; +void tpm_register_interface(interface_control_func interface_start, + interface_control_func interface_stop) { - if_restart = interface_restart; + if_start = interface_start; + if_stop = interface_stop; } static void tpm_init(void) @@ -615,10 +618,6 @@ static void tpm_init(void) _plat__SetNvAvail(); } - - /* Reinitialize TPM interface unless in chip factory mode. */ - if (!chip_factory_mode()) - if_restart(); } size_t tpm_get_burst_size(void) @@ -812,6 +811,10 @@ void tpm_reinstate_nvmem_commits(void) static void tpm_reset_now(int wipe_first) { + /* TPM is not running in factory mode. */ + if (!chip_factory_mode()) + if_stop(); + /* This is more related to TPM task activity than TPM transactions */ cprints(CC_TASK, "%s(%d)", __func__, wipe_first); @@ -866,6 +869,14 @@ static void tpm_reset_now(int wipe_first) hook_call_deferred(&reinstate_nvmem_commits_data, 3 * SECOND); reset_in_progress = 0; + + /* + * In chip factory mode SPI idle byte sent on MISO is used for + * progress reporting. TPM flow control messes it up, do not start TPM + * in factory mode. + */ + if (!chip_factory_mode()) + if_start(); } void tpm_task(void) |