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-08-06 19:23:52 +0000
commit43bd66432e50493d552961a72181a2d46be4fd55 (patch)
treeb42940398d111a225b1b4839881990aec041d6d4
parent6c3186d0e207907cf3595d44982a926680857bd0 (diff)
downloadchrome-ec-43bd66432e50493d552961a72181a2d46be4fd55.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> (cherry picked from commit 8afa696aa05a02ee6a4015533a011a6b82716f05) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3078206 Tested-by: Mary Ruthven <mruthven@chromium.org> Commit-Queue: 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 9a21b6e9c1..0e2e5edfef 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);
@@ -329,8 +324,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 */
{
@@ -1054,32 +1048,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 a05b3586a9..856396f6e9 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -320,8 +320,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 0e5b081bb4..4837c6330f 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.
@@ -111,7 +111,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 8282236caa..b4c52e4ab0 100644
--- a/board/cr50/tpm2/tpm_mode.c
+++ b/board/cr50/tpm2/tpm_mode.c
@@ -33,11 +33,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)
{
@@ -52,8 +58,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];