summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2018-01-29 15:55:51 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-01-31 18:00:55 -0800
commit45b04f6d55465e90880e3308803d9c9d72f66671 (patch)
tree5074a92eb072b7f6edcebb7bd9f2bcf6e17aa0f4
parentc034c45873bf3ecedfb1f81be40a8d40ffededdd (diff)
downloadvboot-45b04f6d55465e90880e3308803d9c9d72f66671.tar.gz
detachables: Refactor BROKEN screen handling, add OPTIONS menu to it
This patch factors the code handling the BROKEN screen out of the recovery_ui() function since it's already pretty much a completely separate piece anyway. It is also rewritten to more closely match the other UI loops and to use the same OPTIONS menu that allows language and debug info access as the existing manual recovery UI. BRANCH=None BUG=b:64400036 TEST=make runtests, boot Scarlet in non-manual recovery mode and play with OPTIONS menu. Also check manual recovery mode menu again, and confirm that language selections and recovery reasons persist when initiating manual recovery from the BROKEN screen. Change-Id: Ib680c4e30d728c16a3661041d9b2987648e592e3 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/892280 Reviewed-by: Furquan Shaikh <furquan@chromium.org>
-rw-r--r--firmware/lib/vboot_ui_menu.c87
1 files changed, 45 insertions, 42 deletions
diff --git a/firmware/lib/vboot_ui_menu.c b/firmware/lib/vboot_ui_menu.c
index 8e11bc03..bdd5686d 100644
--- a/firmware/lib/vboot_ui_menu.c
+++ b/firmware/lib/vboot_ui_menu.c
@@ -230,7 +230,9 @@ static VbError_t enter_language_menu(struct vb2_context *ctx)
static VbError_t enter_recovery_base_screen(struct vb2_context *ctx)
{
- if (usb_nogood)
+ if (!vb2_allow_recovery(vb2_get_sd(ctx)->vbsd->flags))
+ vb2_change_menu(VB_MENU_RECOVERY_BROKEN, 0);
+ else if (usb_nogood)
vb2_change_menu(VB_MENU_RECOVERY_NO_GOOD, 0);
else
vb2_change_menu(VB_MENU_RECOVERY_INSERT, 0);
@@ -277,8 +279,19 @@ static VbError_t debug_info_action(struct vb2_context *ctx)
/* Action when selecting a language entry in the language menu. */
static VbError_t language_action(struct vb2_context *ctx)
{
+ VbSharedDataHeader *vbsd = vb2_get_sd(ctx)->vbsd;
+
+ /* Write selected language ID back to NVRAM. */
vb2_nv_set(ctx, VB2_NV_LOCALIZATION_INDEX, current_menu_idx);
+ /*
+ * Non-manual recovery mode is meant to be left via hard reset (into
+ * manual recovery mode). Need to commit NVRAM changes immediately.
+ */
+ if (vbsd->recovery_reason && !vb2_allow_recovery(vbsd->flags))
+ vb2_nv_commit(ctx);
+
+ /* Return to previous menu. */
switch (prev_menu) {
case VB_MENU_DEV_WARNING:
return enter_dev_warning_menu(ctx);
@@ -714,6 +727,32 @@ VbError_t VbBootDeveloperMenu(struct vb2_context *ctx)
return retval;
}
+/* Main function that handles non-manual recovery (BROKEN) menu functionality */
+static VbError_t broken_ui(struct vb2_context *ctx)
+{
+ VbSharedDataHeader *vbsd = vb2_get_sd(ctx)->vbsd;
+
+ /*
+ * Temporarily stash recovery reason in subcode so we'll still know what
+ * to display if the user reboots into manual recovery from here. Commit
+ * immediately since the user may hard-reset out of here.
+ */
+ VB2_DEBUG("saving recovery reason (%#x)\n", vbsd->recovery_reason);
+ vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, vbsd->recovery_reason);
+ vb2_nv_commit(ctx);
+
+ enter_recovery_base_screen(ctx);
+
+ /* Loop and wait for the user to reset or shut down. */
+ VB2_DEBUG("waiting for manual recovery\n");
+ while (1) {
+ uint32_t key = VbExKeyboardRead();
+ VbError_t ret = vb2_handle_menu_input(ctx, key, 0);
+ if (ret != VBERROR_KEEP_LOOPING)
+ return ret;
+ }
+}
+
/* Delay in recovery mode */
#define REC_DISK_DELAY 1000 /* Check disks every 1s */
#define REC_KEY_DELAY 20 /* Check keys every 20ms */
@@ -727,50 +766,13 @@ VbError_t VbBootDeveloperMenu(struct vb2_context *ctx)
*/
static VbError_t recovery_ui(struct vb2_context *ctx)
{
- VbSharedDataHeader *vbsd = vb2_get_sd(ctx)->vbsd;
uint32_t key;
uint32_t key_flags;
VbError_t ret;
int i;
- if (!vb2_allow_recovery(vbsd->flags)) {
- /*
- * We have to save the reason here so that it will survive
- * coming up three-finger-salute. We're saving it in
- * VB2_RECOVERY_SUBCODE to avoid a recovery loop.
- * If we save the reason in VB2_RECOVERY_REQUEST, we will come
- * back here, thus, we won't be able to give a user a chance to
- * reboot to workaround a boot hiccup.
- */
- VB2_DEBUG("saving recovery reason (%#x)\n",
- vbsd->recovery_reason);
- vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE,
- vbsd->recovery_reason);
- /*
- * Commit NV now, because it won't get saved if the user forces
- * manual recovery via the three-finger salute.
- */
- vb2_nv_commit(ctx);
-
- VbDisplayScreen(ctx, VB_SCREEN_OS_BROKEN, 0);
- vb2_change_menu(VB_MENU_RECOVERY_BROKEN, 0);
- VB2_DEBUG("waiting for manual recovery\n");
- while (1) {
- key = VbExKeyboardRead();
- if (key == VB_BUTTON_POWER_SHORT_PRESS)
- return VBERROR_SHUTDOWN_REQUESTED;
- else {
- VbCheckDisplayKey(ctx, key);
- if (VbWantShutdownMenu(ctx))
- return VBERROR_SHUTDOWN_REQUESTED;
- }
- VbExSleepMs(REC_KEY_DELAY);
- }
- }
-
/* Loop and wait for a recovery image */
VB2_DEBUG("waiting for a recovery image\n");
-
usb_nogood = -1;
while (1) {
VB2_DEBUG("attempting to load kernel2\n");
@@ -786,7 +788,7 @@ static VbError_t recovery_ui(struct vb2_context *ctx)
VB2_RECOVERY_NOT_REQUESTED);
if (VBERROR_SUCCESS == ret)
- break; /* Found a recovery kernel */
+ return ret; /* Found a recovery kernel */
if (usb_nogood != (ret != VBERROR_NO_DISK_FOUND)) {
/* USB state changed, force back to base screen */
@@ -814,8 +816,6 @@ static VbError_t recovery_ui(struct vb2_context *ctx)
VbExSleepMs(REC_KEY_DELAY);
}
}
-
- return VBERROR_SUCCESS;
}
/* Recovery mode entry point. */
@@ -824,7 +824,10 @@ VbError_t VbBootRecoveryMenu(struct vb2_context *ctx)
VbError_t retval = vb2_init_menus(ctx);
if (VBERROR_SUCCESS != retval)
return retval;
- retval = recovery_ui(ctx);
+ if (vb2_allow_recovery(vb2_get_sd(ctx)->vbsd->flags))
+ retval = recovery_ui(ctx);
+ else
+ retval = broken_ui(ctx);
VbDisplayScreen(ctx, VB_SCREEN_BLANK, 0);
return retval;
}