diff options
-rw-r--r-- | board/cr50/board.c | 6 | ||||
-rw-r--r-- | board/cr50/board.h | 6 | ||||
-rw-r--r-- | board/cr50/power_button.c | 74 | ||||
-rw-r--r-- | include/system.h | 3 |
4 files changed, 87 insertions, 2 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c index 6843673662..defb033d52 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -1175,6 +1175,12 @@ void assert_ec_rst(void) void deassert_ec_rst(void) { + if (ec_rst_override()) { + ccprintf("EC un-reset blocked, try powercycle or Cr50 reboot." + "\n"); + return; + } + wait_ec_rst(0); if (uart_bitbang_is_enabled()) diff --git a/board/cr50/board.h b/board/cr50/board.h index fea738f7d2..b9dc15e988 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -364,6 +364,12 @@ int ec_is_rx_allowed(void); int servo_is_connected(void); /* + * Returns nonzero value if EC reset line is taken over and should not be + * touched by the 'standard' EC reset functions. + */ +int ec_rst_override(void); + +/* * Assert INT_AP_L to acknowledge AP that cr50 is ready for next TPM command. * NOTE: must be called by ISR only. * diff --git a/board/cr50/power_button.c b/board/cr50/power_button.c index 6aca820caf..6dab74d134 100644 --- a/board/cr50/power_button.c +++ b/board/cr50/power_button.c @@ -60,6 +60,71 @@ static void power_button_press_enable_interrupt(int enable) #ifdef CONFIG_AP_RO_VERIFICATION /* + * A hook used to keep the EC in reset, no matter what keys the user presses, + * the only way out is the Cr50 reboot, most likely through power cycle by + * battery cutoff. + * + * Cr50 console over SuzyQ would still be available in case the user has the + * cable and wants to see what happens with the system. The easiest way to see + * the system is in this state to run the 'flog' command and examine the flash + * log. + */ +static void keep_ec_in_reset(void); +static bool ap_ro_verification_failed_; + +DECLARE_DEFERRED(keep_ec_in_reset); + +static void keep_ec_in_reset(void) +{ + if (!ap_ro_verification_failed_) { + enable_sleep(SLEEP_MASK_AP_RO_VERIFICATION); + return; + } + + assert_ec_rst(); + hook_call_deferred(&keep_ec_in_reset_data, 100 * MSEC); +} + +static int ver_state_cmd(int argc, char **argv) +{ +#ifdef CR50_DEV + int const max_args = 2; +#else + int const max_args = 1; +#endif + + if (argc > max_args) + return EC_ERROR_PARAM_COUNT; +#ifdef CR50_DEV + if (argc == max_args) { + if (strcasecmp(argv[1], "clear")) + return EC_ERROR_PARAM1; + if (ap_ro_verification_failed_) { + ap_ro_verification_failed_ = false; + deassert_ec_rst(); + } + } +#endif + ccprintf("%sAP RO verification failure detected\n", + ap_ro_verification_failed_ ? "" : "NO "); + + return EC_SUCCESS; +} +DECLARE_SAFE_CONSOLE_COMMAND(ver_state, ver_state_cmd, +#ifdef CR50_DEV + "[clear]", + "Display and/or clear AP RO validation state" +#else + "", "Display AP RO validation state" +#endif +); + +int ec_rst_override(void) +{ + return ap_ro_verification_failed_; +} + +/* * Implement sequence detecting trigger for starting AP RO verification. * * 'RCTD' is short for 'RO check trigger detection'. @@ -169,7 +234,14 @@ static int rctd_poll_handler(void) CPRINTS("RO Validation triggered"); ap_ro_add_flash_event(APROF_CHECK_TRIGGERED); - validate_ap_ro(); + + if (validate_ap_ro() == EC_ERROR_CRC) { + /* Validation failed, no go. */ + ap_ro_verification_failed_ = true; + disable_sleep(SLEEP_MASK_AP_RO_VERIFICATION); + keep_ec_in_reset(); + } + return 0; } diff --git a/include/system.h b/include/system.h index 1df48cf28e..4862ad2dc0 100644 --- a/include/system.h +++ b/include/system.h @@ -425,7 +425,8 @@ enum { SLEEP_MASK_USB_PD = BIT(5), /* USB PD device connected */ SLEEP_MASK_SPI = BIT(6), /* SPI communications ongoing */ SLEEP_MASK_I2C_SLAVE = BIT(7), /* I2C slave communication ongoing */ - SLEEP_MASK_FAN = BIT(8), /* Fan control loop ongoing */ + SLEEP_MASK_AP_RO_VERIFICATION + = BIT(8), /* AP RO verification failure. */ SLEEP_MASK_USB_DEVICE = BIT(9), /* Generic USB device in use */ SLEEP_MASK_PWM = BIT(10), /* PWM output is enabled */ SLEEP_MASK_PHYSICAL_PRESENCE = BIT(11), /* Physical presence |