// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2020, Linaro Limited
 */

#define LOG_CATEGORY LOGC_EFI
#include <common.h>
#include <efi_loader.h>
#include <efi_load_initrd.h>
#include <efi_variable.h>
#include <fs.h>
#include <malloc.h>
#include <mapmem.h>

static efi_status_t EFIAPI
efi_load_file2_initrd(struct efi_load_file_protocol *this,
		      struct efi_device_path *file_path, bool boot_policy,
		      efi_uintn_t *buffer_size, void *buffer);

static const struct efi_load_file_protocol efi_lf2_protocol = {
	.load_file = efi_load_file2_initrd,
};

/*
 * Device path defined by Linux to identify the handle providing the
 * EFI_LOAD_FILE2_PROTOCOL used for loading the initial ramdisk.
 */
static const struct efi_initrd_dp dp_lf2_handle = {
	.vendor = {
		{
		   DEVICE_PATH_TYPE_MEDIA_DEVICE,
		   DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
		   sizeof(dp_lf2_handle.vendor),
		},
		EFI_INITRD_MEDIA_GUID,
	},
	.end = {
		DEVICE_PATH_TYPE_END,
		DEVICE_PATH_SUB_TYPE_END,
		sizeof(dp_lf2_handle.end),
	}
};

static efi_handle_t efi_initrd_handle;

/**
 * get_initrd_fp() - Get initrd device path from a FilePathList device path
 *
 * @initrd_fp:	the final initrd filepath
 *
 * Return:	status code. Caller must free initrd_fp
 */
static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp)
{
	const efi_guid_t lf2_initrd_guid = EFI_INITRD_MEDIA_GUID;
	struct efi_device_path *dp = NULL;

	/*
	 * if bootmgr is setup with and initrd, the device path will be
	 * in the FilePathList[] of our load options in Boot####.
	 * The first device path of the multi instance device path will
	 * start with a VenMedia and the initrds will follow.
	 *
	 * If the device path is not found return EFI_INVALID_PARAMETER.
	 * We can then use this specific return value and not install the
	 * protocol, while allowing the boot to continue
	 */
	dp = efi_get_dp_from_boot(lf2_initrd_guid);
	if (!dp)
		return EFI_INVALID_PARAMETER;

	*initrd_fp = dp;
	return EFI_SUCCESS;
}

/**
 * efi_load_file2_initrd() - load initial RAM disk
 *
 * This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL
 * in order to load an initial RAM disk requested by the Linux kernel stub.
 *
 * See the UEFI spec for details.
 *
 * @this:			EFI_LOAD_FILE2_PROTOCOL instance
 * @file_path:			media device path of the file, "" in this case
 * @boot_policy:		must be false
 * @buffer_size:		size of allocated buffer
 * @buffer:			buffer to load the file
 *
 * Return:			status code
 */
static efi_status_t EFIAPI
efi_load_file2_initrd(struct efi_load_file_protocol *this,
		      struct efi_device_path *file_path, bool boot_policy,
		      efi_uintn_t *buffer_size, void *buffer)
{
	struct efi_device_path *initrd_fp = NULL;
	efi_status_t ret = EFI_NOT_FOUND;
	struct efi_file_handle *f = NULL;
	efi_uintn_t bs;

	EFI_ENTRY("%p, %p, %d, %p, %p", this, file_path, boot_policy,
		  buffer_size, buffer);

	if (!this || this != &efi_lf2_protocol ||
	    !buffer_size) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	if (file_path->type != dp_lf2_handle.end.type ||
	    file_path->sub_type != dp_lf2_handle.end.sub_type) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	if (boot_policy) {
		ret = EFI_UNSUPPORTED;
		goto out;
	}

	ret = get_initrd_fp(&initrd_fp);
	if (ret != EFI_SUCCESS)
		goto out;

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

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

	if (!buffer || *buffer_size < bs) {
		ret = EFI_BUFFER_TOO_SMALL;
		*buffer_size = bs;
	} else {
		ret = EFI_CALL(f->read(f, &bs, (void *)(uintptr_t)buffer));
		*buffer_size = bs;
	}

out:
	efi_free_pool(initrd_fp);
	if (f)
		EFI_CALL(f->close(f));
	return EFI_EXIT(ret);
}

/**
 * check_initrd() - Determine if the file defined as an initrd in Boot####
 *		    load_options device path is present
 *
 * Return:	status code
 */
static efi_status_t check_initrd(void)
{
	struct efi_device_path *initrd_fp = NULL;
	struct efi_file_handle *f;
	efi_status_t ret;

	ret = get_initrd_fp(&initrd_fp);
	if (ret != EFI_SUCCESS)
		goto out;

	/*
	 * If the file is not found, but the file path is set, return an error
	 * and trigger the bootmgr fallback
	 */
	f = efi_file_from_path(initrd_fp);
	if (!f) {
		log_err("Can't find initrd specified in Boot####\n");
		ret = EFI_NOT_FOUND;
		goto out;
	}

	EFI_CALL(f->close(f));

out:
	efi_free_pool(initrd_fp);
	return ret;
}

/**
 * efi_initrd_register() - create handle for loading initial RAM disk
 *
 * This function creates a new handle and installs a Linux specific vendor
 * device path and an EFI_LOAD_FILE2_PROTOCOL. Linux uses the device path
 * to identify the handle and then calls the LoadFile service of the
 * EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk.
 *
 * Return:	status code
 */
efi_status_t efi_initrd_register(void)
{
	efi_status_t ret;

	/*
	 * Allow the user to continue if Boot#### file path is not set for
	 * an initrd
	 */
	ret = check_initrd();
	if (ret == EFI_INVALID_PARAMETER)
		return EFI_SUCCESS;
	if (ret != EFI_SUCCESS)
		return ret;

	ret = EFI_CALL(efi_install_multiple_protocol_interfaces
		       (&efi_initrd_handle,
			/* initramfs */
			&efi_guid_device_path, &dp_lf2_handle,
			/* LOAD_FILE2 */
			&efi_guid_load_file2_protocol,
			(void *)&efi_lf2_protocol,
			NULL));

	return ret;
}

/**
 * efi_initrd_deregister() - delete the handle for loading initial RAM disk
 *
 * This will delete the handle containing the Linux specific vendor device
 * path and EFI_LOAD_FILE2_PROTOCOL for loading an initrd
 *
 * Return:	status code
 */
void efi_initrd_deregister(void)
{
	efi_delete_handle(efi_initrd_handle);
	efi_initrd_handle = NULL;
}
