// SPDX-License-Identifier: GPL-2.0
/*
 * Support for extracting embedded firmware for peripherals from EFI code,
 *
 * Copyright (c) 2018 Hans de Goede <hdegoede@redhat.com>
 */

#include <linux/dmi.h>
#include <linux/efi.h>
#include <linux/efi_embedded_fw.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <crypto/sha2.h>

/* Exported for use by lib/test_firmware.c only */
LIST_HEAD(efi_embedded_fw_list);
EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_list, "TEST_FIRMWARE");
bool efi_embedded_fw_checked;
EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_checked, "TEST_FIRMWARE");

static const struct dmi_system_id * const embedded_fw_table[] = {
#ifdef CONFIG_TOUCHSCREEN_DMI
	touchscreen_dmi_table,
#endif
	NULL
};

/*
 * Note the efi_check_for_embedded_firmwares() code currently makes the
 * following 2 assumptions. This may needs to be revisited if embedded firmware
 * is found where this is not true:
 * 1) The firmware is only found in EFI_BOOT_SERVICES_CODE memory segments
 * 2) The firmware always starts at an offset which is a multiple of 8 bytes
 */
static int __init efi_check_md_for_embedded_firmware(
	efi_memory_desc_t *md, const struct efi_embedded_fw_desc *desc)
{
	struct efi_embedded_fw *fw;
	u8 hash[32];
	u64 i, size;
	u8 *map;

	size = md->num_pages << EFI_PAGE_SHIFT;
	map = memremap(md->phys_addr, size, MEMREMAP_WB);
	if (!map) {
		pr_err("Error mapping EFI mem at %#llx\n", md->phys_addr);
		return -ENOMEM;
	}

	for (i = 0; (i + desc->length) <= size; i += 8) {
		if (memcmp(map + i, desc->prefix, EFI_EMBEDDED_FW_PREFIX_LEN))
			continue;

		sha256(map + i, desc->length, hash);
		if (memcmp(hash, desc->sha256, 32) == 0)
			break;
	}
	if ((i + desc->length) > size) {
		memunmap(map);
		return -ENOENT;
	}

	pr_info("Found EFI embedded fw '%s'\n", desc->name);

	fw = kmalloc(sizeof(*fw), GFP_KERNEL);
	if (!fw) {
		memunmap(map);
		return -ENOMEM;
	}

	fw->data = kmemdup(map + i, desc->length, GFP_KERNEL);
	memunmap(map);
	if (!fw->data) {
		kfree(fw);
		return -ENOMEM;
	}

	fw->name = desc->name;
	fw->length = desc->length;
	list_add(&fw->list, &efi_embedded_fw_list);

	return 0;
}

void __init efi_check_for_embedded_firmwares(void)
{
	const struct efi_embedded_fw_desc *fw_desc;
	const struct dmi_system_id *dmi_id;
	efi_memory_desc_t *md;
	int i, r;

	for (i = 0; embedded_fw_table[i]; i++) {
		dmi_id = dmi_first_match(embedded_fw_table[i]);
		if (!dmi_id)
			continue;

		fw_desc = dmi_id->driver_data;

		/*
		 * In some drivers the struct driver_data contains may contain
		 * other driver specific data after the fw_desc struct; and
		 * the fw_desc struct itself may be empty, skip these.
		 */
		if (!fw_desc->name)
			continue;

		for_each_efi_memory_desc(md) {
			if (md->type != EFI_BOOT_SERVICES_CODE)
				continue;

			r = efi_check_md_for_embedded_firmware(md, fw_desc);
			if (r == 0)
				break;
		}
	}

	efi_embedded_fw_checked = true;
}

int efi_get_embedded_fw(const char *name, const u8 **data, size_t *size)
{
	struct efi_embedded_fw *iter, *fw = NULL;

	if (!efi_embedded_fw_checked) {
		pr_warn("Warning %s called while we did not check for embedded fw\n",
			__func__);
		return -ENOENT;
	}

	list_for_each_entry(iter, &efi_embedded_fw_list, list) {
		if (strcmp(name, iter->name) == 0) {
			fw = iter;
			break;
		}
	}

	if (!fw)
		return -ENOENT;

	*data = fw->data;
	*size = fw->length;

	return 0;
}
EXPORT_SYMBOL_GPL(efi_get_embedded_fw);
