/* 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 "region.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_nvstorage.h"

static void VbAllowUsbBootMenu(struct vb2_context *ctx)
{
	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_USB, 1);
}

/**
 * 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(uint32_t gbb_flags)
{
	uint32_t shutdown_request = VbExIsShutdownRequested();

	/* If desired, ignore shutdown request due to lid closure. */
	if (gbb_flags & 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;
}

static void VbTryLegacyMenu(int allowed)
{
	if (!allowed)
		VB2_DEBUG("Legacy boot is disabled\n");
	else if (0 != RollbackKernelLock(0))
		VB2_DEBUG("Error locking kernel versions on legacy boot.\n");
	else
		VbExLegacy();	/* Will not return if successful */

	/* If legacy boot fails, beep and return to calling UI loop. */
	VbExBeep(120, 400);
	VbExSleepMs(120);
	VbExBeep(120, 400);
}

uint32_t VbTryUsbMenu(struct vb2_context *ctx, VbCommonParams *cparams)
{
	uint32_t retval = VbTryLoadKernel(ctx, cparams, VB_DISK_FLAG_REMOVABLE);
	if (VBERROR_SUCCESS == retval) {
		VB2_DEBUG("booting USB\n");
	} else {
		VB2_DEBUG("no kernel found on USB\n");
		VbExBeep(250, 200);
		VbExSleepMs(120);
		/*
		 * Clear recovery requests from failed
		 * kernel loading, so that powering off
		 * at this point doesn't put us into
		 * recovery mode.
		 */
		vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST,
			   VBNV_RECOVERY_NOT_REQUESTED);
	}
	return retval;
}

#define CONFIRM_KEY_DELAY 20  /* Check confirm screen keys every 20ms */

int VbUserConfirmsMenu(struct vb2_context *ctx, VbCommonParams *cparams,
		   uint32_t confirm_flags)
{
	VbSharedDataHeader *shared =
           (VbSharedDataHeader *)cparams->shared_data_blob;
	uint32_t key;
	uint32_t key_flags;
        uint32_t button;
	int rec_button_was_pressed = 0;

	VB2_DEBUG("Entering (0x%x)\n", confirm_flags);

	/* Await further instructions */
	while (1) {
		if (VbWantShutdownMenu(cparams->gbb->flags))
			return -1;
		key = VbExKeyboardReadWithFlags(&key_flags);
                button = VbExGetSwitches(VB_INIT_FLAG_REC_BUTTON_PRESSED);
		switch (key) {
		case '\r':
			/* If we require a trusted keyboard for confirmation,
			 * but the keyboard may be faked (for instance, a USB
			 * device), beep and keep waiting.
			 */
			if (confirm_flags & VB_CONFIRM_MUST_TRUST_KEYBOARD &&
			    !(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)) {
				VbExBeep(120, 400);
				break;
                        }

			VB2_DEBUG("Yes (1)\n");
			return 1;
			break;
		case ' ':
			VB2_DEBUG("Space (%d)\n",
				  confirm_flags & VB_CONFIRM_SPACE_MEANS_NO);
			if (confirm_flags & VB_CONFIRM_SPACE_MEANS_NO)
				return 0;
			break;
		case 0x1b:
			VB2_DEBUG("No (0)\n");
			return 0;
			break;
		default:
			/* If the recovery button is physical, and is pressed,
			 * this is also a YES, but must wait for release.
			 */
			if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL)) {
				if (button) {
					VB2_DEBUG("Rec button pressed\n");
	                                rec_button_was_pressed = 1;
				} else if (rec_button_was_pressed) {
					VB2_DEBUG("Rec button (1)\n");
					return 1;
				}
			}
		}
		VbExSleepMs(CONFIRM_KEY_DELAY);
	}

	/* Not reached, but compiler will complain without it */
	return -1;
}

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";

typedef enum _VB_MENU {
	VB_MENU_DEV_WARNING,
	VB_MENU_DEV,
	VB_MENU_TO_NORM,
	VB_MENU_RECOVERY,
	VB_MENU_TO_DEV,
	VB_MENU_LANGUAGES,
	VB_MENU_RECOVERY_INSERT,
	VB_MENU_COUNT,
} VB_MENU;

typedef enum _VB_DEV_WARNING_MENU {
	VB_WARN_OPTIONS,
	VB_WARN_DBG_INFO,
	VB_WARN_ENABLE_VER,
	VB_WARN_POWER_OFF,
	VB_WARN_LANGUAGE,
	VB_WARN_COUNT,
} VB_DEV_WARNING_MENU;

typedef enum _VB_DEV_MENU {
	VB_DEV_NETWORK,
	VB_DEV_LEGACY,
	VB_DEV_USB,
	VB_DEV_DISK,
	VB_DEV_CANCEL,
	VB_DEV_POWER_OFF,
	VB_DEV_LANGUAGE,
	VB_DEV_COUNT,
} VB_DEV_MENU;

typedef enum _VB_TO_NORM_MENU {
	VB_TO_NORM_CONFIRM,
	VB_TO_NORM_CANCEL,
	VB_TO_NORM_POWER_OFF,
	VB_TO_NORM_LANGUAGE,
	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;

// TODO: currently we're only supporting
// english.  Will need to somehow find mapping
// from language to localization index.
typedef enum _VB_LANGUAGES_MENU {
	VB_LANGUAGES_EN_US,
	VB_LANGUAGES_COUNT,
} VB_LANGUAGES_MENU;

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
static char *dev_warning_menu[] = {
	"Developer Options\n",
	"Show Debug Info\n",
	"Enable Root Verification\n",
	"Power Off\n",
	"Language\n"
};

static char *dev_menu[] = {
	"Boot Network Image (not working yet)\n",
	"Boot Legacy BIOS\n",
	"Boot USB Image\n",
	"Boot Developer Image\n",
	"Cancel\n",
	"Power Off\n",
	"Language\n"
};

static char *to_normal_menu[] = {
	"Confirm Enabling Verified Boot\n",
	"Cancel\n",
	"Power Off\n",
	"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"
};

static char *languages_menu[] = {
	"US English\n",
};

/**
 * Get the string array and size of current_menu.
 *
 * @param menu:	The current_menu
 * @param menu_array:	Pointer to the menu's string array.  If menu_array==NULL
 *			will not return string array.
 * @param size:	Size of menu's string array.
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
VbError_t vb2_get_current_menu_size(VB_MENU menu, char ***menu_array,
				    uint32_t *size)
{
	char **temp_menu;

	switch(menu) {
	case VB_MENU_DEV_WARNING:
		*size = VB_WARN_COUNT;
		temp_menu = dev_warning_menu;
		break;
	case VB_MENU_DEV:
		*size = VB_DEV_COUNT;
		temp_menu = dev_menu;
		break;
	case VB_MENU_TO_NORM:
		*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;
	case VB_MENU_LANGUAGES:
		*size = VB_LANGUAGES_COUNT;
		temp_menu = languages_menu;
		break;
	default:
		*size = 0;
		return VBERROR_UNKNOWN;
	}
	if (menu_array)
		*menu_array = temp_menu;

	return VBERROR_SUCCESS;
}

/**
 * Print current_menu state, including selected entry.
 *
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
VbError_t vb2_print_current_menu()
{
	uint32_t size = 0;
	int i = 0;
	static char **m = NULL;
	int highlight = 0;
	// TODO: We probably want to center this text.
	uint32_t xindex, yindex;

	// TODO: need to check for error code.
	vb2_get_current_menu_size(current_menu, &m, &size);

	/* Center block of text */
	VbExDisplayGetDimension(&xindex, &yindex);
	xindex = xindex/2 - strlen(m[0])/2;
	yindex = yindex/2 - size/2;

	// TODO: do clear screen here.
	/* Create menu string */
	for (i = 0; i < size; i++) {
		highlight = !!(current_menu_idx == i);
		VbExDisplayText(xindex, yindex, m[i], highlight);
		VB2_DEBUG("[%d,%d]: %s", xindex, yindex, m[i]);
		yindex++;
	}

	return VBERROR_SUCCESS;
}

/*
 * Static array for mapping current_menu to matching screen item in depthcharge.
 * Note that order here is important and needs to match that of items in
 * VB_MENU.
 */
static const uint32_t VB_MENU_TO_SCREEN_MAP[] = {
	VB_SCREEN_DEVELOPER_WARNING_MENU,
	VB_SCREEN_DEVELOPER_MENU,
	VB_SCREEN_DEVELOPER_TO_NORM_MENU,
	VB_SCREEN_RECOVERY_MENU,
	VB_SCREEN_RECOVERY_TO_DEV_MENU,
	VB_SCREEN_LANGUAGES_MENU,
	VB_SCREEN_RECOVERY_INSERT,
};

VbError_t vb2_draw_current_screen(struct vb2_context *ctx,
				  VbCommonParams *cparams) {
	uint32_t screen;
	if (current_menu < VB_MENU_COUNT)
		screen = VB_MENU_TO_SCREEN_MAP[current_menu];
	else
		return VBERROR_UNKNOWN;
	return VbDisplayMenu(ctx, cparams, screen, 0,
			     current_menu_idx, disabled_idx_mask);
}

/**
 * Set current_menu to new_current_menu
 *
 * @param new_current_menu:	new menu to set current_menu to
 * @param new_current_menu_idx: new idx to set current_menu_idx to
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
VbError_t vb2_set_menu_items(VB_MENU new_current_menu,
			     int new_current_menu_idx)
{
	prev_menu = current_menu;
	current_menu = new_current_menu;
	current_menu_idx = new_current_menu_idx;
	/* Changing menus, so reset selected */
	selected = 0;

	return VBERROR_SUCCESS;
}

/**
 * This updates current_menu and current_menu_idx, as necessary
 *
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
VbError_t vb2_update_menu(struct vb2_context *ctx)
{
	VbError_t ret = VBERROR_SUCCESS;
	VB_MENU next_menu_idx = current_menu_idx;
	uint32_t loc = vb2_nv_get(ctx, VB2_NV_LOCALIZATION_INDEX);
	switch(current_menu) {
	case VB_MENU_DEV_WARNING:
		switch(current_menu_idx) {
		case VB_WARN_OPTIONS:
			switch(default_boot) {
			case VBNV_DEV_DEFAULT_BOOT_DISK:
				next_menu_idx = VB_DEV_DISK;
				break;
			case VBNV_DEV_DEFAULT_BOOT_USB:
				next_menu_idx = VB_DEV_USB;
				break;
			case VBNV_DEV_DEFAULT_BOOT_LEGACY:
				next_menu_idx = VB_DEV_LEGACY;
				break;
			}

			/*
			 * 1. Select dev menu
			 * 2. Default to dev boot device
			 */
			vb2_set_menu_items(VB_MENU_DEV, next_menu_idx);
			break;
		case VB_WARN_DBG_INFO:
			/* Show debug info */
			break;
		case VB_WARN_ENABLE_VER:
			/*
			 * 1. Enable boot verification
			 * 2. Default to the confirm option
			 */
			vb2_set_menu_items(VB_MENU_TO_NORM,
					   VB_TO_NORM_CONFIRM);
			break;
		case VB_WARN_POWER_OFF:
			/* Power off machine */
			ret =  VBERROR_SHUTDOWN_REQUESTED;
			break;
		case VB_WARN_LANGUAGE:
			/* Languages */
			vb2_set_menu_items(VB_MENU_LANGUAGES,
					   loc);
			break;
		default:
			/* Invalid menu item.  Don't update anything. */
			break;
		}
		break;
	case VB_MENU_DEV:
		switch(current_menu_idx) {
		case VB_DEV_NETWORK:
			/* Boot network image */
			break;
		case VB_DEV_LEGACY:
			/* Boot legacy BIOS */
			break;
		case VB_DEV_USB:
			/* Boot USB image */
			break;
		case VB_DEV_DISK:
			/* Boot developer image */
			break;
		case VB_DEV_CANCEL:
			/*
			 * 1. Cancel (go back to developer warning menu)
			 * 2. Default to power off option.
			 */
			vb2_set_menu_items(VB_MENU_DEV_WARNING,
					   VB_WARN_POWER_OFF);
			break;
		case VB_DEV_POWER_OFF:
			/* Power off */
			ret = VBERROR_SHUTDOWN_REQUESTED;
			break;
		case VB_DEV_LANGUAGE:
			/* Language */
			vb2_set_menu_items(VB_MENU_LANGUAGES,
					   loc);
			break;
		default:
			/* Invalid menu item.  Don't update anything. */
			break;
		}
		break;
	case VB_MENU_TO_NORM:
		switch(current_menu_idx) {
		case VB_TO_NORM_CONFIRM:
			/* Confirm enabling verified boot */
			break;
		case VB_TO_NORM_CANCEL:
			/*
			 * 1. Cancel (go back to developer warning menu)
			 * 2. Default to power off
			 */
			vb2_set_menu_items(VB_MENU_DEV_WARNING,
					   VB_WARN_POWER_OFF);
			break;
		case VB_TO_NORM_POWER_OFF:
			/* Power off */
			ret = VBERROR_SHUTDOWN_REQUESTED;
			break;
		case VB_TO_NORM_LANGUAGE:
			/* Language */
			vb2_set_menu_items(VB_MENU_LANGUAGES,
					   loc);
			break;
		default:
			/* Invalid menu item.  Don't update anything */
			break;
		}
		break;
	case VB_MENU_RECOVERY_INSERT:
		vb2_set_menu_items(VB_MENU_RECOVERY,
				   VB_RECOVERY_POWER_OFF);
		break;
	case VB_MENU_RECOVERY:
		switch(current_menu_idx) {
		case VB_RECOVERY_TO_DEV:
			/*
			 * 1. Switch to TO_DEV menu
			 * 2. Default to cancel option
			 */
			vb2_set_menu_items(VB_MENU_TO_DEV,
					   VB_TO_DEV_CANCEL);
			break;
		case VB_RECOVERY_DBG_INFO:
			break;
		case VB_RECOVERY_POWER_OFF:
			ret = VBERROR_SHUTDOWN_REQUESTED;
			break;
		case VB_RECOVERY_LANGUAGE:
			vb2_set_menu_items(VB_MENU_LANGUAGES,
					   loc);
			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:
			vb2_set_menu_items(VB_MENU_RECOVERY,
					   VB_RECOVERY_POWER_OFF);
			break;
		case VB_TO_DEV_POWER_OFF:
			ret = VBERROR_SHUTDOWN_REQUESTED;
			break;
		case VB_TO_DEV_LANGUAGE:
			vb2_set_menu_items(VB_MENU_LANGUAGES,
					   loc);
			break;
		default:
			/* Invalid menu item.  Don't update anything. */
			break;
		}
		break;
	case VB_MENU_LANGUAGES:
		/*
		 * 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 with the exception of
		 * TO_DEV and TO_NORM menus
		 */
		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_CONFIRM;
			break;
		case VB_MENU_RECOVERY:
			current_menu_idx = VB_RECOVERY_POWER_OFF;
			break;
		case VB_MENU_TO_DEV:
			current_menu_idx = VB_TO_DEV_CANCEL;
			break;
		default:
			current_menu_idx = 0;
			break;
		}
		selected = current_menu_idx;
		break;
	default:
		VB2_DEBUG("Current Menu Invalid! 0x%x\n", current_menu_idx);
	}
	return ret;
}

/**
 * This updates the current locale to the current_menu_index
 * This function only does something in the VB_MENU_LANGUAGES menu
 * Otherwise it's a noop.
 *
 * @return VBERROR_SUCCESS
 */
VbError_t vb2_update_locale(struct vb2_context *ctx) {
	if (current_menu == VB_MENU_LANGUAGES) {
		vb2_nv_set(ctx, VB2_NV_LOCALIZATION_INDEX, current_menu_idx);
		vb2_nv_set(ctx, VB2_NV_BACKUP_NVRAM_REQUEST, 1);
#ifdef SAVE_LOCALE_IMMEDIATELY
		if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
			VbExNvStorageWrite(ctx.nvdata);
			ctx.flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
		}
#endif
	}
	return VBERROR_SUCCESS;
}

/**
 * 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;
	}
	/* Disable Network Boot Option */
	if (current_menu == VB_MENU_DEV)
		disabled_idx_mask |= 1 << VB_DEV_NETWORK;
	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_BUTTON_VOL_UP:
	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:
	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
 * @param cparams	Vboot1 common params
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
VbError_t vb2_developer_menu(struct vb2_context *ctx, VbCommonParams *cparams)
{
	GoogleBinaryBlockHeader *gbb = cparams->gbb;
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;

	uint32_t disable_dev_boot = 0;
	uint32_t use_usb = 0;
	uint32_t use_legacy = 0;
	uint32_t ctrl_d_pressed = 0;

	VbAudioContext *audio = 0;
	VbError_t ret;
	VB2_DEBUG("Entering\n");

	/* Check if USB booting is allowed */
	uint32_t allow_usb = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_USB);
	uint32_t allow_legacy = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_LEGACY);

	/* Check if the default is to boot using disk, usb, or legacy */
	default_boot = vb2_nv_get(ctx, VB2_NV_DEV_DEFAULT_BOOT);

	if(default_boot == VBNV_DEV_DEFAULT_BOOT_USB)
		use_usb = 1;
	if(default_boot == VBNV_DEV_DEFAULT_BOOT_LEGACY)
		use_legacy = 1;

	/* Handle GBB flag override */
	if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_USB)
		allow_usb = 1;
	if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_LEGACY)
		allow_legacy = 1;
	if (gbb->flags & GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY) {
		use_legacy = 1;
		use_usb = 0;
	}

	/* Handle FWMP override */
	uint32_t fwmp_flags = vb2_get_fwmp_flags();
	if (fwmp_flags & FWMP_DEV_ENABLE_USB)
		allow_usb = 1;
	if (fwmp_flags & FWMP_DEV_ENABLE_LEGACY)
		allow_legacy = 1;
	if (fwmp_flags & FWMP_DEV_DISABLE_BOOT) {
		if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) {
			VB2_DEBUG("FWMP_DEV_DISABLE_BOOT rejected by"
				  "FORCE_DEV_SWITCH_ON\n");
		} else {
			disable_dev_boot = 1;
		}
	}

	/* If dev mode is disabled, only allow TONORM */
	while (disable_dev_boot) {
		VB2_DEBUG("dev_disable_boot is set.\n");
		VbDisplayScreen(ctx, cparams, VB_SCREEN_DEVELOPER_TO_NORM_MENU,
				0);
		VbExDisplayDebugInfo(dev_disable_msg);

		/* Ignore space in VbUserConfirmsMenu()... */
		switch (VbUserConfirmsMenu(ctx, cparams, 0)) {
		case 1:
			VB2_DEBUG("leaving dev-mode.\n");
			vb2_nv_set(ctx, VB2_NV_DISABLE_DEV_REQUEST, 1);
			VbDisplayScreen(ctx, cparams,
					VB_SCREEN_TO_NORM_CONFIRMED,
					0);
			VbExSleepMs(5000);
			return VBERROR_REBOOT_REQUIRED;
		case -1:
			VB2_DEBUG("shutdown requested\n");
			return VBERROR_SHUTDOWN_REQUESTED;
		default:
			/* Ignore user attempt to cancel */
			VB2_DEBUG("ignore cancel TONORM\n");
		}
	}


	vb2_set_disabled_idx_mask(shared->flags);
	/* Show the dev mode warning screen */
	vb2_draw_current_screen(ctx, cparams);

	/* Get audio/delay context */
	audio = VbAudioOpen(cparams);

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

		if (VbWantShutdownMenu(gbb->flags)) {
			VB2_DEBUG("shutdown requested!\n");
			VbAudioClose(audio);
			return VBERROR_SHUTDOWN_REQUESTED;
		}

		key = VbExKeyboardRead();
		switch (key) {
		case 0:
			/* Nothing pressed */
			break;
		case 0x04:
			/* Ctrl+D = dismiss warning; advance to timeout */
			VB2_DEBUG("user pressed Ctrl+D; skip delay\n");
			ctrl_d_pressed = 1;
			goto fallout;
			break;
		case 0x0c:
			VB2_DEBUG("user pressed Ctrl+L; Try legacy boot\n");
			VbTryLegacyMenu(allow_legacy);
			break;
		case 0x15:
			/* Ctrl+U = try USB boot, or beep if failure */
			VB2_DEBUG("user pressed Ctrl+U; try USB\n");
			if (!allow_usb) {
				VB2_DEBUG("USB booting is disabled\n");
				VbExDisplayDebugInfo(
					"WARNING: Booting from external media "
					"(USB/SD) has not been enabled. Refer "
					"to the developer-mode documentation "
					"for details.\n");
				VbExBeep(120, 400);
				VbExSleepMs(120);
				VbExBeep(120, 400);
			} else {
				/*
				 * Clear the screen to show we get the Ctrl+U
				 * key press.
				 */
				VbDisplayScreen(ctx, cparams, VB_SCREEN_BLANK,
						0);
				if (VBERROR_SUCCESS ==
				    VbTryUsbMenu(ctx, cparams)) {
					VbAudioClose(audio);
					return VBERROR_SUCCESS;
				} else {
					/* Show dev mode warning screen again */
					vb2_draw_current_screen(ctx, cparams);
				}
			}
			break;
		case VB_BUTTON_VOL_UP:
		case VB_KEY_UP:
			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:
			vb2_update_selection(cparams, key);
			vb2_draw_current_screen(ctx, cparams);
			/* reset 30 second timer */
			audio = VbAudioOpen(cparams);
			break;
		case VB_BUTTON_POWER:
		case '\r':
			selected = 1;

			/*
			 * Need to update locale before updating the menu or
			 * we'll lose the previous state
			 */
			vb2_update_locale(ctx);

			ret = vb2_update_menu(ctx);
			vb2_set_disabled_idx_mask(shared->flags);
			vb2_draw_current_screen(ctx, cparams);

			/* Probably shutting down */
			if (ret != VBERROR_SUCCESS) {
			  VB2_DEBUG("shutting down!\n");
			  return ret;
			}

			/* Nothing selected, skip everything else */
			if (selected == 0)
				break;

			/* All the actions associated with selection */

			/* Display debug information */
			if (current_menu == VB_MENU_DEV_WARNING &&
			    current_menu_idx == VB_WARN_DBG_INFO) {
				VbDisplayDebugInfo(ctx, cparams);
			}

			/* Boot Legacy mode */
			if (current_menu == VB_MENU_DEV &&
			    current_menu_idx == VB_DEV_LEGACY) {
				VB2_DEBUG("user pressed Ctrl+L; "
					  "Try legacy boot\n");
				VbTryLegacyMenu(allow_legacy);
			}

			/* USB boot, or beep if failure */
			if (current_menu == VB_MENU_DEV &&
			    current_menu_idx == VB_DEV_USB) {
				VB2_DEBUG("user pressed Ctrl+U; try USB\n");
				if (!allow_usb) {
					VB2_DEBUG("USB booting is disabled\n");
					VbExDisplayDebugInfo(
						"WARNING: Booting from external media "
						"(USB/SD) has not been enabled. Refer "
						"to the developer-mode documentation "
						"for details.\n");
					VbExBeep(120, 400);
					VbExSleepMs(120);
					VbExBeep(120, 400);
				} else {
					/*
					 * Clear the screen to show we get the
					 * Ctrl+U key press.
					 */
					VbDisplayScreen(ctx,
						cparams, VB_SCREEN_BLANK, 0);
					if (VBERROR_SUCCESS ==
					    VbTryUsbMenu(ctx, cparams)) {
						VbAudioClose(audio);
						return VBERROR_SUCCESS;
					} else
						/*
						 * Show dev mode warning screen
						 * again
						 */
						vb2_draw_current_screen(ctx,
								       cparams);
				}
			}

			/* Boot developer mode: advance to timeout */
			if (current_menu == VB_MENU_DEV &&
			    current_menu_idx == VB_DEV_DISK) {
				VB2_DEBUG("user pressed Ctrl+D; skip delay\n");
				ctrl_d_pressed = 1;
				goto fallout;
			}

			/* Enabling verified boot */
			if (current_menu == VB_MENU_TO_NORM &&
			    current_menu_idx == VB_TO_NORM_CONFIRM) {
				if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) {
					/*
					 * Throw error when user tries to
					 * confirm transition to normal
					 * mode if FORCE_DEV_SWITCH_ON
					 * is enabled.
					 */
					VB2_DEBUG("TONORM rejected by "
						  "FORCE_DEV_SWITCH_ON\n");
					VbExDisplayDebugInfo(
						"WARNING: TONORM prohibited by "
						"GBB FORCE_DEV_SWITCH_ON.\n\n");
					VbExBeep(120, 400);
				} else {
					/*
					 * See if we should disable
					 * virtual dev-mode switch.
					 */
					VB2_DEBUG("%s shared->flags=0x%x\n",
						  __func__, shared->flags);
					VB2_DEBUG("leaving dev-mode.\n");
					vb2_nv_set(ctx,
						   VB2_NV_DISABLE_DEV_REQUEST,
						   1);
					VbDisplayScreen(ctx,
						cparams,
						VB_SCREEN_TO_NORM_CONFIRMED,
						0);
					VbExSleepMs(5000);
					return VBERROR_REBOOT_REQUIRED;
				}
			}
			/* reset 30 second timer */
			audio = VbAudioOpen(cparams);
			break;
		default:
			VB2_DEBUG("pressed key %d\n", key);
			break;
		}
	} while(VbAudioLooping(audio));

fallout:

	/* If defaulting to legacy boot, try that unless Ctrl+D was pressed */
	if (use_legacy && !ctrl_d_pressed) {
		VB2_DEBUG("defaulting to legacy\n");
		VbTryLegacyMenu(allow_legacy);
	}

	if ((use_usb && !ctrl_d_pressed) && allow_usb) {
		if (VBERROR_SUCCESS == VbTryUsbMenu(ctx, cparams)) {
			VbAudioClose(audio);
			return VBERROR_SUCCESS;
		}
	}

	/* Timeout or Ctrl+D; attempt loading from fixed disk */
	VB2_DEBUG("trying fixed disk\n");
	VbAudioClose(audio);
	return VbTryLoadKernel(ctx, cparams, VB_DISK_FLAG_FIXED);
}

VbError_t VbBootDeveloperMenu(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbError_t retval = vb2_developer_menu(ctx, cparams);
	VbDisplayScreen(ctx, cparams, VB_SCREEN_BLANK, 0);
	return retval;
}

/* 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
 * @param cparams	Vboot1 common params
 * @return VBERROR_SUCCESS, or non-zero error code if error.
 */
static VbError_t recovery_ui(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	uint32_t retval;
	uint32_t key;
	uint32_t key_flags;
	int i;
	VbError_t ret;

	VB2_DEBUG("start\n");

	if (!vb2_allow_recovery(shared->flags)) {
		/*
		 * We have to save the reason here so that it will survive
		 * coming up three-finger-salute. We're saving it in
		 * VBNV_RECOVERY_SUBCODE to avoid a recovery loop.
		 * If we save the reason in VBNV_RECOVERY_REQUEST, we will come
		 * back here, thus, we won't be able to give a user a chance to
		 * reboot to workaround a boot hiccup.
		 */
		VB2_DEBUG("saving recovery reason (%#x)\n",
			  shared->recovery_reason);
		vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE,
			   shared->recovery_reason);
		/*
		 * Commit NV now, because it won't get saved if the user forces
		 * manual recovery via the three-finger salute.
		 */
		vb2_nv_commit(ctx);

		VbDisplayScreen(ctx, cparams, VB_SCREEN_OS_BROKEN, 0);
		VB2_DEBUG("waiting for manual recovery\n");
		while (1) {
			key = VbExKeyboardRead();
			if (key == VB_BUTTON_POWER)
				return VBERROR_SHUTDOWN_REQUESTED;
			else {
				VbCheckDisplayKey(ctx, cparams, key);
				if (VbWantShutdownMenu(cparams->gbb->flags))
					return VBERROR_SHUTDOWN_REQUESTED;
			}
			VbExSleepMs(REC_KEY_DELAY);
		}
	}

	/* Loop and wait for a recovery image */
	VB2_DEBUG("waiting for a recovery image\n");

	/* Initialize menu to recovery menu. */
	current_menu = VB_MENU_RECOVERY_INSERT;
	prev_menu = VB_MENU_RECOVERY_INSERT;
	current_menu_idx = 0;

	while (1) {
		VB2_DEBUG("attempting to load kernel2\n");
		retval = VbTryLoadKernel(ctx, cparams, 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,
			   VBNV_RECOVERY_NOT_REQUESTED);

		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)
				vb2_draw_current_screen(ctx, cparams);
			else
				VbDisplayScreen(ctx, cparams,
						VB_SCREEN_RECOVERY_NO_GOOD,
						0);
		}

		/*
		 * 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);
			switch (key) {
			case 0:
				/* nothing pressed */
				break;
			case VB_KEY_UP:
			case VB_KEY_DOWN:
			case VB_BUTTON_VOL_UP:
			case VB_BUTTON_VOL_DOWN:
				/* User cannot use keyboard to enable dev mode.
				 * They need to use the volume buttons from a
				 * trusted source to navigate to the disable os
				 * verification menu item.  Beep so user knows
				 * that they're doing something wrong.
				 */
				if (current_menu == VB_MENU_TO_DEV &&
				    !(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)) {
					VbExBeep(120, 400);
					break;
				}

				if (current_menu == VB_MENU_RECOVERY_INSERT) {
					ret = vb2_update_menu(ctx);
					if (ret != VBERROR_SUCCESS)
						return ret;
					vb2_set_disabled_idx_mask(shared->flags);
				} else {
					vb2_update_selection(cparams, key);
				}
				vb2_draw_current_screen(ctx, cparams);
				break;
			case VB_BUTTON_POWER:
			case '\r':
				selected = 1;

				/*
				 * If user hits power button in
				 * initial recovery screen (ie:
				 * because didn't really want to go
				 * there), power button will turn off
				 * device.
				 */
				if (current_menu == VB_MENU_RECOVERY_INSERT) {
					ret = VBERROR_SHUTDOWN_REQUESTED;
				} else {
					/*
					 * Need to update locale
					 * before updating the menu or
					 * we'll lose the previous state
					 */
					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) {
					/*
					 * Unfortunately we need this screen
					 * blanking to clear previous menus
					 * printed.
					 */
					if (retval == VBERROR_NO_DISK_FOUND)
						vb2_draw_current_screen(ctx,
							cparams);
					else
						VbDisplayScreen(ctx, cparams,
						VB_SCREEN_RECOVERY_NO_GOOD,
						0);
				}

				/* Probably shutting down */
				if (ret != VBERROR_SUCCESS) {
					VB2_DEBUG("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
				 */
				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)) {
					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("^D but rec switch "
							  "is pressed\n");
						VbExBeep(120, 400);
						continue;
					}

					VB2_DEBUG("Enabling dev-mode...\n");
					if (TPM_SUCCESS != SetVirtualDevMode(1))
						return VBERROR_TPM_SET_BOOT_MODE_STATE;
					VB2_DEBUG("Reboot so it will take "
						  "effect\n");
					if (VbExGetSwitches
					    (VB_INIT_FLAG_ALLOW_USB_BOOT))
						VbAllowUsbBootMenu(ctx);
					return VBERROR_REBOOT_REQUIRED;
				}
			}
			if (VbWantShutdownMenu(cparams->gbb->flags))
				return VBERROR_SHUTDOWN_REQUESTED;
			VbExSleepMs(REC_KEY_DELAY);
		}
	}

	return VBERROR_SUCCESS;
}

VbError_t VbBootRecoveryMenu(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbError_t retval = recovery_ui(ctx, cparams);
	VbDisplayScreen(ctx, cparams, VB_SCREEN_BLANK, 0);
	return retval;
}
