// SPDX-License-Identifier: GPL-2.0+
/*
 *  EFI application loader
 *
 *  Copyright (c) 2016 Alexander Graf
 */

#define LOG_CATEGORY LOGC_EFI

#include <command.h>
#include <efi.h>
#include <efi_loader.h>
#include <exports.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <vsprintf.h>
#include <asm-generic/sections.h>
#include <asm/global_data.h>
#include <linux/string.h>

DECLARE_GLOBAL_DATA_PTR;

static struct efi_device_path *test_image_path;
static struct efi_device_path *test_device_path;

static efi_status_t bootefi_run_prepare(const char *load_options_path,
		struct efi_device_path *device_path,
		struct efi_device_path *image_path,
		struct efi_loaded_image_obj **image_objp,
		struct efi_loaded_image **loaded_image_infop)
{
	efi_status_t ret;
	u16 *load_options;

	ret = efi_setup_loaded_image(device_path, image_path, image_objp,
				     loaded_image_infop);
	if (ret != EFI_SUCCESS)
		return ret;

	/* Transfer environment variable as load options */
	return efi_env_set_load_options((efi_handle_t)*image_objp,
					load_options_path,
					&load_options);
}

/**
 * bootefi_test_prepare() - prepare to run an EFI test
 *
 * Prepare to run a test as if it were provided by a loaded image.
 *
 * @image_objp:		pointer to be set to the loaded image handle
 * @loaded_image_infop:	pointer to be set to the loaded image protocol
 * @path:		dummy file path used to construct the device path
 *			set in the loaded image protocol
 * @load_options_path:	name of a U-Boot environment variable. Its value is
 *			set as load options in the loaded image protocol.
 * Return:		status code
 */
static efi_status_t bootefi_test_prepare
		(struct efi_loaded_image_obj **image_objp,
		 struct efi_loaded_image **loaded_image_infop, const char *path,
		 const char *load_options_path)
{
	efi_status_t ret;

	/* Construct a dummy device path */
	test_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0);
	if (!test_device_path)
		return EFI_OUT_OF_RESOURCES;

	test_image_path = efi_dp_from_file(NULL, path);
	if (!test_image_path) {
		ret = EFI_OUT_OF_RESOURCES;
		goto failure;
	}

	ret = bootefi_run_prepare(load_options_path, test_device_path,
				  test_image_path, image_objp,
				  loaded_image_infop);
	if (ret == EFI_SUCCESS)
		return ret;

failure:
	efi_free_pool(test_device_path);
	efi_free_pool(test_image_path);
	/* TODO: not sure calling clear function is necessary */
	efi_clear_bootdev();
	return ret;
}

/**
 * do_efi_selftest() - execute EFI selftest
 *
 * Return:	status code
 */
static int do_efi_selftest(void)
{
	struct efi_loaded_image_obj *image_obj;
	struct efi_loaded_image *loaded_image_info;
	efi_status_t ret;

	ret = bootefi_test_prepare(&image_obj, &loaded_image_info,
				   "\\selftest", "efi_selftest");
	if (ret != EFI_SUCCESS)
		return CMD_RET_FAILURE;

	/* Execute the test */
	ret = EFI_CALL(efi_selftest(&image_obj->header, &systab));
	efi_restore_gd();
	free(loaded_image_info->load_options);
	efi_free_pool(test_device_path);
	efi_free_pool(test_image_path);
	if (ret != EFI_SUCCESS)
		efi_delete_handle(&image_obj->header);
	else
		ret = efi_delete_handle(&image_obj->header);

	return ret != EFI_SUCCESS;
}

/**
 * do_bootefi() - execute `bootefi` command
 *
 * @cmdtp:	table entry describing command
 * @flag:	bitmap indicating how the command was invoked
 * @argc:	number of arguments
 * @argv:	command line arguments
 * Return:	status code
 */
static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	efi_status_t ret;
	char *p;
	void *fdt, *image_buf;
	unsigned long addr, size;
	void *image_addr;
	size_t image_size;

	if (argc < 2)
		return CMD_RET_USAGE;

	if (argc > 2) {
		uintptr_t fdt_addr;

		fdt_addr = hextoul(argv[2], NULL);
		fdt = map_sysmem(fdt_addr, 0);
	} else {
		fdt = EFI_FDT_USE_INTERNAL;
	}

	if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
	    !strcmp(argv[1], "bootmgr")) {
		ret = efi_bootmgr_run(fdt);

		if (ret == EFI_INVALID_PARAMETER)
			return CMD_RET_USAGE;
		else if (ret)
			return CMD_RET_FAILURE;

		return CMD_RET_SUCCESS;
	}

	if (IS_ENABLED(CONFIG_CMD_BOOTEFI_SELFTEST) &&
	    !strcmp(argv[1], "selftest")) {
		/* Initialize EFI drivers */
		ret = efi_init_obj_list();
		if (ret != EFI_SUCCESS) {
			log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
				ret & ~EFI_ERROR_MASK);
			return CMD_RET_FAILURE;
		}

		ret = efi_install_fdt(fdt);
		if (ret == EFI_INVALID_PARAMETER)
			return CMD_RET_USAGE;
		else if (ret != EFI_SUCCESS)
			return CMD_RET_FAILURE;

		return do_efi_selftest();
	}

	if (!IS_ENABLED(CONFIG_CMD_BOOTEFI_BINARY))
		return CMD_RET_SUCCESS;

	if (IS_ENABLED(CONFIG_CMD_BOOTEFI_HELLO) &&
	    !strcmp(argv[1], "hello")) {
		image_buf = __efi_helloworld_begin;
		size = __efi_helloworld_end - __efi_helloworld_begin;
		/* TODO: not sure calling clear function is necessary */
		efi_clear_bootdev();
	} else {
		addr = strtoul(argv[1], NULL, 16);
		/* Check that a numeric value was passed */
		if (!addr)
			return CMD_RET_USAGE;
		image_buf = map_sysmem(addr, 0);

		p  = strchr(argv[1], ':');
		if (p) {
			size = strtoul(++p, NULL, 16);
			if (!size)
				return CMD_RET_USAGE;
			efi_clear_bootdev();
		} else {
			/* Image should be already loaded */
			efi_get_image_parameters(&image_addr, &image_size);

			if (image_buf != image_addr) {
				log_err("No UEFI binary known at %s\n",
					argv[1]);
				return CMD_RET_FAILURE;
			}
			size = image_size;
		}
	}

	ret = efi_binary_run(image_buf, size, fdt);

	if (ret == EFI_INVALID_PARAMETER)
		return CMD_RET_USAGE;
	else if (ret)
		return CMD_RET_FAILURE;

	return CMD_RET_SUCCESS;
}

U_BOOT_LONGHELP(bootefi,
	"<image address>[:<image size>] [<fdt address>]\n"
	"  - boot EFI payload\n"
#ifdef CONFIG_CMD_BOOTEFI_HELLO
	"bootefi hello\n"
	"  - boot a sample Hello World application stored within U-Boot\n"
#endif
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
	"bootefi selftest [fdt address]\n"
	"  - boot an EFI selftest application stored within U-Boot\n"
	"    Use environment variable efi_selftest to select a single test.\n"
	"    Use 'setenv efi_selftest list' to enumerate all tests.\n"
#endif
#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
	"bootefi bootmgr [fdt address]\n"
	"  - load and boot EFI payload based on BootOrder/BootXXXX variables.\n"
	"\n"
	"    If specified, the device tree located at <fdt address> gets\n"
	"    exposed as EFI configuration table.\n"
#endif
	);

U_BOOT_CMD(
	bootefi, 4, 0, do_bootefi,
	"Boots an EFI payload from memory",
	bootefi_help_text
);
