// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2016-2018, NVIDIA CORPORATION.
 */

#include <common.h>
#include <env.h>
#include <fdt_support.h>
#include <fdtdec.h>
#include <hang.h>
#include <init.h>
#include <log.h>
#include <malloc.h>
#include <net.h>
#include <stdlib.h>
#include <string.h>
#include <asm/global_data.h>
#include <linux/printk.h>

#include <linux/ctype.h>
#include <linux/sizes.h>

#include <asm/arch/tegra.h>
#include <asm/arch-tegra/cboot.h>
#include <asm/armv8/mmu.h>

/*
 * Size of a region that's large enough to hold the relocated U-Boot and all
 * other allocations made around it (stack, heap, page tables, etc.)
 * In practice, running "bdinfo" at the shell prompt, the stack reaches about
 * 5MB from the address selected for ram_top as of the time of writing,
 * so a 16MB region should be plenty.
 */
#define MIN_USABLE_RAM_SIZE SZ_16M
/*
 * The amount of space we expect to require for stack usage. Used to validate
 * that all reservations fit into the region selected for the relocation target
 */
#define MIN_USABLE_STACK_SIZE SZ_1M

DECLARE_GLOBAL_DATA_PTR;

extern struct mm_region tegra_mem_map[];

/*
 * These variables are written to before relocation, and hence cannot be
 * in.bss, since .bss overlaps the DTB that's appended to the U-Boot binary.
 * The section attribute forces this into .data and avoids this issue. This
 * also has the nice side-effect of the content being valid after relocation.
 */

/* The number of valid entries in ram_banks[] */
static int ram_bank_count __section(".data");

/*
 * The usable top-of-RAM for U-Boot. This is both:
 * a) Below 4GB to avoid issues with peripherals that use 32-bit addressing.
 * b) At the end of a region that has enough space to hold the relocated U-Boot
 *    and all other allocations made around it (stack, heap, page tables, etc.)
 */
static u64 ram_top __section(".data");
/* The base address of the region of RAM that ends at ram_top */
static u64 region_base __section(".data");

/*
 * Explicitly put this in the .data section because it is written before the
 * .bss section is zeroed out but it needs to persist.
 */
unsigned long cboot_boot_x0 __section(".data");

void cboot_save_boot_params(unsigned long x0, unsigned long x1,
			    unsigned long x2, unsigned long x3)
{
	cboot_boot_x0 = x0;
}

int cboot_dram_init(void)
{
	unsigned int na, ns;
	const void *cboot_blob = (void *)cboot_boot_x0;
	int node, len, i;
	const u32 *prop;

	if (!cboot_blob)
		return -EINVAL;

	na = fdtdec_get_uint(cboot_blob, 0, "#address-cells", 2);
	ns = fdtdec_get_uint(cboot_blob, 0, "#size-cells", 2);

	node = fdt_path_offset(cboot_blob, "/memory");
	if (node < 0) {
		pr_err("Can't find /memory node in cboot DTB");
		hang();
	}
	prop = fdt_getprop(cboot_blob, node, "reg", &len);
	if (!prop) {
		pr_err("Can't find /memory/reg property in cboot DTB");
		hang();
	}

	/* Calculate the true # of base/size pairs to read */
	len /= 4;		/* Convert bytes to number of cells */
	len /= (na + ns);	/* Convert cells to number of banks */
	if (len > CONFIG_NR_DRAM_BANKS)
		len = CONFIG_NR_DRAM_BANKS;

	/* Parse the /memory node, and save useful entries */
	gd->ram_size = 0;
	ram_bank_count = 0;
	for (i = 0; i < len; i++) {
		u64 bank_start, bank_end, bank_size, usable_bank_size;

		/* Extract raw memory region data from DTB */
		bank_start = fdt_read_number(prop, na);
		prop += na;
		bank_size = fdt_read_number(prop, ns);
		prop += ns;
		gd->ram_size += bank_size;
		bank_end = bank_start + bank_size;
		debug("Bank %d: %llx..%llx (+%llx)\n", i,
		      bank_start, bank_end, bank_size);

		/*
		 * Align the bank to MMU section size. This is not strictly
		 * necessary, since the translation table construction code
		 * handles page granularity without issue. However, aligning
		 * the MMU entries reduces the size and number of levels in the
		 * page table, so is worth it.
		 */
		bank_start = ROUND(bank_start, SZ_2M);
		bank_end = bank_end & ~(SZ_2M - 1);
		bank_size = bank_end - bank_start;
		debug("  aligned: %llx..%llx (+%llx)\n",
		      bank_start, bank_end, bank_size);
		if (bank_end <= bank_start)
			continue;

		/* Record data used to create MMU translation tables */
		ram_bank_count++;
		/* Index below is deliberately 1-based to skip MMIO entry */
		tegra_mem_map[ram_bank_count].virt = bank_start;
		tegra_mem_map[ram_bank_count].phys = bank_start;
		tegra_mem_map[ram_bank_count].size = bank_size;
		tegra_mem_map[ram_bank_count].attrs =
			PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE;

		/* Determine best bank to relocate U-Boot into */
		if (bank_end > SZ_4G)
			bank_end = SZ_4G;
		debug("  end  %llx (usable)\n", bank_end);
		usable_bank_size = bank_end - bank_start;
		debug("  size %llx (usable)\n", usable_bank_size);
		if ((usable_bank_size >= MIN_USABLE_RAM_SIZE) &&
		    (bank_end > ram_top)) {
			ram_top = bank_end;
			region_base = bank_start;
			debug("ram top now %llx\n", ram_top);
		}
	}

	/* Ensure memory map contains the desired sentinel entry */
	tegra_mem_map[ram_bank_count + 1].virt = 0;
	tegra_mem_map[ram_bank_count + 1].phys = 0;
	tegra_mem_map[ram_bank_count + 1].size = 0;
	tegra_mem_map[ram_bank_count + 1].attrs = 0;

	/* Error out if a relocation target couldn't be found */
	if (!ram_top) {
		pr_err("Can't find a usable RAM top");
		hang();
	}

	return 0;
}

int cboot_dram_init_banksize(void)
{
	int i;

	if (ram_bank_count == 0)
		return -EINVAL;

	if ((gd->start_addr_sp - region_base) < MIN_USABLE_STACK_SIZE) {
		pr_err("Reservations exceed chosen region size");
		hang();
	}

	for (i = 0; i < ram_bank_count; i++) {
		gd->bd->bi_dram[i].start = tegra_mem_map[1 + i].virt;
		gd->bd->bi_dram[i].size = tegra_mem_map[1 + i].size;
	}

#ifdef CONFIG_PCI
	gd->pci_ram_top = ram_top;
#endif

	return 0;
}

ulong cboot_get_usable_ram_top(ulong total_size)
{
	return ram_top;
}

/*
 * The following few functions run late during the boot process and dynamically
 * calculate the load address of various binaries. To keep track of multiple
 * allocations, some writable list of RAM banks must be used. tegra_mem_map[]
 * is used for this purpose to avoid making yet another copy of the list of RAM
 * banks. This is safe because tegra_mem_map[] is only used once during very
 * early boot to create U-Boot's page tables, long before this code runs. If
 * this assumption becomes invalid later, we can just fix the code to copy the
 * list of RAM banks into some private data structure before running.
 */

static char *gen_varname(const char *var, const char *ext)
{
	size_t len_var = strlen(var);
	size_t len_ext = strlen(ext);
	size_t len = len_var + len_ext + 1;
	char *varext = malloc(len);

	if (!varext)
		return 0;
	strcpy(varext, var);
	strcpy(varext + len_var, ext);
	return varext;
}

static void mark_ram_allocated(int bank, u64 allocated_start, u64 allocated_end)
{
	u64 bank_start = tegra_mem_map[bank].virt;
	u64 bank_size = tegra_mem_map[bank].size;
	u64 bank_end = bank_start + bank_size;
	bool keep_front = allocated_start != bank_start;
	bool keep_tail = allocated_end != bank_end;

	if (keep_front && keep_tail) {
		/*
		 * There are CONFIG_NR_DRAM_BANKS DRAM entries in the array,
		 * starting at index 1 (index 0 is MMIO). So, we are at DRAM
		 * entry "bank" not "bank - 1" as for a typical 0-base array.
		 * The number of remaining DRAM entries is therefore
		 * "CONFIG_NR_DRAM_BANKS - bank". We want to duplicate the
		 * current entry and shift up the remaining entries, dropping
		 * the last one. Thus, we must copy one fewer entry than the
		 * number remaining.
		 */
		memmove(&tegra_mem_map[bank + 1], &tegra_mem_map[bank],
			CONFIG_NR_DRAM_BANKS - bank - 1);
		tegra_mem_map[bank].size = allocated_start - bank_start;
		bank++;
		tegra_mem_map[bank].virt = allocated_end;
		tegra_mem_map[bank].phys = allocated_end;
		tegra_mem_map[bank].size = bank_end - allocated_end;
	} else if (keep_front) {
		tegra_mem_map[bank].size = allocated_start - bank_start;
	} else if (keep_tail) {
		tegra_mem_map[bank].virt = allocated_end;
		tegra_mem_map[bank].phys = allocated_end;
		tegra_mem_map[bank].size = bank_end - allocated_end;
	} else {
		/*
		 * We could move all subsequent banks down in the array but
		 * that's not necessary for subsequent allocations to work, so
		 * we skip doing so.
		 */
		tegra_mem_map[bank].size = 0;
	}
}

static void reserve_ram(u64 start, u64 size)
{
	int bank;
	u64 end = start + size;

	for (bank = 1; bank <= CONFIG_NR_DRAM_BANKS; bank++) {
		u64 bank_start = tegra_mem_map[bank].virt;
		u64 bank_size = tegra_mem_map[bank].size;
		u64 bank_end = bank_start + bank_size;

		if (end <= bank_start || start > bank_end)
			continue;
		mark_ram_allocated(bank, start, end);
		break;
	}
}

static u64 alloc_ram(u64 size, u64 align, u64 offset)
{
	int bank;

	for (bank = 1; bank <= CONFIG_NR_DRAM_BANKS; bank++) {
		u64 bank_start = tegra_mem_map[bank].virt;
		u64 bank_size = tegra_mem_map[bank].size;
		u64 bank_end = bank_start + bank_size;
		u64 allocated = ROUND(bank_start, align) + offset;
		u64 allocated_end = allocated + size;

		if (allocated_end > bank_end)
			continue;
		mark_ram_allocated(bank, allocated, allocated_end);
		return allocated;
	}
	return 0;
}

static void set_calculated_aliases(char *aliases, u64 address)
{
	char *tmp, *alias;
	int err;

	aliases = strdup(aliases);
	if (!aliases) {
		pr_err("strdup(aliases) failed");
		return;
	}

	tmp = aliases;
	while (true) {
		alias = strsep(&tmp, " ");
		if (!alias)
			break;
		debug("%s: alias: %s\n", __func__, alias);
		err = env_set_hex(alias, address);
		if (err)
			pr_err("Could not set %s\n", alias);
	}

	free(aliases);
}

static void set_calculated_env_var(const char *var)
{
	char *var_size;
	char *var_align;
	char *var_offset;
	char *var_aliases;
	u64 size;
	u64 align;
	u64 offset;
	char *aliases;
	u64 address;
	int err;

	var_size = gen_varname(var, "_size");
	if (!var_size)
		return;
	var_align = gen_varname(var, "_align");
	if (!var_align)
		goto out_free_var_size;
	var_offset = gen_varname(var, "_offset");
	if (!var_offset)
		goto out_free_var_align;
	var_aliases = gen_varname(var, "_aliases");
	if (!var_aliases)
		goto out_free_var_offset;

	size = env_get_hex(var_size, 0);
	if (!size) {
		pr_err("%s not set or zero\n", var_size);
		goto out_free_var_aliases;
	}
	align = env_get_hex(var_align, 1);
	/* Handle extant variables, but with a value of 0 */
	if (!align)
		align = 1;
	offset = env_get_hex(var_offset, 0);
	aliases = env_get(var_aliases);

	debug("%s: Calc var %s; size=%llx, align=%llx, offset=%llx\n",
	      __func__, var, size, align, offset);
	if (aliases)
		debug("%s: Aliases: %s\n", __func__, aliases);

	address = alloc_ram(size, align, offset);
	if (!address) {
		pr_err("Could not allocate %s\n", var);
		goto out_free_var_aliases;
	}
	debug("%s: Address %llx\n", __func__, address);

	err = env_set_hex(var, address);
	if (err)
		pr_err("Could not set %s\n", var);
	if (aliases)
		set_calculated_aliases(aliases, address);

out_free_var_aliases:
	free(var_aliases);
out_free_var_offset:
	free(var_offset);
out_free_var_align:
	free(var_align);
out_free_var_size:
	free(var_size);
}

#ifdef DEBUG
static void dump_ram_banks(void)
{
	int bank;

	for (bank = 1; bank <= CONFIG_NR_DRAM_BANKS; bank++) {
		u64 bank_start = tegra_mem_map[bank].virt;
		u64 bank_size = tegra_mem_map[bank].size;
		u64 bank_end = bank_start + bank_size;

		if (!bank_size)
			continue;
		printf("%d: %010llx..%010llx (+%010llx)\n", bank - 1,
		       bank_start, bank_end, bank_size);
	}
}
#endif

static void set_calculated_env_vars(void)
{
	char *vars, *tmp, *var;

#ifdef DEBUG
	printf("RAM banks before any calculated env. var.s:\n");
	dump_ram_banks();
#endif

	reserve_ram(cboot_boot_x0, fdt_totalsize(cboot_boot_x0));

#ifdef DEBUG
	printf("RAM after reserving cboot DTB:\n");
	dump_ram_banks();
#endif

	vars = env_get("calculated_vars");
	if (!vars) {
		debug("%s: No env var calculated_vars\n", __func__);
		return;
	}

	vars = strdup(vars);
	if (!vars) {
		pr_err("strdup(calculated_vars) failed");
		return;
	}

	tmp = vars;
	while (true) {
		var = strsep(&tmp, " ");
		if (!var)
			break;
		debug("%s: var: %s\n", __func__, var);
		set_calculated_env_var(var);
#ifdef DEBUG
		printf("RAM banks after allocating %s:\n", var);
		dump_ram_banks();
#endif
	}

	free(vars);
}

static int set_fdt_addr(void)
{
	int ret;

	ret = env_set_hex("fdt_addr", cboot_boot_x0);
	if (ret) {
		printf("Failed to set fdt_addr to point at DTB: %d\n", ret);
		return ret;
	}

	return 0;
}

/*
 * Attempt to use /chosen/nvidia,ether-mac in the cboot DTB to U-Boot's
 * ethaddr environment variable if possible.
 */
static int cboot_get_ethaddr_legacy(const void *fdt, uint8_t mac[ETH_ALEN])
{
	const char *const properties[] = {
		"nvidia,ethernet-mac",
		"nvidia,ether-mac",
	};
	const char *prop;
	unsigned int i;
	int node, len;

	node = fdt_path_offset(fdt, "/chosen");
	if (node < 0) {
		printf("Can't find /chosen node in cboot DTB\n");
		return node;
	}

	for (i = 0; i < ARRAY_SIZE(properties); i++) {
		prop = fdt_getprop(fdt, node, properties[i], &len);
		if (prop)
			break;
	}

	if (!prop) {
		printf("Can't find Ethernet MAC address in cboot DTB\n");
		return -ENOENT;
	}

	string_to_enetaddr(prop, mac);

	if (!is_valid_ethaddr(mac)) {
		printf("Invalid MAC address: %s\n", prop);
		return -EINVAL;
	}

	debug("Legacy MAC address: %pM\n", mac);

	return 0;
}

int cboot_get_ethaddr(const void *fdt, uint8_t mac[ETH_ALEN])
{
	int node, len, err = 0;
	const uchar *prop;
	const char *path;

	path = fdt_get_alias(fdt, "ethernet");
	if (!path) {
		err = -ENOENT;
		goto out;
	}

	debug("ethernet alias found: %s\n", path);

	node = fdt_path_offset(fdt, path);
	if (node < 0) {
		err = -ENOENT;
		goto out;
	}

	prop = fdt_getprop(fdt, node, "local-mac-address", &len);
	if (!prop) {
		err = -ENOENT;
		goto out;
	}

	if (len != ETH_ALEN) {
		err = -EINVAL;
		goto out;
	}

	debug("MAC address: %pM\n", prop);
	memcpy(mac, prop, ETH_ALEN);

out:
	if (err < 0)
		err = cboot_get_ethaddr_legacy(fdt, mac);

	return err;
}

static char *strip(const char *ptr)
{
	const char *end;

	while (*ptr && isblank(*ptr))
		ptr++;

	/* empty string */
	if (*ptr == '\0')
		return strdup(ptr);

	end = ptr;

	while (end[1])
		end++;

	while (isblank(*end))
		end--;

	return strndup(ptr, end - ptr + 1);
}

static char *cboot_get_bootargs(const void *fdt)
{
	const char *args;
	int offset, len;

	offset = fdt_path_offset(fdt, "/chosen");
	if (offset < 0)
		return NULL;

	args = fdt_getprop(fdt, offset, "bootargs", &len);
	if (!args)
		return NULL;

	return strip(args);
}

int cboot_late_init(void)
{
	const void *fdt = (const void *)cboot_boot_x0;
	uint8_t mac[ETH_ALEN];
	char *bootargs;
	int err;

	set_calculated_env_vars();
	/*
	 * Ignore errors here; the value may not be used depending on
	 * extlinux.conf or boot script content.
	 */
	set_fdt_addr();

	/* Ignore errors here; not all cases care about Ethernet addresses */
	err = cboot_get_ethaddr(fdt, mac);
	if (!err) {
		void *blob = (void *)gd->fdt_blob;

		err = fdtdec_set_ethernet_mac_address(blob, mac, sizeof(mac));
		if (err < 0)
			printf("failed to set MAC address %pM: %d\n", mac, err);
	}

	bootargs = cboot_get_bootargs(fdt);
	if (bootargs) {
		env_set("cbootargs", bootargs);
		free(bootargs);
	}

	return 0;
}
