mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-24 16:57:21 +00:00
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
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user