diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2013-06-04 10:03:34 -0700 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2013-07-10 21:44:22 +0200 |
commit | 7cced0d20e44c1bbcd0b5d4aced53c682fcd23fc (patch) | |
tree | a423cfcfb051acd296a81d277abb1fe827560a3a /src/ec/google/chromeec/ec.c | |
parent | 433432b6544fc57c7998a66aaa34c45609e4fc8c (diff) |
ec: Add romstage function for checking and rebooting EC
Now that we are executing VbInit() in coreboot we can end up
in a situation where the recovery reason is consumed during
VbInit (end of romstage) and then the EC is rebooted to RO
during ramstage EC init, thereby losing the recovery reason.
Two possiblities are to remove the EC check+reboot from ramstage
and let it happen in depthcharge. This however means that the
system has to boot all the way into depthcharge and then reboot
the EC and the system again.
Instead if we do a check in romstage before VbInit() is called
then we can reboot the EC into RO early and avoid booting all
the way to depthcharge first.
This change adds a ramstage version the EC init function and
calls it from the shared romstage code immediately after the
PCH decode windows are setup.
Change-Id: I30d2a0c7131b8e4ec30c63eea36944ec111a8fba
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/3744
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/ec/google/chromeec/ec.c')
-rw-r--r-- | src/ec/google/chromeec/ec.c | 39 |
1 files changed, 37 insertions, 2 deletions
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) |