/* 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;
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) {
	return VbDisplayMenu(ctx, menus[current_menu].screen, 0,
			     current_menu_idx, disabled_idx_mask);
}

/* 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(0);
	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)
{
	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(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_HONOR_VIRT_DEV_SWITCH) ||
	    (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_INIT_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_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(altfw_allowed, key - '0');
			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;
}
