Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[platform/kernel/u-boot.git] / common / cmd_spl.c
1 /*
2  * Copyright (C) 2011
3  * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <command.h>
26 #include <cmd_spl.h>
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 static const char **subcmd_list[] = {
31
32         [SPL_EXPORT_FDT] = (const char * []) {
33 #ifdef CONFIG_OF_LIBFDT
34                 "start",
35                 "loados",
36         #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
37                 "ramdisk",
38         #endif
39                 "fdt",
40                 "cmdline",
41                 "bdt",
42                 "prep",
43 #endif
44                 NULL,
45         },
46         [SPL_EXPORT_ATAGS] = (const char * []) {
47 #if defined(CONFIG_SETUP_MEMORY_TAGS) || \
48         defined(CONFIG_CMDLINE_TAG) || \
49         defined(CONFIG_INITRD_TAG) || \
50         defined(CONFIG_SERIAL_TAG) || \
51         defined(CONFIG_REVISION_TAG)
52                 "start",
53                 "loados",
54 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
55                 "ramdisk",
56 #endif
57                 "cmdline",
58                 "bdt",
59                 "prep",
60 #endif
61                 NULL,
62         },
63         NULL
64 };
65
66 /* Calls bootm with the parameters given */
67 static int call_bootm(int argc, char * const argv[], const char *subcommand[])
68 {
69         char *bootm_argv[5];
70
71         int i = 0;
72         int ret = 0;
73         int j;
74
75         /* create paramter array */
76         bootm_argv[0] = "do_bootm";
77         switch (argc) {
78         case 3:
79                 bootm_argv[4] = argv[2]; /* fdt addr */
80         case 2:
81                 bootm_argv[3] = argv[1]; /* initrd addr */
82         case 1:
83                 bootm_argv[2] = argv[0]; /* kernel addr */
84         }
85
86
87         /*
88          * - do the work -
89          * exec subcommands of do_bootm to init the images
90          * data structure
91          */
92         while (subcommand[i] != NULL) {
93                 bootm_argv[1] = (char *)subcommand[i];
94                 debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]);
95                 for (j = 0; j < argc; j++)
96                         debug("%s ", bootm_argv[j + 2]);
97                 debug("\n");
98
99                 ret = do_bootm(find_cmd("do_bootm"), 0, argc+2,
100                         bootm_argv);
101                 debug("Subcommand retcode: %d\n", ret);
102                 i++;
103         }
104
105         if (ret) {
106                 printf("ERROR prep subcommand failed!\n");
107                 return -1;
108         }
109
110         return 0;
111 }
112
113 static cmd_tbl_t cmd_spl_export_sub[] = {
114         U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""),
115         U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""),
116 };
117
118 static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
119 {
120         const cmd_tbl_t *c;
121
122         if (argc < 2) /* no subcommand */
123                 return cmd_usage(cmdtp);
124
125         c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0],
126                 ARRAY_SIZE(cmd_spl_export_sub));
127         if ((c) && ((int)c->cmd <= SPL_EXPORT_LAST)) {
128                 argc -= 2;
129                 argv += 2;
130                 if (call_bootm(argc, argv, subcmd_list[(int)c->cmd]))
131                         return -1;
132                 switch ((int)c->cmd) {
133 #ifdef CONFIG_OF_LIBFDT
134                 case SPL_EXPORT_FDT:
135                         printf("Argument image is now in RAM: 0x%p\n",
136                                 (void *)images.ft_addr);
137                         break;
138 #endif
139                 case SPL_EXPORT_ATAGS:
140                         printf("Argument image is now in RAM at: 0x%p\n",
141                                 (void *)gd->bd->bi_boot_params);
142                         break;
143                 }
144         } else {
145                 /* Unrecognized command */
146                 return cmd_usage(cmdtp);
147         }
148
149         return 0;
150 }
151
152 static cmd_tbl_t cmd_spl_sub[] = {
153         U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""),
154 };
155
156 static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
157 {
158         const cmd_tbl_t *c;
159         int cmd;
160
161         if (argc < 2) /* no subcommand */
162                 return cmd_usage(cmdtp);
163
164         c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub));
165         if (c) {
166                 cmd = (int)c->cmd;
167                 switch (cmd) {
168                 case SPL_EXPORT:
169                         argc--;
170                         argv++;
171                         if (spl_export(cmdtp, flag, argc, argv))
172                                 printf("Subcommand failed\n");
173                         break;
174                 default:
175                         /* unrecognized command */
176                         return cmd_usage(cmdtp);
177                 }
178         } else {
179                 /* Unrecognized command */
180                 return cmd_usage(cmdtp);
181         }
182         return 0;
183 }
184
185 U_BOOT_CMD(
186         spl, 6 , 1, do_spl, "SPL configuration",
187         "export <img=atags|fdt> [kernel_addr] [initrd_addr] [fdt_addr]\n"
188         "\timg\t\t\"atags\" or \"fdt\"\n"
189         "\tkernel_addr\taddress where a kernel image is stored.\n"
190         "\t\t\tkernel is loaded as part of the boot process, but it is not started.\n"
191         "\tinitrd_addr\taddress of initial ramdisk\n"
192         "\t\t\tcan be set to \"-\" if fdt_addr without initrd_addr is used.\n"
193         "\tfdt_addr\tin case of fdt, the address of the device tree.\n"
194         );