summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShelley Chen <shchen@chromium.org>2016-12-27 14:10:26 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-01-18 19:17:53 -0800
commit755bf33ad1081322cff612a531b3edc74ecfcb3c (patch)
treea65864b445e92f0d4fd256eacaa6528659cab871
parent71c6c033f9de1ec9d9f7c1321bb996ee9fd14199 (diff)
downloadvboot-755bf33ad1081322cff612a531b3edc74ecfcb3c.tar.gz
firmware: Add recovery menu support for detachables
Adding in basic menu support (using arrow keys) for detachables. This is specifically for the recovery menu. BUG=chrome-os-partner:61275 BRANCH=None TEST=reboot into recovery and try booting into developer mode. Change-Id: I9596cde62f2748928b4b796bde0a0226dc981235 Signed-off-by: Shelley Chen <shchen@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/424354
-rw-r--r--firmware/lib/vboot_ui_menu.c240
1 files changed, 176 insertions, 64 deletions
diff --git a/firmware/lib/vboot_ui_menu.c b/firmware/lib/vboot_ui_menu.c
index 7fa44edd..252d27e7 100644
--- a/firmware/lib/vboot_ui_menu.c
+++ b/firmware/lib/vboot_ui_menu.c
@@ -162,6 +162,8 @@ typedef enum _VB_MENU {
VB_MENU_DEV_WARNING,
VB_MENU_DEV,
VB_MENU_TO_NORM,
+ VB_MENU_RECOVERY,
+ VB_MENU_TO_DEV,
VB_MENU_COUNT,
} VB_MENU;
@@ -193,6 +195,22 @@ typedef enum _VB_TO_NORM_MENU {
VB_TO_NORM_COUNT,
} VB_TO_NORM_MENU;
+typedef enum _VB_RECOVERY_MENU {
+ VB_RECOVERY_TO_DEV,
+ VB_RECOVERY_DBG_INFO,
+ VB_RECOVERY_POWER_OFF,
+ VB_RECOVERY_LANGUAGE,
+ VB_RECOVERY_COUNT,
+} VB_RECOVERY_MENU;
+
+typedef enum _VB_TO_DEV_MENU {
+ VB_TO_DEV_CONFIRM,
+ VB_TO_DEV_CANCEL,
+ VB_TO_DEV_POWER_OFF,
+ VB_TO_DEV_LANGUAGE,
+ VB_TO_DEV_COUNT,
+} VB_TO_DEV_MENU;
+
static VB_MENU current_menu = VB_MENU_DEV_WARNING;
static int current_menu_idx = 0;
static int selected = 0;
@@ -223,6 +241,20 @@ static char *to_normal_menu[] = {
"Language\n"
};
+static char *recovery_menu[] = {
+ "Enable developer mode\n",
+ "Show Debug Info\n",
+ "Power Off\n",
+ "Language\n"
+};
+
+static char *to_dev_menu[] = {
+ "Confirm enabling developer mode\n",
+ "Cancel\n",
+ "Power Off\n",
+ "Language\n"
+};
+
// function that gets the current menu string array and size.
// can set menu_array to NULL and only return string size.
VbError_t vb2_get_current_menu_size(VB_MENU menu, char ***menu_array, int *size)
@@ -242,6 +274,14 @@ VbError_t vb2_get_current_menu_size(VB_MENU menu, char ***menu_array, int *size)
*size = VB_TO_NORM_COUNT;
temp_menu = to_normal_menu;
break;
+ case VB_MENU_RECOVERY:
+ *size = VB_RECOVERY_COUNT;
+ temp_menu = recovery_menu;
+ break;
+ case VB_MENU_TO_DEV:
+ *size = VB_TO_DEV_COUNT;
+ temp_menu = to_dev_menu;
+ break;
default:
*size = 0;
return VBERROR_UNKNOWN;
@@ -286,7 +326,7 @@ VbError_t vb2_print_current_menu()
}
VB2_DEBUG("%s", m_str);
- return VbExDisplayText(0,0,m_str);
+ return VbExDisplayText(0,50,m_str);
}
// This updates current_menu and current_menu_idx,
@@ -381,6 +421,46 @@ VbError_t vb2_update_menu()
break;
}
break;
+ case VB_MENU_RECOVERY:
+ switch(current_menu_idx) {
+ case VB_RECOVERY_TO_DEV:
+ // switch to TO_DEV menu
+ current_menu = VB_MENU_TO_DEV;
+ current_menu_idx = 0;
+ selected = 0;
+ break;
+ case VB_RECOVERY_DBG_INFO:
+ break;
+ case VB_RECOVERY_POWER_OFF:
+ ret = VBERROR_SHUTDOWN_REQUESTED;
+ break;
+ case VB_RECOVERY_LANGUAGE:
+ break;
+ default:
+ // invalid menu item. don't update anything
+ break;
+ }
+ break;
+ case VB_MENU_TO_DEV:
+ switch(current_menu_idx) {
+ case VB_TO_DEV_CONFIRM:
+ // confirm enabling dev mode
+ break;
+ case VB_TO_DEV_CANCEL:
+ current_menu = VB_MENU_RECOVERY;
+ current_menu_idx = 0;
+ selected = 0;
+ break;
+ case VB_TO_DEV_POWER_OFF:
+ ret = VBERROR_SHUTDOWN_REQUESTED;
+ break;
+ case VB_TO_DEV_LANGUAGE:
+ break;
+ default:
+ // invalid menu item. don't update anything.
+ break;
+ }
+ break;
default:
VB2_DEBUG("Current Menu Invalid!");
}
@@ -662,8 +742,10 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
uint32_t retval;
uint32_t key;
int i;
+ VbError_t ret;
+ int menu_size;
- VBDEBUG(("VbBootRecoveryMenu() start\n"));
+ VB2_DEBUG("VbBootRecoveryMenu() start\n");
/*
* If the dev-mode switch is off and the user didn't press the recovery
@@ -681,8 +763,8 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
* back here, thus, we won't be able to give a user a chance to
* reboot to workaround boot hicups.
*/
- VBDEBUG(("VbBootRecoveryMenu() saving recovery reason (%#x)\n",
- shared->recovery_reason));
+ VB2_DEBUG("VbBootRecoveryMenu() saving recovery reason (%#x)\n",
+ shared->recovery_reason);
vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE,
shared->recovery_reason);
/*
@@ -692,7 +774,7 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
vb2_nv_commit(ctx);
VbDisplayScreen(ctx, cparams, VB_SCREEN_OS_BROKEN, 0);
- VBDEBUG(("VbBootRecoveryMenu() waiting for manual recovery\n"));
+ VB2_DEBUG("VbBootRecoveryMenu() waiting for manual recovery\n");
while (1) {
VbCheckDisplayKey(ctx, cparams, VbExKeyboardRead());
if (VbWantShutdownMenu(cparams->gbb->flags))
@@ -702,9 +784,13 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
}
/* Loop and wait for a recovery image */
- VBDEBUG(("VbBootRecoveryMenu() waiting for a recovery image\n"));
+ VB2_DEBUG("VbBootRecoveryMenu() waiting for a recovery image\n");
+ // initialize menu to recovery menu.
+ current_menu = VB_MENU_RECOVERY;
+ current_menu_idx = 0;
+
while (1) {
- VBDEBUG(("VbBootRecoveryMenu() attempting to load kernel2\n"));
+ VB2_DEBUG("VbBootRecoveryMenu() attempting to load kernel2\n");
retval = VbTryLoadKernel(ctx, cparams, VB_DISK_FLAG_REMOVABLE);
/*
@@ -723,6 +809,10 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
VB_SCREEN_RECOVERY_INSERT :
VB_SCREEN_RECOVERY_NO_GOOD,
0);
+ if (current_menu != VB_MENU_RECOVERY ||
+ current_menu_idx != VB_RECOVERY_DBG_INFO) {
+ vb2_print_current_menu();
+ }
/*
* Scan keyboard more frequently than media, since x86
@@ -730,72 +820,94 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
*/
for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
key = VbExKeyboardRead();
- /*
- * We might want to enter dev-mode from the Insert
- * screen if all of the following are true:
- * - user pressed Ctrl-D
- * - we can honor the virtual dev switch
- * - not already in dev mode
- * - user forced recovery mode
- * - EC isn't pwned
- */
- if (key == 0x04 &&
- shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
- !(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
- (shared->flags & VBSD_BOOT_REC_SWITCH_ON) &&
- VbExTrustEC(0)) {
- if (!(shared->flags &
- VBSD_BOOT_REC_SWITCH_VIRTUAL) &&
- VbExGetSwitches(
- VB_INIT_FLAG_REC_BUTTON_PRESSED)) {
- /*
- * Is the recovery button stuck? In
- * any case we don't like this. Beep
- * and ignore.
- */
- VBDEBUG(("%s() - ^D but rec switch "
- "is pressed\n", __func__));
- VbExBeep(120, 400);
- continue;
+ switch (key) {
+ case 0:
+ /* nothing pressed */
+ break;
+ case VB_KEY_UP:
+ VB2_DEBUG("VbBootRecoveryMenu() - pressed key VB_KEY_UP\n");
+ vb2_get_current_menu_size(current_menu, NULL, &menu_size);
+ current_menu_idx = (current_menu_idx+menu_size-1) % menu_size;
+ vb2_print_current_menu();
+ break;
+ case VB_KEY_DOWN:
+ VB2_DEBUG("VbBootRecoveryMenu() - pressed key VB_KEY_DOWN\n");
+ vb2_get_current_menu_size(current_menu, NULL, &menu_size);
+ current_menu_idx = (current_menu_idx+1) % menu_size;
+ vb2_print_current_menu();
+ break;
+ case VB_KEY_RIGHT:
+ // temporarily using this as a stand in for
+ // power button until get power button bypassed
+ VB2_DEBUG("VbBootRecoveryMenu() - pressed key VB_KEY_RIGHT (SELECT)\n");
+ selected = 1;
+
+ ret = vb2_update_menu();
+ if (current_menu != VB_MENU_RECOVERY ||
+ current_menu_idx != VB_RECOVERY_DBG_INFO) {
+ vb2_print_current_menu();
}
- /* Ask the user to confirm entering dev-mode */
- VbDisplayScreen(ctx, cparams,
- VB_SCREEN_RECOVERY_TO_DEV,
- 0);
- /* SPACE means no... */
- uint32_t vbc_flags =
- VB_CONFIRM_SPACE_MEANS_NO |
- VB_CONFIRM_MUST_TRUST_KEYBOARD;
- switch (VbUserConfirmsMenu(ctx, cparams,
- vbc_flags)) {
- case 1:
- VBDEBUG(("%s() Enabling dev-mode...\n",
- __func__));
+ // probably shutting down
+ if (ret != VBERROR_SUCCESS) {
+ VB2_DEBUG("VbBootRecoveryMenu() - update_menu - shutting down!\n");
+ return ret;
+ }
+
+ // nothing selected, skip everything else.
+ if (selected == 0)
+ break;
+
+ /* Display debug information */
+ if (current_menu == VB_MENU_RECOVERY &&
+ current_menu_idx == VB_RECOVERY_DBG_INFO) {
+ VbDisplayDebugInfo(ctx, cparams);
+ }
+
+ /* Confirm going into developer mode */
+ /*
+ * We might want to enter dev-mode from the Insert
+ * screen if all of the following are true:
+ * - user pressed Ctrl-D
+ * - we can honor the virtual dev switch
+ * - not already in dev mode
+ * - user forced recovery mode
+ * - EC isn't pwned
+ */
+ // TODO: let's put an error here if we're
+ // already in dev mode.
+ if (current_menu == VB_MENU_TO_DEV &&
+ current_menu_idx == 0 &&
+ shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
+ !(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
+ (shared->flags & VBSD_BOOT_REC_SWITCH_ON) &&
+ VbExTrustEC(0)) {
+ if (!(shared->flags &
+ VBSD_BOOT_REC_SWITCH_VIRTUAL) &&
+ VbExGetSwitches(
+ VB_INIT_FLAG_REC_BUTTON_PRESSED)) {
+ /*
+ * Is the recovery button stuck? In
+ * any case we don't like this. Beep
+ * and ignore.
+ */
+ VB2_DEBUG("%s() - ^D but rec switch "
+ "is pressed\n", __func__);
+ VbExBeep(120, 400);
+ continue;
+ }
+
+ VB2_DEBUG("%s() Enabling dev-mode...\n",
+ __func__);
if (TPM_SUCCESS != SetVirtualDevMode(1))
return VBERROR_TPM_SET_BOOT_MODE_STATE;
- VBDEBUG(("%s() Reboot so it will take "
- "effect\n", __func__));
+ VB2_DEBUG("%s() Reboot so it will take "
+ "effect\n", __func__);
if (VbExGetSwitches
(VB_INIT_FLAG_ALLOW_USB_BOOT))
VbAllowUsbBootMenu(ctx);
return VBERROR_REBOOT_REQUIRED;
- case -1:
- VBDEBUG(("%s() - Shutdown requested\n",
- __func__));
- return VBERROR_SHUTDOWN_REQUESTED;
- default: /* zero, actually */
- VBDEBUG(("%s() - Not enabling "
- "dev-mode\n", __func__));
- /*
- * Jump out of the outer loop to
- * refresh the display quickly.
- */
- i = 4;
- break;
}
- } else {
- VbCheckDisplayKey(ctx, cparams, key);
}
if (VbWantShutdownMenu(cparams->gbb->flags))
return VBERROR_SHUTDOWN_REQUESTED;