1*2e192b24SSimon Glass /* 2*2e192b24SSimon Glass * Copyright (C) 2011 3*2e192b24SSimon Glass * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> 4*2e192b24SSimon Glass * 5*2e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6*2e192b24SSimon Glass */ 7*2e192b24SSimon Glass 8*2e192b24SSimon Glass #include <common.h> 9*2e192b24SSimon Glass #include <command.h> 10*2e192b24SSimon Glass #include <cmd_spl.h> 11*2e192b24SSimon Glass 12*2e192b24SSimon Glass DECLARE_GLOBAL_DATA_PTR; 13*2e192b24SSimon Glass 14*2e192b24SSimon Glass static const char **subcmd_list[] = { 15*2e192b24SSimon Glass 16*2e192b24SSimon Glass [SPL_EXPORT_FDT] = (const char * []) { 17*2e192b24SSimon Glass #ifdef CONFIG_OF_LIBFDT 18*2e192b24SSimon Glass "start", 19*2e192b24SSimon Glass "loados", 20*2e192b24SSimon Glass #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 21*2e192b24SSimon Glass "ramdisk", 22*2e192b24SSimon Glass #endif 23*2e192b24SSimon Glass "fdt", 24*2e192b24SSimon Glass "cmdline", 25*2e192b24SSimon Glass "bdt", 26*2e192b24SSimon Glass "prep", 27*2e192b24SSimon Glass #endif 28*2e192b24SSimon Glass NULL, 29*2e192b24SSimon Glass }, 30*2e192b24SSimon Glass [SPL_EXPORT_ATAGS] = (const char * []) { 31*2e192b24SSimon Glass #if defined(CONFIG_SETUP_MEMORY_TAGS) || \ 32*2e192b24SSimon Glass defined(CONFIG_CMDLINE_TAG) || \ 33*2e192b24SSimon Glass defined(CONFIG_INITRD_TAG) || \ 34*2e192b24SSimon Glass defined(CONFIG_SERIAL_TAG) || \ 35*2e192b24SSimon Glass defined(CONFIG_REVISION_TAG) 36*2e192b24SSimon Glass "start", 37*2e192b24SSimon Glass "loados", 38*2e192b24SSimon Glass #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 39*2e192b24SSimon Glass "ramdisk", 40*2e192b24SSimon Glass #endif 41*2e192b24SSimon Glass "cmdline", 42*2e192b24SSimon Glass "bdt", 43*2e192b24SSimon Glass "prep", 44*2e192b24SSimon Glass #endif 45*2e192b24SSimon Glass NULL, 46*2e192b24SSimon Glass }, 47*2e192b24SSimon Glass NULL 48*2e192b24SSimon Glass }; 49*2e192b24SSimon Glass 50*2e192b24SSimon Glass /* Calls bootm with the parameters given */ 51*2e192b24SSimon Glass static int call_bootm(int argc, char * const argv[], const char *subcommand[]) 52*2e192b24SSimon Glass { 53*2e192b24SSimon Glass char *bootm_argv[5]; 54*2e192b24SSimon Glass 55*2e192b24SSimon Glass int i = 0; 56*2e192b24SSimon Glass int ret = 0; 57*2e192b24SSimon Glass int j; 58*2e192b24SSimon Glass 59*2e192b24SSimon Glass /* create paramter array */ 60*2e192b24SSimon Glass bootm_argv[0] = "do_bootm"; 61*2e192b24SSimon Glass switch (argc) { 62*2e192b24SSimon Glass case 3: 63*2e192b24SSimon Glass bootm_argv[4] = argv[2]; /* fdt addr */ 64*2e192b24SSimon Glass case 2: 65*2e192b24SSimon Glass bootm_argv[3] = argv[1]; /* initrd addr */ 66*2e192b24SSimon Glass case 1: 67*2e192b24SSimon Glass bootm_argv[2] = argv[0]; /* kernel addr */ 68*2e192b24SSimon Glass } 69*2e192b24SSimon Glass 70*2e192b24SSimon Glass 71*2e192b24SSimon Glass /* 72*2e192b24SSimon Glass * - do the work - 73*2e192b24SSimon Glass * exec subcommands of do_bootm to init the images 74*2e192b24SSimon Glass * data structure 75*2e192b24SSimon Glass */ 76*2e192b24SSimon Glass while (subcommand[i] != NULL) { 77*2e192b24SSimon Glass bootm_argv[1] = (char *)subcommand[i]; 78*2e192b24SSimon Glass debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]); 79*2e192b24SSimon Glass for (j = 0; j < argc; j++) 80*2e192b24SSimon Glass debug("%s ", bootm_argv[j + 2]); 81*2e192b24SSimon Glass debug("\n"); 82*2e192b24SSimon Glass 83*2e192b24SSimon Glass ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, 84*2e192b24SSimon Glass bootm_argv); 85*2e192b24SSimon Glass debug("Subcommand retcode: %d\n", ret); 86*2e192b24SSimon Glass i++; 87*2e192b24SSimon Glass } 88*2e192b24SSimon Glass 89*2e192b24SSimon Glass if (ret) { 90*2e192b24SSimon Glass printf("ERROR prep subcommand failed!\n"); 91*2e192b24SSimon Glass return -1; 92*2e192b24SSimon Glass } 93*2e192b24SSimon Glass 94*2e192b24SSimon Glass return 0; 95*2e192b24SSimon Glass } 96*2e192b24SSimon Glass 97*2e192b24SSimon Glass static cmd_tbl_t cmd_spl_export_sub[] = { 98*2e192b24SSimon Glass U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), 99*2e192b24SSimon Glass U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), 100*2e192b24SSimon Glass }; 101*2e192b24SSimon Glass 102*2e192b24SSimon Glass static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 103*2e192b24SSimon Glass { 104*2e192b24SSimon Glass const cmd_tbl_t *c; 105*2e192b24SSimon Glass 106*2e192b24SSimon Glass if (argc < 2) /* no subcommand */ 107*2e192b24SSimon Glass return cmd_usage(cmdtp); 108*2e192b24SSimon Glass 109*2e192b24SSimon Glass c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], 110*2e192b24SSimon Glass ARRAY_SIZE(cmd_spl_export_sub)); 111*2e192b24SSimon Glass if ((c) && ((int)c->cmd <= SPL_EXPORT_LAST)) { 112*2e192b24SSimon Glass argc -= 2; 113*2e192b24SSimon Glass argv += 2; 114*2e192b24SSimon Glass if (call_bootm(argc, argv, subcmd_list[(int)c->cmd])) 115*2e192b24SSimon Glass return -1; 116*2e192b24SSimon Glass switch ((int)c->cmd) { 117*2e192b24SSimon Glass #ifdef CONFIG_OF_LIBFDT 118*2e192b24SSimon Glass case SPL_EXPORT_FDT: 119*2e192b24SSimon Glass printf("Argument image is now in RAM: 0x%p\n", 120*2e192b24SSimon Glass (void *)images.ft_addr); 121*2e192b24SSimon Glass break; 122*2e192b24SSimon Glass #endif 123*2e192b24SSimon Glass case SPL_EXPORT_ATAGS: 124*2e192b24SSimon Glass printf("Argument image is now in RAM at: 0x%p\n", 125*2e192b24SSimon Glass (void *)gd->bd->bi_boot_params); 126*2e192b24SSimon Glass break; 127*2e192b24SSimon Glass } 128*2e192b24SSimon Glass } else { 129*2e192b24SSimon Glass /* Unrecognized command */ 130*2e192b24SSimon Glass return cmd_usage(cmdtp); 131*2e192b24SSimon Glass } 132*2e192b24SSimon Glass 133*2e192b24SSimon Glass return 0; 134*2e192b24SSimon Glass } 135*2e192b24SSimon Glass 136*2e192b24SSimon Glass static cmd_tbl_t cmd_spl_sub[] = { 137*2e192b24SSimon Glass U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), 138*2e192b24SSimon Glass }; 139*2e192b24SSimon Glass 140*2e192b24SSimon Glass static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 141*2e192b24SSimon Glass { 142*2e192b24SSimon Glass const cmd_tbl_t *c; 143*2e192b24SSimon Glass int cmd; 144*2e192b24SSimon Glass 145*2e192b24SSimon Glass if (argc < 2) /* no subcommand */ 146*2e192b24SSimon Glass return cmd_usage(cmdtp); 147*2e192b24SSimon Glass 148*2e192b24SSimon Glass c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); 149*2e192b24SSimon Glass if (c) { 150*2e192b24SSimon Glass cmd = (int)c->cmd; 151*2e192b24SSimon Glass switch (cmd) { 152*2e192b24SSimon Glass case SPL_EXPORT: 153*2e192b24SSimon Glass argc--; 154*2e192b24SSimon Glass argv++; 155*2e192b24SSimon Glass if (spl_export(cmdtp, flag, argc, argv)) 156*2e192b24SSimon Glass printf("Subcommand failed\n"); 157*2e192b24SSimon Glass break; 158*2e192b24SSimon Glass default: 159*2e192b24SSimon Glass /* unrecognized command */ 160*2e192b24SSimon Glass return cmd_usage(cmdtp); 161*2e192b24SSimon Glass } 162*2e192b24SSimon Glass } else { 163*2e192b24SSimon Glass /* Unrecognized command */ 164*2e192b24SSimon Glass return cmd_usage(cmdtp); 165*2e192b24SSimon Glass } 166*2e192b24SSimon Glass return 0; 167*2e192b24SSimon Glass } 168*2e192b24SSimon Glass 169*2e192b24SSimon Glass U_BOOT_CMD( 170*2e192b24SSimon Glass spl, 6 , 1, do_spl, "SPL configuration", 171*2e192b24SSimon Glass "export <img=atags|fdt> [kernel_addr] [initrd_addr] [fdt_addr]\n" 172*2e192b24SSimon Glass "\timg\t\t\"atags\" or \"fdt\"\n" 173*2e192b24SSimon Glass "\tkernel_addr\taddress where a kernel image is stored.\n" 174*2e192b24SSimon Glass "\t\t\tkernel is loaded as part of the boot process, but it is not started.\n" 175*2e192b24SSimon Glass "\tinitrd_addr\taddress of initial ramdisk\n" 176*2e192b24SSimon Glass "\t\t\tcan be set to \"-\" if fdt_addr without initrd_addr is used.\n" 177*2e192b24SSimon Glass "\tfdt_addr\tin case of fdt, the address of the device tree.\n" 178*2e192b24SSimon Glass ); 179