* 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.
This commit is contained in:
wdenk 2003-05-28 08:06:31 +00:00
parent 38b99261c1
commit f07771cc28
6 changed files with 178 additions and 127 deletions

View file

@ -2,6 +2,18 @@
Changes since U-Boot 0.3.1: 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!) * Add zero-copy ramdisk support (requires corresponding kernel support!)
* Patch by Kyle Harris, 20 May 2003: * Patch by Kyle Harris, 20 May 2003:

44
README
View file

@ -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 :-). 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: Note for Redundant Ethernet Interfaces:
======================================= =======================================
@ -2565,7 +2607,7 @@ Minicom warning:
Over time, many people have reported problems when trying to used the Over time, many people have reported problems when trying to used the
"minicom" terminal emulation program for serial download. I (wd) "minicom" terminal emulation program for serial download. I (wd)
consider minicom to be broken, and recommend not to use it. Under consider minicom to be broken, and recommend not to use it. Under
Unix, I recommend to use CKermit for general purpose use (and Unix, I recommend to use C-Kermit for general purpose use (and
especially for kermit binary protocol download ("loadb" command), and especially for kermit binary protocol download ("loadb" command), and
use "cu" for S-Record download ("loads" command). use "cu" for S-Record download ("loads" command).

View file

@ -431,7 +431,15 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
* handle word aligned part * handle word aligned part
*/ */
while (cnt >= 4) { while (cnt >= 4) {
if (((ulong)src) & 0x3) {
for (i = 0; i < 4; i++) {
((char *)&data)[i] = ((vu_char *)src)[i];
}
}
else {
data = *((vu_long *) src); data = *((vu_long *) src);
}
if ((rc = write_word (info, wp, data)) != 0) { if ((rc = write_word (info, wp, data)) != 0) {
return (rc); return (rc);
} }

View file

@ -746,9 +746,9 @@ int run_command (const char *cmd, int flag)
char finaltoken[CFG_CBSIZE]; char finaltoken[CFG_CBSIZE];
char *str = cmdbuf; char *str = cmdbuf;
char *argv[CFG_MAXARGS + 1]; /* NULL terminated */ char *argv[CFG_MAXARGS + 1]; /* NULL terminated */
int argc; int argc, inquotes;
int repeatable = 1; int repeatable = 1;
int inquotes; int rc = 0;
#ifdef DEBUG_PARSER #ifdef DEBUG_PARSER
printf ("[RUN_COMMAND] cmd[%p]=\"", cmd); printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
@ -817,13 +817,15 @@ int run_command (const char *cmd, int flag)
/* Look up command in command table */ /* Look up command in command table */
if ((cmdtp = find_cmd(argv[0])) == NULL) { if ((cmdtp = find_cmd(argv[0])) == NULL) {
printf ("Unknown command '%s' - try 'help'\n", argv[0]); 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 */ /* found - check max args */
if (argc > cmdtp->maxargs) { if (argc > cmdtp->maxargs) {
printf ("Usage:\n%s\n", cmdtp->usage); printf ("Usage:\n%s\n", cmdtp->usage);
return -1; rc = -1;
continue;
} }
#if (CONFIG_COMMANDS & CFG_CMD_BOOTD) #if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
@ -834,7 +836,8 @@ int run_command (const char *cmd, int flag)
#endif #endif
if (flag & CMD_FLAG_BOOTD) { if (flag & CMD_FLAG_BOOTD) {
printf ("'bootd' recursion detected\n"); printf ("'bootd' recursion detected\n");
return -1; rc = -1;
continue;
} }
else else
flag |= CMD_FLAG_BOOTD; flag |= CMD_FLAG_BOOTD;
@ -843,7 +846,7 @@ int run_command (const char *cmd, int flag)
/* OK - call function to do the command */ /* OK - call function to do the command */
if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
return (-1); rc = -1;
} }
repeatable &= cmdtp->repeatable; repeatable &= cmdtp->repeatable;
@ -853,7 +856,7 @@ int run_command (const char *cmd, int flag)
return 0; /* if stopped then not repeatable */ return 0; /* if stopped then not repeatable */
} }
return repeatable; return rc ? rc : repeatable;
} }
/****************************************************************************/ /****************************************************************************/

View file

@ -317,17 +317,15 @@ cpu_init_crit:
.macro bad_save_user_regs .macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12 stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
ldr r2, _armboot_end ldr r2, _armboot_end
add r2, r2, #CONFIG_STACKSIZE add r2, r2, #CONFIG_STACKSIZE
sub r2, r2, #8 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 r0, sp, #S_FRAME_SIZE @ restore sp_SVC
add r5, sp, #S_SP add r5, sp, #S_SP
mov r1, lr 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 mov r0, sp
.endm .endm

View file

@ -2,7 +2,7 @@
* (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Andreas Heppel <aheppel@sysgo.de> * Andreas Heppel <aheppel@sysgo.de>
* *
* (C) Copyright 2002 * (C) Copyright 2002, 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* *
* See file CREDITS for list of people who contributed to this * See file CREDITS for list of people who contributed to this
@ -148,8 +148,7 @@ struct pci_controller* pci_bus_to_hose(int bus)
struct pci_controller *hose; struct pci_controller *hose;
for (hose = hose_head; hose; hose = hose->next) for (hose = hose_head; hose; hose = hose->next)
if (bus >= hose->first_busno && if (bus >= hose->first_busno && bus <= hose->last_busno)
bus <= hose->last_busno)
return hose; return hose;
return NULL; return NULL;
@ -178,16 +177,13 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
#endif #endif
bdf += PCI_BDF(0,0,1)) bdf += PCI_BDF(0,0,1))
{ {
if (!PCI_FUNC(bdf)) if (!PCI_FUNC(bdf)) {
{
pci_read_config_byte(bdf, pci_read_config_byte(bdf,
PCI_HEADER_TYPE, PCI_HEADER_TYPE,
&header_type); &header_type);
found_multi = header_type & 0x80; found_multi = header_type & 0x80;
} } else {
else
{
if (!found_multi) if (!found_multi)
continue; continue;
} }
@ -236,14 +232,12 @@ unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
unsigned long bus_addr; unsigned long bus_addr;
int i; int i;
if (!hose) if (!hose) {
{
printf ("pci_hose_phys_to_bus: %s\n", "invalid hose"); printf ("pci_hose_phys_to_bus: %s\n", "invalid hose");
goto Done; goto Done;
} }
for (i=0; i<hose->region_count; i++) for (i = 0; i < hose->region_count; i++) {
{
res = &hose->regions[i]; res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
@ -252,8 +246,7 @@ unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
bus_addr = phys_addr - res->phys_start + res->bus_start; bus_addr = phys_addr - res->phys_start + res->bus_start;
if (bus_addr >= 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; return bus_addr;
} }
} }
@ -271,22 +264,19 @@ unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
struct pci_region *res; struct pci_region *res;
int i; int i;
if (!hose) if (!hose) {
{
printf ("pci_hose_bus_to_phys: %s\n", "invalid hose"); printf ("pci_hose_bus_to_phys: %s\n", "invalid hose");
goto Done; goto Done;
} }
for (i=0; i<hose->region_count; i++) for (i = 0; i < hose->region_count; i++) {
{
res = &hose->regions[i]; res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue; continue;
if (bus_addr >= 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 - res->bus_start + res->phys_start; return bus_addr - res->bus_start + res->phys_start;
} }
} }
@ -311,12 +301,12 @@ int pci_hose_config_device(struct pci_controller *hose,
unsigned char pin; unsigned char pin;
int bar, found_mem64; 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) for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4) {
{
pci_hose_write_config_dword (hose, dev, bar, 0xffffffff); pci_hose_write_config_dword (hose, dev, bar, 0xffffffff);
pci_hose_read_config_dword (hose, dev, bar, &bar_response); pci_hose_read_config_dword (hose, dev, bar, &bar_response);
@ -326,30 +316,31 @@ int pci_hose_config_device(struct pci_controller *hose,
found_mem64 = 0; found_mem64 = 0;
/* Check the BAR type and set our address mask */ /* 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_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; io = ((io - 1) | (bar_size - 1)) + 1;
} bar_value = io;
else /* compute new region base address */
{ io = io + bar_size;
} else {
if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
PCI_BASE_ADDRESS_MEM_TYPE_64) PCI_BASE_ADDRESS_MEM_TYPE_64)
found_mem64 = 1; found_mem64 = 1;
bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 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; 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 */ /* 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; bar += 4;
pci_hose_write_config_dword (hose, dev, bar, 0x00000000); pci_hose_write_config_dword (hose, dev, bar, 0x00000000);
} }
@ -363,8 +354,7 @@ int pci_hose_config_device(struct pci_controller *hose,
/* Disable interrupt line, if device says it wants to use interrupts */ /* Disable interrupt line, if device says it wants to use interrupts */
pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin); pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin);
if (pin != 0) if (pin != 0) {
{
pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff); pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff);
} }
@ -389,15 +379,13 @@ struct pci_config_table *pci_find_config(struct pci_controller *hose,
{ {
struct pci_config_table *table; 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) && if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
(table->device == PCI_ANY_ID || table->device == device) && (table->device == PCI_ANY_ID || table->device == device) &&
(table->class == PCI_ANY_ID || table->class == class) && (table->class == PCI_ANY_ID || table->class == class) &&
(table->bus == PCI_ANY_ID || table->bus == bus) && (table->bus == PCI_ANY_ID || table->bus == bus) &&
(table->dev == PCI_ANY_ID || table->dev == dev) && (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; return table;
} }
} }