#include <common.h>
#include <watchdog.h>
#include <command.h>
+#include <version.h>
#ifdef CONFIG_MODEM_SUPPORT
#include <malloc.h> /* for free() prototype */
#endif
#endif
#include <post.h>
+#include <linux/ctype.h>
+#include <menu.h>
#if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING)
DECLARE_GLOBAL_DATA_PTR;
void inline __show_boot_progress (int val) {}
void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
-#if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY)
-extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* for do_reset() prototype */
-#endif
-
-extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-
#if defined(CONFIG_UPDATE_TFTP)
-void update_tftp (void);
+int update_tftp (ulong addr);
#endif /* CONFIG_UPDATE_TFTP */
#define MAX_DELAY_STOP_STR 32
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
-static int abortboot(int);
-#endif
-
#undef DEBUG_PARSER
-char console_buffer[CONFIG_SYS_CBSIZE]; /* console I/O buffer */
+char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */
static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
-static char erase_seq[] = "\b \b"; /* erase sequence */
-static char tab_seq[] = " "; /* used to expand TABs */
+static const char erase_seq[] = "\b \b"; /* erase sequence */
+static const char tab_seq[] = " "; /* used to expand TABs */
#ifdef CONFIG_BOOT_RETRY_TIME
static uint64_t endtime = 0; /* must be set, default is instant timeout */
/***************************************************************************
* Watch for 'delay' seconds for autoboot stop or autoboot delay string.
- * returns: 0 - no key string, allow autoboot
- * 1 - got key string, abort
+ * returns: 0 - no key string, allow autoboot 1 - got key string, abort
*/
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
# if defined(CONFIG_AUTOBOOT_KEYED)
-static __inline__ int abortboot(int bootdelay)
+#ifndef CONFIG_MENU
+static inline
+#endif
+int abortboot(int bootdelay)
{
int abort = 0;
uint64_t etime = endtick(bootdelay);
static int menukey = 0;
#endif
-static __inline__ int abortboot(int bootdelay)
+#ifndef CONFIG_MENU
+static inline
+#endif
+int abortboot(int bootdelay)
{
int abort = 0;
char bcs_set[16];
#endif /* CONFIG_BOOTCOUNT_LIMIT */
-#if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)
- ulong bmp = 0; /* default bitmap */
- extern int trab_vfd (ulong bitmap);
-
-#ifdef CONFIG_MODEM_SUPPORT
- if (do_mdm_init)
- bmp = 1; /* alternate bitmap */
-#endif
- trab_vfd (bmp);
-#endif /* CONFIG_VFD && VFD_TEST_LOGO */
-
-#if defined(CONFIG_UPDATE_TFTP)
- update_tftp ();
-#endif /* CONFIG_UPDATE_TFTP */
-
#ifdef CONFIG_BOOTCOUNT_LIMIT
bootcount = bootcount_load();
bootcount++;
#ifdef CONFIG_VERSION_VARIABLE
{
- extern char version_string[];
-
setenv ("ver", version_string); /* set version variable */
}
#endif /* CONFIG_VERSION_VARIABLE */
hush_init_var ();
#endif
-#ifdef CONFIG_AUTO_COMPLETE
- install_auto_complete();
-#endif
-
#ifdef CONFIG_PREBOOT
if ((p = getenv ("preboot")) != NULL) {
# ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif
-# ifndef CONFIG_SYS_HUSH_PARSER
- run_command (p, 0);
-# else
- parse_string_outer(p, FLAG_PARSE_SEMICOLON |
- FLAG_EXIT_FROM_LOOP);
-# endif
+ run_command(p, 0);
# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
}
#endif /* CONFIG_PREBOOT */
+#if defined(CONFIG_UPDATE_TFTP)
+ update_tftp (0UL);
+#endif /* CONFIG_UPDATE_TFTP */
+
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
+#if defined(CONFIG_MENU_SHOW)
+ bootdelay = menu_show(bootdelay);
+#endif
# ifdef CONFIG_BOOT_RETRY_TIME
init_cmd_timeout ();
# endif /* CONFIG_BOOT_RETRY_TIME */
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif
-# ifndef CONFIG_SYS_HUSH_PARSER
- run_command (s, 0);
-# else
- parse_string_outer(s, FLAG_PARSE_SEMICOLON |
- FLAG_EXIT_FROM_LOOP);
-# endif
+ run_command(s, 0);
# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
# ifdef CONFIG_MENUKEY
if (menukey == CONFIG_MENUKEY) {
- s = getenv("menucmd");
- if (s) {
-# ifndef CONFIG_SYS_HUSH_PARSER
- run_command (s, 0);
-# else
- parse_string_outer(s, FLAG_PARSE_SEMICOLON |
- FLAG_EXIT_FROM_LOOP);
-# endif
- }
+ s = getenv("menucmd");
+ if (s)
+ run_command(s, 0);
}
#endif /* CONFIG_MENUKEY */
-#endif /* CONFIG_BOOTDELAY */
-
-#ifdef CONFIG_AMIGAONEG3SE
- {
- extern void video_banner(void);
- video_banner();
- }
-#endif
+#endif /* CONFIG_BOOTDELAY */
/*
* Main Loop for Monitor Command Processing
if (len == -1)
puts ("<INTERRUPT>\n");
else
- rc = run_command (lastcommand, flag);
+ rc = run_command(lastcommand, flag);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
} while (0)
#define CTL_CH(c) ((c) - 'a' + 1)
-
-#define MAX_CMDBUF_SIZE 256
-
#define CTL_BACKSPACE ('\b')
#define DEL ((char)255)
#define DEL7 ((char)127)
#define getcmd_cbeep() getcmd_putch('\a')
#define HIST_MAX 20
-#define HIST_SIZE MAX_CMDBUF_SIZE
+#define HIST_SIZE CONFIG_SYS_CBSIZE
static int hist_max = 0;
static int hist_add_idx = 0;
unsigned hist_num = 0;
char* hist_list[HIST_MAX];
-char hist_lines[HIST_MAX][HIST_SIZE];
+char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */
#define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1)
#define ERASE_TO_EOL() { \
if (num < eol_num) { \
- int tmp; \
- for (tmp = num; tmp < eol_num; tmp++) \
- getcmd_putch(' '); \
- while (tmp-- > num) \
+ printf("%*s", (int)(eol_num - num), ""); \
+ do { \
getcmd_putch(CTL_BACKSPACE); \
- eol_num = num; \
+ } while (--eol_num > num); \
} \
}
}
}
-static int cread_line(const char *const prompt, char *buf, unsigned int *len)
+static int cread_line(const char *const prompt, char *buf, unsigned int *len,
+ int timeout)
{
unsigned long num = 0;
unsigned long eol_num = 0;
- unsigned long rlen;
unsigned long wlen;
char ichar;
int insert = 1;
int esc_len = 0;
- int rc = 0;
char esc_save[8];
+ int init_len = strlen(buf);
+ int first = 1;
+
+ if (init_len)
+ cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len);
while (1) {
- rlen = 1;
#ifdef CONFIG_BOOT_RETRY_TIME
while (!tstc()) { /* while no incoming data */
if (retry_time >= 0 && get_ticks() > endtime)
return (-2); /* timed out */
+ WATCHDOG_RESET();
}
#endif
+ if (first && timeout) {
+ uint64_t etime = endtick(timeout);
+
+ while (!tstc()) { /* while no incoming data */
+ if (get_ticks() >= etime)
+ return -2; /* timed out */
+ WATCHDOG_RESET();
+ }
+ first = 0;
+ }
ichar = getcmd_getch();
cread_add_to_hist(buf);
hist_cur = hist_add_idx;
- return (rc);
+ return 0;
}
#endif /* CONFIG_CMDLINE_EDITING */
*/
int readline (const char *const prompt)
{
- return readline_into_buffer(prompt, console_buffer);
+ /*
+ * If console_buffer isn't 0-length the user will be prompted to modify
+ * it instead of entering it from scratch as desired.
+ */
+ console_buffer[0] = '\0';
+
+ return readline_into_buffer(prompt, console_buffer, 0);
}
-int readline_into_buffer (const char *const prompt, char * buffer)
+int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
{
char *p = buffer;
#ifdef CONFIG_CMDLINE_EDITING
- unsigned int len=MAX_CMDBUF_SIZE;
+ unsigned int len = CONFIG_SYS_CBSIZE;
int rc;
static int initted = 0;
initted = 1;
}
- puts (prompt);
+ if (prompt)
+ puts (prompt);
- rc = cread_line(prompt, p, &len);
+ rc = cread_line(prompt, p, &len, timeout);
return rc < 0 ? rc : len;
} else {
while (!tstc()) { /* while no incoming data */
if (retry_time >= 0 && get_ticks() > endtime)
return (-2); /* timed out */
+ WATCHDOG_RESET();
}
#endif
WATCHDOG_RESET(); /* Trigger watchdog, if needed */
while (!tstc()) {
extern void show_activity(int arg);
show_activity(0);
+ WATCHDOG_RESET();
}
#endif
c = getc();
while (nargs < CONFIG_SYS_MAXARGS) {
/* skip any white space */
- while ((*line == ' ') || (*line == '\t')) {
+ while (isblank(*line))
++line;
- }
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
argv[nargs++] = line; /* begin of argument string */
/* find end of string */
- while (*line && (*line != ' ') && (*line != '\t')) {
+ while (*line && !isblank(*line))
++line;
- }
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
/****************************************************************************/
+#ifndef CONFIG_SYS_HUSH_PARSER
static void process_macros (const char *input, char *output)
{
char c, prev;
* the environment data, which may change magicly when the command we run
* creates or modifies environment variables (like "bootp" does).
*/
-
-int run_command (const char *cmd, int flag)
+static int builtin_run_command(const char *cmd, int flag)
{
- cmd_tbl_t *cmdtp;
char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */
char *token; /* start of token in cmdbuf */
char *sep; /* end of token (separator) in cmdbuf */
continue;
}
- /* Look up command in command table */
- if ((cmdtp = find_cmd(argv[0])) == NULL) {
- printf ("Unknown command '%s' - try 'help'\n", argv[0]);
- rc = -1; /* give up after bad command */
- continue;
- }
-
- /* found - check max args */
- if (argc > cmdtp->maxargs) {
- cmd_usage(cmdtp);
- rc = -1;
- continue;
- }
-
-#if defined(CONFIG_CMD_BOOTD)
- /* avoid "bootd" recursion */
- if (cmdtp->cmd == do_bootd) {
-#ifdef DEBUG_PARSER
- printf ("[%s]\n", finaltoken);
-#endif
- if (flag & CMD_FLAG_BOOTD) {
- puts ("'bootd' recursion detected\n");
- rc = -1;
- continue;
- } else {
- flag |= CMD_FLAG_BOOTD;
- }
- }
-#endif
-
- /* OK - call function to do the command */
- if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
+ if (cmd_process(flag, argc, argv, &repeatable))
rc = -1;
- }
-
- repeatable &= cmdtp->repeatable;
/* Did the user stop this? */
if (had_ctrlc ())
return rc ? rc : repeatable;
}
+#endif
+
+/*
+ * Run a command using the selected parser.
+ *
+ * @param cmd Command to run
+ * @param flag Execution flags (CMD_FLAG_...)
+ * @return 0 on success, or != 0 on error.
+ */
+int run_command(const char *cmd, int flag)
+{
+#ifndef CONFIG_SYS_HUSH_PARSER
+ /*
+ * builtin_run_command can return 0 or 1 for success, so clean up
+ * its result.
+ */
+ if (builtin_run_command(cmd, flag) == -1)
+ return 1;
+
+ return 0;
+#else
+ return parse_string_outer(cmd,
+ FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+#endif
+}
/****************************************************************************/
#if defined(CONFIG_CMD_RUN)
-int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int i;
- if (argc < 2) {
- cmd_usage(cmdtp);
- return 1;
- }
+ if (argc < 2)
+ return CMD_RET_USAGE;
for (i=1; i<argc; ++i) {
char *arg;
printf ("## Error: \"%s\" not defined\n", argv[i]);
return 1;
}
-#ifndef CONFIG_SYS_HUSH_PARSER
- if (run_command (arg, flag) == -1)
- return 1;
-#else
- if (parse_string_outer(arg,
- FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
+
+ if (run_command(arg, flag) != 0)
return 1;
-#endif
}
return 0;
}