#include <common.h>
#include <watchdog.h>
#include <command.h>
+#include <version.h>
#ifdef CONFIG_MODEM_SUPPORT
#include <malloc.h> /* for free() prototype */
#endif
-#ifdef CFG_HUSH_PARSER
+#ifdef CONFIG_SYS_HUSH_PARSER
#include <hush.h>
#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;
* Board-specific Platform code can reimplement show_boot_progress () if needed
*/
void inline __show_boot_progress (int val) {}
-void inline 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[]);
+void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
#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[CFG_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);
/* In order to keep up with incoming data, check timeout only
* when catch up.
*/
- while (!abort && get_ticks() <= etime) {
+ do {
+ if (tstc()) {
+ if (presskey_len < presskey_max) {
+ presskey [presskey_len ++] = getc();
+ }
+ else {
+ for (i = 0; i < presskey_max - 1; i ++)
+ presskey [i] = presskey [i + 1];
+
+ presskey [i] = getc();
+ }
+ }
+
for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
if (delaykey[i].len > 0 &&
presskey_len >= delaykey[i].len &&
abort = 1;
}
}
+ } while (!abort && get_ticks() <= etime);
- if (tstc()) {
- if (presskey_len < presskey_max) {
- presskey [presskey_len ++] = getc();
- }
- else {
- for (i = 0; i < presskey_max - 1; i ++)
- presskey [i] = presskey [i + 1];
-
- presskey [i] = getc();
- }
- }
- }
# if DEBUG_BOOTKEYS
if (!abort)
puts("key timeout\n");
static int menukey = 0;
#endif
-static __inline__ int abortboot(int bootdelay)
+#ifndef CONFIG_MENU
+static inline
+#endif
+int abortboot(int bootdelay)
{
int abort = 0;
void main_loop (void)
{
-#ifndef CFG_HUSH_PARSER
- static char lastcommand[CFG_CBSIZE] = { 0, };
+#ifndef CONFIG_SYS_HUSH_PARSER
+ static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
int len;
int rc = 1;
int flag;
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 */
-#ifdef CFG_HUSH_PARSER
+#ifdef CONFIG_SYS_HUSH_PARSER
u_boot_hush_start ();
#endif
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 CFG_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 CFG_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 CFG_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
*/
-#ifdef CFG_HUSH_PARSER
+#ifdef CONFIG_SYS_HUSH_PARSER
parse_file_outer();
/* This point is never reached */
for (;;);
reset_cmd_timeout();
}
#endif
- len = readline (CFG_PROMPT);
+ len = readline (CONFIG_SYS_PROMPT);
flag = 0; /* assume no special flags for now */
if (len > 0)
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 */
lastcommand[0] = 0;
}
}
-#endif /*CFG_HUSH_PARSER*/
+#endif /*CONFIG_SYS_HUSH_PARSER*/
}
#ifdef CONFIG_BOOT_RETRY_TIME
} 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();
/*
* Must be a normal character then
*/
- if (n < CFG_CBSIZE-2) {
+ if (n < CONFIG_SYS_CBSIZE-2) {
if (c == '\t') { /* expand TABs */
#ifdef CONFIG_AUTO_COMPLETE
/* if auto completion triggered just continue */
#ifdef DEBUG_PARSER
printf ("parse_line: \"%s\"\n", line);
#endif
- while (nargs < CFG_MAXARGS) {
+ 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;
*line++ = '\0'; /* terminate current arg */
}
- printf ("** Too many args (max. %d) **\n", CFG_MAXARGS);
+ printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS);
#ifdef DEBUG_PARSER
printf ("parse_line: nargs=%d\n", nargs);
/****************************************************************************/
+#ifndef CONFIG_SYS_HUSH_PARSER
static void process_macros (const char *input, char *output)
{
char c, prev;
const char *varname_start = NULL;
int inputcnt = strlen (input);
- int outputcnt = CFG_CBSIZE;
+ int outputcnt = CONFIG_SYS_CBSIZE;
int state = 0; /* 0 = waiting for '$' */
/* 1 = waiting for '(' or '{' */
case 2: /* Waiting for ) */
if (c == ')' || c == '}') {
int i;
- char envname[CFG_CBSIZE], *envval;
+ char envname[CONFIG_SYS_CBSIZE], *envval;
int envcnt = input - varname_start - 1; /* Varname # of chars */
/* Get the varname */
* 0 - command executed but not repeatable, interrupted commands are
* always considered not repeatable
* -1 - not executed (unrecognized, bootd recursion or too many args)
- * (If cmd is NULL or "" or longer than CFG_CBSIZE-1 it is
+ * (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is
* considered unrecognized)
*
* WARNING:
* 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[CFG_CBSIZE]; /* working copy of cmd */
+ 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 finaltoken[CFG_CBSIZE];
+ char finaltoken[CONFIG_SYS_CBSIZE];
char *str = cmdbuf;
- char *argv[CFG_MAXARGS + 1]; /* NULL terminated */
+ char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
int argc, inquotes;
int repeatable = 1;
int rc = 0;
return -1; /* empty command */
}
- if (strlen(cmd) >= CFG_CBSIZE) {
+ if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {
puts ("## Command too long!\n");
return -1;
}
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) {
- printf ("Usage:\n%s\n", cmdtp->usage);
- 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) {
- printf ("Usage:\n%s\n", cmdtp->usage);
- 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 CFG_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;
}