11539Srgrimes// SPDX-License-Identifier: GPL-2.0+ 21539Srgrimes/* 31539Srgrimes * Copyright (C) 2011 41539Srgrimes * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> 51539Srgrimes */ 61539Srgrimes 71539Srgrimes#include <common.h> 81539Srgrimes#include <command.h> 91539Srgrimes#include <cmd_spl.h> 101539Srgrimes#include <env.h> 111539Srgrimes#include <image.h> 121539Srgrimes#include <log.h> 131539Srgrimes#include <asm/global_data.h> 141539Srgrimes#include <linux/libfdt.h> 151539Srgrimes 161539SrgrimesDECLARE_GLOBAL_DATA_PTR; 171539Srgrimes 181539Srgrimesstatic const char **subcmd_list[] = { 191539Srgrimes 201539Srgrimes [SPL_EXPORT_FDT] = (const char * []) { 211539Srgrimes#ifdef CONFIG_OF_LIBFDT 221539Srgrimes "start", 231539Srgrimes "loados", 241539Srgrimes #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 251539Srgrimes "ramdisk", 261539Srgrimes #endif 271539Srgrimes "fdt", 281539Srgrimes "cmdline", 291539Srgrimes "bdt", 301539Srgrimes "prep", 311539Srgrimes#endif 321539Srgrimes NULL, 3323657Speter }, 341539Srgrimes [SPL_EXPORT_ATAGS] = (const char * []) { 351539Srgrimes#ifdef CONFIG_SUPPORT_PASSING_ATAGS 361539Srgrimes "start", 377865Sbde "loados", 381539Srgrimes#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 3933861Sbde "ramdisk", 4033861Sbde#endif 411539Srgrimes "cmdline", 4226636Sache "bdt", 4326636Sache "prep", 4426630Sache#endif 451539Srgrimes NULL, 4615483Sbde }, 4715483Sbde NULL 4815483Sbde}; 4915483Sbde 5015483Sbde/* Calls bootm with the parameters given */ 5115483Sbdestatic int call_bootm(int argc, char *const argv[], const char *subcommand[]) 521539Srgrimes{ 531539Srgrimes char *bootm_argv[5]; 541539Srgrimes 551539Srgrimes int i = 0; 561539Srgrimes int ret = 0; 571539Srgrimes int j; 581539Srgrimes 591539Srgrimes /* create paramter array */ 601539Srgrimes bootm_argv[0] = "do_bootm"; 611539Srgrimes switch (argc) { 621539Srgrimes case 3: 631539Srgrimes bootm_argv[4] = argv[2]; /* fdt addr */ 641539Srgrimes case 2: 651539Srgrimes bootm_argv[3] = argv[1]; /* initrd addr */ 661539Srgrimes case 1: 671539Srgrimes bootm_argv[2] = argv[0]; /* kernel addr */ 681539Srgrimes } 691539Srgrimes 701539Srgrimes 711539Srgrimes /* 721539Srgrimes * - do the work - 731539Srgrimes * exec subcommands of do_bootm to init the images 741539Srgrimes * data structure 751539Srgrimes */ 761539Srgrimes while (subcommand[i] != NULL) { 771539Srgrimes bootm_argv[1] = (char *)subcommand[i]; 781539Srgrimes debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]); 791539Srgrimes for (j = 0; j < argc; j++) 801539Srgrimes debug("%s ", bootm_argv[j + 2]); 811539Srgrimes debug("\n"); 821539Srgrimes 831539Srgrimes ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, 841539Srgrimes bootm_argv); 8518286Sbde debug("Subcommand retcode: %d\n", ret); 8618286Sbde i++; 871539Srgrimes } 881539Srgrimes 891539Srgrimes if (ret) { 901539Srgrimes printf("ERROR prep subcommand failed!\n"); 911539Srgrimes return -1; 921539Srgrimes } 931539Srgrimes 9418286Sbde return 0; 9518286Sbde} 961539Srgrimes 971539Srgrimesstatic struct cmd_tbl cmd_spl_export_sub[] = { 9818286Sbde U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), 9918286Sbde U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), 1001539Srgrimes}; 1011539Srgrimes 1021539Srgrimesstatic int spl_export(struct cmd_tbl *cmdtp, int flag, int argc, 1031539Srgrimes char *const argv[]) 1041539Srgrimes{ 1051539Srgrimes const struct cmd_tbl *c; 1061539Srgrimes 1071539Srgrimes if (argc < 2) /* no subcommand */ 1081539Srgrimes return cmd_usage(cmdtp); 1091539Srgrimes 1101539Srgrimes c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], 1111539Srgrimes ARRAY_SIZE(cmd_spl_export_sub)); 1121539Srgrimes if ((c) && ((long)c->cmd <= SPL_EXPORT_LAST)) { 1131539Srgrimes argc -= 2; 1141539Srgrimes argv += 2; 1151539Srgrimes if (call_bootm(argc, argv, subcmd_list[(long)c->cmd])) 1161539Srgrimes return -1; 1171539Srgrimes switch ((long)c->cmd) { 1187865Sbde#ifdef CONFIG_OF_LIBFDT 1191539Srgrimes case SPL_EXPORT_FDT: 1201539Srgrimes printf("Argument image is now in RAM: 0x%p\n", 1211539Srgrimes (void *)images.ft_addr); 1227865Sbde env_set_addr("fdtargsaddr", images.ft_addr); 1237865Sbde env_set_hex("fdtargslen", fdt_totalsize(images.ft_addr)); 1247865Sbde#ifdef CONFIG_CMD_SPL_WRITE_SIZE 1257865Sbde if (fdt_totalsize(images.ft_addr) > 1267865Sbde CONFIG_CMD_SPL_WRITE_SIZE) 1277865Sbde puts("WARN: FDT size > CMD_SPL_WRITE_SIZE\n"); 1287865Sbde#endif 1297865Sbde break; 1307865Sbde#endif 1317865Sbde case SPL_EXPORT_ATAGS: 1324749Sats printf("Argument image is now in RAM at: 0x%p\n", 1331539Srgrimes (void *)gd->bd->bi_boot_params); 1341539Srgrimes break; 13526630Sache } 13626630Sache } else { 13726636Sache /* Unrecognized command */ 13826630Sache return cmd_usage(cmdtp); 1391539Srgrimes } 1401539Srgrimes 1411539Srgrimes return 0; 1421539Srgrimes} 1431539Srgrimes 1441539Srgrimesstatic struct cmd_tbl cmd_spl_sub[] = { 1451539Srgrimes U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), 1461539Srgrimes}; 1471539Srgrimes 1481539Srgrimesstatic int do_spl(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 1491539Srgrimes{ 1501539Srgrimes const struct cmd_tbl *c; 1511539Srgrimes int cmd; 1521539Srgrimes 1531539Srgrimes if (argc < 2) /* no subcommand */ 1541539Srgrimes return cmd_usage(cmdtp); 1551539Srgrimes 1561539Srgrimes c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); 1571539Srgrimes if (c) { 15823657Speter cmd = (long)c->cmd; 1591539Srgrimes switch (cmd) { 1601539Srgrimes case SPL_EXPORT: 1611539Srgrimes argc--; 1621539Srgrimes argv++; 1631539Srgrimes if (spl_export(cmdtp, flag, argc, argv)) 1641539Srgrimes printf("Subcommand failed\n"); 1651539Srgrimes break; 16639191Simp default: 1671539Srgrimes /* unrecognized command */ 1681539Srgrimes return cmd_usage(cmdtp); 16923657Speter } 17026624Sache } else { 1711539Srgrimes /* Unrecognized command */ 1721539Srgrimes return cmd_usage(cmdtp); 17335943Sjb } 17435943Sjb return 0; 1751539Srgrimes} 1761539Srgrimes 1771539SrgrimesU_BOOT_CMD( 1787865Sbde spl, 6 , 1, do_spl, "SPL configuration", 1791539Srgrimes "export <img=atags|fdt> [kernel_addr] [initrd_addr] [fdt_addr]\n" 1801539Srgrimes "\timg\t\t\"atags\" or \"fdt\"\n" 1817865Sbde "\tkernel_addr\taddress where a kernel image is stored.\n" 182 "\t\t\tkernel is loaded as part of the boot process, but it is not started.\n" 183 "\tinitrd_addr\taddress of initial ramdisk\n" 184 "\t\t\tcan be set to \"-\" if fdt_addr without initrd_addr is used.\n" 185 "\tfdt_addr\tin case of fdt, the address of the device tree.\n" 186 ); 187