diff options
author | wdenk | 2004-04-18 10:13:26 +0000 |
---|---|---|
committer | wdenk | 2004-04-18 10:13:26 +0000 |
commit | c26e454dfc6650428854fa2db3b1ed7f19e0ba0e (patch) | |
tree | 2ad2368558e366e127683028a71381cb1dd37140 /common | |
parent | ea66bc8804b66633faae5b7066571c9d68b4d14a (diff) |
Patches by Pantelis Antoniou, 16 Apr 2004:
- add support for a new version of an Intracom board and fix
various other things on others.
- add verify support to the crc32 command (define
CONFIG_CRC32_VERIFY to enable it)
- fix FEC driver for MPC8xx systems:
1. fix compilation problems for boards that use dynamic
allocation of DPRAM
2. shut down FEC after network transfers
- HUSH parser fixes:
1. A new test command was added. This is a simplified version of
the one in the bourne shell.
2. A new exit command was added which terminates the current
executing script.
3. Fixed handing of $? (exit code of last executed command)
Diffstat (limited to 'common')
-rw-r--r-- | common/cmd_mem.c | 71 | ||||
-rw-r--r-- | common/cmd_pcmcia.c | 2 | ||||
-rw-r--r-- | common/command.c | 153 | ||||
-rw-r--r-- | common/hush.c | 85 |
4 files changed, 303 insertions, 8 deletions
diff --git a/common/cmd_mem.c b/common/cmd_mem.c index f18bfde3aee..8430298a34c 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -963,6 +963,8 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) return 0; } +#ifndef CONFIG_CRC32_VERIFY + int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr, length; @@ -992,6 +994,62 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } +#else /* CONFIG_CRC32_VERIFY */ + +int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + ulong addr, length; + ulong crc; + ulong *ptr; + ulong vcrc; + int verify; + int ac; + char **av; + + if (argc < 3) { + usage: + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + av = argv + 1; + ac = argc - 1; + if (strcmp(*av, "-v") == 0) { + verify = 1; + av++; + ac--; + if (ac < 3) + goto usage; + } else + verify = 0; + + addr = simple_strtoul(*av++, NULL, 16); + addr += base_address; + length = simple_strtoul(*av++, NULL, 16); + + crc = crc32(0, (const uchar *) addr, length); + + if (!verify) { + printf ("CRC32 for %08lx ... %08lx ==> %08lx\n", + addr, addr + length - 1, crc); + if (ac > 2) { + ptr = (ulong *) simple_strtoul (*av++, NULL, 16); + *ptr = crc; + } + } else { + vcrc = simple_strtoul(*av++, NULL, 16); + if (vcrc != crc) { + printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n", + addr, addr + length - 1, crc, vcrc); + return 1; + } + } + + return 0; + +} +#endif /* CONFIG_CRC32_VERIFY */ + /**************************************************/ #if (CONFIG_COMMANDS & CFG_CMD_MEMORY) U_BOOT_CMD( @@ -1032,12 +1090,25 @@ U_BOOT_CMD( "[.b, .w, .l] addr1 addr2 count\n - compare memory\n" ); +#ifndef CONFIG_CRC32_VERIFY + U_BOOT_CMD( crc32, 4, 1, do_mem_crc, "crc32 - checksum calculation\n", "address count [addr]\n - compute CRC32 checksum [save at addr]\n" ); +#else /* CONFIG_CRC32_VERIFY */ + +U_BOOT_CMD( + crc32, 5, 1, do_mem_crc, + "crc32 - checksum calculation\n", + "address count [addr]\n - compute CRC32 checksum [save at addr]\n" + "-v address count crc\n - verify crc of memory area\n" +); + +#endif /* CONFIG_CRC32_VERIFY */ + U_BOOT_CMD( base, 2, 1, do_mem_base, "base - print or set address offset\n", diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c index 47632e75590..7a2ca9e456b 100644 --- a/common/cmd_pcmcia.c +++ b/common/cmd_pcmcia.c @@ -289,7 +289,7 @@ int pcmcia_on (void) return (rc); } -#endif / CONFIG_PXA_PCMCIA */ +#endif /* CONFIG_PXA_PCMCIA */ #endif /* CONFIG_I82365 */ diff --git a/common/command.c b/common/command.c index df5d3e9bca5..2b48a1c9155 100644 --- a/common/command.c +++ b/common/command.c @@ -74,6 +74,159 @@ U_BOOT_CMD( " - echo args to console; \\c suppresses newline\n" ); +#ifdef CFG_HUSH_PARSER + +int +do_test (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char **ap; + int left, adv, expr, last_expr, neg, last_cmp; + + /* args? */ + if (argc < 3) + return 1; + +#if 0 + { + printf("test:"); + left = 1; + while (argv[left]) + printf(" %s", argv[left++]); + } +#endif + + last_expr = 0; + left = argc - 1; ap = argv + 1; + if (left > 0 && strcmp(ap[0], "!") == 0) { + neg = 1; + ap++; + left--; + } else + neg = 0; + + expr = -1; + last_cmp = -1; + last_expr = -1; + while (left > 0) { + + if (strcmp(ap[0], "-o") == 0 || strcmp(ap[0], "-a") == 0) + adv = 1; + else if (strcmp(ap[0], "-z") == 0 || strcmp(ap[0], "-n") == 0) + adv = 2; + else + adv = 3; + + if (left < adv) { + expr = 1; + break; + } + + if (adv == 1) { + if (strcmp(ap[0], "-o") == 0) { + last_expr = expr; + last_cmp = 0; + } else if (strcmp(ap[0], "-a") == 0) { + last_expr = expr; + last_cmp = 1; + } else { + expr = 1; + break; + } + } + + if (adv == 2) { + if (strcmp(ap[0], "-z") == 0) + expr = strlen(ap[1]) == 0 ? 0 : 1; + else if (strcmp(ap[0], "-n") == 0) + expr = strlen(ap[1]) == 0 ? 1 : 0; + else { + expr = 1; + break; + } + + if (last_cmp == 0) + expr = last_expr || expr; + else if (last_cmp == 1) + expr = last_expr && expr; + last_cmp = -1; + } + + if (adv == 3) { + if (strcmp(ap[1], "=") == 0) + expr = strcmp(ap[0], ap[2]) == 0; + else if (strcmp(ap[1], "!=") == 0) + expr = strcmp(ap[0], ap[2]) != 0; + else if (strcmp(ap[1], ">") == 0) + expr = strcmp(ap[0], ap[2]) > 0; + else if (strcmp(ap[1], "<") == 0) + expr = strcmp(ap[0], ap[2]) < 0; + else if (strcmp(ap[1], "-eq") == 0) + expr = simple_strtol(ap[0], NULL, 10) == simple_strtol(ap[2], NULL, 10); + else if (strcmp(ap[1], "-ne") == 0) + expr = simple_strtol(ap[0], NULL, 10) != simple_strtol(ap[2], NULL, 10); + else if (strcmp(ap[1], "-lt") == 0) + expr = simple_strtol(ap[0], NULL, 10) < simple_strtol(ap[2], NULL, 10); + else if (strcmp(ap[1], "-le") == 0) + expr = simple_strtol(ap[0], NULL, 10) <= simple_strtol(ap[2], NULL, 10); + else if (strcmp(ap[1], "-gt") == 0) + expr = simple_strtol(ap[0], NULL, 10) > simple_strtol(ap[2], NULL, 10); + else if (strcmp(ap[1], "-ge") == 0) + expr = simple_strtol(ap[0], NULL, 10) >= simple_strtol(ap[2], NULL, 10); + else { + expr = 1; + break; + } + + if (last_cmp == 0) + expr = last_expr || expr; + else if (last_cmp == 1) + expr = last_expr && expr; + last_cmp = -1; + } + + ap += adv; left -= adv; + } + + if (neg) + expr = !expr; + + expr = !expr; + +#if 0 + printf(": returns %d\n", expr); +#endif + + return expr; +} + +U_BOOT_CMD( + test, CFG_MAXARGS, 1, do_test, + "test - minimal test like /bin/sh\n", + "[args..]\n" + " - test functionality\n" +); + +int +do_exit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int r; + + r = 0; + if (argc > 1) + r = simple_strtoul(argv[1], NULL, 10); + + return -r - 2; +} + +U_BOOT_CMD( + exit, 2, 1, do_exit, + "exit - exit script\n", + " - exit functionality\n" +); + + +#endif + /* * Use puts() instead of printf() to avoid printf buffer overflow * for long help messages diff --git a/common/hush.c b/common/hush.c index eeb970cd536..47680edec38 100644 --- a/common/hush.c +++ b/common/hush.c @@ -290,6 +290,7 @@ char **global_argv; unsigned int global_argc; #endif unsigned int last_return_code; +int nesting_level; #ifndef __U_BOOT__ extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */ #endif @@ -416,7 +417,9 @@ static int b_check_space(o_string *o, int len); static int b_addchr(o_string *o, int ch); static void b_reset(o_string *o); static int b_addqchr(o_string *o, int ch, int quote); +#ifndef __U_BOOT__ static int b_adduint(o_string *o, unsigned int i); +#endif /* in_str manipulations: */ static int static_get(struct in_str *i); static int static_peek(struct in_str *i); @@ -936,6 +939,7 @@ char *simple_itoa(unsigned int i) return p + 1; } +#ifndef __U_BOOT__ static int b_adduint(o_string *o, unsigned int i) { int r; @@ -944,6 +948,7 @@ static int b_adduint(o_string *o, unsigned int i) do r=b_addchr(o, *p++); while (r==0 && *p); return r; } +#endif static int static_get(struct in_str *i) { @@ -1921,6 +1926,10 @@ static int run_list_real(struct pipe *pi) } last_return_code=rcode; #else + if (rcode < -1) { + last_return_code = -rcode - 2; + return -2; /* exit */ + } last_return_code=(rcode == 0) ? 0 : 1; #endif #ifndef __U_BOOT__ @@ -2145,6 +2154,10 @@ static int xglob(o_string *dest, int flags, glob_t *pglob) } #endif +#ifdef __U_BOOT__ +static char *get_dollar_var(char ch); +#endif + /* This is used to get/check local shell variables */ static char *get_local_var(const char *s) { @@ -2152,6 +2165,12 @@ static char *get_local_var(const char *s) if (!s) return NULL; + +#ifdef __U_BOOT__ + if (*s == '$') + return get_dollar_var(s[1]); +#endif + for (cur = top_vars; cur; cur=cur->next) if(strcmp(cur->name, s)==0) return cur->value; @@ -2168,12 +2187,19 @@ static int set_local_var(const char *s, int flg_export) int result=0; struct variables *cur; +#ifdef __U_BOOT__ + /* might be possible! */ + if (!isalpha(*s)) + return -1; +#endif + name=strdup(s); #ifdef __U_BOOT__ if (getenv(name) != NULL) { printf ("ERROR: " "There is a global environment variable with the same name.\n"); + free(name); return -1; } #endif @@ -2278,7 +2304,10 @@ static void unset_local_var(const char *name) static int is_assignment(const char *s) { - if (s==NULL || !isalpha(*s)) return 0; + if (s == NULL) + return 0; + + if (!isalpha(*s)) return 0; ++s; while(isalnum(*s) || *s=='_') ++s; return *s=='='; @@ -2749,15 +2778,35 @@ static int parse_group(o_string *dest, struct p_context *ctx, * see the bash man page under "Parameter Expansion" */ static char *lookup_param(char *src) { - char *p=NULL; - if (src) { + char *p; + + if (!src) + return NULL; + p = getenv(src); if (!p) p = get_local_var(src); - } + return p; } +#ifdef __U_BOOT__ +static char *get_dollar_var(char ch) +{ + static char buf[40]; + + buf[0] = '\0'; + switch (ch) { + case '?': + sprintf(buf, "%u", (unsigned int)last_return_code); + break; + default: + return NULL; + } + return buf; +} +#endif + /* return code: 0 for OK, 1 for syntax error */ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) { @@ -2799,7 +2848,15 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i break; #endif case '?': +#ifndef __U_BOOT__ b_adduint(dest,last_return_code); +#else + ctx->child->sp++; + b_addchr(dest, SPECIAL_VAR_SYMBOL); + b_addchr(dest, '$'); + b_addchr(dest, '?'); + b_addchr(dest, SPECIAL_VAR_SYMBOL); +#endif advance = 1; break; #ifndef __U_BOOT__ @@ -2885,8 +2942,11 @@ int parse_stream(o_string *dest, struct p_context *ctx, if (input->__promptme == 0) return 1; #endif next = (ch == '\n') ? 0 : b_peek(input); - debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n", - ch,ch,m,dest->quote); + + debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d - %c\n", + ch >= ' ' ? ch : '.', ch, m, + dest->quote, ctx->stack == NULL ? '*' : '.'); + if (m==0 || ((m==1 || m==2) && dest->quote)) { b_addqchr(dest, ch, dest->quote); } else { @@ -3107,7 +3167,18 @@ int parse_stream_outer(struct in_str *inp, int flag) #ifndef __U_BOOT__ run_list(ctx.list_head); #else - if (((code = run_list(ctx.list_head)) == -1)) + code = run_list(ctx.list_head); + if (code == -2) { /* exit */ + b_free(&temp); + code = 0; + /* XXX hackish way to not allow exit from main loop */ + if (inp->peek == file_peek) { + printf("exit not allowed from main input shell.\n"); + continue; + } + break; + } + if (code == -1) flag_repeat = 0; #endif } else { |