diff options
-rw-r--r-- | board/cr50/ap_state.c | 34 | ||||
-rw-r--r-- | board/cr50/board.c | 7 | ||||
-rw-r--r-- | board/cr50/board.h | 1 |
3 files changed, 37 insertions, 5 deletions
diff --git a/board/cr50/ap_state.c b/board/cr50/ap_state.c index 32064ae07c..7e7d1231d2 100644 --- a/board/cr50/ap_state.c +++ b/board/cr50/ap_state.c @@ -4,12 +4,11 @@ * * AP state machine */ -#include "ccd_config.h" -#include "common.h" -#include "console.h" #include "gpio.h" #include "hooks.h" +#include "registers.h" #include "system.h" +#include "tpm_registers.h" #define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) @@ -101,6 +100,7 @@ void set_ap_on(void) disable_deep_sleep(); } +static uint8_t waiting_for_ap_reset; /* * If TPM_RST_L is asserted, the AP is in reset. Disable all AP functionality * in 1 second if it remains asserted. @@ -117,6 +117,34 @@ void tpm_rst_asserted(enum gpio_signal unused) hook_call_deferred(&deferred_set_ap_off_data, SECOND); set_state(DEVICE_STATE_DEBOUNCING); + + if (waiting_for_ap_reset) { + waiting_for_ap_reset = 0; + deassert_ec_rst(); + enable_sleep(SLEEP_MASK_AP_RUN); + } +} + +void board_closed_loop_reset(void) +{ + /* Disable sleep while waiting for the reset */ + disable_sleep(SLEEP_MASK_AP_RUN); + + waiting_for_ap_reset = 1; + + /* Disable AP communications with the TPM until cr50 sees the reset */ + tpm_stop(); + + /* Use EC_RST_L to reset the system */ + assert_ec_rst(); + + /* + * DETECT_TPM_RST_L_ASSERTED is edge triggered. If TPM_RST_L is already + * low, tpm_rst_asserted wont get called. Alert tpm_rst_asserted + * manually if the signal is already low. + */ + if (!gpio_get_level(GPIO_DETECT_TPM_RST_L_ASSERTED)) + tpm_rst_asserted(GPIO_TPM_RST_L); } /** diff --git a/board/cr50/board.c b/board/cr50/board.c index 3aa3693f16..8eb2303ee2 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -1114,7 +1114,10 @@ static int command_ec_rst(int argc, char **argv) if (!ccd_is_cap_enabled(CCD_CAP_REBOOT_EC_AP)) return EC_ERROR_ACCESS_DENIED; - if (!strcasecmp("pulse", argv[1])) { + if (!strcasecmp("cl", argv[1])) { + /* Assert EC_RST_L until TPM_RST_L is asserted */ + board_closed_loop_reset(); + } else if (!strcasecmp("pulse", argv[1])) { ccprintf("Pulsing EC reset\n"); board_reboot_ec(); } else if (parse_bool(argv[1], &val)) { @@ -1132,7 +1135,7 @@ static int command_ec_rst(int argc, char **argv) return EC_SUCCESS; } DECLARE_SAFE_CONSOLE_COMMAND(ecrst, command_ec_rst, - "[pulse | <BOOLEAN>]", + "[cl | pulse | <BOOLEAN>]", "Assert/deassert EC_RST_L to reset the EC (and AP)"); /* diff --git a/board/cr50/board.h b/board/cr50/board.h index 352afdc04f..4878090ab0 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -318,6 +318,7 @@ int board_battery_is_present(void); int board_fwmp_allows_unlock(void); int board_vboot_dev_mode_enabled(void); void board_reboot_ap(void); +void board_closed_loop_reset(void); int board_wipe_tpm(void); int board_is_first_factory_boot(void); |