summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2021-06-25 15:23:24 -0700
committerCommit Bot <commit-bot@chromium.org>2021-06-30 23:48:31 +0000
commit8afa696aa05a02ee6a4015533a011a6b82716f05 (patch)
tree31fe0b4cef21f51d4f0d0c8f157219a9bf556641
parent1e68e66a387c91b63a7a79324f3c828f7f0fed4b (diff)
downloadchrome-ec-8afa696aa05a02ee6a4015533a011a6b82716f05.tar.gz
tpm_mode: make available to all boards and restore on resets
This patch removes the restriction of TPM_MODE vendor command, allowing any board's AP to disable TPM mode if required. In addition, TPM reset processing flow is being modified to always reboot the H1 in case TPM reset happens when TPM is disabled. BUG=b:191180387, b:191180208 TEST=on an Atlas device: localhost ~ # gsctool -a -f start target running protocol version 6 keyids: RO 0xaa66150f, RW 0x334f70df offsets: backup RO at 0, backup RW at 0x4000 Current versions: RO 0.0.11 RW 0.6.30 $ localhost ~ # gsctool -a -m disable TPM Mode: disabled (2) localhost ~ # gsctool -a -f start [WARNING:bus.cc(638)] Bus::SendWithReplyAndBlock took 1516ms to... Problems reading from TPM, got 10 bytes Failed to start transfer localhost ~ # reboot -- GSC reboots during device rebnoot localhost ~ # gsctool -a -f start target running protocol version 6 keyids: RO 0xaa66150f, RW 0x334f70df offsets: backup RO at 0, backup RW at 0x4000 Current versions: RO 0.0.11 RW 0.6.30 localhost ~ # reboot -- GSC does NOT reboot during device rebnoot Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Change-Id: I492bd2f201f3c5c7d1cd9b228ec6ab1cdcf8fa53 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2987913 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/board.c59
-rw-r--r--board/cr50/board.h2
-rw-r--r--board/cr50/scratch_reg1.h5
-rw-r--r--board/cr50/tpm2/tpm_mode.c17
4 files changed, 42 insertions, 41 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 25f226542d..71453e888e 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -177,11 +177,6 @@ int board_has_ina_support(void)
return !(board_properties & BOARD_NO_INA_SUPPORT);
}
-int board_tpm_mode_change_allowed(void)
-{
- return !!(board_properties & BOARD_ALLOW_CHANGE_TPM_MODE);
-}
-
int board_has_ec_cr50_comm_support(void)
{
return !!(board_properties & BOARD_EC_CR50_COMM_SUPPORT);
@@ -324,8 +319,7 @@ static struct board_cfg board_cfg_table[] = {
.strap_cfg = 0x70,
.board_properties = BOARD_PERIPH_CONFIG_I2C |
BOARD_USE_PLT_RESET | BOARD_WP_DISABLE_DELAY |
- BOARD_CLOSED_SOURCE_SET1 | BOARD_NO_INA_SUPPORT |
- BOARD_ALLOW_CHANGE_TPM_MODE,
+ BOARD_CLOSED_SOURCE_SET1 | BOARD_NO_INA_SUPPORT,
},
/* Dedede/Puff/Volteer: DIOA9 = 5K PU, DIOA1 = 1M PU */
{
@@ -1049,32 +1043,37 @@ static void deferred_tpm_rst_isr(void)
{
CPRINTS("%s", __func__);
- /*
- * TPM reset is used to detect the AP, connect AP. Let the AP state
- * machine know the AP is on.
- */
- set_ap_on();
+ if (get_tpm_mode() != TPM_MODE_DISABLED) {
- /*
- * If no reboot request is posted, OR if the other RW's header is not
- * ready to run - do not try rebooting the device, just reset the
- * TPM.
- *
- * The inactive header will have to be restored by the appropriate
- * vendor command, the device will be rebooted then.
- */
- if (!reboot_request_posted || other_rw_is_inactive()) {
- /* Reset TPM, no need to wait for completion. */
- tpm_reset_request(0, 0);
- return;
- }
+ /*
+ * TPM reset is used to detect the AP, connect AP. Let the AP
+ * state machine know the AP is on.
+ */
+ set_ap_on();
- /*
- * Reset TPM and wait to completion to make sure nvmem is
- * committed before reboot.
- */
- tpm_reset_request(1, 0);
+ /*
+ * If no reboot request is posted, OR if the other RW's header
+ * is not ready to run - do not try rebooting the device, just
+ * reset the TPM.
+ *
+ * The inactive header will have to be restored by the
+ * appropriate vendor command, the device will be rebooted
+ * then.
+ */
+ if (!reboot_request_posted || other_rw_is_inactive()) {
+ /* Reset TPM, no need to wait for completion. */
+ tpm_reset_request(0, 0);
+ return;
+ }
+
+ /*
+ * Reset TPM and wait to completion to make sure nvmem is
+ * committed before reboot.
+ */
+ tpm_reset_request(1, 0);
+ }
+ cflush();
/* This will never return. */
system_reset(SYSTEM_RESET_MANUALLY_TRIGGERED | SYSTEM_RESET_HARD);
}
diff --git a/board/cr50/board.h b/board/cr50/board.h
index a91bb9ba2a..b05718961f 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -324,8 +324,6 @@ int board_uses_closed_loop_reset(void);
* @return 0 if option is not set, !=0 if option set.
*/
int board_has_ina_support(void);
-/* The board allows vendor commands to enable/disable tpm. */
-int board_tpm_mode_change_allowed(void);
/* The board supports EC-CR50 communication. */
int board_has_ec_cr50_comm_support(void);
int board_id_is_mismatched(void);
diff --git a/board/cr50/scratch_reg1.h b/board/cr50/scratch_reg1.h
index b70894a905..b4cdd9c6d8 100644
--- a/board/cr50/scratch_reg1.h
+++ b/board/cr50/scratch_reg1.h
@@ -81,9 +81,9 @@
#define BOARD_NO_INA_SUPPORT BIT(19)
/*
- * The board allows commands to stop TPM (Wilco, Campfire, etc.)
+ ****** Bit20 unused. DON'T FORGET TO INCLUDE IT INTO BOARD_ALL_PROPERTIES
+ ****** WHEN IT GETS A NEW USE.
*/
-#define BOARD_ALLOW_CHANGE_TPM_MODE BIT(20)
/*
* The board supports EC-CR50 communication.
@@ -112,7 +112,6 @@
* updated if additional strap related properties are added.
*/
#define BOARD_ALL_PROPERTIES ( \
- BOARD_ALLOW_CHANGE_TPM_MODE | \
BOARD_CCD_REC_LID_PIN_MASK | \
BOARD_CLOSED_LOOP_RESET | \
BOARD_CLOSED_SOURCE_SET1 | \
diff --git a/board/cr50/tpm2/tpm_mode.c b/board/cr50/tpm2/tpm_mode.c
index dea38abf02..3049ab840c 100644
--- a/board/cr50/tpm2/tpm_mode.c
+++ b/board/cr50/tpm2/tpm_mode.c
@@ -32,11 +32,17 @@ static void disable_tpm(void)
DECLARE_DEFERRED(disable_tpm);
/*
- * On TPM reset event, tpm_reset_now() in tpm_registers.c clears TPM2 BSS memory
- * area. By placing s_tpm_mode in TPM2 BSS area, TPM mode value shall be
- * "TPM_MODE_ENABLED_TENTATIVE" on every TPM reset events.
+ * tpm_mode can be set only once after a hardware reset, to either
+ * TPM_MODE_ENABLED or TPM_MODE_DISABLED.
+ *
+ * This allows the AP to make sure that TPM can't be disabled by setting mode
+ * to TPM_MODE_ENABLED during start up.
+ *
+ * If mode is set to TPM_MODE_DISABLED, the AP loses the ability to
+ * communicate with the TPM until next TPM reset (which will trigger the H1
+ * hardware reset in that case).
*/
-static enum tpm_modes s_tpm_mode __attribute__((section(".bss.Tpm2_common")));
+static enum tpm_modes s_tpm_mode;
static enum vendor_cmd_rc process_tpm_mode(struct vendor_cmd_params *p)
{
@@ -51,8 +57,7 @@ static enum vendor_cmd_rc process_tpm_mode(struct vendor_cmd_params *p)
buffer = (uint8_t *)p->buffer;
if (p->in_size == sizeof(uint8_t)) {
- if (!board_tpm_mode_change_allowed() ||
- (s_tpm_mode != TPM_MODE_ENABLED_TENTATIVE))
+ if (s_tpm_mode != TPM_MODE_ENABLED_TENTATIVE)
return VENDOR_RC_NOT_ALLOWED;
mode_val = buffer[0];