/* Copyright (c) 2013 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_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 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, int *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()
{
	int 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,
};

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);
}

/**
 * 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()
{
	VbError_t ret = VBERROR_SUCCESS;
	VB_MENU next_menu_idx = current_menu_idx;
	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 power off option
			 */
			vb2_set_menu_items(VB_MENU_TO_NORM,
					   VB_TO_NORM_POWER_OFF);
			break;
		case VB_WARN_POWER_OFF:
			/* Power off machine */
			ret =  VBERROR_SHUTDOWN_REQUESTED;
			break;
		case VB_WARN_LANGUAGE:
			/* Languages */
			// TODO: we'll have to figure out how to display this
			vb2_set_menu_items(VB_MENU_LANGUAGES,
					   VB_LANGUAGES_EN_US);
			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,
					   VB_LANGUAGES_EN_US);
			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,
					   VB_LANGUAGES_EN_US);
			break;
		default:
			/* Invalid menu item.  Don't update anything */
			break;
		}
		break;
	case VB_MENU_RECOVERY:
		switch(current_menu_idx) {
		case VB_RECOVERY_TO_DEV:
			/*
			 * 1. Switch to TO_DEV menu
			 * 2. Default to power off option
			 */
			vb2_set_menu_items(VB_MENU_TO_DEV,
					   VB_TO_DEV_POWER_OFF);
			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,
					   VB_LANGUAGES_EN_US);
			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,
					   VB_LANGUAGES_EN_US);
			break;
		default:
			/* Invalid menu item.  Don't update anything. */
			break;
		}
		break;
	case VB_MENU_LANGUAGES:
		switch(current_menu_idx) {
		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;
			current_menu_idx = 0;
			prev_menu = VB_MENU_LANGUAGES;
			selected = 0;
			break;
		}
	default:
		VB2_DEBUG("Current Menu Invalid!");
	}
	return ret;
}

/**
 * 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;
#if defined(VBOOT_DEBUG)
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
#endif

	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, 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");
		}
	}

	/* Show the dev mode warning screen */
	//TODO: change this to blank screen?
	VbDisplayScreen(ctx, cparams, VB_SCREEN_BASE, 0);
	vb2_print_current_menu();

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

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

		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 */
					VbDisplayScreen(ctx,
						cparams,
						VB_SCREEN_BASE,
						0);
					vb2_print_current_menu();
				}
			}
			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_draw_current_screen(ctx, cparams);
			vb2_print_current_menu();
			break;
		case VB_BUTTON_VOL_DOWN:
		case VB_KEY_DOWN:
			vb2_get_current_menu_size(current_menu,
						  NULL, &menu_size);
			/* Do no wrap selection index */
			if (current_menu_idx < menu_size-1)
				current_menu_idx++;
			vb2_draw_current_screen(ctx, cparams);
			vb2_print_current_menu();
			break;
		case VB_BUTTON_POWER:
		case '\r':
			selected = 1;

			ret = vb2_update_menu();
			/*
			 * Unfortunately, we need the blanking to get rid of
			 * artifacts from previous menu printing.
			 */
			VbDisplayScreen(ctx, cparams, VB_SCREEN_BLANK, 0);
			VbDisplayScreen(ctx, cparams,
					VB_SCREEN_BASE, 0);
			vb2_print_current_menu();

			/* 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
						 */
						VbDisplayScreen(ctx,
							cparams,
							VB_SCREEN_BASE,
							0);
						vb2_print_current_menu();
					}
				}
			}

			/* 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) {
				/*
				 * See if we should disable virtual dev-mode
				 * switch.
				 */
				VB2_DEBUG("%s shared->flags=0x%x\n",
					  __func__, shared->flags);
				/* Ignore space in VbUserConfirmsMenu()... */
			        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;
			}
			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.
 */
VbError_t vb2_recovery_menu(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	uint32_t retval;
	uint32_t key;
	int i;
	VbError_t ret;
	int menu_size;

	VB2_DEBUG("start\n");

	/*
	 * If the dev-mode switch is off and the user didn't press the recovery
	 * button (recovery was triggerred automatically), show 'broken' screen.
	 * The user can either only shutdown to abort or hit esc+refresh+power
	 * to initiate recovery as instructed on the screen.
	 */
	if (!(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
	    !(shared->flags & VBSD_BOOT_REC_SWITCH_ON)) {
		/*
		 * 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 boot hicups.
		 */
		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) {
			VbCheckDisplayKey(ctx, cparams, VbExKeyboardRead());
			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;
	prev_menu = VB_MENU_RECOVERY;
	current_menu_idx = VB_RECOVERY_POWER_OFF;

	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 */

		if (current_menu != VB_MENU_RECOVERY ||
		    current_menu_idx != VB_RECOVERY_DBG_INFO) {
			VbDisplayScreen(ctx, cparams,
					VBERROR_NO_DISK_FOUND == retval ?
					VB_SCREEN_BASE :
					VB_SCREEN_RECOVERY_NO_GOOD,
					0);
			vb2_print_current_menu();
		}

		/*
		 * 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 = VbExKeyboardRead();
			switch (key) {
			case 0:
				/* nothing pressed */
				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_draw_current_screen(ctx, cparams);
				vb2_print_current_menu();
				break;
			case VB_BUTTON_VOL_DOWN:
			case VB_KEY_DOWN:
				vb2_get_current_menu_size(current_menu, NULL, &menu_size);
				if (current_menu_idx < menu_size-1)
					current_menu_idx++;
				vb2_draw_current_screen(ctx, cparams);
				vb2_print_current_menu();
				break;
			case VB_BUTTON_POWER:
			case '\r':
				selected = 1;

				ret = vb2_update_menu();
				if (current_menu != VB_MENU_RECOVERY ||
				     current_menu_idx != VB_RECOVERY_DBG_INFO) {
					/*
					 * Unfortunately we need this screen
					 * blanking to clear previous menus
					 * printed.
					 */
					VbDisplayScreen(ctx, cparams, VB_SCREEN_BLANK, 0);
					VbDisplayScreen(ctx, cparams, VBERROR_NO_DISK_FOUND == retval ?
							VB_SCREEN_BASE :
							VB_SCREEN_RECOVERY_NO_GOOD,
							0);
					vb2_print_current_menu();
				}

				/* 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
				 *   - EC isn't pwned
				 */
				// TODO: let's put an error here if we're
				// already in dev mode.
				if (current_menu == VB_MENU_TO_DEV &&
				    current_menu_idx == 0 &&
				    shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
				    !(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
				    (shared->flags & VBSD_BOOT_REC_SWITCH_ON) &&
				    VbExTrustEC(0)) {
					if (!(shared->flags &
					      VBSD_BOOT_REC_SWITCH_VIRTUAL) &&
					    VbExGetSwitches(
						VB_INIT_FLAG_REC_BUTTON_PRESSED)) {
						/*
						 * Is the recovery button stuck?  In
						 * any case we don't like this.  Beep
						 * and ignore.
						 */
						VB2_DEBUG("^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 = vb2_recovery_menu(ctx, cparams);
	VbDisplayScreen(ctx, cparams, VB_SCREEN_BLANK, 0);
	return retval;
}
