summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2017-10-31 18:51:51 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-11-13 18:58:44 +0000
commitb9783a70c645fb2043a1f63a9056201f8f7649eb (patch)
treeb4efdba9926648361a23226d6b39d506ecd94c55 /common
parent0a3a60ec48b086f51dec542f40c6d0f54a5893e8 (diff)
downloadchrome-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.c9
-rw-r--r--common/tpm_registers.c25
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)