/*
 * 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) && ((int)c->cmd <= SPL_EXPORT_LAST)) {
		argc -= 2;
		argv += 2;
		if (call_bootm(argc, argv, subcmd_list[(int)c->cmd]))
			return -1;
		switch ((int)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 = (int)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"
	);
