2018-05-06 21:58:06 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
2011-10-03 19:26:45 +00:00
|
|
|
/*
|
2012-02-15 23:51:15 +00:00
|
|
|
* Copyright (c) 2011-2012 The Chromium OS Authors.
|
2011-10-03 19:26:45 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <common.h>
|
2022-03-04 15:42:58 +00:00
|
|
|
#include <cli.h>
|
2019-11-14 19:57:43 +00:00
|
|
|
#include <command.h>
|
2020-12-02 15:22:11 +00:00
|
|
|
#include <efi_loader.h>
|
2015-05-04 17:31:08 +00:00
|
|
|
#include <errno.h>
|
2022-03-04 15:43:04 +00:00
|
|
|
#include <event.h>
|
2020-05-10 17:40:02 +00:00
|
|
|
#include <init.h>
|
2020-11-27 10:20:55 +00:00
|
|
|
#include <log.h>
|
2013-11-10 17:27:03 +00:00
|
|
|
#include <os.h>
|
2020-02-03 14:35:47 +00:00
|
|
|
#include <sort.h>
|
2012-02-15 23:51:16 +00:00
|
|
|
#include <asm/getopt.h>
|
2020-10-31 03:38:53 +00:00
|
|
|
#include <asm/global_data.h>
|
2014-07-11 04:23:27 +00:00
|
|
|
#include <asm/io.h>
|
2020-02-03 14:36:05 +00:00
|
|
|
#include <asm/malloc.h>
|
2012-02-15 23:51:16 +00:00
|
|
|
#include <asm/sections.h>
|
2012-02-15 23:51:15 +00:00
|
|
|
#include <asm/state.h>
|
2022-03-04 15:42:58 +00:00
|
|
|
#include <dm/root.h>
|
2020-02-03 14:35:47 +00:00
|
|
|
#include <linux/ctype.h>
|
2011-10-03 19:26:45 +00:00
|
|
|
|
2013-11-10 17:26:59 +00:00
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
2020-10-27 19:29:25 +00:00
|
|
|
static char **os_argv;
|
|
|
|
|
2020-02-03 14:35:47 +00:00
|
|
|
/* Compare two options so that they can be sorted into alphabetical order */
|
|
|
|
static int h_compare_opt(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const struct sandbox_cmdline_option *opt1 = p1;
|
|
|
|
const struct sandbox_cmdline_option *opt2 = p2;
|
|
|
|
const char *str1, *str2;
|
|
|
|
char flag1[2], flag2[2];
|
|
|
|
|
|
|
|
opt1 = *(struct sandbox_cmdline_option **)p1;
|
|
|
|
opt2 = *(struct sandbox_cmdline_option **)p2;
|
|
|
|
flag1[1] = '\0';
|
|
|
|
flag2[1] = '\0';
|
|
|
|
|
|
|
|
*flag1 = opt1->flag_short < 0x100 ? opt1->flag_short : '\0';
|
|
|
|
*flag2 = opt2->flag_short < 0x100 ? opt2->flag_short : '\0';
|
|
|
|
|
|
|
|
str1 = *flag1 ? flag1 : opt1->flag;
|
|
|
|
str2 = *flag2 ? flag2 : opt2->flag;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Force lower-case flags to come before upper-case ones. We only
|
|
|
|
* support upper-case for short flags.
|
|
|
|
*/
|
|
|
|
if (isalpha(*str1) && isalpha(*str2) &&
|
|
|
|
tolower(*str1) == tolower(*str2))
|
|
|
|
return isupper(*str1) - isupper(*str2);
|
|
|
|
|
|
|
|
return strcasecmp(str1, str2);
|
|
|
|
}
|
|
|
|
|
2012-02-15 23:51:16 +00:00
|
|
|
int sandbox_early_getopt_check(void)
|
|
|
|
{
|
|
|
|
struct sandbox_state *state = state_get_current();
|
2021-05-20 11:24:06 +00:00
|
|
|
struct sandbox_cmdline_option **sb_opt =
|
|
|
|
__u_boot_sandbox_option_start();
|
2012-02-15 23:51:16 +00:00
|
|
|
size_t num_options = __u_boot_sandbox_option_count();
|
|
|
|
size_t i;
|
|
|
|
int max_arg_len, max_noarg_len;
|
2020-02-03 14:35:47 +00:00
|
|
|
struct sandbox_cmdline_option **sorted_opt;
|
|
|
|
int size;
|
2012-02-15 23:51:16 +00:00
|
|
|
|
|
|
|
/* parse_err will be a string of the faulting option */
|
|
|
|
if (!state->parse_err)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (strcmp(state->parse_err, "help")) {
|
|
|
|
printf("u-boot: error: failed while parsing option: %s\n"
|
|
|
|
"\ttry running with --help for more information.\n",
|
|
|
|
state->parse_err);
|
|
|
|
os_exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf(
|
|
|
|
"u-boot, a command line test interface to U-Boot\n\n"
|
|
|
|
"Usage: u-boot [options]\n"
|
|
|
|
"Options:\n");
|
|
|
|
|
|
|
|
max_arg_len = 0;
|
|
|
|
for (i = 0; i < num_options; ++i)
|
linux/kernel.h: sync min, max, min3, max3 macros with Linux
U-Boot has never cared about the type when we get max/min of two
values, but Linux Kernel does. This commit gets min, max, min3, max3
macros synced with the kernel introducing type checks.
Many of references of those macros must be fixed to suppress warnings.
We have two options:
- Use min, max, min3, max3 only when the arguments have the same type
(or add casts to the arguments)
- Use min_t/max_t instead with the appropriate type for the first
argument
Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
Acked-by: Pavel Machek <pavel@denx.de>
Acked-by: Lukasz Majewski <l.majewski@samsung.com>
Tested-by: Lukasz Majewski <l.majewski@samsung.com>
[trini: Fixup arch/blackfin/lib/string.c]
Signed-off-by: Tom Rini <trini@ti.com>
2014-11-06 18:03:31 +00:00
|
|
|
max_arg_len = max((int)strlen(sb_opt[i]->flag), max_arg_len);
|
2012-02-15 23:51:16 +00:00
|
|
|
max_noarg_len = max_arg_len + 7;
|
|
|
|
|
2020-02-03 14:35:47 +00:00
|
|
|
/* Sort the options */
|
|
|
|
size = sizeof(*sorted_opt) * num_options;
|
2021-02-06 16:57:33 +00:00
|
|
|
sorted_opt = os_malloc(size);
|
2020-02-03 14:35:47 +00:00
|
|
|
if (!sorted_opt) {
|
|
|
|
printf("No memory to sort options\n");
|
|
|
|
os_exit(1);
|
|
|
|
}
|
|
|
|
memcpy(sorted_opt, sb_opt, size);
|
|
|
|
qsort(sorted_opt, num_options, sizeof(*sorted_opt), h_compare_opt);
|
|
|
|
|
2012-02-15 23:51:16 +00:00
|
|
|
for (i = 0; i < num_options; ++i) {
|
2020-02-03 14:35:47 +00:00
|
|
|
struct sandbox_cmdline_option *opt = sorted_opt[i];
|
2012-02-15 23:51:16 +00:00
|
|
|
|
|
|
|
/* first output the short flag if it has one */
|
|
|
|
if (opt->flag_short >= 0x100)
|
|
|
|
printf(" ");
|
|
|
|
else
|
|
|
|
printf(" -%c, ", opt->flag_short);
|
|
|
|
|
|
|
|
/* then the long flag */
|
|
|
|
if (opt->has_arg)
|
|
|
|
printf("--%-*s <arg> ", max_arg_len, opt->flag);
|
2013-11-10 17:26:58 +00:00
|
|
|
else
|
|
|
|
printf("--%-*s", max_noarg_len, opt->flag);
|
2012-02-15 23:51:16 +00:00
|
|
|
|
|
|
|
/* finally the help text */
|
|
|
|
printf(" %s\n", opt->help);
|
|
|
|
}
|
|
|
|
|
|
|
|
os_exit(0);
|
|
|
|
}
|
|
|
|
|
2022-03-04 15:43:04 +00:00
|
|
|
static int sandbox_misc_init_f(void *ctx, struct event *event)
|
2017-03-28 16:27:28 +00:00
|
|
|
{
|
|
|
|
return sandbox_early_getopt_check();
|
|
|
|
}
|
2022-03-04 15:43:04 +00:00
|
|
|
EVENT_SPY(EVT_MISC_INIT_F, sandbox_misc_init_f);
|
2017-03-28 16:27:28 +00:00
|
|
|
|
2013-12-03 23:43:23 +00:00
|
|
|
static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)
|
2012-02-15 23:51:16 +00:00
|
|
|
{
|
|
|
|
/* just flag to sandbox_early_getopt_check to show usage */
|
|
|
|
return 1;
|
|
|
|
}
|
2013-12-03 23:43:23 +00:00
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
|
2012-02-15 23:51:16 +00:00
|
|
|
|
2016-07-04 17:57:50 +00:00
|
|
|
#ifndef CONFIG_SPL_BUILD
|
2012-02-26 22:38:50 +00:00
|
|
|
int sandbox_main_loop_init(void)
|
|
|
|
{
|
2012-02-15 23:51:16 +00:00
|
|
|
struct sandbox_state *state = state_get_current();
|
|
|
|
|
|
|
|
/* Execute command if required */
|
2015-04-30 20:16:09 +00:00
|
|
|
if (state->cmd || state->run_distro_boot) {
|
|
|
|
int retval = 0;
|
2015-02-06 21:37:31 +00:00
|
|
|
|
2014-10-29 22:21:38 +00:00
|
|
|
cli_init();
|
|
|
|
|
2016-03-14 01:07:30 +00:00
|
|
|
#ifdef CONFIG_CMDLINE
|
2015-04-30 20:16:09 +00:00
|
|
|
if (state->cmd)
|
|
|
|
retval = run_command_list(state->cmd, -1, 0);
|
|
|
|
|
|
|
|
if (state->run_distro_boot)
|
|
|
|
retval = cli_simple_run_command("run distro_bootcmd",
|
|
|
|
0);
|
2016-03-14 01:07:30 +00:00
|
|
|
#endif
|
2013-11-10 17:27:02 +00:00
|
|
|
if (!state->interactive)
|
2015-02-06 21:37:31 +00:00
|
|
|
os_exit(retval);
|
2012-02-15 23:51:16 +00:00
|
|
|
}
|
|
|
|
|
2012-02-26 22:38:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2016-07-04 17:57:50 +00:00
|
|
|
#endif
|
2012-02-26 22:38:50 +00:00
|
|
|
|
2015-04-30 20:16:09 +00:00
|
|
|
static int sandbox_cmdline_cb_boot(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->run_distro_boot = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(boot, 'b', 0, "Run distro boot commands");
|
|
|
|
|
2013-12-03 23:43:23 +00:00
|
|
|
static int sandbox_cmdline_cb_command(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
2012-02-15 23:51:16 +00:00
|
|
|
{
|
|
|
|
state->cmd = arg;
|
|
|
|
return 0;
|
|
|
|
}
|
2013-12-03 23:43:23 +00:00
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
|
2012-02-15 23:51:16 +00:00
|
|
|
|
2013-12-03 23:43:23 +00:00
|
|
|
static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
|
2013-04-20 08:42:41 +00:00
|
|
|
{
|
|
|
|
state->fdt_fname = arg;
|
|
|
|
return 0;
|
|
|
|
}
|
2013-12-03 23:43:23 +00:00
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
|
2013-04-20 08:42:41 +00:00
|
|
|
|
2015-01-20 03:21:34 +00:00
|
|
|
static int sandbox_cmdline_cb_default_fdt(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
const char *fmt = "%s.dtb";
|
|
|
|
char *fname;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
len = strlen(state->argv[0]) + strlen(fmt) + 1;
|
2021-02-06 16:57:33 +00:00
|
|
|
fname = os_malloc(len);
|
2015-01-20 03:21:34 +00:00
|
|
|
if (!fname)
|
|
|
|
return -ENOMEM;
|
|
|
|
snprintf(fname, len, fmt, state->argv[0]);
|
|
|
|
state->fdt_fname = fname;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0,
|
|
|
|
"Use the default u-boot.dtb control FDT in U-Boot directory");
|
|
|
|
|
2019-09-25 14:56:07 +00:00
|
|
|
static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
2022-09-07 02:27:08 +00:00
|
|
|
char buf[256];
|
2019-09-25 14:56:07 +00:00
|
|
|
char *fname;
|
|
|
|
int len;
|
|
|
|
|
2022-09-07 02:27:08 +00:00
|
|
|
len = state_get_rel_filename("arch/sandbox/dts/test.dtb", buf,
|
|
|
|
sizeof(buf));
|
|
|
|
if (len < 0)
|
|
|
|
return len;
|
|
|
|
|
2021-02-06 16:57:33 +00:00
|
|
|
fname = os_malloc(len);
|
2019-09-25 14:56:07 +00:00
|
|
|
if (!fname)
|
|
|
|
return -ENOMEM;
|
2022-09-07 02:27:08 +00:00
|
|
|
strcpy(fname, buf);
|
2019-09-25 14:56:07 +00:00
|
|
|
state->fdt_fname = fname;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(test_fdt, 'T', 0,
|
|
|
|
"Use the test.dtb control FDT in U-Boot directory");
|
|
|
|
|
2013-11-10 17:27:02 +00:00
|
|
|
static int sandbox_cmdline_cb_interactive(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->interactive = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode");
|
|
|
|
|
2014-02-27 20:26:16 +00:00
|
|
|
static int sandbox_cmdline_cb_jump(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
2014-02-27 20:26:23 +00:00
|
|
|
/* Remember to delete this U-Boot image later */
|
|
|
|
state->jumped_fname = arg;
|
2014-02-27 20:26:16 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(jump, 'j', 1, "Jumped from previous U-Boot");
|
|
|
|
|
2022-10-21 00:23:02 +00:00
|
|
|
static int sandbox_cmdline_cb_program(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Record the program name to use when jumping to future phases. This
|
|
|
|
* is the original executable which holds all the phases. We need to
|
|
|
|
* use this instead of argv[0] since each phase is started by
|
|
|
|
* extracting a particular binary from the full program, then running
|
|
|
|
* it. Therefore in that binary, argv[0] contains only the
|
|
|
|
* current-phase executable.
|
|
|
|
*
|
|
|
|
* For example, sandbox TPL may be started using image file:
|
|
|
|
*
|
|
|
|
* ./image.bin
|
|
|
|
*
|
|
|
|
* but then TPL needs to run VPL, which it does by extracting the VPL
|
|
|
|
* image from the image.bin file.
|
|
|
|
*
|
|
|
|
* ./temp-vpl
|
|
|
|
*
|
|
|
|
* When VPL runs it needs access to the original image.bin so it can
|
|
|
|
* extract the next phase (SPL). This works if we use '-f image.bin'
|
|
|
|
* when starting the original image.bin file.
|
|
|
|
*/
|
|
|
|
state->prog_fname = arg;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(program, 'p', 1, "U-Boot program name");
|
|
|
|
|
2013-11-10 17:27:03 +00:00
|
|
|
static int sandbox_cmdline_cb_memory(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
/* For now assume we always want to write it */
|
|
|
|
state->write_ram_buf = true;
|
|
|
|
state->ram_buf_fname = arg;
|
|
|
|
|
2014-11-11 19:47:08 +00:00
|
|
|
err = os_read_ram_buf(arg);
|
|
|
|
if (err) {
|
2018-10-01 17:55:12 +00:00
|
|
|
printf("Failed to read RAM buffer '%s': %d\n", arg, err);
|
2013-11-10 17:27:03 +00:00
|
|
|
return err;
|
|
|
|
}
|
2018-11-24 04:29:29 +00:00
|
|
|
state->ram_buf_read = true;
|
2013-11-10 17:27:03 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1,
|
|
|
|
"Read/write ram_buf memory contents from file");
|
|
|
|
|
2014-02-27 20:26:23 +00:00
|
|
|
static int sandbox_cmdline_cb_rm_memory(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->ram_buf_rm = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT(rm_memory, 0, "Remove memory file after reading");
|
|
|
|
|
2013-11-10 17:27:04 +00:00
|
|
|
static int sandbox_cmdline_cb_state(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->state_fname = arg;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(state, 's', 1, "Specify the sandbox state FDT");
|
|
|
|
|
|
|
|
static int sandbox_cmdline_cb_read(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->read_state = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(read, 'r', 0, "Read the state FDT on startup");
|
|
|
|
|
|
|
|
static int sandbox_cmdline_cb_write(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->write_state = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(write, 'w', 0, "Write state FDT on exit");
|
|
|
|
|
|
|
|
static int sandbox_cmdline_cb_ignore_missing(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->ignore_missing_state_on_read = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(ignore_missing, 'n', 0,
|
|
|
|
"Ignore missing state on read");
|
|
|
|
|
2014-02-27 20:26:19 +00:00
|
|
|
static int sandbox_cmdline_cb_show_lcd(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->show_lcd = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0,
|
|
|
|
"Show the sandbox LCD display");
|
|
|
|
|
2020-02-03 14:36:13 +00:00
|
|
|
static int sandbox_cmdline_cb_double_lcd(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->double_lcd = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(double_lcd, 'K', 0,
|
|
|
|
"Double the LCD display size in each direction");
|
|
|
|
|
2014-02-27 20:26:22 +00:00
|
|
|
static const char *term_args[STATE_TERM_COUNT] = {
|
|
|
|
"raw-with-sigs",
|
|
|
|
"raw",
|
|
|
|
"cooked",
|
|
|
|
};
|
|
|
|
|
|
|
|
static int sandbox_cmdline_cb_terminal(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < STATE_TERM_COUNT; i++) {
|
|
|
|
if (!strcmp(arg, term_args[i])) {
|
|
|
|
state->term_raw = i;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("Unknown terminal setting '%s' (", arg);
|
|
|
|
for (i = 0; i < STATE_TERM_COUNT; i++)
|
|
|
|
printf("%s%s", i ? ", " : "", term_args[i]);
|
|
|
|
puts(")\n");
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(terminal, 't', 1,
|
|
|
|
"Set terminal to raw/cooked mode");
|
|
|
|
|
2015-11-09 06:47:50 +00:00
|
|
|
static int sandbox_cmdline_cb_verbose(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->show_test_output = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(verbose, 'v', 0, "Show test output");
|
|
|
|
|
2018-10-01 17:55:11 +00:00
|
|
|
static int sandbox_cmdline_cb_log_level(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->default_log_level = simple_strtol(arg, NULL, 10);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(log_level, 'L', 1,
|
|
|
|
"Set log level (0=panic, 7=debug)");
|
|
|
|
|
2020-10-26 02:38:28 +00:00
|
|
|
static int sandbox_cmdline_cb_unittests(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->run_unittests = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(unittests, 'u', 0, "Run unit tests");
|
|
|
|
|
2020-10-26 02:38:33 +00:00
|
|
|
static int sandbox_cmdline_cb_select_unittests(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->select_unittests = arg;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(select_unittests, 'k', 1, "Select unit tests to run");
|
|
|
|
|
2021-03-22 05:21:01 +00:00
|
|
|
static int sandbox_cmdline_cb_signals(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->handle_signals = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT_SHORT(signals, 'S', 0,
|
|
|
|
"Handle signals (such as SIGSEGV) in sandbox");
|
|
|
|
|
2021-07-24 21:14:39 +00:00
|
|
|
static int sandbox_cmdline_cb_autoboot_keyed(struct sandbox_state *state,
|
|
|
|
const char *arg)
|
|
|
|
{
|
|
|
|
state->autoboot_keyed = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
SANDBOX_CMDLINE_OPT(autoboot_keyed, 0, "Allow keyed autoboot");
|
|
|
|
|
2017-03-28 16:27:16 +00:00
|
|
|
static void setup_ram_buf(struct sandbox_state *state)
|
|
|
|
{
|
2018-11-24 04:29:29 +00:00
|
|
|
/* Zero the RAM buffer if we didn't read it, to keep valgrind happy */
|
2019-04-08 19:20:43 +00:00
|
|
|
if (!state->ram_buf_read)
|
2018-11-24 04:29:29 +00:00
|
|
|
memset(state->ram_buf, '\0', state->ram_size);
|
|
|
|
|
2017-03-28 16:27:16 +00:00
|
|
|
gd->arch.ram_buf = state->ram_buf;
|
|
|
|
gd->ram_size = state->ram_size;
|
|
|
|
}
|
|
|
|
|
2018-11-16 01:44:03 +00:00
|
|
|
void state_show(struct sandbox_state *state)
|
|
|
|
{
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
printf("Arguments:\n");
|
|
|
|
for (p = state->argv; *p; p++)
|
|
|
|
printf("%s ", *p);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2020-12-02 15:22:11 +00:00
|
|
|
void __efi_runtime EFIAPI efi_reset_system(
|
|
|
|
enum efi_reset_type reset_type,
|
|
|
|
efi_status_t reset_status,
|
|
|
|
unsigned long data_size, void *reset_data)
|
|
|
|
{
|
2021-11-20 13:49:18 +00:00
|
|
|
if (reset_type == EFI_RESET_SHUTDOWN)
|
|
|
|
sandbox_exit();
|
|
|
|
else
|
|
|
|
sandbox_reset();
|
2020-12-02 15:22:11 +00:00
|
|
|
}
|
|
|
|
|
2020-10-27 19:29:25 +00:00
|
|
|
void sandbox_reset(void)
|
|
|
|
{
|
|
|
|
/* Do this here while it still has an effect */
|
|
|
|
os_fd_restore();
|
|
|
|
if (state_uninit())
|
|
|
|
os_exit(2);
|
|
|
|
|
|
|
|
/* Restart U-Boot */
|
|
|
|
os_relaunch(os_argv);
|
|
|
|
}
|
|
|
|
|
2022-05-30 10:00:10 +00:00
|
|
|
int sandbox_main(int argc, char *argv[])
|
2011-10-03 19:26:45 +00:00
|
|
|
{
|
2012-02-15 23:51:16 +00:00
|
|
|
struct sandbox_state *state;
|
2021-05-15 17:29:13 +00:00
|
|
|
void * text_base;
|
2014-07-11 04:23:27 +00:00
|
|
|
gd_t data;
|
2021-02-06 16:57:33 +00:00
|
|
|
int size;
|
2013-11-10 17:27:04 +00:00
|
|
|
int ret;
|
2012-02-15 23:51:15 +00:00
|
|
|
|
2021-05-15 17:29:13 +00:00
|
|
|
text_base = os_find_text_base();
|
|
|
|
|
2021-05-11 19:03:16 +00:00
|
|
|
/*
|
|
|
|
* This must be the first invocation of os_malloc() to have
|
|
|
|
* state->ram_buf in the low 4 GiB.
|
|
|
|
*/
|
|
|
|
ret = state_init();
|
|
|
|
if (ret)
|
|
|
|
goto err;
|
|
|
|
|
2020-10-27 19:29:25 +00:00
|
|
|
/*
|
|
|
|
* Copy argv[] so that we can pass the arguments in the original
|
|
|
|
* sequence when resetting the sandbox.
|
|
|
|
*/
|
2021-02-06 16:57:33 +00:00
|
|
|
size = sizeof(char *) * (argc + 1);
|
|
|
|
os_argv = os_malloc(size);
|
2020-10-27 19:29:25 +00:00
|
|
|
if (!os_argv)
|
|
|
|
os_exit(1);
|
2021-02-06 16:57:33 +00:00
|
|
|
memcpy(os_argv, argv, size);
|
2020-10-27 19:29:25 +00:00
|
|
|
|
2019-04-08 19:20:41 +00:00
|
|
|
memset(&data, '\0', sizeof(data));
|
|
|
|
gd = &data;
|
2021-05-15 17:29:13 +00:00
|
|
|
gd->arch.text_base = text_base;
|
2019-04-08 19:20:41 +00:00
|
|
|
|
2012-02-15 23:51:16 +00:00
|
|
|
state = state_get_current();
|
|
|
|
if (os_parse_args(state, argc, argv))
|
|
|
|
return 1;
|
|
|
|
|
2020-11-20 08:48:33 +00:00
|
|
|
/* Remove old memory file if required */
|
|
|
|
if (state->ram_buf_rm && state->ram_buf_fname) {
|
|
|
|
os_unlink(state->ram_buf_fname);
|
|
|
|
state->write_ram_buf = false;
|
|
|
|
state->ram_buf_fname = NULL;
|
|
|
|
}
|
|
|
|
|
2013-11-10 17:27:04 +00:00
|
|
|
ret = sandbox_read_state(state, state->state_fname);
|
|
|
|
if (ret)
|
|
|
|
goto err;
|
|
|
|
|
2021-03-22 05:21:01 +00:00
|
|
|
if (state->handle_signals) {
|
|
|
|
ret = os_setup_signal_handlers();
|
|
|
|
if (ret)
|
|
|
|
goto err;
|
|
|
|
}
|
2020-11-11 23:29:56 +00:00
|
|
|
|
2017-07-24 09:49:59 +00:00
|
|
|
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
|
2014-07-11 04:23:31 +00:00
|
|
|
gd->malloc_base = CONFIG_MALLOC_F_ADDR;
|
2018-10-01 17:55:11 +00:00
|
|
|
#endif
|
|
|
|
#if CONFIG_IS_ENABLED(LOG)
|
|
|
|
gd->default_log_level = state->default_log_level;
|
2014-07-11 04:23:31 +00:00
|
|
|
#endif
|
2017-03-28 16:27:16 +00:00
|
|
|
setup_ram_buf(state);
|
2014-07-11 04:23:27 +00:00
|
|
|
|
2019-04-08 19:20:41 +00:00
|
|
|
/*
|
|
|
|
* Set up the relocation offset here, since sandbox symbols are always
|
|
|
|
* relocated by the OS before sandbox is entered.
|
|
|
|
*/
|
|
|
|
gd->reloc_off = (ulong)gd->arch.text_base;
|
|
|
|
|
2020-11-27 10:20:55 +00:00
|
|
|
/* sandbox test: log functions called before log_init in board_init_f */
|
|
|
|
log_debug("debug: %s\n", __func__);
|
|
|
|
|
2013-11-10 17:26:59 +00:00
|
|
|
/* Do pre- and post-relocation init */
|
2011-10-03 19:26:45 +00:00
|
|
|
board_init_f(0);
|
2013-01-22 13:11:21 +00:00
|
|
|
|
2013-11-10 17:26:59 +00:00
|
|
|
board_init_r(gd->new_gd, 0);
|
|
|
|
|
|
|
|
/* NOTREACHED - board_init_r() does not return */
|
2013-01-22 13:11:21 +00:00
|
|
|
return 0;
|
2013-11-10 17:27:04 +00:00
|
|
|
|
|
|
|
err:
|
|
|
|
printf("Error %d\n", ret);
|
|
|
|
return 1;
|
2011-10-03 19:26:45 +00:00
|
|
|
}
|