X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fmain.c;h=79ad2912a751c6097e524dca9b7224990f30fb96;hb=7f9f4347cf325c63a39fe30910f3fb211ae2cc15;hp=13d12a430807ba94e1607a3590eddc2a9b0020e2;hpb=0855c50e6509d03ce2af1e9c4d1dc09ba426faa5;p=oweals%2Fu-boot.git diff --git a/common/main.c b/common/main.c index 13d12a4308..79ad2912a7 100644 --- a/common/main.c +++ b/common/main.c @@ -40,10 +40,16 @@ #include -#ifdef CONFIG_SILENT_CONSOLE +#if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING) DECLARE_GLOBAL_DATA_PTR; #endif +/* + * 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 @@ -53,7 +59,6 @@ extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #define MAX_DELAY_STOP_STR 32 -static int parse_line (char *, char *[]); #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) static int abortboot(int); #endif @@ -62,11 +67,9 @@ static int abortboot(int); char console_buffer[CFG_CBSIZE]; /* console I/O buffer */ -#ifndef CONFIG_CMDLINE_EDITING 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 */ -#endif /* CONFIG_CMDLINE_EDITING */ #ifdef CONFIG_BOOT_RETRY_TIME static uint64_t endtime = 0; /* must be set, default is instant timeout */ @@ -95,14 +98,12 @@ static __inline__ int abortboot(int bootdelay) { int abort = 0; uint64_t etime = endtick(bootdelay); - struct - { + struct { char* str; u_int len; int retry; } - delaykey [] = - { + delaykey [] = { { str: getenv ("bootdelaykey"), retry: 1 }, { str: getenv ("bootdelaykey2"), retry: 1 }, { str: getenv ("bootstopkey"), retry: 0 }, @@ -114,16 +115,8 @@ static __inline__ int abortboot(int bootdelay) u_int presskey_max = 0; u_int i; -#ifdef CONFIG_SILENT_CONSOLE - 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); + printf(CONFIG_AUTOBOOT_PROMPT, bootdelay); # endif # ifdef CONFIG_AUTOBOOT_DELAY_STR @@ -197,18 +190,12 @@ static __inline__ int abortboot(int bootdelay) } # if DEBUG_BOOTKEYS if (!abort) - puts ("key timeout\n"); + puts("key timeout\n"); # endif #ifdef CONFIG_SILENT_CONSOLE - 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"); - } + if (abort) + gd->flags &= ~GD_FLG_SILENT; #endif return abort; @@ -224,14 +211,6 @@ static __inline__ int abortboot(int bootdelay) { int abort = 0; -#ifdef CONFIG_SILENT_CONSOLE - 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 @@ -247,7 +226,7 @@ static __inline__ int abortboot(int bootdelay) if (tstc()) { /* we got a key press */ (void) getc(); /* consume input */ puts ("\b\b\b 0"); - abort = 1; /* don't auto boot */ + abort = 1; /* don't auto boot */ } } #endif @@ -268,23 +247,17 @@ static __inline__ int abortboot(int bootdelay) # endif break; } - udelay (10000); + udelay(10000); } - printf ("\b\b\b%2d ", bootdelay); + printf("\b\b\b%2d ", bootdelay); } - putc ('\n'); + putc('\n'); #ifdef CONFIG_SILENT_CONSOLE - 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"); - } + if (abort) + gd->flags &= ~GD_FLG_SILENT; #endif return abort; @@ -394,6 +367,12 @@ void main_loop (void) init_cmd_timeout (); # endif /* CONFIG_BOOT_RETRY_TIME */ +#ifdef CONFIG_POST + if (gd->flags & GD_FLG_POSTFAIL) { + s = getenv("failbootcmd"); + } + else +#endif /* CONFIG_POST */ #ifdef CONFIG_BOOTCOUNT_LIMIT if (bootlimit && (bootcount > bootlimit)) { printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n", @@ -498,7 +477,7 @@ void main_loop (void) #ifdef CONFIG_BOOT_RETRY_TIME /*************************************************************************** - * initialise command line timeout + * initialize command line timeout */ void init_cmd_timeout(void) { @@ -529,23 +508,9 @@ void reset_cmd_timeout(void) * Author: Janghoon Lyu */ -#if 1 /* avoid redundand code -- wd */ #define putnstr(str,n) do { \ - printf ("%.*s", n, str); \ + printf ("%.*s", (int)n, str); \ } while (0) -#else -void putnstr(const char *str, size_t n) -{ - if (str == NULL) - return; - - while (n && *str != '\0') { - putc(*str); - str++; - n--; - } -} -#endif #define CTL_CH(c) ((c) - 'a' + 1) @@ -734,7 +699,7 @@ static void cread_add_str(char *str, int strsize, int insert, unsigned long *num } } -static int cread_line(char *buf, unsigned int *len) +static int cread_line(const char *const prompt, char *buf, unsigned int *len) { unsigned long num = 0; unsigned long eol_num = 0; @@ -748,6 +713,13 @@ static int cread_line(char *buf, unsigned int *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 */ + } +#endif + ichar = getcmd_getch(); if ((ichar == '\n') || (ichar == '\r')) { @@ -856,6 +828,7 @@ static int cread_line(char *buf, unsigned int *len) insert = !insert; break; case CTL_CH('x'): + case CTL_CH('u'): BEGINNING_OF_LINE(); ERASE_TO_EOL(); break; @@ -905,6 +878,27 @@ static int cread_line(char *buf, unsigned int *len) REFRESH_TO_EOL(); continue; } +#ifdef CONFIG_AUTO_COMPLETE + case '\t': { + int num2, col; + + /* do not autocomplete when in the middle */ + if (num < eol_num) { + getcmd_cbeep(); + break; + } + + buf[num] = '\0'; + col = strlen(prompt) + eol_num; + num2 = num; + if (cmd_auto_complete(prompt, buf, &num2, &col)) { + col = num2 - num; + num += col; + eol_num += col; + } + break; + } +#endif default: cread_add_char(ichar, insert, &num, &eol_num, buf, *len); break; @@ -934,23 +928,38 @@ static int cread_line(char *buf, unsigned int *len) */ int readline (const char *const prompt) { + return readline_into_buffer(prompt, console_buffer); +} + + +int readline_into_buffer (const char *const prompt, char * buffer) +{ + char *p = buffer; #ifdef CONFIG_CMDLINE_EDITING - char *p = console_buffer; unsigned int len=MAX_CMDBUF_SIZE; int rc; static int initted = 0; - if (!initted) { - hist_init(); - initted = 1; - } + /* + * History uses a global array which is not + * writable until after relocation to RAM. + * Revert to non-history version if still + * running from flash. + */ + if (gd->flags & GD_FLG_RELOC) { + if (!initted) { + hist_init(); + initted = 1; + } - puts (prompt); + puts (prompt); - rc = cread_line(p, &len); - return rc < 0 ? rc : len; -#else - char *p = console_buffer; + rc = cread_line(prompt, p, &len); + return rc < 0 ? rc : len; + + } else { +#endif /* CONFIG_CMDLINE_EDITING */ + char * p_buf = p; int n = 0; /* buffer index */ int plen = 0; /* prompt length */ int col; /* output column cnt */ @@ -988,13 +997,13 @@ int readline (const char *const prompt) case '\n': *p = '\0'; puts ("\r\n"); - return (p - console_buffer); + return (p - p_buf); case '\0': /* nul */ continue; case 0x03: /* ^C - break */ - console_buffer[0] = '\0'; /* discard input */ + p_buf[0] = '\0'; /* discard input */ return (-1); case 0x15: /* ^U - erase line */ @@ -1002,20 +1011,20 @@ int readline (const char *const prompt) puts (erase_seq); --col; } - p = console_buffer; + p = p_buf; n = 0; continue; - case 0x17: /* ^W - erase word */ - p=delete_char(console_buffer, p, &col, &n, plen); + case 0x17: /* ^W - erase word */ + p=delete_char(p_buf, p, &col, &n, plen); while ((n > 0) && (*p != ' ')) { - p=delete_char(console_buffer, p, &col, &n, plen); + p=delete_char(p_buf, p, &col, &n, plen); } continue; case 0x08: /* ^H - backspace */ case 0x7F: /* DEL - backspace */ - p=delete_char(console_buffer, p, &col, &n, plen); + p=delete_char(p_buf, p, &col, &n, plen); continue; default: @@ -1028,7 +1037,7 @@ int readline (const char *const prompt) /* if auto completion triggered just continue */ *p = '\0'; if (cmd_auto_complete(prompt, console_buffer, &n, &col)) { - p = console_buffer + n; /* reset */ + p = p_buf + n; /* reset */ continue; } #endif @@ -1045,12 +1054,13 @@ int readline (const char *const prompt) } } } -#endif /* CONFIG_CMDLINE_EDITING */ +#ifdef CONFIG_CMDLINE_EDITING + } +#endif } /****************************************************************************/ -#ifndef CONFIG_CMDLINE_EDITING static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen) { char *s; @@ -1080,7 +1090,6 @@ static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen) (*np)--; return (p); } -#endif /* CONFIG_CMDLINE_EDITING */ /****************************************************************************/ @@ -1138,105 +1147,109 @@ static void process_macros (const char *input, char *output) { char c, prev; const char *varname_start = NULL; - int inputcnt = strlen (input); + int inputcnt = strlen (input); int outputcnt = CFG_CBSIZE; - int state = 0; /* 0 = waiting for '$' */ - /* 1 = waiting for '(' or '{' */ - /* 2 = waiting for ')' or '}' */ - /* 3 = waiting for ''' */ + int state = 0; /* 0 = waiting for '$' */ + + /* 1 = waiting for '(' or '{' */ + /* 2 = waiting for ')' or '}' */ + /* 3 = waiting for ''' */ #ifdef DEBUG_PARSER char *output_start = output; - printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input), input); + printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input), + input); #endif - prev = '\0'; /* previous character */ + prev = '\0'; /* previous character */ while (inputcnt && outputcnt) { - c = *input++; - inputcnt--; - - if (state!=3) { - /* remove one level of escape characters */ - if ((c == '\\') && (prev != '\\')) { - if (inputcnt-- == 0) - break; - prev = c; c = *input++; - } - } - - switch (state) { - case 0: /* Waiting for (unescaped) $ */ - if ((c == '\'') && (prev != '\\')) { - state = 3; - break; - } - if ((c == '$') && (prev != '\\')) { - state++; - } else { - *(output++) = c; - outputcnt--; + inputcnt--; + + if (state != 3) { + /* remove one level of escape characters */ + if ((c == '\\') && (prev != '\\')) { + if (inputcnt-- == 0) + break; + prev = c; + c = *input++; + } } - break; - case 1: /* Waiting for ( */ - if (c == '(' || c == '{') { - state++; - varname_start = input; - } else { - state = 0; - *(output++) = '$'; - outputcnt--; - - if (outputcnt) { + + switch (state) { + case 0: /* Waiting for (unescaped) $ */ + if ((c == '\'') && (prev != '\\')) { + state = 3; + break; + } + if ((c == '$') && (prev != '\\')) { + state++; + } else { *(output++) = c; outputcnt--; } - } - break; - case 2: /* Waiting for ) */ - if (c == ')' || c == '}') { - int i; - char envname[CFG_CBSIZE], *envval; - int envcnt = input-varname_start-1; /* Varname # of chars */ - - /* Get the varname */ - for (i = 0; i < envcnt; i++) { - envname[i] = varname_start[i]; - } - envname[i] = 0; - - /* Get its value */ - envval = getenv (envname); + break; + case 1: /* Waiting for ( */ + if (c == '(' || c == '{') { + state++; + varname_start = input; + } else { + state = 0; + *(output++) = '$'; + outputcnt--; - /* Copy into the line if it exists */ - if (envval != NULL) - while ((*envval) && outputcnt) { - *(output++) = *(envval++); + if (outputcnt) { + *(output++) = c; outputcnt--; } - /* Look for another '$' */ - state = 0; - } - break; - case 3: /* Waiting for ' */ - if ((c == '\'') && (prev != '\\')) { - state = 0; - } else { - *(output++) = c; - outputcnt--; + } + break; + case 2: /* Waiting for ) */ + if (c == ')' || c == '}') { + int i; + char envname[CFG_CBSIZE], *envval; + int envcnt = input - varname_start - 1; /* Varname # of chars */ + + /* Get the varname */ + for (i = 0; i < envcnt; i++) { + envname[i] = varname_start[i]; + } + envname[i] = 0; + + /* Get its value */ + envval = getenv (envname); + + /* Copy into the line if it exists */ + if (envval != NULL) + while ((*envval) && outputcnt) { + *(output++) = *(envval++); + outputcnt--; + } + /* Look for another '$' */ + state = 0; + } + break; + case 3: /* Waiting for ' */ + if ((c == '\'') && (prev != '\\')) { + state = 0; + } else { + *(output++) = c; + outputcnt--; + } + break; } - break; - } - prev = c; + prev = c; } if (outputcnt) *output = 0; + else + *(output - 1) = 0; #ifdef DEBUG_PARSER printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n", - strlen(output_start), output_start); + strlen (output_start), output_start); #endif } @@ -1351,7 +1364,7 @@ int run_command (const char *cmd, int flag) continue; } -#if (CONFIG_COMMANDS & CFG_CMD_BOOTD) +#if defined(CONFIG_CMD_BOOTD) /* avoid "bootd" recursion */ if (cmdtp->cmd == do_bootd) { #ifdef DEBUG_PARSER @@ -1365,7 +1378,7 @@ int run_command (const char *cmd, int flag) flag |= CMD_FLAG_BOOTD; } } -#endif /* CFG_CMD_BOOTD */ +#endif /* OK - call function to do the command */ if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { @@ -1376,7 +1389,7 @@ int run_command (const char *cmd, int flag) /* Did the user stop this? */ if (had_ctrlc ()) - return 0; /* if stopped then not repeatable */ + return -1; /* if stopped then not repeatable */ } return rc ? rc : repeatable; @@ -1384,7 +1397,7 @@ int run_command (const char *cmd, int flag) /****************************************************************************/ -#if (CONFIG_COMMANDS & CFG_CMD_RUN) +#if defined(CONFIG_CMD_RUN) int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int i; @@ -1412,4 +1425,4 @@ int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } return 0; } -#endif /* CFG_CMD_RUN */ +#endif