+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011-2012 The Chromium OS Authors.
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <command.h>
#include <errno.h>
+#include <init.h>
#include <os.h>
#include <cli.h>
-#include <malloc.h>
+#include <sort.h>
#include <asm/getopt.h>
#include <asm/io.h>
+#include <asm/malloc.h>
#include <asm/sections.h>
#include <asm/state.h>
+#include <linux/ctype.h>
DECLARE_GLOBAL_DATA_PTR;
+/* 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);
+}
+
int sandbox_early_getopt_check(void)
{
struct sandbox_state *state = state_get_current();
size_t num_options = __u_boot_sandbox_option_count();
size_t i;
int max_arg_len, max_noarg_len;
+ struct sandbox_cmdline_option **sorted_opt;
+ int size;
/* parse_err will be a string of the faulting option */
if (!state->parse_err)
max_arg_len = max((int)strlen(sb_opt[i]->flag), max_arg_len);
max_noarg_len = max_arg_len + 7;
+ /* Sort the options */
+ size = sizeof(*sorted_opt) * num_options;
+ sorted_opt = malloc(size);
+ 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);
+
for (i = 0; i < num_options; ++i) {
- struct sandbox_cmdline_option *opt = sb_opt[i];
+ struct sandbox_cmdline_option *opt = sorted_opt[i];
/* first output the short flag if it has one */
if (opt->flag_short >= 0x100)
os_exit(0);
}
+int misc_init_f(void)
+{
+ return sandbox_early_getopt_check();
+}
+
static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)
{
/* just flag to sandbox_early_getopt_check to show usage */
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
- fname = os_malloc(len);
+ fname = malloc(len);
if (!fname)
return -ENOMEM;
snprintf(fname, len, fmt, state->argv[0]);
SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0,
"Use the default u-boot.dtb control FDT in U-Boot directory");
+static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
+ const char *arg)
+{
+ const char *fmt = "/arch/sandbox/dts/test.dtb";
+ char *p;
+ char *fname;
+ int len;
+
+ len = strlen(state->argv[0]) + strlen(fmt) + 1;
+ fname = malloc(len);
+ if (!fname)
+ return -ENOMEM;
+ strcpy(fname, state->argv[0]);
+ p = strrchr(fname, '/');
+ if (!p)
+ p = fname + strlen(fname);
+ len -= p - fname;
+ snprintf(p, len, fmt, p);
+ state->fdt_fname = fname;
+
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(test_fdt, 'T', 0,
+ "Use the test.dtb control FDT in U-Boot directory");
+
static int sandbox_cmdline_cb_interactive(struct sandbox_state *state,
const char *arg)
{
err = os_read_ram_buf(arg);
if (err) {
- printf("Failed to read RAM buffer\n");
+ printf("Failed to read RAM buffer '%s': %d\n", arg, err);
return err;
}
+ state->ram_buf_read = true;
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0,
"Show the sandbox LCD display");
+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");
+
static const char *term_args[STATE_TERM_COUNT] = {
"raw-with-sigs",
"raw",
}
SANDBOX_CMDLINE_OPT_SHORT(verbose, 'v', 0, "Show test output");
-int board_run_command(const char *cmdline)
+static int sandbox_cmdline_cb_log_level(struct sandbox_state *state,
+ const char *arg)
{
- printf("## Commands are disabled. Please enable CONFIG_CMDLINE.\n");
+ state->default_log_level = simple_strtol(arg, NULL, 10);
- return 1;
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(log_level, 'L', 1,
+ "Set log level (0=panic, 7=debug)");
+
+static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state,
+ const char *arg)
+{
+ state->show_of_platdata = true;
+
+ return 0;
+}
+SANDBOX_CMDLINE_OPT(show_of_platdata, 0, "Show of-platdata in SPL");
+
+static void setup_ram_buf(struct sandbox_state *state)
+{
+ /* Zero the RAM buffer if we didn't read it, to keep valgrind happy */
+ if (!state->ram_buf_read)
+ memset(state->ram_buf, '\0', state->ram_size);
+
+ gd->arch.ram_buf = state->ram_buf;
+ gd->ram_size = state->ram_size;
+}
+
+void state_show(struct sandbox_state *state)
+{
+ char **p;
+
+ printf("Arguments:\n");
+ for (p = state->argv; *p; p++)
+ printf("%s ", *p);
+ printf("\n");
}
int main(int argc, char *argv[])
gd_t data;
int ret;
+ memset(&data, '\0', sizeof(data));
+ gd = &data;
+ gd->arch.text_base = os_find_text_base();
+
ret = state_init();
if (ret)
goto err;
if (ret)
goto err;
- /* Remove old memory file if required */
- if (state->ram_buf_rm && state->ram_buf_fname)
- os_unlink(state->ram_buf_fname);
-
- memset(&data, '\0', sizeof(data));
- gd = &data;
-#ifdef CONFIG_SYS_MALLOC_F_LEN
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
gd->malloc_base = CONFIG_MALLOC_F_ADDR;
#endif
+#if CONFIG_IS_ENABLED(LOG)
+ gd->default_log_level = state->default_log_level;
+#endif
+ setup_ram_buf(state);
+
+ /*
+ * 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;
/* Do pre- and post-relocation init */
board_init_f(0);