// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2017 Intel Corporation
 */

#include <common.h>
#include <init.h>
#include <log.h>
#include <asm/e820.h>
#include <asm/global_data.h>
#include <asm/sfi.h>
#include <linux/printk.h>

DECLARE_GLOBAL_DATA_PTR;

/*
 * SFI tables are part of the first stage bootloader.
 *
 * U-Boot finds the System Table by searching 16-byte boundaries between
 * physical address 0x000E0000 and 0x000FFFFF. U-Boot shall search this region
 * starting at the low address and shall stop searching when the 1st valid SFI
 * System Table is found.
 */
#define SFI_BASE_ADDR		0x000E0000
#define SFI_LENGTH		0x00020000
#define SFI_TABLE_LENGTH	16

static int sfi_table_check(struct sfi_table_header *sbh)
{
	char chksum = 0;
	char *pos = (char *)sbh;
	u32 i;

	if (sbh->len < SFI_TABLE_LENGTH)
		return -ENXIO;

	if (sbh->len > SFI_LENGTH)
		return -ENXIO;

	for (i = 0; i < sbh->len; i++)
		chksum += *pos++;

	if (chksum)
		pr_err("sfi: Invalid checksum\n");

	/* Checksum is OK if zero */
	return chksum ? -EILSEQ : 0;
}

static int sfi_table_is_type(struct sfi_table_header *sbh, const char *signature)
{
	return !strncmp(sbh->sig, signature, SFI_SIGNATURE_SIZE) &&
	       !sfi_table_check(sbh);
}

static struct sfi_table_simple *sfi_get_table_by_sig(unsigned long addr,
						     const char *signature)
{
	struct sfi_table_simple *sb;
	u32 i;

	for (i = 0; i < SFI_LENGTH; i += SFI_TABLE_LENGTH) {
		sb = (struct sfi_table_simple *)(addr + i);
		if (sfi_table_is_type(&sb->header, signature))
			return sb;
	}

	return NULL;
}

static struct sfi_table_simple *sfi_search_mmap(void)
{
	struct sfi_table_header *sbh;
	struct sfi_table_simple *sb;
	u32 sys_entry_cnt;
	u32 i;

	/* Find SYST table */
	sb = sfi_get_table_by_sig(SFI_BASE_ADDR, SFI_SIG_SYST);
	if (!sb) {
		pr_err("sfi: failed to locate SYST table\n");
		return NULL;
	}

	sys_entry_cnt = (sb->header.len - sizeof(*sbh)) / 8;

	/* Search through each SYST entry for MMAP table */
	for (i = 0; i < sys_entry_cnt; i++) {
		sbh = (struct sfi_table_header *)(unsigned long)sb->pentry[i];

		if (sfi_table_is_type(sbh, SFI_SIG_MMAP))
			return (struct sfi_table_simple *)sbh;
	}

	pr_err("sfi: failed to locate SFI MMAP table\n");
	return NULL;
}

#define sfi_for_each_mentry(i, sb, mentry)				\
	for (i = 0, mentry = (struct sfi_mem_entry *)sb->pentry;	\
	     i < SFI_GET_NUM_ENTRIES(sb, struct sfi_mem_entry);		\
	     i++, mentry++)						\

static unsigned int sfi_setup_e820(unsigned int max_entries,
				   struct e820_entry *entries)
{
	struct sfi_table_simple *sb;
	struct sfi_mem_entry *mentry;
	unsigned long long start, end, size;
	int type, total = 0;
	u32 i;

	sb = sfi_search_mmap();
	if (!sb)
		return 0;

	sfi_for_each_mentry(i, sb, mentry) {
		start = mentry->phys_start;
		size = mentry->pages << 12;
		end = start + size;

		if (start > end)
			continue;

		/* translate SFI mmap type to E820 map type */
		switch (mentry->type) {
		case SFI_MEM_CONV:
			type = E820_RAM;
			break;
		case SFI_MEM_UNUSABLE:
		case SFI_RUNTIME_SERVICE_DATA:
			continue;
		default:
			type = E820_RESERVED;
		}

		if (total == E820MAX)
			break;
		entries[total].addr = start;
		entries[total].size = size;
		entries[total].type = type;

		total++;
	}

	return total;
}

static int sfi_get_bank_size(void)
{
	struct sfi_table_simple *sb;
	struct sfi_mem_entry *mentry;
	int bank = 0;
	u32 i;

	sb = sfi_search_mmap();
	if (!sb)
		return 0;

	sfi_for_each_mentry(i, sb, mentry) {
		if (mentry->type != SFI_MEM_CONV)
			continue;

		gd->bd->bi_dram[bank].start = mentry->phys_start;
		gd->bd->bi_dram[bank].size = mentry->pages << 12;
		bank++;
	}

	return bank;
}

static phys_size_t sfi_get_ram_size(void)
{
	struct sfi_table_simple *sb;
	struct sfi_mem_entry *mentry;
	phys_size_t ram = 0;
	u32 i;

	sb = sfi_search_mmap();
	if (!sb)
		return 0;

	sfi_for_each_mentry(i, sb, mentry) {
		if (mentry->type != SFI_MEM_CONV)
			continue;

		ram += mentry->pages << 12;
	}

	debug("sfi: RAM size %llu\n", ram);
	return ram;
}

unsigned int install_e820_map(unsigned int max_entries,
			      struct e820_entry *entries)
{
	return sfi_setup_e820(max_entries, entries);
}

/*
 * This function looks for the highest region of memory lower than 2GB which
 * has enough space for U-Boot where U-Boot is aligned on a page boundary. It
 * overrides the default implementation found elsewhere which simply picks the
 * end of RAM, wherever that may be. The location of the stack, the relocation
 * address, and how far U-Boot is moved by relocation are set in the global
 * data structure.
 */
phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
{
	struct sfi_table_simple *sb;
	struct sfi_mem_entry *mentry;
	ulong dest_addr = 0;
	u32 i;

	sb = sfi_search_mmap();
	if (!sb)
		panic("No available memory found for relocation");

	sfi_for_each_mentry(i, sb, mentry) {
		unsigned long long start, end;

		if (mentry->type != SFI_MEM_CONV)
			continue;

		start = mentry->phys_start;
		end = start + (mentry->pages << 12);

		/* Filter memory over 2GB. */
		if (end > 0x7fffffffULL)
			end = 0x80000000ULL;
		/* Skip this region if it's too small. */
		if (end - start < total_size)
			continue;

		/* Use this address if it's the largest so far. */
		if (end > dest_addr)
			dest_addr = end;
	}

	return dest_addr;
}

int dram_init_banksize(void)
{
	sfi_get_bank_size();
	return 0;
}

int dram_init(void)
{
	gd->ram_size = sfi_get_ram_size();
	return 0;
}
