
In cmd_bootm.c the function pointer is misused as a flags word. It is better to add a flag word to each command, so that bootm can avoid this hack.
To avoid increasing the size of the U-Boot binary, we can re-use the existing 'repeatable' flag, which only needs a single bit.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/cmd_bootm.c | 35 ++++++++++++++++++++++------------- common/cmd_nvedit.c | 10 +++++----- common/command.c | 3 ++- include/command.h | 41 +++++++++++++++++++++++++++++++---------- 4 files changed, 60 insertions(+), 29 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9751edc..14d504b 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -522,19 +522,28 @@ static int do_bootm_standalone(int flag, int argc, char * const argv[], /* we overload the cmd field with our state machine info instead of a * function pointer */ static cmd_tbl_t cmd_bootm_sub[] = { - U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""), - U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""), + U_BOOT_CMD_MKENT_COMPLETE(start, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_START), + U_BOOT_CMD_MKENT_COMPLETE(loados, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_LOADOS), #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH - U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""), + U_BOOT_CMD_MKENT_COMPLETE(ramdisk, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_RAMDISK), #endif #ifdef CONFIG_OF_LIBFDT - U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""), -#endif - U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""), - U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""), - U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""), - U_BOOT_CMD_MKENT(fake, 0, 1, (void *)BOOTM_STATE_OS_FAKE_GO, "", ""), - U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""), + U_BOOT_CMD_MKENT_COMPLETE(fdt, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_FDT), +#endif + U_BOOT_CMD_MKENT_COMPLETE(cmdline, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_CMDLINE), + U_BOOT_CMD_MKENT_COMPLETE(bdt, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_BD_T), + U_BOOT_CMD_MKENT_COMPLETE(prep, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_PREP), + U_BOOT_CMD_MKENT_COMPLETE(fake, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_FAKE_GO), + U_BOOT_CMD_MKENT_COMPLETE(go, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_GO), };
static int boot_selected_os(int argc, char * const argv[], int state, @@ -752,9 +761,7 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, argc--; argv++;
if (c) { - state = (long)c->cmd; - if (state == BOOTM_STATE_START) - state |= BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER; + state = cmd_get_info(c); } else { /* Unrecognized command */ return CMD_RET_USAGE; @@ -765,6 +772,8 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, return CMD_RET_USAGE; }
+ if (state == BOOTM_STATE_START) + state |= BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER; ret = do_bootm_states(cmdtp, flag, argc, argv, state, &images, 0);
return ret; diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index c53601c..a09263c 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -1201,7 +1201,7 @@ U_BOOT_CMD_COMPLETE( "edit environment variable", "name\n" " - edit environment variable 'name'", - var_complete + var_complete, 0 ); #endif
@@ -1211,7 +1211,7 @@ U_BOOT_CMD_COMPLETE( "[-a]\n - print [all] values of all environment variables\n" "printenv name ...\n" " - print value of environment variable 'name'", - var_complete + var_complete, 0 );
#ifdef CONFIG_CMD_GREPENV @@ -1229,7 +1229,7 @@ U_BOOT_CMD_COMPLETE( #endif " "-n": search variable names; "-v": search values;\n" " "-b": search both names and values (default)", - var_complete + var_complete, 0 ); #endif
@@ -1240,7 +1240,7 @@ U_BOOT_CMD_COMPLETE( " - [forcibly] set environment variable 'name' to 'value ...'\n" "setenv [-f] name\n" " - [forcibly] delete environment variable 'name'", - var_complete + var_complete, 0 );
#if defined(CONFIG_CMD_ASKENV) @@ -1259,7 +1259,7 @@ U_BOOT_CMD_COMPLETE( "run commands in an environment variable", "var [...]\n" " - run the commands in the environment variable(s) 'var'", - var_complete + var_complete, 0 ); #endif #endif /* CONFIG_SPL_BUILD */ diff --git a/common/command.c b/common/command.c index 746b7e3..35c9d71 100644 --- a/common/command.c +++ b/common/command.c @@ -536,7 +536,8 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[], rc = cmd_call(cmdtp, flag, argc, argv); if (ticks) *ticks = get_timer(*ticks); - *repeatable &= cmdtp->repeatable; + if (!(cmdtp->info & CMD_INFO_REPEATABLE)) + *repeatable = 0; } if (rc == CMD_RET_USAGE) rc = cmd_usage(cmdtp); diff --git a/include/command.h b/include/command.h index d3f700f..53ec853 100644 --- a/include/command.h +++ b/include/command.h @@ -24,6 +24,12 @@ #endif
#ifndef __ASSEMBLY__ +enum { + CMD_INFO_MASK = 0xffffff, /* user data */ + CMD_INFO_REPEATABLE_SHIFT = 24, /* commaand is repeatable */ + CMD_INFO_REPEATABLE = 1U << CMD_INFO_REPEATABLE_SHIFT, +}; + /* * Monitor Command Table */ @@ -31,7 +37,7 @@ struct cmd_tbl_s { char *name; /* Command Name */ int maxargs; /* maximum number of arguments */ - int repeatable; /* autorepeat allowed? */ + int info; /* CMD_INFO_... flags */ /* Implementation function */ int (*cmd)(struct cmd_tbl_s *, int, int, char * const []); char *usage; /* Usage message (short) */ @@ -46,6 +52,12 @@ struct cmd_tbl_s {
typedef struct cmd_tbl_s cmd_tbl_t;
+/* Returns the info word for a command */ +static inline int cmd_get_info(struct cmd_tbl_s *cmd) +{ + return cmd->info & CMD_INFO_MASK; +} +
#if defined(CONFIG_CMD_RUN) extern int do_run(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); @@ -141,8 +153,6 @@ enum command_ret_t { int cmd_process(int flag, int argc, char * const argv[], int *repeatable, unsigned long *ticks);
-#endif /* __ASSEMBLY__ */ - /* * Command Flags: */ @@ -161,24 +171,35 @@ int cmd_process(int flag, int argc, char * const argv[], #endif
#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp) \ - { #_name, _maxargs, _rep, _cmd, _usage, \ - _CMD_HELP(_help) _CMD_COMPLETE(_comp) } + _usage, _help, _comp, _info) \ + { #_name, _maxargs, (_rep) << CMD_INFO_REPEATABLE_SHIFT | (_info), \ + _cmd, _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
#define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, NULL) + _usage, _help, NULL, 0)
-#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \ +#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ + _comp, _info) \ ll_entry_declare(cmd_tbl_t, _name, cmd) = \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp); + _usage, _help, _comp, _info);
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \ - U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL) + U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ + NULL, 0)
#if defined(CONFIG_NEEDS_MANUAL_RELOC) void fixup_cmdtable(cmd_tbl_t *cmdtp, int size); #endif
+/* Dummy command for use in U_BOOT_CMD_MKENT() when none is needed */ +static inline int cmd_dummy(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return 0; +} + +#endif /* __ASSEMBLY__ */ + #endif /* __COMMAND_H */