// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * (C) Copyright 2023 Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
 */

#define LOG_CATEGORY UCLASS_QFW

#include <efi_loader.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <qfw.h>
#include <smbios.h>
#include <tables_csum.h>
#include <linux/sizes.h>
#include <asm/global_data.h>

DECLARE_GLOBAL_DATA_PTR;

/**
 * qfw_load_smbios_table() - load a QEMU firmware file
 *
 * @dev:	QEMU firmware device
 * @size:	parameter to return the size of the loaded table
 * @name:	name of the table to load
 * Return:	address of the loaded table, NULL on error
 */
static void *qfw_load_smbios_table(struct udevice *dev, uint32_t *size,
				   char *name)
{
	struct fw_file *file;
	struct bios_linker_entry *table;

	file = qfw_find_file(dev, name);
	if (!file) {
		log_debug("Can't find %s\n", name);
		return NULL;
	}

	*size = be32_to_cpu(file->cfg.size);

	table = malloc(*size);
	if (!table) {
		log_err("Out of memory\n");
		return NULL;
	}

	qfw_read_entry(dev, be16_to_cpu(file->cfg.select), *size, table);

	return table;
}

/**
 * qfw_parse_smbios_anchor() - parse QEMU's SMBIOS anchor
 *
 * @dev:	QEMU firmware device
 * @entry:	SMBIOS 3 structure to be filled from QEMU's anchor
 * Return:	0 for success, -ve on error
 */
static int qfw_parse_smbios_anchor(struct udevice *dev,
				   struct smbios3_entry *entry)
{
	void *table;
	uint32_t size;
	struct smbios_entry *entry2;
	struct smbios3_entry *entry3;
	const char smbios_sig[] = "_SM_";
	const char smbios3_sig[] = "_SM3_";
	int ret = 0;

	table = qfw_load_smbios_table(dev, &size, "etc/smbios/smbios-anchor");
	if (!table)
		return -ENOMEM;
	if (!memcmp(table, smbios3_sig, sizeof(smbios3_sig) - 1)) {
		entry3 = table;
		if (entry3->length != sizeof(struct smbios3_entry)) {
			ret = -ENOENT;
			goto out;
		}
		memcpy(entry, entry3, sizeof(struct smbios3_entry));
	} else if (!memcmp(table, smbios_sig, sizeof(smbios_sig) - 1)) {
		entry2 = table;
		if (entry2->length != sizeof(struct smbios_entry)) {
			ret = -ENOENT;
			goto out;
		}
		memset(entry, 0, sizeof(struct smbios3_entry));
		memcpy(entry, smbios3_sig, sizeof(smbios3_sig));
		entry->length = sizeof(struct smbios3_entry);
		entry->major_ver = entry2->major_ver;
		entry->minor_ver = entry2->minor_ver;
		entry->max_struct_size = entry2->max_struct_size;
	} else {
		ret = -ENOENT;
		goto out;
	}
	ret = 0;
out:
	free(table);

	return ret;
}

/**
 * qfw_write_smbios_tables() - copy SMBIOS tables from QEMU
 *
 * @addr:	target buffer
 * @size:	size of target buffer
 * Return:	0 for success, -ve on error
 */
static int qfw_write_smbios_tables(u8 *addr, uint32_t size)
{
	int ret;
	struct udevice *dev;
	struct smbios3_entry *entry = (void *)addr;
	void *table;
	uint32_t table_size;

	ret = qfw_get_dev(&dev);
	if (ret) {
		log_err("No QEMU firmware device\n");
		return ret;
	}

	ret = qfw_read_firmware_list(dev);
	if (ret) {
		log_err("Can't read firmware file list\n");
		return ret;
	}

	ret = qfw_parse_smbios_anchor(dev, entry);
	if (ret) {
		log_debug("Can't parse anchor\n");
		return ret;
	}

	addr += entry->length;
	entry->struct_table_address = (uintptr_t)addr;
	entry->checksum = 0;
	entry->checksum = table_compute_checksum(entry,
						 sizeof(struct smbios3_entry));

	table = qfw_load_smbios_table(dev, &table_size,
				      "etc/smbios/smbios-tables");
	if (table_size + sizeof(struct smbios3_entry) > size) {
		free(table);
		return -ENOMEM;
	}
	memcpy(addr, table, table_size);
	free(table);

	return 0;
}

/**
 * qfw_evt_write_smbios_tables() - event handler for copying QEMU SMBIOS tables
 *
 * Return:	0 on success, -ve on error (only out of memory)
 */
static int qfw_evt_write_smbios_tables(void)
{
	phys_addr_t addr;
	void *ptr;
	int ret;
	/*
	 * TODO:
	 * This size is currently hard coded in lib/efi_loader/efi_smbios.c.
	 * We need a field in global data for the size.
	 */
	uint32_t size = SZ_4K;

	/* Reserve 64K for SMBIOS tables, aligned to a 4K boundary */
	ptr = memalign(SZ_4K, size);
	if (!ptr) {
		log_err("Out of memory\n");
		return -ENOMEM;
	}
	addr = map_to_sysmem(ptr);

	/* Generate SMBIOS tables */
	ret = qfw_write_smbios_tables(ptr, size);
	if (ret) {
		if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) {
			log_info("Falling back to U-Boot generated SMBIOS tables\n");
			write_smbios_table(addr);
		}
	} else {
		log_debug("SMBIOS tables copied from QEMU\n");
	}

	gd_set_smbios_start(addr);

	return 0;
}

EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, qfw_evt_write_smbios_tables);
