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

#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 memory 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_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 %pUs 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 %pUs 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_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 %pUs\n",
				  &cur_img_info->image_type_id);
			continue;
		}
	}

out:
	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_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_free_pool(img_info);
			goto out;
		}

		num_entries += desc_count;

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