cmd_spl.c 4.28 KB
Newer Older
Simon Schwarz's avatar
Simon Schwarz committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
/*
 * Copyright (C) 2011
 * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#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) {
		case SPL_EXPORT_FDT:
			printf("Argument image is now in RAM: 0x%p\n",
				(void *)images.ft_addr);
			break;
		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 if <img> = fdt] - export a kernel parameter image\n"
	"\t initrd_img can be set to \"-\" if fdt_addr without initrd img is"
	"used");