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