summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/intel/haswell/romstage.c8
-rw-r--r--src/ec/google/chromeec/ec.c39
-rw-r--r--src/ec/google/chromeec/ec.h1
3 files changed, 46 insertions, 2 deletions
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 <vendorcode/google/chromeos/chromeos.h>
#endif
+#if CONFIG_EC_GOOGLE_CHROMEEC
+#include <ec/google/chromeec/ec.h>
+#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 <console/console.h>
#include <arch/io.h>
#include <delay.h>
+#include <arch/hlt.h>
+#include <reset.h>
#ifndef __PRE_RAM__
#include <elog.h>
#include <stdlib.h>
#include <string.h>
-#include <reset.h>
-#include <arch/hlt.h>
#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);