[U-Boot] [PATCH 1/6] Add an info word to commands

Simon Glass sjg at chromium.org
Mon Mar 24 16:51:06 CET 2014


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 at 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 */
-- 
1.9.1.423.g4596e3a



More information about the U-Boot mailing list