1 /* 2 * (C) Copyright 2000 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* #define DEBUG */ 9 10 #include <common.h> 11 #include <autoboot.h> 12 #include <cli.h> 13 #include <command.h> 14 #include <cli_hush.h> 15 #include <malloc.h> 16 #include <version.h> 17 18 /* 19 * Board-specific Platform code can reimplement show_boot_progress () if needed 20 */ 21 void inline __show_boot_progress (int val) {} 22 void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress"))); 23 24 #ifdef CONFIG_MODEM_SUPPORT 25 int do_mdm_init = 0; 26 extern void mdm_init(void); /* defined in board.c */ 27 #endif 28 29 void main_loop(void) 30 { 31 #ifdef CONFIG_PREBOOT 32 char *p; 33 #endif 34 35 bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); 36 37 #ifndef CONFIG_SYS_GENERIC_BOARD 38 puts("Warning: Your board does not use generic board. Please read\n"); 39 puts("doc/README.generic-board and take action. Boards not\n"); 40 puts("upgraded by the late 2014 may break or be removed.\n"); 41 #endif 42 43 #ifdef CONFIG_MODEM_SUPPORT 44 debug("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init); 45 if (do_mdm_init) { 46 char *str = strdup(getenv("mdm_cmd")); 47 setenv("preboot", str); /* set or delete definition */ 48 if (str != NULL) 49 free(str); 50 mdm_init(); /* wait for modem connection */ 51 } 52 #endif /* CONFIG_MODEM_SUPPORT */ 53 54 #ifdef CONFIG_VERSION_VARIABLE 55 { 56 setenv("ver", version_string); /* set version variable */ 57 } 58 #endif /* CONFIG_VERSION_VARIABLE */ 59 60 #ifdef CONFIG_SYS_HUSH_PARSER 61 u_boot_hush_start(); 62 #endif 63 64 #if defined(CONFIG_HUSH_INIT_VAR) 65 hush_init_var(); 66 #endif 67 68 #ifdef CONFIG_PREBOOT 69 p = getenv("preboot"); 70 if (p != NULL) { 71 # ifdef CONFIG_AUTOBOOT_KEYED 72 int prev = disable_ctrlc(1); /* disable Control C checking */ 73 # endif 74 75 run_command_list(p, -1, 0); 76 77 # ifdef CONFIG_AUTOBOOT_KEYED 78 disable_ctrlc(prev); /* restore Control C checking */ 79 # endif 80 } 81 #endif /* CONFIG_PREBOOT */ 82 83 #if defined(CONFIG_UPDATE_TFTP) 84 update_tftp(0UL); 85 #endif /* CONFIG_UPDATE_TFTP */ 86 87 bootdelay_process(); 88 /* 89 * Main Loop for Monitor Command Processing 90 */ 91 #ifdef CONFIG_SYS_HUSH_PARSER 92 parse_file_outer(); 93 /* This point is never reached */ 94 for (;;); 95 #else 96 cli_loop(); 97 #endif /*CONFIG_SYS_HUSH_PARSER*/ 98 } 99 100 /****************************************************************************/ 101 102 /* 103 * Run a command using the selected parser. 104 * 105 * @param cmd Command to run 106 * @param flag Execution flags (CMD_FLAG_...) 107 * @return 0 on success, or != 0 on error. 108 */ 109 int run_command(const char *cmd, int flag) 110 { 111 #ifndef CONFIG_SYS_HUSH_PARSER 112 /* 113 * cli_run_command can return 0 or 1 for success, so clean up 114 * its result. 115 */ 116 if (cli_simple_run_command(cmd, flag) == -1) 117 return 1; 118 119 return 0; 120 #else 121 return parse_string_outer(cmd, 122 FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); 123 #endif 124 } 125 126 int run_command_list(const char *cmd, int len, int flag) 127 { 128 int need_buff = 1; 129 char *buff = (char *)cmd; /* cast away const */ 130 int rcode = 0; 131 132 if (len == -1) { 133 len = strlen(cmd); 134 #ifdef CONFIG_SYS_HUSH_PARSER 135 /* hush will never change our string */ 136 need_buff = 0; 137 #else 138 /* the built-in parser will change our string if it sees \n */ 139 need_buff = strchr(cmd, '\n') != NULL; 140 #endif 141 } 142 if (need_buff) { 143 buff = malloc(len + 1); 144 if (!buff) 145 return 1; 146 memcpy(buff, cmd, len); 147 buff[len] = '\0'; 148 } 149 #ifdef CONFIG_SYS_HUSH_PARSER 150 rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON); 151 #else 152 /* 153 * This function will overwrite any \n it sees with a \0, which 154 * is why it can't work with a const char *. Here we are making 155 * using of internal knowledge of this function, to avoid always 156 * doing a malloc() which is actually required only in a case that 157 * is pretty rare. 158 */ 159 rcode = cli_simple_run_command_list(buff, flag); 160 if (need_buff) 161 free(buff); 162 #endif 163 164 return rcode; 165 } 166 167 /****************************************************************************/ 168 169 #if defined(CONFIG_CMD_RUN) 170 int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 171 { 172 int i; 173 174 if (argc < 2) 175 return CMD_RET_USAGE; 176 177 for (i=1; i<argc; ++i) { 178 char *arg; 179 180 if ((arg = getenv (argv[i])) == NULL) { 181 printf ("## Error: \"%s\" not defined\n", argv[i]); 182 return 1; 183 } 184 185 if (run_command_list(arg, -1, flag) != 0) 186 return 1; 187 } 188 return 0; 189 } 190 #endif 191