// 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/sha.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);
