/* 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.
 *
 * High-level firmware wrapper API - user interface for RW firmware
 */

#include "2sysincludes.h"
#include "2common.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "2rsa.h"
#include "ec_sync.h"
#include "gbb_access.h"
#include "gbb_header.h"
#include "load_kernel_fw.h"
#include "rollback_index.h"
#include "utility.h"
#include "vb2_common.h"
#include "vboot_api.h"
#include "vboot_audio.h"
#include "vboot_common.h"
#include "vboot_display.h"
#include "vboot_kernel.h"
#include "vboot_ui_common.h"
#include "vboot_ui_menu_private.h"

static const char dev_disable_msg[] =
	"Developer mode is disabled on this device by system policy.\n"
	"For more information, see http://dev.chromium.org/chromium-os/fwmp\n"
	"\n";

static VB_MENU current_menu, prev_menu;
static int current_menu_idx, disabled_idx_mask, usb_nogood, force_redraw;
static uint32_t default_boot;
static uint32_t disable_dev_boot;
static uint32_t altfw_allowed;
static struct vb2_menu menus[];
static const char no_legacy[] = "Legacy boot failed. Missing BIOS?\n";

/**
 * Checks GBB flags against VbExIsShutdownRequested() shutdown request to
 * determine if a shutdown is required.
 *
 * Returns true if a shutdown is required and false if no shutdown is required.
 */
static int VbWantShutdownMenu(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	uint32_t shutdown_request = VbExIsShutdownRequested();

	/* If desired, ignore shutdown request due to lid closure. */
	if (sd->gbb_flags & VB2_GBB_FLAG_DISABLE_LID_SHUTDOWN)
		shutdown_request &= ~VB_SHUTDOWN_REQUEST_LID_CLOSED;

	/*
	 * In detachables, disabling shutdown due to power button.
	 * We are using it for selection instead.
	 */
	shutdown_request &= ~VB_SHUTDOWN_REQUEST_POWER_BUTTON;

	return !!shutdown_request;
}

/* (Re-)Draw the menu identified by current_menu[_idx] to the screen. */
static VbError_t vb2_draw_current_screen(struct vb2_context *ctx) {
	VbError_t ret = VbDisplayMenu(ctx, menus[current_menu].screen,
			force_redraw, current_menu_idx, disabled_idx_mask);
	force_redraw = 0;
	return ret;
}

/* Flash the screen to black to catch user awareness, then redraw menu. */
static void vb2_flash_screen(struct vb2_context *ctx)
{
	VbDisplayScreen(ctx, VB_SCREEN_BLANK, 0, NULL);
	VbExSleepMs(50);
	vb2_draw_current_screen(ctx);
}

static void vb2_log_menu_change(void)
{
	if (menus[current_menu].size)
		VB2_DEBUG("================ %s Menu ================ [ %s ]\n",
			  menus[current_menu].name,
			  menus[current_menu].items[current_menu_idx].text);
	else
		VB2_DEBUG("=============== %s Screen ===============\n",
			  menus[current_menu].name);
}

/**
 * Switch to a new menu (but don't draw it yet).
 *
 * @param new_current_menu:	new menu to set current_menu to
 * @param new_current_menu_idx: new idx to set current_menu_idx to
 */
static void vb2_change_menu(VB_MENU new_current_menu,
			    int new_current_menu_idx)
{
	prev_menu = current_menu;
	current_menu = new_current_menu;

	/* Reconfigure disabled_idx_mask for the new menu */
	disabled_idx_mask = 0;
	/* Disable Network Boot Option */
	if (current_menu == VB_MENU_DEV)
		disabled_idx_mask |= 1 << VB_DEV_NETWORK;
	/* Disable cancel option if enterprise disabled dev mode */
	if (current_menu == VB_MENU_TO_NORM &&
	    disable_dev_boot == 1)
		disabled_idx_mask |= 1 << VB_TO_NORM_CANCEL;

	/* Enable menu items for the selected bootloaders */
	if (current_menu == VB_MENU_ALT_FW) {
		disabled_idx_mask = ~(VbExGetAltFwIdxMask() >> 1);

		/* Make sure 'cancel' is shown even with an invalid mask */
		disabled_idx_mask &= (1 << VB_ALTFW_COUNT) - 1;
	}
	/* We assume that there is at least one enabled item */
	while ((1 << new_current_menu_idx) & disabled_idx_mask)
		new_current_menu_idx++;
	if (new_current_menu_idx < menus[current_menu].size)
		current_menu_idx = new_current_menu_idx;

	vb2_log_menu_change();
}

/************************
 *    Menu Actions      *
 ************************/

/* Boot from internal disk if allowed. */
static VbError_t boot_disk_action(struct vb2_context *ctx)
{
	if (disable_dev_boot) {
		vb2_flash_screen(ctx);
		vb2_error_notify("Developer mode disabled\n", NULL,
				 VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}
	VB2_DEBUG("trying fixed disk\n");
	return VbTryLoadKernel(ctx, VB_DISK_FLAG_FIXED);
}

/* Boot legacy BIOS if allowed and available. */
static VbError_t boot_legacy_action(struct vb2_context *ctx)
{
	if (disable_dev_boot) {
		vb2_flash_screen(ctx);
		vb2_error_notify("Developer mode disabled\n", NULL,
				 VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}

	if (!altfw_allowed) {
		vb2_flash_screen(ctx);
		vb2_error_notify("WARNING: Booting legacy BIOS has not "
				 "been enabled. Refer to the developer"
				 "-mode documentation for details.\n",
				 "Legacy boot is disabled\n",
				 VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}

	vb2_run_altfw(ctx, VB_ALTFW_DEFAULT);
	vb2_flash_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

/* Boot from USB or SD card if allowed and available. */
static VbError_t boot_usb_action(struct vb2_context *ctx)
{
	const char no_kernel[] = "No bootable kernel found on USB/SD.\n";

	if (disable_dev_boot) {
		vb2_flash_screen(ctx);
		vb2_error_notify("Developer mode disabled\n", NULL,
				 VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}

	if (!vb2_nv_get(ctx, VB2_NV_DEV_BOOT_USB) &&
	    !(vb2_get_sd(ctx)->gbb_flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_USB) &&
	    !(vb2_get_fwmp_flags() & FWMP_DEV_ENABLE_USB)) {
		vb2_flash_screen(ctx);
		vb2_error_notify("WARNING: Booting from external media "
				 "(USB/SD) has not been enabled. Refer "
				 "to the developer-mode documentation "
				 "for details.\n",
				 "USB booting is disabled\n",
				 VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}

	if (VBERROR_SUCCESS == VbTryLoadKernel(ctx, VB_DISK_FLAG_REMOVABLE)) {
		VB2_DEBUG("booting USB\n");
		return VBERROR_SUCCESS;
	}

	/* Loading kernel failed. Clear recovery request from that. */
	vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_NOT_REQUESTED);
	vb2_flash_screen(ctx);
	vb2_error_notify(no_kernel, NULL, VB_BEEP_FAILED);
	return VBERROR_KEEP_LOOPING;
}

static VbError_t enter_developer_menu(struct vb2_context *ctx)
{
	int menu_idx;
	switch(default_boot) {
	default:
	case VB2_DEV_DEFAULT_BOOT_DISK:
		menu_idx = VB_DEV_DISK;
		break;
	case VB2_DEV_DEFAULT_BOOT_USB:
		menu_idx = VB_DEV_USB;
		break;
	case VB2_DEV_DEFAULT_BOOT_LEGACY:
		menu_idx = VB_DEV_LEGACY;
		break;
	}
	vb2_change_menu(VB_MENU_DEV, menu_idx);
	vb2_draw_current_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

static VbError_t enter_dev_warning_menu(struct vb2_context *ctx)
{
	vb2_change_menu(VB_MENU_DEV_WARNING, VB_WARN_POWER_OFF);
	vb2_draw_current_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

static VbError_t enter_language_menu(struct vb2_context *ctx)
{
	vb2_change_menu(VB_MENU_LANGUAGES,
			vb2_nv_get(ctx, VB2_NV_LOCALIZATION_INDEX));
	vb2_draw_current_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

static VbError_t enter_recovery_base_screen(struct vb2_context *ctx)
{
	if (!vb2_allow_recovery(ctx))
		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);
	vb2_draw_current_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

static VbError_t enter_options_menu(struct vb2_context *ctx)
{
	vb2_change_menu(VB_MENU_OPTIONS, VB_OPTIONS_CANCEL);
	vb2_draw_current_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

static VbError_t enter_to_dev_menu(struct vb2_context *ctx)
{
	const char dev_already_on[] =
		"WARNING: TODEV rejected, developer mode is already on.\n";
	if (vb2_get_sd(ctx)->vbsd->flags & VBSD_BOOT_DEV_SWITCH_ON) {
		vb2_flash_screen(ctx);
		vb2_error_notify(dev_already_on, NULL, VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}
	vb2_change_menu(VB_MENU_TO_DEV, VB_TO_DEV_CANCEL);
	vb2_draw_current_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

static VbError_t enter_to_norm_menu(struct vb2_context *ctx)
{
	vb2_change_menu(VB_MENU_TO_NORM, VB_TO_NORM_CONFIRM);
	vb2_draw_current_screen(ctx);
	return VBERROR_KEEP_LOOPING;
}

/* Boot alternative bootloader if allowed and available. */
static VbError_t enter_altfw_menu(struct vb2_context *ctx)
{
	VB2_DEBUG("enter_altfw_menu()\n");
	if (disable_dev_boot) {
		vb2_flash_screen(ctx);
		vb2_error_beep(VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}
	if (!altfw_allowed) {
		vb2_flash_screen(ctx);
		vb2_error_no_altfw();
		return VBERROR_KEEP_LOOPING;
	}
	vb2_change_menu(VB_MENU_ALT_FW, 0);
	vb2_draw_current_screen(ctx);

	return VBERROR_KEEP_LOOPING;
}

static VbError_t debug_info_action(struct vb2_context *ctx)
{
	force_redraw = 1;
	VbDisplayDebugInfo(ctx);
	return VBERROR_KEEP_LOOPING;
}

/* 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(ctx))
		vb2_nv_commit(ctx);

	/* Return to previous menu. */
	switch (prev_menu) {
	case VB_MENU_DEV_WARNING:
		return enter_dev_warning_menu(ctx);
	case VB_MENU_DEV:
		return enter_developer_menu(ctx);
	case VB_MENU_TO_NORM:
		return enter_to_norm_menu(ctx);
	case VB_MENU_TO_DEV:
		return enter_to_dev_menu(ctx);
	case VB_MENU_OPTIONS:
		return enter_options_menu(ctx);
	default:
		/* This should never happen. */
		VB2_DEBUG("ERROR: prev_menu state corrupted, force shutdown\n");
		return VBERROR_SHUTDOWN_REQUESTED;
	}
}

/* Action when selecting a bootloader in the alternative firmware menu. */
static VbError_t altfw_action(struct vb2_context *ctx)
{
	vb2_run_altfw(ctx, current_menu_idx + 1);
	vb2_flash_screen(ctx);
	VB2_DEBUG(no_legacy);
	VbExDisplayDebugInfo(no_legacy, 0);

	return VBERROR_KEEP_LOOPING;
}

/* Action that enables developer mode and reboots. */
static VbError_t to_dev_action(struct vb2_context *ctx)
{
	uint32_t vbsd_flags = vb2_get_sd(ctx)->vbsd->flags;

	/* Sanity check, should never happen. */
	if ((vbsd_flags & VBSD_BOOT_DEV_SWITCH_ON) ||
	    !vb2_allow_recovery(ctx))
		return VBERROR_KEEP_LOOPING;

	VB2_DEBUG("Enabling dev-mode...\n");
	if (TPM_SUCCESS != SetVirtualDevMode(1))
		return VBERROR_TPM_SET_BOOT_MODE_STATE;

	/* This was meant for headless devices, shouldn't really matter here. */
	if (VbExGetSwitches(VB_SWITCH_FLAG_ALLOW_USB_BOOT))
		vb2_nv_set(ctx, VB2_NV_DEV_BOOT_USB, 1);

	VB2_DEBUG("Reboot so it will take effect\n");
	return VBERROR_REBOOT_REQUIRED;
}

/* Action that disables developer mode, shows TO_NORM_CONFIRMED and reboots. */
static VbError_t to_norm_action(struct vb2_context *ctx)
{
	if (vb2_get_sd(ctx)->gbb_flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) {
		vb2_flash_screen(ctx);
		vb2_error_notify("WARNING: TONORM prohibited by "
				 "GBB FORCE_DEV_SWITCH_ON.\n", NULL,
				 VB_BEEP_NOT_ALLOWED);
		return VBERROR_KEEP_LOOPING;
	}

	VB2_DEBUG("leaving dev-mode.\n");
	vb2_nv_set(ctx, VB2_NV_DISABLE_DEV_REQUEST, 1);
	vb2_change_menu(VB_MENU_TO_NORM_CONFIRMED, 0);
	vb2_draw_current_screen(ctx);
	VbExSleepMs(5000);
	return VBERROR_REBOOT_REQUIRED;
}

/* Action that will power off the system. */
static VbError_t power_off_action(struct vb2_context *ctx)
{
	VB2_DEBUG("Power off requested from screen 0x%x\n",
		  menus[current_menu].screen);
	return VBERROR_SHUTDOWN_REQUESTED;
}

/**
 * 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  key      VOL_KEY_UP = increase index selection
 *                  VOL_KEY_DOWN = decrease index selection.
 *                  Every other key has no effect now.
 */
static void vb2_update_selection(uint32_t key) {
	int idx;

	switch (key) {
	case VB_BUTTON_VOL_UP_SHORT_PRESS:
	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_BUTTON_VOL_DOWN_SHORT_PRESS:
	case VB_KEY_DOWN:
		idx = current_menu_idx + 1;
		while (idx < menus[current_menu].size &&
		       ((1 << idx) & disabled_idx_mask))
		  idx++;
		/* Only update if idx is valid */
		if (idx < menus[current_menu].size)
			current_menu_idx = idx;
		break;
	default:
		VB2_DEBUG("ERROR: %s called with key 0x%x!\n", __func__, key);
		break;
	}

	vb2_log_menu_change();
}

static VbError_t vb2_handle_menu_input(struct vb2_context *ctx,
				       uint32_t key, uint32_t key_flags)
{
	switch (key) {
	case 0:
		/* nothing pressed */
		break;
	case '\t':
		/* Tab = display debug info */
		return debug_info_action(ctx);
	case VB_KEY_ESC:
		/* Esc = redraw screen (to clear old debug info) */
		vb2_draw_current_screen(ctx);
		break;
	case VB_KEY_UP:
	case VB_KEY_DOWN:
	case VB_BUTTON_VOL_UP_SHORT_PRESS:
	case VB_BUTTON_VOL_DOWN_SHORT_PRESS:
		/* Untrusted (USB keyboard) input disabled for TO_DEV menu. */
		if (current_menu == VB_MENU_TO_DEV &&
		    !(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)) {
			vb2_flash_screen(ctx);
			vb2_error_notify("Please use the on-device volume "
					 "buttons to navigate\n",
					 "vb2_handle_menu_input() - Untrusted "
					 "(USB keyboard) input disabled\n",
					 VB_BEEP_NOT_ALLOWED);
			break;
		}

		/* Menuless screens enter OPTIONS on volume button press. */
		if (!menus[current_menu].size) {
			enter_options_menu(ctx);
			break;
		}

		vb2_update_selection(key);
		vb2_draw_current_screen(ctx);
		break;
	case VB_BUTTON_POWER_SHORT_PRESS:
	case VB_KEY_ENTER:
		/* Menuless screens shut down on power button press. */
		if (!menus[current_menu].size)
			return VBERROR_SHUTDOWN_REQUESTED;

		return menus[current_menu].items[current_menu_idx].action(ctx);
	default:
		VB2_DEBUG("pressed key 0x%x\n", key);
		break;
	}

	if (VbWantShutdownMenu(ctx)) {
		VB2_DEBUG("shutdown requested!\n");
		return VBERROR_SHUTDOWN_REQUESTED;
	}

	return VBERROR_KEEP_LOOPING;
}

/* Delay in developer menu */
#define DEV_KEY_DELAY        20       /* Check keys every 20ms */

/* Master table of all menus. Menus with size == 0 count as menuless screens. */
static struct vb2_menu menus[VB_MENU_COUNT] = {
	[VB_MENU_DEV_WARNING] = {
		.name = "Developer Warning",
		.size = VB_WARN_COUNT,
		.screen = VB_SCREEN_DEVELOPER_WARNING_MENU,
		.items = (struct vb2_menu_item[]){
			[VB_WARN_OPTIONS] = {
				.text = "Developer Options",
				.action = enter_developer_menu,
			},
			[VB_WARN_DBG_INFO] = {
				.text = "Show Debug Info",
				.action = debug_info_action,
			},
			[VB_WARN_ENABLE_VER] = {
				.text = "Enable OS Verification",
				.action = enter_to_norm_menu,
			},
			[VB_WARN_POWER_OFF] = {
				.text = "Power Off",
				.action = power_off_action,
			},
			[VB_WARN_LANGUAGE] = {
				.text = "Language",
				.action = enter_language_menu,
			},
		},
	},
	[VB_MENU_DEV] = {
		.name = "Developer Boot Options",
		.size = VB_DEV_COUNT,
		.screen = VB_SCREEN_DEVELOPER_MENU,
		.items = (struct vb2_menu_item[]){
			[VB_DEV_NETWORK] = {
				.text = "Boot From Network",
				.action = NULL,	/* unimplemented */
			},
			[VB_DEV_LEGACY] = {
				.text = "Boot Legacy BIOS",
				.action = enter_altfw_menu,
			},
			[VB_DEV_USB] = {
				.text = "Boot From USB or SD Card",
				.action = boot_usb_action,
			},
			[VB_DEV_DISK] = {
				.text = "Boot From Internal Disk",
				.action = boot_disk_action,
			},
			[VB_DEV_CANCEL] = {
				.text = "Cancel",
				.action = enter_dev_warning_menu,
			},
			[VB_DEV_POWER_OFF] = {
				.text = "Power Off",
				.action = power_off_action,
			},
			[VB_DEV_LANGUAGE] = {
				.text = "Language",
				.action = enter_language_menu,
			},
		},
	},
	[VB_MENU_TO_NORM] = {
		.name = "TO_NORM Confirmation",
		.size = VB_TO_NORM_COUNT,
		.screen = VB_SCREEN_DEVELOPER_TO_NORM_MENU,
		.items = (struct vb2_menu_item[]){
			[VB_TO_NORM_CONFIRM] = {
				.text = "Confirm Enabling OS Verification",
				.action = to_norm_action,
			},
			[VB_TO_NORM_CANCEL] = {
				.text = "Cancel",
				.action = enter_dev_warning_menu,
			},
			[VB_TO_NORM_POWER_OFF] = {
				.text = "Power Off",
				.action = power_off_action,
			},
			[VB_TO_NORM_LANGUAGE] = {
				.text = "Language",
				.action = enter_language_menu,
			},
		},
	},
	[VB_MENU_TO_DEV] = {
		.name = "TO_DEV Confirmation",
		.size = VB_TO_DEV_COUNT,
		.screen = VB_SCREEN_RECOVERY_TO_DEV_MENU,
		.items = (struct vb2_menu_item[]){
			[VB_TO_DEV_CONFIRM] = {
				.text = "Confirm Disabling OS Verification",
				.action = to_dev_action,
			},
			[VB_TO_DEV_CANCEL] = {
				.text = "Cancel",
				.action = enter_recovery_base_screen,
			},
			[VB_TO_DEV_POWER_OFF] = {
				.text = "Power Off",
				.action = power_off_action,
			},
			[VB_TO_DEV_LANGUAGE] = {
				.text = "Language",
				.action = enter_language_menu,
			},
		},
	},
	[VB_MENU_LANGUAGES] = {
		.name = "Language Selection",
		.screen = VB_SCREEN_LANGUAGES_MENU,
		/* Rest is filled out dynamically by vb2_init_menus() */
	},
	[VB_MENU_OPTIONS] = {
		.name = "Options",
		.size = VB_OPTIONS_COUNT,
		.screen = VB_SCREEN_OPTIONS_MENU,
		.items = (struct vb2_menu_item[]){
			[VB_OPTIONS_DBG_INFO] = {
				.text = "Show Debug Info",
				.action = debug_info_action,
			},
			[VB_OPTIONS_CANCEL] = {
				.text = "Cancel",
				.action = enter_recovery_base_screen,
			},
			[VB_OPTIONS_POWER_OFF] = {
				.text = "Power Off",
				.action = power_off_action,
			},
			[VB_OPTIONS_LANGUAGE] = {
				.text = "Language",
				.action = enter_language_menu,
			},
		},
	},
	[VB_MENU_RECOVERY_INSERT] = {
		.name = "Recovery INSERT",
		.size = 0,
		.screen = VB_SCREEN_RECOVERY_INSERT,
		.items = NULL,
	},
	[VB_MENU_RECOVERY_NO_GOOD] = {
		.name = "Recovery NO_GOOD",
		.size = 0,
		.screen = VB_SCREEN_RECOVERY_NO_GOOD,
		.items = NULL,
	},
	[VB_MENU_RECOVERY_BROKEN] = {
		.name = "Non-manual Recovery (BROKEN)",
		.size = 0,
		.screen = VB_SCREEN_OS_BROKEN,
		.items = NULL,
	},
	[VB_MENU_TO_NORM_CONFIRMED] = {
		.name = "TO_NORM Interstitial",
		.size = 0,
		.screen = VB_SCREEN_TO_NORM_CONFIRMED,
		.items = NULL,
	},
	[VB_MENU_ALT_FW] = {
		.name = "Alternative Firmware Selection",
		.screen = VB_SCREEN_ALT_FW_MENU,
		.size = VB_ALTFW_COUNT + 1,
		.items = (struct vb2_menu_item[]) {{
				.text = "Bootloader 1",
				.action = altfw_action,
			}, {
				.text = "Bootloader 2",
				.action = altfw_action,
			}, {
				.text = "Bootloader 3",
				.action = altfw_action,
			}, {
				.text = "Bootloader 4",
				.action = altfw_action,
			}, {
				.text = "Bootloader 5",
				.action = altfw_action,
			}, {
				.text = "Bootloader 6",
				.action = altfw_action,
			}, {
				.text = "Bootloader 7",
				.action = altfw_action,
			}, {
				.text = "Bootloader 8",
				.action = altfw_action,
			}, {
				.text = "Bootloader 9",
				.action = altfw_action,
			}, {
				.text = "Cancel",
				.action = enter_developer_menu,
			},
		},
	},
};

/* Initialize menu state. Must be called once before displaying any menus. */
static VbError_t vb2_init_menus(struct vb2_context *ctx)
{
	struct vb2_menu_item *items;
	uint32_t count;
	int i;

	/* Initialize language menu with the correct amount of entries. */
	VbExGetLocalizationCount(&count);
	if (!count)
		count = 1;	/* Always need at least one language entry. */

	items = malloc(count * sizeof(struct vb2_menu_item));
	if (!items)
		return VBERROR_UNKNOWN;

	for (i = 0; i < count; i++) {
		/* The actual language is drawn by the bootloader */
		items[i].text = "Some Language";
		items[i].action = language_action;
	}
	menus[VB_MENU_LANGUAGES].size = count;
	menus[VB_MENU_LANGUAGES].items = items;

	return VBERROR_SUCCESS;
}

/**
 * Main function that handles developer warning menu functionality
 *
 * @param ctx		Vboot2 context
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
static VbError_t vb2_developer_menu(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	VbError_t ret;

	/* Check if the default is to boot using disk, usb, or legacy */
	default_boot = vb2_nv_get(ctx, VB2_NV_DEV_DEFAULT_BOOT);
	if (sd->gbb_flags & VB2_GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY)
		default_boot = VB2_DEV_DEFAULT_BOOT_LEGACY;

	/* Check if developer mode is disabled by FWMP */
	disable_dev_boot = 0;
	if (vb2_get_fwmp_flags() & FWMP_DEV_DISABLE_BOOT) {
		if (sd->gbb_flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) {
			VB2_DEBUG("FWMP_DEV_DISABLE_BOOT rejected by"
				  "FORCE_DEV_SWITCH_ON\n");
		} else {
			/* If dev mode is disabled, only allow TONORM */
			disable_dev_boot = 1;
			VB2_DEBUG("dev_disable_boot is set.\n");
		}
	}
	altfw_allowed = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_LEGACY) ||
	    (vb2_get_sd(ctx)->gbb_flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_LEGACY) ||
	    (vb2_get_fwmp_flags() & FWMP_DEV_ENABLE_LEGACY);

	/* Show appropriate initial menu */
	if (disable_dev_boot)
		enter_to_norm_menu(ctx);
	else
		enter_dev_warning_menu(ctx);

	/* Get audio/delay context */
	vb2_audio_start(ctx);

	/* We'll loop until we finish the delay or are interrupted */
	do {
		uint32_t key = VbExKeyboardRead();

		/* Make sure user knows dev mode disabled */
		if (disable_dev_boot)
			VbExDisplayDebugInfo(dev_disable_msg, 0);

		switch (key) {
		case VB_BUTTON_VOL_DOWN_LONG_PRESS:
		case VB_KEY_CTRL('D'):
			/* Ctrl+D = boot from internal disk */
			ret = boot_disk_action(ctx);
			break;
		case VB_KEY_CTRL('L'):
			/* Ctrl+L = boot alternative bootloader */
			ret = enter_altfw_menu(ctx);
			break;
		case VB_BUTTON_VOL_UP_LONG_PRESS:
		case VB_KEY_CTRL('U'):
			/* Ctrl+U = boot from USB or SD card */
			ret = boot_usb_action(ctx);
			break;
		/* We allow selection of the default '0' bootloader here */
		case '0'...'9':
			VB2_DEBUG("VbBootDeveloper() - "
				  "user pressed key '%c': Boot alternative "
				  "firmware\n", key);
			vb2_try_alt_fw(ctx, altfw_allowed, key - '0');
			ret = VBERROR_KEEP_LOOPING;
			break;
		default:
			ret = vb2_handle_menu_input(ctx, key, 0);
			break;
		}

		/* We may have loaded a kernel or decided to shut down now. */
		if (ret != VBERROR_KEEP_LOOPING)
			return ret;

		/* Reset 30 second timer whenever we see a new key. */
		if (key != 0)
			vb2_audio_start(ctx);

		VbExSleepMs(DEV_KEY_DELAY);

		/* If dev mode was disabled, loop forever (never timeout) */
	} while (disable_dev_boot ? 1 : vb2_audio_looping());

	if (default_boot == VB2_DEV_DEFAULT_BOOT_LEGACY)
		boot_legacy_action(ctx);	/* Doesn't return on success. */

	if (default_boot == VB2_DEV_DEFAULT_BOOT_USB)
		if (VBERROR_SUCCESS == boot_usb_action(ctx))
			return VBERROR_SUCCESS;

	return boot_disk_action(ctx);
}

/* Developer mode entry point. */
VbError_t VbBootDeveloperMenu(struct vb2_context *ctx)
{
	VbError_t retval = vb2_init_menus(ctx);
	if (VBERROR_SUCCESS != retval)
		return retval;
	retval = vb2_developer_menu(ctx);
	VbDisplayScreen(ctx, VB_SCREEN_BLANK, 0, NULL);
	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 */
#define REC_MEDIA_INIT_DELAY 500      /* Check removable media every 500ms */

/**
 * Main function that handles recovery menu functionality
 *
 * @param ctx		Vboot2 context
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
static VbError_t recovery_ui(struct vb2_context *ctx)
{
	uint32_t key;
	uint32_t key_flags;
	VbError_t ret;
	int i;

	/* 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");
		ret = VbTryLoadKernel(ctx, VB_DISK_FLAG_REMOVABLE);

		/*
		 * Clear recovery requests from failed kernel loading, since
		 * we're already in recovery mode.  Do this now, so that
		 * powering off after inserting an invalid disk doesn't leave
		 * us stuck in recovery mode.
		 */
		vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST,
			   VB2_RECOVERY_NOT_REQUESTED);

		if (VBERROR_SUCCESS == ret)
			return ret; /* Found a recovery kernel */

		if (usb_nogood != (ret != VBERROR_NO_DISK_FOUND)) {
			/* USB state changed, force back to base screen */
			usb_nogood = ret != VBERROR_NO_DISK_FOUND;
			enter_recovery_base_screen(ctx);
		}

		/*
		 * Scan keyboard more frequently than media, since x86
		 * platforms don't like to scan USB too rapidly.
		 */
		for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
			key = VbExKeyboardReadWithFlags(&key_flags);
			if (key == VB_BUTTON_VOL_UP_DOWN_COMBO_PRESS) {
				if (key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)
					enter_to_dev_menu(ctx);
				else
					VB2_DEBUG("ERROR: untrusted combo?!\n");
			} else {
				ret = vb2_handle_menu_input(ctx, key,
							    key_flags);
				if (ret != VBERROR_KEEP_LOOPING)
					return ret;
			}
			VbExSleepMs(REC_KEY_DELAY);
		}
	}
}

/* Recovery mode entry point. */
VbError_t VbBootRecoveryMenu(struct vb2_context *ctx)
{
	VbError_t retval = vb2_init_menus(ctx);
	if (VBERROR_SUCCESS != retval)
		return retval;
	if (vb2_allow_recovery(ctx))
		retval = recovery_ui(ctx);
	else
		retval = broken_ui(ctx);
	VbDisplayScreen(ctx, VB_SCREEN_BLANK, 0, NULL);
	return retval;
}
