// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2015 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

/*
 * Intel Simple Firmware Interface (SFI)
 *
 * Yet another way to pass information to the Linux kernel.
 *
 * See https://simplefirmware.org/ for details
 */

#include <cpu.h>
#include <dm.h>
#include <asm/cpu.h>
#include <asm/ioapic.h>
#include <asm/sfi.h>
#include <asm/tables.h>
#include <dm/uclass-internal.h>

struct table_info {
	u32 base;
	int ptr;
	u32 entry_start;
	u64 table[SFI_TABLE_MAX_ENTRIES];
	int count;
};

static void *get_entry_start(struct table_info *tab)
{
	if (tab->count == SFI_TABLE_MAX_ENTRIES)
		return NULL;
	tab->entry_start = tab->base + tab->ptr;
	tab->table[tab->count] = tab->entry_start;
	tab->entry_start += sizeof(struct sfi_table_header);

	return (void *)(uintptr_t)tab->entry_start;
}

static void finish_table(struct table_info *tab, const char *sig, void *entry)
{
	struct sfi_table_header *hdr;

	hdr = (struct sfi_table_header *)(uintptr_t)(tab->base + tab->ptr);
	strcpy(hdr->sig, sig);
	hdr->len = sizeof(*hdr) + ((ulong)entry - tab->entry_start);
	hdr->rev = 1;
	strncpy(hdr->oem_id, "U-Boot", SFI_OEM_ID_SIZE);
	strncpy(hdr->oem_table_id, "Table v1", SFI_OEM_TABLE_ID_SIZE);
	hdr->csum = 0;
	hdr->csum = table_compute_checksum(hdr, hdr->len);
	tab->ptr += hdr->len;
	tab->ptr = ALIGN(tab->ptr, 16);
	tab->count++;
}

static int sfi_write_system_header(struct table_info *tab)
{
	u64 *entry = get_entry_start(tab);
	int i;

	if (!entry)
		return -ENOSPC;

	for (i = 0; i < tab->count; i++)
		*entry++ = tab->table[i];
	finish_table(tab, SFI_SIG_SYST, entry);

	return 0;
}

static int sfi_write_cpus(struct table_info *tab)
{
	struct sfi_cpu_table_entry *entry = get_entry_start(tab);
	struct udevice *dev;
	int count = 0;

	if (!entry)
		return -ENOSPC;

	for (uclass_find_first_device(UCLASS_CPU, &dev);
	     dev;
	     uclass_find_next_device(&dev)) {
		struct cpu_plat *plat = dev_get_parent_plat(dev);

		if (!device_active(dev))
			continue;
		entry->apic_id = plat->cpu_id;
		entry++;
		count++;
	}

	/* Omit the table if there is only one CPU */
	if (count > 1)
		finish_table(tab, SFI_SIG_CPUS, entry);

	return 0;
}

static int sfi_write_apic(struct table_info *tab)
{
	struct sfi_apic_table_entry *entry = get_entry_start(tab);

	if (!entry)
		return -ENOSPC;

	entry->phys_addr = IO_APIC_ADDR;
	entry++;
	finish_table(tab, SFI_SIG_APIC, entry);

	return 0;
}

static int sfi_write_xsdt(struct table_info *tab)
{
	struct sfi_xsdt_header *entry = get_entry_start(tab);

	if (!entry)
		return -ENOSPC;

	entry->oem_revision = 1;
	entry->creator_id = 1;
	entry->creator_revision = 1;
	entry++;
	finish_table(tab, SFI_SIG_XSDT, entry);

	return 0;
}

ulong write_sfi_table(ulong base)
{
	struct table_info table;

	table.base = base;
	table.ptr = 0;
	table.count = 0;
	sfi_write_cpus(&table);
	sfi_write_apic(&table);

	/*
	 * The SFI specification marks the XSDT table as option, but Linux 4.0
	 * crashes on start-up when it is not provided.
	 */
	sfi_write_xsdt(&table);

	/* Finally, write out the system header which points to the others */
	sfi_write_system_header(&table);

	return base + table.ptr;
}
