summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2014-10-16 11:05:13 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-20 16:41:16 +0000
commitbef43856a68a39f5484111ad95febc6be2ec5292 (patch)
tree9a9a1c6904ebdb8eb55087cc758eefb77d6eb6e1
parentdd424b1f82198e03e6a6b244d276b3710cb802e3 (diff)
downloadvboot-bef43856a68a39f5484111ad95febc6be2ec5292.tar.gz
vboot: Support SLOW_EC_UPDATE with OPROM_MATTERS
In order to display the slow EC update screen on x86 devices in normal mode it is necessary to request a reboot where the VGA Option ROM is loaded. This needs a bit of plumbing to pass the OPROM_MATTERS and OPROM_LOADED flags into shared data so they can be consumed in the VbEcSoftwareSync() function. It also needs the VbInit() function to not immediately request a reboot if the VGA Option ROM was loaded in normal mode and the SLOW_EC flag is set as it will still need to be used during software sync. A FIXME in VbEcSoftwareSync() is implemented and the comment is removed, and two extra checks are done. First, if rebooting to RO then also check if the VGA Option ROM is needed to save an extra reboot, and second when exiting the software sync function request a reboot without the VGA Option ROM if it was done in normal mode and the option rom was needed+loaded. The request for a reboot from VbEcSoftwareSync() is saved when doing EC update in case there is an (optional) PD software sync that may also need to display the screen. BUG=chrome-os-partner:12257,chrome-os-partner:32379 BRANCH=samus TEST=all tests pass, manual testing: 1) in normal mode, with EC/PD in RW, ensure that they are rebooted to RO and the VGA Option ROM is loaded and the wait screen is displayed, and then the system is rebooted at the end and the VGA Option ROM is not loaded. 2) same as #1 with EC/PD in RO already, same result 3) same as #1 with system in developer mode, same result except there is no reboot at the end of software sync 4) same as #1 with system in developer mode and EC/PD in RO, ensure that there is no extra reboot at the beginning or end of software sync. Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/223718 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> (cherry picked from commit 731f8e8a1df73a00f4840120171b07a259a6304a) Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Change-Id: Id592181efd640f4cd37a986cd1dcc29f3ca45104 Reviewed-on: https://chromium-review.googlesource.com/224403 Tested-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Commit-Queue: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--firmware/include/vboot_struct.h4
-rw-r--r--firmware/lib/vboot_api_init.c13
-rw-r--r--firmware/lib/vboot_api_kernel.c60
3 files changed, 70 insertions, 7 deletions
diff --git a/firmware/include/vboot_struct.h b/firmware/include/vboot_struct.h
index 5e637ba0..923e63cd 100644
--- a/firmware/include/vboot_struct.h
+++ b/firmware/include/vboot_struct.h
@@ -263,6 +263,10 @@ typedef struct VbKernelPreambleHeader {
#define VBSD_BOOT_REC_SWITCH_VIRTUAL 0x00004000
/* Firmware used vboot2 for firmware selection */
#define VBSD_BOOT_FIRMWARE_VBOOT2 0x00008000
+/* Firmware needs VGA Option ROM to display screens */
+#define VBSD_OPROM_MATTERS 0x00010000
+/* Firmware has loaded the VGA Option ROM */
+#define VBSD_OPROM_LOADED 0x00020000
/*
* Supported flags by header version. It's ok to add new flags while keeping
diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c
index b83214f2..38bc8793 100644
--- a/firmware/lib/vboot_api_init.c
+++ b/firmware/lib/vboot_api_init.c
@@ -82,6 +82,10 @@ VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams)
shared->flags |= VBSD_EC_SLOW_UPDATE;
if (iparams->flags & VB_INIT_FLAG_VIRTUAL_REC_SWITCH)
shared->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
+ if (iparams->flags & VB_INIT_FLAG_OPROM_MATTERS)
+ shared->flags |= VBSD_OPROM_MATTERS;
+ if (iparams->flags & VB_INIT_FLAG_OPROM_LOADED)
+ shared->flags |= VBSD_OPROM_LOADED;
is_s3_resume = (iparams->flags & VB_INIT_FLAG_S3_RESUME ? 1 : 0);
@@ -327,7 +331,14 @@ VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams)
if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) &&
(iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) {
VbNvSet(&vnc, VBNV_OPROM_NEEDED, 0);
- retval = VBERROR_VGA_OPROM_MISMATCH;
+ /*
+ * If this is a system with slow EC update then don't
+ * reboot immediately in case VGA option ROM is still
+ * needed to display an update screen. The reboot will
+ * be requested after EC software sync is complete.
+ */
+ if (!(iparams->flags & VB_INIT_FLAG_EC_SLOW_UPDATE))
+ retval = VBERROR_VGA_OPROM_MISMATCH;
VBDEBUG(("VbInit() has oprom, doesn't need it\n"));
}
}
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 0b2f941e..0609b55b 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -802,6 +802,18 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams)
if (in_rw) {
if (need_update) {
/*
+ * Check if BIOS should also load VGA Option ROM when
+ * rebooting to save another reboot if possible.
+ */
+ if ((shared->flags & VBSD_EC_SLOW_UPDATE) &&
+ (shared->flags & VBSD_OPROM_MATTERS) &&
+ !(shared->flags & VBSD_OPROM_LOADED)) {
+ VBDEBUG(("VbEcSoftwareSync() - Reboot to "
+ "load VGA Option ROM\n"));
+ VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
+ }
+
+ /*
* EC is running the wrong RW image. Reboot the EC to
* RO so we can update it on the next boot.
*/
@@ -821,10 +833,16 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams)
if (shared->flags & VBSD_EC_SLOW_UPDATE) {
VBDEBUG(("VbEcSoftwareSync() - "
"EC is slow. Show WAIT screen.\n"));
- /*
- * FIXME(crosbug.com/p/12257): Ensure the VGA Option
- * ROM is loaded!
- */
+
+ /* Ensure the VGA Option ROM is loaded */
+ if ((shared->flags & VBSD_OPROM_MATTERS) &&
+ !(shared->flags & VBSD_OPROM_LOADED)) {
+ VBDEBUG(("VbEcSoftwareSync() - Reboot to "
+ "load VGA Option ROM\n"));
+ VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
+ return VBERROR_VGA_OPROM_MISMATCH;
+ }
+
VbDisplayScreen(cparams, VB_SCREEN_WAIT, 0, &vnc);
}
@@ -890,6 +908,23 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams)
return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
}
+ /*
+ * Reboot to unload VGA Option ROM if:
+ * - RW update was done
+ * - the system is NOT in developer mode
+ * - the system has slow EC update flag set
+ * - the VGA Option ROM was needed and loaded
+ */
+ if (need_update &&
+ !(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
+ (shared->flags & VBSD_EC_SLOW_UPDATE) &&
+ (shared->flags & VBSD_OPROM_MATTERS) &&
+ (shared->flags & VBSD_OPROM_LOADED)) {
+ VBDEBUG(("VbEcSoftwareSync() - Reboot to "
+ "unload VGA Option ROM\n"));
+ return VBERROR_VGA_OPROM_MISMATCH;
+ }
+
VBDEBUG(("VbEcSoftwareSync() in RW; done\n"));
return VBERROR_SUCCESS;
}
@@ -939,18 +974,31 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
/* Do EC software sync if necessary */
if ((shared->flags & VBSD_EC_SOFTWARE_SYNC) &&
!(cparams->gbb->flags & GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC)) {
+ int oprom_mismatch = 0;
+
retval = VbEcSoftwareSync(0, cparams);
- if (retval != VBERROR_SUCCESS)
+ /* Save reboot requested until after possible PD sync */
+ if (retval == VBERROR_VGA_OPROM_MISMATCH)
+ oprom_mismatch = 1;
+ else if (retval != VBERROR_SUCCESS)
goto VbSelectAndLoadKernel_exit;
#ifdef PD_SYNC
if (!(cparams->gbb->flags &
GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC)) {
retval = VbEcSoftwareSync(1, cparams);
- if (retval != VBERROR_SUCCESS)
+ if (retval == VBERROR_VGA_OPROM_MISMATCH)
+ oprom_mismatch = 1;
+ else if (retval != VBERROR_SUCCESS)
goto VbSelectAndLoadKernel_exit;
}
#endif
+
+ /* Request reboot to unload VGA Option ROM */
+ if (oprom_mismatch) {
+ retval = VBERROR_VGA_OPROM_MISMATCH;
+ goto VbSelectAndLoadKernel_exit;
+ }
}
/* Read kernel version from the TPM. Ignore errors in recovery mode. */