* Fix data abort exception handling for arm920t CPU
authorwdenk <wdenk>
Wed, 28 May 2003 08:06:31 +0000 (08:06 +0000)
committerwdenk <wdenk>
Wed, 28 May 2003 08:06:31 +0000 (08:06 +0000)
* Fix alignment problems with flash driver for TRAB board

* Patch by Donald White, 21 May 2003:
  fix calculation of base address in pci_hose_config_device()

* Fix bug in command line parsing: "cmd1;cmd2" is supposed to always
  execute "cmd2", even if "cmd1" fails. Note that this is different
  to "run var1 var2" where the contents of "var2" will NOT be
  executed when a command in "var1" fails.

CHANGELOG
README
board/trab/flash.c
common/main.c
cpu/arm920t/start.S
drivers/pci.c

index 10ae064..f28631a 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,18 @@
 Changes since U-Boot 0.3.1:
 ======================================================================
 
+* Fix data abort exception handling for arm920t CPU
+
+* Fix alignment problems with flash driver for TRAB board
+
+* Patch by Donald White, 21 May 2003:
+  fix calculation of base address in pci_hose_config_device()
+
+* Fix bug in command line parsing: "cmd1;cmd2" is supposed to always
+  execute "cmd2", even if "cmd1" fails. Note that this is different
+  to "run var1 var2" where the contents of "var2" will NOT be
+  executed when a command in "var1" fails.
+
 * Add zero-copy ramdisk support (requires corresponding kernel support!)
 
 * Patch by Kyle Harris, 20 May 2003:
diff --git a/README b/README
index ecc087a..e9b7145 100644 (file)
--- a/README
+++ b/README
@@ -2048,6 +2048,48 @@ Please note that changes to some configuration parameters may take
 only effect after the next boot (yes, that's just like Windoze :-).
 
 
+Command Line Parsing:
+=====================
+
+There are two different command line parsers available  with  U-Boot:
+the old "simple" one, and the much more pwerful "hush" shell:
+
+Old, simple command line parser:
+--------------------------------
+
+- supports environment variables (through setenv / saveenv commands)
+- several commands on one line, separated by ';'
+- variable substitution using "... $(name) ..." syntax
+- special characters ('$', ';') can be escaped by prefixing with '\',
+  for example:
+       setenv bootcmd bootm \$(address)
+- You can also escape text by enclosing in single apostrophes, for example:
+       setenv addip 'setenv bootargs $bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname::off'
+
+Hush shell:
+-----------
+
+- similar to Bourne shell, with control structures like
+  if...then...else...fi, for...do...done; while...do...done,
+  until...do...done, ...
+- supports environment ("global") variables (through setenv / saveenv
+  commands) and local shell variables (through standard shell syntax
+  "name=value"); only environment variables can be used with "run"
+  command
+
+General rules:
+--------------
+
+(1) If a command line (or an environment variable executed by a "run"
+    command) contains several commands separated by semicolon, and
+    one of these commands fails, then the remaining commands will be
+    executed anyway.
+
+(2) If you execute several variables with one call to run (i. e.
+    calling run with a list af variables as arguments), any failing
+    command will cause "run" to terminate, i. e. the remaining
+    variables are not executed.
+
 Note for Redundant Ethernet Interfaces:
 =======================================
 
@@ -2563,9 +2605,9 @@ Minicom warning:
 ================
 
 Over time, many people have reported problems when trying to used the
-"minicom" terminal emulation program  for  serial  download.  I  (wd)
-consider  minicom  to  be  broken, and recommend not to use it. Under
-Unix, I recommend  to  use  CKermit  for  general  purpose  use  (and
+"minicom" terminal emulation program for serial download. I (wd)
+consider minicom to be broken, and recommend not to use it. Under
+Unix, I recommend to use C-Kermit for general purpose use (and
 especially for kermit binary protocol download ("loadb" command), and
 use "cu" for S-Record download ("loads" command).
 
index 27c2a5b..1550e17 100644 (file)
@@ -431,7 +431,15 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
         * handle word aligned part
         */
        while (cnt >= 4) {
-               data = *((vu_long *) src);
+               if (((ulong)src) & 0x3) {
+                       for (i = 0; i < 4; i++) {
+                               ((char *)&data)[i] = ((vu_char *)src)[i];
+                       }
+               }
+               else {
+                       data = *((vu_long *) src);
+               }
+                       
                if ((rc = write_word (info, wp, data)) != 0) {
                        return (rc);
                }
index fe4ebb4..6192dff 100644 (file)
@@ -746,9 +746,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 +817,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)
@@ -834,7 +836,8 @@ int run_command (const char *cmd, int flag)
 #endif
                        if (flag & CMD_FLAG_BOOTD) {
                                printf ("'bootd' recursion detected\n");
-                               return -1;
+                               rc = -1;
+                               continue;
                        }
                        else
                                flag |= CMD_FLAG_BOOTD;
@@ -843,7 +846,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 +856,7 @@ int run_command (const char *cmd, int flag)
                        return 0;       /* if stopped then not repeatable */
        }
 
-       return repeatable;
+       return rc ? rc : repeatable;
 }
 
 /****************************************************************************/
index 4a4825a..ed16176 100644 (file)
@@ -317,17 +317,15 @@ cpu_init_crit:
        .macro  bad_save_user_regs
        sub     sp, sp, #S_FRAME_SIZE
        stmia   sp, {r0 - r12}                  @ Calling r0-r12
-       add     r8, sp, #S_PC
-
        ldr     r2, _armboot_end
        add     r2, r2, #CONFIG_STACKSIZE
        sub     r2, r2, #8
-       ldmia   r2, {r2 - r4}                   @ get pc, cpsr, old_r0
+       ldmia   r2, {r2 - r3}                   @ get pc, cpsr
        add     r0, sp, #S_FRAME_SIZE           @ restore sp_SVC
 
        add     r5, sp, #S_SP
        mov     r1, lr
-       stmia   r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_r
+       stmia   r5, {r0 - r3}                   @ save sp_SVC, lr_SVC, pc, cpsr
        mov     r0, sp
        .endm
 
index 9eaaa15..289db8f 100644 (file)
@@ -2,7 +2,7 @@
  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  * Andreas Heppel <aheppel@sysgo.de>
  *
- * (C) Copyright 2002
+ * (C) Copyright 2002, 2003
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
  *
  */
 
-#define PCI_HOSE_OP(rw, size, type)                                            \
-int pci_hose_##rw##_config_##size(struct pci_controller *hose,                         \
-                                 pci_dev_t dev,                                \
-                                 int offset, type value)                       \
-{                                                                              \
-       return hose->rw##_##size(hose, dev, offset, value);                     \
+#define PCI_HOSE_OP(rw, size, type)                                    \
+int pci_hose_##rw##_config_##size(struct pci_controller *hose,                 \
+                                 pci_dev_t dev,                        \
+                                 int offset, type value)               \
+{                                                                      \
+       return hose->rw##_##size(hose, dev, offset, value);             \
 }
 
 PCI_HOSE_OP(read, byte, u8 *)
@@ -63,18 +63,18 @@ PCI_HOSE_OP(write, byte, u8)
 PCI_HOSE_OP(write, word, u16)
 PCI_HOSE_OP(write, dword, u32)
 
-#define PCI_OP(rw, size, type, error_code)                                     \
-int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)            \
-{                                                                              \
-       struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));            \
-                                                                               \
-       if (!hose)                                                              \
-       {                                                                       \
-               error_code;                                                     \
-               return -1;                                                      \
-       }                                                                       \
-                                                                               \
-       return pci_hose_##rw##_config_##size(hose, dev, offset, value);         \
+#define PCI_OP(rw, size, type, error_code)                             \
+int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)    \
+{                                                                      \
+       struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));    \
+                                                                       \
+       if (!hose)                                                      \
+       {                                                               \
+               error_code;                                             \
+               return -1;                                              \
+       }                                                               \
+                                                                       \
+       return pci_hose_##rw##_config_##size(hose, dev, offset, value); \
 }
 
 PCI_OP(read, byte, u8 *, *value = 0xff)
@@ -84,40 +84,40 @@ PCI_OP(write, byte, u8, )
 PCI_OP(write, word, u16, )
 PCI_OP(write, dword, u32, )
 
-#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)                            \
-int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,       \
-                                       pci_dev_t dev,                          \
-                                       int offset, type val)                   \
-{                                                                              \
-       u32 val32;                                                              \
-                                                                               \
-       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)   \
-               return -1;                                                      \
-                                                                               \
-       *val = (val32 >> ((offset & (int)off_mask) * 8));                       \
-                                                                               \
-       return 0;                                                               \
+#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)                    \
+int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
+                                       pci_dev_t dev,                  \
+                                       int offset, type val)           \
+{                                                                      \
+       u32 val32;                                                      \
+                                                                       \
+       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
+               return -1;                                              \
+                                                                       \
+       *val = (val32 >> ((offset & (int)off_mask) * 8));               \
+                                                                       \
+       return 0;                                                       \
 }
 
-#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)                 \
-int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,      \
-                                            pci_dev_t dev,                     \
-                                            int offset, type val)              \
-{                                                                              \
-       u32 val32, mask, ldata;                                                 \
-                                                                               \
-       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)   \
-               return -1;                                                      \
-                                                                               \
-       mask = val_mask;                                                        \
+#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)         \
+int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
+                                            pci_dev_t dev,             \
+                                            int offset, type val)      \
+{                                                                      \
+       u32 val32, mask, ldata;                                         \
+                                                                       \
+       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
+               return -1;                                              \
+                                                                       \
+       mask = val_mask;                                                \
        ldata = (((unsigned long)val) & mask) << ((offset & (int)off_mask) * 8);\
-       mask <<= ((mask & (int)off_mask) * 8);                                  \
-       val32 = (val32 & ~mask) | ldata;                                        \
-                                                                               \
-       if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)   \
-               return -1;                                                      \
-                                                                               \
-       return 0;                                                               \
+       mask <<= ((mask & (int)off_mask) * 8);                          \
+       val32 = (val32 & ~mask) | ldata;                                \
+                                                                       \
+       if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\
+               return -1;                                              \
+                                                                       \
+       return 0;                                                       \
 }
 
 PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
@@ -143,13 +143,12 @@ void pci_register_hose(struct pci_controller* hose)
        *phose = hose;
 }
 
-struct pci_controller* pci_bus_to_hose(int bus)
+struct pci_controller *pci_bus_to_hose (int bus)
 {
        struct pci_controller *hose;
 
        for (hose = hose_head; hose; hose = hose->next)
-               if (bus >= hose->first_busno &&
-                   bus <= hose->last_busno)
+               if (bus >= hose->first_busno && bus <= hose->last_busno)
                        return hose;
 
        return NULL;
@@ -178,16 +177,13 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
 #endif
                             bdf += PCI_BDF(0,0,1))
                        {
-                               if (!PCI_FUNC(bdf))
-                               {
+                               if (!PCI_FUNC(bdf)) {
                                        pci_read_config_byte(bdf,
                                                             PCI_HEADER_TYPE,
                                                             &header_type);
 
                                        found_multi = header_type & 0x80;
-                               }
-                               else
-                               {
+                               } else {
                                        if (!found_multi)
                                                continue;
                                }
@@ -228,22 +224,20 @@ pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
  *
  */
 
-unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
-                                  unsigned long phys_addr,
-                                  unsigned long flags)
+unsigned long pci_hose_phys_to_bus (struct pci_controller *hose,
+                                   unsigned long phys_addr,
+                                   unsigned long flags)
 {
        struct pci_region *res;
        unsigned long bus_addr;
        int i;
 
-       if (!hose)
-       {
-               printf("pci_hose_phys_to_bus: %s\n", "invalid hose");
+       if (!hose) {
+               printf ("pci_hose_phys_to_bus: %s\n", "invalid hose");
                goto Done;
        }
 
-       for (i=0; i<hose->region_count; i++)
-       {
+       for (i = 0; i < hose->region_count; i++) {
                res = &hose->regions[i];
 
                if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
@@ -252,15 +246,14 @@ unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
                bus_addr = phys_addr - res->phys_start + res->bus_start;
 
                if (bus_addr >= res->bus_start &&
-                   bus_addr <  res->bus_start + res->size)
-               {
+                       bus_addr < res->bus_start + res->size) {
                        return bus_addr;
                }
        }
 
-       printf("pci_hose_phys_to_bus: %s\n", "invalid physical address");
+       printf ("pci_hose_phys_to_bus: %s\n", "invalid physical address");
 
- Done:
+Done:
        return 0;
 }
 
@@ -271,29 +264,26 @@ unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
        struct pci_region *res;
        int i;
 
-       if (!hose)
-       {
-               printf("pci_hose_bus_to_phys: %s\n", "invalid hose");
+       if (!hose) {
+               printf ("pci_hose_bus_to_phys: %s\n", "invalid hose");
                goto Done;
        }
 
-       for (i=0; i<hose->region_count; i++)
-       {
+       for (i = 0; i < hose->region_count; i++) {
                res = &hose->regions[i];
 
                if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
                        continue;
 
                if (bus_addr >= res->bus_start &&
-                   bus_addr <  res->bus_start + res->size)
-               {
+                       bus_addr < res->bus_start + res->size) {
                        return bus_addr - res->bus_start + res->phys_start;
                }
        }
 
-       printf("pci_hose_bus_to_phys: %s\n", "invalid physical address");
+       printf ("pci_hose_bus_to_phys: %s\n", "invalid physical address");
 
- Done:
+Done:
        return 0;
 }
 
@@ -311,14 +301,14 @@ int pci_hose_config_device(struct pci_controller *hose,
        unsigned char pin;
        int bar, found_mem64;
 
-       DEBUGF("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n", io, mem, command);
+       DEBUGF ("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n",
+               io, mem, command);
 
-       pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0);
+       pci_hose_write_config_dword (hose, dev, PCI_COMMAND, 0);
 
-       for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4)
-       {
-               pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
-               pci_hose_read_config_dword(hose, dev, bar, &bar_response);
+       for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4) {
+               pci_hose_write_config_dword (hose, dev, bar, 0xffffffff);
+               pci_hose_read_config_dword (hose, dev, bar, &bar_response);
 
                if (!bar_response)
                        continue;
@@ -326,51 +316,51 @@ int pci_hose_config_device(struct pci_controller *hose,
                found_mem64 = 0;
 
                /* Check the BAR type and set our address mask */
-               if (bar_response & PCI_BASE_ADDRESS_SPACE)
-               {
+               if (bar_response & PCI_BASE_ADDRESS_SPACE) {
                        bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
-                       bar_value = io;
-
+                       /* round up region base address to a multiple of size */
                        io = ((io - 1) | (bar_size - 1)) + 1;
-               }
-               else
-               {
-                       if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-                            PCI_BASE_ADDRESS_MEM_TYPE_64)
+                       bar_value = io;
+                       /* compute new region base address */
+                       io = io + bar_size;
+               } else {
+                       if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+                               PCI_BASE_ADDRESS_MEM_TYPE_64)
                                found_mem64 = 1;
 
                        bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
-                       bar_value = mem;
 
+                       /* round up region base address to multiple of size */
                        mem = ((mem - 1) | (bar_size - 1)) + 1;
+                       bar_value = mem;
+                       /* compute new region base address */
+                       mem = mem + bar_size;
                }
 
                /* Write it out and update our limit */
-               pci_hose_write_config_dword(hose, dev, bar, bar_value);
+               pci_hose_write_config_dword (hose, dev, bar, bar_value);
 
-               if (found_mem64)
-               {
+               if (found_mem64) {
                        bar += 4;
-                       pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
+                       pci_hose_write_config_dword (hose, dev, bar, 0x00000000);
                }
        }
 
        /* Configure Cache Line Size Register */
-       pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+       pci_hose_write_config_byte (hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
 
        /* Configure Latency Timer */
-       pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+       pci_hose_write_config_byte (hose, dev, PCI_LATENCY_TIMER, 0x80);
 
        /* Disable interrupt line, if device says it wants to use interrupts */
-       pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
-       if (pin != 0)
-       {
-               pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff);
+       pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin);
+       if (pin != 0) {
+               pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff);
        }
 
-       pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command);
-       pci_hose_write_config_dword(hose, dev, PCI_COMMAND,
-                                   (old_command & 0xffff0000) | command );
+       pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &old_command);
+       pci_hose_write_config_dword (hose, dev, PCI_COMMAND,
+                                    (old_command & 0xffff0000) | command);
 
        return 0;
 }
@@ -389,15 +379,13 @@ struct pci_config_table *pci_find_config(struct pci_controller *hose,
 {
        struct pci_config_table *table;
 
-       for (table = hose->config_table; table && table->vendor; table++)
-       {
+       for (table = hose->config_table; table && table->vendor; table++) {
                if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
                    (table->device == PCI_ANY_ID || table->device == device) &&
                    (table->class  == PCI_ANY_ID || table->class  == class)  &&
                    (table->bus    == PCI_ANY_ID || table->bus    == bus)    &&
                    (table->dev    == PCI_ANY_ID || table->dev    == dev)    &&
-                   (table->func   == PCI_ANY_ID || table->func   == func))
-               {
+                   (table->func   == PCI_ANY_ID || table->func   == func)) {
                        return table;
                }
        }