12e192b24SSimon Glass /* 22e192b24SSimon Glass * Copyright (C) 2011 32e192b24SSimon Glass * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> 42e192b24SSimon Glass * 52e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 62e192b24SSimon Glass */ 72e192b24SSimon Glass 82e192b24SSimon Glass #include <common.h> 92e192b24SSimon Glass #include <command.h> 102e192b24SSimon Glass #include <cmd_spl.h> 112e192b24SSimon Glass 122e192b24SSimon Glass DECLARE_GLOBAL_DATA_PTR; 132e192b24SSimon Glass 142e192b24SSimon Glass static const char **subcmd_list[] = { 152e192b24SSimon Glass 162e192b24SSimon Glass [SPL_EXPORT_FDT] = (const char * []) { 172e192b24SSimon Glass #ifdef CONFIG_OF_LIBFDT 182e192b24SSimon Glass "start", 192e192b24SSimon Glass "loados", 202e192b24SSimon Glass #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 212e192b24SSimon Glass "ramdisk", 222e192b24SSimon Glass #endif 232e192b24SSimon Glass "fdt", 242e192b24SSimon Glass "cmdline", 252e192b24SSimon Glass "bdt", 262e192b24SSimon Glass "prep", 272e192b24SSimon Glass #endif 282e192b24SSimon Glass NULL, 292e192b24SSimon Glass }, 302e192b24SSimon Glass [SPL_EXPORT_ATAGS] = (const char * []) { 312e192b24SSimon Glass #if defined(CONFIG_SETUP_MEMORY_TAGS) || \ 322e192b24SSimon Glass defined(CONFIG_CMDLINE_TAG) || \ 332e192b24SSimon Glass defined(CONFIG_INITRD_TAG) || \ 342e192b24SSimon Glass defined(CONFIG_SERIAL_TAG) || \ 352e192b24SSimon Glass defined(CONFIG_REVISION_TAG) 362e192b24SSimon Glass "start", 372e192b24SSimon Glass "loados", 382e192b24SSimon Glass #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 392e192b24SSimon Glass "ramdisk", 402e192b24SSimon Glass #endif 412e192b24SSimon Glass "cmdline", 422e192b24SSimon Glass "bdt", 432e192b24SSimon Glass "prep", 442e192b24SSimon Glass #endif 452e192b24SSimon Glass NULL, 462e192b24SSimon Glass }, 472e192b24SSimon Glass NULL 482e192b24SSimon Glass }; 492e192b24SSimon Glass 502e192b24SSimon Glass /* Calls bootm with the parameters given */ 512e192b24SSimon Glass static int call_bootm(int argc, char * const argv[], const char *subcommand[]) 522e192b24SSimon Glass { 532e192b24SSimon Glass char *bootm_argv[5]; 542e192b24SSimon Glass 552e192b24SSimon Glass int i = 0; 562e192b24SSimon Glass int ret = 0; 572e192b24SSimon Glass int j; 582e192b24SSimon Glass 592e192b24SSimon Glass /* create paramter array */ 602e192b24SSimon Glass bootm_argv[0] = "do_bootm"; 612e192b24SSimon Glass switch (argc) { 622e192b24SSimon Glass case 3: 632e192b24SSimon Glass bootm_argv[4] = argv[2]; /* fdt addr */ 642e192b24SSimon Glass case 2: 652e192b24SSimon Glass bootm_argv[3] = argv[1]; /* initrd addr */ 662e192b24SSimon Glass case 1: 672e192b24SSimon Glass bootm_argv[2] = argv[0]; /* kernel addr */ 682e192b24SSimon Glass } 692e192b24SSimon Glass 702e192b24SSimon Glass 712e192b24SSimon Glass /* 722e192b24SSimon Glass * - do the work - 732e192b24SSimon Glass * exec subcommands of do_bootm to init the images 742e192b24SSimon Glass * data structure 752e192b24SSimon Glass */ 762e192b24SSimon Glass while (subcommand[i] != NULL) { 772e192b24SSimon Glass bootm_argv[1] = (char *)subcommand[i]; 782e192b24SSimon Glass debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]); 792e192b24SSimon Glass for (j = 0; j < argc; j++) 802e192b24SSimon Glass debug("%s ", bootm_argv[j + 2]); 812e192b24SSimon Glass debug("\n"); 822e192b24SSimon Glass 832e192b24SSimon Glass ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, 842e192b24SSimon Glass bootm_argv); 852e192b24SSimon Glass debug("Subcommand retcode: %d\n", ret); 862e192b24SSimon Glass i++; 872e192b24SSimon Glass } 882e192b24SSimon Glass 892e192b24SSimon Glass if (ret) { 902e192b24SSimon Glass printf("ERROR prep subcommand failed!\n"); 912e192b24SSimon Glass return -1; 922e192b24SSimon Glass } 932e192b24SSimon Glass 942e192b24SSimon Glass return 0; 952e192b24SSimon Glass } 962e192b24SSimon Glass 972e192b24SSimon Glass static cmd_tbl_t cmd_spl_export_sub[] = { 982e192b24SSimon Glass U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), 992e192b24SSimon Glass U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), 1002e192b24SSimon Glass }; 1012e192b24SSimon Glass 1022e192b24SSimon Glass static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1032e192b24SSimon Glass { 1042e192b24SSimon Glass const cmd_tbl_t *c; 1052e192b24SSimon Glass 1062e192b24SSimon Glass if (argc < 2) /* no subcommand */ 1072e192b24SSimon Glass return cmd_usage(cmdtp); 1082e192b24SSimon Glass 1092e192b24SSimon Glass c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], 1102e192b24SSimon Glass ARRAY_SIZE(cmd_spl_export_sub)); 1112e192b24SSimon Glass if ((c) && ((int)c->cmd <= SPL_EXPORT_LAST)) { 1122e192b24SSimon Glass argc -= 2; 1132e192b24SSimon Glass argv += 2; 1142e192b24SSimon Glass if (call_bootm(argc, argv, subcmd_list[(int)c->cmd])) 1152e192b24SSimon Glass return -1; 1162e192b24SSimon Glass switch ((int)c->cmd) { 1172e192b24SSimon Glass #ifdef CONFIG_OF_LIBFDT 1182e192b24SSimon Glass case SPL_EXPORT_FDT: 1192e192b24SSimon Glass printf("Argument image is now in RAM: 0x%p\n", 1202e192b24SSimon Glass (void *)images.ft_addr); 121*767cb74aSAnatolij Gustschin env_set_addr("fdtargsaddr", images.ft_addr); 122*767cb74aSAnatolij Gustschin env_set_hex("fdtargslen", fdt_totalsize(images.ft_addr)); 123*767cb74aSAnatolij Gustschin if (fdt_totalsize(images.ft_addr) > 124*767cb74aSAnatolij Gustschin CONFIG_CMD_SPL_WRITE_SIZE) 125*767cb74aSAnatolij Gustschin puts("WARN: FDT size > CMD_SPL_WRITE_SIZE\n"); 1262e192b24SSimon Glass break; 1272e192b24SSimon Glass #endif 1282e192b24SSimon Glass case SPL_EXPORT_ATAGS: 1292e192b24SSimon Glass printf("Argument image is now in RAM at: 0x%p\n", 1302e192b24SSimon Glass (void *)gd->bd->bi_boot_params); 1312e192b24SSimon Glass break; 1322e192b24SSimon Glass } 1332e192b24SSimon Glass } else { 1342e192b24SSimon Glass /* Unrecognized command */ 1352e192b24SSimon Glass return cmd_usage(cmdtp); 1362e192b24SSimon Glass } 1372e192b24SSimon Glass 1382e192b24SSimon Glass return 0; 1392e192b24SSimon Glass } 1402e192b24SSimon Glass 1412e192b24SSimon Glass static cmd_tbl_t cmd_spl_sub[] = { 1422e192b24SSimon Glass U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), 1432e192b24SSimon Glass }; 1442e192b24SSimon Glass 1452e192b24SSimon Glass static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1462e192b24SSimon Glass { 1472e192b24SSimon Glass const cmd_tbl_t *c; 1482e192b24SSimon Glass int cmd; 1492e192b24SSimon Glass 1502e192b24SSimon Glass if (argc < 2) /* no subcommand */ 1512e192b24SSimon Glass return cmd_usage(cmdtp); 1522e192b24SSimon Glass 1532e192b24SSimon Glass c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); 1542e192b24SSimon Glass if (c) { 1552e192b24SSimon Glass cmd = (int)c->cmd; 1562e192b24SSimon Glass switch (cmd) { 1572e192b24SSimon Glass case SPL_EXPORT: 1582e192b24SSimon Glass argc--; 1592e192b24SSimon Glass argv++; 1602e192b24SSimon Glass if (spl_export(cmdtp, flag, argc, argv)) 1612e192b24SSimon Glass printf("Subcommand failed\n"); 1622e192b24SSimon Glass break; 1632e192b24SSimon Glass default: 1642e192b24SSimon Glass /* unrecognized command */ 1652e192b24SSimon Glass return cmd_usage(cmdtp); 1662e192b24SSimon Glass } 1672e192b24SSimon Glass } else { 1682e192b24SSimon Glass /* Unrecognized command */ 1692e192b24SSimon Glass return cmd_usage(cmdtp); 1702e192b24SSimon Glass } 1712e192b24SSimon Glass return 0; 1722e192b24SSimon Glass } 1732e192b24SSimon Glass 1742e192b24SSimon Glass U_BOOT_CMD( 1752e192b24SSimon Glass spl, 6 , 1, do_spl, "SPL configuration", 1762e192b24SSimon Glass "export <img=atags|fdt> [kernel_addr] [initrd_addr] [fdt_addr]\n" 1772e192b24SSimon Glass "\timg\t\t\"atags\" or \"fdt\"\n" 1782e192b24SSimon Glass "\tkernel_addr\taddress where a kernel image is stored.\n" 1792e192b24SSimon Glass "\t\t\tkernel is loaded as part of the boot process, but it is not started.\n" 1802e192b24SSimon Glass "\tinitrd_addr\taddress of initial ramdisk\n" 1812e192b24SSimon Glass "\t\t\tcan be set to \"-\" if fdt_addr without initrd_addr is used.\n" 1822e192b24SSimon Glass "\tfdt_addr\tin case of fdt, the address of the device tree.\n" 1832e192b24SSimon Glass ); 184