]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/main.c
Move autoboot code to autoboot.c
[karo-tx-uboot.git] / common / main.c
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