* 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:
======================================================================
* 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:

48
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 :-).
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).

View 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);
}

View 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;
}
/****************************************************************************/

View 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

View 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
@ -48,12 +48,12 @@
*
*/
#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;
}
}