// SPDX-License-Identifier: GPL-2.0-only
/*
 *  EFI application ESRT tables support
 *
 *  Copyright (C) 2021 Arm Ltd.
 */

#include <common.h>
#include <efi_loader.h>
#include <log.h>
#include <efi_api.h>
#include <malloc.h>

const efi_guid_t efi_esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID;

static struct efi_system_resource_table *esrt;

#define EFI_ESRT_VERSION 1

/**
 * efi_esrt_image_info_to_entry() - copy the information present in a fw image
 * descriptor to a ESRT entry.
 * The function ensures the ESRT entry matches the image_type_id in @img_info.
 * In case of a mismatch we leave the entry unchanged.
 *
 * @img_info:     the source image info descriptor
 * @entry:        pointer to the ESRT entry to be filled
 * @desc_version: the version of the elements in img_info
 * @image_type:   the image type value to be set in the ESRT entry
 * @flags:        the capsule flags value to be set in the ESRT entry
 *
 * Return:
 * - EFI_SUCCESS if the entry is correctly updated
 * - EFI_INVALID_PARAMETER if entry does not match image_type_id in @img_info.
 */
static efi_status_t
efi_esrt_image_info_to_entry(struct efi_firmware_image_descriptor *img_info,
			     struct efi_system_resource_entry *entry,
			     u32 desc_version, u32 image_type, u32 flags)
{
	if (guidcmp(&entry->fw_class, &img_info->image_type_id)) {
		EFI_PRINT("ESRT entry %pUL mismatches img_type_id %pUL\n",
			  &entry->fw_class, &img_info->image_type_id);
		return EFI_INVALID_PARAMETER;
	}

	entry->fw_version = img_info->version;

	entry->fw_type = image_type;
	entry->capsule_flags = flags;

	/*
	 * The field lowest_supported_image_version is only present
	 * on image info structure of version 2 or greater.
	 * See the EFI_FIRMWARE_IMAGE_DESCRIPTOR definition in UEFI.
	 */
	if (desc_version >= 2)
		entry->lowest_supported_fw_version =
			img_info->lowest_supported_image_version;
	else
		entry->lowest_supported_fw_version = 0;

	/*
	 * The fields last_attempt_version and last_attempt_status
	 * are only present on image info structure of version 3 or
	 * greater.
	 * See the EFI_FIRMWARE_IMAGE_DESCRIPTOR definition in UEFI.
	 */
	if (desc_version >= 3) {
		entry->last_attempt_version =
			img_info->last_attempt_version;

		entry->last_attempt_status =
			img_info->last_attempt_status;
	} else {
		entry->last_attempt_version = 0;
		entry->last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
	}

	return EFI_SUCCESS;
}

/**
 * efi_esrt_entries_to_size() - Obtain the bytes used by an ESRT
 * datastructure with @num_entries.
 *
 * @num_entries: the number of entries in the ESRT.
 *
 * Return: the number of bytes an ESRT with @num_entries occupies in memory.
 */
static
inline u32 efi_esrt_entries_to_size(u32 num_entries)
{
	u32 esrt_size = sizeof(struct efi_system_resource_table) +
		num_entries * sizeof(struct efi_system_resource_entry);

	return esrt_size;
}

/**
 * efi_esrt_allocate_install() - Allocates @num_entries for the ESRT and
 * performs basic ESRT initialization.
 *
 * @num_entries: the number of entries that the ESRT will hold.
 *
 * Return:
 * - pointer to the ESRT if successful.
 * - NULL otherwise.
 */
static
efi_status_t efi_esrt_allocate_install(u32 num_entries)
{
	efi_status_t ret;
	struct efi_system_resource_table *new_esrt;
	u32 size = efi_esrt_entries_to_size(num_entries);
	efi_guid_t esrt_guid = efi_esrt_guid;

	/* Reserve num_pages for ESRT */
	ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, size,
				(void **)&new_esrt);

	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT cannot allocate memory for %u entries (%u bytes)\n",
			  num_entries, size);

		return ret;
	}

	new_esrt->fw_resource_count_max = num_entries;
	new_esrt->fw_resource_count = 0;
	new_esrt->fw_resource_version = EFI_ESRT_VERSION;

	/* Install the ESRT in the system configuration table. */
	ret = efi_install_configuration_table(&esrt_guid, (void *)new_esrt);
	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT failed to install the ESRT in the system table\n");
		return ret;
	}

	/* If there was a previous ESRT, deallocate its memory now. */
	if (esrt)
		ret = EFI_CALL(efi_free_pool(esrt));

	esrt = new_esrt;

	return EFI_SUCCESS;
}

/**
 * esrt_find_entry() - Obtain the ESRT entry for the image with GUID
 * @img_fw_class.
 *
 * If the img_fw_class is not yet present in the ESRT, this function
 * reserves the tail element of the current ESRT as the entry for that fw_class.
 * The number of elements in the ESRT is updated in that case.
 *
 * @img_fw_class: the GUID of the FW image which ESRT entry we want to obtain.
 *
 * Return:
 *  - A pointer to the ESRT entry for the image with GUID img_fw_class,
 *  - NULL if:
 *   - there is no more space in the ESRT,
 *   - ESRT is not initialized,
 */
static
struct efi_system_resource_entry *esrt_find_entry(efi_guid_t *img_fw_class)
{
	u32 filled_entries;
	u32 max_entries;
	struct efi_system_resource_entry *entry;

	if (!esrt) {
		EFI_PRINT("ESRT access before initialized\n");
		return NULL;
	}

	filled_entries = esrt->fw_resource_count;
	entry = esrt->entries;

	/* Check if the image with img_fw_class is already in the ESRT. */
	for (u32 idx = 0; idx < filled_entries; idx++) {
		if (!guidcmp(&entry[idx].fw_class, img_fw_class)) {
			EFI_PRINT("ESRT found entry for image %pUl at index %u\n",
				  img_fw_class, idx);
			return &entry[idx];
		}
	}

	max_entries = esrt->fw_resource_count_max;
	/*
	 * Since the image with img_fw_class is not present in the ESRT, check
	 * if ESRT is full before appending the new entry to it.
	 */
	if (filled_entries == max_entries) {
		EFI_PRINT("ESRT full, this should not happen\n");
		return NULL;
	}

	/*
	 * This is a new entry for a fw image, increment the element
	 * number in the table and set the fw_class field.
	 */
	esrt->fw_resource_count++;
	entry[filled_entries].fw_class = *img_fw_class;
	EFI_PRINT("ESRT allocated new entry for image %pUl at index %u\n",
		  img_fw_class, filled_entries);

	return &entry[filled_entries];
}

/**
 * efi_esrt_add_from_fmp() - Populates a sequence of ESRT entries from the FW
 * images in the FMP.
 *
 * @fmp: the FMP instance from which FW images are added to the ESRT
 *
 * Return:
 * - EFI_SUCCESS if all the FW images in the FMP are added to the ESRT
 * - Error status otherwise
 */
static
efi_status_t efi_esrt_add_from_fmp(struct efi_firmware_management_protocol *fmp)
{
	struct efi_system_resource_entry *entry = NULL;
	size_t info_size = 0;
	struct efi_firmware_image_descriptor *img_info = NULL;
	u32 desc_version;
	u8 desc_count;
	size_t desc_size;
	u32 package_version;
	u16 *package_version_name;
	efi_status_t ret = EFI_SUCCESS;

	/*
	 * TODO: set the field image_type depending on the FW image type
	 * defined in a platform basis.
	 */
	u32 image_type = ESRT_FW_TYPE_UNKNOWN;

	/* TODO: set the capsule flags as a function of the FW image type. */
	u32 flags = 0;

	ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, img_info,
					   &desc_version, &desc_count,
					   &desc_size, NULL, NULL));

	if (ret != EFI_BUFFER_TOO_SMALL) {
		/*
		 * An input of info_size=0 should always lead
		 * fmp->get_image_info to return BUFFER_TO_SMALL.
		 */
		EFI_PRINT("Erroneous FMP implementation\n");
		return EFI_INVALID_PARAMETER;
	}

	ret = EFI_CALL(efi_allocate_pool(EFI_BOOT_SERVICES_DATA, info_size,
					 (void **)&img_info));
	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT failed to allocate memory for image info.\n");
		return ret;
	}

	ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, img_info,
					   &desc_version, &desc_count,
					   &desc_size, &package_version,
					   &package_version_name));
	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT failed to obtain the FMP image info\n");
		goto out;
	}

	/*
	 * Iterate over all the FW images in the FMP.
	 */
	for (u32 desc_idx = 0; desc_idx < desc_count; desc_idx++) {
		struct efi_firmware_image_descriptor *cur_img_info =
			(struct efi_firmware_image_descriptor *)
			((uintptr_t)img_info + desc_idx * desc_size);

		/*
		 * Obtain the ESRT entry for the FW image with fw_class
		 * equal to cur_img_info->image_type_id.
		 */
		entry = esrt_find_entry(&cur_img_info->image_type_id);

		if (entry) {
			ret = efi_esrt_image_info_to_entry(cur_img_info, entry,
							   desc_version,
							   image_type, flags);
			if (ret != EFI_SUCCESS)
				EFI_PRINT("ESRT entry mismatches image_type\n");

		} else {
			EFI_PRINT("ESRT failed to add entry for %pUl\n",
				  &cur_img_info->image_type_id);
			continue;
		}
	}

out:
	EFI_CALL(efi_free_pool(img_info));
	return EFI_SUCCESS;
}

/**
 * efi_esrt_populate() - Populates the ESRT entries from the FMP instances
 * present in the system.
 * If an ESRT already exists, the old ESRT is replaced in the system table.
 * The memory of the old ESRT is deallocated.
 *
 * Return:
 * - EFI_SUCCESS if the ESRT is correctly created
 * - error code otherwise.
 */
efi_status_t efi_esrt_populate(void)
{
	efi_handle_t *base_handle = NULL;
	efi_handle_t *it_handle;
	efi_uintn_t no_handles = 0;
	struct efi_firmware_management_protocol *fmp;
	efi_status_t ret;
	u32 num_entries = 0;
	struct efi_handler *handler;

	/*
	 * Obtain the number of registered FMP handles.
	 */
	ret = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL,
						&efi_guid_firmware_management_protocol,
						NULL, &no_handles,
						(efi_handle_t **)&base_handle));

	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT There are no FMP instances\n");

		ret = efi_esrt_allocate_install(0);
		if (ret != EFI_SUCCESS) {
			EFI_PRINT("ESRT failed to create table with 0 entries\n");
			return ret;
		}
		return EFI_SUCCESS;
	}

	EFI_PRINT("ESRT populate esrt from (%zd) available FMP handles\n",
		  no_handles);

	/*
	 * Iterate over all FMPs to determine an upper bound on the number of
	 * ESRT entries.
	 */
	it_handle = base_handle;
	for (u32 idx = 0; idx < no_handles; idx++, it_handle++) {
		struct efi_firmware_image_descriptor *img_info = NULL;
		size_t info_size = 0;
		u32 desc_version = 0;
		u8 desc_count = 0;
		size_t desc_size = 0;
		u32 package_version;
		u16 *package_version_name;

		ret = efi_search_protocol(*it_handle,
					  &efi_guid_firmware_management_protocol,
					  &handler);

		if (ret != EFI_SUCCESS) {
			EFI_PRINT("ESRT Unable to find FMP handle (%u)\n",
				  idx);
			goto out;
		}
		fmp = handler->protocol_interface;

		ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, NULL,
						   &desc_version, &desc_count,
						   &desc_size, &package_version,
						   &package_version_name));

		if (ret != EFI_BUFFER_TOO_SMALL) {
			/*
			 * An input of info_size=0 should always lead
			 * fmp->get_image_info to return BUFFER_TO_SMALL.
			 */
			EFI_PRINT("ESRT erroneous FMP implementation\n");
			ret = EFI_INVALID_PARAMETER;
			goto out;
		}

		ret = EFI_CALL(efi_allocate_pool(EFI_BOOT_SERVICES_DATA, info_size,
						 (void **)&img_info));
		if (ret != EFI_SUCCESS) {
			EFI_PRINT("ESRT failed to allocate memory for image info\n");
			goto out;
		}

		/*
		 * Calls to a FMP get_image_info method do not return the
		 * desc_count value if the return status differs from EFI_SUCCESS.
		 * We need to repeat the call to get_image_info with a properly
		 * sized buffer in order to obtain the real number of images
		 * handled by the FMP.
		 */
		ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, img_info,
						   &desc_version, &desc_count,
						   &desc_size, &package_version,
						   &package_version_name));

		if (ret != EFI_SUCCESS) {
			EFI_PRINT("ESRT failed to obtain image info from FMP\n");
			EFI_CALL(efi_free_pool(img_info));
			goto out;
		}

		num_entries += desc_count;

		EFI_CALL(efi_free_pool(img_info));
	}

	EFI_PRINT("ESRT create table with %u entries\n", num_entries);
	/*
	 * Allocate an ESRT with the sufficient number of entries to accommodate
	 * all the FMPs in the system.
	 */
	ret = efi_esrt_allocate_install(num_entries);
	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT failed to initialize table\n");
		goto out;
	}

	/*
	 * Populate the ESRT entries with all existing FMP.
	 */
	it_handle = base_handle;
	for (u32 idx = 0; idx < no_handles; idx++, it_handle++) {
		ret = EFI_CALL(efi_search_protocol(*it_handle,
						   &efi_guid_firmware_management_protocol,
						   &handler));

		if (ret != EFI_SUCCESS) {
			EFI_PRINT("ESRT unable to find FMP handle (%u)\n",
				  idx);
			break;
		}
		fmp = handler->protocol_interface;

		ret = efi_esrt_add_from_fmp(fmp);
		if (ret != EFI_SUCCESS)
			EFI_PRINT("ESRT failed to add FMP to the table\n");
	}

out:

	EFI_CALL(efi_free_pool(base_handle));

	return ret;
}

/**
 * efi_esrt_new_fmp_notify() - Callback for the EVT_NOTIFY_SIGNAL event raised
 * when a new FMP protocol instance is registered in the system.
 */
static void EFIAPI efi_esrt_new_fmp_notify(struct efi_event *event,
					   void *context)
{
	efi_status_t ret;

	EFI_ENTRY();

	ret = efi_esrt_populate();
	if (ret != EFI_SUCCESS)
		EFI_PRINT("ESRT failed to populate ESRT entry\n");

	EFI_EXIT(ret);
}

/**
 * efi_esrt_register() - Install the ESRT system table.
 *
 * Return: status code
 */
efi_status_t efi_esrt_register(void)
{
	struct efi_event *ev = NULL;
	void *registration;
	efi_status_t ret;

	EFI_PRINT("ESRT creation start\n");

	ret = efi_esrt_populate();
	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT failed to initiate the table\n");
		return ret;
	}

	ret = EFI_CALL(efi_create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
					efi_esrt_new_fmp_notify, NULL, NULL, &ev));
	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT failed to create event\n");
		return ret;
	}

	ret = EFI_CALL(efi_register_protocol_notify(&efi_guid_firmware_management_protocol,
						    ev, &registration));
	if (ret != EFI_SUCCESS) {
		EFI_PRINT("ESRT failed to register FMP callback\n");
		return ret;
	}

	EFI_PRINT("ESRT table created\n");

	return ret;
}
