summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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];