summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShelley Chen <shchen@chromium.org>2017-07-31 14:28:42 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-08-14 20:37:45 -0700
commit8c4b828502d8c6c7112286720dddfd30c92a968e (patch)
tree051cd3d48aef4bd58d8ca91862868466b2881cfd
parent3f24b902e473777f59c35673f645a6e05f19977d (diff)
downloadvboot-8c4b828502d8c6c7112286720dddfd30c92a968e.tar.gz
detachables: Skip "Enable Developer Mode" in DEV mode
When DUT is already in dev mode, don't let user select the "Enable Developer Mode" selection in the menu. Add disabled_idx_mask to VbExDisplayMenu API to allow for disabling of menu items in the future if needed. BUG=b:63078243, b:35585623 BRANCH=None TEST=reboot into recovery with DUT already in dev mode. Make sure can't scroll to "Enable Developer Mode: entry. reboot into recovery with DUT in normal mode. Make sure "Enable Developer Mode" entry is selectable. CQ-DEPEND=CL:565335 Change-Id: Ic71fe6aa2e41337787a0c2278f729356edb155fd Signed-off-by: Shelley Chen <shchen@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/598430 Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r--firmware/include/vboot_api.h15
-rw-r--r--firmware/lib/include/vboot_display.h3
-rw-r--r--firmware/lib/vboot_display.c10
-rw-r--r--firmware/lib/vboot_ui_menu.c176
-rw-r--r--firmware/stub/vboot_api_stub.c3
5 files changed, 128 insertions, 79 deletions
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index 049ec90f..ccd65961 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -808,13 +808,18 @@ VbError_t VbExDisplayScreen(uint32_t screen_type, uint32_t locale);
/**
* Display a predefined menu screen; see VB_SCREEN_* for valid screens.
*
- * This is a backup method of screen display, intended for use if the GBB does
- * not contain a full set of bitmaps. It is acceptable for the backup screen
- * to be simple ASCII text such as "NO GOOD" or "INSERT"; these screens should
- * only be seen during development.
+ * @param screen_type ID of screen to draw
+ * @param locale language to display
+ * @param selected_index Index of menu item that is currently selected.
+ * @param disabled_idx_mask Bitmap for enabling/disabling certain menu items.
+ * each bit corresponds to the menu item's index.
+ * @param redraw_base Setting 1 will force a full redraw of the screen
+ *
+ * @return VBERROR_SUCCESS or error code on error.
*/
VbError_t VbExDisplayMenu(uint32_t screen_type, uint32_t locale,
- uint32_t selected_index, uint32_t redraw_base);
+ uint32_t selected_index, uint32_t disabled_idx_mask,
+ uint32_t redraw_base);
/**
* Write an image to the display, with the upper left corner at the specified
diff --git a/firmware/lib/include/vboot_display.h b/firmware/lib/include/vboot_display.h
index 664bc195..2f237533 100644
--- a/firmware/lib/include/vboot_display.h
+++ b/firmware/lib/include/vboot_display.h
@@ -20,7 +20,8 @@ VbError_t VbDisplayScreenFromGBB(struct vb2_context *ctx,
VbError_t VbDisplayScreen(struct vb2_context *ctx, VbCommonParams *cparams,
uint32_t screen, int force);
VbError_t VbDisplayMenu(struct vb2_context *ctx, VbCommonParams *cparams,
- uint32_t screen, int force, uint32_t selected_index);
+ uint32_t screen, int force, uint32_t selected_index,
+ uint32_t disabled_idx_mask);
VbError_t VbDisplayDebugInfo(struct vb2_context *ctx, VbCommonParams *cparams);
VbError_t VbCheckDisplayKey(struct vb2_context *ctx, VbCommonParams *cparams,
uint32_t key);
diff --git a/firmware/lib/vboot_display.c b/firmware/lib/vboot_display.c
index f3cb4d6e..24ac0725 100644
--- a/firmware/lib/vboot_display.c
+++ b/firmware/lib/vboot_display.c
@@ -23,6 +23,7 @@
static uint32_t disp_current_screen = VB_SCREEN_BLANK;
static uint32_t disp_current_index = 0;
+static uint32_t disp_disabled_idx_mask = 0;
static uint32_t disp_width = 0, disp_height = 0;
__attribute__((weak))
@@ -375,7 +376,7 @@ VbError_t VbDisplayScreen(struct vb2_context *ctx,
VbError_t VbDisplayMenu(struct vb2_context *ctx,
VbCommonParams *cparams, uint32_t screen, int force,
- uint32_t selected_index)
+ uint32_t selected_index, uint32_t disabled_idx_mask)
{
uint32_t locale;
VbError_t rv;
@@ -400,7 +401,8 @@ VbError_t VbDisplayMenu(struct vb2_context *ctx,
/* Read the locale last saved */
locale = vb2_nv_get(ctx, VB2_NV_LOCALIZATION_INDEX);
- rv = VbExDisplayMenu(screen, locale, selected_index, redraw_base_screen);
+ rv = VbExDisplayMenu(screen, locale, selected_index,
+ disabled_idx_mask, redraw_base_screen);
if (rv == VBERROR_SUCCESS) {
/*
@@ -409,6 +411,7 @@ VbError_t VbDisplayMenu(struct vb2_context *ctx,
*/
disp_current_screen = screen;
disp_current_index = selected_index;
+ disp_disabled_idx_mask = disabled_idx_mask;
}
return rv;
@@ -613,7 +616,8 @@ VbError_t VbDisplayDebugInfo(struct vb2_context *ctx, VbCommonParams *cparams)
* highlighted. On a non-detachable screen, this will be a
* no-op.
*/
- VbDisplayMenu(ctx, cparams, disp_current_screen, 1, disp_current_index);
+ VbDisplayMenu(ctx, cparams, disp_current_screen, 1,
+ disp_current_index, disp_disabled_idx_mask);
/* Add hardware ID */
VbRegionReadHWID(cparams, hwid, sizeof(hwid));
diff --git a/firmware/lib/vboot_ui_menu.c b/firmware/lib/vboot_ui_menu.c
index 29c561b5..d7c647ca 100644
--- a/firmware/lib/vboot_ui_menu.c
+++ b/firmware/lib/vboot_ui_menu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
@@ -226,6 +226,7 @@ static VB_MENU current_menu = VB_MENU_DEV_WARNING;
static VB_MENU prev_menu = VB_MENU_DEV_WARNING;
static int current_menu_idx = VB_WARN_POWER_OFF;
static int selected = 0;
+static int disabled_idx_mask = 0;
static uint32_t default_boot = VB2_DEV_DEFAULT_BOOT_DISK;
// TODO: add in consts
@@ -376,7 +377,8 @@ VbError_t vb2_draw_current_screen(struct vb2_context *ctx,
screen = VB_MENU_TO_SCREEN_MAP[current_menu];
else
return VBERROR_UNKNOWN;
- return VbDisplayMenu(ctx, cparams, screen, 0, current_menu_idx);
+ return VbDisplayMenu(ctx, cparams, screen, 0,
+ current_menu_idx, disabled_idx_mask);
}
/**
@@ -564,41 +566,38 @@ VbError_t vb2_update_menu(struct vb2_context *ctx)
}
break;
case VB_MENU_LANGUAGES:
- switch(current_menu_idx) {
+ /*
+ * Assume that we selected a language. Go to previous
+ * menu. Purposely bypassing vb2_set_menu_items() here
+ * because need to do in different order.
+ */
+ current_menu = prev_menu;
+ prev_menu = VB_MENU_LANGUAGES;
+ /* default to power off index */
+ switch (current_menu) {
+ case VB_MENU_DEV_WARNING:
+ current_menu_idx = VB_WARN_POWER_OFF;
+ break;
+ case VB_MENU_DEV:
+ current_menu_idx = VB_DEV_POWER_OFF;
+ break;
+ case VB_MENU_TO_NORM:
+ current_menu_idx = VB_TO_NORM_POWER_OFF;
+ break;
+ case VB_MENU_RECOVERY:
+ current_menu_idx = VB_RECOVERY_POWER_OFF;
+ break;
+ case VB_MENU_TO_DEV:
+ current_menu_idx = VB_TO_DEV_POWER_OFF;
+ break;
default:
- /*
- * Assume that we selected a language. Go to previous
- * menu. Purposely bypassing vb2_set_menu_items() here
- * because need to do in different order.
- */
- current_menu = prev_menu;
- prev_menu = VB_MENU_LANGUAGES;
- /* default to power off index */
- switch (current_menu) {
- case VB_MENU_DEV_WARNING:
- current_menu_idx = VB_WARN_POWER_OFF;
- break;
- case VB_MENU_DEV:
- current_menu_idx = VB_DEV_POWER_OFF;
- break;
- case VB_MENU_TO_NORM:
- current_menu_idx = VB_TO_NORM_POWER_OFF;
- break;
- case VB_MENU_RECOVERY:
- current_menu_idx = VB_RECOVERY_POWER_OFF;
- break;
- case VB_MENU_TO_DEV:
- current_menu_idx = VB_TO_DEV_POWER_OFF;
- break;
- default:
- current_menu_idx = 0;
- break;
- }
- selected = current_menu_idx;
+ current_menu_idx = 0;
break;
}
+ selected = current_menu_idx;
+ break;
default:
- VB2_DEBUG("Current Menu Invalid!");
+ VB2_DEBUG("Current Menu Invalid! 0x%x\n", current_menu_idx);
}
return ret;
}
@@ -625,6 +624,69 @@ VbError_t vb2_update_locale(struct vb2_context *ctx) {
}
/**
+ * Adjust the disabled_idx_mask based on current menu and settings.
+ *
+ * @param flags flag to check for dev/normal mode.
+ * @return VBERROR_SUCCESS
+ */
+VbError_t vb2_set_disabled_idx_mask(uint32_t flags) {
+ /* Disable "Enable Developer Mode" menu item */
+ disabled_idx_mask = 0;
+ if (current_menu == VB_MENU_RECOVERY &&
+ (flags & VBSD_BOOT_DEV_SWITCH_ON)) {
+ disabled_idx_mask |= 1 << VB_RECOVERY_TO_DEV;
+ }
+ return VBERROR_SUCCESS;
+}
+
+/**
+ * Updates current_menu_idx upon an up/down key press, taking into
+ * account disabled indices (from disabled_idx_mask). The cursor
+ * will not wrap, meaning that we block on the 0 or max index when
+ * we hit the ends of the menu.
+ *
+ * @param cparams common params
+ * @param key VOL_KEY_UP = increase index selection
+ * VOL_KEY_DOWN = decrease index selection.
+ * Every other key has no effect now.
+ */
+void vb2_update_selection(VbCommonParams *cparams, uint32_t key) {
+ int idx;
+ uint32_t menu_size;
+
+ if (current_menu == VB_MENU_LANGUAGES) {
+ VbGetLocalizationCount(cparams, &menu_size);
+ } else {
+ vb2_get_current_menu_size(current_menu,
+ NULL, &menu_size);
+ }
+
+ switch (key) {
+ case VB_KEY_UP:
+ idx = current_menu_idx - 1;
+ while (idx >= 0 &&
+ ((1 << idx) & disabled_idx_mask))
+ idx--;
+ /* Only update if idx is valid */
+ if (idx >= 0)
+ current_menu_idx = idx;
+ break;
+ case VB_KEY_DOWN:
+ idx = current_menu_idx + 1;
+ while (idx < menu_size &&
+ ((1 << idx) & disabled_idx_mask))
+ idx++;
+ /* Only update if idx is valid */
+ if (idx < menu_size)
+ current_menu_idx = idx;
+ break;
+ default:
+ /* Do not update anything */
+ break;
+ }
+}
+
+/**
* Main function that handles developer warning menu functionality
*
* @param ctx Vboot2 context
@@ -634,10 +696,8 @@ VbError_t vb2_update_locale(struct vb2_context *ctx) {
VbError_t vb2_developer_menu(struct vb2_context *ctx, VbCommonParams *cparams)
{
GoogleBinaryBlockHeader *gbb = cparams->gbb;
-#if defined(VBOOT_DEBUG)
VbSharedDataHeader *shared =
(VbSharedDataHeader *)cparams->shared_data_blob;
-#endif
uint32_t disable_dev_boot = 0;
uint32_t use_usb = 0;
@@ -646,7 +706,6 @@ VbError_t vb2_developer_menu(struct vb2_context *ctx, VbCommonParams *cparams)
VbAudioContext *audio = 0;
VbError_t ret;
-
VB2_DEBUG("Entering\n");
/* Check if USB booting is allowed */
@@ -712,6 +771,8 @@ VbError_t vb2_developer_menu(struct vb2_context *ctx, VbCommonParams *cparams)
}
}
+
+ vb2_set_disabled_idx_mask(shared->flags);
/* Show the dev mode warning screen */
vb2_draw_current_screen(ctx, cparams);
@@ -721,7 +782,6 @@ VbError_t vb2_developer_menu(struct vb2_context *ctx, VbCommonParams *cparams)
/* We'll loop until we finish the delay or are interrupted */
do {
uint32_t key;
- uint32_t menu_size;
if (VbWantShutdownMenu(gbb->flags)) {
VB2_DEBUG("shutdown requested!\n");
@@ -776,27 +836,14 @@ VbError_t vb2_developer_menu(struct vb2_context *ctx, VbCommonParams *cparams)
break;
case VB_BUTTON_VOL_UP:
case VB_KEY_UP:
- vb2_get_current_menu_size(current_menu,
- NULL, &menu_size);
- /* Do not wrap selection index */
- if (current_menu_idx > 0)
- current_menu_idx--;
+ vb2_update_selection(cparams, key);
vb2_draw_current_screen(ctx, cparams);
/* reset 30 second timer */
audio = VbAudioOpen(cparams);
break;
case VB_BUTTON_VOL_DOWN:
case VB_KEY_DOWN:
- /* Do not wrap selection index */
- if (current_menu == VB_MENU_LANGUAGES) {
- VbGetLocalizationCount(cparams, &menu_size);
- }
- else {
- vb2_get_current_menu_size(current_menu,
- NULL, &menu_size);
- }
- if (current_menu_idx < menu_size-1)
- current_menu_idx++;
+ vb2_update_selection(cparams, key);
vb2_draw_current_screen(ctx, cparams);
/* reset 30 second timer */
audio = VbAudioOpen(cparams);
@@ -812,6 +859,7 @@ VbError_t vb2_developer_menu(struct vb2_context *ctx, VbCommonParams *cparams)
vb2_update_locale(ctx);
ret = vb2_update_menu(ctx);
+ vb2_set_disabled_idx_mask(shared->flags);
/*
* Unfortunately, we need the blanking to get rid of
* artifacts from previous menu printing.
@@ -965,7 +1013,6 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
uint32_t key;
int i;
VbError_t ret;
- uint32_t menu_size;
VB2_DEBUG("start\n");
@@ -1029,6 +1076,8 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
if (VBERROR_SUCCESS == retval)
break; /* Found a recovery kernel */
+ vb2_set_disabled_idx_mask(shared->flags);
+
if (current_menu != VB_MENU_RECOVERY ||
current_menu_idx != VB_RECOVERY_DBG_INFO) {
if (retval == VBERROR_NO_DISK_FOUND)
@@ -1051,24 +1100,12 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
break;
case VB_BUTTON_VOL_UP:
case VB_KEY_UP:
- vb2_get_current_menu_size(current_menu, NULL,
- &menu_size);
- if (current_menu_idx > 0)
- current_menu_idx--;
+ vb2_update_selection(cparams, key);
vb2_draw_current_screen(ctx, cparams);
break;
case VB_BUTTON_VOL_DOWN:
case VB_KEY_DOWN:
- /* Do not wrap selection index */
- if (current_menu == VB_MENU_LANGUAGES) {
- VbGetLocalizationCount(cparams, &menu_size);
- }
- else {
- vb2_get_current_menu_size(current_menu,
- NULL, &menu_size);
- }
- if (current_menu_idx < menu_size-1)
- current_menu_idx++;
+ vb2_update_selection(cparams, key);
vb2_draw_current_screen(ctx, cparams);
break;
case VB_BUTTON_POWER:
@@ -1082,6 +1119,9 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
vb2_update_locale(ctx);
ret = vb2_update_menu(ctx);
+
+ vb2_set_disabled_idx_mask(shared->flags);
+
if (current_menu != VB_MENU_RECOVERY ||
current_menu_idx != VB_RECOVERY_DBG_INFO) {
/*
@@ -1124,8 +1164,6 @@ VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
* - 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 &&
diff --git a/firmware/stub/vboot_api_stub.c b/firmware/stub/vboot_api_stub.c
index 834bff1c..c51cef4b 100644
--- a/firmware/stub/vboot_api_stub.c
+++ b/firmware/stub/vboot_api_stub.c
@@ -52,7 +52,8 @@ VbError_t VbExDisplayScreen(uint32_t screen_type, uint32_t locale)
}
VbError_t VbExDisplayMenu(uint32_t screen_type, uint32_t locale,
- uint32_t selected_index, uint32_t redraw_base)
+ uint32_t selected_index, uint32_t disabled_idx_mask,
+ uint32_t redraw_base)
{
return VBERROR_SUCCESS;
}