bin_header_debug: add support for commands in prompt mode

	** this is patch #5 in bin_header_debug series of patches

	- add command parser in prompt mode, that run saved commands
	  and exits when "q" is entered as command
	- commands are stored in 'commands' array

Change-Id: I58e602a2eb3d289e0e3617d4388b96e1398bd64a
Signed-off-by: Bassel Saba <basselsa@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/19670
Tested-by: Star_Automation <star@marvell.com>
Reviewed-by: Omri Itach <omrii@marvell.com>
diff --git a/tools/marvell/bin_hdr/platform/Makefile b/tools/marvell/bin_hdr/platform/Makefile
index b597933..2a8e885 100755
--- a/tools/marvell/bin_hdr/platform/Makefile
+++ b/tools/marvell/bin_hdr/platform/Makefile
@@ -80,7 +80,7 @@
 CSRC_DRV = $(DRV)/mv_uart.c $(DRV)/mv_twsi.c $(DRV)/mv_time.c
 CSRC_UTILS = $(UTILS)/utils.c $(UTILS)/printf.c $(UTILS)/mvHwsSiliconIf.c
 CSRC_SYS_ENV = $(SYS_ENV)/mvSysEnvLib.c
-CSRC_BIN_HDR_DEBUG = $(BIN_HDR_DEBUG)/debug.c $(BIN_HDR_DEBUG)/lib_utils.c
+CSRC_BIN_HDR_DEBUG = $(BIN_HDR_DEBUG)/debug.c $(BIN_HDR_DEBUG)/lib_utils.c $(BIN_HDR_DEBUG)/command.c
 
 ifeq "$(CONFIG_ALLEYCAT3)"  "y"
   CSRC_UTILS += $(UTILS)/mv_seq_exec_ext.c
diff --git a/tools/marvell/bin_hdr/platform/utils/debug/command.c b/tools/marvell/bin_hdr/platform/utils/debug/command.c
new file mode 100644
index 0000000..319d230
--- /dev/null
+++ b/tools/marvell/bin_hdr/platform/utils/debug/command.c
@@ -0,0 +1,404 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+This software file (the "File") is owned and distributed by Marvell
+International Ltd. and/or its affiliates ("Marvell") under the following
+alternative licensing terms.  Once you have made an election to distribute the
+File under one of the following license alternatives, please (i) delete this
+introductory statement regarding license alternatives, (ii) delete the two
+license alternatives that you have not elected to use and (iii) preserve the
+Marvell copyright notice above.
+
+********************************************************************************
+Marvell Commercial License Option
+
+If you received this File from Marvell and you have entered into a commercial
+license agreement (a "Commercial License") with Marvell, the File is licensed
+to you under the terms of the applicable Commercial License.
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+********************************************************************************
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+	    this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+/* includes */
+
+#include "command.h"
+#include "mvUart.h"
+#include "lib_utils.h"
+#include "printf.h"
+
+int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+/* Commands Table
+ * Every new command is added here, Thus it must be declared in
+ * this file, or include the file declaring it
+ * For example, To add new command that is implemented in 'hello_world' function
+ * this line is added to the declaration:
+ *	{ "hello", 2, hello_world, "prints hello world", ""}
+ */
+cmd_tbl_t commands[] = {
+	{ "?", 2, do_help, "prints help message of command", "command-name"}
+};
+
+/* local functions definitions */
+cmd_tbl_t *find_cmd(const char *cmd);
+void cmd_usage(const cmd_tbl_t *cmdtp);
+
+/*******************************************************************************
+* do_help
+*
+* DESCRIPTION:
+* Command that prints the help message of commands
+*
+*******************************************************************************/
+int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *cmd;
+
+	if (argc <= 1)
+		return 0;
+
+	cmd = find_cmd(argv[1]);
+	if (cmd == NULL) {
+		mvPrintf("Command not found");
+		return 0;
+	}
+
+	cmd_usage(cmd);
+	return 0;
+}
+
+
+/*******************************************************************************
+* cmd_get_data_size
+*
+* DESCRIPTION:
+* Check for a size specification .b, .w or .l.
+*
+* INPUT:
+*	arg		- command (e.g. "mw.l")
+*	default_size	- default size to return if no size was specified
+*
+* RETURN:
+*	if size was specified, return corresponding size
+*		(.b = 1, .w = 2, .l = 4)
+*	otherwise, return default_size
+*
+*******************************************************************************/
+int cmd_get_data_size(char *arg, int default_size)
+{
+	int len = strlen(arg);
+	if (len > 2 && arg[len-2] == '.') {
+		switch (arg[len-1]) {
+		case 'b':
+			return 1;
+		case 'w':
+			return 2;
+		case 'l':
+			return 4;
+		case 's':
+			return -2;
+		default:
+			return -1;
+		}
+	}
+	return default_size;
+}
+
+/*******************************************************************************
+* find_cmd_tbl
+*
+* DESCRIPTION:
+* search for command in command table
+*
+* INPUT:
+*	cmd		- command (e.g. "ir")
+*	table		- commands table
+*	table_len	- commands table length
+*
+* RETURN:
+*	if command was found, cmd_tbl_t entry corresponding the command
+*	otherwise, NULL
+*
+*******************************************************************************/
+cmd_tbl_t *find_cmd_tbl(const char *cmd, cmd_tbl_t *table, int table_len)
+{
+	cmd_tbl_t *cmdtp;
+	cmd_tbl_t *cmdtp_temp = table;	/*Init value */
+	const char *p;
+	int len;
+	int n_found = 0;
+
+	if (!cmd)
+		return NULL;
+	/*
+	 * Some commands allow length modifiers (like "cp.b");
+	 * compare command name only until first dot.
+	 */
+	len = ((p = strchr(cmd, '.')) == NULL) ? strlen(cmd) : (p - cmd);
+
+	for (cmdtp = table;
+	     cmdtp != table + table_len;
+	     cmdtp++) {
+		if (strncmp(cmd, cmdtp->name, len) == 0) {
+			if (len == strlen(cmdtp->name))
+				return cmdtp;	/* full match */
+
+			cmdtp_temp = cmdtp;	/* abbreviated command ? */
+			n_found++;
+		}
+	}
+	if (n_found == 1) {			/* exactly one match */
+		return cmdtp_temp;
+	}
+
+	return NULL;	/* not found or ambiguous command */
+}
+
+/*******************************************************************************
+* find_cmd
+*
+* DESCRIPTION:
+* wrapper function for 'find_cmd_tbl'
+*
+*******************************************************************************/
+cmd_tbl_t *find_cmd(const char *cmd)
+{
+	return find_cmd_tbl(cmd, commands, sizeof(commands)/sizeof(struct cmd_tbl_s));
+}
+
+static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int result;
+
+	result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
+	return result;
+}
+
+/*******************************************************************************
+* cmd_usage
+*
+* DESCRIPTION:
+* prints the help message of the command
+*
+* INPUT:
+*	cmdtp	- command entry pointer
+*
+*
+*******************************************************************************/
+void cmd_usage(const cmd_tbl_t *cmdtp)
+{
+	mvPrintf("%s - %s\n\n", cmdtp->name, cmdtp->usage);
+	mvPrintf("Usage:\n%s ", cmdtp->name);
+
+	if (!cmdtp->help)
+		return;
+
+	mvPrintf("%s\n", cmdtp->help);
+}
+
+/*******************************************************************************
+* cmd_process
+*
+* DESCRIPTION:
+* search for command in command table and run it
+*
+* INPUT:
+*	flag	- command flag
+*	argc	- number of arguments
+*	argv	- arguments array
+*
+* RETURN:
+*	CMD_RET_SUCCESS(0), if command was ran successfully
+*	CMD_RET_FAILURE(1), on failure
+*	CMD_RET_USAGE(-1), on failure and need to print help message (future use)
+*
+*
+*******************************************************************************/
+enum command_ret_t cmd_process(int flag, int argc, char * const argv[])
+{
+	enum command_ret_t rc = CMD_RET_SUCCESS;
+	cmd_tbl_t *cmdtp;
+
+	/* Look up command in command table */
+	cmdtp = find_cmd(argv[0]);
+	if (cmdtp == NULL) {
+		putstring("Unknown command\n");
+		return 1;
+	}
+
+	/* found - check max args */
+	if (argc > cmdtp->maxargs)
+		rc = CMD_RET_USAGE;
+
+
+	/* If OK so far, then do the command */
+	if (!rc)
+		rc = cmd_call(cmdtp, flag, argc, argv);
+
+	if (rc == CMD_RET_USAGE)
+		cmd_usage(cmdtp);
+
+	return rc;
+}
+
+/*******************************************************************************
+* parse_line
+*
+* DESCRIPTION:
+* parse command and store arguments in argv
+*
+* INPUT:
+*	line	- pointer to the beginning of the command string
+*
+* OUTPUT:
+*	argv	- output array of the parsed arguments
+*
+* RETURN:
+*	number of arguments
+*
+*******************************************************************************/
+int parse_line(char *line, char *argv[])
+{
+	int nargs = 0;
+
+	while (nargs < CONFIG_SYS_MAXARGS) {
+
+		/* skip any white space */
+		while (isblank1(*line))
+			++line;
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		argv[nargs++] = line;	/* begin of argument string	*/
+
+		/* find end of string */
+		while (*line && !isblank1(*line))
+			++line;
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		*line++ = '\0';		/* terminate current arg	 */
+	}
+
+	putstring("** Too many args **\n");
+
+	return nargs;
+}
+
+/*******************************************************************************
+* run_command
+*
+* DESCRIPTION:
+* runs input command
+*
+* INPUT:
+*	cmd	- input command string to run (including parameters).
+*	flag	- command flag
+*
+*******************************************************************************/
+void run_command(const char *cmd, int flag)
+{
+	char cmdbuf[CONFIG_SYS_CBSIZE];	/* working copy of cmd		*/
+	char *token;			/* start of token in cmdbuf	*/
+	char *sep;			/* end of token (separator) in cmdbuf */
+	char *str = cmdbuf;
+	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated	*/
+	int argc, inquotes;
+
+	if (!cmd || !*cmd)
+		return;	/* empty command */
+
+	if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {
+		putstring("## Command too long!\n");
+		return;
+	}
+
+	strcpy(cmdbuf, cmd);
+
+	/* Process separators */
+
+	while (*str) {
+
+		/*
+		 * Find separator, or string end
+		 * Allow simple escape of ';' by writing "\;"
+		 */
+		for (inquotes = 0, sep = str; *sep; sep++) {
+			if ((*sep == '\'') &&
+			    (*(sep - 1) != '\\'))
+				inquotes = !inquotes;
+
+			if (!inquotes &&
+			    (*sep == ';') &&	/* separator		*/
+			    (sep != str) &&	/* past string start	*/
+			    (*(sep-1) != '\\'))	/* and NOT escaped	*/
+				break;
+		}
+
+		/*
+		 * Limit the token to data between separators
+		 */
+		token = str;
+		if (*sep) {
+			str = sep + 1;	/* start of command for next pass */
+			*sep = '\0';
+		} else
+			str = sep;	/* no more commands for next pass */
+
+		/* Extract arguments */
+		argc = parse_line(token, argv);
+		if (argc == 0)
+			continue;
+
+		cmd_process(flag, argc, argv);
+	}
+}
+
diff --git a/tools/marvell/bin_hdr/platform/utils/debug/command.h b/tools/marvell/bin_hdr/platform/utils/debug/command.h
new file mode 100644
index 0000000..f4d2b90
--- /dev/null
+++ b/tools/marvell/bin_hdr/platform/utils/debug/command.h
@@ -0,0 +1,91 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+This software file (the "File") is owned and distributed by Marvell
+International Ltd. and/or its affiliates ("Marvell") under the following
+alternative licensing terms.  Once you have made an election to distribute the
+File under one of the following license alternatives, please (i) delete this
+introductory statement regarding license alternatives, (ii) delete the two
+license alternatives that you have not elected to use and (iii) preserve the
+Marvell copyright notice above.
+
+********************************************************************************
+Marvell Commercial License Option
+
+If you received this File from Marvell and you have entered into a commercial
+license agreement (a "Commercial License") with Marvell, the File is licensed
+to you under the terms of the applicable Commercial License.
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+********************************************************************************
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+	    this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+	used to endorse or promote products derived from this software without
+	specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include "mv_os.h"
+#include "mvUart.h"
+
+#define CONFIG_SYS_MAXARGS 8
+
+struct cmd_tbl_s {
+	char		*name;		/* Command Name			*/
+	int		maxargs;	/* maximum number of arguments	*/
+					/* Implementation function	*/
+	int		(*cmd)(struct cmd_tbl_s *, int, int, char * const []);
+	char		*usage;		/* Usage message	(short)	*/
+	char		*help;		/* Usage message	(long)	*/
+};
+
+enum command_ret_t {
+	CMD_RET_SUCCESS,	/* 0 = Success */
+	CMD_RET_FAILURE,	/* 1 = Failure */
+	CMD_RET_USAGE = -1,	/* Failure, please report 'usage' error */
+};
+
+typedef struct cmd_tbl_s cmd_tbl_t;
+
+int cmd_get_data_size(char *arg, int default_size);
+
+void run_command(const char *cmd, int flag);
+
+
diff --git a/tools/marvell/bin_hdr/platform/utils/debug/debug.c b/tools/marvell/bin_hdr/platform/utils/debug/debug.c
index 0064797..47830cf 100644
--- a/tools/marvell/bin_hdr/platform/utils/debug/debug.c
+++ b/tools/marvell/bin_hdr/platform/utils/debug/debug.c
@@ -68,9 +68,19 @@
 #include "mvUart.h"
 #include "printf.h"
 #include "mvSysEnvLib.h"
+#include "command.h"
+#include "lib_utils.h"
 
 MV_STATUS mvBinHeaderDebugPrompt(void)
 {
+	putstring("\nPrompt mode\n");
+	while (1) {
+		readline("Marvell_Debug>> ");
+		if (strcmp(console_buffer, "q") == 0)
+			break;
+
+		run_command(console_buffer, 0);
+	}
 	return MV_OK;
 }