// SPDX-License-Identifier: GPL-2.0+
/*
 *  EFI Capsule
 *
 *  Copyright (c) 2018 Linaro Limited
 *			Author: AKASHI Takahiro
 */

#define LOG_CATEGORY LOGC_EFI

#include <common.h>
#include <efi_loader.h>
#include <efi_variable.h>
#include <env.h>
#include <fdtdec.h>
#include <fs.h>
#include <hang.h>
#include <malloc.h>
#include <mapmem.h>
#include <sort.h>
#include <sysreset.h>
#include <asm/global_data.h>

#include <crypto/pkcs7.h>
#include <crypto/pkcs7_parser.h>
#include <linux/err.h>

DECLARE_GLOBAL_DATA_PTR;

const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
static const efi_guid_t efi_guid_firmware_management_capsule_id =
		EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
const efi_guid_t efi_guid_firmware_management_protocol =
		EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;

#ifdef CONFIG_EFI_CAPSULE_ON_DISK
/* for file system access */
static struct efi_file_handle *bootdev_root;
#endif

/**
 * get_last_capsule - get the last capsule index
 *
 * Retrieve the index of the capsule invoked last time from "CapsuleLast"
 * variable.
 *
 * Return:
 * * > 0	- the last capsule index invoked
 * * 0xffff	- on error, or no capsule invoked yet
 */
static __maybe_unused unsigned int get_last_capsule(void)
{
	u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
	char value[5];
	efi_uintn_t size;
	unsigned long index = 0xffff;
	efi_status_t ret;
	int i;

	size = sizeof(value16);
	ret = efi_get_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
				   NULL, &size, value16, NULL);
	if (ret != EFI_SUCCESS || size != 22 ||
	    u16_strncmp(value16, u"Capsule", 7))
		goto err;
	for (i = 0; i < 4; ++i) {
		u16 c = value16[i + 7];

		if (!c || c > 0x7f)
			goto err;
		value[i] = c;
	}
	value[4] = 0;
	if (strict_strtoul(value, 16, &index))
		index = 0xffff;
err:
	return index;
}

/**
 * set_capsule_result - set a result variable
 * @capsule:		Capsule
 * @return_status:	Return status
 *
 * Create and set a result variable, "CapsuleXXXX", for the capsule,
 * @capsule.
 */
static __maybe_unused
void set_capsule_result(int index, struct efi_capsule_header *capsule,
			efi_status_t return_status)
{
	u16 variable_name16[12];
	struct efi_capsule_result_variable_header result;
	struct efi_time time;
	efi_status_t ret;

	efi_create_indexed_name(variable_name16, sizeof(variable_name16),
				"Capsule", index);
	result.variable_total_size = sizeof(result);
	result.capsule_guid = capsule->capsule_guid;
	ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL));
	if (ret == EFI_SUCCESS)
		memcpy(&result.capsule_processed, &time, sizeof(time));
	else
		memset(&result.capsule_processed, 0, sizeof(time));
	result.capsule_status = return_status;
	ret = efi_set_variable_int(variable_name16, &efi_guid_capsule_report,
				   EFI_VARIABLE_NON_VOLATILE |
				   EFI_VARIABLE_BOOTSERVICE_ACCESS |
				   EFI_VARIABLE_RUNTIME_ACCESS,
				   sizeof(result), &result, false);
	if (ret != EFI_SUCCESS) {
		log_err("Setting %ls failed\n", variable_name16);
		return;
	}

	/* Variable CapsuleLast must not include terminating 0x0000 */
	ret = efi_set_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
				   EFI_VARIABLE_READ_ONLY |
				   EFI_VARIABLE_NON_VOLATILE |
				   EFI_VARIABLE_BOOTSERVICE_ACCESS |
				   EFI_VARIABLE_RUNTIME_ACCESS,
				   22, variable_name16, false);
	if (ret != EFI_SUCCESS)
		log_err("Setting %ls failed\n", u"CapsuleLast");
}

#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT
/**
 * efi_fmp_find - search for Firmware Management Protocol drivers
 * @image_type:		Image type guid
 * @image_index:	Image Index
 * @instance:		Instance number
 * @handles:		Handles of FMP drivers
 * @no_handles:		Number of handles
 *
 * Search for Firmware Management Protocol drivers, matching the image
 * type, @image_type and the machine instance, @instance, from the list,
 * @handles.
 *
 * Return:
 * * Protocol instance	- on success
 * * NULL		- on failure
 */
static struct efi_firmware_management_protocol *
efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance,
	     efi_handle_t *handles, efi_uintn_t no_handles)
{
	efi_handle_t *handle;
	struct efi_firmware_management_protocol *fmp;
	struct efi_firmware_image_descriptor *image_info, *desc;
	efi_uintn_t info_size, descriptor_size;
	u32 descriptor_version;
	u8 descriptor_count;
	u32 package_version;
	u16 *package_version_name;
	bool found = false;
	int i, j;
	efi_status_t ret;

	for (i = 0, handle = handles; i < no_handles; i++, handle++) {
		ret = EFI_CALL(efi_handle_protocol(
				*handle,
				&efi_guid_firmware_management_protocol,
				(void **)&fmp));
		if (ret != EFI_SUCCESS)
			continue;

		/* get device's image info */
		info_size = 0;
		image_info = NULL;
		descriptor_version = 0;
		descriptor_count = 0;
		descriptor_size = 0;
		package_version = 0;
		package_version_name = NULL;
		ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
						   image_info,
						   &descriptor_version,
						   &descriptor_count,
						   &descriptor_size,
						   &package_version,
						   &package_version_name));
		if (ret != EFI_BUFFER_TOO_SMALL)
			goto skip;

		image_info = malloc(info_size);
		if (!image_info)
			goto skip;

		ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
						   image_info,
						   &descriptor_version,
						   &descriptor_count,
						   &descriptor_size,
						   &package_version,
						   &package_version_name));
		if (ret != EFI_SUCCESS ||
		    descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
			goto skip;

		/* matching */
		for (j = 0, desc = image_info; j < descriptor_count;
		     j++, desc = (void *)desc + descriptor_size) {
			log_debug("+++ desc[%d] index: %d, name: %ls\n",
				  j, desc->image_index, desc->image_id_name);
			if (!guidcmp(&desc->image_type_id, image_type) &&
			    (desc->image_index == image_index) &&
			    (!instance ||
			     !desc->hardware_instance ||
			      desc->hardware_instance == instance))
				found = true;
		}

skip:
		efi_free_pool(package_version_name);
		free(image_info);
		EFI_CALL(efi_close_protocol(
				(efi_handle_t)fmp,
				&efi_guid_firmware_management_protocol,
				NULL, NULL));
		if (found)
			return fmp;
	}

	return NULL;
}

/**
 * efi_remove_auth_hdr - remove authentication data from image
 * @image:	Pointer to pointer to Image
 * @image_size:	Pointer to Image size
 *
 * Remove the authentication data from image if possible.
 * Update @image and @image_size.
 *
 * Return:		status code
 */
static efi_status_t efi_remove_auth_hdr(void **image, efi_uintn_t *image_size)
{
	struct efi_firmware_image_authentication *auth_hdr;
	efi_status_t ret = EFI_INVALID_PARAMETER;

	auth_hdr = (struct efi_firmware_image_authentication *)*image;
	if (*image_size < sizeof(*auth_hdr))
		goto out;

	if (auth_hdr->auth_info.hdr.dwLength <=
	    offsetof(struct win_certificate_uefi_guid, cert_data))
		goto out;

	*image = (uint8_t *)*image + sizeof(auth_hdr->monotonic_count) +
		auth_hdr->auth_info.hdr.dwLength;
	*image_size = *image_size - auth_hdr->auth_info.hdr.dwLength -
		sizeof(auth_hdr->monotonic_count);

	ret = EFI_SUCCESS;
out:
	return ret;
}

#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
{
	const void *fdt_blob = gd->fdt_blob;
	const void *blob;
	const char *cnode_name = "capsule-key";
	const char *snode_name = "signature";
	int sig_node;
	int len;

	sig_node = fdt_subnode_offset(fdt_blob, 0, snode_name);
	if (sig_node < 0) {
		log_err("Unable to get signature node offset\n");

		return -FDT_ERR_NOTFOUND;
	}

	blob = fdt_getprop(fdt_blob, sig_node, cnode_name, &len);

	if (!blob || len < 0) {
		log_err("Unable to get capsule-key value\n");
		*pkey = NULL;
		*pkey_len = 0;

		return -FDT_ERR_NOTFOUND;
	}

	*pkey = (void *)blob;
	*pkey_len = len;

	return 0;
}

efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
				      void **image, efi_uintn_t *image_size)
{
	u8 *buf;
	int ret;
	void *fdt_pkey, *pkey;
	efi_uintn_t pkey_len;
	uint64_t monotonic_count;
	struct efi_signature_store *truststore;
	struct pkcs7_message *capsule_sig;
	struct efi_image_regions *regs;
	struct efi_firmware_image_authentication *auth_hdr;
	efi_status_t status;

	status = EFI_SECURITY_VIOLATION;
	capsule_sig = NULL;
	truststore = NULL;
	regs = NULL;

	/* Sanity checks */
	if (capsule == NULL || capsule_size == 0)
		goto out;

	*image = (uint8_t *)capsule;
	*image_size = capsule_size;
	if (efi_remove_auth_hdr(image, image_size) != EFI_SUCCESS)
		goto out;

	auth_hdr = (struct efi_firmware_image_authentication *)capsule;
	if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
		goto out;

	memcpy(&monotonic_count, &auth_hdr->monotonic_count,
	       sizeof(monotonic_count));

	/* data to be digested */
	regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 2, 1);
	if (!regs)
		goto out;

	regs->max = 2;
	efi_image_region_add(regs, (uint8_t *)*image,
			     (uint8_t *)*image + *image_size, 1);

	efi_image_region_add(regs, (uint8_t *)&monotonic_count,
			     (uint8_t *)&monotonic_count + sizeof(monotonic_count),
			     1);

	capsule_sig = efi_parse_pkcs7_header(auth_hdr->auth_info.cert_data,
					     auth_hdr->auth_info.hdr.dwLength
					     - sizeof(auth_hdr->auth_info),
					     &buf);
	if (IS_ERR(capsule_sig)) {
		debug("Parsing variable's pkcs7 header failed\n");
		capsule_sig = NULL;
		goto out;
	}

	ret = efi_get_public_key_data(&fdt_pkey, &pkey_len);
	if (ret < 0)
		goto out;

	pkey = malloc(pkey_len);
	if (!pkey)
		goto out;

	memcpy(pkey, fdt_pkey, pkey_len);
	truststore = efi_build_signature_store(pkey, pkey_len);
	if (!truststore)
		goto out;

	/* verify signature */
	if (efi_signature_verify(regs, capsule_sig, truststore, NULL)) {
		debug("Verified\n");
	} else {
		debug("Verifying variable's signature failed\n");
		goto out;
	}

	status = EFI_SUCCESS;

out:
	efi_sigstore_free(truststore);
	pkcs7_free_message(capsule_sig);
	free(regs);

	return status;
}
#else
efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
				      void **image, efi_uintn_t *image_size)
{
	return EFI_UNSUPPORTED;
}
#endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */


/**
 * efi_capsule_update_firmware - update firmware from capsule
 * @capsule_data:	Capsule
 *
 * Update firmware, using a capsule, @capsule_data. Loading any FMP
 * drivers embedded in a capsule is not supported.
 *
 * Return:		status code
 */
static efi_status_t efi_capsule_update_firmware(
		struct efi_capsule_header *capsule_data)
{
	struct efi_firmware_management_capsule_header *capsule;
	struct efi_firmware_management_capsule_image_header *image;
	size_t capsule_size, image_binary_size;
	void *image_binary, *vendor_code;
	efi_handle_t *handles;
	efi_uintn_t no_handles;
	int item;
	struct efi_firmware_management_protocol *fmp;
	u16 *abort_reason;
	efi_status_t ret = EFI_SUCCESS;

	/* sanity check */
	if (capsule_data->header_size < sizeof(*capsule) ||
	    capsule_data->header_size >= capsule_data->capsule_image_size)
		return EFI_INVALID_PARAMETER;

	capsule = (void *)capsule_data + capsule_data->header_size;
	capsule_size = capsule_data->capsule_image_size
			- capsule_data->header_size;

	if (capsule->version != 0x00000001)
		return EFI_UNSUPPORTED;

	handles = NULL;
	ret = EFI_CALL(efi_locate_handle_buffer(
			BY_PROTOCOL,
			&efi_guid_firmware_management_protocol,
			NULL, &no_handles, (efi_handle_t **)&handles));
	if (ret != EFI_SUCCESS)
		return EFI_UNSUPPORTED;

	/* Payload */
	for (item = capsule->embedded_driver_count;
	     item < capsule->embedded_driver_count
		    + capsule->payload_item_count; item++) {
		/* sanity check */
		if ((capsule->item_offset_list[item] + sizeof(*image)
				 >= capsule_size)) {
			log_err("Capsule does not have enough data\n");
			ret = EFI_INVALID_PARAMETER;
			goto out;
		}

		image = (void *)capsule + capsule->item_offset_list[item];

		if (image->version != 0x00000003) {
			ret = EFI_UNSUPPORTED;
			goto out;
		}

		/* find a device for update firmware */
		fmp = efi_fmp_find(&image->update_image_type_id,
				   image->update_image_index,
				   image->update_hardware_instance,
				   handles, no_handles);
		if (!fmp) {
			log_err("FMP driver not found for firmware type %pUs, hardware instance %lld\n",
				&image->update_image_type_id,
				image->update_hardware_instance);
			ret = EFI_UNSUPPORTED;
			goto out;
		}

		/* do update */
		if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
		    !(image->image_capsule_support &
				CAPSULE_SUPPORT_AUTHENTICATION)) {
			/* no signature */
			ret = EFI_SECURITY_VIOLATION;
			goto out;
		}

		image_binary = (void *)image + sizeof(*image);
		image_binary_size = image->update_image_size;
		vendor_code = image_binary + image_binary_size;
		if (!IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
		    (image->image_capsule_support &
				CAPSULE_SUPPORT_AUTHENTICATION)) {
			ret = efi_remove_auth_hdr(&image_binary,
						  &image_binary_size);
			if (ret != EFI_SUCCESS)
				goto out;
		}

		abort_reason = NULL;
		ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
					      image_binary,
					      image_binary_size,
					      vendor_code, NULL,
					      &abort_reason));
		if (ret != EFI_SUCCESS) {
			log_err("Firmware update failed: %ls\n",
				abort_reason);
			efi_free_pool(abort_reason);
			goto out;
		}
	}

out:
	efi_free_pool(handles);

	return ret;
}
#else
static efi_status_t efi_capsule_update_firmware(
		struct efi_capsule_header *capsule_data)
{
	return EFI_UNSUPPORTED;
}
#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */

/**
 * efi_update_capsule() - process information from operating system
 * @capsule_header_array:	Array of virtual address pointers
 * @capsule_count:		Number of pointers in capsule_header_array
 * @scatter_gather_list:	Array of physical address pointers
 *
 * This function implements the UpdateCapsule() runtime service.
 *
 * See the Unified Extensible Firmware Interface (UEFI) specification for
 * details.
 *
 * Return:			status code
 */
efi_status_t EFIAPI efi_update_capsule(
		struct efi_capsule_header **capsule_header_array,
		efi_uintn_t capsule_count,
		u64 scatter_gather_list)
{
	struct efi_capsule_header *capsule;
	unsigned int i;
	efi_status_t ret;

	EFI_ENTRY("%p, %zu, %llu\n", capsule_header_array, capsule_count,
		  scatter_gather_list);

	if (!capsule_count) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	ret = EFI_SUCCESS;
	for (i = 0, capsule = *capsule_header_array; i < capsule_count;
	     i++, capsule = *(++capsule_header_array)) {
		/* sanity check */
		if (capsule->header_size < sizeof(*capsule) ||
		    capsule->capsule_image_size < sizeof(*capsule)) {
			log_err("Capsule does not have enough data\n");
			continue;
		}

		log_debug("Capsule[%d] (guid:%pUs)\n",
			  i, &capsule->capsule_guid);
		if (!guidcmp(&capsule->capsule_guid,
			     &efi_guid_firmware_management_capsule_id)) {
			ret  = efi_capsule_update_firmware(capsule);
		} else {
			log_err("Unsupported capsule type: %pUs\n",
				&capsule->capsule_guid);
			ret = EFI_UNSUPPORTED;
		}

		if (ret != EFI_SUCCESS)
			goto out;
	}

	if (IS_ENABLED(CONFIG_EFI_ESRT)) {
		/* Rebuild the ESRT to reflect any updated FW images. */
		ret = efi_esrt_populate();
		if (ret != EFI_SUCCESS)
			log_warning("ESRT update failed\n");
	}
out:

	return EFI_EXIT(ret);
}

/**
 * efi_query_capsule_caps() - check if capsule is supported
 * @capsule_header_array:	Array of virtual pointers
 * @capsule_count:		Number of pointers in capsule_header_array
 * @maximum_capsule_size:	Maximum capsule size
 * @reset_type:			Type of reset needed for capsule update
 *
 * This function implements the QueryCapsuleCapabilities() runtime service.
 *
 * See the Unified Extensible Firmware Interface (UEFI) specification for
 * details.
 *
 * Return:			status code
 */
efi_status_t EFIAPI efi_query_capsule_caps(
		struct efi_capsule_header **capsule_header_array,
		efi_uintn_t capsule_count,
		u64 *maximum_capsule_size,
		u32 *reset_type)
{
	struct efi_capsule_header *capsule __attribute__((unused));
	unsigned int i;
	efi_status_t ret;

	EFI_ENTRY("%p, %zu, %p, %p\n", capsule_header_array, capsule_count,
		  maximum_capsule_size, reset_type);

	if (!maximum_capsule_size) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	*maximum_capsule_size = U64_MAX;
	*reset_type = EFI_RESET_COLD;

	ret = EFI_SUCCESS;
	for (i = 0, capsule = *capsule_header_array; i < capsule_count;
	     i++, capsule = *(++capsule_header_array)) {
		/* TODO */
	}
out:
	return EFI_EXIT(ret);
}

/**
 * efi_load_capsule_drivers - initialize capsule drivers
 *
 * Generic FMP drivers backed by DFU
 *
 * Return:	status code
 */
efi_status_t __weak efi_load_capsule_drivers(void)
{
	__maybe_unused efi_handle_t handle;
	efi_status_t ret = EFI_SUCCESS;

	if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
		handle = NULL;
		ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
				&handle, &efi_guid_firmware_management_protocol,
				&efi_fmp_fit, NULL));
	}

	if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
		handle = NULL;
		ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
				&handle,
				&efi_guid_firmware_management_protocol,
				&efi_fmp_raw, NULL));
	}

	return ret;
}

#ifdef CONFIG_EFI_CAPSULE_ON_DISK
/**
 * get_dp_device - retrieve a device  path from boot variable
 * @boot_var:	Boot variable name
 * @device_dp	Device path
 *
 * Retrieve a device patch from boot variable, @boot_var.
 *
 * Return:	status code
 */
static efi_status_t get_dp_device(u16 *boot_var,
				  struct efi_device_path **device_dp)
{
	void *buf = NULL;
	efi_uintn_t size;
	struct efi_load_option lo;
	struct efi_device_path *file_dp;
	efi_status_t ret;

	size = 0;
	ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
				   NULL, &size, NULL, NULL);
	if (ret == EFI_BUFFER_TOO_SMALL) {
		buf = malloc(size);
		if (!buf)
			return EFI_OUT_OF_RESOURCES;
		ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
					   NULL, &size, buf, NULL);
	}
	if (ret != EFI_SUCCESS)
		return ret;

	efi_deserialize_load_option(&lo, buf, &size);

	if (lo.attributes & LOAD_OPTION_ACTIVE) {
		efi_dp_split_file_path(lo.file_path, device_dp, &file_dp);
		efi_free_pool(file_dp);

		ret = EFI_SUCCESS;
	} else {
		ret = EFI_NOT_FOUND;
	}

	free(buf);

	return ret;
}

/**
 * device_is_present_and_system_part - check if a device exists
 *
 * Check if a device pointed to by the device path, @dp, exists and is
 * located in UEFI system partition.
 *
 * @dp		device path
 * Return:	true - yes, false - no
 */
static bool device_is_present_and_system_part(struct efi_device_path *dp)
{
	efi_handle_t handle;
	struct efi_device_path *rem;

	/* Check device exists */
	handle = efi_dp_find_obj(dp, NULL, NULL);
	if (!handle)
		return false;

	/* Check device is on system partition */
	handle = efi_dp_find_obj(dp, &efi_system_partition_guid, &rem);
	if (!handle)
		return false;

	return true;
}

/**
 * find_boot_device - identify the boot device
 *
 * Identify the boot device from boot-related variables as UEFI
 * specification describes and put its handle into bootdev_root.
 *
 * Return:	status code
 */
static efi_status_t find_boot_device(void)
{
	char boot_var[9];
	u16 boot_var16[9], *p, bootnext, *boot_order = NULL;
	efi_uintn_t size;
	int i, num;
	struct efi_simple_file_system_protocol *volume;
	struct efi_device_path *boot_dev = NULL;
	efi_status_t ret;

	/* find active boot device in BootNext */
	bootnext = 0;
	size = sizeof(bootnext);
	ret = efi_get_variable_int(u"BootNext",
				   (efi_guid_t *)&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");
			goto skip;
		}
		sprintf((char *)boot_var, "Boot%04X", bootnext);
		p = boot_var16;
		utf8_utf16_strcpy(&p, boot_var);

		ret = get_dp_device(boot_var16, &boot_dev);
		if (ret == EFI_SUCCESS) {
			if (device_is_present_and_system_part(boot_dev)) {
				goto found;
			} else {
				efi_free_pool(boot_dev);
				boot_dev = NULL;
			}
		}
	}

skip:
	/* find active boot device in BootOrder */
	size = 0;
	ret = efi_get_variable_int(u"BootOrder", &efi_global_variable_guid,
				   NULL, &size, NULL, NULL);
	if (ret == EFI_BUFFER_TOO_SMALL) {
		boot_order = malloc(size);
		if (!boot_order) {
			ret = EFI_OUT_OF_RESOURCES;
			goto out;
		}

		ret = efi_get_variable_int(u"BootOrder",
					   &efi_global_variable_guid,
					   NULL, &size, boot_order, NULL);
	}
	if (ret != EFI_SUCCESS)
		goto out;

	/* check in higher order */
	num = size / sizeof(u16);
	for (i = 0; i < num; i++) {
		sprintf((char *)boot_var, "Boot%04X", boot_order[i]);
		p = boot_var16;
		utf8_utf16_strcpy(&p, boot_var);
		ret = get_dp_device(boot_var16, &boot_dev);
		if (ret != EFI_SUCCESS)
			continue;

		if (device_is_present_and_system_part(boot_dev))
			break;

		efi_free_pool(boot_dev);
		boot_dev = NULL;
	}
found:
	if (boot_dev) {
		log_debug("Boot device %pD\n", boot_dev);

		volume = efi_fs_from_path(boot_dev);
		if (!volume)
			ret = EFI_DEVICE_ERROR;
		else
			ret = EFI_CALL(volume->open_volume(volume,
							   &bootdev_root));
		efi_free_pool(boot_dev);
	} else {
		ret = EFI_NOT_FOUND;
	}
out:
	free(boot_order);

	return ret;
}

/**
 * efi_capsule_scan_dir - traverse a capsule directory in boot device
 * @files:	Array of file names
 * @num:	Number of elements in @files
 *
 * Traverse a capsule directory in boot device.
 * Called by initialization code, and returns an array of capsule file
 * names in @files.
 *
 * Return:	status code
 */
static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
{
	struct efi_file_handle *dirh;
	struct efi_file_info *dirent;
	efi_uintn_t dirent_size, tmp_size;
	unsigned int count;
	u16 **tmp_files;
	efi_status_t ret;

	ret = find_boot_device();
	if (ret == EFI_NOT_FOUND) {
		log_debug("Boot device is not set\n");
		*num = 0;
		return EFI_SUCCESS;
	} else if (ret != EFI_SUCCESS) {
		return EFI_DEVICE_ERROR;
	}

	/* count capsule files */
	ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
					     EFI_CAPSULE_DIR,
					     EFI_FILE_MODE_READ, 0));
	if (ret != EFI_SUCCESS) {
		*num = 0;
		return EFI_SUCCESS;
	}

	dirent_size = 256;
	dirent = malloc(dirent_size);
	if (!dirent)
		return EFI_OUT_OF_RESOURCES;

	count = 0;
	while (1) {
		tmp_size = dirent_size;
		ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
		if (ret == EFI_BUFFER_TOO_SMALL) {
			struct efi_file_info *old_dirent = dirent;

			dirent = realloc(dirent, tmp_size);
			if (!dirent) {
				dirent = old_dirent;
				ret = EFI_OUT_OF_RESOURCES;
				goto err;
			}
			dirent_size = tmp_size;
			ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
		}
		if (ret != EFI_SUCCESS)
			goto err;
		if (!tmp_size)
			break;

		if (!(dirent->attribute & EFI_FILE_DIRECTORY))
			count++;
	}

	ret = EFI_CALL((*dirh->setpos)(dirh, 0));
	if (ret != EFI_SUCCESS)
		goto err;

	/* make a list */
	tmp_files = malloc(count * sizeof(*tmp_files));
	if (!tmp_files) {
		ret = EFI_OUT_OF_RESOURCES;
		goto err;
	}

	count = 0;
	while (1) {
		tmp_size = dirent_size;
		ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
		if (ret != EFI_SUCCESS)
			goto err;
		if (!tmp_size)
			break;

		if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
		    u16_strcmp(dirent->file_name, u".") &&
		    u16_strcmp(dirent->file_name, u".."))
			tmp_files[count++] = u16_strdup(dirent->file_name);
	}
	/* ignore an error */
	EFI_CALL((*dirh->close)(dirh));

	/* in ascii order */
	/* FIXME: u16 version of strcasecmp */
	qsort(tmp_files, count, sizeof(*tmp_files),
	      (int (*)(const void *, const void *))strcasecmp);
	*files = tmp_files;
	*num = count;
	ret = EFI_SUCCESS;
err:
	free(dirent);

	return ret;
}

/**
 * efi_capsule_read_file - read in a capsule file
 * @filename:	File name
 * @capsule:	Pointer to buffer for capsule
 *
 * Read a capsule file and put its content in @capsule.
 *
 * Return:	status code
 */
static efi_status_t efi_capsule_read_file(const u16 *filename,
					  struct efi_capsule_header **capsule)
{
	struct efi_file_handle *dirh, *fh;
	struct efi_file_info *file_info = NULL;
	struct efi_capsule_header *buf = NULL;
	efi_uintn_t size;
	efi_status_t ret;

	ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
					     EFI_CAPSULE_DIR,
					     EFI_FILE_MODE_READ, 0));
	if (ret != EFI_SUCCESS)
		return ret;
	ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
				     EFI_FILE_MODE_READ, 0));
	/* ignore an error */
	EFI_CALL((*dirh->close)(dirh));
	if (ret != EFI_SUCCESS)
		return ret;

	/* file size */
	size = 0;
	ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
				      &size, file_info));
	if (ret == EFI_BUFFER_TOO_SMALL) {
		file_info = malloc(size);
		if (!file_info) {
			ret = EFI_OUT_OF_RESOURCES;
			goto err;
		}
		ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
					      &size, file_info));
	}
	if (ret != EFI_SUCCESS)
		goto err;
	size = file_info->file_size;
	free(file_info);
	buf = malloc(size);
	if (!buf) {
		ret = EFI_OUT_OF_RESOURCES;
		goto err;
	}

	/* fetch data */
	ret = EFI_CALL((*fh->read)(fh, &size, buf));
	if (ret == EFI_SUCCESS) {
		if (size >= buf->capsule_image_size) {
			*capsule = buf;
		} else {
			free(buf);
			ret = EFI_INVALID_PARAMETER;
		}
	} else {
		free(buf);
	}
err:
	EFI_CALL((*fh->close)(fh));

	return ret;
}

/**
 * efi_capsule_delete_file - delete a capsule file
 * @filename:	File name
 *
 * Delete a capsule file from capsule directory.
 *
 * Return:	status code
 */
static efi_status_t efi_capsule_delete_file(const u16 *filename)
{
	struct efi_file_handle *dirh, *fh;
	efi_status_t ret;

	ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
					     EFI_CAPSULE_DIR,
					     EFI_FILE_MODE_READ, 0));
	if (ret != EFI_SUCCESS)
		return ret;
	ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
				     EFI_FILE_MODE_READ, 0));
	/* ignore an error */
	EFI_CALL((*dirh->close)(dirh));

	if (ret == EFI_SUCCESS)
		ret = EFI_CALL((*fh->delete)(fh));

	return ret;
}

/**
 * efi_capsule_scan_done - reset a scan help function
 *
 * Reset a scan help function
 */
static void efi_capsule_scan_done(void)
{
	EFI_CALL((*bootdev_root->close)(bootdev_root));
	bootdev_root = NULL;
}

/**
 * check_run_capsules() - check whether capsule update should run
 *
 * The spec says OsIndications must be set in order to run the capsule update
 * on-disk.  Since U-Boot doesn't support runtime SetVariable, allow capsules to
 * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
 *
 * Return:	EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise
 */
static efi_status_t check_run_capsules(void)
{
	u64 os_indications;
	efi_uintn_t size;
	efi_status_t r;

	size = sizeof(os_indications);
	r = efi_get_variable_int(u"OsIndications", &efi_global_variable_guid,
				 NULL, &size, &os_indications, NULL);
	if (r != EFI_SUCCESS || size != sizeof(os_indications))
		return EFI_NOT_FOUND;

	if (os_indications &
	    EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) {
		os_indications &=
			~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
		r = efi_set_variable_int(u"OsIndications",
					 &efi_global_variable_guid,
					 EFI_VARIABLE_NON_VOLATILE |
					 EFI_VARIABLE_BOOTSERVICE_ACCESS |
					 EFI_VARIABLE_RUNTIME_ACCESS,
					 sizeof(os_indications),
					 &os_indications, false);
		if (r != EFI_SUCCESS)
			log_err("Setting %ls failed\n", L"OsIndications");
		return EFI_SUCCESS;
	} else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
		return EFI_SUCCESS;
	} else  {
		return EFI_NOT_FOUND;
	}
}

/**
 * efi_launch_capsule - launch capsules
 *
 * Launch all the capsules in system at boot time.
 * Called by efi init code
 *
 * Return:	status codde
 */
efi_status_t efi_launch_capsules(void)
{
	struct efi_capsule_header *capsule = NULL;
	u16 **files;
	unsigned int nfiles, index, i;
	efi_status_t ret;

	if (check_run_capsules() != EFI_SUCCESS)
		return EFI_SUCCESS;

	index = get_last_capsule();

	/*
	 * Find capsules on disk.
	 * All the capsules are collected at the beginning because
	 * capsule files will be removed instantly.
	 */
	nfiles = 0;
	files = NULL;
	ret = efi_capsule_scan_dir(&files, &nfiles);
	if (ret != EFI_SUCCESS)
		return ret;
	if (!nfiles)
		return EFI_SUCCESS;

	/* Launch capsules */
	for (i = 0, ++index; i < nfiles; i++, index++) {
		log_debug("Applying %ls\n", files[i]);
		if (index > 0xffff)
			index = 0;
		ret = efi_capsule_read_file(files[i], &capsule);
		if (ret == EFI_SUCCESS) {
			ret = efi_capsule_update_firmware(capsule);
			if (ret != EFI_SUCCESS)
				log_err("Applying capsule %ls failed.\n",
					files[i]);
			else
				log_info("Applying capsule %ls succeeded.\n",
					 files[i]);

			/* create CapsuleXXXX */
			set_capsule_result(index, capsule, ret);

			free(capsule);
		} else {
			log_err("Reading capsule %ls failed\n", files[i]);
		}
		/* delete a capsule either in case of success or failure */
		ret = efi_capsule_delete_file(files[i]);
		if (ret != EFI_SUCCESS)
			log_err("Deleting capsule %ls failed\n",
				files[i]);
	}
	efi_capsule_scan_done();

	for (i = 0; i < nfiles; i++)
		free(files[i]);
	free(files);

	/*
	 * UEFI spec requires to reset system after complete processing capsule
	 * update on the storage.
	 */
	log_info("Reboot after firmware update.\n");
	/* Cold reset is required for loading the new firmware. */
	sysreset_walk_halt(SYSRESET_COLD);
	hang();
	/* not reach here */

	return 0;
}
#endif /* CONFIG_EFI_CAPSULE_ON_DISK */
