xref: /openbmc/u-boot/common/main.c (revision 66ded17dfc8110f0d9aa9d50fe140a320bfa4e53)
1c609719bSwdenk /*
2c609719bSwdenk  * (C) Copyright 2000
3c609719bSwdenk  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4c609719bSwdenk  *
51a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
6c609719bSwdenk  */
7c609719bSwdenk 
8a6c7ad2fSwdenk /* #define	DEBUG	*/
9a6c7ad2fSwdenk 
10c609719bSwdenk #include <common.h>
11*66ded17dSSimon Glass #include <autoboot.h>
1218d66533SSimon Glass #include <cli.h>
13c609719bSwdenk #include <command.h>
14eca86fadSSimon Glass #include <cli_hush.h>
15fbcdf32aSSimon Glass #include <malloc.h>
16fbcdf32aSSimon Glass #include <version.h>
17bdccc4feSwdenk 
18fad63407SHeiko Schocher /*
19fad63407SHeiko Schocher  * Board-specific Platform code can reimplement show_boot_progress () if needed
20fad63407SHeiko Schocher  */
21fad63407SHeiko Schocher void inline __show_boot_progress (int val) {}
225e2c08c3SEmil Medve void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
23fad63407SHeiko Schocher 
24c609719bSwdenk #ifdef CONFIG_MODEM_SUPPORT
25c609719bSwdenk int do_mdm_init = 0;
26c609719bSwdenk extern void mdm_init(void); /* defined in board.c */
27c609719bSwdenk #endif
28c609719bSwdenk 
29bc2b4c27SSimon Glass void main_loop(void)
30bc2b4c27SSimon Glass {
31bc2b4c27SSimon Glass #ifdef CONFIG_PREBOOT
32bc2b4c27SSimon Glass 	char *p;
33bc2b4c27SSimon Glass #endif
34bc2b4c27SSimon Glass 
35bc2b4c27SSimon Glass 	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
36bc2b4c27SSimon Glass 
370f605c15SSimon Glass #ifndef CONFIG_SYS_GENERIC_BOARD
380f605c15SSimon Glass 	puts("Warning: Your board does not use generic board. Please read\n");
390f605c15SSimon Glass 	puts("doc/README.generic-board and take action. Boards not\n");
400f605c15SSimon Glass 	puts("upgraded by the late 2014 may break or be removed.\n");
410f605c15SSimon Glass #endif
420f605c15SSimon Glass 
43bc2b4c27SSimon Glass #ifdef CONFIG_MODEM_SUPPORT
44bc2b4c27SSimon Glass 	debug("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init);
45bc2b4c27SSimon Glass 	if (do_mdm_init) {
46bc2b4c27SSimon Glass 		char *str = strdup(getenv("mdm_cmd"));
47bc2b4c27SSimon Glass 		setenv("preboot", str);  /* set or delete definition */
48bc2b4c27SSimon Glass 		if (str != NULL)
49bc2b4c27SSimon Glass 			free(str);
50bc2b4c27SSimon Glass 		mdm_init(); /* wait for modem connection */
51bc2b4c27SSimon Glass 	}
52bc2b4c27SSimon Glass #endif  /* CONFIG_MODEM_SUPPORT */
53bc2b4c27SSimon Glass 
54bc2b4c27SSimon Glass #ifdef CONFIG_VERSION_VARIABLE
55bc2b4c27SSimon Glass 	{
56bc2b4c27SSimon Glass 		setenv("ver", version_string);  /* set version variable */
57bc2b4c27SSimon Glass 	}
58bc2b4c27SSimon Glass #endif /* CONFIG_VERSION_VARIABLE */
59bc2b4c27SSimon Glass 
60bc2b4c27SSimon Glass #ifdef CONFIG_SYS_HUSH_PARSER
61bc2b4c27SSimon Glass 	u_boot_hush_start();
62bc2b4c27SSimon Glass #endif
63bc2b4c27SSimon Glass 
64bc2b4c27SSimon Glass #if defined(CONFIG_HUSH_INIT_VAR)
65bc2b4c27SSimon Glass 	hush_init_var();
66bc2b4c27SSimon Glass #endif
67bc2b4c27SSimon Glass 
68bc2b4c27SSimon Glass #ifdef CONFIG_PREBOOT
69bc2b4c27SSimon Glass 	p = getenv("preboot");
70bc2b4c27SSimon Glass 	if (p != NULL) {
71bc2b4c27SSimon Glass # ifdef CONFIG_AUTOBOOT_KEYED
72bc2b4c27SSimon Glass 		int prev = disable_ctrlc(1);	/* disable Control C checking */
73bc2b4c27SSimon Glass # endif
74bc2b4c27SSimon Glass 
75bc2b4c27SSimon Glass 		run_command_list(p, -1, 0);
76bc2b4c27SSimon Glass 
77bc2b4c27SSimon Glass # ifdef CONFIG_AUTOBOOT_KEYED
78bc2b4c27SSimon Glass 		disable_ctrlc(prev);	/* restore Control C checking */
79bc2b4c27SSimon Glass # endif
80bc2b4c27SSimon Glass 	}
81bc2b4c27SSimon Glass #endif /* CONFIG_PREBOOT */
82bc2b4c27SSimon Glass 
83bc2b4c27SSimon Glass #if defined(CONFIG_UPDATE_TFTP)
84bc2b4c27SSimon Glass 	update_tftp(0UL);
85bc2b4c27SSimon Glass #endif /* CONFIG_UPDATE_TFTP */
86bc2b4c27SSimon Glass 
87*66ded17dSSimon Glass 	bootdelay_process();
88c609719bSwdenk 	/*
89c609719bSwdenk 	 * Main Loop for Monitor Command Processing
90c609719bSwdenk 	 */
916d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_HUSH_PARSER
92c609719bSwdenk 	parse_file_outer();
93c609719bSwdenk 	/* This point is never reached */
94c609719bSwdenk 	for (;;);
95c609719bSwdenk #else
966493ccc7SSimon Glass 	cli_loop();
976d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #endif /*CONFIG_SYS_HUSH_PARSER*/
98c609719bSwdenk }
99c609719bSwdenk 
100c609719bSwdenk /****************************************************************************/
101c609719bSwdenk 
102c609719bSwdenk /*
10353071532SSimon Glass  * Run a command using the selected parser.
10453071532SSimon Glass  *
10553071532SSimon Glass  * @param cmd	Command to run
10653071532SSimon Glass  * @param flag	Execution flags (CMD_FLAG_...)
10753071532SSimon Glass  * @return 0 on success, or != 0 on error.
10853071532SSimon Glass  */
10953071532SSimon Glass int run_command(const char *cmd, int flag)
11053071532SSimon Glass {
11153071532SSimon Glass #ifndef CONFIG_SYS_HUSH_PARSER
11253071532SSimon Glass 	/*
1136493ccc7SSimon Glass 	 * cli_run_command can return 0 or 1 for success, so clean up
11453071532SSimon Glass 	 * its result.
11553071532SSimon Glass 	 */
1166493ccc7SSimon Glass 	if (cli_simple_run_command(cmd, flag) == -1)
11753071532SSimon Glass 		return 1;
11853071532SSimon Glass 
11953071532SSimon Glass 	return 0;
12053071532SSimon Glass #else
12153071532SSimon Glass 	return parse_string_outer(cmd,
12253071532SSimon Glass 			FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
12353071532SSimon Glass #endif
12453071532SSimon Glass }
12553071532SSimon Glass 
126d51004a8SSimon Glass int run_command_list(const char *cmd, int len, int flag)
127d51004a8SSimon Glass {
128d51004a8SSimon Glass 	int need_buff = 1;
129d51004a8SSimon Glass 	char *buff = (char *)cmd;	/* cast away const */
130d51004a8SSimon Glass 	int rcode = 0;
131d51004a8SSimon Glass 
132d51004a8SSimon Glass 	if (len == -1) {
133d51004a8SSimon Glass 		len = strlen(cmd);
134d51004a8SSimon Glass #ifdef CONFIG_SYS_HUSH_PARSER
135d51004a8SSimon Glass 		/* hush will never change our string */
136d51004a8SSimon Glass 		need_buff = 0;
137d51004a8SSimon Glass #else
138d51004a8SSimon Glass 		/* the built-in parser will change our string if it sees \n */
139d51004a8SSimon Glass 		need_buff = strchr(cmd, '\n') != NULL;
140d51004a8SSimon Glass #endif
141d51004a8SSimon Glass 	}
142d51004a8SSimon Glass 	if (need_buff) {
143d51004a8SSimon Glass 		buff = malloc(len + 1);
144d51004a8SSimon Glass 		if (!buff)
145d51004a8SSimon Glass 			return 1;
146d51004a8SSimon Glass 		memcpy(buff, cmd, len);
147d51004a8SSimon Glass 		buff[len] = '\0';
148d51004a8SSimon Glass 	}
149d51004a8SSimon Glass #ifdef CONFIG_SYS_HUSH_PARSER
150d51004a8SSimon Glass 	rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON);
151d51004a8SSimon Glass #else
152d51004a8SSimon Glass 	/*
153d51004a8SSimon Glass 	 * This function will overwrite any \n it sees with a \0, which
154d51004a8SSimon Glass 	 * is why it can't work with a const char *. Here we are making
155d51004a8SSimon Glass 	 * using of internal knowledge of this function, to avoid always
156d51004a8SSimon Glass 	 * doing a malloc() which is actually required only in a case that
157d51004a8SSimon Glass 	 * is pretty rare.
158d51004a8SSimon Glass 	 */
1596493ccc7SSimon Glass 	rcode = cli_simple_run_command_list(buff, flag);
160d51004a8SSimon Glass 	if (need_buff)
161d51004a8SSimon Glass 		free(buff);
162d51004a8SSimon Glass #endif
163d51004a8SSimon Glass 
164d51004a8SSimon Glass 	return rcode;
165d51004a8SSimon Glass }
166d51004a8SSimon Glass 
167c609719bSwdenk /****************************************************************************/
168c609719bSwdenk 
169c3517f91SJon Loeliger #if defined(CONFIG_CMD_RUN)
17054841ab5SWolfgang Denk int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
171c609719bSwdenk {
172c609719bSwdenk 	int i;
173c609719bSwdenk 
17447e26b1bSWolfgang Denk 	if (argc < 2)
1754c12eeb8SSimon Glass 		return CMD_RET_USAGE;
176c609719bSwdenk 
177c609719bSwdenk 	for (i=1; i<argc; ++i) {
1783e38691eSwdenk 		char *arg;
1793e38691eSwdenk 
1803e38691eSwdenk 		if ((arg = getenv (argv[i])) == NULL) {
1813e38691eSwdenk 			printf ("## Error: \"%s\" not defined\n", argv[i]);
1823e38691eSwdenk 			return 1;
1833e38691eSwdenk 		}
184c8a2079eSJason Hobbs 
1851992dbfdSSimon Glass 		if (run_command_list(arg, -1, flag) != 0)
1863e38691eSwdenk 			return 1;
187c609719bSwdenk 	}
1883e38691eSwdenk 	return 0;
189c609719bSwdenk }
19090253178SJon Loeliger #endif
191