/*
 * Copyright (C) 2011
 * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <cmd_spl.h>

DECLARE_GLOBAL_DATA_PTR;

static const char **subcmd_list[] = {

	[SPL_EXPORT_FDT] = (const char * []) {
#ifdef CONFIG_OF_LIBFDT
		"start",
		"loados",
	#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
		"ramdisk",
	#endif
		"fdt",
		"cmdline",
		"bdt",
		"prep",
#endif
		NULL,
	},
	[SPL_EXPORT_ATAGS] = (const char * []) {
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
	defined(CONFIG_CMDLINE_TAG) || \
	defined(CONFIG_INITRD_TAG) || \
	defined(CONFIG_SERIAL_TAG) || \
	defined(CONFIG_REVISION_TAG)
		"start",
		"loados",
#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
		"ramdisk",
#endif
		"cmdline",
		"bdt",
		"prep",
#endif
		NULL,
	},
	NULL
};

/* Calls bootm with the parameters given */
static int call_bootm(int argc, char * const argv[], const char *subcommand[])
{
	char *bootm_argv[5];

	int i = 0;
	int ret = 0;
	int j;

	/* create paramter array */
	bootm_argv[0] = "do_bootm";
	switch (argc) {
	case 3:
		bootm_argv[4] = argv[2]; /* fdt addr */
	case 2:
		bootm_argv[3] = argv[1]; /* initrd addr */
	case 1:
		bootm_argv[2] = argv[0]; /* kernel addr */
	}


	/*
	 * - do the work -
	 * exec subcommands of do_bootm to init the images
	 * data structure
	 */
	while (subcommand[i] != NULL) {
		bootm_argv[1] = (char *)subcommand[i];
		debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]);
		for (j = 0; j < argc; j++)
			debug("%s ", bootm_argv[j + 2]);
		debug("\n");

		ret = do_bootm(find_cmd("do_bootm"), 0, argc+2,
			bootm_argv);
		debug("Subcommand retcode: %d\n", ret);
		i++;
	}

	if (ret) {
		printf("ERROR prep subcommand failed!\n");
		return -1;
	}

	return 0;
}

static cmd_tbl_t cmd_spl_export_sub[] = {
	U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""),
	U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""),
};

static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	const cmd_tbl_t *c;

	if (argc < 2) /* no subcommand */
		return cmd_usage(cmdtp);

	c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0],
		ARRAY_SIZE(cmd_spl_export_sub));
	if ((c) && ((long)c->cmd <= SPL_EXPORT_LAST)) {
		argc -= 2;
		argv += 2;
		if (call_bootm(argc, argv, subcmd_list[(long)c->cmd]))
			return -1;
		switch ((long)c->cmd) {
#ifdef CONFIG_OF_LIBFDT
		case SPL_EXPORT_FDT:
			printf("Argument image is now in RAM: 0x%p\n",
				(void *)images.ft_addr);
			break;
#endif
		case SPL_EXPORT_ATAGS:
			printf("Argument image is now in RAM at: 0x%p\n",
				(void *)gd->bd->bi_boot_params);
			break;
		}
	} else {
		/* Unrecognized command */
		return cmd_usage(cmdtp);
	}

	return 0;
}

static cmd_tbl_t cmd_spl_sub[] = {
	U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""),
};

static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	const cmd_tbl_t *c;
	int cmd;

	if (argc < 2) /* no subcommand */
		return cmd_usage(cmdtp);

	c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub));
	if (c) {
		cmd = (long)c->cmd;
		switch (cmd) {
		case SPL_EXPORT:
			argc--;
			argv++;
			if (spl_export(cmdtp, flag, argc, argv))
				printf("Subcommand failed\n");
			break;
		default:
			/* unrecognized command */
			return cmd_usage(cmdtp);
		}
	} else {
		/* Unrecognized command */
		return cmd_usage(cmdtp);
	}
	return 0;
}

U_BOOT_CMD(
	spl, 6 , 1, do_spl, "SPL configuration",
	"export <img=atags|fdt> [kernel_addr] [initrd_addr] [fdt_addr]\n"
	"\timg\t\t\"atags\" or \"fdt\"\n"
	"\tkernel_addr\taddress where a kernel image is stored.\n"
	"\t\t\tkernel is loaded as part of the boot process, but it is not started.\n"
	"\tinitrd_addr\taddress of initial ramdisk\n"
	"\t\t\tcan be set to \"-\" if fdt_addr without initrd_addr is used.\n"
	"\tfdt_addr\tin case of fdt, the address of the device tree.\n"
	);
