cli: Make the sandbox board_run_command the default
[oweals/u-boot.git] / arch / sandbox / cpu / start.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2011-2012 The Chromium OS Authors.
4  */
5
6 #include <common.h>
7 #include <command.h>
8 #include <errno.h>
9 #include <os.h>
10 #include <cli.h>
11 #include <malloc.h>
12 #include <asm/getopt.h>
13 #include <asm/io.h>
14 #include <asm/sections.h>
15 #include <asm/state.h>
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 int sandbox_early_getopt_check(void)
20 {
21         struct sandbox_state *state = state_get_current();
22         struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
23         size_t num_options = __u_boot_sandbox_option_count();
24         size_t i;
25         int max_arg_len, max_noarg_len;
26
27         /* parse_err will be a string of the faulting option */
28         if (!state->parse_err)
29                 return 0;
30
31         if (strcmp(state->parse_err, "help")) {
32                 printf("u-boot: error: failed while parsing option: %s\n"
33                         "\ttry running with --help for more information.\n",
34                         state->parse_err);
35                 os_exit(1);
36         }
37
38         printf(
39                 "u-boot, a command line test interface to U-Boot\n\n"
40                 "Usage: u-boot [options]\n"
41                 "Options:\n");
42
43         max_arg_len = 0;
44         for (i = 0; i < num_options; ++i)
45                 max_arg_len = max((int)strlen(sb_opt[i]->flag), max_arg_len);
46         max_noarg_len = max_arg_len + 7;
47
48         for (i = 0; i < num_options; ++i) {
49                 struct sandbox_cmdline_option *opt = sb_opt[i];
50
51                 /* first output the short flag if it has one */
52                 if (opt->flag_short >= 0x100)
53                         printf("      ");
54                 else
55                         printf("  -%c, ", opt->flag_short);
56
57                 /* then the long flag */
58                 if (opt->has_arg)
59                         printf("--%-*s <arg> ", max_arg_len, opt->flag);
60                 else
61                         printf("--%-*s", max_noarg_len, opt->flag);
62
63                 /* finally the help text */
64                 printf("  %s\n", opt->help);
65         }
66
67         os_exit(0);
68 }
69
70 int misc_init_f(void)
71 {
72         return sandbox_early_getopt_check();
73 }
74
75 static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)
76 {
77         /* just flag to sandbox_early_getopt_check to show usage */
78         return 1;
79 }
80 SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
81
82 #ifndef CONFIG_SPL_BUILD
83 int sandbox_main_loop_init(void)
84 {
85         struct sandbox_state *state = state_get_current();
86
87         /* Execute command if required */
88         if (state->cmd || state->run_distro_boot) {
89                 int retval = 0;
90
91                 cli_init();
92
93 #ifdef CONFIG_CMDLINE
94                 if (state->cmd)
95                         retval = run_command_list(state->cmd, -1, 0);
96
97                 if (state->run_distro_boot)
98                         retval = cli_simple_run_command("run distro_bootcmd",
99                                                         0);
100 #endif
101                 if (!state->interactive)
102                         os_exit(retval);
103         }
104
105         return 0;
106 }
107 #endif
108
109 static int sandbox_cmdline_cb_boot(struct sandbox_state *state,
110                                       const char *arg)
111 {
112         state->run_distro_boot = true;
113         return 0;
114 }
115 SANDBOX_CMDLINE_OPT_SHORT(boot, 'b', 0, "Run distro boot commands");
116
117 static int sandbox_cmdline_cb_command(struct sandbox_state *state,
118                                       const char *arg)
119 {
120         state->cmd = arg;
121         return 0;
122 }
123 SANDBOX_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
124
125 static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
126 {
127         state->fdt_fname = arg;
128         return 0;
129 }
130 SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
131
132 static int sandbox_cmdline_cb_default_fdt(struct sandbox_state *state,
133                                           const char *arg)
134 {
135         const char *fmt = "%s.dtb";
136         char *fname;
137         int len;
138
139         len = strlen(state->argv[0]) + strlen(fmt) + 1;
140         fname = os_malloc(len);
141         if (!fname)
142                 return -ENOMEM;
143         snprintf(fname, len, fmt, state->argv[0]);
144         state->fdt_fname = fname;
145
146         return 0;
147 }
148 SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0,
149                 "Use the default u-boot.dtb control FDT in U-Boot directory");
150
151 static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
152                                        const char *arg)
153 {
154         const char *fmt = "/arch/sandbox/dts/test.dtb";
155         char *p;
156         char *fname;
157         int len;
158
159         len = strlen(state->argv[0]) + strlen(fmt) + 1;
160         fname = os_malloc(len);
161         if (!fname)
162                 return -ENOMEM;
163         strcpy(fname, state->argv[0]);
164         p = strrchr(fname, '/');
165         if (!p)
166                 p = fname + strlen(fname);
167         len -= p - fname;
168         snprintf(p, len, fmt, p);
169         state->fdt_fname = fname;
170
171         return 0;
172 }
173 SANDBOX_CMDLINE_OPT_SHORT(test_fdt, 'T', 0,
174                           "Use the test.dtb control FDT in U-Boot directory");
175
176 static int sandbox_cmdline_cb_interactive(struct sandbox_state *state,
177                                           const char *arg)
178 {
179         state->interactive = true;
180         return 0;
181 }
182
183 SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode");
184
185 static int sandbox_cmdline_cb_jump(struct sandbox_state *state,
186                                    const char *arg)
187 {
188         /* Remember to delete this U-Boot image later */
189         state->jumped_fname = arg;
190
191         return 0;
192 }
193 SANDBOX_CMDLINE_OPT_SHORT(jump, 'j', 1, "Jumped from previous U-Boot");
194
195 static int sandbox_cmdline_cb_memory(struct sandbox_state *state,
196                                      const char *arg)
197 {
198         int err;
199
200         /* For now assume we always want to write it */
201         state->write_ram_buf = true;
202         state->ram_buf_fname = arg;
203
204         err = os_read_ram_buf(arg);
205         if (err) {
206                 printf("Failed to read RAM buffer '%s': %d\n", arg, err);
207                 return err;
208         }
209         state->ram_buf_read = true;
210
211         return 0;
212 }
213 SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1,
214                           "Read/write ram_buf memory contents from file");
215
216 static int sandbox_cmdline_cb_rm_memory(struct sandbox_state *state,
217                                         const char *arg)
218 {
219         state->ram_buf_rm = true;
220
221         return 0;
222 }
223 SANDBOX_CMDLINE_OPT(rm_memory, 0, "Remove memory file after reading");
224
225 static int sandbox_cmdline_cb_state(struct sandbox_state *state,
226                                     const char *arg)
227 {
228         state->state_fname = arg;
229         return 0;
230 }
231 SANDBOX_CMDLINE_OPT_SHORT(state, 's', 1, "Specify the sandbox state FDT");
232
233 static int sandbox_cmdline_cb_read(struct sandbox_state *state,
234                                    const char *arg)
235 {
236         state->read_state = true;
237         return 0;
238 }
239 SANDBOX_CMDLINE_OPT_SHORT(read, 'r', 0, "Read the state FDT on startup");
240
241 static int sandbox_cmdline_cb_write(struct sandbox_state *state,
242                                     const char *arg)
243 {
244         state->write_state = true;
245         return 0;
246 }
247 SANDBOX_CMDLINE_OPT_SHORT(write, 'w', 0, "Write state FDT on exit");
248
249 static int sandbox_cmdline_cb_ignore_missing(struct sandbox_state *state,
250                                              const char *arg)
251 {
252         state->ignore_missing_state_on_read = true;
253         return 0;
254 }
255 SANDBOX_CMDLINE_OPT_SHORT(ignore_missing, 'n', 0,
256                           "Ignore missing state on read");
257
258 static int sandbox_cmdline_cb_show_lcd(struct sandbox_state *state,
259                                        const char *arg)
260 {
261         state->show_lcd = true;
262         return 0;
263 }
264 SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0,
265                           "Show the sandbox LCD display");
266
267 static const char *term_args[STATE_TERM_COUNT] = {
268         "raw-with-sigs",
269         "raw",
270         "cooked",
271 };
272
273 static int sandbox_cmdline_cb_terminal(struct sandbox_state *state,
274                                        const char *arg)
275 {
276         int i;
277
278         for (i = 0; i < STATE_TERM_COUNT; i++) {
279                 if (!strcmp(arg, term_args[i])) {
280                         state->term_raw = i;
281                         return 0;
282                 }
283         }
284
285         printf("Unknown terminal setting '%s' (", arg);
286         for (i = 0; i < STATE_TERM_COUNT; i++)
287                 printf("%s%s", i ? ", " : "", term_args[i]);
288         puts(")\n");
289
290         return 1;
291 }
292 SANDBOX_CMDLINE_OPT_SHORT(terminal, 't', 1,
293                           "Set terminal to raw/cooked mode");
294
295 static int sandbox_cmdline_cb_verbose(struct sandbox_state *state,
296                                       const char *arg)
297 {
298         state->show_test_output = true;
299         return 0;
300 }
301 SANDBOX_CMDLINE_OPT_SHORT(verbose, 'v', 0, "Show test output");
302
303 static int sandbox_cmdline_cb_log_level(struct sandbox_state *state,
304                                         const char *arg)
305 {
306         state->default_log_level = simple_strtol(arg, NULL, 10);
307
308         return 0;
309 }
310 SANDBOX_CMDLINE_OPT_SHORT(log_level, 'L', 1,
311                           "Set log level (0=panic, 7=debug)");
312
313 static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state,
314                                                const char *arg)
315 {
316         state->show_of_platdata = true;
317
318         return 0;
319 }
320 SANDBOX_CMDLINE_OPT(show_of_platdata, 0, "Show of-platdata in SPL");
321
322 static void setup_ram_buf(struct sandbox_state *state)
323 {
324         /* Zero the RAM buffer if we didn't read it, to keep valgrind happy */
325         if (!state->ram_buf_read)
326                 memset(state->ram_buf, '\0', state->ram_size);
327
328         gd->arch.ram_buf = state->ram_buf;
329         gd->ram_size = state->ram_size;
330 }
331
332 void state_show(struct sandbox_state *state)
333 {
334         char **p;
335
336         printf("Arguments:\n");
337         for (p = state->argv; *p; p++)
338                 printf("%s ", *p);
339         printf("\n");
340 }
341
342 int main(int argc, char *argv[])
343 {
344         struct sandbox_state *state;
345         gd_t data;
346         int ret;
347
348         memset(&data, '\0', sizeof(data));
349         gd = &data;
350         gd->arch.text_base = os_find_text_base();
351
352         ret = state_init();
353         if (ret)
354                 goto err;
355
356         state = state_get_current();
357         if (os_parse_args(state, argc, argv))
358                 return 1;
359
360         ret = sandbox_read_state(state, state->state_fname);
361         if (ret)
362                 goto err;
363
364 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
365         gd->malloc_base = CONFIG_MALLOC_F_ADDR;
366 #endif
367 #if CONFIG_IS_ENABLED(LOG)
368         gd->default_log_level = state->default_log_level;
369 #endif
370         setup_ram_buf(state);
371
372         /*
373          * Set up the relocation offset here, since sandbox symbols are always
374          * relocated by the OS before sandbox is entered.
375          */
376         gd->reloc_off = (ulong)gd->arch.text_base;
377
378         /* Do pre- and post-relocation init */
379         board_init_f(0);
380
381         board_init_r(gd->new_gd, 0);
382
383         /* NOTREACHED - board_init_r() does not return */
384         return 0;
385
386 err:
387         printf("Error %d\n", ret);
388         return 1;
389 }