// SPDX-License-Identifier: GPL-2.0+
/*
 *  EFI boot manager
 *
 *  Copyright (c) 2017 Rob Clark
 */

#define LOG_CATEGORY LOGC_EFI

#include <blk.h>
#include <blkmap.h>
#include <charset.h>
#include <dm.h>
#include <efi.h>
#include <efi_device_path.h>
#include <env.h>
#include <log.h>
#include <malloc.h>
#include <net.h>
#include <part.h>
#include <efi_loader.h>
#include <efi_variable.h>
#include <asm/unaligned.h>
#include <linux/kernel.h>
#include <linux/sizes.h>

static const struct efi_boot_services *bs;
static const struct efi_runtime_services *rs;

/**
 * struct uridp_context - uri device path resource
 *
 * @image_size:		image size
 * @image_addr:		image address
 * @loaded_dp:		pointer to loaded device path
 * @ramdisk_blk_dev:	pointer to the ramdisk blk device
 * @mem_handle:		efi_handle to the loaded PE-COFF image
 */
struct uridp_context {
	ulong image_size;
	ulong image_addr;
	struct efi_device_path *loaded_dp;
	struct udevice *ramdisk_blk_dev;
	efi_handle_t mem_handle;
};

const efi_guid_t efi_guid_bootmenu_auto_generated =
		EFICONFIG_AUTO_GENERATED_ENTRY_GUID;

/*
 * bootmgr implements the logic of trying to find a payload to boot
 * based on the BootOrder + BootXXXX variables, and then loading it.
 *
 * TODO detecting a special key held (f9?) and displaying a boot menu
 * like you would get on a PC would be clever.
 *
 * TODO if we had a way to write and persist variables after the OS
 * has started, we'd also want to check OsIndications to see if we
 * should do normal or recovery boot.
 */

/**
 * expand_media_path() - expand a device path for default file name
 * @device_path:	device path to check against
 *
 * If @device_path is a media or disk partition which houses a file
 * system, this function returns a full device path which contains
 * an architecture-specific default file name for removable media.
 *
 * Return:	a newly allocated device path
 */
static
struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
{
	struct efi_device_path *rem, *full_path;
	efi_handle_t handle;

	if (!device_path)
		return NULL;

	/*
	 * If device_path is a (removable) media or partition which provides
	 * simple file system protocol, append a default file name to support
	 * booting from removable media.
	 */
	handle = efi_dp_find_obj(device_path,
				 &efi_simple_file_system_protocol_guid, &rem);
	if (handle) {
		if (rem->type == DEVICE_PATH_TYPE_END) {
			char fname[30];

			snprintf(fname, sizeof(fname), "/EFI/BOOT/%s",
				 efi_get_basename());
			full_path = efi_dp_from_file(device_path, fname);

		} else {
			full_path = efi_dp_dup(device_path);
		}
	} else {
		full_path = efi_dp_dup(device_path);
	}

	return full_path;
}

/**
 * try_load_from_file_path() - try to load a file
 *
 * Given a file media path iterate through a list of handles and try to
 * to load the file from each of them until the first success.
 *
 * @fs_handles: array of handles with the simple file protocol
 * @num:	number of handles in fs_handles
 * @fp:		file path to open
 * @handle:	on return pointer to handle for loaded image
 * @removable:	if true only consider removable media, else only non-removable
 */
static efi_status_t try_load_from_file_path(efi_handle_t *fs_handles,
					    efi_uintn_t num,
					    struct efi_device_path *fp,
					    efi_handle_t *handle,
					    bool removable)
{
	struct efi_handler *handler;
	struct efi_device_path *dp;
	int i;
	efi_status_t ret;

	for (i = 0; i < num; i++) {
		if (removable != efi_disk_is_removable(fs_handles[i]))
			continue;

		ret = efi_search_protocol(fs_handles[i], &efi_guid_device_path,
					  &handler);
		if (ret != EFI_SUCCESS)
			continue;

		dp = handler->protocol_interface;
		if (!dp)
			continue;

		dp = efi_dp_concat(dp, fp, 0);
		if (!dp)
			continue;

		ret = EFI_CALL(efi_load_image(true, efi_root, dp, NULL, 0,
					      handle));
		efi_free_pool(dp);
		if (ret == EFI_SUCCESS)
			return ret;
	}

	return EFI_NOT_FOUND;
}

/**
 * try_load_from_short_path
 * @fp:		file path
 * @handle:	pointer to handle for newly installed image
 *
 * Enumerate all the devices which support file system operations,
 * prepend its media device path to the file path, @fp, and
 * try to load the file.
 * This function should be called when handling a short-form path
 * which is starting with a file device path.
 *
 * Return:	status code
 */
static efi_status_t try_load_from_short_path(struct efi_device_path *fp,
					     efi_handle_t *handle)
{
	efi_handle_t *fs_handles;
	efi_uintn_t num;
	efi_status_t ret;

	ret = EFI_CALL(efi_locate_handle_buffer(
					BY_PROTOCOL,
					&efi_simple_file_system_protocol_guid,
					NULL,
					&num, &fs_handles));
	if (ret != EFI_SUCCESS)
		return ret;
	if (!num)
		return EFI_NOT_FOUND;

	/* removable media first */
	ret = try_load_from_file_path(fs_handles, num, fp, handle, true);
	if (ret == EFI_SUCCESS)
		goto out;

	/* fixed media */
	ret = try_load_from_file_path(fs_handles, num, fp, handle, false);
	if (ret == EFI_SUCCESS)
		goto out;

out:
	return ret;
}

/**
 * mount_image() - mount the image with blkmap
 *
 * @lo_label:	u16 label string of load option
 * @addr:	image address
 * @size:	image size
 * Return:	pointer to the UCLASS_BLK udevice, NULL if failed
 */
static struct udevice *mount_image(u16 *lo_label, ulong addr, ulong size)
{
	int err;
	struct blkmap *bm;
	struct udevice *bm_dev;
	char *label = NULL, *p;

	label = efi_alloc(utf16_utf8_strlen(lo_label) + 1);
	if (!label)
		return NULL;

	p = label;
	utf16_utf8_strcpy(&p, lo_label);
	err = blkmap_create_ramdisk(label, addr, size, &bm_dev);
	if (err) {
		efi_free_pool(label);
		return NULL;
	}
	bm = dev_get_plat(bm_dev);

	efi_free_pool(label);

	return bm->blk;
}

/**
 * search_default_file() - search default file
 *
 * @dev:	pointer to the UCLASS_BLK or UCLASS_PARTITION udevice
 * @loaded_dp:	pointer to default file device path
 * Return:	status code
 */
static efi_status_t search_default_file(struct udevice *dev,
					struct efi_device_path **loaded_dp)
{
	efi_status_t ret;
	efi_handle_t handle;
	u16 *default_file_name = NULL;
	struct efi_file_handle *root, *f;
	struct efi_device_path *dp = NULL, *fp = NULL;
	struct efi_simple_file_system_protocol *file_system;
	struct efi_device_path *device_path, *full_path = NULL;

	if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) {
		log_warning("DM_TAG_EFI not found\n");
		return EFI_INVALID_PARAMETER;
	}

	ret = EFI_CALL(bs->open_protocol(handle, &efi_guid_device_path,
					 (void **)&device_path, efi_root, NULL,
					 EFI_OPEN_PROTOCOL_GET_PROTOCOL));
	if (ret != EFI_SUCCESS)
		return ret;

	ret = EFI_CALL(bs->open_protocol(handle, &efi_simple_file_system_protocol_guid,
					 (void **)&file_system, efi_root, NULL,
					 EFI_OPEN_PROTOCOL_GET_PROTOCOL));
	if (ret != EFI_SUCCESS)
		return ret;

	ret = EFI_CALL(file_system->open_volume(file_system, &root));
	if (ret != EFI_SUCCESS)
		return ret;

	full_path = expand_media_path(device_path);
	ret = efi_dp_split_file_path(full_path, &dp, &fp);
	if (ret != EFI_SUCCESS)
		goto err;

	default_file_name = efi_dp_str(fp);
	efi_free_pool(dp);
	efi_free_pool(fp);
	if (!default_file_name) {
		ret = EFI_OUT_OF_RESOURCES;
		goto err;
	}

	ret = EFI_CALL(root->open(root, &f, default_file_name,
				  EFI_FILE_MODE_READ, 0));
	efi_free_pool(default_file_name);
	if (ret != EFI_SUCCESS)
		goto err;

	EFI_CALL(f->close(f));
	EFI_CALL(root->close(root));

	*loaded_dp = full_path;

	return EFI_SUCCESS;

err:
	EFI_CALL(root->close(root));
	efi_free_pool(full_path);

	return ret;
}

/**
 * fill_default_file_path() - get fallback boot device path for block device
 *
 * Provide the device path to the fallback UEFI boot file, e.g.
 * EFI/BOOT/BOOTAA64.EFI if that file exists on the block device @blk.
 *
 * @blk:	pointer to the UCLASS_BLK udevice
 * @dp:		pointer to store the fallback boot device path
 * Return:	status code
 */
static efi_status_t fill_default_file_path(struct udevice *blk,
					   struct efi_device_path **dp)
{
	efi_status_t ret;
	struct udevice *partition;

	/* image that has no partition table but a file system */
	ret = search_default_file(blk, dp);
	if (ret == EFI_SUCCESS)
		return ret;

	/* try the partitions */
	device_foreach_child(partition, blk) {
		enum uclass_id id;

		id = device_get_uclass_id(partition);
		if (id != UCLASS_PARTITION)
			continue;

		ret = search_default_file(partition, dp);
		if (ret == EFI_SUCCESS)
			return ret;
	}

	return EFI_NOT_FOUND;
}

/**
 * prepare_loaded_image() - prepare ramdisk for downloaded image
 *
 * @label:	label of load option
 * @addr:	image address
 * @size:	image size
 * @dp:		pointer to default file device path
 * @blk:	pointer to created blk udevice
 * Return:	status code
 *
 * This function handles device creation internally and performs cleanup
 * on error paths.
 */
static efi_status_t prepare_loaded_image(u16 *label, ulong addr, ulong size,
					 struct efi_device_path **dp,
					 struct udevice **blk)
{
	u64 pages;
	efi_status_t ret;
	struct udevice *ramdisk_blk;
	struct blk_desc *desc;
	struct part_driver *part_drv;

	/* Create the ramdisk block device internally */
	ramdisk_blk = mount_image(label, addr, size);
	if (!ramdisk_blk) {
		log_warning("Failed to create ramdisk block device\n");
		return EFI_DEVICE_ERROR;
	}

	/* Get the block descriptor and detect partitions */
	desc = dev_get_uclass_plat(ramdisk_blk);
	if (!desc) {
		log_err("Failed to get block descriptor\n");
		ret = EFI_DEVICE_ERROR;
		goto err;
	}

	/* Use part_driver_lookup_type for comprehensive partition detection */
	part_drv = part_driver_lookup_type(desc);
	if (!part_drv) {
		log_err("Image is not a valid disk image\n");
		ret = EFI_INVALID_PARAMETER;
		goto err;
	}

	ret = fill_default_file_path(ramdisk_blk, dp);
	if (ret != EFI_SUCCESS) {
		log_info("Cannot boot from downloaded image\n");
		goto err;
	}

	/*
	 * Linux supports 'pmem' which allows OS installers to find, reclaim
	 * the mounted images and continue the installation since the contents
	 * of the pmem region are treated as local media.
	 *
	 * The memory regions used for it needs to be carved out of the EFI
	 * memory map.
	 */
	pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK));
	ret = efi_update_memory_map(addr, pages, EFI_CONVENTIONAL_MEMORY,
				    false, true);
	if (ret != EFI_SUCCESS) {
		log_err("Failed to reserve memory\n");
		goto err;
	}

	*blk = ramdisk_blk;

	return EFI_SUCCESS;

err:
	if (blkmap_destroy(ramdisk_blk->parent))
		log_err("Destroying blkmap failed\n");

	return ret;
}

/**
 * efi_bootmgr_release_uridp() - cleanup uri device path resource
 *
 * @ctx:	event context
 * Return:	status code
 */
static efi_status_t efi_bootmgr_release_uridp(struct uridp_context *ctx)
{
	efi_status_t ret = EFI_SUCCESS;
	efi_status_t ret2 = EFI_SUCCESS;

	if (!ctx)
		return ret;

	/* cleanup for disk image */
	if (ctx->ramdisk_blk_dev) {
		ret = efi_add_memory_map(ctx->image_addr, ctx->image_size,
					 EFI_CONVENTIONAL_MEMORY);
		if (ret != EFI_SUCCESS)
			log_err("Reclaiming memory failed\n");

		if (blkmap_destroy(ctx->ramdisk_blk_dev->parent)) {
			log_err("Destroying blkmap failed\n");
			ret = EFI_DEVICE_ERROR;
		}
	}

	/* cleanup for PE-COFF image */
	if (ctx->mem_handle) {
		ret2 = efi_uninstall_multiple_protocol_interfaces(ctx->mem_handle,
								  &efi_guid_device_path,
								  ctx->loaded_dp,
								  NULL);
		if (ret2 != EFI_SUCCESS)
			log_err("Uninstall device_path protocol failed\n");
	}

	efi_free_pool(ctx->loaded_dp);
	free(ctx);

	return ret == EFI_SUCCESS ? ret2 : ret;
}

/**
 * efi_bootmgr_http_return() - return to efibootmgr callback
 *
 * @event:	the event for which this notification function is registered
 * @context:	event context
 */
static void EFIAPI efi_bootmgr_http_return(struct efi_event *event,
					   void *context)
{
	efi_status_t ret;

	EFI_ENTRY("%p, %p", event, context);
	ret = efi_bootmgr_release_uridp(context);
	EFI_EXIT(ret);
}

/**
 * try_load_from_uri_path() - Handle the URI device path
 *
 * @uridp:	uri device path
 * @lo_label:	label of load option
 * @handle:	pointer to handle for newly installed image
 * Return:	status code
 */
static efi_status_t try_load_from_uri_path(struct efi_device_path_uri *uridp,
					   u16 *lo_label,
					   efi_handle_t *handle)
{
	char *s;
	int err;
	efi_status_t ret;
	void *source_buffer;
	efi_uintn_t source_size;
	struct uridp_context *ctx;
	struct udevice *blk = NULL;
	struct efi_event *event = NULL;
	efi_handle_t mem_handle = NULL;
	struct efi_device_path *loaded_dp;
	static ulong image_size, image_addr;

	ctx = calloc(1, sizeof(struct uridp_context));
	if (!ctx)
		return EFI_OUT_OF_RESOURCES;

	s = env_get("ipaddr");
	if (!s && dhcp_run(0, NULL, false)) {
		log_err("Error: Can't find a valid IP address\n");
		ret = EFI_DEVICE_ERROR;
		goto err;
	}

	s = env_get("loadaddr");
	if (!s) {
		log_err("Error: loadaddr is not set\n");
		ret = EFI_INVALID_PARAMETER;
		goto err;
	}

	image_addr = hextoul(s, NULL);
	err = wget_do_request(image_addr, uridp->uri);
	if (err < 0) {
		ret = EFI_INVALID_PARAMETER;
		goto err;
	}

	image_size = env_get_hex("filesize", 0);
	if (!image_size) {
		ret = EFI_INVALID_PARAMETER;
		goto err;
	}
	/*
	 * Depending on the kernel configuration, pmem memory areas must be
	 * page aligned or 2MiB aligned. PowerPC is an exception here and
	 * requires 16MiB alignment, but since we don't have EFI support for
	 * it, limit the alignment to 2MiB.
	 */
	image_size = ALIGN(image_size, SZ_2M);

	/*
	 * Check if the downloaded file is a disk image or PE-COFF image.
	 * Try disk image detection first using prepare_loaded_image().
	 */

	/* First, try to treat the image as a disk image */
	ret = prepare_loaded_image(lo_label, image_addr, image_size,
				   &loaded_dp, &blk);
	if (ret == EFI_SUCCESS) {
		/* Image is a disk image, set up for disk boot */
		source_buffer = NULL;
		source_size = 0;
	} else if (efi_check_pe((void *)image_addr, image_size, NULL) == EFI_SUCCESS) {
		/*
		 * loaded_dp must exist until efi application returns,
		 * will be freed in return_to_efibootmgr event callback.
		 */
		loaded_dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
					    image_addr, image_size);
		ret = efi_install_multiple_protocol_interfaces(
			&mem_handle, &efi_guid_device_path, loaded_dp, NULL);
		if (ret != EFI_SUCCESS)
			goto err;

		source_buffer = (void *)image_addr;
		source_size = image_size;
	} else {
		log_err("Error: file type is not supported\n");
		ret = EFI_UNSUPPORTED;
		goto err;
	}

	ctx->image_size = image_size;
	ctx->image_addr = image_addr;
	ctx->loaded_dp = loaded_dp;
	ctx->ramdisk_blk_dev = blk;
	ctx->mem_handle = mem_handle;

	ret = EFI_CALL(efi_load_image(false, efi_root, loaded_dp, source_buffer,
				      source_size, handle));
	if (ret != EFI_SUCCESS)
		goto err;

	/* create event for cleanup when the image returns or error occurs */
	ret = efi_create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
			       efi_bootmgr_http_return, ctx,
			       &efi_guid_event_group_return_to_efibootmgr,
			       &event);
	if (ret != EFI_SUCCESS) {
		log_err("Creating event failed\n");
		goto err;
	}

	return ret;

err:
	efi_bootmgr_release_uridp(ctx);

	return ret;
}

/**
 * try_load_from_media() - load file from media
 *
 * @file_path:		file path
 * @handle_img:		on return handle for the newly installed image
 *
 * If @file_path contains a file name, load the file.
 * If @file_path does not have a file name, search the architecture-specific
 * fallback boot file and load it.
 * TODO: If the FilePathList[0] device does not support
 * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but supports EFI_BLOCK_IO_PROTOCOL,
 * call EFI_BOOT_SERVICES.ConnectController()
 * TODO: FilePathList[0] device supports the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
 * not based on EFI_BLOCK_IO_PROTOCOL
 *
 * Return:	status code
 */
static efi_status_t try_load_from_media(struct efi_device_path *file_path,
					efi_handle_t *handle_img)
{
	efi_handle_t handle_blkdev;
	efi_status_t ret = EFI_SUCCESS;
	struct efi_device_path *rem, *dp = NULL;
	struct efi_device_path *final_dp = file_path;

	handle_blkdev = efi_dp_find_obj(file_path, &efi_block_io_guid, &rem);
	if (handle_blkdev) {
		if (rem->type == DEVICE_PATH_TYPE_END) {
			/* no file name present, try default file */
			ret = fill_default_file_path(handle_blkdev->dev, &dp);
			if (ret != EFI_SUCCESS)
				return ret;

			final_dp = dp;
		}
	}

	ret = EFI_CALL(efi_load_image(true, efi_root, final_dp, NULL, 0, handle_img));

	efi_free_pool(dp);

	return ret;
}

/**
 * try_load_entry() - try to load image for boot option
 *
 * Attempt to load load-option number 'n', returning device_path and file_path
 * if successful. This checks that the EFI_LOAD_OPTION is active (enabled)
 * and that the specified file to boot exists.
 *
 * @n:			number of the boot option, e.g. 0x0a13 for Boot0A13
 * @handle:		on return handle for the newly installed image
 * @load_options:	load options set on the loaded image protocol
 * Return:		status code
 */
static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
				   void **load_options)
{
	struct efi_load_option lo;
	u16 varname[9];
	void *load_option;
	efi_uintn_t size;
	efi_status_t ret;
	u32 attributes;

	*handle = NULL;
	*load_options = NULL;

	efi_create_indexed_name(varname, sizeof(varname), "Boot", n);
	load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
	if (!load_option)
		return EFI_LOAD_ERROR;

	ret = efi_deserialize_load_option(&lo, load_option, &size);
	if (ret != EFI_SUCCESS) {
		log_warning("Invalid load option for %ls\n", varname);
		goto error;
	}

	if (!(lo.attributes & LOAD_OPTION_ACTIVE)) {
		ret = EFI_LOAD_ERROR;
		goto error;
	}

	log_debug("trying to load \"%ls\" from %pD\n", lo.label, lo.file_path);

	if (EFI_DP_TYPE(lo.file_path, MEDIA_DEVICE, FILE_PATH)) {
		/* file_path doesn't contain a device path */
		ret = try_load_from_short_path(lo.file_path, handle);
	} else if (EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE, MSG_URI)) {
		if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))
			ret = try_load_from_uri_path(
				(struct efi_device_path_uri *)lo.file_path,
				lo.label, handle);
		else
			ret = EFI_LOAD_ERROR;
	} else {
		ret = try_load_from_media(lo.file_path, handle);
	}
	if (ret != EFI_SUCCESS) {
		log_warning("Loading %ls '%ls' failed\n",
			    varname, lo.label);
		goto error;
	}

	attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
		     EFI_VARIABLE_RUNTIME_ACCESS;
	ret = efi_set_variable_int(u"BootCurrent", &efi_global_variable_guid,
				   attributes, sizeof(n), &n, false);
	if (ret != EFI_SUCCESS)
		goto error;

	/* try to register load file2 for initrd's */
	if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
		ret = efi_initrd_register(NULL);
		if (ret != EFI_SUCCESS)
			goto error;
	}

	log_info("Booting: Label: %ls Device path: %pD\n", lo.label, lo.file_path);

	/* Ignore the optional data in auto-generated boot options */
	if (size >= sizeof(efi_guid_t) &&
	    !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated))
		size = 0;

	/* Set optional data in loaded file protocol */
	if (size) {
		*load_options = malloc(size);
		if (!*load_options) {
			ret = EFI_OUT_OF_RESOURCES;
			goto error;
		}
		memcpy(*load_options, lo.optional_data, size);
		ret = efi_set_load_options(*handle, size, *load_options);
		if (ret != EFI_SUCCESS)
			free(load_options);
	}

error:
	if (ret != EFI_SUCCESS && *handle &&
	    EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS)
		log_err("Unloading image failed\n");

	free(load_option);

	return ret;
}

/**
 * efi_bootmgr_load() - try to load from BootNext or BootOrder
 *
 * Attempt to load from BootNext or in the order specified by BootOrder
 * EFI variable, the available load-options, finding and returning
 * the first one that can be loaded successfully.
 *
 * @handle:		on return handle for the newly installed image
 * @load_options:	load options set on the loaded image protocol
 * Return:		status code
 */
efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options)
{
	u16 bootnext, *bootorder;
	efi_uintn_t size;
	int i, num;
	efi_status_t ret;

	bs = systab.boottime;
	rs = systab.runtime;

	/* BootNext */
	size = sizeof(bootnext);
	ret = efi_get_variable_int(u"BootNext",
				   &efi_global_variable_guid,
				   NULL, &size, &bootnext, NULL);
	if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
		/* BootNext does exist here */
		if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16))
			log_err("BootNext must be 16-bit integer\n");

		/* delete BootNext */
		ret = efi_set_variable_int(u"BootNext",
					   &efi_global_variable_guid,
					   0, 0, NULL, false);

		/* load BootNext */
		if (ret == EFI_SUCCESS) {
			if (size == sizeof(u16)) {
				ret = try_load_entry(bootnext, handle,
						     load_options);
				if (ret == EFI_SUCCESS)
					return ret;
				log_warning(
					"Loading from BootNext failed, falling back to BootOrder\n");
			}
		} else {
			log_err("Deleting BootNext failed\n");
		}
	}

	/* BootOrder */
	bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
	if (!bootorder) {
		log_info("BootOrder not defined\n");
		ret = EFI_NOT_FOUND;
		goto error;
	}

	num = size / sizeof(uint16_t);
	for (i = 0; i < num; i++) {
		log_debug("trying to load Boot%04X\n", bootorder[i]);
		ret = try_load_entry(bootorder[i], handle, load_options);
		if (ret == EFI_SUCCESS)
			break;
	}

	free(bootorder);

error:
	return ret;
}

/**
 * efi_bootmgr_enumerate_boot_options() - enumerate the possible bootable media
 *
 * @opt:		pointer to the media boot option structure
 * @index:		index of the opt array to store the boot option
 * @handles:		pointer to block device handles
 * @count:		On entry number of handles to block devices.
 *			On exit number of boot options.
 * @removable:		flag to parse removable only
 * Return:		status code
 */
static efi_status_t
efi_bootmgr_enumerate_boot_options(struct eficonfig_media_boot_option *opt,
				   efi_uintn_t index, efi_handle_t *handles,
				   efi_uintn_t *count, bool removable)
{
	u32 i, num = index;
	struct efi_handler *handler;
	efi_status_t ret = EFI_SUCCESS;

	for (i = 0; i < *count; i++) {
		u16 *p;
		u16 dev_name[BOOTMENU_DEVICE_NAME_MAX];
		char *optional_data;
		struct efi_load_option lo;
		char buf[BOOTMENU_DEVICE_NAME_MAX];
		struct efi_device_path *device_path;
		struct efi_device_path *short_dp;
		struct efi_block_io *blkio;

		ret = efi_search_protocol(handles[i], &efi_block_io_guid, &handler);
		blkio = handler->protocol_interface;

		if (blkio->media->logical_partition)
			continue;

		if (removable != (blkio->media->removable_media != 0))
			continue;

		ret = efi_search_protocol(handles[i], &efi_guid_device_path, &handler);
		if (ret != EFI_SUCCESS)
			continue;
		ret = efi_protocol_open(handler, (void **)&device_path,
					efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
		if (ret != EFI_SUCCESS)
			continue;

		ret = efi_disk_get_device_name(handles[i], buf, BOOTMENU_DEVICE_NAME_MAX);
		if (ret != EFI_SUCCESS)
			continue;

		p = dev_name;
		utf8_utf16_strncpy(&p, buf, strlen(buf));

		/* prefer to short form device path */
		short_dp = efi_dp_shorten(device_path);
		if (short_dp)
			device_path = short_dp;

		lo.label = dev_name;
		lo.attributes = LOAD_OPTION_ACTIVE;
		lo.file_path = device_path;
		lo.file_path_length = efi_dp_size(device_path) +
			sizeof(EFI_DP_END);
		/*
		 * Set the dedicated guid to optional_data, it is used to identify
		 * the boot option that automatically generated by the bootmenu.
		 * efi_serialize_load_option() expects optional_data is null-terminated
		 * utf8 string, so set the "1234567" string to allocate enough space
		 * to store guid, instead of realloc the load_option.
		 */
		lo.optional_data = "1234567";
		opt[num].size = efi_serialize_load_option(&lo, (u8 **)&opt[num].lo);
		if (!opt[num].size) {
			ret = EFI_OUT_OF_RESOURCES;
			goto out;
		}
		/* set the guid */
		optional_data = (char *)opt[num].lo + (opt[num].size - u16_strsize(u"1234567"));
		memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t));
		num++;

		if (num >= *count)
			break;
	}

out:
	*count = num;

	return ret;
}

/**
 * efi_bootmgr_delete_invalid_boot_option() - delete non-existing boot option
 *
 * @opt:		pointer to the media boot option structure
 * @count:		number of media boot option structure
 * Return:		status code
 */
static efi_status_t efi_bootmgr_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt,
							   efi_status_t count)
{
	efi_uintn_t size;
	void *load_option;
	u32 i, list_size = 0;
	struct efi_load_option lo;
	u16 *var_name16 = NULL;
	u16 varname[] = u"Boot####";
	efi_status_t ret = EFI_SUCCESS;
	u16 *delete_index_list = NULL, *p;
	efi_uintn_t buf_size;

	buf_size = 128;
	var_name16 = malloc(buf_size);
	if (!var_name16)
		return EFI_OUT_OF_RESOURCES;

	var_name16[0] = 0;
	for (;;) {
		int index;
		efi_guid_t guid;
		efi_uintn_t tmp;

		ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
		if (ret == EFI_NOT_FOUND) {
			/*
			 * EFI_NOT_FOUND indicates we retrieved all EFI variables.
			 * This should be treated as success.
			 */
			ret = EFI_SUCCESS;
			break;
		}

		if (ret != EFI_SUCCESS)
			goto out;

		if (!efi_varname_is_load_option(var_name16, &index))
			continue;

		efi_create_indexed_name(varname, sizeof(varname), "Boot", index);
		load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
		if (!load_option)
			continue;

		tmp = size;
		ret = efi_deserialize_load_option(&lo, load_option, &size);
		if (ret != EFI_SUCCESS)
			goto next;

		if (size >= sizeof(efi_guid_bootmenu_auto_generated) &&
		    !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) {
			for (i = 0; i < count; i++) {
				if (opt[i].size == tmp &&
				    memcmp(opt[i].lo, load_option, tmp) == 0) {
					opt[i].exist = true;
					break;
				}
			}

			/*
			 * The entire list of variables must be retrieved by
			 * efi_get_next_variable_name_int() before deleting the invalid
			 * boot option, just save the index here.
			 */
			if (i == count) {
				p = realloc(delete_index_list, sizeof(u32) *
					    (list_size + 1));
				if (!p) {
					ret = EFI_OUT_OF_RESOURCES;
					goto out;
				}
				delete_index_list = p;
				delete_index_list[list_size++] = index;
			}
		}
next:
		free(load_option);
	}

	/* delete all invalid boot options */
	for (i = 0; i < list_size; i++) {
		ret = efi_bootmgr_delete_boot_option(delete_index_list[i]);
		if (ret != EFI_SUCCESS)
			goto out;
	}

out:
	free(var_name16);
	free(delete_index_list);

	return ret;
}

/**
 * efi_bootmgr_get_unused_bootoption() - get unused "Boot####" index
 *
 * @buf:	pointer to the buffer to store boot option variable name
 * @buf_size:	buffer size
 * @index:	pointer to store the index in the BootOrder variable
 * Return:	status code
 */
efi_status_t efi_bootmgr_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size,
					       unsigned int *index)
{
	u32 i;
	efi_status_t ret;
	efi_uintn_t size;

	if (buf_size < u16_strsize(u"Boot####"))
		return EFI_BUFFER_TOO_SMALL;

	for (i = 0; i <= 0xFFFF; i++) {
		size = 0;
		efi_create_indexed_name(buf, buf_size, "Boot", i);
		ret = efi_get_variable_int(buf, &efi_global_variable_guid,
					   NULL, &size, NULL, NULL);
		if (ret == EFI_BUFFER_TOO_SMALL)
			continue;
		else
			break;
	}

	if (i > 0xFFFF)
		return EFI_OUT_OF_RESOURCES;

	*index = i;

	return EFI_SUCCESS;
}

/**
 * efi_bootmgr_append_bootorder() - append new boot option in BootOrder variable
 *
 * @index:	"Boot####" index to append to BootOrder variable
 * Return:	status code
 */
efi_status_t efi_bootmgr_append_bootorder(u16 index)
{
	u16 *bootorder;
	efi_status_t ret;
	u16 *new_bootorder = NULL;
	efi_uintn_t last, size, new_size;

	/* append new boot option */
	bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
	last = size / sizeof(u16);
	new_size = size + sizeof(u16);
	new_bootorder = calloc(1, new_size);
	if (!new_bootorder) {
		ret = EFI_OUT_OF_RESOURCES;
		goto out;
	}
	memcpy(new_bootorder, bootorder, size);
	new_bootorder[last] = index;

	ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
				   EFI_VARIABLE_NON_VOLATILE |
				   EFI_VARIABLE_BOOTSERVICE_ACCESS |
				   EFI_VARIABLE_RUNTIME_ACCESS,
				   new_size, new_bootorder, false);
	if (ret != EFI_SUCCESS)
		goto out;

out:
	free(bootorder);
	free(new_bootorder);

	return ret;
}

/**
 * efi_bootmgr_delete_boot_option() - delete selected boot option
 *
 * @boot_index:	boot option index to delete
 * Return:	status code
 */
efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index)
{
	u16 *bootorder;
	u16 varname[9];
	efi_status_t ret;
	unsigned int index;
	efi_uintn_t num, size;

	efi_create_indexed_name(varname, sizeof(varname),
				"Boot", boot_index);
	ret = efi_set_variable_int(varname, &efi_global_variable_guid,
				   0, 0, NULL, false);
	if (ret != EFI_SUCCESS) {
		log_err("delete boot option(%ls) failed\n", varname);
		return ret;
	}

	/* update BootOrder if necessary */
	bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
	if (!bootorder)
		return EFI_SUCCESS;

	num = size / sizeof(u16);
	if (!efi_search_bootorder(bootorder, num, boot_index, &index))
		return EFI_SUCCESS;

	memmove(&bootorder[index], &bootorder[index + 1],
		(num - index - 1) * sizeof(u16));
	size -= sizeof(u16);
	ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
				   EFI_VARIABLE_NON_VOLATILE |
				   EFI_VARIABLE_BOOTSERVICE_ACCESS |
				   EFI_VARIABLE_RUNTIME_ACCESS,
				   size, bootorder, false);

	return ret;
}

/**
 * efi_bootmgr_update_media_device_boot_option() - generate the media device boot option
 *
 * This function enumerates all BlockIo devices and add the boot option for it.
 * This function also provide the BOOT#### variable maintenance for
 * the media device entries.
 * - Automatically create the BOOT#### variable for the newly detected device,
 * this BOOT#### variable is distinguished by the special GUID
 * stored in the EFI_LOAD_OPTION.optional_data
 * - If the device is not attached to the system, the associated BOOT#### variable
 * is automatically deleted.
 *
 * Return:	status code
 */
efi_status_t efi_bootmgr_update_media_device_boot_option(void)
{
	u32 i;
	efi_status_t ret;
	efi_uintn_t count, num, total = 0;
	efi_handle_t *handles = NULL;
	struct eficonfig_media_boot_option *opt = NULL;

	ret = efi_locate_handle_buffer_int(BY_PROTOCOL,
					   &efi_block_io_guid,
					   NULL, &count,
					   (efi_handle_t **)&handles);
	if (ret != EFI_SUCCESS)
		goto out;

	opt = calloc(count, sizeof(struct eficonfig_media_boot_option));
	if (!opt) {
		ret = EFI_OUT_OF_RESOURCES;
		goto out;
	}

	/* parse removable block io followed by fixed block io */
	num = count;
	ret = efi_bootmgr_enumerate_boot_options(opt, 0, handles, &num, true);
	if (ret != EFI_SUCCESS)
		goto out;

	total = num;
	num = count;
	ret = efi_bootmgr_enumerate_boot_options(opt, total, handles, &num, false);
	if (ret != EFI_SUCCESS)
		goto out;

	total = num;

	/*
	 * System hardware configuration may vary depending on the user setup.
	 * The boot option is automatically added by the bootmenu.
	 * If the device is not attached to the system, the boot option needs
	 * to be deleted.
	 */
	ret = efi_bootmgr_delete_invalid_boot_option(opt, total);
	if (ret != EFI_SUCCESS)
		goto out;

	/* add non-existent boot option */
	for (i = 0; i < total; i++) {
		u32 boot_index;
		u16 var_name[9];

		if (!opt[i].exist) {
			ret = efi_bootmgr_get_unused_bootoption(var_name, sizeof(var_name),
								&boot_index);
			if (ret != EFI_SUCCESS)
				goto out;

			ret = efi_set_variable_int(var_name, &efi_global_variable_guid,
						   EFI_VARIABLE_NON_VOLATILE |
						   EFI_VARIABLE_BOOTSERVICE_ACCESS |
						   EFI_VARIABLE_RUNTIME_ACCESS,
						   opt[i].size, opt[i].lo, false);
			if (ret != EFI_SUCCESS)
				goto out;

			ret = efi_bootmgr_append_bootorder(boot_index);
			if (ret != EFI_SUCCESS) {
				efi_set_variable_int(var_name, &efi_global_variable_guid,
						     0, 0, NULL, false);
				goto out;
			}
		}
	}

out:
	if (opt) {
		for (i = 0; i < total; i++)
			free(opt[i].lo);
	}
	free(opt);
	efi_free_pool(handles);

	if (ret == EFI_NOT_FOUND)
		return EFI_SUCCESS;
	return ret;
}

/**
 * load_fdt_from_load_option - load device-tree from load option
 *
 * @fdt:	pointer to loaded device-tree or NULL
 * Return:	status code
 */
static efi_status_t load_fdt_from_load_option(void **fdt)
{
	struct efi_device_path *dp = NULL;
	struct efi_file_handle *f = NULL;
	efi_uintn_t filesize;
	efi_status_t ret;

	*fdt = NULL;

	dp = efi_get_dp_from_boot(&efi_guid_fdt);
	if (!dp)
		return EFI_SUCCESS;

	/* Open file */
	f = efi_file_from_path(dp);
	if (!f) {
		log_err("Can't find %pD specified in Boot####\n", dp);
		ret = EFI_NOT_FOUND;
		goto out;
	}

	/* Get file size */
	ret = efi_file_size(f, &filesize);
	if (ret != EFI_SUCCESS)
		goto out;

	*fdt = calloc(1, filesize);
	if (!*fdt) {
		log_err("Out of memory\n");
		ret = EFI_OUT_OF_RESOURCES;
		goto out;
	}
	ret = EFI_CALL(f->read(f, &filesize, *fdt));
	if (ret != EFI_SUCCESS) {
		log_err("Can't read fdt\n");
		free(*fdt);
		*fdt = NULL;
	}

out:
	efi_free_pool(dp);
	if (f)
		EFI_CALL(f->close(f));

	return ret;
}

/**
 * efi_bootmgr_run() - execute EFI boot manager
 * @fdt:	Flat device tree
 *
 * Invoke EFI boot manager and execute a binary depending on
 * boot options. If @fdt is not NULL, it will be passed to
 * the executed binary.
 *
 * Return:	status code
 */
efi_status_t efi_bootmgr_run(void *fdt)
{
	efi_handle_t handle;
	void *load_options;
	efi_status_t ret;
	void *fdt_lo, *fdt_distro = NULL;
	efi_uintn_t fdt_size;

	/* Initialize EFI drivers */
	ret = efi_init_obj_list();
	if (ret != EFI_SUCCESS)
		return ret;

	ret = efi_bootmgr_load(&handle, &load_options);
	if (ret != EFI_SUCCESS) {
		log_notice("EFI boot manager: Cannot load any image\n");
		return ret;
	}

	if (!IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
		ret = load_fdt_from_load_option(&fdt_lo);
		if (ret != EFI_SUCCESS)
			return ret;
		if (fdt_lo)
			fdt = fdt_lo;
		if (!fdt) {
			efi_load_distro_fdt(handle, &fdt_distro, &fdt_size);
			fdt = fdt_distro;
		}
	}

	/*
	 * Needed in ACPI case to create reservations based on
	 * control device-tree.
	 */
	ret = efi_install_fdt(fdt);

	if (!IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
		free(fdt_lo);
		if (fdt_distro)
			efi_free_pages((uintptr_t)fdt_distro,
				       efi_size_in_pages(fdt_size));
	}

	if (ret != EFI_SUCCESS) {
		if (EFI_CALL(efi_unload_image(handle)) == EFI_SUCCESS)
			free(load_options);
		else
			log_err("Unloading image failed\n");

		return ret;
	}

	return do_bootefi_exec(handle, load_options);
}
