]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/main.c
Merge with /home/m8/git/u-boot
[karo-tx-uboot.git] / common / main.c
index 33d871771bdb66568217b3459f332d38c90e04a4..f042f3a636fd6171ce2f96c6f8a15b49fb33169b 100644 (file)
 #include <common.h>
 #include <watchdog.h>
 #include <command.h>
-#include <cmd_nvedit.h>
-#include <cmd_bootm.h>
-#include <malloc.h>
-#if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY)
-#include <cmd_boot.h>          /* for do_reset() prototype */
+#ifdef CONFIG_MODEM_SUPPORT
+#include <malloc.h>            /* for free() prototype */
 #endif
 
 #ifdef CFG_HUSH_PARSER
 #include <hush.h>
 #endif
 
+#include <post.h>
+
+#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[]);
+
+
 #define MAX_DELAY_STOP_STR 32
 
 static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
@@ -98,6 +104,18 @@ static __inline__ int abortboot(int bootdelay)
        u_int presskey_max = 0;
        u_int i;
 
+#ifdef CONFIG_SILENT_CONSOLE
+       {
+               DECLARE_GLOBAL_DATA_PTR;
+
+               if (gd->flags & GD_FLG_SILENT) {
+                       /* Restore serial console */
+                       console_assign (stdout, "serial");
+                       console_assign (stderr, "serial");
+               }
+       }
+#endif
+
 #  ifdef CONFIG_AUTOBOOT_PROMPT
        printf (CONFIG_AUTOBOOT_PROMPT, bootdelay);
 #  endif
@@ -143,7 +161,7 @@ static __inline__ int abortboot(int bootdelay)
                        if (delaykey[i].len > 0 &&
                            presskey_len >= delaykey[i].len &&
                            memcmp (presskey + presskey_len - delaykey[i].len,
-                                   delaykey[i].str,
+                                   delaykey[i].str,
                                    delaykey[i].len) == 0) {
 #  if DEBUG_BOOTKEYS
                                printf("got %skey\n",
@@ -173,9 +191,24 @@ static __inline__ int abortboot(int bootdelay)
        }
 #  if DEBUG_BOOTKEYS
        if (!abort)
-               printf("key timeout\n");
+               puts ("key timeout\n");
 #  endif
 
+#ifdef CONFIG_SILENT_CONSOLE
+       {
+               DECLARE_GLOBAL_DATA_PTR;
+
+               if (abort) {
+                       /* permanently enable normal console output */
+                       gd->flags &= ~(GD_FLG_SILENT);
+               } else if (gd->flags & GD_FLG_SILENT) {
+                       /* Restore silent console */
+                       console_assign (stdout, "nulldev");
+                       console_assign (stderr, "nulldev");
+               }
+       }
+#endif
+
        return abort;
 }
 
@@ -189,6 +222,18 @@ static __inline__ int abortboot(int bootdelay)
 {
        int abort = 0;
 
+#ifdef CONFIG_SILENT_CONSOLE
+       {
+               DECLARE_GLOBAL_DATA_PTR;
+
+               if (gd->flags & GD_FLG_SILENT) {
+                       /* Restore serial console */
+                       console_assign (stdout, "serial");
+                       console_assign (stderr, "serial");
+               }
+       }
+#endif
+
 #ifdef CONFIG_MENUPROMPT
        printf(CONFIG_MENUPROMPT, bootdelay);
 #else
@@ -196,20 +241,20 @@ static __inline__ int abortboot(int bootdelay)
 #endif
 
 #if defined CONFIG_ZERO_BOOTDELAY_CHECK
-        /*
-         * Check if key already pressed
-         * Don't check if bootdelay < 0
-         */
+       /*
+        * Check if key already pressed
+        * Don't check if bootdelay < 0
+        */
        if (bootdelay >= 0) {
                if (tstc()) {   /* we got a key press   */
                        (void) getc();  /* consume input        */
-                       printf ("\b\b\b 0\n");
-                       return 1;       /* don't auto boot      */
+                       puts ("\b\b\b 0");
+                       abort = 1;      /* don't auto boot      */
                }
-        }
+       }
 #endif
 
-       while (bootdelay > 0) {
+       while ((bootdelay > 0) && (!abort)) {
                int i;
 
                --bootdelay;
@@ -233,6 +278,21 @@ static __inline__ int abortboot(int bootdelay)
 
        putc ('\n');
 
+#ifdef CONFIG_SILENT_CONSOLE
+       {
+               DECLARE_GLOBAL_DATA_PTR;
+
+               if (abort) {
+                       /* permanently enable normal console output */
+                       gd->flags &= ~(GD_FLG_SILENT);
+               } else if (gd->flags & GD_FLG_SILENT) {
+                       /* Restore silent console */
+                       console_assign (stdout, "nulldev");
+                       console_assign (stderr, "nulldev");
+               }
+       }
+#endif
+
        return abort;
 }
 # endif        /* CONFIG_AUTOBOOT_KEYED */
@@ -256,6 +316,12 @@ void main_loop (void)
 #ifdef CONFIG_PREBOOT
        char *p;
 #endif
+#ifdef CONFIG_BOOTCOUNT_LIMIT
+       unsigned long bootcount = 0;
+       unsigned long bootlimit = 0;
+       char *bcs;
+       char bcs_set[16];
+#endif /* CONFIG_BOOTCOUNT_LIMIT */
 
 #if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)
        ulong bmp = 0;          /* default bitmap */
@@ -268,10 +334,20 @@ void main_loop (void)
        trab_vfd (bmp);
 #endif /* CONFIG_VFD && VFD_TEST_LOGO */
 
+#ifdef CONFIG_BOOTCOUNT_LIMIT
+       bootcount = bootcount_load();
+       bootcount++;
+       bootcount_store (bootcount);
+       sprintf (bcs_set, "%lu", bootcount);
+       setenv ("bootcount", bcs_set);
+       bcs = getenv ("bootlimit");
+       bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;
+#endif /* CONFIG_BOOTCOUNT_LIMIT */
+
 #ifdef CONFIG_MODEM_SUPPORT
        debug ("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init);
        if (do_mdm_init) {
-               uchar *str = strdup(getenv("mdm_cmd"));
+               char *str = strdup(getenv("mdm_cmd"));
                setenv ("preboot", str);  /* set or delete definition */
                if (str != NULL)
                        free (str);
@@ -282,10 +358,8 @@ void main_loop (void)
 #ifdef CONFIG_VERSION_VARIABLE
        {
                extern char version_string[];
-               char *str = getenv("ver");
 
-               if (!str)
-                       setenv ("ver", version_string);  /* set version variable */
+               setenv ("ver", version_string);  /* set version variable */
        }
 #endif /* CONFIG_VERSION_VARIABLE */
 
@@ -293,6 +367,10 @@ void main_loop (void)
        u_boot_hush_start ();
 #endif
 
+#ifdef CONFIG_AUTO_COMPLETE
+       install_auto_complete();
+#endif
+
 #ifdef CONFIG_PREBOOT
        if ((p = getenv ("preboot")) != NULL) {
 # ifdef CONFIG_AUTOBOOT_KEYED
@@ -319,16 +397,18 @@ void main_loop (void)
        debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
 
 # ifdef CONFIG_BOOT_RETRY_TIME
-       s = getenv ("bootretry");
-       if (s != NULL)
-               retry_time = (int)simple_strtoul(s, NULL, 10);
-       else
-               retry_time =  CONFIG_BOOT_RETRY_TIME;
-       if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
-               retry_time = CONFIG_BOOT_RETRY_MIN;
+       init_cmd_timeout ();
 # endif        /* CONFIG_BOOT_RETRY_TIME */
 
-       s = getenv ("bootcmd");
+#ifdef CONFIG_BOOTCOUNT_LIMIT
+       if (bootlimit && (bootcount > bootlimit)) {
+               printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
+                       (unsigned)bootlimit);
+               s = getenv ("altbootcmd");
+       }
+       else
+#endif /* CONFIG_BOOTCOUNT_LIMIT */
+               s = getenv ("bootcmd");
 
        debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
 
@@ -354,7 +434,7 @@ void main_loop (void)
            s = getenv("menucmd");
            if (s) {
 # ifndef CFG_HUSH_PARSER
-               run_command (s, bd, 0);
+               run_command (s, 0);
 # else
                parse_string_outer(s, FLAG_PARSE_SEMICOLON |
                                    FLAG_EXIT_FROM_LOOP);
@@ -399,7 +479,7 @@ void main_loop (void)
                else if (len == -2) {
                        /* -2 means timed out, retry autoboot
                         */
-                       printf("\nTimed out waiting for command\n");
+                       puts ("\nTimed out waiting for command\n");
 # ifdef CONFIG_RESET_TO_RETRY
                        /* Reinit board to run initialization code again */
                        do_reset (NULL, 0, 0, NULL);
@@ -410,7 +490,7 @@ void main_loop (void)
 #endif
 
                if (len == -1)
-                       printf ("<INTERRUPT>\n");
+                       puts ("<INTERRUPT>\n");
                else
                        rc = run_command (lastcommand, flag);
 
@@ -422,10 +502,26 @@ void main_loop (void)
 #endif /*CFG_HUSH_PARSER*/
 }
 
+#ifdef CONFIG_BOOT_RETRY_TIME
+/***************************************************************************
+ * initialise command line timeout
+ */
+void init_cmd_timeout(void)
+{
+       char *s = getenv ("bootretry");
+
+       if (s != NULL)
+               retry_time = (int)simple_strtol(s, NULL, 10);
+       else
+               retry_time =  CONFIG_BOOT_RETRY_TIME;
+
+       if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
+               retry_time = CONFIG_BOOT_RETRY_MIN;
+}
+
 /***************************************************************************
  * reset command line timeout to retry_time seconds
  */
-#ifdef CONFIG_BOOT_RETRY_TIME
 void reset_cmd_timeout(void)
 {
        endtime = endtick(retry_time);
@@ -484,6 +580,9 @@ int readline (const char *const prompt)
                        puts ("\r\n");
                        return (p - console_buffer);
 
+               case '\0':                              /* nul                  */
+                       continue;
+
                case 0x03:                              /* ^C - break           */
                        console_buffer[0] = '\0';       /* discard input */
                        return (-1);
@@ -515,6 +614,14 @@ int readline (const char *const prompt)
                         */
                        if (n < CFG_CBSIZE-2) {
                                if (c == '\t') {        /* expand TABs          */
+#ifdef CONFIG_AUTO_COMPLETE
+                                       /* if auto completion triggered just continue */
+                                       *p = '\0';
+                                       if (cmd_auto_complete(prompt, console_buffer, &n, &col)) {
+                                               p = console_buffer + n; /* reset */
+                                               continue;
+                                       }
+#endif
                                        puts (tab_seq+(col&07));
                                        col += 8 - (col&07);
                                } else {
@@ -621,9 +728,9 @@ static void process_macros (const char *input, char *output)
        int inputcnt  = strlen (input);
        int outputcnt = CFG_CBSIZE;
        int state = 0;  /* 0 = waiting for '$'  */
-                       /* 1 = waiting for '('  */
-                       /* 2 = waiting for ')'  */
-                       /* 3 = waiting for '''  */
+                       /* 1 = waiting for '(' or '{' */
+                       /* 2 = waiting for ')' or '}' */
+                       /* 3 = waiting for '''  */
 #ifdef DEBUG_PARSER
        char *output_start = output;
 
@@ -642,7 +749,7 @@ static void process_macros (const char *input, char *output)
                if (inputcnt-- == 0)
                        break;
                prev = c;
-               c = *input++;
+               c = *input++;
            }
            }
 
@@ -660,7 +767,7 @@ static void process_macros (const char *input, char *output)
                }
                break;
            case 1:                     /* Waiting for (        */
-               if (c == '(') {
+               if (c == '(' || c == '{') {
                        state++;
                        varname_start = input;
                } else {
@@ -675,7 +782,7 @@ static void process_macros (const char *input, char *output)
                }
                break;
            case 2:                     /* Waiting for )        */
-               if (c == ')') {
+               if (c == ')' || c == '}') {
                        int i;
                        char envname[CFG_CBSIZE], *envval;
                        int envcnt = input-varname_start-1; /* Varname # of chars */
@@ -746,9 +853,9 @@ int run_command (const char *cmd, int flag)
        char finaltoken[CFG_CBSIZE];
        char *str = cmdbuf;
        char *argv[CFG_MAXARGS + 1];    /* NULL terminated      */
-       int argc;
+       int argc, inquotes;
        int repeatable = 1;
-       int inquotes;
+       int rc = 0;
 
 #ifdef DEBUG_PARSER
        printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
@@ -817,13 +924,15 @@ int run_command (const char *cmd, int flag)
                /* Look up command in command table */
                if ((cmdtp = find_cmd(argv[0])) == NULL) {
                        printf ("Unknown command '%s' - try 'help'\n", argv[0]);
-                       return -1;      /* give up after bad command */
+                       rc = -1;        /* give up after bad command */
+                       continue;
                }
 
                /* found - check max args */
                if (argc > cmdtp->maxargs) {
                        printf ("Usage:\n%s\n", cmdtp->usage);
-                       return -1;
+                       rc = -1;
+                       continue;
                }
 
 #if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
@@ -833,8 +942,9 @@ int run_command (const char *cmd, int flag)
                        printf ("[%s]\n", finaltoken);
 #endif
                        if (flag & CMD_FLAG_BOOTD) {
-                               printf ("'bootd' recursion detected\n");
-                               return -1;
+                               puts ("'bootd' recursion detected\n");
+                               rc = -1;
+                               continue;
                        }
                        else
                                flag |= CMD_FLAG_BOOTD;
@@ -843,7 +953,7 @@ int run_command (const char *cmd, int flag)
 
                /* OK - call function to do the command */
                if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
-                       return (-1);
+                       rc = -1;
                }
 
                repeatable &= cmdtp->repeatable;
@@ -853,7 +963,7 @@ int run_command (const char *cmd, int flag)
                        return 0;       /* if stopped then not repeatable */
        }
 
-       return repeatable;
+       return rc ? rc : repeatable;
 }
 
 /****************************************************************************/
@@ -880,7 +990,7 @@ int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                        return 1;
 #else
                if (parse_string_outer(arg,
-                   FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) == 0)
+                   FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
                        return 1;
 #endif
        }