summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorwdenk <wdenk>2004-04-18 10:13:26 +0000
committerwdenk <wdenk>2004-04-18 10:13:26 +0000
commitc26e454dfc6650428854fa2db3b1ed7f19e0ba0e (patch)
tree2ad2368558e366e127683028a71381cb1dd37140 /common
parentea66bc8804b66633faae5b7066571c9d68b4d14a (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.c71
-rw-r--r--common/cmd_pcmcia.c2
-rw-r--r--common/command.c153
-rw-r--r--common/hush.c85
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 {