// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2000-2009
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#ifndef USE_HOSTCC
#include <common.h>
#include <bootstage.h>
#include <cli.h>
#include <cpu_func.h>
#include <env.h>
#include <errno.h>
#include <fdt_support.h>
#include <irq_func.h>
#include <lmb.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <net.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/sizes.h>
#if defined(CONFIG_CMD_USB)
#include <usb.h>
#endif
#else
#include "mkimage.h"
#endif

#include <command.h>
#include <bootm.h>
#include <image.h>

#define MAX_CMDLINE_SIZE	SZ_4K

#define IH_INITRD_ARCH IH_ARCH_DEFAULT

#ifndef USE_HOSTCC

DECLARE_GLOBAL_DATA_PTR;

struct bootm_headers images;		/* pointers to os/initrd/fdt images */

static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
				   char *const argv[], struct bootm_headers *images,
				   ulong *os_data, ulong *os_len);

__weak void board_quiesce_devices(void)
{
}

#ifdef CONFIG_LMB
static void boot_start_lmb(struct bootm_headers *images)
{
	ulong		mem_start;
	phys_size_t	mem_size;

	mem_start = env_get_bootm_low();
	mem_size = env_get_bootm_size();

	lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
				   mem_size, NULL);
}
#else
#define lmb_reserve(lmb, base, size)
static inline void boot_start_lmb(struct bootm_headers *images) { }
#endif

static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc,
		       char *const argv[])
{
	memset((void *)&images, 0, sizeof(images));
	images.verify = env_get_yesno("verify");

	boot_start_lmb(&images);

	bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
	images.state = BOOTM_STATE_START;

	return 0;
}

static ulong bootm_data_addr(int argc, char *const argv[])
{
	ulong addr;

	if (argc > 0)
		addr = simple_strtoul(argv[0], NULL, 16);
	else
		addr = image_load_addr;

	return addr;
}

static int bootm_pre_load(struct cmd_tbl *cmdtp, int flag, int argc,
			  char *const argv[])
{
	ulong data_addr = bootm_data_addr(argc, argv);
	int ret = 0;

	if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD))
		ret = image_pre_load(data_addr);

	if (ret)
		ret = CMD_RET_FAILURE;

	return ret;
}

static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
			 char *const argv[])
{
	const void *os_hdr;
#ifdef CONFIG_ANDROID_BOOT_IMAGE
	const void *vendor_boot_img;
	const void *boot_img;
#endif
	bool ep_found = false;
	int ret;

	/* get kernel image header, start address and length */
	os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
			&images, &images.os.image_start, &images.os.image_len);
	if (images.os.image_len == 0) {
		puts("ERROR: can't get kernel image!\n");
		return 1;
	}

	/* get image parameters */
	switch (genimg_get_format(os_hdr)) {
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
	case IMAGE_FORMAT_LEGACY:
		images.os.type = image_get_type(os_hdr);
		images.os.comp = image_get_comp(os_hdr);
		images.os.os = image_get_os(os_hdr);

		images.os.end = image_get_image_end(os_hdr);
		images.os.load = image_get_load(os_hdr);
		images.os.arch = image_get_arch(os_hdr);
		break;
#endif
#if CONFIG_IS_ENABLED(FIT)
	case IMAGE_FORMAT_FIT:
		if (fit_image_get_type(images.fit_hdr_os,
				       images.fit_noffset_os,
				       &images.os.type)) {
			puts("Can't get image type!\n");
			bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
			return 1;
		}

		if (fit_image_get_comp(images.fit_hdr_os,
				       images.fit_noffset_os,
				       &images.os.comp)) {
			puts("Can't get image compression!\n");
			bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
			return 1;
		}

		if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
				     &images.os.os)) {
			puts("Can't get image OS!\n");
			bootstage_error(BOOTSTAGE_ID_FIT_OS);
			return 1;
		}

		if (fit_image_get_arch(images.fit_hdr_os,
				       images.fit_noffset_os,
				       &images.os.arch)) {
			puts("Can't get image ARCH!\n");
			return 1;
		}

		images.os.end = fit_get_end(images.fit_hdr_os);

		if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
				       &images.os.load)) {
			puts("Can't get image load address!\n");
			bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
			return 1;
		}
		break;
#endif
#ifdef CONFIG_ANDROID_BOOT_IMAGE
	case IMAGE_FORMAT_ANDROID:
		boot_img = os_hdr;
		vendor_boot_img = NULL;
		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
			boot_img = map_sysmem(get_abootimg_addr(), 0);
			vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0);
		}
		images.os.type = IH_TYPE_KERNEL;
		images.os.comp = android_image_get_kcomp(boot_img, vendor_boot_img);
		images.os.os = IH_OS_LINUX;
		images.os.end = android_image_get_end(boot_img, vendor_boot_img);
		images.os.load = android_image_get_kload(boot_img, vendor_boot_img);
		images.ep = images.os.load;
		ep_found = true;
		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
			unmap_sysmem(vendor_boot_img);
			unmap_sysmem(boot_img);
		}
		break;
#endif
	default:
		puts("ERROR: unknown image format type!\n");
		return 1;
	}

	/* If we have a valid setup.bin, we will use that for entry (x86) */
	if (images.os.arch == IH_ARCH_I386 ||
	    images.os.arch == IH_ARCH_X86_64) {
		ulong len;

		ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
		if (ret < 0 && ret != -ENOENT) {
			puts("Could not find a valid setup.bin for x86\n");
			return 1;
		}
		/* Kernel entry point is the setup.bin */
	} else if (images.legacy_hdr_valid) {
		images.ep = image_get_ep(&images.legacy_hdr_os_copy);
#if CONFIG_IS_ENABLED(FIT)
	} else if (images.fit_uname_os) {
		int ret;

		ret = fit_image_get_entry(images.fit_hdr_os,
					  images.fit_noffset_os, &images.ep);
		if (ret) {
			puts("Can't get entry point property!\n");
			return 1;
		}
#endif
	} else if (!ep_found) {
		puts("Could not find kernel entry point!\n");
		return 1;
	}

	if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
		if (IS_ENABLED(CONFIG_CMD_BOOTI) &&
		    images.os.arch == IH_ARCH_ARM64) {
			ulong image_addr;
			ulong image_size;

			ret = booti_setup(images.os.image_start, &image_addr,
					  &image_size, true);
			if (ret != 0)
				return 1;

			images.os.type = IH_TYPE_KERNEL;
			images.os.load = image_addr;
			images.ep = image_addr;
		} else {
			images.os.load = images.os.image_start;
			images.ep += images.os.image_start;
		}
	}

	images.os.start = map_to_sysmem(os_hdr);

	return 0;
}

/**
 * bootm_find_images - wrapper to find and locate various images
 * @flag: Ignored Argument
 * @argc: command argument count
 * @argv: command argument list
 * @start: OS image start address
 * @size: OS image size
 *
 * boot_find_images() will attempt to load an available ramdisk,
 * flattened device tree, as well as specifically marked
 * "loadable" images (loadables are FIT only)
 *
 * Note: bootm_find_images will skip an image if it is not found
 *
 * @return:
 *     0, if all existing images were loaded correctly
 *     1, if an image is found but corrupted, or invalid
 */
int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
		      ulong size)
{
	int ret;

	/* find ramdisk */
	ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
			       &images.rd_start, &images.rd_end);
	if (ret) {
		puts("Ramdisk image is corrupt or invalid\n");
		return 1;
	}

	/* check if ramdisk overlaps OS image */
	if (images.rd_start && (((ulong)images.rd_start >= start &&
				 (ulong)images.rd_start < start + size) ||
				((ulong)images.rd_end > start &&
				 (ulong)images.rd_end <= start + size) ||
				((ulong)images.rd_start < start &&
				 (ulong)images.rd_end >= start + size))) {
		printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n",
		       start, start + size);
		return 1;
	}

#if CONFIG_IS_ENABLED(OF_LIBFDT)
	/* find flattened device tree */
	ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
			   &images.ft_addr, &images.ft_len);
	if (ret) {
		puts("Could not find a valid device tree\n");
		return 1;
	}

	/* check if FDT overlaps OS image */
	if (images.ft_addr &&
	    (((ulong)images.ft_addr >= start &&
	      (ulong)images.ft_addr < start + size) ||
	     ((ulong)images.ft_addr + images.ft_len >= start &&
	      (ulong)images.ft_addr + images.ft_len < start + size))) {
		printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n",
		       start, start + size);
		return 1;
	}

	if (IS_ENABLED(CONFIG_CMD_FDT))
		set_working_fdt_addr(map_to_sysmem(images.ft_addr));
#endif

#if CONFIG_IS_ENABLED(FIT)
	if (IS_ENABLED(CONFIG_FPGA)) {
		/* find bitstreams */
		ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
				    NULL, NULL);
		if (ret) {
			printf("FPGA image is corrupted or invalid\n");
			return 1;
		}
	}

	/* find all of the loadables */
	ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
			       NULL, NULL);
	if (ret) {
		printf("Loadable(s) is corrupt or invalid\n");
		return 1;
	}
#endif

	return 0;
}

static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc,
			    char *const argv[])
{
	if (((images.os.type == IH_TYPE_KERNEL) ||
	     (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
	     (images.os.type == IH_TYPE_MULTI)) &&
	    (images.os.os == IH_OS_LINUX ||
		 images.os.os == IH_OS_VXWORKS))
		return bootm_find_images(flag, argc, argv, 0, 0);

	return 0;
}
#endif /* USE_HOSTC */

#if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE)
/**
 * handle_decomp_error() - display a decompression error
 *
 * This function tries to produce a useful message. In the case where the
 * uncompressed size is the same as the available space, we can assume that
 * the image is too large for the buffer.
 *
 * @comp_type:		Compression type being used (IH_COMP_...)
 * @uncomp_size:	Number of bytes uncompressed
 * @buf_size:		Number of bytes the decompresion buffer was
 * @ret:		errno error code received from compression library
 * Return: Appropriate BOOTM_ERR_ error code
 */
static int handle_decomp_error(int comp_type, size_t uncomp_size,
			       size_t buf_size, int ret)
{
	const char *name = genimg_get_comp_name(comp_type);

	/* ENOSYS means unimplemented compression type, don't reset. */
	if (ret == -ENOSYS)
		return BOOTM_ERR_UNIMPLEMENTED;

	if (uncomp_size >= buf_size)
		printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
	else
		printf("%s: uncompress error %d\n", name, ret);

	/*
	 * The decompression routines are now safe, so will not write beyond
	 * their bounds. Probably it is not necessary to reset, but maintain
	 * the current behaviour for now.
	 */
	printf("Must RESET board to recover\n");
#ifndef USE_HOSTCC
	bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
#endif

	return BOOTM_ERR_RESET;
}
#endif

#ifndef USE_HOSTCC
static int bootm_load_os(struct bootm_headers *images, int boot_progress)
{
	struct image_info os = images->os;
	ulong load = os.load;
	ulong load_end;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	ulong flush_start = ALIGN_DOWN(load, ARCH_DMA_MINALIGN);
	bool no_overlap;
	void *load_buf, *image_buf;
	int err;

	load_buf = map_sysmem(load, 0);
	image_buf = map_sysmem(os.image_start, image_len);
	err = image_decomp(os.comp, load, os.image_start, os.type,
			   load_buf, image_buf, image_len,
			   CONFIG_SYS_BOOTM_LEN, &load_end);
	if (err) {
		err = handle_decomp_error(os.comp, load_end - load,
					  CONFIG_SYS_BOOTM_LEN, err);
		bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
		return err;
	}
	/* We need the decompressed image size in the next steps */
	images->os.image_len = load_end - load;

	flush_cache(flush_start, ALIGN(load_end, ARCH_DMA_MINALIGN) - flush_start);

	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end);
	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);

	no_overlap = (os.comp == IH_COMP_NONE && load == image_start);

	if (!no_overlap && load < blob_end && load_end > blob_start) {
		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
		      blob_start, blob_end);
		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
		      load_end);

		/* Check what type of image this is. */
		if (images->legacy_hdr_valid) {
			if (image_get_type(&images->legacy_hdr_os_copy)
					== IH_TYPE_MULTI)
				puts("WARNING: legacy format multi component image overwritten\n");
			return BOOTM_ERR_OVERLAP;
		} else {
			puts("ERROR: new format image overwritten - must RESET the board to recover\n");
			bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
			return BOOTM_ERR_RESET;
		}
	}

	lmb_reserve(&images->lmb, images->os.load, (load_end -
						    images->os.load));
	return 0;
}

/**
 * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
 *
 * Return: interrupt flag (0 if interrupts were disabled, non-zero if they were
 *	enabled)
 */
ulong bootm_disable_interrupts(void)
{
	ulong iflag;

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();
#ifdef CONFIG_NETCONSOLE
	/* Stop the ethernet stack if NetConsole could have left it up */
	eth_halt();
#endif

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif
	return iflag;
}

#define CONSOLE_ARG		"console="
#define NULL_CONSOLE		(CONSOLE_ARG "ttynull")
#define CONSOLE_ARG_SIZE	sizeof(NULL_CONSOLE)

/**
 * fixup_silent_linux() - Handle silencing the linux boot if required
 *
 * This uses the silent_linux envvar to control whether to add/set a "console="
 * parameter to the command line
 *
 * @buf: Buffer containing the string to process
 * @maxlen: Maximum length of buffer
 * Return: 0 if OK, -ENOSPC if @maxlen is too small
 */
static int fixup_silent_linux(char *buf, int maxlen)
{
	int want_silent;
	char *cmdline;
	int size;

	/*
	 * Move the input string to the end of buffer. The output string will be
	 * built up at the start.
	 */
	size = strlen(buf) + 1;
	if (size * 2 > maxlen)
		return -ENOSPC;
	cmdline = buf + maxlen - size;
	memmove(cmdline, buf, size);
	/*
	 * Only fix cmdline when requested. The environment variable can be:
	 *
	 *	no - we never fixup
	 *	yes - we always fixup
	 *	unset - we rely on the console silent flag
	 */
	want_silent = env_get_yesno("silent_linux");
	if (want_silent == 0)
		return 0;
	else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
		return 0;

	debug("before silent fix-up: %s\n", cmdline);
	if (*cmdline) {
		char *start = strstr(cmdline, CONSOLE_ARG);

		/* Check space for maximum possible new command line */
		if (size + CONSOLE_ARG_SIZE > maxlen)
			return -ENOSPC;

		if (start) {
			char *end = strchr(start, ' ');
			int start_bytes;

			start_bytes = start - cmdline;
			strncpy(buf, cmdline, start_bytes);
			strncpy(buf + start_bytes, NULL_CONSOLE, CONSOLE_ARG_SIZE);
			if (end)
				strcpy(buf + start_bytes + CONSOLE_ARG_SIZE - 1, end);
			else
				buf[start_bytes + CONSOLE_ARG_SIZE] = '\0';
		} else {
			sprintf(buf, "%s %s", cmdline, NULL_CONSOLE);
		}
		if (buf + strlen(buf) >= cmdline)
			return -ENOSPC;
	} else {
		if (maxlen < CONSOLE_ARG_SIZE)
			return -ENOSPC;
		strcpy(buf, NULL_CONSOLE);
	}
	debug("after silent fix-up: %s\n", buf);

	return 0;
}

/**
 * process_subst() - Handle substitution of ${...} fields in the environment
 *
 * Handle variable substitution in the provided buffer
 *
 * @buf: Buffer containing the string to process
 * @maxlen: Maximum length of buffer
 * Return: 0 if OK, -ENOSPC if @maxlen is too small
 */
static int process_subst(char *buf, int maxlen)
{
	char *cmdline;
	int size;
	int ret;

	/* Move to end of buffer */
	size = strlen(buf) + 1;
	cmdline = buf + maxlen - size;
	if (buf + size > cmdline)
		return -ENOSPC;
	memmove(cmdline, buf, size);

	ret = cli_simple_process_macros(cmdline, buf, cmdline - buf);

	return ret;
}

int bootm_process_cmdline(char *buf, int maxlen, int flags)
{
	int ret;

	/* Check config first to enable compiler to eliminate code */
	if (IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
	    !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) &&
	    (flags & BOOTM_CL_SILENT)) {
		ret = fixup_silent_linux(buf, maxlen);
		if (ret)
			return log_msg_ret("silent", ret);
	}
	if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && IS_ENABLED(CONFIG_CMDLINE) &&
	    (flags & BOOTM_CL_SUBST)) {
		ret = process_subst(buf, maxlen);
		if (ret)
			return log_msg_ret("subst", ret);
	}

	return 0;
}

int bootm_process_cmdline_env(int flags)
{
	const int maxlen = MAX_CMDLINE_SIZE;
	bool do_silent;
	const char *env;
	char *buf;
	int ret;

	/* First check if any action is needed */
	do_silent = IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
	    !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) && (flags & BOOTM_CL_SILENT);
	if (!do_silent && !IS_ENABLED(CONFIG_BOOTARGS_SUBST))
		return 0;

	env = env_get("bootargs");
	if (env && strlen(env) >= maxlen)
		return -E2BIG;
	buf = malloc(maxlen);
	if (!buf)
		return -ENOMEM;
	if (env)
		strcpy(buf, env);
	else
		*buf = '\0';
	ret = bootm_process_cmdline(buf, maxlen, flags);
	if (!ret) {
		ret = env_set("bootargs", buf);

		/*
		 * If buf is "" and bootargs does not exist, this will produce
		 * an error trying to delete bootargs. Ignore it
		 */
		if (ret == -ENOENT)
			ret = 0;
	}
	free(buf);
	if (ret)
		return log_msg_ret("env", ret);

	return 0;
}

/**
 * Execute selected states of the bootm command.
 *
 * Note the arguments to this state must be the first argument, Any 'bootm'
 * or sub-command arguments must have already been taken.
 *
 * Note that if states contains more than one flag it MUST contain
 * BOOTM_STATE_START, since this handles and consumes the command line args.
 *
 * Also note that aside from boot_os_fn functions and bootm_load_os no other
 * functions we store the return value of in 'ret' may use a negative return
 * value, without special handling.
 *
 * @param cmdtp		Pointer to bootm command table entry
 * @param flag		Command flags (CMD_FLAG_...)
 * @param argc		Number of subcommand arguments (0 = no arguments)
 * @param argv		Arguments
 * @param states	Mask containing states to run (BOOTM_STATE_...)
 * @param images	Image header information
 * @param boot_progress 1 to show boot progress, 0 to not do this
 * Return: 0 if ok, something else on error. Some errors will cause this
 *	function to perform a reboot! If states contains BOOTM_STATE_OS_GO
 *	then the intent is to boot an OS, so this function will not return
 *	unless the image type is standalone.
 */
int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
		    char *const argv[], int states, struct bootm_headers *images,
		    int boot_progress)
{
	boot_os_fn *boot_fn;
	ulong iflag = 0;
	int ret = 0, need_boot_fn;

	images->state |= states;

	/*
	 * Work through the states and see how far we get. We stop on
	 * any error.
	 */
	if (states & BOOTM_STATE_START)
		ret = bootm_start(cmdtp, flag, argc, argv);

	if (!ret && (states & BOOTM_STATE_PRE_LOAD))
		ret = bootm_pre_load(cmdtp, flag, argc, argv);

	if (!ret && (states & BOOTM_STATE_FINDOS))
		ret = bootm_find_os(cmdtp, flag, argc, argv);

	if (!ret && (states & BOOTM_STATE_FINDOTHER))
		ret = bootm_find_other(cmdtp, flag, argc, argv);

	/* Load the OS */
	if (!ret && (states & BOOTM_STATE_LOADOS)) {
		iflag = bootm_disable_interrupts();
		ret = bootm_load_os(images, 0);
		if (ret && ret != BOOTM_ERR_OVERLAP)
			goto err;
		else if (ret == BOOTM_ERR_OVERLAP)
			ret = 0;
	}

	/* Relocate the ramdisk */
#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
	if (!ret && (states & BOOTM_STATE_RAMDISK)) {
		ulong rd_len = images->rd_end - images->rd_start;

		ret = boot_ramdisk_high(&images->lmb, images->rd_start,
			rd_len, &images->initrd_start, &images->initrd_end);
		if (!ret) {
			env_set_hex("initrd_start", images->initrd_start);
			env_set_hex("initrd_end", images->initrd_end);
		}
	}
#endif
#if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB)
	if (!ret && (states & BOOTM_STATE_FDT)) {
		boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
		ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
					&images->ft_len);
	}
#endif

	/* From now on, we need the OS boot function */
	if (ret)
		return ret;
	boot_fn = bootm_os_get_boot_func(images->os.os);
	need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
			BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
			BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
	if (boot_fn == NULL && need_boot_fn) {
		if (iflag)
			enable_interrupts();
		printf("ERROR: booting os '%s' (%d) is not supported\n",
		       genimg_get_os_name(images->os.os), images->os.os);
		bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
		return 1;
	}


	/* Call various other states that are not generally used */
	if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
		ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
	if (!ret && (states & BOOTM_STATE_OS_BD_T))
		ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
	if (!ret && (states & BOOTM_STATE_OS_PREP)) {
		ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX);
		if (ret) {
			printf("Cmdline setup failed (err=%d)\n", ret);
			ret = CMD_RET_FAILURE;
			goto err;
		}
		ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
	}

#ifdef CONFIG_TRACE
	/* Pretend to run the OS, then run a user command */
	if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
		char *cmd_list = env_get("fakegocmd");

		ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
				images, boot_fn);
		if (!ret && cmd_list)
			ret = run_command_list(cmd_list, -1, flag);
	}
#endif

	/* Check for unsupported subcommand. */
	if (ret) {
		printf("subcommand failed (err=%d)\n", ret);
		return ret;
	}

	/* Now run the OS! We hope this doesn't return */
	if (!ret && (states & BOOTM_STATE_OS_GO))
		ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
				images, boot_fn);

	/* Deal with any fallout */
err:
	if (iflag)
		enable_interrupts();

	if (ret == BOOTM_ERR_UNIMPLEMENTED)
		bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
	else if (ret == BOOTM_ERR_RESET)
		do_reset(cmdtp, flag, argc, argv);

	return ret;
}

#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
/**
 * image_get_kernel - verify legacy format kernel image
 * @img_addr: in RAM address of the legacy format image to be verified
 * @verify: data CRC verification flag
 *
 * image_get_kernel() verifies legacy image integrity and returns pointer to
 * legacy image header if image verification was completed successfully.
 *
 * returns:
 *     pointer to a legacy image header if valid image was found
 *     otherwise return NULL
 */
static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify)
{
	struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)img_addr;

	if (!image_check_magic(hdr)) {
		puts("Bad Magic Number\n");
		bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
		return NULL;
	}
	bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);

	if (!image_check_hcrc(hdr)) {
		puts("Bad Header Checksum\n");
		bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
		return NULL;
	}

	bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
	image_print_contents(hdr);

	if (verify) {
		puts("   Verifying Checksum ... ");
		if (!image_check_dcrc(hdr)) {
			printf("Bad Data CRC\n");
			bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
			return NULL;
		}
		puts("OK\n");
	}
	bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);

	if (!image_check_target_arch(hdr)) {
		printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
		bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
		return NULL;
	}
	return hdr;
}
#endif

/**
 * boot_get_kernel - find kernel image
 * @os_data: pointer to a ulong variable, will hold os data start address
 * @os_len: pointer to a ulong variable, will hold os data length
 *
 * boot_get_kernel() tries to find a kernel image, verifies its integrity
 * and locates kernel data.
 *
 * returns:
 *     pointer to image header if valid image was found, plus kernel start
 *     address and length, otherwise NULL
 */
static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
				   char *const argv[], struct bootm_headers *images,
				   ulong *os_data, ulong *os_len)
{
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
	struct legacy_img_hdr	*hdr;
#endif
	ulong		img_addr;
	const void *buf;
	const char	*fit_uname_config = NULL;
	const char	*fit_uname_kernel = NULL;
#if CONFIG_IS_ENABLED(FIT)
	int		os_noffset;
#endif

#ifdef CONFIG_ANDROID_BOOT_IMAGE
	const void *boot_img;
	const void *vendor_boot_img;
#endif
	img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
					      &fit_uname_config,
					      &fit_uname_kernel);

	if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD))
		img_addr += image_load_offset;

	bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);

	/* check image type, for FIT images get FIT kernel node */
	*os_data = *os_len = 0;
	buf = map_sysmem(img_addr, 0);
	switch (genimg_get_format(buf)) {
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
	case IMAGE_FORMAT_LEGACY:
		printf("## Booting kernel from Legacy Image at %08lx ...\n",
		       img_addr);
		hdr = image_get_kernel(img_addr, images->verify);
		if (!hdr)
			return NULL;
		bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);

		/* get os_data and os_len */
		switch (image_get_type(hdr)) {
		case IH_TYPE_KERNEL:
		case IH_TYPE_KERNEL_NOLOAD:
			*os_data = image_get_data(hdr);
			*os_len = image_get_data_size(hdr);
			break;
		case IH_TYPE_MULTI:
			image_multi_getimg(hdr, 0, os_data, os_len);
			break;
		case IH_TYPE_STANDALONE:
			*os_data = image_get_data(hdr);
			*os_len = image_get_data_size(hdr);
			break;
		default:
			printf("Wrong Image Type for %s command\n",
			       cmdtp->name);
			bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
			return NULL;
		}

		/*
		 * copy image header to allow for image overwrites during
		 * kernel decompression.
		 */
		memmove(&images->legacy_hdr_os_copy, hdr,
			sizeof(struct legacy_img_hdr));

		/* save pointer to image header */
		images->legacy_hdr_os = hdr;

		images->legacy_hdr_valid = 1;
		bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
		break;
#endif
#if CONFIG_IS_ENABLED(FIT)
	case IMAGE_FORMAT_FIT:
		os_noffset = fit_image_load(images, img_addr,
				&fit_uname_kernel, &fit_uname_config,
				IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
				BOOTSTAGE_ID_FIT_KERNEL_START,
				FIT_LOAD_IGNORED, os_data, os_len);
		if (os_noffset < 0)
			return NULL;

		images->fit_hdr_os = map_sysmem(img_addr, 0);
		images->fit_uname_os = fit_uname_kernel;
		images->fit_uname_cfg = fit_uname_config;
		images->fit_noffset_os = os_noffset;
		break;
#endif
#ifdef CONFIG_ANDROID_BOOT_IMAGE
	case IMAGE_FORMAT_ANDROID:
		boot_img = buf;
		vendor_boot_img = NULL;
		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
			boot_img = map_sysmem(get_abootimg_addr(), 0);
			vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0);
		}
		printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
		if (android_image_get_kernel(boot_img, vendor_boot_img, images->verify,
					     os_data, os_len))
			return NULL;
		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
			unmap_sysmem(vendor_boot_img);
			unmap_sysmem(boot_img);
		}
		break;
#endif
	default:
		printf("Wrong Image Format for %s command\n", cmdtp->name);
		bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
		return NULL;
	}

	debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
	      *os_data, *os_len, *os_len);

	return buf;
}

/**
 * switch_to_non_secure_mode() - switch to non-secure mode
 *
 * This routine is overridden by architectures requiring this feature.
 */
void __weak switch_to_non_secure_mode(void)
{
}

#else /* USE_HOSTCC */

#if defined(CONFIG_FIT_SIGNATURE)
static int bootm_host_load_image(const void *fit, int req_image_type,
				 int cfg_noffset)
{
	const char *fit_uname_config = NULL;
	ulong data, len;
	struct bootm_headers images;
	int noffset;
	ulong load_end, buf_size;
	uint8_t image_type;
	uint8_t image_comp;
	void *load_buf;
	int ret;

	fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
	memset(&images, '\0', sizeof(images));
	images.verify = 1;
	noffset = fit_image_load(&images, (ulong)fit,
		NULL, &fit_uname_config,
		IH_ARCH_DEFAULT, req_image_type, -1,
		FIT_LOAD_IGNORED, &data, &len);
	if (noffset < 0)
		return noffset;
	if (fit_image_get_type(fit, noffset, &image_type)) {
		puts("Can't get image type!\n");
		return -EINVAL;
	}

	if (fit_image_get_comp(fit, noffset, &image_comp))
		image_comp = IH_COMP_NONE;

	/* Allow the image to expand by a factor of 4, should be safe */
	buf_size = (1 << 20) + len * 4;
	load_buf = malloc(buf_size);
	ret = image_decomp(image_comp, 0, data, image_type, load_buf,
			   (void *)data, len, buf_size, &load_end);
	free(load_buf);

	if (ret) {
		ret = handle_decomp_error(image_comp, load_end - 0, buf_size, ret);
		if (ret != BOOTM_ERR_UNIMPLEMENTED)
			return ret;
	}

	return 0;
}

int bootm_host_load_images(const void *fit, int cfg_noffset)
{
	static uint8_t image_types[] = {
		IH_TYPE_KERNEL,
		IH_TYPE_FLATDT,
		IH_TYPE_RAMDISK,
	};
	int err = 0;
	int i;

	for (i = 0; i < ARRAY_SIZE(image_types); i++) {
		int ret;

		ret = bootm_host_load_image(fit, image_types[i], cfg_noffset);
		if (!err && ret && ret != -ENOENT)
			err = ret;
	}

	/* Return the first error we found */
	return err;
}
#endif

#endif /* ndef USE_HOSTCC */
