| /* | 
 |  * 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" | 
 | 	); |