/* SPDX-License-Identifier: GPL-2.0-only */

#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <smbios.h>
#include <console/console.h>
#include <arch/io.h>
#include <acpi/acpi.h>
#include <commonlib/endian.h>

#include "fw_cfg.h"
#include "fw_cfg_if.h"

#define FW_CFG_PORT_CTL       0x0510
#define FW_CFG_PORT_DATA      0x0511
#define FW_CFG_DMA_ADDR_HIGH  0x0514
#define FW_CFG_DMA_ADDR_LOW   0x0518

static int fw_cfg_detected;
static uint8_t fw_ver;

static void fw_cfg_dma(int control, void *buf, int len);

static int fw_cfg_present(void)
{
	static const char qsig[] = "QEMU";
	unsigned char sig[FW_CFG_SIG_SIZE];
	int detected = 0;

	if (fw_cfg_detected == 0) {
		fw_cfg_get(FW_CFG_SIGNATURE, sig, sizeof(sig));
		detected = memcmp(sig, qsig, FW_CFG_SIG_SIZE) == 0;
		printk(BIOS_INFO, "QEMU: firmware config interface %s\n",
				detected ? "detected" : "not found");
		if (detected) {
			fw_cfg_get(FW_CFG_ID, &fw_ver, sizeof(fw_ver));
			printk(BIOS_INFO, "Firmware config version id: %d\n", fw_ver);
		}
		fw_cfg_detected = detected + 1;
	}
	return fw_cfg_detected - 1;
}

static void fw_cfg_select(uint16_t entry)
{
	if (fw_ver & FW_CFG_VERSION_DMA)
		fw_cfg_dma(FW_CFG_DMA_CTL_SELECT | entry << 16, NULL, 0);
	else
		outw(entry, FW_CFG_PORT_CTL);
}

static void fw_cfg_read(void *dst, int dstlen)
{
	if (fw_ver & FW_CFG_VERSION_DMA)
		fw_cfg_dma(FW_CFG_DMA_CTL_READ, dst, dstlen);
	else
		insb(FW_CFG_PORT_DATA, dst, dstlen);
}

void fw_cfg_get(uint16_t entry, void *dst, int dstlen)
{
	fw_cfg_select(entry);
	fw_cfg_read(dst, dstlen);
}

static int fw_cfg_find_file(FWCfgFile *file, const char *name)
{
	uint32_t count = 0;

	fw_cfg_select(FW_CFG_FILE_DIR);
	fw_cfg_read(&count, sizeof(count));
	count = be32_to_cpu(count);

	for (int i = 0; i < count; i++) {
		fw_cfg_read(file, sizeof(*file));
		if (strcmp(file->name, name) == 0) {
			file->size = be32_to_cpu(file->size);
			file->select = be16_to_cpu(file->select);
			printk(BIOS_INFO, "QEMU: firmware config: Found '%s'\n", name);
			return 0;
		}
	}
	printk(BIOS_INFO, "QEMU: firmware config: Couldn't find '%s'\n", name);
	return -1;
}

int fw_cfg_check_file(FWCfgFile *file, const char *name)
{
	if (!fw_cfg_present())
		return -1;
	return fw_cfg_find_file(file, name);
}

static int fw_cfg_e820_select(uint32_t *size)
{
	FWCfgFile file;

	if (!fw_cfg_present() || fw_cfg_find_file(&file, "etc/e820"))
		return -1;
	fw_cfg_select(file.select);
	*size = file.size;
	return 0;
}

static int fw_cfg_e820_read(FwCfgE820Entry *entry, uint32_t *size,
		uint32_t *pos)
{
	if (*pos + sizeof(*entry) > *size)
		return -1;

	fw_cfg_read(entry, sizeof(*entry));
	*pos += sizeof(*entry);
	return 0;
}

/* returns tolud on success or 0 on failure */
uintptr_t fw_cfg_tolud(void)
{
	FwCfgE820Entry e;
	uint64_t top = 0;
	uint32_t size = 0, pos = 0;

	if (fw_cfg_e820_select(&size) == 0) {
		while (!fw_cfg_e820_read(&e, &size, &pos)) {
			uint64_t limit = e.address + e.length;
			if (e.type == 1 && limit < 4ULL * GiB && limit > top)
				top = limit;
		}
	}
	return (uintptr_t)top;
}

int fw_cfg_max_cpus(void)
{
	unsigned short max_cpus;

	if (!fw_cfg_present())
		return 0;

	fw_cfg_get(FW_CFG_MAX_CPUS, &max_cpus, sizeof(max_cpus));
	return max_cpus;
}

/* ---------------------------------------------------------------------- */

/*
 * Starting with release 1.7 qemu provides ACPI tables via fw_cfg.
 * Main advantage is that new (virtual) hardware which needs acpi
 * support JustWorks[tm] without having to patch & update the firmware
 * (seabios, coreboot, ...) accordingly.
 *
 * Qemu provides a etc/table-loader file with instructions for the
 * firmware:
 *   - A "load" instruction to fetch ACPI data from fw_cfg.
 *   - A "pointer" instruction to patch a pointer.  This is needed to
 *     get table-to-table references right, it is basically a
 *     primitive dynamic linker for ACPI tables.
 *   - A "checksum" instruction to generate ACPI table checksums.
 *
 * If a etc/table-loader file is found we'll go try loading the acpi
 * tables from fw_cfg, otherwise we'll fallback to the ACPI tables
 * compiled in.
 */

#define BIOS_LINKER_LOADER_FILESZ 56

struct BiosLinkerLoaderEntry {
	uint32_t command;
	union {
		/*
		 * COMMAND_ALLOCATE - allocate a table from @alloc.file
		 * subject to @alloc.align alignment (must be power of 2)
		 * and @alloc.zone (can be HIGH or FSEG) requirements.
		 *
		 * Must appear exactly once for each file, and before
		 * this file is referenced by any other command.
		 */
		struct {
			char file[BIOS_LINKER_LOADER_FILESZ];
			uint32_t align;
			uint8_t zone;
		} alloc;

		/*
		 * COMMAND_ADD_POINTER - patch the table (originating from
		 * @dest_file) at @pointer.offset, by adding a pointer to the table
		 * originating from @src_file. 1,2,4 or 8 byte unsigned
		 * addition is used depending on @pointer.size.
		 */
		struct {
			char dest_file[BIOS_LINKER_LOADER_FILESZ];
			char src_file[BIOS_LINKER_LOADER_FILESZ];
			uint32_t offset;
			uint8_t size;
		} pointer;

		/*
		 * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by
		 * @cksum_start and @cksum_length fields,
		 * and then add the value at @cksum.offset.
		 * Checksum simply sums -X for each byte X in the range
		 * using 8-bit math.
		 */
		struct {
			char file[BIOS_LINKER_LOADER_FILESZ];
			uint32_t offset;
			uint32_t start;
			uint32_t length;
		} cksum;

		/* padding */
		char pad[124];
	};
} __packed;
typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry;

enum {
	BIOS_LINKER_LOADER_COMMAND_ALLOCATE     = 0x1,
	BIOS_LINKER_LOADER_COMMAND_ADD_POINTER  = 0x2,
	BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3,
};

enum {
	BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1,
	BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2,
};

unsigned long fw_cfg_acpi_tables(unsigned long start)
{
	FWCfgFile f;
	BiosLinkerLoaderEntry *s;
	unsigned long *addrs, current;
	uint8_t *ptr;
	int i, j, src, dst, max;

	if (fw_cfg_check_file(&f, "etc/table-loader"))
		return 0;

	printk(BIOS_DEBUG, "QEMU: found ACPI tables in fw_cfg.\n");

	max = f.size / sizeof(*s);
	s = malloc(f.size);
	addrs = malloc(max * sizeof(*addrs));
	fw_cfg_get(f.select, s, f.size);

	current = start;
	for (i = 0; i < max && s[i].command != 0; i++) {
		void *cksum_data;
		uint32_t cksum;
		uint32_t addr4;
		uint64_t addr8;
		switch (s[i].command) {
		case BIOS_LINKER_LOADER_COMMAND_ALLOCATE:
			current = ALIGN_UP(current, s[i].alloc.align);
			if (fw_cfg_check_file(&f, s[i].alloc.file))
				goto err;

			printk(BIOS_DEBUG, "QEMU: loading \"%s\" to 0x%lx (len %d)\n",
			       s[i].alloc.file, current, f.size);
			fw_cfg_get(f.select, (void *)current, f.size);
			addrs[i] = current;
			current += f.size;
			break;

		case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER:
			src = -1; dst = -1;
			for (j = 0; j < i; j++) {
				if (s[j].command != BIOS_LINKER_LOADER_COMMAND_ALLOCATE)
					continue;
				if (strcmp(s[j].alloc.file, s[i].pointer.dest_file) == 0)
					dst = j;
				if (strcmp(s[j].alloc.file, s[i].pointer.src_file) == 0)
					src = j;
			}
			if (src == -1 || dst == -1)
				goto err;

			switch (s[i].pointer.size) {
			case 4:
				ptr = (uint8_t *)addrs[dst];
				ptr += s[i].pointer.offset;
				addr4 = read_le32(ptr);
				addr4 += addrs[src];
				write_le32(ptr, addr4);
				break;

			case 8:
				ptr = (uint8_t *)addrs[dst];
				ptr += s[i].pointer.offset;
				addr8 = read_le64(ptr);
				addr8 += addrs[src];
				write_le64(ptr, addr8);
				break;

			default:
				/*
				 * Should not happen.  ACPI knows 1 and 2 byte ptrs
				 * too, but we are operating with 32bit offsets which
				 * would simply not fit in there ...
				 */
				printk(BIOS_DEBUG, "QEMU: acpi: unimplemented ptr size %d\n",
				       s[i].pointer.size);
				goto err;
			}
			break;

		case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM:
			dst = -1;
			for (j = 0; j < i; j++) {
				if (s[j].command != BIOS_LINKER_LOADER_COMMAND_ALLOCATE)
					continue;
				if (strcmp(s[j].alloc.file, s[i].cksum.file) == 0)
					dst = j;
			}
			if (dst == -1)
				goto err;

			ptr = (uint8_t *)(addrs[dst] + s[i].cksum.offset);
			cksum_data = (void *)(addrs[dst] + s[i].cksum.start);
			cksum = acpi_checksum(cksum_data, s[i].cksum.length);
			write_le8(ptr, cksum);
			break;

		default:
			printk(BIOS_DEBUG, "QEMU: acpi: unknown script cmd 0x%x @ %p\n",
			       s[i].command, s+i);
			goto err;
		};
	}

	printk(BIOS_DEBUG, "QEMU: loaded ACPI tables from fw_cfg.\n");
	free(s);
	free(addrs);
	return ALIGN_UP(current, 16);

err:
	printk(BIOS_DEBUG, "QEMU: loading ACPI tables from fw_cfg failed.\n");
	free(s);
	free(addrs);
	return 0;
}

/* ---------------------------------------------------------------------- */
/* pick up smbios information from fw_cfg                                 */

#if CONFIG(GENERATE_SMBIOS_TABLES)
static const char *type1_manufacturer;
static const char *type1_product_name;
static const char *type1_version;
static const char *type1_serial_number;
static const char *type1_family;
static u8 type1_uuid[16];

static void fw_cfg_smbios_init(void)
{
	static int done = 0;
	uint16_t i, count = 0;
	FwCfgSmbios entry;
	char *buf;

	if (done)
		return;
	done = 1;

	fw_cfg_get(FW_CFG_SMBIOS_ENTRIES, &count, sizeof(count));
	for (i = 0; i < count; i++) {
		fw_cfg_read(&entry, sizeof(entry));
		buf = malloc(entry.length - sizeof(entry));
		fw_cfg_read(buf, entry.length - sizeof(entry));
		if (entry.headertype == SMBIOS_FIELD_ENTRY &&
		    entry.tabletype == 1) {
			switch (entry.fieldoffset) {
			case offsetof(struct smbios_type1, manufacturer):
				type1_manufacturer = strdup(buf);
				break;
			case offsetof(struct smbios_type1, product_name):
				type1_product_name = strdup(buf);
				break;
			case offsetof(struct smbios_type1, version):
				type1_version = strdup(buf);
				break;
			case offsetof(struct smbios_type1, serial_number):
				type1_serial_number = strdup(buf);
				break;
			case offsetof(struct smbios_type1, family):
				type1_family = strdup(buf);
				break;
			case offsetof(struct smbios_type1, uuid):
				memcpy(type1_uuid, buf, 16);
				break;
			}
		}
		free(buf);
	}
}

static unsigned long smbios_next(unsigned long current)
{
	struct smbios_header *header;
	int l, count = 0;
	char *s;

	header = (void *)current;
	current += header->length;
	for (;;) {
		s = (void *)current;
		l = strlen(s);
		if (!l)
			return current + (count ? 1 : 2);
		current += l + 1;
		count++;
	}
}

/*
 * Starting with version 2.1 qemu provides a full set of smbios tables
 * for the virtual hardware emulated, except type 0 (bios information).
 *
 * What we are going to do here is find the type0 table, keep it, and
 * override everything else generated by coreboot with the qemu smbios
 * tables.
 *
 * It's a bit hackish, but qemu is a special case (compared to real
 * hardware) and this way we don't need special qemu support in the
 * generic smbios code.
 */
unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current)
{
	FWCfgFile f;
	struct smbios_header *header;
	unsigned long start, end;
	int ret, i, count = 1;
	char *str;

	if (fw_cfg_check_file(&f, "etc/smbios/smbios-tables"))
		return 0;

	printk(BIOS_DEBUG, "QEMU: found smbios tables in fw_cfg (len %d).\n", f.size);

	/*
	 * Search backwards for "coreboot" (first string in type0 table,
	 * see src/arch/x86/boot/smbios.c), then find type0 table.
	 */
	for (i = 0; i < 16384; i++) {
		str = (char*)(*current - i);
		if (strcmp(str, "coreboot") == 0)
			break;
	}
	if (i == 16384)
		return 0;
	i += sizeof(struct smbios_type0) - 2;
	header = (struct smbios_header *)(*current - i);
	if (header->type != SMBIOS_BIOS_INFORMATION || header->handle != 0)
		return 0;
	printk(BIOS_DEBUG, "QEMU: coreboot type0 table found at 0x%lx.\n",
	       *current - i);
	start = smbios_next(*current - i);

	/*
	 * Fetch smbios tables from qemu, go find the end marker.
	 * We'll exclude the end marker as coreboot will add one.
	 */
	printk(BIOS_DEBUG, "QEMU: loading smbios tables to 0x%lx\n", start);
	fw_cfg_get(f.select, (void *)start, f.size);
	end = start;
	do {
		header = (struct smbios_header *)end;
		if (header->type == SMBIOS_END_OF_TABLE)
			break;
		end = smbios_next(end);
		count++;
	} while (end < start + f.size);

	/* final fixups. */
	ret = end - *current;
	*current = end;
	*handle = count;
	return ret;
}

const char *smbios_mainboard_manufacturer(void)
{
	fw_cfg_smbios_init();
	return type1_manufacturer ?: CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
}

const char *smbios_mainboard_product_name(void)
{
	fw_cfg_smbios_init();
	return type1_product_name ?: CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME;
}

const char *smbios_mainboard_version(void)
{
	fw_cfg_smbios_init();
	return type1_version ?: CONFIG_MAINBOARD_VERSION;
}

const char *smbios_mainboard_serial_number(void)
{
	fw_cfg_smbios_init();
	return type1_serial_number ?: CONFIG_MAINBOARD_SERIAL_NUMBER;
}

void smbios_system_set_uuid(u8 *uuid)
{
	fw_cfg_smbios_init();
	memcpy(uuid, type1_uuid, 16);
}
#endif /* CONFIG(GENERATE_SMBIOS_TABLES) */

/*
 * Configure DMA setup
 */

static void fw_cfg_dma(int control, void *buf, int len)
{
	volatile FwCfgDmaAccess dma;
	uintptr_t dma_desc_addr;
	uint32_t dma_desc_addr_hi, dma_desc_addr_lo;

	dma.control = be32_to_cpu(control);
	dma.length  = be32_to_cpu(len);
	dma.address = be64_to_cpu((uintptr_t)buf);

	dma_desc_addr = (uintptr_t)&dma;
	dma_desc_addr_lo = (uint32_t)(dma_desc_addr & 0xFFFFFFFFU);
	dma_desc_addr_hi = sizeof(uintptr_t) > sizeof(uint32_t)
				? (uint32_t)(dma_desc_addr >> 32) : 0;

	// Skip writing high half if unnecessary.
	if (dma_desc_addr_hi)
		outl(be32_to_cpu(dma_desc_addr_hi), FW_CFG_DMA_ADDR_HIGH);
	outl(be32_to_cpu(dma_desc_addr_lo), FW_CFG_DMA_ADDR_LOW);

	while (be32_to_cpu(dma.control) & ~FW_CFG_DMA_CTL_ERROR)
		;
}
