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

#define LOG_CATEGORY LOGC_EFI

#include <efi_loader.h>
#include <efi_variable.h>
#include <env.h>
#include <fdtdec.h>
#include <fs.h>
#include <fwu.h>
#include <hang.h>
#include <malloc.h>
#include <mapmem.h>
#include <sort.h>
#include <sysreset.h>
#include <asm/global_data.h>
#include <u-boot/uuid.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;
const efi_guid_t fwu_guid_os_request_fw_revert =
		FWU_OS_REQUEST_FW_REVERT_GUID;
const efi_guid_t fwu_guid_os_request_fw_accept =
		FWU_OS_REQUEST_FW_ACCEPT_GUID;

#define FW_ACCEPT_OS	(u32)0x8000

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

static __maybe_unused unsigned int get_capsule_index(const u16 *variable_name)
{
	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(variable_name, &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;
}

/**
 * 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)
{
	return get_capsule_index(u"CapsuleLast");
}

/**
 * get_max_capsule - get the max capsule index
 *
 * Retrieve the max capsule index value from "CapsuleMax" variable.
 *
 * Return:
 * * > 0	- the max capsule index
 * * 0xffff	- on error, or "CapsuleMax" variable does not exist
 */
static __maybe_unused unsigned int get_max_capsule(void)
{
	return get_capsule_index(u"CapsuleMax");
}

/**
 * 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++) {
		struct efi_handler *fmp_handler;

		ret = efi_search_protocol(
				*handle, &efi_guid_firmware_management_protocol,
				&fmp_handler);
		if (ret != EFI_SUCCESS)
			continue;
		fmp = fmp_handler->protocol_interface;

		/* 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);
		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 (!capsule_sig) {
		debug("Parsing variable's pkcs7 header failed\n");
		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;
}
#endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */

static __maybe_unused bool fwu_empty_capsule(struct efi_capsule_header *capsule)
{
	return !guidcmp(&capsule->capsule_guid,
			&fwu_guid_os_request_fw_revert) ||
		!guidcmp(&capsule->capsule_guid,
			 &fwu_guid_os_request_fw_accept);
}

static __maybe_unused efi_status_t fwu_to_efi_error(int err)
{
	efi_status_t ret;

	switch(err) {
	case 0:
		ret = EFI_SUCCESS;
		break;
	case -ERANGE:
	case -EIO:
		ret = EFI_DEVICE_ERROR;
		break;
	case -EINVAL:
		ret = EFI_INVALID_PARAMETER;
		break;
	case -ENODEV:
		ret = EFI_NOT_FOUND;
		break;
	default:
		ret = EFI_OUT_OF_RESOURCES;
	}

	return ret;
}

static __maybe_unused efi_status_t fwu_empty_capsule_process(
	struct efi_capsule_header *capsule)
{
	int status;
	u32 active_idx;
	efi_guid_t *image_guid;
	efi_status_t ret = EFI_INVALID_PARAMETER;

	if (!guidcmp(&capsule->capsule_guid,
		     &fwu_guid_os_request_fw_revert)) {
		/*
		 * One of the previously updated image has
		 * failed the OS acceptance test. OS has
		 * requested to revert back to the earlier
		 * boot index
		 */
		status = fwu_revert_boot_index();
		ret = fwu_to_efi_error(status);
		if (ret == EFI_SUCCESS)
			log_debug("Reverted the FWU active_index. Recommend rebooting the system\n");
		else
			log_err("Failed to revert the FWU boot index\n");
	} else if (!guidcmp(&capsule->capsule_guid,
			    &fwu_guid_os_request_fw_accept)) {
		/*
		 * Image accepted by the OS. Set the acceptance
		 * status for the image.
		 */
		image_guid = (void *)(char *)capsule +
			capsule->header_size;

		status = fwu_get_active_index(&active_idx);
		ret = fwu_to_efi_error(status);
		if (ret != EFI_SUCCESS) {
			log_err("Unable to get the active_index from the FWU metadata\n");
			return ret;
		}

		status = fwu_accept_image(image_guid, active_idx);
		ret = fwu_to_efi_error(status);
		if (ret != EFI_SUCCESS)
			log_err("Unable to set the Accept bit for the image %pUs\n",
				image_guid);

		status = fwu_state_machine_updates(0, active_idx);
		if (status < 0)
			ret = EFI_DEVICE_ERROR;

	}

	return ret;
}

static __maybe_unused void fwu_post_update_checks(
	struct efi_capsule_header *capsule,
	bool *fw_accept_os, bool *capsule_update)
{
	if (fwu_empty_capsule(capsule))
		*capsule_update = false;
	else
		if (!*fw_accept_os)
			*fw_accept_os =
				capsule->flags & FW_ACCEPT_OS ? true : false;
}

static __maybe_unused efi_status_t fwu_post_update_process(bool fw_accept_os)
{
	int status;
	uint update_index;
	efi_status_t ret;

	status = fwu_plat_get_update_index(&update_index);
	if (status < 0) {
		log_err("Failed to get the FWU update_index value\n");
		return EFI_DEVICE_ERROR;
	}

	/*
	 * All the capsules have been updated successfully,
	 * update the FWU metadata.
	 */
	log_debug("Update Complete. Now updating active_index to %u\n",
		  update_index);
	status = fwu_set_active_index(update_index);
	ret = fwu_to_efi_error(status);
	if (ret != EFI_SUCCESS) {
		log_err("Failed to update FWU metadata index values\n");
	} else {
		log_debug("Successfully updated the active_index\n");
		status = fwu_state_machine_updates(fw_accept_os ? 1 : 0,
						   update_index);
		if (status < 0)
			ret = EFI_DEVICE_ERROR;
	}

	return ret;
}

/**
 * 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_guid_t *image_type_id;
	efi_status_t ret = EFI_SUCCESS;
	int status;
	uint update_index;
	bool fw_accept_os;

	if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
		if (fwu_empty_capsule_checks_pass() &&
		    fwu_empty_capsule(capsule_data))
			return fwu_empty_capsule_process(capsule_data);

		if (!fwu_update_checks_pass()) {
			log_err("FWU checks failed. Cannot start update\n");
			return EFI_INVALID_PARAMETER;
		}

		/* Obtain the update_index from the platform */
		status = fwu_plat_get_update_index(&update_index);
		if (status < 0) {
			log_err("Failed to get the FWU update_index value\n");
			return EFI_DEVICE_ERROR;
		}

		fw_accept_os = capsule_data->flags & FW_ACCEPT_OS ? 0x1 : 0x0;
	}

	if (guidcmp(&capsule_data->capsule_guid,
		    &efi_guid_firmware_management_capsule_id)) {
		log_err("Unsupported capsule type: %pUs\n",
			&capsule_data->capsule_guid);
		return EFI_UNSUPPORTED;
	}

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

		if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
			image_type_id = &image->update_image_type_id;
			if (!fw_accept_os) {
				/*
				 * The OS will not be accepting the firmware
				 * images. Set the accept bit of all the
				 * images contained in this capsule.
				 */
				status = fwu_accept_image(image_type_id,
							  update_index);
			} else {
				status = fwu_clear_accept_image(image_type_id,
								update_index);
			}
			ret = fwu_to_efi_error(status);
			if (ret != EFI_SUCCESS) {
				log_err("Unable to %s the accept bit for the image %pUs\n",
					fw_accept_os ? "clear" : "set",
					image_type_id);
				goto out;
			}

			log_debug("%s the accepted bit for Image %pUs\n",
				  fw_accept_os ? "Cleared" : "Set",
				  image_type_id);
		}

	}

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);
		ret  = efi_capsule_update_firmware(capsule);
		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_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_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));

	/*
	 * Capsule files are applied in case insensitive alphabetic order
	 *
	 * TODO: special handling of rightmost period
	 */
	qsort(tmp_files, count, sizeof(*tmp_files),
	      (int (*)(const void *, const void *))u16_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 = 0x0;
	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 (!IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS) &&
	    (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, index_max, i;
	efi_status_t ret;
	bool capsule_update = true;
	bool update_status = true;
	bool fw_accept_os = false;

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

	index_max = get_max_capsule();
	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 > index_max)
			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]);
				update_status = false;
			} else {
				log_info("Applying capsule %ls succeeded.\n",
					 files[i]);
				if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
					fwu_post_update_checks(capsule,
							       &fw_accept_os,
							       &capsule_update);
				}
			}

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

			free(capsule);
		} else {
			log_err("Reading capsule %ls failed\n", files[i]);
			update_status = false;
		}
		/* 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();

	if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
		if (capsule_update == true && update_status == true) {
			ret = fwu_post_update_process(fw_accept_os);
		} else if (capsule_update == true && update_status == false) {
			log_err("All capsules were not updated. Not updating FWU metadata\n");
		}
	}

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