diff options
-rw-r--r-- | src/mainboard/google/sarien/Kconfig | 1 | ||||
-rw-r--r-- | src/mainboard/google/sarien/chromeos.c | 39 |
2 files changed, 32 insertions, 8 deletions
diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index ff2f678831..f93910fe4c 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -100,5 +100,6 @@ config VBOOT select HAS_RECOVERY_MRC_CACHE select MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN select VBOOT_LID_SWITCH + select VBOOT_PHYSICAL_REC_SWITCH endif # BOARD_GOOGLE_BASEBOARD_SARIEN diff --git a/src/mainboard/google/sarien/chromeos.c b/src/mainboard/google/sarien/chromeos.c index 8b2090e5b0..0ea237a407 100644 --- a/src/mainboard/google/sarien/chromeos.c +++ b/src/mainboard/google/sarien/chromeos.c @@ -14,6 +14,7 @@ */ #include <arch/acpi.h> +#include <arch/early_variables.h> #include <boot/coreboot_tables.h> #include <gpio.h> #include <soc/gpio.h> @@ -21,12 +22,20 @@ #include <vendorcode/google/chromeos/chromeos.h> #include <security/tpm/tss.h> +enum rec_mode_state { + REC_MODE_UNINITIALIZED, + REC_MODE_NOT_REQUESTED, + REC_MODE_REQUESTED, +}; +static enum rec_mode_state saved_rec_mode CAR_GLOBAL; void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { - {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, + {GPIO_PCH_WP, ACTIVE_HIGH, get_write_protect_state(), + "write protect"}, + {GPIO_REC_MODE, ACTIVE_LOW, get_recovery_mode_switch(), + "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, @@ -72,16 +81,30 @@ int get_write_protect_state(void) int get_recovery_mode_switch(void) { - uint8_t recovery_button_state; - int recovery_mode_switch = 0; + enum rec_mode_state state = car_get_var(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; + + /* Read state from the GPIO controlled by servo. */ if (cros_get_gpio_value(CROS_GPIO_REC)) - recovery_mode_switch = 1; + state = REC_MODE_REQUESTED; + /* Read one-time recovery request from cr50. */ else if (tlcl_cr50_get_recovery_button(&recovery_button_state) - == TPM_SUCCESS) - recovery_mode_switch = 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. */ + car_set_var(saved_rec_mode, state); - return recovery_mode_switch; + return state == REC_MODE_REQUESTED; } int get_lid_switch(void) |