diff options
-rw-r--r-- | board/cr50/board.c | 59 | ||||
-rw-r--r-- | board/cr50/board.h | 2 | ||||
-rw-r--r-- | board/cr50/scratch_reg1.h | 5 | ||||
-rw-r--r-- | board/cr50/tpm2/tpm_mode.c | 17 |
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]; |