// SPDX-License-Identifier: GPL-2.0+
/*
 *  EFI boot manager
 *
 *  Copyright (c) 2017 Rob Clark
 */

#include <common.h>
#include <charset.h>
#include <malloc.h>
#include <efi_loader.h>

static const struct efi_boot_services *bs;
static const struct efi_runtime_services *rs;

#define LOAD_OPTION_ACTIVE		0x00000001
#define LOAD_OPTION_FORCE_RECONNECT	0x00000002
#define LOAD_OPTION_HIDDEN		0x00000008

/*
 * bootmgr implements the logic of trying to find a payload to boot
 * based on the BootOrder + BootXXXX variables, and then loading it.
 *
 * TODO detecting a special key held (f9?) and displaying a boot menu
 * like you would get on a PC would be clever.
 *
 * TODO if we had a way to write and persist variables after the OS
 * has started, we'd also want to check OsIndications to see if we
 * should do normal or recovery boot.
 */


/*
 * See section 3.1.3 in the v2.7 UEFI spec for more details on
 * the layout of EFI_LOAD_OPTION.  In short it is:
 *
 *    typedef struct _EFI_LOAD_OPTION {
 *        UINT32 Attributes;
 *        UINT16 FilePathListLength;
 *        // CHAR16 Description[];   <-- variable length, NULL terminated
 *        // EFI_DEVICE_PATH_PROTOCOL FilePathList[];  <-- FilePathListLength bytes
 *        // UINT8 OptionalData[];
 *    } EFI_LOAD_OPTION;
 */
struct load_option {
	u32 attributes;
	u16 file_path_length;
	u16 *label;
	struct efi_device_path *file_path;
	u8 *optional_data;
};

/* parse an EFI_LOAD_OPTION, as described above */
static void parse_load_option(struct load_option *lo, void *ptr)
{
	lo->attributes = *(u32 *)ptr;
	ptr += sizeof(u32);

	lo->file_path_length = *(u16 *)ptr;
	ptr += sizeof(u16);

	lo->label = ptr;
	ptr += (u16_strlen(lo->label) + 1) * 2;

	lo->file_path = ptr;
	ptr += lo->file_path_length;

	lo->optional_data = ptr;
}

/* free() the result */
static void *get_var(u16 *name, const efi_guid_t *vendor,
		     efi_uintn_t *size)
{
	efi_guid_t *v = (efi_guid_t *)vendor;
	efi_status_t ret;
	void *buf = NULL;

	*size = 0;
	EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf));
	if (ret == EFI_BUFFER_TOO_SMALL) {
		buf = malloc(*size);
		EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf));
	}

	if (ret != EFI_SUCCESS) {
		free(buf);
		*size = 0;
		return NULL;
	}

	return buf;
}

/*
 * Attempt to load load-option number 'n', returning device_path and file_path
 * if successful.  This checks that the EFI_LOAD_OPTION is active (enabled)
 * and that the specified file to boot exists.
 */
static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
			    struct efi_device_path **file_path)
{
	struct load_option lo;
	u16 varname[] = L"Boot0000";
	u16 hexmap[] = L"0123456789ABCDEF";
	void *load_option, *image = NULL;
	efi_uintn_t size;

	varname[4] = hexmap[(n & 0xf000) >> 12];
	varname[5] = hexmap[(n & 0x0f00) >> 8];
	varname[6] = hexmap[(n & 0x00f0) >> 4];
	varname[7] = hexmap[(n & 0x000f) >> 0];

	load_option = get_var(varname, &efi_global_variable_guid, &size);
	if (!load_option)
		return NULL;

	parse_load_option(&lo, load_option);

	if (lo.attributes & LOAD_OPTION_ACTIVE) {
		efi_status_t ret;

		debug("%s: trying to load \"%ls\" from %pD\n",
		      __func__, lo.label, lo.file_path);

		ret = efi_load_image_from_path(lo.file_path, &image);

		if (ret != EFI_SUCCESS)
			goto error;

		printf("Booting: %ls\n", lo.label);
		efi_dp_split_file_path(lo.file_path, device_path, file_path);
	}

error:
	free(load_option);

	return image;
}

/*
 * Attempt to load, in the order specified by BootOrder EFI variable, the
 * available load-options, finding and returning the first one that can
 * be loaded successfully.
 */
void *efi_bootmgr_load(struct efi_device_path **device_path,
		       struct efi_device_path **file_path)
{
	uint16_t *bootorder;
	efi_uintn_t size;
	void *image = NULL;
	int i, num;

	__efi_entry_check();

	bs = systab.boottime;
	rs = systab.runtime;

	bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size);
	if (!bootorder)
		goto error;

	num = size / sizeof(uint16_t);
	for (i = 0; i < num; i++) {
		debug("%s: trying to load Boot%04X\n", __func__, bootorder[i]);
		image = try_load_entry(bootorder[i], device_path, file_path);
		if (image)
			break;
	}

	free(bootorder);

error:
	__efi_exit_check();

	return image;
}
