/*
 * This file is part of the coreboot project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <string.h>
#include <swab.h>
#include <smbios.h>
#include <console/console.h>
#include <arch/io.h>
#include <arch/acpigen.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

static int fw_cfg_detected;

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

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

static void fw_cfg_select(uint16_t entry)
{
	outw(entry, FW_CFG_PORT_CTL);
}

static void fw_cfg_read(void *dst, int dstlen)
{
	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);
			return 0;
		}
	}
	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)) {
		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 -1;

	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(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, sizeof(current));
			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(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                                 */

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++) {
		insb(FW_CFG_PORT_DATA, &entry, sizeof(entry));
		buf = malloc(entry.length - sizeof(entry));
		insb(FW_CFG_PORT_DATA, 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_type0 *t0;
	int l, count = 0;
	char *s;

	t0 = (void*)current;
	current += t0->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_type0 *t0;
	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;
	t0 = (struct smbios_type0*)(*current - i);
	if (t0->type != SMBIOS_BIOS_INFORMATION || t0->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, sizeof(start));
	end = start;
	do {
		t0 = (struct smbios_type0*)end;
		if (t0->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_mainboard_set_uuid(u8 *uuid)
{
	fw_cfg_smbios_init();
	memcpy(uuid, type1_uuid, 16);
}
