diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c index 8196273195..0cef888b49 100644 --- a/src/cpu/intel/haswell/romstage.c +++ b/src/cpu/intel/haswell/romstage.c @@ -38,6 +38,9 @@ #if CONFIG_CHROMEOS #include #endif +#if CONFIG_EC_GOOGLE_CHROMEEC +#include +#endif #include "haswell.h" #include "northbridge/intel/haswell/haswell.h" #include "northbridge/intel/haswell/raminit.h" @@ -216,6 +219,11 @@ void romstage_common(const struct romstage_params *params) wake_from_s3 = early_pch_init(params->gpio_map, params->rcba_config); +#if CONFIG_EC_GOOGLE_CHROMEEC + /* Ensure the EC is in the right mode for recovery */ + google_chromeec_early_init(); +#endif + /* Halt if there was a built in self test failure */ report_bist_failure(params->bist); diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index d94338fa18..9b848c06c2 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -21,12 +21,12 @@ #include #include #include +#include +#include #ifndef __PRE_RAM__ #include #include #include -#include -#include #include "chip.h" #endif #include "ec.h" @@ -99,6 +99,41 @@ u32 google_chromeec_get_events_b(void) return google_chromeec_get_mask(EC_CMD_HOST_EVENT_GET_B); } +#ifndef __SMM__ +/* Check for recovery mode and ensure EC is in RO */ +void google_chromeec_early_init(void) +{ + struct chromeec_command cec_cmd; + struct ec_response_get_version cec_resp = {{0}}; + + cec_cmd.cmd_code = EC_CMD_GET_VERSION; + cec_cmd.cmd_version = 0; + cec_cmd.cmd_data_out = &cec_resp; + cec_cmd.cmd_size_in = 0; + cec_cmd.cmd_size_out = sizeof(cec_resp); + google_chromeec_command(&cec_cmd); + + if (cec_cmd.cmd_code || + (recovery_mode_enabled() && + (cec_resp.current_image != EC_IMAGE_RO))) { + struct ec_params_reboot_ec reboot_ec; + /* Reboot the EC and make it come back in RO mode */ + reboot_ec.cmd = EC_REBOOT_COLD; + reboot_ec.flags = 0; + cec_cmd.cmd_code = EC_CMD_REBOOT_EC; + cec_cmd.cmd_version = 0; + cec_cmd.cmd_data_in = &reboot_ec; + cec_cmd.cmd_size_in = sizeof(reboot_ec); + cec_cmd.cmd_size_out = 0; /* ignore response, if any */ + printk(BIOS_DEBUG, "Rebooting with EC in RO mode:\n"); + google_chromeec_command(&cec_cmd); + udelay(1000); + hard_reset(); + hlt(); + } +} +#endif /* ! __SMM__ */ + #ifndef __PRE_RAM__ static int google_chromeec_set_mask(u8 type, u32 mask) diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 3eb555c103..7679a8bcc6 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -33,6 +33,7 @@ u16 google_chromeec_get_board_version(void); void google_chromeec_init(void); #endif +void google_chromeec_early_init(void); uint8_t google_chromeec_calc_checksum(const uint8_t *data, int size); u32 google_chromeec_get_events_b(void); int google_chromeec_kbbacklight(int percent);