// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2013, Google Inc.
 *
 * (C) Copyright 2008 Semihalf
 *
 * (C) Copyright 2000-2006
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#include <command.h>
#include <fdt_support.h>
#include <fdtdec.h>
#include <env.h>
#include <errno.h>
#include <image.h>
#include <lmb.h>
#include <log.h>
#include <malloc.h>
#include <asm/global_data.h>
#include <linux/libfdt.h>
#include <mapmem.h>
#include <asm/io.h>
#include <dm/ofnode.h>
#include <tee/optee.h>

DECLARE_GLOBAL_DATA_PTR;

static void fdt_error(const char *msg)
{
	puts("ERROR: ");
	puts(msg);
	puts(" - must RESET the board to recover.\n");
}

#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr)
{
	const struct legacy_img_hdr *fdt_hdr = map_sysmem(fdt_addr, 0);

	image_print_contents(fdt_hdr);

	puts("   Verifying Checksum ... ");
	if (!image_check_hcrc(fdt_hdr)) {
		fdt_error("fdt header checksum invalid");
		return NULL;
	}

	if (!image_check_dcrc(fdt_hdr)) {
		fdt_error("fdt checksum invalid");
		return NULL;
	}
	puts("OK\n");

	if (!image_check_type(fdt_hdr, IH_TYPE_FLATDT)) {
		fdt_error("uImage is not a fdt");
		return NULL;
	}
	if (image_get_comp(fdt_hdr) != IH_COMP_NONE) {
		fdt_error("uImage is compressed");
		return NULL;
	}
	if (fdt_check_header((void *)image_get_data(fdt_hdr)) != 0) {
		fdt_error("uImage data is not a fdt");
		return NULL;
	}
	return fdt_hdr;
}
#endif

static void boot_fdt_reserve_region(u64 addr, u64 size, enum lmb_flags flags)
{
	long ret;

	ret = lmb_reserve_flags(addr, size, flags);
	if (!ret) {
		debug("   reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
		      (unsigned long long)addr,
		      (unsigned long long)size, flags);
	} else {
		puts("ERROR: reserving fdt memory region failed ");
		printf("(addr=%llx size=%llx flags=%x)\n",
		       (unsigned long long)addr,
		       (unsigned long long)size, flags);
	}
}

/**
 * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
 * sections as unusable
 * @fdt_blob: pointer to fdt blob base address
 *
 * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block.
 * Adding the memreserve regions prevents u-boot from using them to store the
 * initrd or the fdt blob.
 */
void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
{
	uint64_t addr, size;
	int i, total, ret;
	int nodeoffset, subnode;
	struct fdt_resource res;
	enum lmb_flags flags;

	if (fdt_check_header(fdt_blob) != 0)
		return;

	/* process memreserve sections */
	total = fdt_num_mem_rsv(fdt_blob);
	for (i = 0; i < total; i++) {
		if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
			continue;
		boot_fdt_reserve_region(addr, size, LMB_NOOVERWRITE);
	}

	/* process reserved-memory */
	nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory");
	if (nodeoffset >= 0) {
		subnode = fdt_first_subnode(fdt_blob, nodeoffset);
		while (subnode >= 0) {
			/* check if this subnode has a reg property */
			ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
					       &res);
			if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) {
				flags = LMB_NOOVERWRITE;
				if (fdtdec_get_bool(fdt_blob, subnode,
						    "no-map"))
					flags = LMB_NOMAP;
				addr = res.start;
				size = res.end - res.start + 1;
				boot_fdt_reserve_region(addr, size, flags);
			}

			subnode = fdt_next_subnode(fdt_blob, subnode);
		}
	}
}

/**
 * boot_relocate_fdt - relocate flat device tree
 * @of_flat_tree: pointer to a char* variable, will hold fdt start address
 * @of_size: pointer to a ulong variable, will hold fdt length
 *
 * boot_relocate_fdt() allocates a region of memory within the bootmap and
 * relocates the of_flat_tree into that region, even if the fdt is already in
 * the bootmap.  It also expands the size of the fdt by CONFIG_SYS_FDT_PAD
 * bytes.
 *
 * of_flat_tree and of_size are set to final (after relocation) values
 *
 * returns:
 *      0 - success
 *      1 - failure
 */
int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
{
	u64	start, size, usable, addr, low, mapsize;
	void	*fdt_blob = *of_flat_tree;
	void	*of_start = NULL;
	char	*fdt_high;
	ulong	of_len = 0;
	int	bank;
	int	err;
	int	disable_relocation = 0;

	/* nothing to do */
	if (*of_size == 0)
		return 0;

	if (fdt_check_header(fdt_blob) != 0) {
		fdt_error("image is not a fdt");
		goto error;
	}

	/* position on a 4K boundary before the alloc_current */
	/* Pad the FDT by a specified amount */
	of_len = *of_size + CONFIG_SYS_FDT_PAD;

	/* If fdt_high is set use it to select the relocation address */
	fdt_high = env_get("fdt_high");
	if (fdt_high) {
		ulong desired_addr = hextoul(fdt_high, NULL);

		if (desired_addr == ~0UL) {
			/* All ones means use fdt in place */
			of_start = fdt_blob;
			lmb_reserve(map_to_sysmem(of_start), of_len);
			disable_relocation = 1;
		} else if (desired_addr) {
			addr = lmb_alloc_base(of_len, 0x1000, desired_addr);
			of_start = map_sysmem(addr, of_len);
			if (of_start == NULL) {
				puts("Failed using fdt_high value for Device Tree");
				goto error;
			}
		} else {
			addr = lmb_alloc(of_len, 0x1000);
			of_start = map_sysmem(addr, of_len);
		}
	} else {
		mapsize = env_get_bootm_mapsize();
		low = env_get_bootm_low();
		of_start = NULL;

		for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
			start = gd->bd->bi_dram[bank].start;
			size = gd->bd->bi_dram[bank].size;

			/* DRAM bank addresses are too low, skip it. */
			if (start + size < low)
				continue;

			/*
			 * At least part of this DRAM bank is usable, try
			 * using the DRAM bank up to 'usable' address limit
			 * for LMB allocation.
			 */
			usable = min(start + size, low + mapsize);
			addr = lmb_alloc_base(of_len, 0x1000, usable);
			of_start = map_sysmem(addr, of_len);
			/* Allocation succeeded, use this block. */
			if (of_start != NULL)
				break;

			/*
			 * Reduce the mapping size in the next bank
			 * by the size of attempt in current bank.
			 */
			mapsize -= usable - max(start, low);
			if (!mapsize)
				break;
		}
	}

	if (of_start == NULL) {
		puts("device tree - allocation error\n");
		goto error;
	}

	if (disable_relocation) {
		/*
		 * We assume there is space after the existing fdt to use
		 * for padding
		 */
		fdt_set_totalsize(of_start, of_len);
		printf("   Using Device Tree in place at %p, end %p\n",
		       of_start, of_start + of_len - 1);
	} else {
		debug("## device tree at %p ... %p (len=%ld [0x%lX])\n",
		      fdt_blob, fdt_blob + *of_size - 1, of_len, of_len);

		printf("   Loading Device Tree to %p, end %p ... ",
		       of_start, of_start + of_len - 1);

		err = fdt_open_into(fdt_blob, of_start, of_len);
		if (err != 0) {
			fdt_error("fdt move failed");
			goto error;
		}
		puts("OK\n");
	}

	*of_flat_tree = of_start;
	*of_size = of_len;

	if (IS_ENABLED(CONFIG_CMD_FDT))
		set_working_fdt_addr(map_to_sysmem(*of_flat_tree));
	return 0;

error:
	return 1;
}

/**
 * select_fdt() - Select and locate the FDT to use
 *
 * @images: pointer to the bootm images structure
 * @select: name of FDT to select, or NULL for any
 * @arch: expected FDT architecture
 * @fdt_addrp: pointer to a ulong variable, will hold FDT pointer
 * Return: 0 if OK, -ENOPKG if no FDT (but an error should not be reported),
 *	other -ve value on other error
 */

static int select_fdt(struct bootm_headers *images, const char *select, u8 arch,
		      ulong *fdt_addrp)
{
	const char *buf;
	ulong fdt_addr;

#if CONFIG_IS_ENABLED(FIT)
	const char *fit_uname_config = images->fit_uname_cfg;
	const char *fit_uname_fdt = NULL;
	ulong default_addr;
	int fdt_noffset;

	if (select) {
			/*
			 * If the FDT blob comes from the FIT image and the
			 * FIT image address is omitted in the command line
			 * argument, try to use ramdisk or os FIT image
			 * address or default load address.
			 */
			if (images->fit_uname_rd)
				default_addr = (ulong)images->fit_hdr_rd;
			else if (images->fit_uname_os)
				default_addr = (ulong)images->fit_hdr_os;
			else
				default_addr = image_load_addr;

			if (fit_parse_conf(select, default_addr, &fdt_addr,
					   &fit_uname_config)) {
				debug("*  fdt: config '%s' from image at 0x%08lx\n",
				      fit_uname_config, fdt_addr);
			} else if (fit_parse_subimage(select, default_addr, &fdt_addr,
				   &fit_uname_fdt)) {
				debug("*  fdt: subimage '%s' from image at 0x%08lx\n",
				      fit_uname_fdt, fdt_addr);
			} else
#endif
		{
			fdt_addr = hextoul(select, NULL);
			debug("*  fdt: cmdline image address = 0x%08lx\n",
			      fdt_addr);
		}
#if CONFIG_IS_ENABLED(FIT)
	} else {
		/* use FIT configuration provided in first bootm
		 * command argument
		 */
		fdt_addr = map_to_sysmem(images->fit_hdr_os);
		fdt_noffset = fit_get_node_from_config(images, FIT_FDT_PROP,
						       fdt_addr);
		if (fdt_noffset == -ENOENT)
			return -ENOPKG;
		else if (fdt_noffset < 0)
			return fdt_noffset;
	}
#endif
	debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",
	      fdt_addr);

	/*
	 * Check if there is an FDT image at the
	 * address provided in the second bootm argument
	 * check image type, for FIT images get a FIT node.
	 */
	buf = map_sysmem(fdt_addr, 0);
	switch (genimg_get_format(buf)) {
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
	case IMAGE_FORMAT_LEGACY: {
			const struct legacy_img_hdr *fdt_hdr;
			ulong load, load_end;
			ulong image_start, image_data, image_end;

			/* verify fdt_addr points to a valid image header */
			printf("## Flattened Device Tree from Legacy Image at %08lx\n",
			       fdt_addr);
			fdt_hdr = image_get_fdt(fdt_addr);
			if (!fdt_hdr)
				return -ENOPKG;

			/*
			 * move image data to the load address,
			 * make sure we don't overwrite initial image
			 */
			image_start = (ulong)fdt_hdr;
			image_data = (ulong)image_get_data(fdt_hdr);
			image_end = image_get_image_end(fdt_hdr);

			load = image_get_load(fdt_hdr);
			load_end = load + image_get_data_size(fdt_hdr);

			if (load == image_start ||
			    load == image_data) {
				fdt_addr = load;
				break;
			}

			if ((load < image_end) && (load_end > image_start)) {
				fdt_error("fdt overwritten");
				return -EFAULT;
			}

			debug("   Loading FDT from 0x%08lx to 0x%08lx\n",
			      image_data, load);

			memmove((void *)load,
				(void *)image_data,
				image_get_data_size(fdt_hdr));

			fdt_addr = load;
			break;
		}
#endif
	case IMAGE_FORMAT_FIT:
		/*
		 * This case will catch both: new uImage format
		 * (libfdt based) and raw FDT blob (also libfdt
		 * based).
		 */
#if CONFIG_IS_ENABLED(FIT)
			/* check FDT blob vs FIT blob */
			if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {
				ulong load, len;

				fdt_noffset = boot_get_fdt_fit(images, fdt_addr,
							       &fit_uname_fdt,
							       &fit_uname_config,
							       arch, &load, &len);

				if (fdt_noffset < 0)
					return -ENOENT;

				images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
				images->fit_uname_fdt = fit_uname_fdt;
				images->fit_noffset_fdt = fdt_noffset;
				fdt_addr = load;

				break;
		} else
#endif
		{
			/*
			 * FDT blob
			 */
			debug("*  fdt: raw FDT blob\n");
			printf("## Flattened Device Tree blob at %08lx\n",
			       (long)fdt_addr);
		}
		break;
	default:
		puts("ERROR: Did not find a cmdline Flattened Device Tree\n");
		return -ENOENT;
	}
	*fdt_addrp = fdt_addr;

	return 0;
}

int boot_get_fdt(void *buf, const char *select, uint arch,
		 struct bootm_headers *images, char **of_flat_tree,
		 ulong *of_size)
{
	char *fdt_blob = NULL;
	ulong fdt_addr;

	*of_flat_tree = NULL;
	*of_size = 0;

	if (select || genimg_has_config(images)) {
		int ret;

		ret = select_fdt(images, select, arch, &fdt_addr);
		if (ret == -ENOPKG)
			goto no_fdt;
		else if (ret)
			return 1;
		printf("   Booting using the fdt blob at %#08lx\n", fdt_addr);
		fdt_blob = map_sysmem(fdt_addr, 0);
	} else if (images->legacy_hdr_valid &&
			image_check_type(&images->legacy_hdr_os_copy,
					 IH_TYPE_MULTI)) {
		ulong fdt_data, fdt_len;

		/*
		 * Now check if we have a legacy multi-component image,
		 * get second entry data start address and len.
		 */
		printf("## Flattened Device Tree from multi component Image at %08lX\n",
		       (ulong)images->legacy_hdr_os);

		image_multi_getimg(images->legacy_hdr_os, 2, &fdt_data,
				   &fdt_len);
		if (fdt_len) {
			fdt_blob = (char *)fdt_data;
			printf("   Booting using the fdt at 0x%p\n", fdt_blob);

			if (fdt_check_header(fdt_blob) != 0) {
				fdt_error("image is not a fdt");
				goto error;
			}

			if (fdt_totalsize(fdt_blob) != fdt_len) {
				fdt_error("fdt size != image size");
				goto error;
			}
		} else {
			debug("## No Flattened Device Tree\n");
			goto no_fdt;
		}
#ifdef CONFIG_ANDROID_BOOT_IMAGE
	} else if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) {
		void *hdr = buf;
		ulong		fdt_data, fdt_len;
		u32			fdt_size, dtb_idx;
		/*
		 * Firstly check if this android boot image has dtb field.
		 */
		dtb_idx = (u32)env_get_ulong("adtb_idx", 10, 0);
		if (android_image_get_dtb_by_index((ulong)hdr, get_avendor_bootimg_addr(),
						   dtb_idx, &fdt_addr, &fdt_size)) {
			fdt_blob = (char *)map_sysmem(fdt_addr, 0);
			if (fdt_check_header(fdt_blob))
				goto no_fdt;

			debug("## Using FDT in Android image dtb area with idx %u\n", dtb_idx);
		} else if (!android_image_get_second(hdr, &fdt_data, &fdt_len) &&
			!fdt_check_header((char *)fdt_data)) {
			fdt_blob = (char *)fdt_data;
			if (fdt_totalsize(fdt_blob) != fdt_len)
				goto error;

			debug("## Using FDT in Android image second area\n");
		} else {
			fdt_addr = env_get_hex("fdtaddr", 0);
			if (!fdt_addr)
				goto no_fdt;

			fdt_blob = map_sysmem(fdt_addr, 0);
			if (fdt_check_header(fdt_blob))
				goto no_fdt;

			debug("## Using FDT at ${fdtaddr}=Ox%lx\n", fdt_addr);
		}
#endif
	} else {
		debug("## No Flattened Device Tree\n");
		goto no_fdt;
	}

	*of_flat_tree = fdt_blob;
	*of_size = fdt_totalsize(fdt_blob);
	debug("   of_flat_tree at 0x%08lx size 0x%08lx\n",
	      (ulong)*of_flat_tree, *of_size);

	return 0;

no_fdt:
	debug("Continuing to boot without FDT\n");
	return 0;
error:
	return 1;
}

/*
 * Verify the device tree.
 *
 * This function is called after all device tree fix-ups have been enacted,
 * so that the final device tree can be verified.  The definition of "verified"
 * is up to the specific implementation.  However, it generally means that the
 * addresses of some of the devices in the device tree are compared with the
 * actual addresses at which U-Boot has placed them.
 *
 * Returns 1 on success, 0 on failure.  If 0 is returned, U-Boot will halt the
 * boot process.
 */
__weak int ft_verify_fdt(void *fdt)
{
	return 1;
}

__weak int arch_fixup_fdt(void *blob)
{
	return 0;
}

int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
{
	ulong *initrd_start = &images->initrd_start;
	ulong *initrd_end = &images->initrd_end;
	int ret, fdt_ret, of_size;

	if (IS_ENABLED(CONFIG_OF_ENV_SETUP)) {
		const char *fdt_fixup;

		fdt_fixup = env_get("fdt_fixup");
		if (fdt_fixup) {
			set_working_fdt_addr(map_to_sysmem(blob));
			ret = run_command_list(fdt_fixup, -1, 0);
			if (ret)
				printf("WARNING: fdt_fixup command returned %d\n",
				       ret);
		}
	}

	ret = -EPERM;

	if (fdt_root(blob) < 0) {
		printf("ERROR: root node setup failed\n");
		goto err;
	}
	if (fdt_chosen(blob) < 0) {
		printf("ERROR: /chosen node create failed\n");
		goto err;
	}
	if (arch_fixup_fdt(blob) < 0) {
		printf("ERROR: arch-specific fdt fixup failed\n");
		goto err;
	}

	fdt_ret = optee_copy_fdt_nodes(blob);
	if (fdt_ret) {
		printf("ERROR: transfer of optee nodes to new fdt failed: %s\n",
		       fdt_strerror(fdt_ret));
		goto err;
	}

	/* Store name of configuration node as u-boot,bootconf in /chosen node */
	if (images->fit_uname_cfg)
		fdt_find_and_setprop(blob, "/chosen", "u-boot,bootconf",
					images->fit_uname_cfg,
					strlen(images->fit_uname_cfg) + 1, 1);

	/* Update ethernet nodes */
	fdt_fixup_ethernet(blob);
#if IS_ENABLED(CONFIG_CMD_PSTORE)
	/* Append PStore configuration */
	fdt_fixup_pstore(blob);
#endif
	if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) {
		const char *skip_board_fixup;

		skip_board_fixup = env_get("skip_board_fixup");
		if (skip_board_fixup && ((int)simple_strtol(skip_board_fixup, NULL, 10) == 1)) {
			printf("skip board fdt fixup\n");
		} else {
			fdt_ret = ft_board_setup(blob, gd->bd);
			if (fdt_ret) {
				printf("ERROR: board-specific fdt fixup failed: %s\n",
				       fdt_strerror(fdt_ret));
				goto err;
			}
		}
	}
	if (IS_ENABLED(CONFIG_OF_SYSTEM_SETUP)) {
		fdt_ret = ft_system_setup(blob, gd->bd);
		if (fdt_ret) {
			printf("ERROR: system-specific fdt fixup failed: %s\n",
			       fdt_strerror(fdt_ret));
			goto err;
		}
	}

	if (fdt_initrd(blob, *initrd_start, *initrd_end))
		goto err;

	if (!ft_verify_fdt(blob))
		goto err;

	/* after here we are using a livetree */
	if (!of_live_active() && CONFIG_IS_ENABLED(EVENT)) {
		struct event_ft_fixup fixup;

		fixup.tree = oftree_from_fdt(blob);
		fixup.images = images;
		if (oftree_valid(fixup.tree)) {
			ret = event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup));
			if (ret) {
				printf("ERROR: fdt fixup event failed: %d\n",
				       ret);
				goto err;
			}
		}
	}

	/* Delete the old LMB reservation */
	if (CONFIG_IS_ENABLED(LMB) && lmb)
		lmb_free(map_to_sysmem(blob), fdt_totalsize(blob));

	ret = fdt_shrink_to_minimum(blob, 0);
	if (ret < 0)
		goto err;
	of_size = ret;

	/* Create a new LMB reservation */
	if (CONFIG_IS_ENABLED(LMB) && lmb)
		lmb_reserve(map_to_sysmem(blob), of_size);

#if defined(CONFIG_ARCH_KEYSTONE)
	if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))
		ft_board_setup_ex(blob, gd->bd);
#endif

	return 0;
err:
	printf(" - must RESET the board to recover.\n\n");

	return ret;
}
