diff options
Diffstat (limited to 'src/mainboard')
-rw-r--r-- | src/mainboard/google/sarien/chromeos.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/src/mainboard/google/sarien/chromeos.c b/src/mainboard/google/sarien/chromeos.c index 1e363fdfdd..2bef829f83 100644 --- a/src/mainboard/google/sarien/chromeos.c +++ b/src/mainboard/google/sarien/chromeos.c @@ -30,7 +30,6 @@ enum rec_mode_state { REC_MODE_NOT_REQUESTED, REC_MODE_REQUESTED, }; -static enum rec_mode_state saved_rec_mode; void fill_lb_gpios(struct lb_gpios *gpios) { @@ -84,25 +83,31 @@ int get_write_protect_state(void) int get_recovery_mode_switch(void) { - enum rec_mode_state state = saved_rec_mode; - uint8_t recovery_button_state = 0; - - /* Check the global variable first. */ - if (state == REC_MODE_NOT_REQUESTED) - return 0; - else if (state == REC_MODE_REQUESTED) - return 1; - - state = REC_MODE_NOT_REQUESTED; + static enum rec_mode_state saved_rec_mode = REC_MODE_UNINITIALIZED; + enum rec_mode_state state = REC_MODE_NOT_REQUESTED; + uint8_t cr50_state = 0; + + /* Check cached state, since TPM will only tell us the first time */ + if (saved_rec_mode != REC_MODE_UNINITIALIZED) + return saved_rec_mode == REC_MODE_REQUESTED; + + /* + * Read one-time recovery request from cr50 in verstage only since + * the TPM driver won't be set up in time for other stages like romstage + * and the value from the TPM would be wrong anyway since the verstage + * read would have cleared the value on the TPM. + * + * The TPM recovery request is passed between stages through the + * vboot_get_shared_data or cbmem depending on stage. + */ + if (ENV_VERSTAGE && + tlcl_cr50_get_recovery_button(&cr50_state) == TPM_SUCCESS && + cr50_state) + state = REC_MODE_REQUESTED; /* Read state from the GPIO controlled by servo. */ if (cros_get_gpio_value(CROS_GPIO_REC)) state = REC_MODE_REQUESTED; - /* Read one-time recovery request from cr50. */ - else if (tlcl_cr50_get_recovery_button(&recovery_button_state) - == TPM_SUCCESS) - state = recovery_button_state ? - REC_MODE_REQUESTED : REC_MODE_NOT_REQUESTED; /* Store the state in case this is called again in verstage. */ saved_rec_mode = state; |