Initial revision

This commit is contained in:
wdenk 2002-11-02 22:58:18 +00:00
parent 1a4d6164af
commit cc1c8a136f
17 changed files with 6163 additions and 0 deletions

12
CHANGELOG Normal file
View File

@ -0,0 +1,12 @@
======================================================================
Notes for U-Boot 1.0.0:
======================================================================
This is the initial version of "Das U-Boot", the Universal Boot Loader.
It is based on version 2.0.0 (the "Halloween Release") of PPCBoot.
For information about the history of the project please see the
PPCBoot project page at http://sourceforge.net/projects/ppcboot
======================================================================

249
MAINTAINERS Normal file
View File

@ -0,0 +1,249 @@
#########################################################################
# #
# Regular Maintainers for U-Boot board support: #
# #
# For any board without permanent maintainer, please contact #
# for PowerPC systems: #
# Wolfgang Denk <wd@denx.de> #
# for ARM systems: #
# Marius Gröger <mag@sysgo.de> #
# and Cc: the <U-Boot-Users@lists.sourceforge.net> mailing lists. #
# #
# Note: lists sorted by Maintainer Name #
#########################################################################
#########################################################################
# #
# Maintainer Name, Email Address #
# Board CPU #
#########################################################################
Greg Allen <gallen@arlut.utexas.edu>
UTX8245 MPC8245
Pantelis Antoniou <panto@intracom.gr>
NETVIA MPC8xx
Jerry Van Baren <vanbaren_gerald@si.com>
sacsng MPC8260
Oliver Brown <obrown@adventnetworks.com>
sbc8260 MPC8260
gw8260 MPC8260
Conn Clark <clark@esteem.com>
ESTEEM192E MPC8xx
Kári Davíðsson <kd@flaga.is>
FLAGADM MPC823
Wolfgang Denk <wd@denx.de>
AMX860 MPC860
ETX094 MPC850
FPS850L MPC850
ICU862 MPC862
IP860 MPC860
IVML24 MPC860
IVML24_128 MPC860
IVML24_256 MPC860
IVMS8 MPC860
IVMS8_128 MPC860
IVMS8_256 MPC860
LANTEC MPC850
RRvision MPC823
SM850 MPC850
SPD823TS MPC823
TQM823L MPC823
TQM823L_LCD MPC823
TQM850L MPC850
TQM855L MPC855
TQM860L MPC860
TQM860L_FEC MPC860
c2mon MPC855
hermes MPC860
lwmon MPC823
pcu_e MPC855
CU824 MPC8240
Sandpoint8240 MPC8240
CPU86 MPC8260
PM826 MPC8260
TQM8260 MPC8260
PCIPPC2 MPC750
PCIPPC6 MPC750
Jon Diekema <diekema_jon@si.com>
sbc8260 MPC8260
Dave Ellis <DGE@sixnetio.com>
SXNI855T MPC8xx
Frank Gottschling <fgottschling@eltec.de>
MHPC MPC8xx
BAB7xx MPC740/MPC750
Wolfgang Grandegger <wg@denx.de>
CCM MPC855
PN62 MPC8240
IPHASE4539 MPC8260
SCM MPC8260
Howard Gray <mvsensor@matrix-vision.de>
MVS1 MPC823
Murray Jensen <Murray.Jensen@cmst.csiro.au>
cogent_mpc8xx MPC8xx
cogent_mpc8260 MPC8260
hymod MPC8260
Brad Kemp <Brad.Kemp@seranoa.com>
ppmc8260 MPC8260
Nye Liu <nyet@zumanetworks.com>
ZUMA MPC7xx_74xx
Thomas Lange <thomas@corelatus.com>
GTH MPC860
Eran Man <eran@nbase.co.il>
EVB64260_750CX MPC750CX
Scott McNutt <smcnutt@artesyncp.com>
EBONY PPC440GP
Keith Outwater <Keith_Outwater@mvis.com>
GEN860T MPC860T
Frank Panno <fpanno@delphintech.com>
ep8260 MPC8260
Denis Peter <d.peter@mpl.ch>
MIP405 PPC4xx
PIP405 PPC4xx
Stefan Roese <stefan.roese@esd-electronics.com>
ADCIOP IOP480 (PPC401)
AR405 PPC405GP
CANBT PPC405CR
CPCI405 PPC405GP
CPCI440 PPC440GP
CPCIISER4 PPC405GP
DASA_SIM IOP480 (PPC401)
DU405 PPC405GP
OCRTC PPC405GP
ORSG PPC405GP
Peter De Schrijver <p2@mind.be>
ML2 PPC4xx
Erik Theisen <etheisen@mindspring.com>
W7OLMC PPC4xx
W7OLMG PPC4xx
Jim Thompson <jim@musenki.com>
MUSENKI MPC8245/8241
Sandpoint8245 MPC8245
-------------------------------------------------------------------------
Unknown / orphaned boards:
ADS860 MPC8xx
FADS823 MPC8xx
FADS850SAR MPC8xx
FADS860T MPC8xx
GENIETV MPC8xx
IAD210 MPC8xx
MBX MPC8xx
MBX860T MPC8xx
NX823 MPC8xx
RPXClassic MPC8xx
RPXlite MPC8xx
CRAYL1 PPC4xx
ERIC PPC4xx
WALNUT405 PPC4xx
MOUSSE MPC824x
MPC8260ADS MPC8260
RPXsuper MPC8260
rsdproto MPC8260
EVB64260 MPC7xx_74xx
#########################################################################
# ARM Systems: #
# #
# Maintainer Name, Email Address #
# Board CPU #
#########################################################################
Marius Gröger <mag@sysgo.de>
impa7 ARM720T (EP7211)
ep7312 ARM720T (EP7312)
Kyle Harris <kharris@nexus-tech.net>
lubbock xscale
cradle xscale
Gary Jennejohn <gj@denx.de>
smdk2400 ARM920T
trab ARM920T
David Müller <d.mueller@elsoft.ch>
smdk2410 ARM920T
Rolf Offermanns <rof@sysgo.de>
shannon SA1100
Robert Schwebel <r.schwebel@pengutronix.de>
csb226 xscale
Alex Züpke <azu@sysgo.de>
lart SA1100
dnp1110 SA1110
#########################################################################
# End of MAINTAINERS list #
#########################################################################

615
board/cpu86/flash.c Normal file
View File

@ -0,0 +1,615 @@
/*
* (C) Copyright 2001, 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Flash Routines for Intel devices
*
*--------------------------------------------------------------------
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc8xx.h>
#include "cpu86.h"
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*-----------------------------------------------------------------------
*/
ulong flash_int_get_size (volatile unsigned long *baseaddr,
flash_info_t * info)
{
short i;
unsigned long flashtest_h, flashtest_l;
info->sector_count = info->size = 0;
info->flash_id = FLASH_UNKNOWN;
/* Write query command sequence and test FLASH answer
*/
baseaddr[0] = 0x00980098;
baseaddr[1] = 0x00980098;
flashtest_h = baseaddr[0]; /* manufacturer ID */
flashtest_l = baseaddr[1];
if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
return (0); /* no or unknown flash */
flashtest_h = baseaddr[2]; /* device ID */
flashtest_l = baseaddr[3];
if (flashtest_h != flashtest_l)
return (0);
switch (flashtest_h) {
case INTEL_ID_28F160C3B:
info->flash_id = FLASH_28F160C3B;
info->sector_count = 39;
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
break;
case INTEL_ID_28F160F3B:
info->flash_id = FLASH_28F160F3B;
info->sector_count = 39;
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
break;
default:
return (0); /* no or unknown flash */
}
info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */
if (info->flash_id & FLASH_BTYPE) {
volatile unsigned long *tmp = baseaddr;
/* set up sector start adress table (bottom sector type)
* AND unlock the sectors (if our chip is 160C3)
*/
for (i = 0; i < info->sector_count; i++) {
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) {
tmp[0] = 0x00600060;
tmp[1] = 0x00600060;
tmp[0] = 0x00D000D0;
tmp[1] = 0x00D000D0;
}
info->start[i] = (uint) tmp;
tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith */
}
}
memset (info->protect, 0, info->sector_count);
baseaddr[0] = 0x00FF00FF;
baseaddr[1] = 0x00FF00FF;
return (info->size);
}
static ulong flash_amd_get_size (vu_char *addr, flash_info_t *info)
{
short i;
uchar vendor, devid;
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x90;
udelay(1000);
vendor = addr[0];
devid = addr[1] & 0xff;
/* only support AMD */
if (vendor != 0x01) {
return 0;
}
vendor &= 0xf;
devid &= 0xff;
if (devid == AMD_ID_F040B) {
info->flash_id = vendor << 16 | devid;
info->sector_count = 8;
info->size = info->sector_count * 0x10000;
}
else if (devid == AMD_ID_F080B) {
info->flash_id = vendor << 16 | devid;
info->sector_count = 16;
info->size = 4 * info->sector_count * 0x10000;
}
else if (devid == AMD_ID_F016D) {
info->flash_id = vendor << 16 | devid;
info->sector_count = 32;
info->size = 4 * info->sector_count * 0x10000;
}
else {
printf ("## Unknown Flash Type: %02x\n", devid);
return 0;
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* sector base address */
info->start[i] = base + i * (info->size / info->sector_count);
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr = (volatile unsigned char *)(info->start[i]);
info->protect[i] = addr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (vu_char *)info->start[0];
addr[0] = 0xF0; /* reset bank */
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size_b0 = 0;
unsigned long size_b1 = 0;
int i;
/* Init: no FLASHes known
*/
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Disable flash protection */
CPU86_BCR |= (CPU86_BCR_FWPT | CPU86_BCR_FWRE);
/* Static FLASH Bank configuration here (only one bank) */
size_b0 = flash_int_get_size ((ulong *) CFG_FLASH_BASE, &flash_info[0]);
size_b1 = flash_amd_get_size ((uchar *) CFG_BOOTROM_BASE, &flash_info[1]);
if (size_b0 > 0 || size_b1 > 0) {
printf("(");
if (size_b0 > 0) {
puts ("Bank#1 - ");
print_size (size_b0, (size_b1 > 0) ? ", " : ") ");
}
if (size_b1 > 0) {
puts ("Bank#2 - ");
print_size (size_b1, ") ");
}
}
else {
printf ("## No FLASH found.\n");
return 0;
}
/* protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_BOOTROM_BASE
if (size_b1) {
/* If U-Boot is booted from ROM the CFG_MONITOR_BASE > CFG_FLASH_BASE
* but we shouldn't protect it.
*/
flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, &flash_info[1]
);
}
#else
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, &flash_info[0]
);
#endif
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# if CFG_ENV_ADDR >= CFG_BOOTROM_BASE
if (size_b1) {
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[1]);
}
# else
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
# endif
#endif
return (size_b0 + size_b1);
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t * info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch ((info->flash_id >> 16) & 0xff) {
case 0x89:
printf ("INTEL ");
break;
case 0x1:
printf ("AMD ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F160C3B:
printf ("28F160C3B (16 Mbit, bottom sector)\n");
break;
case FLASH_28F160F3B:
printf ("28F160F3B (16 Mbit, bottom sector)\n");
break;
case AMD_ID_F040B:
printf ("AM29F040B (4 Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
if (info->size < 0x100000)
printf (" Size: %ld KB in %d Sectors\n",
info->size >> 10, info->sector_count);
else
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
vu_char *addr = (vu_char *)(info->start[0]);
int flag, prot, sect, l_sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect])
prot++;
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
/* Check the type of erased flash
*/
if (info->flash_id >> 16 == 0x1) {
/* Erase AMD flash
*/
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x80;
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_char *)(info->start[sect]);
addr[0] = 0x30;
l_sect = sect;
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto AMD_DONE;
start = get_timer (0);
last = start;
addr = (vu_char *)(info->start[l_sect]);
while ((addr[0] & 0x80) != 0x80) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
serial_putc ('.');
last = now;
}
}
AMD_DONE:
/* reset to read mode */
addr = (volatile unsigned char *)info->start[0];
addr[0] = 0xF0; /* reset bank */
} else {
/* Erase Intel flash
*/
/* Start erase on unprotected sectors
*/
for (sect = s_first; sect <= s_last; sect++) {
volatile ulong *addr =
(volatile unsigned long *) info->start[sect];
start = get_timer (0);
last = start;
if (info->protect[sect] == 0) {
/* Disable interrupts which might cause a timeout here
*/
flag = disable_interrupts ();
/* Erase the block
*/
addr[0] = 0x00200020;
addr[1] = 0x00200020;
addr[0] = 0x00D000D0;
addr[1] = 0x00D000D0;
/* re-enable interrupts if necessary
*/
if (flag)
enable_interrupts ();
/* wait at least 80us - let's wait 1 ms
*/
udelay (1000);
last = start;
while ((addr[0] & 0x00800080) != 0x00800080 ||
(addr[1] & 0x00800080) != 0x00800080) {
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout (erase suspended!)\n");
/* Suspend erase
*/
addr[0] = 0x00B000B0;
addr[1] = 0x00B000B0;
goto DONE;
}
/* show that we're waiting
*/
if ((now - last) > 1000) { /* every second */
serial_putc ('.');
last = now;
}
}
if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
printf ("*** ERROR: erase failed!\n");
goto DONE;
}
}
/* Clear status register and reset to read mode
*/
addr[0] = 0x00500050;
addr[1] = 0x00500050;
addr[0] = 0x00FF00FF;
addr[1] = 0x00FF00FF;
}
}
printf (" done\n");
DONE:
return 0;
}
static int write_word (flash_info_t *, volatile unsigned long *, ulong);
static int write_byte (flash_info_t *info, ulong dest, uchar data);
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong v;
int i, l, rc, cc = cnt, res = 0;
if (info->flash_id >> 16 == 0x1) {
/* Write to AMD 8-bit flash
*/
while (cnt > 0) {
if ((rc = write_byte(info, addr, *src)) != 0) {
return (rc);
}
addr++;
src++;
cnt--;
}
return (0);
} else {
/* Write to Intel 64-bit flash
*/
for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
l = (addr & 3);
addr &= ~3;
for (i = 0; i < 4; i++) {
v = (v << 8) + (i < l || i - l >= cc ?
*((unsigned char *) addr + i) : *src++);
}
if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
break;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t * info, volatile unsigned long *addr,
ulong data)
{
int flag, res = 0;
ulong start;
/* Check if Flash is (sufficiently) erased
*/
if ((*addr & data) != data)
return (2);
/* Disable interrupts which might cause a timeout here
*/
flag = disable_interrupts ();
*addr = 0x00400040;
*addr = data;
/* re-enable interrupts if necessary
*/
if (flag)
enable_interrupts ();
start = get_timer (0);
while ((*addr & 0x00800080) != 0x00800080) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
/* Suspend program
*/
*addr = 0x00B000B0;
res = 1;
goto OUT;
}
}
if (*addr & 0x00220022) {
printf ("*** ERROR: program failed!\n");
res = 1;
}
OUT:
/* Clear status register and reset to read mode
*/
*addr = 0x00500050;
*addr = 0x00FF00FF;
return (res);
}
/*-----------------------------------------------------------------------
* Write a byte to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_byte (flash_info_t *info, ulong dest, uchar data)
{
vu_char *addr = (vu_char *)(info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_char *)dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0xA0;
*((vu_char *)dest) = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
return (0);
}
/*-----------------------------------------------------------------------
*/

127
board/lwmon/README.keybd Normal file
View File

@ -0,0 +1,127 @@
Tastaturabfrage:
Die Implementierung / Decodierung beruht auf den Angaben aus dem Do-
kument "PIC LWE-Tastatur" in der Fassung vom 9. 3. 2001, insbesonde-
re Tabelle 3 im Kapitel 4.3 Tastencodes. In U-Boot werden die vom
Keyboard-Controller gelesenen Daten hexadezimal codiert in der auto-
matisch angelegten Environment-Variablen "keybd" übergeben. Ist kei-
ne Taste gedrückt worden, steht dort:
keybd=000000000000000000
Der decodierte Tastencode ("keybd") kann mit den "bootargs" an den
Linux-Kernel übergeben und dort z. B. in einem Device-Treiber oder
einer Applikation ausgewertet werden.
Sonderfunktionen beim Booten:
Es lassen sich eine oder mehrere (beliebig viele) Tasten oder Tasten-
kombinationen definieren, die Sonderfunktionen auslösen, wenn diese
Tasten beim Booten (Reset) gedrückt sind.
Wird eine eingestellte Taste bzw. Tastenkombination erkannt, so wird
in U-Boot noch vor dem Start des "Countdown" und somit vor jedem an-
deren Kommando der Inhalt einer dieser Taste bzw. Tastenkombination
zugeordneten Environment-Variablen ausführen.
Die Environment-Variable "magic_keys" wird als Liste von Zeichen ver-
standen, die als Suffix an den Namen "key_magic" angefügt werden und
so die Namen der Environment-Variablen definieren, mit denen die
Tasten (-kombinationen) festgelegt werden:
Ist "magic_keys" NICHT definiert, so wird nur die in der Environment-
Variablen "key_magic" codierte Tasten (-kombination) geprüft, und
ggf. der Inhalt der Environment-Variablen "key_cmd" ausgeführt (ge-
nauer: der Inhalt von "key_cmd" wird der Variablen "preboot" zugewie-
sen, die ausgeführt wird, unmittelbar bevor die interaktive Kommando-
interpretation beginnt).
Enthält "magic_keys" z. B. die Zeichenkette "0123CB*", so werden
nacheinander folgende Aktionen ausgeführt:
prüfe Tastencode ggf. führe aus Kommando
in Variable in Variable
-----------------------------------
key_magic0 ==> key_cmd0
key_magic1 ==> key_cmd1
key_magic2 ==> key_cmd2
key_magic3 ==> key_cmd3
key_magicC ==> key_cmdC
key_magicB ==> key_cmdB
key_magicA ==> key_cmdA
key_magic* ==> key_cmd*
Hinweis: sobald ein aktivierter Tastencode erkannt wurde, wird die
Bearbeitung abgebrochen; es wird daher höchstens eines der definier-
ten Kommandos ausgeführt, wobei die Priorität durch die Suchreihen-
folge festgelegt wird, also durch die Reihenfolge der Zeichen in der
Varuiablen "magic_keys".
Die Codierung der Tasten, die beim Booten gedrückt werden müssen, um
eine Funktion auszulösen, erfolgt nach der Tastaturtabelle.
Die Definitionen
=> setenv key_magic0 3a+3b
=> setenv key_cmd0 setenv bootdelay 30
bedeuten dementsprechend, daß die Tasten mit den Codes 0x3A (Taste
"F1") und 0x3B (Taste "F2") gleichzeitig gedrückt werden müssen. Sie
können dort eine beliebige Tastenkombination eintragen (jeweils 2
Zeichen für die Hex-Codes der Tasten, und '+' als Trennzeichen).
Wird die eingestellte Tastenkombination erkannt, so wird in U-Boot
noch vor dem Start des "Countdown" und somit vor jedem anderen Kom-
mando das angebene Kommando ausgeführt und somit ein langes Boot-
Delay eingetragen.
Praktisch könnten Sie also in U-Boot "bootdelay" auf 0 setzen und
somit stets ohne jede User-Interaktion automatisch booten, außer,
wenn die beiden Tasten "F1" und "F2" beim Booten gedrückt werden:
dann würde ein Boot-Delay von 30 Sekunden eingefügt.
Hinweis: dem Zeichen '#' kommt innerhalb von "magic_keys" eine beson-
dere Bedeutung zu: die dadurch definierte Key-Sequenz schaltet den
Monitor in den "Debug-Modus" - das bedeutet zunächst, daß alle weite-
ren Meldungen von U-Boot über das LCD-Display ausgegeben werden;
außerdem kann man durch das mit dieser Tastenkombination verknüpfte
Kommando z. B. die Linux-Bootmeldungen ebenfalls auf das LCD-Display
legen, so daß der Boot-Vorgang direkt und ohne weitere Hilfsmittel
analysiert werden kann.
Beispiel:
In U-Boot werden folgende Environment-Variablen gesetzt und abgespei-
chert:
(1) => setenv magic_keys 01234#X
(2) => setenv key_cmd# setenv addfb setenv bootargs \\$(bootargs) console=tty0 console=ttyS1,\\$(baudrate)
(3) => setenv nfsargs setenv bootargs root=/dev/nfs rw nfsroot=\$(serverip):\$(rootpath)
(4) => setenv addip setenv bootargs \$(bootargs) ip=\$(ipaddr):\$(serverip):\$(gatewayip):\$(netmask):\$(hostname)::off panic=1
(5) => setenv addfb setenv bootargs \$(bootargs) console=ttyS1,\$(baudrate)
(6) => setenv bootcmd bootp\;run nfsargs\;run addip\;run addfb\;bootm
Hierbei wird die Linux Commandline (in der Variablen "bootargs") im
Boot-Kommando "bootcmd" (6) schrittweise zusammengesetzt: zunächst
werden die für Root-Filesystem über NFS erforderlichen Optionen ge-
setzt ("run nfsargs", vgl. (3)), dann die Netzwerkkonfiguration an-
gefügt ("run addip", vgl. (4)), und schließlich die Systemconsole
definiert ("run addfb").
Dabei wird im Normalfall die Definition (5) verwendt; wurde aller-
dings beim Reset die entsprechende Taste gedrückt gehalten, so wird
diese Definition bei der Ausführung des in (2) definierten Kommandos
überschrieben, so daß Linux die Bootmeldungen auch über das Frame-
buffer-Device (=LCD-Display) ausgibt.
Beachten Sie die Verdoppelung der '\'-Escapes in der Definition von
"key_cmd#" - diese ist erforderlich, weil der String _zweimal_ inter-
pretiert wird: das erste Mal bei der Eingabe von "key_cmd#", das
zweite Mal, wenn der String (als Inhalt von "preboot") ausgeführt
wird.

944
board/mousse/flash.c Normal file
View File

@ -0,0 +1,944 @@
/*
* MOUSSE/MPC8240 Board definitions.
* Flash Routines for MOUSSE onboard AMD29LV106DB devices
*
* (C) Copyright 2000
* Marius Groeger <mgroeger@sysgo.de>
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp.
* (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc8xx.h>
#include <malloc.h>
#include "mousse.h"
#include "flash.h"
int flashLibDebug = 0;
int flashLibInited = 0;
#define OK 0
#define ERROR -1
#define STATUS int
#define PRINTF if (flashLibDebug) printf
#if 0
#define PRIVATE static
#else
#define PRIVATE
#endif
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#define SLEEP_DELAY 166
#define FLASH_SECTOR_SIZE (64*1024)
/***********************************************************************
*
* Virtual Flash Devices on Mousse board
*
* These must be kept in sync with the definitions in flashLib.h.
*
***********************************************************************/
PRIVATE flash_dev_t flashDev[] = {
/* Bank 0 sector SA0 (16 kB) */
{ "SA0",FLASH0_BANK, FLASH0_SEG0_START, 1, 14,
FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
},
/* Bank 0 sector SA1 (8 kB) */
{ "SA1", FLASH0_BANK, FLASH0_SEG0_START + 0x4000, 1, 13,
FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
},
/* Bank 0 sector SA2 (8 kB) */
{ "SA2", FLASH0_BANK, FLASH0_SEG0_START + 0x6000, 1, 13,
FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
},
/* Bank 0 sector SA3 is occluded by Mousse I/O devices */
/* Bank 0 sectors SA4-SA18, after Mousse devices up to PLCC (960 kB) */
{ "KERNEL", FLASH0_BANK, FLASH0_SEG1_START, 15, 16,
FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
},
/* Bank 0 sectors SA19-SA26, jumper can occlude this by PLCC (512 kB) */
/* This is where the Kahlua boot vector and boot ROM code resides. */
{ "BOOT",FLASH0_BANK, FLASH0_SEG2_START, 8, 16,
FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
},
/* Bank 0 sectors SA27-SA34 (512 kB) */
{ "RAMDISK",FLASH0_BANK, FLASH0_SEG3_START, 8, 16,
FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
},
};
int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0]));
#define DEV(no) (&flashDev[no])
#define DEV_NO(dev) ((dev) - flashDev)
/***********************************************************************
*
* Private Flash Routines
*
***********************************************************************/
/*
* The convention is:
*
* "addr" is always the PROM raw address, which is the address of an
* 8-bit quantity for flash 0 and 16-bit quantity for flash 1.
*
* "pos" is always a logical byte position from the PROM beginning.
*/
#define FLASH0_ADDR(dev, addr) \
((unsigned char *) ((dev)->base + (addr)))
#define FLASH0_WRITE(dev, addr, value) \
(*FLASH0_ADDR(dev, addr) = (value))
#define FLASH0_READ(dev, addr) \
(*FLASH0_ADDR(dev, addr))
PRIVATE int flashCheck(flash_dev_t *dev)
{
if (! flashLibInited) {
printf("flashCheck: flashLib not initialized\n");
return ERROR;
}
if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) {
printf("flashCheck: Bad dev parameter\n");
return ERROR;
}
if (! dev->found) {
printf("flashCheck: Device %d not available\n", DEV_NO(dev));
return ERROR;
}
return OK;
}
PRIVATE void flashReset(flash_dev_t *dev)
{
PRINTF("flashReset: dev=%d\n", DEV_NO(dev));
if (dev->bank == FLASH0_BANK) {
FLASH0_WRITE(dev, 0x555, 0xaa);
FLASH0_WRITE(dev, 0xaaa, 0x55);
FLASH0_WRITE(dev, 0x555, 0xf0);
}
udelay(SLEEP_DELAY);
PRINTF("flashReset: done\n");
}
PRIVATE int flashProbe(flash_dev_t *dev)
{
int rv, deviceID, vendorID;
PRINTF("flashProbe: dev=%d\n", DEV_NO(dev));
if (dev->bank != FLASH0_BANK) {
rv = ERROR;
goto DONE;
}
FLASH0_WRITE(dev, 0xaaa, 0xaa);
FLASH0_WRITE(dev, 0x555, 0x55);
FLASH0_WRITE(dev, 0xaaa, 0x90);
udelay(SLEEP_DELAY);
vendorID = FLASH0_READ(dev, 0);
deviceID = FLASH0_READ(dev, 2);
FLASH0_WRITE(dev, 0, 0xf0);
PRINTF("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID);
if (vendorID == dev->vendorID && deviceID == dev->deviceID)
rv = OK;
else
rv = ERROR;
DONE:
PRINTF("flashProbe: rv=%d\n", rv);
return rv;
}
PRIVATE int flashWait(flash_dev_t *dev, int addr, int expect, int erase)
{
int rv = ERROR;
int i, data;
int polls;
#if 0
PRINTF("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
DEV_NO(dev), addr, expect, erase);
#endif
if (dev->bank != FLASH0_BANK) {
rv = ERROR;
goto done;
}
if (erase)
polls = FLASH_ERASE_SECTOR_TIMEOUT; /* Ticks */
else
polls = FLASH_PROGRAM_POLLS; /* Loops */
for (i = 0; i < polls; i++) {
if (erase)
udelay(SLEEP_DELAY);
data = FLASH0_READ(dev, addr);
if (((data ^ expect) & 0x80) == 0) {
rv = OK;
goto done;
}
if (data & 0x20) {
/*
* If the 0x20 bit has come on, it could actually be because
* the operation succeeded, so check the done bit again.
*/
data = FLASH0_READ(dev, addr);
if (((data ^ expect) & 0x80) == 0) {
rv = OK;
goto done;
}
printf("flashWait: Program error (dev: %d, addr: 0x%x)\n",
DEV_NO(dev), addr);
flashReset(dev);
rv = ERROR;
goto done;
}
}
printf("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
erase ? "erasing sector" : "programming byte",
DEV_NO(dev), addr);
done:
#if 0
PRINTF("flashWait: rv=%d\n", rv);
#endif
return rv;
}
/***********************************************************************
*
* Public Flash Routines
*
***********************************************************************/
STATUS flashLibInit(void)
{
int i;
PRINTF("flashLibInit: devices=%d\n", flashDevCount);
for (i = 0; i < flashDevCount; i++) {
flash_dev_t *dev = &flashDev[i];
/*
* For bank 1, probe both without and with byte swappage,
* so that this module works on both old and new Mousse boards.
*/
flashReset(dev);
if (flashProbe(dev) != ERROR)
dev->found = 1;
flashReset(dev);
if (flashProbe(dev) != ERROR)
dev->found = 1;
dev->swap = 0;
if(dev->found){
PRINTF("\n FLASH %s[%d]: iobase=0x%x - %d sectors %d KB",
flashDev[i].name,i,flashDev[i].base, flashDev[i].sectors,
(flashDev[i].sectors * FLASH_SECTOR_SIZE)/1024);
}
}
flashLibInited = 1;
PRINTF("flashLibInit: done\n");
return OK;
}
STATUS flashEraseSector(flash_dev_t *dev, int sector)
{
int pos, addr;
PRINTF("flashErasesector: dev=%d sector=%d\n", DEV_NO(dev), sector);
if (flashCheck(dev) == ERROR)
return ERROR;
if (sector < 0 || sector >= dev->sectors) {
printf("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n",
DEV_NO(dev), sector);
return ERROR;
}
pos = FLASH_SECTOR_POS(dev, sector);
if (dev->bank != FLASH0_BANK) {
return ERROR;
}
addr = pos;
FLASH0_WRITE(dev, 0xaaa, 0xaa);
FLASH0_WRITE(dev, 0x555, 0x55);
FLASH0_WRITE(dev, 0xaaa, 0x80);
FLASH0_WRITE(dev, 0xaaa, 0xaa);
FLASH0_WRITE(dev, 0x555, 0x55);
FLASH0_WRITE(dev, addr, 0x30);
return flashWait(dev, addr, 0xff, 1);
}
/*
* Note: it takes about as long to flash all sectors together with Chip
* Erase as it does to flash them one at a time (about 30 seconds for 2
* MB). Also since we want to be able to treat subsets of sectors as if
* they were complete devices, we don't use Chip Erase.
*/
STATUS flashErase(flash_dev_t *dev)
{
int sector;
PRINTF("flashErase: dev=%d sectors=%d\n", DEV_NO(dev), dev->sectors);
if (flashCheck(dev) == ERROR)
return ERROR;
for (sector = 0; sector < dev->sectors; sector++) {
if (flashEraseSector(dev, sector) == ERROR)
return ERROR;
}
return OK;
}
/*
* Read and write bytes
*/
STATUS flashRead(flash_dev_t *dev, int pos, char *buf, int len)
{
int addr, words;
PRINTF("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
DEV_NO(dev), pos, (int) buf, len);
if (flashCheck(dev) == ERROR)
return ERROR;
if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
printf("flashRead: Position out of range "
"(dev: %d, pos: 0x%x, len: 0x%x)\n",
DEV_NO(dev), pos, len);
return ERROR;
}
if (len == 0)
return OK;
if (dev->bank == FLASH0_BANK) {
addr = pos;
words = len;
PRINTF("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n",
(int) buf, (int) FLASH0_ADDR(dev, pos), len);
memcpy(buf, FLASH0_ADDR(dev, addr), words);
}
PRINTF("flashRead: rv=OK\n");
return OK;
}
STATUS flashWrite(flash_dev_t *dev, int pos, char *buf, int len)
{
int addr, words;
PRINTF("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
DEV_NO(dev), pos, (int) buf, len);
if (flashCheck(dev) == ERROR)
return ERROR;
if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
printf("flashWrite: Position out of range "
"(dev: %d, pos: 0x%x, len: 0x%x)\n",
DEV_NO(dev), pos, len);
return ERROR;
}
if (len == 0)
return OK;
if (dev->bank == FLASH0_BANK) {
unsigned char tmp;
addr = pos;
words = len;
while (words--) {
tmp = *buf;
if (~FLASH0_READ(dev, addr) & tmp) {
printf("flashWrite: Attempt to program 0 to 1 "
"(dev: %d, addr: 0x%x, data: 0x%x)\n",
DEV_NO(dev), addr, tmp);
return ERROR;
}
FLASH0_WRITE(dev, 0xaaa, 0xaa);
FLASH0_WRITE(dev, 0x555, 0x55);
FLASH0_WRITE(dev, 0xaaa, 0xa0);
FLASH0_WRITE(dev, addr, tmp);
if (flashWait(dev, addr, tmp, 0) < 0)
return ERROR;
buf++;
addr++;
}
}
PRINTF("flashWrite: rv=OK\n");
return OK;
}
/*
* flashWritable returns TRUE if a range contains all F's.
*/
STATUS flashWritable(flash_dev_t *dev, int pos, int len)
{
int addr, words;
int rv = ERROR;
PRINTF("flashWritable: dev=%d pos=0x%x len=0x%x\n",
DEV_NO(dev), pos, len);
if (flashCheck(dev) == ERROR)
goto done;
if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
printf("flashWritable: Position out of range "
"(dev: %d, pos: 0x%x, len: 0x%x)\n",
DEV_NO(dev), pos, len);
goto done;
}
if (len == 0) {
rv = 1;
goto done;
}
if (dev->bank == FLASH0_BANK) {
addr = pos;
words = len;
while (words--) {
if (FLASH0_READ(dev, addr) != 0xff) {
rv = 0;
goto done;
}
addr++;
}
}
rv = 1;
done:
PRINTF("flashWrite: rv=%d\n", rv);
return rv;
}
/*
* NOTE: the below code cannot run from FLASH!!!
*/
/***********************************************************************
*
* Flash Diagnostics
*
***********************************************************************/
STATUS flashDiag(flash_dev_t *dev)
{
unsigned int *buf = 0;
int i, len, sector;
int rv = ERROR;
if (flashCheck(dev) == ERROR)
return ERROR;
printf("flashDiag: Testing device %d, "
"base: 0x%x, %d sectors @ %d kB = %d kB\n",
DEV_NO(dev), dev->base,
dev->sectors,
1 << (dev->lgSectorSize - 10),
dev->sectors << (dev->lgSectorSize - 10));
len = 1 << dev->lgSectorSize;
printf("flashDiag: Erasing\n");
if (flashErase(dev) == ERROR) {
printf("flashDiag: Erase failed\n");
goto done;
}
printf("%d bytes requested ...\n", len);
buf = malloc(len);
printf("allocated %d bytes ...\n", len);
if (buf == 0) {
printf("flashDiag: Out of memory\n");
goto done;
}
/*
* Write unique counting pattern to each sector
*/
for (sector = 0; sector < dev->sectors; sector++) {
printf("flashDiag: Write sector %d\n", sector);
for (i = 0; i < len / 4; i++)
buf[i] = sector << 24 | i;
if (flashWrite(dev,
sector << dev->lgSectorSize,
(char *) buf,
len) == ERROR) {
printf("flashDiag: Write failed (dev: %d, sector: %d)\n",
DEV_NO(dev), sector);
goto done;
}
}
/*
* Verify
*/
for (sector = 0; sector < dev->sectors; sector++) {
printf("flashDiag: Verify sector %d\n", sector);
if (flashRead(dev,
sector << dev->lgSectorSize,
(char *) buf,
len) == ERROR) {
printf("flashDiag: Read failed (dev: %d, sector: %d)\n",
DEV_NO(dev), sector);
goto done;
}
for (i = 0; i < len / 4; i++) {
if (buf[i] != (sector << 24 | i)) {
printf("flashDiag: Verify error "
"(dev: %d, sector: %d, offset: 0x%x)\n",
DEV_NO(dev), sector, i);
printf("flashDiag: Expected 0x%08x, got 0x%08x\n",
sector << 24 | i, buf[i]);
goto done;
}
}
}
printf("flashDiag: Erasing\n");
if (flashErase(dev) == ERROR) {
printf("flashDiag: Final erase failed\n");
goto done;
}
rv = OK;
done:
if (buf)
free(buf);
if (rv == OK)
printf("flashDiag: Device %d passed\n", DEV_NO(dev));
else
printf("flashDiag: Device %d failed\n", DEV_NO(dev));
return rv;
}
STATUS flashDiagAll(void)
{
int i;
int rv = OK;
PRINTF("flashDiagAll: devices=%d\n", flashDevCount);
for (i = 0; i < flashDevCount; i++) {
flash_dev_t *dev = &flashDev[i];
if (dev->found && flashDiag(dev) == ERROR)
rv = ERROR;
}
if (rv == OK)
printf("flashDiagAll: Passed\n");
else
printf("flashDiagAll: Failed because of earlier errors\n");
return OK;
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size = 0;
flash_dev_t *dev = NULL;
flashLibInit();
/*
* Provide info for FLASH (up to 960K) of Kernel Image data.
*/
dev = FLASH_DEV_BANK0_LOW;
flash_info[FLASH_BANK_KERNEL].flash_id =
(dev->vendorID << 16) | dev->deviceID;
flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors;
flash_info[FLASH_BANK_KERNEL].size =
flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE;
flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base;
size += flash_info[FLASH_BANK_KERNEL].size;
/*
* Provide info for 512K PLCC FLASH ROM (U-Boot)
*/
dev = FLASH_DEV_BANK0_BOOT;
flash_info[FLASH_BANK_BOOT].flash_id =
(dev->vendorID << 16) | dev->deviceID;
flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors;
flash_info[FLASH_BANK_BOOT].size =
flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE;
flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base;
size += flash_info[FLASH_BANK_BOOT].size;
/*
* Provide info for 512K FLASH0 segment (U-Boot)
*/
dev = FLASH_DEV_BANK0_HIGH;
flash_info[FLASH_BANK_AUX].flash_id =
(dev->vendorID << 16) | dev->deviceID;
flash_info[FLASH_BANK_AUX].sector_count = dev->sectors;
flash_info[FLASH_BANK_AUX].size =
flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE;
flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base;
size += flash_info[FLASH_BANK_AUX].size;
return size;
}
/*
* Get flash device from U-Boot flash info.
*/
flash_dev_t*
getFlashDevFromInfo(flash_info_t* info)
{
int i;
if(!info)
return NULL;
for (i = 0; i < flashDevCount; i++) {
flash_dev_t *dev = &flashDev[i];
if(dev->found && (dev->base == info->start[0]))
return dev;
}
printf("ERROR: notice, no FLASH mapped at address 0x%x\n",
(unsigned int)info->start[0]);
return NULL;
}
ulong
flash_get_size (vu_long *addr, flash_info_t *info)
{
int i;
for(i = 0; i < flashDevCount; i++) {
flash_dev_t *dev = &flashDev[i];
if(dev->found){
if(dev->base == (unsigned int)addr){
info->flash_id = (dev->vendorID << 16) | dev->deviceID;
info->sector_count = dev->sectors;
info->size = info->sector_count * FLASH_SECTOR_SIZE;
return dev->sectors * FLASH_SECTOR_SIZE;
}
}
}
return 0;
}
void
flash_print_info (flash_info_t *info)
{
int i;
unsigned int chip;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch ((info->flash_id >> 16) & 0xff) {
case 0x1:
printf ("AMD ");
break;
default:
printf ("Unknown Vendor ");
break;
}
chip = (unsigned int) info->flash_id & 0x000000ff;
switch (chip) {
case AMD_ID_F040B:
printf ("AM29F040B (4 Mbit)\n");
break;
case AMD_ID_LV160B:
case FLASH_AM160LV:
case 0x49:
printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n");
break;
default:
printf ("Unknown Chip Type:0x%x\n", chip);
break;
}
printf (" Size: %ld bytes in %d Sectors\n",
info->size, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[FIRST_SECTOR] + i*FLASH_SECTOR_SIZE,
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
}
/*
* Erase a range of flash sectors.
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
vu_long *addr = (vu_long*)(info->start[0]);
int prot, sect, l_sect;
flash_dev_t* dev = NULL;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
l_sect = -1;
/* Start erase on unprotected sectors */
dev = getFlashDevFromInfo(info);
if(dev){
printf("Erase FLASH[%s] -%d sectors:", dev->name, dev->sectors);
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_long*)(dev->base);
/* printf("erase_sector: sector=%d, addr=0x%x\n",
sect, addr); */
printf(".");
if(ERROR == flashEraseSector(dev, sect)){
printf("ERROR: could not erase sector %d on FLASH[%s]\n",
sect, dev->name);
return 1;
}
}
}
}
printf (" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int
write_word (flash_info_t *info, ulong dest, ulong data)
{
flash_dev_t* dev = getFlashDevFromInfo(info);
int addr = dest - info->start[0];
if (! dev)
return 1;
if(OK != flashWrite(dev, addr, (char*)&data, sizeof(ulong))){
printf("ERROR: could not write to addr=0x%x, data=0x%x\n",
(unsigned int)addr, (unsigned)data);
return 1;
}
if((addr % FLASH_SECTOR_SIZE) == 0)
printf(".");
PRINTF("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n",
(unsigned)info->start[0],
(unsigned)dest,
(unsigned)(dest - info->start[0]),
(unsigned)data);
return (0);
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
flash_dev_t* dev = getFlashDevFromInfo(info);
if( dev ) {
printf("FLASH[%s]:", dev->name);
wp = (addr & ~3); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i=0; i<4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
cnt -= 4;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_word(info, wp, data));
}
return 1;
}
/*-----------------------------------------------------------------------
*/

323
board/mousse/m48t59y.c Normal file
View File

@ -0,0 +1,323 @@
/*
* SGS M48-T59Y TOD/NVRAM Driver
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp.
*
* (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* SGS M48-T59Y TOD/NVRAM Driver
*
* The SGS M48 an 8K NVRAM starting at offset M48_BASE_ADDR and
* continuing for 8176 bytes. After that starts the Time-Of-Day (TOD)
* registers which are used to set/get the internal date/time functions.
*
* This module implements Y2K compliance by taking full year numbers
* and translating back and forth from the TOD 2-digit year.
*
* NOTE: for proper interaction with an operating system, the TOD should
* be used to store Universal Coordinated Time (GMT) and timezone
* conversions should be used.
*
* Here is a diagram of the memory layout:
*
* +---------------------------------------------+ 0xffe0a000
* | Non-volatile memory | .
* | | .
* | (8176 bytes of Non-volatile memory) | .
* | | .
* +---------------------------------------------+ 0xffe0bff0
* | Flags |
* +---------------------------------------------+ 0xffe0bff1
* | Unused |
* +---------------------------------------------+ 0xffe0bff2
* | Alarm Seconds |
* +---------------------------------------------+ 0xffe0bff3
* | Alarm Minutes |
* +---------------------------------------------+ 0xffe0bff4
* | Alarm Date |
* +---------------------------------------------+ 0xffe0bff5
* | Interrupts |
* +---------------------------------------------+ 0xffe0bff6
* | WatchDog |
* +---------------------------------------------+ 0xffe0bff7
* | Calibration |
* +---------------------------------------------+ 0xffe0bff8
* | Seconds |
* +---------------------------------------------+ 0xffe0bff9
* | Minutes |
* +---------------------------------------------+ 0xffe0bffa
* | Hours |
* +---------------------------------------------+ 0xffe0bffb
* | Day |
* +---------------------------------------------+ 0xffe0bffc
* | Date |
* +---------------------------------------------+ 0xffe0bffd
* | Month |
* +---------------------------------------------+ 0xffe0bffe
* | Year (2 digits only) |
* +---------------------------------------------+ 0xffe0bfff
*/
#include <common.h>
#include <rtc.h>
#include "mousse.h"
/*
* Imported from mousse.h:
*
* TOD_REG_BASE Base of m48t59y TOD registers
* SYS_TOD_UNPROTECT() Disable NVRAM write protect
* SYS_TOD_PROTECT() Re-enable NVRAM write protect
*/
#define YEAR 0xf
#define MONTH 0xe
#define DAY 0xd
#define DAY_OF_WEEK 0xc
#define HOUR 0xb
#define MINUTE 0xa
#define SECOND 0x9
#define CONTROL 0x8
#define WATCH 0x7
#define INTCTL 0x6
#define WD_DATE 0x5
#define WD_HOUR 0x4
#define WD_MIN 0x3
#define WD_SEC 0x2
#define _UNUSED 0x1
#define FLAGS 0x0
#define M48_ADDR ((volatile unsigned char *) TOD_REG_BASE)
int m48_tod_init(void)
{
SYS_TOD_UNPROTECT();
M48_ADDR[CONTROL] = 0;
M48_ADDR[WATCH] = 0;
M48_ADDR[INTCTL] = 0;
/*
* If the oscillator is currently stopped (as on a new part shipped
* from the factory), start it running.
*
* Here is an example of the TOD bytes on a brand new M48T59Y part:
* 00 00 00 00 00 00 00 00 00 88 8c c3 bf c8 f5 01
*/
if (M48_ADDR[SECOND] & 0x80)
M48_ADDR[SECOND] = 0;
/* Is battery low */
if ( M48_ADDR[FLAGS] & 0x10) {
printf("NOTICE: Battery low on Real-Time Clock (replace SNAPHAT).\n");
}
SYS_TOD_PROTECT();
return 0;
}
/*
* m48_tod_set
*/
static int to_bcd(int value)
{
return value / 10 * 16 + value % 10;
}
static int from_bcd(int value)
{
return value / 16 * 10 + value % 16;
}
static int day_of_week(int y, int m, int d) /* 0-6 ==> Sun-Sat */
{
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
/*
* Note: the TOD should store the current GMT
*/
int m48_tod_set(int year, /* 1980-2079 */
int month, /* 01-12 */
int day, /* 01-31 */
int hour, /* 00-23 */
int minute, /* 00-59 */
int second) /* 00-59 */
{
SYS_TOD_UNPROTECT();
M48_ADDR[CONTROL] |= 0x80; /* Set WRITE bit */
M48_ADDR[YEAR] = to_bcd(year % 100);
M48_ADDR[MONTH] = to_bcd(month);
M48_ADDR[DAY] = to_bcd(day);
M48_ADDR[DAY_OF_WEEK] = day_of_week(year, month, day) + 1;
M48_ADDR[HOUR] = to_bcd(hour);
M48_ADDR[MINUTE] = to_bcd(minute);
M48_ADDR[SECOND] = to_bcd(second);
M48_ADDR[CONTROL] &= ~0x80; /* Clear WRITE bit */
SYS_TOD_PROTECT();
return 0;
}
/*
* Note: the TOD should store the current GMT
*/
int m48_tod_get(int *year, /* 1980-2079 */
int *month, /* 01-12 */
int *day, /* 01-31 */
int *hour, /* 00-23 */
int *minute, /* 00-59 */
int *second) /* 00-59 */
{
int y;
SYS_TOD_UNPROTECT();
M48_ADDR[CONTROL] |= 0x40; /* Set READ bit */
y = from_bcd(M48_ADDR[YEAR]);
*year = y < 80 ? 2000 + y : 1900 + y;
*month = from_bcd(M48_ADDR[MONTH]);
*day = from_bcd(M48_ADDR[DAY]);
/* day_of_week = M48_ADDR[DAY_OF_WEEK] & 0xf; */
*hour = from_bcd(M48_ADDR[HOUR]);
*minute = from_bcd(M48_ADDR[MINUTE]);
*second = from_bcd(M48_ADDR[SECOND] & 0x7f);
M48_ADDR[CONTROL] &= ~0x40; /* Clear READ bit */
SYS_TOD_PROTECT();
return 0;
}
int m48_tod_get_second(void)
{
return from_bcd(M48_ADDR[SECOND] & 0x7f);
}
/*
* Watchdog function
*
* If usec is 0, the watchdog timer is disarmed.
*
* If usec is non-zero, the watchdog timer is armed (or re-armed) for
* approximately usec microseconds (if the exact requested usec is
* not supported by the chip, the next higher available value is used).
*
* Minimum watchdog timeout = 62500 usec
* Maximum watchdog timeout = 124 sec (124000000 usec)
*/
void m48_watchdog_arm(int usec)
{
int mpy, res;
SYS_TOD_UNPROTECT();
if (usec == 0) {
res = 0;
mpy = 0;
} else if (usec < 2000000) { /* Resolution: 1/16s if below 2s */
res = 0;
mpy = (usec + 62499) / 62500;
} else if (usec < 8000000) { /* Resolution: 1/4s if below 8s */
res = 1;
mpy = (usec + 249999) / 250000;
} else if (usec < 32000000) { /* Resolution: 1s if below 32s */
res = 2;
mpy = (usec + 999999) / 1000000;
} else { /* Resolution: 4s up to 124s */
res = 3;
mpy = (usec + 3999999) / 4000000;
if (mpy > 31)
mpy = 31;
}
M48_ADDR[WATCH] = (0x80 | /* Steer to RST signal (IRQ = N/C) */
mpy << 2 |
res);
SYS_TOD_PROTECT();
}
/*
* U-Boot RTC support.
*/
void
rtc_get( struct rtc_time *tmp )
{
m48_tod_get(&tmp->tm_year,
&tmp->tm_mon,
&tmp->tm_mday,
&tmp->tm_hour,
&tmp->tm_min,
&tmp->tm_sec);
tmp->tm_yday = 0;
tmp->tm_isdst= 0;
#ifdef RTC_DEBUG
printf( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
#endif
}
void
rtc_set( struct rtc_time *tmp )
{
m48_tod_set(tmp->tm_year, /* 1980-2079 */
tmp->tm_mon, /* 01-12 */
tmp->tm_mday, /* 01-31 */
tmp->tm_hour, /* 00-23 */
tmp->tm_min, /* 00-59 */
tmp->tm_sec); /* 00-59 */
#ifdef RTC_DEBUG
printf( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
#endif
}
void
rtc_reset (void)
{
m48_tod_init();
}

377
board/pm826/flash.c Normal file
View File

@ -0,0 +1,377 @@
/*
* (C) Copyright 2001, 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Flash Routines for Intel devices
*
*--------------------------------------------------------------------
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc8xx.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*-----------------------------------------------------------------------
*/
ulong flash_get_size (volatile unsigned long *baseaddr,
flash_info_t * info)
{
short i;
unsigned long flashtest_h, flashtest_l;
info->sector_count = info->size = 0;
info->flash_id = FLASH_UNKNOWN;
/* Write query command sequence and test FLASH answer
*/
baseaddr[0] = 0x00980098;
baseaddr[1] = 0x00980098;
flashtest_h = baseaddr[0]; /* manufacturer ID */
flashtest_l = baseaddr[1];
if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
return (0); /* no or unknown flash */
flashtest_h = baseaddr[2]; /* device ID */
flashtest_l = baseaddr[3];
if (flashtest_h != flashtest_l)
return (0);
switch (flashtest_h) {
case INTEL_ID_28F160C3B:
info->flash_id = FLASH_28F160C3B;
info->sector_count = 39;
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
break;
case INTEL_ID_28F160F3B:
info->flash_id = FLASH_28F160F3B;
info->sector_count = 39;
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
break;
default:
return (0); /* no or unknown flash */
}
info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */
if (info->flash_id & FLASH_BTYPE) {
volatile unsigned long *tmp = baseaddr;
/* set up sector start adress table (bottom sector type)
* AND unlock the sectors (if our chip is 160C3)
*/
for (i = 0; i < info->sector_count; i++) {
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) {
tmp[0] = 0x00600060;
tmp[1] = 0x00600060;
tmp[0] = 0x00D000D0;
tmp[1] = 0x00D000D0;
}
info->start[i] = (uint) tmp;
tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith */
}
}
memset (info->protect, 0, info->sector_count);
baseaddr[0] = 0x00FF00FF;
baseaddr[1] = 0x00FF00FF;
return (info->size);
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size_b0 = 0;
int i;
/* Init: no FLASHes known
*/
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Static FLASH Bank configuration here (only one bank) */
size_b0 = flash_get_size ((ulong *) CFG_FLASH0_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0 >> 20);
}
/* protect monitor and environment sectors
*/
#ifndef CONFIG_BOOT_ROM
/* If U-Boot is booted from ROM the CFG_MONITOR_BASE > CFG_FLASH0_BASE
* but we shouldn't protect it.
*/
# if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, &flash_info[0]
);
# endif
#endif /* CONFIG_BOOT_ROM */
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
#endif
return (size_b0);
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t * info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch ((info->flash_id >> 16) & 0xff) {
case 0x89:
printf ("INTEL ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F160C3B:
printf ("28F160C3B (16 M, bottom sector)\n");
break;
case FLASH_28F160F3B:
printf ("28F160F3B (16 M, bottom sector)\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect])
prot++;
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
/* Start erase on unprotected sectors
*/
for (sect = s_first; sect <= s_last; sect++) {
volatile ulong *addr =
(volatile unsigned long *) info->start[sect];
start = get_timer (0);
last = start;
if (info->protect[sect] == 0) {
/* Disable interrupts which might cause a timeout here
*/
flag = disable_interrupts ();
/* Erase the block
*/
addr[0] = 0x00200020;
addr[1] = 0x00200020;
addr[0] = 0x00D000D0;
addr[1] = 0x00D000D0;
/* re-enable interrupts if necessary
*/
if (flag)
enable_interrupts ();
/* wait at least 80us - let's wait 1 ms
*/
udelay (1000);
last = start;
while ((addr[0] & 0x00800080) != 0x00800080 ||
(addr[1] & 0x00800080) != 0x00800080) {
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout (erase suspended!)\n");
/* Suspend erase
*/
addr[0] = 0x00B000B0;
addr[1] = 0x00B000B0;
goto DONE;
}
/* show that we're waiting
*/
if ((now - last) > 1000) { /* every second */
serial_putc ('.');
last = now;
}
}
if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
printf ("*** ERROR: erase failed!\n");
goto DONE;
}
}
/* Clear status register and reset to read mode
*/
addr[0] = 0x00500050;
addr[1] = 0x00500050;
addr[0] = 0x00FF00FF;
addr[1] = 0x00FF00FF;
}
printf (" done\n");
DONE:
return 0;
}
static int write_word (flash_info_t *, volatile unsigned long *, ulong);
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong v;
int i, l, cc = cnt, res = 0;
for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
l = (addr & 3);
addr &= ~3;
for (i = 0; i < 4; i++) {
v = (v << 8) + (i < l || i - l >= cc ?
*((unsigned char *) addr + i) : *src++);
}
if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
break;
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t * info, volatile unsigned long *addr,
ulong data)
{
int flag, res = 0;
ulong start;
/* Check if Flash is (sufficiently) erased
*/
if ((*addr & data) != data)
return (2);
/* Disable interrupts which might cause a timeout here
*/
flag = disable_interrupts ();
*addr = 0x00400040;
*addr = data;
/* re-enable interrupts if necessary
*/
if (flag)
enable_interrupts ();
start = get_timer (0);
while ((*addr & 0x00800080) != 0x00800080) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
/* Suspend program
*/
*addr = 0x00B000B0;
res = 1;
goto OUT;
}
}
if (*addr & 0x00220022) {
printf ("*** ERROR: program failed!\n");
res = 1;
}
OUT:
/* Clear status register and reset to read mode
*/
*addr = 0x00500050;
*addr = 0x00FF00FF;
return (res);
}

523
board/sacsng/flash.c Normal file
View File

@ -0,0 +1,523 @@
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <configs/sacsng.h>
#undef DEBUG
#ifndef CFG_ENV_ADDR
#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
#endif
#ifndef CFG_ENV_SIZE
#define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
#endif
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (vu_short *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size_b0, size_b1;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
size_b0 = flash_get_size((vu_short *)CFG_FLASH0_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0<<20);
}
size_b1 = flash_get_size((vu_short *)CFG_FLASH1_BASE, &flash_info[1]);
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
&flash_info[0]);
#endif
if (size_b1) {
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[1]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
&flash_info[1]);
#endif
} else {
flash_info[1].flash_id = FLASH_UNKNOWN;
flash_info[1].sector_count = -1;
}
flash_info[0].size = size_b0;
flash_info[1].size = size_b1;
/*
* We only report the primary flash for U-Boot's use.
*/
return (size_b0);
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
break;
case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
break;
case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
break;
case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
break;
case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
break;
case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
break;
case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (vu_short *addr, flash_info_t *info)
{
short i;
ushort value;
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
addr[0x0555] = 0xAAAA;
addr[0x02AA] = 0x5555;
addr[0x0555] = 0x9090;
__asm__ __volatile__(" sync\n ");
value = addr[0];
#ifdef DEBUG
printf("Flash manufacturer 0x%04X\n", value);
#endif
if(value == (ushort)AMD_MANUFACT) {
info->flash_id = FLASH_MAN_AMD;
} else if (value == (ushort)FUJ_MANUFACT) {
info->flash_id = FLASH_MAN_FUJ;
} else {
#ifdef DEBUG
printf("Unknown flash manufacturer 0x%04X\n", value);
#endif
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
value = addr[1]; /* device ID */
#ifdef DEBUG
printf("Flash type 0x%04X\n", value);
#endif
if(value == (ushort)AMD_ID_LV400T) {
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00080000; /* => 0.5 MB */
} else if(value == (ushort)AMD_ID_LV400B) {
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00080000; /* => 0.5 MB */
} else if(value == (ushort)AMD_ID_LV800T) {
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00100000; /* => 1 MB */
} else if(value == (ushort)AMD_ID_LV800B) {
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00100000; /* => 1 MB */
} else if(value == (ushort)AMD_ID_LV160T) {
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00200000; /* => 2 MB */
} else if(value == (ushort)AMD_ID_LV160B) {
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00200000; /* => 2 MB */
} else if(value == (ushort)AMD_ID_LV320T) {
info->flash_id += FLASH_AM320T;
info->sector_count = 67;
info->size = 0x00400000; /* => 4 MB */
} else if(value == (ushort)AMD_ID_LV320B) {
info->flash_id += FLASH_AM320B;
info->sector_count = 67;
info->size = 0x00400000; /* => 4 MB */
} else {
#ifdef DEBUG
printf("Unknown flash type 0x%04X\n", value);
info->size = CFG_FLASH_SIZE;
#else
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
#endif
}
/* set up sector start address table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00004000;
info->start[2] = base + 0x00006000;
info->start[3] = base + 0x00008000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + ((i - 3) * 0x00010000);
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00004000;
info->start[i--] = base + info->size - 0x00006000;
info->start[i--] = base + info->size - 0x00008000;
for (; i >= 0; i--) {
info->start[i] = base + (i * 0x00010000);
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr = (volatile unsigned short *)(info->start[i]);
info->protect[i] = addr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (volatile unsigned short *)info->start[0];
}
addr[0] = 0xF0F0; /* reset bank */
__asm__ __volatile__(" sync\n ");
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
vu_short *addr = (vu_short*)(info->start[0]);
int flag, prot, sect, l_sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id == FLASH_UNKNOWN) ||
(info->flash_id > FLASH_AMD_COMP)) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAAAA;
addr[0x02AA] = 0x5555;
addr[0x0555] = 0x8080;
addr[0x0555] = 0xAAAA;
addr[0x02AA] = 0x5555;
__asm__ __volatile__(" sync\n ");
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_short*)(info->start[sect]);
addr[0] = 0x3030;
l_sect = sect;
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
start = get_timer (0);
last = start;
addr = (vu_short*)(info->start[l_sect]);
while ((addr[0] & 0x0080) != 0x0080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
addr[0] = 0xF0F0; /* reset bank */
__asm__ __volatile__(" sync\n ");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
DONE:
/* reset to read mode */
addr = (vu_short*)info->start[0];
addr[0] = 0xF0F0; /* reset bank */
__asm__ __volatile__(" sync\n ");
printf (" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
wp = (addr & ~3); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i=0; i<4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
cnt -= 4;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_word(info, wp, data));
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t *info, ulong dest, ulong data)
{
vu_short *addr = (vu_short*)(info->start[0]);
ulong start;
int flag;
int j;
/* Check if Flash is (sufficiently) erased */
if (((*(vu_long *)dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* The original routine was designed to write 32 bit words to
* 32 bit wide memory. We have 16 bit wide memory so we do
* two writes. We write the LSB first at dest+2 and then the
* MSB at dest (lousy big endian).
*/
dest += 2;
for(j = 0; j < 2; j++) {
addr[0x0555] = 0xAAAA;
addr[0x02AA] = 0x5555;
addr[0x0555] = 0xA0A0;
__asm__ __volatile__(" sync\n ");
*((vu_short *)dest) = (ushort)data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while (*(vu_short *)dest != (ushort)data) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
dest -= 2;
data >>= 16;
}
return (0);
}
/*-----------------------------------------------------------------------
*/

15
board/sandpoint/README Normal file
View File

@ -0,0 +1,15 @@
This port of U-Boot will run on a Motorola Sandpoint 3 development
system equipped with a Unity X4 PPMC card (MPC8240 CPU) only. It is a
snapshot of work in progress and far from being completed. In order
to run it on the target system, it has to be downloaded using the
DINK32 monitor program that came with your Sandpoint system. Please
note that DINK32 does not accept the S-Record file created by the
U-Boot build process unmodified, because it contains CR/LF line
terminators. You have to strip the CR characters first. There is a
tiny script named 'dinkdl' I created for this purpose.
The Sandpoint port is based on the work of Rob Taylor, who does not
seem to maintain it any more. I can be reached by mail as
tkoeller@gmx.net.
Thomas Koeller

257
disk/part_iso.c Normal file
View File

@ -0,0 +1,257 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <cmd_disk.h>
#include "part_iso.h"
#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_ISO_PARTITION)
#undef ISO_PART_DEBUG
#ifdef ISO_PART_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/* enable this if CDs are written with the PowerPC Platform ID */
#undef CHECK_FOR_POWERPC_PLATTFORM
#define CD_SECTSIZE 2048
static unsigned char tmpbuf[CD_SECTSIZE];
/* Convert char[4] in little endian format to the host format integer
*/
static inline unsigned long le32_to_int(unsigned char *le32)
{
return ((le32[3] << 24) +
(le32[2] << 16) +
(le32[1] << 8) +
le32[0]
);
}
/* Convert char[2] in little endian format to the host format integer
*/
static inline unsigned short le16_to_int(unsigned char *le16)
{
return ((le16[1] << 8) +
le16[0]
);
}
/* only boot records will be listed as valid partitions */
int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info, int verb)
{
int i,offset,entry_num;
unsigned short *chksumbuf;
unsigned short chksum;
unsigned long newblkaddr,blkaddr,lastsect,bootaddr;
iso_boot_rec_t *pbr = (iso_boot_rec_t *)tmpbuf; /* boot record */
iso_pri_rec_t *ppr = (iso_pri_rec_t *)tmpbuf; /* primary desc */
iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;
iso_init_def_entry_t *pide;
/* the first sector (sector 0x10) must be a primary volume desc */
blkaddr=PVD_OFFSET;
if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1)
return (-1);
if(ppr->desctype!=0x01) {
if(verb)
printf ("** First descriptor is NOT a primary desc on %d:%d **\n",
dev_desc->dev, part_num);
return (-1);
}
if(strncmp(ppr->stand_ident,"CD001",5)!=0) {
if(verb)
printf ("** Wrong ISO Ident: %s on %d:%d **\n",
ppr->stand_ident,dev_desc->dev, part_num);
return (-1);
}
lastsect= ((ppr->firstsek_LEpathtab1_LE & 0x000000ff)<<24) +
((ppr->firstsek_LEpathtab1_LE & 0x0000ff00)<< 8) +
((ppr->firstsek_LEpathtab1_LE & 0x00ff0000)>> 8) +
((ppr->firstsek_LEpathtab1_LE & 0xff000000)>>24) ;
info->blksz=ppr->secsize_BE; /* assuming same block size for all entries */
PRINTF(" Lastsect:%08lx\n",lastsect);
for(i=blkaddr;i<lastsect;i++) {
if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *) tmpbuf) != 1)
return (-1);
if(ppr->desctype==0x00)
break; /* boot entry found */
if(ppr->desctype==0xff) {
if(verb)
printf ("** No valid boot catalog found on %d:%d **\n",
dev_desc->dev, part_num);
return (-1);
}
}
/* boot entry found */
if(strncmp(pbr->ident_str,"EL TORITO SPECIFICATION",23)!=0) {
if(verb)
printf ("** Wrong El Torito ident: %s on %d:%d **\n",
pbr->ident_str,dev_desc->dev, part_num);
return (-1);
}
bootaddr=le32_to_int(pbr->pointer);
PRINTF(" Boot Entry at: %08lX\n",bootaddr);
if (dev_desc->block_read (dev_desc->dev, bootaddr, 1, (ulong *) tmpbuf) != 1) {
if(verb)
printf ("** Can't read Boot Entry at %lX on %d:%d **\n",
bootaddr,dev_desc->dev, part_num);
return (-1);
}
chksum=0;
chksumbuf = (unsigned short *)tmpbuf;
for(i=0;i<0x10;i++)
chksum+=((chksumbuf[i] &0xff)<<8)+((chksumbuf[i] &0xff00)>>8);
if(chksum!=0) {
if(verb)
printf ("** Checksum Error in booting catalog validation entry on %d:%d **\n",
dev_desc->dev, part_num);
return (-1);
}
if((pve->key[0]!=0x55)||(pve->key[1]!=0xAA)) {
if(verb)
printf ("** Key 0x55 0xAA error on %d:%d **\n",
dev_desc->dev, part_num);
return(-1);
}
#ifdef CHECK_FOR_POWERPC_PLATTFORM
if(pve->platform!=0x01) {
if(verb)
printf ("** No PowerPC platform CD on %d:%d **\n",
dev_desc->dev, part_num);
return(-1);
}
#endif
/* the validation entry seems to be ok, now search the "partition" */
entry_num=0;
offset=0x20;
sprintf (info->type, "U-Boot");
switch(dev_desc->if_type) {
case IF_TYPE_IDE:
case IF_TYPE_ATAPI:
sprintf (info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
case IF_TYPE_SCSI:
sprintf (info->name, "sd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
case IF_TYPE_USB:
sprintf (info->name, "usbd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
case IF_TYPE_DOC:
sprintf (info->name, "docd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
default:
sprintf (info->name, "xx%c%d\n", 'a' + dev_desc->dev, part_num);
break;
}
/* the bootcatalog (including validation Entry) is limited to 2048Bytes
* (63 boot entries + validation entry) */
while(offset<2048) {
pide=(iso_init_def_entry_t *)&tmpbuf[offset];
if ((pide->boot_ind==0x88) ||
(pide->boot_ind==0x00)) { /* Header Id for default Sections Entries */
if(entry_num==part_num) { /* part found */
goto found;
}
entry_num++; /* count partitions Entries (boot and non bootables */
offset+=0x20;
continue;
}
if ((pide->boot_ind==0x90) || /* Section Header Entry */
(pide->boot_ind==0x91) || /* Section Header Entry (last) */
(pide->boot_ind==0x44)) { /* Extension Indicator */
offset+=0x20; /* skip unused entries */
}
else {
if(verb)
printf ("** Partition %d not found on device %d **\n",
part_num,dev_desc->dev);
return(-1);
}
}
/* if we reach this point entire sector has been
* searched w/o succsess */
if(verb)
printf ("** Partition %d not found on device %d **\n",
part_num,dev_desc->dev);
return(-1);
found:
if(pide->boot_ind!=0x88) {
if(verb)
printf ("** Partition %d is not bootable on device %d **\n",
part_num,dev_desc->dev);
return (-1);
}
switch(pide->boot_media) {
case 0x00: /* no emulation */
info->size=le16_to_int(pide->sec_cnt)>>2;
break;
case 0x01: info->size=2400>>2; break; /* 1.2MByte Floppy */
case 0x02: info->size=2880>>2; break; /* 1.44MByte Floppy */
case 0x03: info->size=5760>>2; break; /* 2.88MByte Floppy */
case 0x04: info->size=2880>>2; break; /* dummy (HD Emulation) */
default: info->size=0; break;
}
newblkaddr=le32_to_int(pide->rel_block_addr);
info->start=newblkaddr;
PRINTF(" part %d found @ %lx size %lx\n",part_num,newblkaddr,info->size);
return 0;
}
int get_partition_info_iso(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info)
{
return(get_partition_info_iso_verb(dev_desc, part_num, info, 1));
}
void print_part_iso(block_dev_desc_t * dev_desc)
{
disk_partition_t info;
int i;
if(get_partition_info_iso_verb(dev_desc,0,&info,0)==-1) {
printf("** No boot partition found on device %d **\n",dev_desc->dev);
return;
}
printf("Part Start Sect x Size Type\n");
i=0;
do {
printf (" %2d %8ld %8ld %6ld %.32s\n",
i, info.start, info.size, info.blksz, info.type);
i++;
} while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);
}
int test_part_iso (block_dev_desc_t *dev_desc)
{
disk_partition_t info;
return(get_partition_info_iso_verb(dev_desc,0,&info,0));
}
#endif /* ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_ISO_PARTITION) */

25
doc/README.OXC Normal file
View File

@ -0,0 +1,25 @@
This document contains different information about the port
of U-Boot for the OXC board designed by Lucent Technologies,
Inc.
1. Showing activity
U-Boot for the OXC board can show its current status using
the Active LED. This feature is configured by the following
options:
CONFIG_SHOW_ACTIVITY
When this option is on, the Active LED is blinking fast
when U-Boot runs in the idle loop (i.e. waits for user
commands from serial console) and blinking slow when it
downloads an image over network. When U-Boot loads an image
over serial line the Active LED does not blink and its state
is random (i.e. either constant on or constant off).
CONFIG_SHOW_BOOT_PROGRESS
When this option is on, U-Boot switches the Active LED
off before booting an image and switches it on if booting
failed due to some reasons.

158
doc/README.autoboot Normal file
View File

@ -0,0 +1,158 @@
/*
* (C) Copyright 2001
* Dave Ellis, SIXNET, dge@sixnetio.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
Using autoboot configuration options
====================================
The basic autoboot configuration options are documented in the main
U-Boot README. See it for details. They are:
bootdelay
bootcmd
CONFIG_BOOTDELAY
CONFIG_BOOTCOMMAND
Some additional options that make autoboot safer in a production
product are documented here.
Why use them?
-------------
The basic autoboot feature allows a system to automatically boot to
the real application (such as Linux) without a user having to enter
any commands. If any key is pressed before the boot delay time
expires, U-Boot stops the autoboot process, gives a U-Boot prompt
and waits forever for a command. That's a good thing if you pressed a
key because you wanted to get the prompt.
It's not so good if the key press was a stray character on the
console serial port, say because a user who knows nothing about
U-Boot pressed a key before the system had time to boot. It's even
worse on an embedded product that doesn't have a console during
normal use. The modem plugged into that console port sends a
character at the wrong time and the system hangs, with no clue as to
why it isn't working.
You might want the system to autoboot to recover after an external
configuration program stops autoboot. If the configuration program
dies or loses its connection (modems can disconnect at the worst
time) U-Boot will patiently wait forever for it to finish.
These additional configuration options can help provide a system that
boots when it should, but still allows access to U-Boot.
What they do
------------
CONFIG_BOOT_RETRY_TIME
CONFIG_BOOT_RETRY_MIN
bootretry environment variable
These options determine what happens after autoboot is
stopped and U-Boot is waiting for commands.
CONFIG_BOOT_RETRY_TIME must be defined to enable the boot
retry feature. If the environment variable 'bootretry' is
found then its value is used, otherwise the retry timeout is
CONFIG_BOOT_RETRY_TIME. CONFIG_BOOT_RETRY_MIN is optional and
defaults to CONFIG_BOOT_RETRY_TIME. All times are in seconds.
If the retry timeout is negative, the U-Boot command prompt
never times out. Otherwise it is forced to be at least
CONFIG_BOOT_RETRY_MIN seconds. If no valid U-Boot command is
entered before the specified time the boot delay sequence is
restarted. Each command that U-Boot executes restarts the
timeout.
If CONFIG_BOOT_RETRY_TIME < 0 the feature is there, but
doesn't do anything unless the environment variable
'bootretry' is >= 0.
CONFIG_AUTOBOOT_KEYED
CONFIG_AUTOBOOT_PROMPT
CONFIG_AUTOBOOT_DELAY_STR
CONFIG_AUTOBOOT_STOP_STR
CONFIG_AUTOBOOT_DELAY_STR2
CONFIG_AUTOBOOT_STOP_STR2
bootdelaykey environment variable
bootstopkey environment variable
bootdelaykey2 environment variable
bootstopkey2 environment variable
These options give more control over stopping autoboot. When
they are used a specific character or string is required to
stop or delay autoboot.
Define CONFIG_AUTOBOOT_KEYED (no value required) to enable
this group of options. CONFIG_AUTOBOOT_DELAY_STR,
CONFIG_AUTOBOOT_STOP_STR or both should be specified (or
specified by the corresponding environment variable),
otherwise there is no way to stop autoboot.
CONFIG_AUTOBOOT_PROMPT is displayed before the boot delay
selected by CONFIG_BOOTDELAY starts. If it is not defined
there is no output indicating that autoboot is in progress.
If "%d" is included, it is replaced by the number of seconds
remaining before autoboot will start, but it does not count
down the seconds. "autoboot in %d seconds\n" is a reasonable
prompt.
If CONFIG_AUTOBOOT_DELAY_STR or bootdelaykey is specified and
this string is received from console input before autoboot
starts booting, U-Boot gives a command prompt. The U-Boot
prompt will time out if CONFIG_BOOT_RETRY_TIME is used,
otherwise it never times out.
If CONFIG_AUTOBOOT_STOP_STR or bootstopkey is specified and
this string is received from console input before autoboot
starts booting, U-Boot gives a command prompt. The U-Boot
prompt never times out, even if CONFIG_BOOT_RETRY_TIME is
used.
The string recognition is not very sophisticated. If a
partial match is detected, the first non-matching character
is checked to see if starts a new match. There is no check
for a shorter partial match, so it's best if the first
character of a key string does not appear in the rest of the
string.
Using the CONFIG_AUTOBOOT_DELAY_STR2 / bootdelaykey2 and/or
CONFIG_AUTOBOOT_STOP_STR2 / bootstopkey #defines and/or
environment variables you can specify a second, alternate
string (which allows you to haw two "password" strings).
CONFIG_ZERO_BOOTDELAY_CHECK
If this option is defined, you can stop the autoboot process
by hitting a key even in that case when "bootdelay" has been
set to 0. You can set "bootdelay" to a negative value to
prevent the check for console input.
CONFIG_RESET_TO_RETRY
(Only effective when CONFIG_BOOT_RETRY_TIME is also set)
After the countdown timed out, the board will be reset to restart
again.

118
doc/README.console Normal file
View File

@ -0,0 +1,118 @@
/*
* (C) Copyright 2000
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
U-Boot console handling
========================
HOW THE CONSOLE WORKS?
----------------------
At system startup U-Boot initializes a serial console. When U-Boot
relocates itself to RAM, all console drivers are initialized (they
will register all detected console devices to the system for further
use).
If not defined in the environment, the first input device is assigned
to the 'stdin' file, the first output one to 'stdout' and 'stderr'.
You can use the command "coninfo" to see all registered console
devices and their flags. You can assign a standard file (stdin,
stdout or stderr) to any device you see in that list simply by
assigning its name to the corresponding environment variable. For
example:
setenv stdin wl_kbd <- To use the wireless keyboard
setenv stdout video <- To use the video console
Do a simple "saveenv" to save the console settings in the environment
and get them working on the next startup, too.
HOW CAN I USE STANDARD FILE INTO THE SOURCES?
---------------------------------------------
You can use the following functions to access the console:
* STDOUT:
putc (to put a char to stdout)
puts (to put a string to stdout)
printf (to format and put a string to stdout)
* STDIN:
tstc (to test for the presence of a char in stdin)
getc (to get a char from stdin)
* STDERR:
eputc (to put a char to stderr)
eputs (to put a string to stderr)
eprintf (to format and put a string to stderr)
* FILE (can be 'stdin', 'stdout', 'stderr'):
fputc (like putc but redirected to a file)
fputs (like puts but redirected to a file)
fprintf (like printf but redirected to a file)
ftstc (like tstc but redirected to a file)
fgetc (like getc but redirected to a file)
Remember that all FILE-related functions CANNOT be used before
U-Boot relocation (done in 'board_init_r' in common/board.c).
HOW CAN I USE STANDARD FILE INTO APPLICATIONS?
----------------------------------------------
Use the 'bd_mon_fnc' field of the bd_t structure passed to the
application to do everything you want with the console.
But REMEMBER that that will work only if you have not overwritten any
U-Boot code while loading (or uncompressing) the image of your
application.
For example, you won't get the console stuff running in the Linux
kernel because the kernel overwrites U-Boot before running. Only
some parameters like the framebuffer descriptors are passed to the
kernel in the high memory area to let the applications (the kernel)
use the framebuffers initialized by U-Boot.
SUPPORTED DRIVERS
-----------------
Working drivers:
serial (architecture dependent serial stuff)
video (mpc8xx video controller)
Work in progress:
wl_kbd (Wireless 4PPM keyboard)
Waiting for volounteers:
lcd (mpc8xx lcd controller; to )
TESTED CONFIGURATIONS
---------------------
The driver has been tested with the following configurations (see
CREDITS for other contact informations):
- MPC823FADS with AD7176 on a PAL TV (YCbYCr) - arsenio@tin.it
- GENIETV with AD7177 on a PAL TV (YCbYCr) - arsenio@tin.it

1709
drivers/bcm570x.c Normal file

File diff suppressed because it is too large Load Diff

57
include/cmd_disk.h Normal file
View File

@ -0,0 +1,57 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Harddisk support
*/
#ifndef _CMD_DISK_H
#define _CMD_DISK_H
#include <common.h>
#include <command.h>
/*
* Type string for PPC bootable partitions
*/
#define BOOT_PART_TYPE "U-Boot"
#if 0
typedef struct disk_partition {
ulong start; /* # of first block in partition */
ulong size; /* number of blocks in partition */
ulong blksz; /* block size in bytes */
uchar name[32]; /* partition name */
uchar type[32]; /* string type description */
} disk_partition_t;
int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
#ifdef CONFIG_MAC_PARTITION
int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
#endif
#ifdef CONFIG_DOS_PARTITION
int get_partition_info_dos (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
#endif
#endif /* 0 */
#endif /* _CMD_DISK_H */

297
include/configs/AMX860.h Normal file
View File

@ -0,0 +1,297 @@
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* board/config.h - configuration options, board specific
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_MPC860 1
#define CONFIG_AMX860 1
#undef CONFIG_8xx_CONS_SMC1 /* Console is on SCC2 */
#undef CONFIG_8xx_CONS_SMC2
#define CONFIG_8xx_CONS_SCC2 1
#undef CONFIG_8xx_CONS_NONE
#define CONFIG_BAUDRATE 9600
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#define MPC8XX_FACT 10 /* Multiply by 10 */
#define MPC8XX_XIN 5000000 /* 5 MHz in */
#define MPC8XX_HZ ((MPC8XX_XIN) * (MPC8XX_FACT))
#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
#if 0
#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
#else
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
#endif
#define CONFIG_BOOTCOMMAND \
"bootp;" \
"setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \
"bootm" /* autoboot command */
#undef CONFIG_BOOTARGS
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#undef CONFIG_KGDB_ON_SMC /* define if kgdb on SMC */
#define CONFIG_KGDB_ON_SCC /* define if kgdb on SCC */
#undef CONFIG_KGDB_NONE /* define if kgdb on something else */
#define CONFIG_KGDB_INDEX 1 /* which serial channel for kgdb */
#define CONFIG_KGDB_BAUDRATE 9600 /* speed to run kgdb serial port at */
#endif
#undef CONFIG_WATCHDOG /* watchdog disabled */
#define CONFIG_SCC1_ENET 1 /* use SCC1 ethernet */
#define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
CFG_CMD_DHCP | \
CFG_CMD_DATE )
#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "=> " /* Monitor Command Prompt */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x0100000 /* memtest works on */
#define CFG_MEMTEST_END 0x0200000 /* 1 ... 4 MB in DRAM */
#define CFG_LOAD_ADDR 0x00100000
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
/*
* Low Level Configuration Settings
* (address mappings, register initial values, etc.)
* You should know what you are doing if you make changes here.
*/
/*-----------------------------------------------------------------------
* Internal Memory Mapped Register
*/
#define CFG_IMMR 0xFF000000
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR CFG_IMMR
#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
*/
#define CFG_SDRAM_BASE 0x00000000
#define CFG_FLASH_BASE 0x40000000
#if defined(DEBUG)
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
#else
#define CFG_MONITOR_LEN (192 << 10) /* Reserve 192 kB for Monitor */
#endif
#define CFG_MONITOR_BASE CFG_FLASH_BASE
#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
/*
* U-Boot for AMX board supports two types of memory extension
* modules: one that provides 4 MB flash memory, and another one with
* 16 MB EDO DRAM.
*
* The flash module swaps the CS0 and CS1 signals: if the module is
* installed, CS0 is connected to Flash on the module and CS1 is
* connected to the on-board Flash. This means that you must intall
* U-Boot when the Flash module is plugged in, if you plan to use
* it.
*
* To enable support for the DRAM extension card, CONFIG_AMX_RAM_EXT
* must be defined. The DRAM module uses CS1.
*
* Only one of these modules may be installed at a time. If U-Boot
* is compiled with the CONFIG_AMX_RAM_EXT option set, it will not
* work if the Flash extension module is installed instead of the
* DRAM module.
*/
#define CONFIG_AMX_RAM_EXT /* 16Mb Ext. DRAM module support */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*
* Use 4 MB for without and 8 MB with 16 MB DRAM extension module
* (CONFIG_AMX_RAM_EXT)
*/
#ifdef CONFIG_AMX_RAM_EXT
# define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
#else
# define CFG_BOOTMAPSZ (4 << 20) /* Initial Memory map for Linux */
#endif
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 35 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_OFFSET 0x8000 /* Offset of Environment Sector */
#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */
#endif
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control 11-9
* SYPCR can only be written once after reset!
*-----------------------------------------------------------------------
* Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
*/
#if defined(CONFIG_WATCHDOG)
#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP)
#else
#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | SYPCR_SWP)
#endif
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration 11-6
*-----------------------------------------------------------------------
* PCMCIA config., multi-function pin tri-state
*/
#define CFG_SIUMCR (SIUMCR_DBGC00 | SIUMCR_DBPC00 | SIUMCR_MLRC01)
/*-----------------------------------------------------------------------
* TBSCR - Time Base Status and Control 11-26
*-----------------------------------------------------------------------
* Clear Reference Interrupt Status, Timebase freezing enabled
*/
#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBE)
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control 11-31
*-----------------------------------------------------------------------
* Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
*/
#define CFG_PISCR (PISCR_PS | PISCR_PITF)
/*-----------------------------------------------------------------------
* PLPRCR - PLL, Low-Power, and Reset Control Register 15-30
*-----------------------------------------------------------------------
* set the PLL, the low-power modes and the reset control (15-29)
*/
#define CFG_PLPRCR (((MPC8XX_FACT-1) << PLPRCR_MF_SHIFT) | \
PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
/*-----------------------------------------------------------------------
* SCCR - System Clock and reset Control Register 15-27
*-----------------------------------------------------------------------
* Set clock output, timebase and RTC source and divider,
* power management and some other internal clocks
*/
#define SCCR_MASK SCCR_EBDF11
#define CFG_SCCR (SCCR_TBS|SCCR_COM00|SCCR_DFSYNC00|SCCR_DFBRG00|SCCR_DFNL000|SCCR_DFNH000|SCCR_DFLCD000|SCCR_DFALCD00)
#define CFG_DER 0
/*
* Init Memory Controller:
*
* BR0/1 and OR0/1 (FLASH)
*/
#define FLASH_BASE0_PRELIM 0x40000000 /* FLASH bank #0 */
#ifndef CONFIG_AMX_RAM_EXT
#define FLASH_BASE1_PRELIM 0x60000000 /* FLASH bank #1 */
#endif
#define CFG_REMAP_OR_AM 0x80000000 /* OR addr mask */
#define CFG_PRELIM_OR_AM 0xFFC00000 /* OR addr mask */
/* FLASH timing: ACS = 10, TRLX = 1, CSNT = 1, SCY = 3, EHTR = 0 */
/* 0x00000800 0x00000400 0x00000100 0x00000030 0x00000004 */
#define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_5_CLK | OR_TRLX)
#define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH)
#define CFG_OR0_PRELIM 0xFFC00954 /* Real values for the board */
#define CFG_BR0_PRELIM 0x40000001 /* Real values for the board */
#ifndef CONFIG_AMX_RAM_EXT
#define CFG_OR1_REMAP CFG_OR0_REMAP
#define CFG_OR1_PRELIM 0xFFC00954 /* Real values for the board */
#define CFG_BR1_PRELIM 0x60000001 /* Real values for the board */
#endif
/* DSP ("Glue") Xilinx */
#define CFG_OR6_PRELIM 0xFFFF8000 /* 32kB, 15 waits, cs after addr, no bursts */
#define CFG_BR6_PRELIM 0x60000401 /* use GPCM for CS generation, 8 bit port */
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#endif /* __CONFIG_H */

357
include/configs/SXNI855T.h Normal file
View File

@ -0,0 +1,357 @@
/*
* U-Boot configuration for SIXNET SXNI855T CPU board.
* This board is based (loosely) on the Motorola FADS board, so this
* file is based (loosely) on config_FADS860T.h, see it for additional
* credits.
*
* Copyright (c) 2000-2002 Dave Ellis, SIXNET, dge@sixnetio.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/*
* Memory map:
*
* ff100000 -> ff13ffff : FPGA CS1
* ff030000 -> ff03ffff : EXPANSION CS7
* ff020000 -> ff02ffff : DATA FLASH CS4
* ff018000 -> ff01ffff : UART B CS6/UPMB
* ff010000 -> ff017fff : UART A CS5/UPMB
* ff000000 -> ff00ffff : IMAP internal to the MPC855T
* f8000000 -> fbffffff : FLASH CS0 up to 64MB
* f4000000 -> f7ffffff : NVSRAM CS2 up to 64MB
* 00000000 -> 0fffffff : SDRAM CS3/UPMA up to 256MB
*/
/* ------------------------------------------------------------------------- */
/*
* board/config.h - configuration options, board specific
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#include <mpc8xx_irq.h>
#define CONFIG_SXNI855T 1 /* SIXNET IPm 855T CPU module */
/* The 855T is just a stripped 860T and needs code for 860, so for now
* at least define 860, 860T and 855T
*/
#define CONFIG_MPC860 1
#define CONFIG_MPC860T 1
#define CONFIG_MPC855T 1
#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */
#undef CONFIG_8xx_CONS_SMC2
#undef CONFIG_8xx_CONS_SCC1
#undef CONFIG_8xx_CONS_NONE
#define CONFIG_BAUDRATE 9600
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#define MPC8XX_FACT 10 /* 50 MHz is 5 MHz in times 10 */
#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
#if 0
#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
#else
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
#endif
#define CONFIG_BOOTCOMMAND "bootm f8040000 f8100000" /* autoboot command */
#define CONFIG_BOOTARGS "root=/dev/ram ip=off"
#define CONFIG_MISC_INIT_R /* have misc_init_r() function */
#define CONFIG_BOARD_POSTCLK_INIT /* have board_postclk_init() function */
#undef CONFIG_WATCHDOG /* watchdog disabled */
#define CONFIG_RTC_DS1306 /* Dallas 1306 real time clock */
#define CONFIG_SOFT_I2C /* I2C bit-banged */
/*
* Software (bit-bang) I2C driver configuration
*/
#define PB_SCL 0x00000020 /* PB 26 */
#define PB_SDA 0x00000010 /* PB 27 */
#define I2C_INIT (immr->im_cpm.cp_pbdir |= PB_SCL)
#define I2C_ACTIVE (immr->im_cpm.cp_pbdir |= PB_SDA)
#define I2C_TRISTATE (immr->im_cpm.cp_pbdir &= ~PB_SDA)
#define I2C_READ ((immr->im_cpm.cp_pbdat & PB_SDA) != 0)
#define I2C_SDA(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SDA; \
else immr->im_cpm.cp_pbdat &= ~PB_SDA
#define I2C_SCL(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SCL; \
else immr->im_cpm.cp_pbdat &= ~PB_SCL
#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
# define CFG_I2C_SPEED 50000
# define CFG_I2C_SLAVE 0xFE
# define CFG_I2C_EEPROM_ADDR 0x50 /* Atmel 24C64 */
# define CFG_I2C_EEPROM_ADDR_LEN 2 /* two byte address */
#define CONFIG_FEC_ENET 1 /* use FEC ethernet */
#define CFG_DISCOVER_PHY
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_EEPROM | CFG_CMD_DATE)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save a little memory */
#define CFG_PROMPT "=>" /* Monitor Command Prompt */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x0100000 /* memtest works on */
#define CFG_MEMTEST_END 0x0400000 /* 1 ... 4 MB in DRAM */
#define CFG_LOAD_ADDR 0x00100000
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
/*
* Low Level Configuration Settings
* (address mappings, register initial values, etc.)
* You should know what you are doing if you make changes here.
*/
/*-----------------------------------------------------------------------
* Internal Memory Mapped Register
*/
#define CFG_IMMR 0xFF000000
#define CFG_IMMR_SIZE ((uint)(64 * 1024))
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR CFG_IMMR
#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
*/
#define CFG_SDRAM_BASE 0x00000000
#define CFG_SRAM_BASE 0xF4000000
#define CFG_SRAM_SIZE 0x04000000 /* autosize up to 64Mbyte */
#define CFG_FLASH_BASE 0xF8000000
#define CFG_FLASH_SIZE ((uint)(8 * 1024 * 1024)) /* max 8Mbyte */
#define CFG_DFLASH_BASE 0xff020000 /* DiskOnChip or NAND FLASH */
#define CFG_DFLASH_SIZE 0x00010000
#define CFG_FPGA_BASE 0xFF100000 /* Xilinx FPGA */
#define CFG_FPGA_PROG 0xFF130000 /* Programming address */
#define CFG_FPGA_SIZE 0x00040000 /* 256KiB usable */
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
#define CFG_MONITOR_BASE CFG_FLASH_BASE
#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
/* Intel 28F640 has 135, 127 64K sectors in 8MB, + 8 more for 8K boot blocks.
* AMD 29LV641 has 128 64K sectors in 8MB
*/
#define CFG_MAX_FLASH_SECT 135 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */
#endif
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control 11-9
* SYPCR can only be written once after reset!
*-----------------------------------------------------------------------
* Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
*/
#if defined(CONFIG_WATCHDOG)
#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP)
#else
#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | SYPCR_SWP)
#endif
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration 11-6
*-----------------------------------------------------------------------
* PCMCIA config., multi-function pin tri-state
*/
#define CFG_SIUMCR (SIUMCR_DBGC00 | SIUMCR_DBPC00 | SIUMCR_MLRC01)
/*-----------------------------------------------------------------------
* TBSCR - Time Base Status and Control 11-26
*-----------------------------------------------------------------------
* Clear Reference Interrupt Status, Timebase freezing enabled
*/
#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBE)
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control 11-31
*-----------------------------------------------------------------------
* Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
*/
#define CFG_PISCR (PISCR_PS | PISCR_PITF)
/*-----------------------------------------------------------------------
* PLPRCR - PLL, Low-Power, and Reset Control Register 15-30
*-----------------------------------------------------------------------
* set the PLL, the low-power modes and the reset control (15-29)
*/
#define CFG_PLPRCR (((MPC8XX_FACT-1) << PLPRCR_MF_SHIFT) | \
PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
/*-----------------------------------------------------------------------
* SCCR - System Clock and reset Control Register 15-27
*-----------------------------------------------------------------------
* Set clock output, timebase and RTC source and divider,
* power management and some other internal clocks
*/
#define SCCR_MASK SCCR_EBDF11
#define CFG_SCCR (SCCR_TBS|SCCR_COM00|SCCR_DFSYNC00|SCCR_DFBRG00|SCCR_DFNL000|SCCR_DFNH000|SCCR_DFLCD000|SCCR_DFALCD00)
/*-----------------------------------------------------------------------
*
*-----------------------------------------------------------------------
*
*/
#define CFG_DER 0
/* Because of the way the 860 starts up and assigns CS0 the
* entire address space, we have to set the memory controller
* differently. Normally, you write the option register
* first, and then enable the chip select by writing the
* base register. For CS0, you must write the base register
* first, followed by the option register.
*/
/*
* Init Memory Controller:
*
**********************************************************
* BR0 and OR0 (FLASH)
*/
#define CFG_PRELIM_OR0_AM 0xFC000000 /* OR addr mask */
/* FLASH timing: ACS = 10, TRLX = 1, CSNT = 1, SCY = 3, EHTR = 0 */
#define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_3_CLK | OR_TRLX)
#define CFG_OR0_PRELIM (CFG_PRELIM_OR0_AM | CFG_OR_TIMING_FLASH)
#define CONFIG_FLASH_16BIT
#define CFG_BR0_PRELIM ((CFG_FLASH_BASE & BR_BA_MSK) | BR_PS_16 | BR_V )
#define CFG_FLASH_PROTECTION /* need to lock/unlock sectors in hardware */
/**********************************************************
* BR1 and OR1 (FPGA)
* These preliminary values are also the final values.
*/
#define CFG_OR_TIMING_FPGA \
(OR_CSNT_SAM | OR_ACS_DIV2 | OR_BI | OR_SCY_5_CLK | OR_EHTR)
#define CFG_BR1_PRELIM ((CFG_FPGA_BASE & BR_BA_MSK) | BR_PS_8 | BR_V )
#define CFG_OR1_PRELIM (((-CFG_FPGA_SIZE) & OR_AM_MSK) | CFG_OR_TIMING_FPGA)
/**********************************************************
* BR4 and OR4 (data flash)
* These preliminary values are also the final values.
*/
#define CFG_OR_TIMING_DFLASH \
(OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_5_CLK | OR_EHTR)
#define CFG_BR4_PRELIM ((CFG_DFLASH_BASE & BR_BA_MSK) | BR_PS_8 | BR_V )
#define CFG_OR4_PRELIM (((-CFG_DFLASH_SIZE) & OR_AM_MSK) | CFG_OR_TIMING_DFLASH)
/**********************************************************
* BR5/6 and OR5/6 (Dual UART)
*/
#define CFG_DUART_SIZE 0x8000 /* 32K window, only uses 8 bytes */
#define CFG_DUARTA_BASE 0xff010000
#define CFG_DUARTB_BASE 0xff018000
#define DUART_MBMR 0
#define DUART_OR_VALUE (ORMASK(CFG_DUART_SIZE) | OR_G5LS| OR_BI)
#define DUART_BR_VALUE (BR_MS_UPMB | BR_PS_8 | BR_V)
#define DUART_BR5_VALUE ((CFG_DUARTA_BASE & BR_BA_MSK ) | DUART_BR_VALUE)
#define DUART_BR6_VALUE ((CFG_DUARTB_BASE & BR_BA_MSK ) | DUART_BR_VALUE)
/**********************************************************
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#define CONFIG_RESET_ON_PANIC /* reset if system panic() */
/* to put environment in EEROM */
#define CFG_ENV_IS_IN_EEPROM 1
#define CFG_ENV_OFFSET 0 /* Start right at beginning of NVRAM */
#define CFG_ENV_SIZE 1024 /* Use only a part of it*/
#if 1
#define CONFIG_BOOT_RETRY_TIME 60 /* boot if no command in 60 seconds */
#endif
#if 1
#define CONFIG_AUTOBOOT_KEYED /* use key strings to stop autoboot */
#define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds\n"
#define CONFIG_AUTOBOOT_DELAY_STR "delayabit"
#define CONFIG_AUTOBOOT_STOP_STR " " /* easy to stop for now */
#endif
#endif /* __CONFIG_H */