Initial revision
diff --git a/CREDITS b/CREDITS
new file mode 100644
index 0000000..2358817
--- /dev/null
+++ b/CREDITS
@@ -0,0 +1,242 @@
+#
+#   Parts of the development effort for this project have been
+#   sponsored by SIEMENS AG, Austria. Thanks to SIEMENS for
+#   supporting an Open Source project!
+#
+#
+#   This is at least a partial credits-file of individual people that
+#   have contributed to the U-Boot project. It is sorted by name and
+#   formatted to allow easy grepping and beautification by scripts.
+#   The fields are: name (N), email (E), web-address (W), PGP key ID
+#   and fingerprint (P), description (D), and snail-mail address (S).
+#   Thanks,
+#
+#                       Wolfgang Denk
+#----------
+
+N: Dr. Bruno Achauer
+E: bruno@exet-ag.de
+D: Support for NetBSD (both as host and target system)
+
+N: Swen Anderson
+E: sand@peppercon.de
+D: ERIC Support
+
+N: Guillaume Alexandre
+E: guillaume.alexandre@gespac.ch
+D: Add PCIPPC6 configuration
+
+N: Pierre Aubert
+E: <p.aubert@staubli.com>
+D: Support for RPXClassic board
+
+N: Andre Beaudin
+E: <andre.beaudin@colubris.com>
+D: PCMCIA, Ethernet, TFTP
+
+N: Jerry van Baren
+E: <vanbaren@cideas.com>
+D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test.
+
+N: Raphael Bossek
+E: raphael.bossek@solutions4linux.de
+D: 8xxrom-0.3.0
+
+N: David Brown
+E: DBrown03@harris.com
+D: Extensions to 8xxrom-0.3.0
+
+N: Oliver Brown
+E: obrown@adventnetworks.com
+D: Port to the gw8260 board
+
+N: Jonathan De Bruyne
+E: jonathan.debruyne@siemens.atea.be
+D: Port to Siemens IAD210 board
+
+N: Conn Clark
+E: clark@esteem.com
+D: ESTEEM192E support
+
+N: Magnus Damm
+E: eramdam@kieray1.p.y.ki.era.ericsson.se
+D: 8xxrom
+
+N: Kári Davíðsson
+E: kd@flaga.is
+D: FLAGA DM Support
+
+N: Wolfgang Denk
+E: wd@denx.de
+D: U-Boot initial version, continuing maintenance, ARMBoot merge
+W: http://www.denx.de
+
+N: Dan A. Dickey
+E: ddickey@charter.net
+D: FADS Support
+
+N: James F. Dougherty
+E: jfd@GigabitNetworks.COM
+D: Port to the MOUSSE board
+
+N: Dave Ellis
+E: DGE@sixnetio.com
+D: EEPROM Speedup, SXNI855T port
+
+N: Dr. Wolfgang Grandegger
+E: wg@denx.de
+D: Support for Interphase 4539 T1/E1/J1 PMC, PN62, CCM, SCM boards
+W: www.denx.de
+
+N: Frank Gottschling
+E: fgottschling@eltec.de
+D: Support for ELTEC MHPC/BAB7xx/ELPPC boards, cfb-console, i8042, SMI LynxEM
+W: www.eltec.de
+
+N: Marius Groeger
+E: mgroeger@sysgo.de
+D: MBX Support, board specific function interface, EST SBC8260 support; initial support for StrongARM (LART), ARM720TDMI (implementa A7)
+W: www.elinos.com
+
+N: Kirk Haderlie
+E: khaderlie@vividimage.com
+D: Added TFTP to 8xxrom (-> 0.3.1)
+
+N: Chris Hallinan
+E: clh@net1plus.com
+D: DHCP Support
+
+N: Anne-Sophie Harnois
+E: Anne-Sophie.Harnois@nextream.fr
+D: Port to Walnut405 board
+
+N: Andreas Heppel
+E: aheppel@sysgo.de
+D: CPU Support for MPC 75x; board support for Eltec BAB750 [obsolete!]
+
+N: Josh Huber
+E: huber@alum.wpi.edu
+D: Port to the Galileo Evaluation Board, and the MPC74xx cpu series.
+W: http://www.mclx.com/
+
+H: Stuart Hughes
+E: stuarth@lineo.com
+D: Port to MPC8260ADS board
+
+H: Rich Ireland
+E: r.ireland@computer.org
+D: FPGA device configuration driver
+
+N: Gary Jennejohn
+E: garyj@jennejohn.org, gj@denx.de
+D: Support for Samsung ARM920T S3C2400X, ARM920T "TRAB"
+W: www.denx.de
+
+N: Murray Jensen
+E: Murray.Jensen@cmst.csiro.au
+D: Initial 8260 support; GDB support
+D: Port to Cogent+Hymod boards; Hymod Board Database
+W: http://www.msa.cmst.csiro.au/ourstaff/MurrayJensen/mjj.html
+
+N: Yoo. Jonghoon
+E: yooth@ipone.co.kr
+D: Added port to the RPXlite board
+
+N: Brad Kemp
+E: Brad.Kemp@seranoa.com
+D: Port to Windriver ppmc8260 board
+
+N: Thomas Koeller
+E: tkoeller@gmx.net
+D: Port to Motorola Sandpoint 3 (MPC8240)
+
+N: Thomas Lange
+E: thomas@corelatus.com
+D: Support for GTH board; lots of PCMCIA fixes
+
+N: Raymond Lo
+E: lo@routefree.com
+D: Support for DOS partitions
+
+N: Dan Malek
+E: dan@netx4.com
+D: FADSROM, the grandfather of all of this
+
+N: Jay Monkman
+E: jtm@smoothsmoothie.com
+D: EST SBC8260 support
+
+N: Frank Morauf
+E: frank.morauf@salzbrenner.com
+D: Support for Embedded Planet RPX Super Board
+
+N: David Müller
+E: d.mueller@elsoft.ch
+D: Support for Samsung ARM920T SMDK2410 eval board
+
+N: Rolf Offermanns
+E: rof@sysgo.de
+D: Initial support for SSV-DNP1110, SMC91111 driver
+W: www.elinos.com
+
+N: Keith Outwater
+E: Keith_Outwater@mvis.com
+D: Support for GEN860T board
+
+N: Keith Outwater
+E: keith_outwater@mvis.com
+D: Support for generic/custom MPC860T board (GEN860T)
+
+N: Frank Panno
+E: fpanno@delphintech.com
+D: Support for Embedded Planet EP8260 Board
+
+N: Denis Peter
+E: d.peter@mpl.ch
+D: Support for 4xx SCSI, floppy, CDROM, CT69000 video, ...
+D: Support for PIP405 board
+D: Support for MIP405 board
+
+N: Bill Pitts
+E: wlp@mindspring.com
+D: BedBug embedded debugger code
+
+N: Stefan Roese
+E: stefan.roese@esd-electronics.com
+D: IBM PPC401/403/405GP Support; Windows environment support
+
+N: Neil Russell
+E: caret@c-side.com
+D: Author of LiMon-1.4.2, which contributed some ideas
+
+N: Paolo Scaffardi
+E: arsenio@tin.it
+D: FADS823 configuration, MPC823 video support, I2C, wireless keyboard, lots more
+
+N: Robert Schwebel
+E: r.schwebel@pengutronix.de
+D: Support for csb226 board (xscale)
+N: Rob Taylor
+E: robt@flyingpig.com
+D: Port to MBX860T and Sandpoint8240
+
+N: Erik Theisen
+E: etheisen@mindspring.com
+D: MBX8xx and many other patches
+
+N: Jim Thompson
+E: jim@musenki.com
+D: Support for MUSENKI board
+
+N: David Updegraff
+E: dave@cray.com
+D: Port to Cray L1 board; DHCP vendor extensions
+
+N: Christian Vejlbo
+E: christian.vejlbo@tellabs.com
+D: FADS860T ethernet support
+
+N: Alex Zuepke
+E: azu@sysgo.de
+D: Overall improvements on StrongARM, ARM720TDMI; Support for Tuxscreen; initial PCMCIA support for ARM
+W: www.elinos.com
diff --git a/README b/README
new file mode 100644
index 0000000..30ff772
--- /dev/null
+++ b/README
@@ -0,0 +1,2663 @@
+#
+# (C) Copyright 2000 - 2002
+# 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
+#
+
+Summary:
+========
+
+This directory contains the source code for U-Boot, a monitor for
+Embedded PowerPC boards, which can be installed in a boot ROM and
+used to test the hardware or download and run application code.
+
+The development of U-Boot is closely related to Linux: some parts of
+the source code originate in the Linux source tree, we still have
+some header files in common, and special provision has been made to
+support booting of Linux images.
+
+Some attention has been paid to make this software easily
+configurable and extendable. For instance, all monitor commands are
+implemented with the same call interface, so that it's very easy to
+add new commands. Also, instead of permanently adding rarely used
+code (for instance hardware test utilities) to the monitor, you can
+load and run it dynamically.
+
+
+Status:
+=======
+
+In general, all boards for which a configuration option exists in the
+Makefile have been tested  to  some  extent  and  can  be  considered
+"working". In fact, many of them are used in production systems.
+
+In case of problems see the CHANGELOG and CREDITS files to  find  out
+who contributed the specific port.
+
+Exception from this rule: the port to the Sandpoint 8240 has not been
+completed yet.
+
+
+Where to get help:
+==================
+
+In case you have questions about, problems with or contributions  for
+U-Boot	 you  should  send  a  message to the U-Boot mailing list at
+<u-boot-users@lists.sourceforge.net>. There is also  an  archive  of
+previous  traffic  on  the  mailing  list - please search the archive
+before asking FAQ's. Please see
+http://lists.sourceforge.net/lists/listinfo/u-boot-users/
+
+
+Where we come from:
+===================
+
+- start from 8xxrom sources
+- clean up code
+- make it easier to add custom boards
+- make it possible to add other [PowerPC] CPUs
+- extend functions, especially:
+  * Provide extended interface to Linux boot loader
+  * S-Record download
+  * network boot
+  * PCMCIA / CompactFLash / ATA disk / SCSI ... boot
+- add other CPU families (starting with ARM)
+
+
+Directory Hierarchy:
+====================
+
+- board		Board dependend files
+- common	Misc architecture independend functions
+- cpu		CPU specific files
+- disk		Code for disk drive partition handling
+- doc		Documentation (don't expect too much)
+- drivers	Common used device drivers
+- dtt		Digital Thermometer and Thermostat drivers
+- examples	Example code for standalone applications, etc.
+- include	Header Files
+- disk		Harddisk interface code
+- net		Networking code
+- ppc		Files generic to PowerPC architecture
+- post		Power On Self Test
+- post/arch		Symlink to architecture specific Power On Self Test
+- post/arch-ppc		PowerPC architecture specific Power On Self Test
+- post/cpu/mpc8260	MPC8260 CPU specific Power On Self Test
+- post/cpu/mpc8xx	MPC8xx CPU specific Power On Self Test
+- rtc		Real Time Clock drivers
+- tools		Tools to build S-Record or U-Boot images, etc.
+
+- cpu/74xx_7xx	Files specific to Motorola MPC74xx and 7xx CPUs
+- cpu/mpc8xx	Files specific to Motorola MPC8xx  CPUs
+- cpu/mpc824x	Files specific to Motorola MPC824x CPUs
+- cpu/mpc8260	Files specific to Motorola MPC8260 CPU
+- cpu/ppc4xx	Files specific to IBM	   4xx	   CPUs
+
+- board/RPXClassic
+		Files specific to RPXClassic boards
+- board/RPXlite	Files specific to RPXlite    boards
+- board/c2mon	Files specific to c2mon	     boards
+- board/cogent	Files specific to Cogent     boards
+		(need further configuration)
+		Files specific to CPCIISER4  boards
+- board/cpu86	Files specific to CPU86      boards
+- board/cray/	Files specific to boards manufactured by Cray
+- board/cray/L1		Files specific to L1         boards
+- board/cu824	Files specific to CU824	     boards
+- board/ebony   Files specific to IBM Ebony board
+- board/eric	Files specific to ERIC	     boards
+- board/esd/	Files specific to boards manufactured by ESD
+- board/esd/adciop	Files specific to ADCIOP     boards
+- board/esd/ar405	Files specific to AR405	     boards
+- board/esd/canbt	Files specific to CANBT	     boards
+- board/esd/cpci405	Files specific to CPCI405    boards
+- board/esd/cpciiser4	Files specific to CPCIISER4  boards
+- board/esd/common	Common files for ESD boards
+- board/esd/dasa_sim	Files specific to DASA_SIM   boards
+- board/esd/du405	Files specific to DU405      boards
+- board/esd/ocrtc	Files specific to OCRTC      boards
+- board/esd/pci405	Files specific to PCI405     boards
+- board/esteem192e
+		Files specific to ESTEEM192E boards
+- board/etx094	Files specific to ETX_094    boards
+- board/evb64260
+		Files specific to EVB64260   boards
+- board/fads	Files specific to FADS	     boards
+- board/flagadm Files specific to FLAGADM    boards
+- board/gen860t Files specific to GEN860T    boards
+- board/genietv Files specific to GENIETV    boards
+- board/gth	Files specific to GTH	     boards
+- board/hermes	Files specific to HERMES     boards
+- board/hymod	Files specific to HYMOD	     boards
+- board/icu862	Files specific to ICU862     boards
+- board/ip860	Files specific to IP860	     boards
+- board/iphase4539
+		Files specific to Interphase4539 boards
+- board/ivm	Files specific to IVMS8/IVML24 boards
+- board/lantec	Files specific to LANTEC     boards
+- board/lwmon	Files specific to LWMON	     boards
+- board/mbx8xx	Files specific to MBX	     boards
+- board/mpc8260ads
+		Files specific to MMPC8260ADS boards
+- board/mpl/	Files specific to boards manufactured by MPL
+- board/mpl/common	Common files for MPL boards
+- board/mpl/pip405	Files specific to PIP405     boards
+- board/mpl/mip405	Files specific to MIP405     boards
+- board/musenki	Files specific to MUSEKNI    boards
+- board/mvs1	Files specific to MVS1       boards
+- board/nx823   Files specific to NX823      boards
+- board/oxc	Files specific to OXC        boards
+- board/pcippc2	Files specific to PCIPPC2/PCIPPC6 boards
+- board/pm826	Files specific to PM826      boards
+- board/ppmc8260
+		Files specific to PPMC8260   boards
+- board/rpxsuper
+		Files specific to RPXsuper   boards
+- board/rsdproto
+		Files specific to RSDproto   boards
+- board/sandpoint
+		Files specific to Sandpoint  boards
+- board/sbc8260	Files specific to SBC8260    boards
+- board/sacsng	Files specific to SACSng     boards
+- board/siemens Files specific to boards manufactured by Siemens AG
+- board/siemens/CCM	Files specific to CCM	     boards
+- board/siemens/IAD210	Files specific to IAD210     boards
+- board/siemens/SCM	Files specific to SCM        boards
+- board/siemens/pcu_e	Files specific to PCU_E	     boards
+- board/sixnet	Files specific to SIXNET     boards
+- board/spd8xx	Files specific to SPD8xxTS   boards
+- board/tqm8260 Files specific to TQM8260    boards
+- board/tqm8xx	Files specific to TQM8xxL    boards
+- board/w7o	Files specific to W7O        boards
+- board/walnut405
+		Files specific to Walnut405  boards
+- board/westel/	Files specific to boards manufactured by Westel Wireless
+- board/westel/amx860	Files specific to AMX860     boards
+- board/utx8245	Files specific to UTX8245   boards
+
+Software Configuration:
+=======================
+
+Configuration is usually done using C preprocessor defines; the
+rationale behind that is to avoid dead code whenever possible.
+
+There are two classes of configuration variables:
+
+* Configuration _OPTIONS_:
+  These are selectable by the user and have names beginning with
+  "CONFIG_".
+
+* Configuration _SETTINGS_:
+  These depend on the hardware etc. and should not be meddled with if
+  you don't know what you're doing; they have names beginning with
+  "CFG_".
+
+Later we will add a configuration tool - probably similar to or even
+identical to what's used for the Linux kernel. Right now, we have to
+do the configuration by hand, which means creating some symbolic
+links and editing some configuration files. We use the TQM8xxL boards
+as an example here.
+
+
+Selection of Processor Architecture and Board Type:
+---------------------------------------------------
+
+For all supported boards there are ready-to-use default
+configurations available; just type "make <board_name>_config".
+
+Example: For a TQM823L module type:
+
+	cd u-boot
+	make TQM823L_config
+
+For the Cogent platform, you need to specify the cpu type as well;
+e.g. "make cogent_mpc8xx_config". And also configure the cogent
+directory according to the instructions in cogent/README.
+
+
+Configuration Options:
+----------------------
+
+Configuration depends on the combination of board and CPU type; all
+such information is kept in a configuration file
+"include/configs/<board_name>.h".
+
+Example: For a TQM823L module, all configuration settings are in
+"include/configs/TQM823L.h".
+
+
+The following options need to be configured:
+
+- CPU Type:	Define exactly one of
+
+		PowerPC based CPUs:
+		-------------------
+		CONFIG_MPC823,	CONFIG_MPC850,	CONFIG_MPC855,	CONFIG_MPC860
+	or	CONFIG_MPC824X, CONFIG_MPC8260
+	or	CONFIG_IOP480
+	or	CONFIG_405GP
+	or	CONFIG_440
+	or	CONFIG_MPC74xx
+
+		ARM based CPUs:
+		---------------
+		CONFIG_SA1110
+		CONFIG_ARM7
+		CONFIG_PXA250
+
+
+- Board Type:	Define exactly one of
+
+		PowerPC based boards:
+		---------------------
+
+		CONFIG_ADCIOP,     CONFIG_ICU862      CONFIG_RPXsuper,
+		CONFIG_ADS860,     CONFIG_IP860,      CONFIG_SM850,
+		CONFIG_AMX860,     CONFIG_IPHASE4539, CONFIG_SPD823TS,
+		CONFIG_AR405,      CONFIG_IVML24,     CONFIG_SXNI855T,
+		CONFIG_BAB7xx,     CONFIG_IVML24_128, CONFIG_Sandpoint8240,
+		CONFIG_CANBT,      CONFIG_IVML24_256, CONFIG_Sandpoint8245,
+		CONFIG_CCM,        CONFIG_IVMS8,      CONFIG_TQM823L,
+		CONFIG_CPCI405,    CONFIG_IVMS8_128,  CONFIG_TQM850L,
+		CONFIG_CPCI4052,   CONFIG_IVMS8_256,  CONFIG_TQM855L,
+		CONFIG_CPCIISER4,  CONFIG_LANTEC,     CONFIG_TQM860L,
+		CONFIG_CPU86,      CONFIG_MBX,        CONFIG_TQM8260,
+		CONFIG_CRAYL1,     CONFIG_MBX860T,    CONFIG_TTTech,
+		CONFIG_CU824,      CONFIG_MHPC,       CONFIG_UTX8245,
+		CONFIG_DASA_SIM,   CONFIG_MIP405,     CONFIG_W7OLMC,
+		CONFIG_DU405,      CONFIG_MOUSSE,     CONFIG_W7OLMG,
+		CONFIG_ELPPC,      CONFIG_MPC8260ADS, CONFIG_WALNUT405,
+		CONFIG_ERIC,       CONFIG_MUSENKI,    CONFIG_ZUMA,
+		CONFIG_ESTEEM192E, CONFIG_MVS1,       CONFIG_c2mon,
+		CONFIG_ETX094,     CONFIG_NX823,      CONFIG_cogent_mpc8260,
+		CONFIG_EVB64260,   CONFIG_OCRTC,      CONFIG_cogent_mpc8xx,
+		CONFIG_FADS823,    CONFIG_ORSG,       CONFIG_ep8260,
+		CONFIG_FADS850SAR, CONFIG_OXC,        CONFIG_gw8260,
+		CONFIG_FADS860T,   CONFIG_PCI405,     CONFIG_hermes,
+		CONFIG_FLAGADM,    CONFIG_PCIPPC2,    CONFIG_hymod,
+		CONFIG_FPS850L,    CONFIG_PCIPPC6,    CONFIG_lwmon,
+		CONFIG_GEN860T,    CONFIG_PIP405,     CONFIG_pcu_e,
+		CONFIG_GENIETV,    CONFIG_PM826,      CONFIG_ppmc8260,
+		CONFIG_GTH,        CONFIG_RPXClassic, CONFIG_rsdproto,
+		CONFIG_IAD210,     CONFIG_RPXlite,    CONFIG_sbc8260,
+		CONFIG_EBONY,      CONFIG_sacsng
+
+		ARM based boards:
+		-----------------
+
+		CONFIG_HHP_CRADLE,  CONFIG_DNP1110,    CONFIG_EP7312,
+		CONFIG_IMPA7,       CONFIG_LART,       CONFIG_LUBBOCK,
+		CONFIG_SHANNON,     CONFIG_SMDK2400,   CONFIG_SMDK2410,
+		CONFIG_TRAB
+
+
+- CPU Module Type: (if CONFIG_COGENT is defined)
+		Define exactly one of
+		CONFIG_CMA286_60_OLD
+--- FIXME --- not tested yet:
+		CONFIG_CMA286_60, CONFIG_CMA286_21, CONFIG_CMA286_60P,
+		CONFIG_CMA287_23, CONFIG_CMA287_50
+
+- Motherboard Type: (if CONFIG_COGENT is defined)
+		Define exactly one of
+		CONFIG_CMA101, CONFIG_CMA102
+
+- Motherboard I/O Modules: (if CONFIG_COGENT is defined)
+		Define one or more of
+		CONFIG_CMA302
+
+- Motherboard Options: (if CONFIG_CMA101 or CONFIG_CMA102 are defined)
+		Define one or more of
+		CONFIG_LCD_HEARTBEAT	- update a character position on
+					  the lcd display every second with
+					  a "rotator" |\-/|\-/
+
+- MPC824X Family Member (if CONFIG_MPC824X is defined)
+	Define exactly one of
+	CONFIG_MPC8240, CONFIG_MPC8245
+
+- 8xx CPU Options: (if using an 8xx cpu)
+		Define one or more of
+		CONFIG_8xx_GCLK_FREQ	- if get_gclk_freq() can not work e.g.
+					  no 32KHz reference PIT/RTC clock
+
+- Clock Interface:
+		CONFIG_CLOCKS_IN_MHZ
+
+		U-Boot stores all clock information in Hz
+		internally. For binary compatibility with older Linux
+		kernels (which expect the clocks passed in the
+		bd_info data to be in MHz) the environment variable
+		"clocks_in_mhz" can be defined so that U-Boot
+		converts clock data to MHZ before passing it to the
+		Linux kernel.
+
+		When CONFIG_CLOCKS_IN_MHZ is defined, a definition of
+		"clocks_in_mhz=1" is  automatically  included  in  the
+		default environment.
+
+- Console Interface:
+                Depending on board, define exactly one serial port
+                (like CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2,
+                CONFIG_8xx_CONS_SCC1, ...), or switch off the serial
+                console by defining CONFIG_8xx_CONS_NONE
+
+		Note: if CONFIG_8xx_CONS_NONE is defined, the serial
+		port routines must be defined elsewhere
+		(i.e. serial_init(), serial_getc(), ...)
+
+		CONFIG_CFB_CONSOLE
+		Enables console device for a color framebuffer. Needs following
+		defines (cf. smiLynxEM, i8042, board/eltec/bab7xx)
+			VIDEO_FB_LITTLE_ENDIAN	graphic memory organisation
+						(default big endian)
+			VIDEO_HW_RECTFILL	graphic chip supports
+						rectangle fill
+						(cf. smiLynxEM)
+			VIDEO_HW_BITBLT		graphic chip supports
+						bit-blit (cf. smiLynxEM)
+			VIDEO_VISIBLE_COLS	visible pixel columns
+						(cols=pitch)
+			VIDEO_VISIBLE_ROWS      visible pixel rows
+			VIDEO_PIXEL_SIZE        bytes per pixel
+			VIDEO_DATA_FORMAT	graphic data format
+						(0-5, cf. cfb_console.c)
+			VIDEO_FB_ADRS           framebuffer address
+			VIDEO_KBD_INIT_FCT	keyboard int fct
+						(i.e. i8042_kbd_init())
+			VIDEO_TSTC_FCT		test char fct
+						(i.e. i8042_tstc)
+			VIDEO_GETC_FCT		get char fct
+						(i.e. i8042_getc)
+			CONFIG_CONSOLE_CURSOR	cursor drawing on/off
+						(requires blink timer
+						cf. i8042.c)
+			CFG_CONSOLE_BLINK_COUNT blink interval (cf. i8042.c)
+			CONFIG_CONSOLE_TIME	display time/date info in
+						upper right corner
+						(requires CFG_CMD_DATE)
+			CONFIG_VIDEO_LOGO	display Linux logo in
+						upper left corner
+			CONFIG_CONSOLE_EXTRA_INFO
+						addional board info beside
+						the logo
+
+                When CONFIG_CFB_CONSOLE is defined, video console is
+                default i/o. Serial console can be forced with
+                environment 'console=serial'.
+
+- Console Baudrate:
+		CONFIG_BAUDRATE - in bps
+		Select one of the baudrates listed in
+		CFG_BAUDRATE_TABLE, see below.
+
+- Interrupt driven serial port input:
+		CONFIG_SERIAL_SOFTWARE_FIFO
+
+		PPC405GP only.
+		Use an interrupt handler for receiving data on the
+		serial port. It also enables using hardware handshake
+		(RTS/CTS) and UART's built-in FIFO. Set the number of
+		bytes the interrupt driven input buffer should have.
+
+		Set to 0 to disable this feature (this is the default).
+		This will also disable hardware handshake.
+
+- Boot Delay:	CONFIG_BOOTDELAY - in seconds
+		Delay before automatically booting the default image;
+		set to -1 to disable autoboot.
+
+		See doc/README.autoboot for these options that
+		work with CONFIG_BOOTDELAY. None are required.
+		CONFIG_BOOT_RETRY_TIME
+		CONFIG_BOOT_RETRY_MIN
+		CONFIG_AUTOBOOT_KEYED
+		CONFIG_AUTOBOOT_PROMPT
+		CONFIG_AUTOBOOT_DELAY_STR
+		CONFIG_AUTOBOOT_STOP_STR
+		CONFIG_AUTOBOOT_DELAY_STR2
+		CONFIG_AUTOBOOT_STOP_STR2
+		CONFIG_ZERO_BOOTDELAY_CHECK
+		CONFIG_RESET_TO_RETRY
+
+- Autoboot Command:
+		CONFIG_BOOTCOMMAND
+		Only needed when CONFIG_BOOTDELAY is enabled;
+		define a command string that is automatically executed
+		when no character is read on the console interface
+		within "Boot Delay" after reset.
+
+		CONFIG_BOOTARGS
+                This can be used to pass arguments to the bootm
+                command. The value of CONFIG_BOOTARGS goes into the
+                environment value "bootargs".
+
+		CONFIG_RAMBOOT and CONFIG_NFSBOOT
+                The value of these goes into the environment as
+                "ramboot" and "nfsboot" respectively, and can be used
+                as a convenience, when switching between booting from
+                ram and nfs.
+
+- Pre-Boot Commands:
+		CONFIG_PREBOOT
+
+		When this option is #defined, the existence of the
+		environment variable "preboot" will be checked
+		immediately before starting the CONFIG_BOOTDELAY
+		countdown and/or running the auto-boot command resp.
+		entering interactive mode.
+
+		This feature is especially useful when "preboot" is
+		automatically generated or modified. For an example
+		see the LWMON board specific code: here "preboot" is
+		modified when the user holds down a certain
+		combination of keys on the (special) keyboard when
+		booting the systems
+
+- Serial Download Echo Mode:
+		CONFIG_LOADS_ECHO
+		If defined to 1, all characters received during a
+		serial download (using the "loads" command) are
+		echoed back. This might be needed by some terminal
+		emulations (like "cu"), but may as well just take
+		time on others. This setting #define's the initial
+		value of the "loads_echo" environment variable.
+
+- Kgdb Serial Baudrate: (if CFG_CMD_KGDB is defined)
+		CONFIG_KGDB_BAUDRATE
+		Select one of the baudrates listed in
+		CFG_BAUDRATE_TABLE, see below.
+
+- Monitor Functions:
+		CONFIG_COMMANDS
+		Most monitor functions can be selected (or
+		de-selected) by adjusting the definition of
+		CONFIG_COMMANDS; to select individual functions,
+		#define CONFIG_COMMANDS by "OR"ing any of the
+		following values:
+
+		#define enables commands:
+		-------------------------
+		CFG_CMD_ASKENV	* ask for env variable
+		CFG_CMD_BDI	  bdinfo
+		CFG_CMD_BEDBUG	  Include BedBug Debugger
+		CFG_CMD_BOOTD	  bootd
+		CFG_CMD_CACHE	  icache, dcache
+		CFG_CMD_CONSOLE	  coninfo
+		CFG_CMD_DATE	* support for RTC, date/time...
+		CFG_CMD_DHCP	  DHCP support
+		CFG_CMD_ECHO	* echo arguments
+		CFG_CMD_EEPROM	* EEPROM read/write support
+		CFG_CMD_ELF	  bootelf, bootvx
+		CFG_CMD_ENV	  saveenv
+		CFG_CMD_FDC	* Floppy Disk Support
+		CFG_CMD_FLASH	  flinfo, erase, protect
+		CFG_CMD_FPGA	  FPGA device initialization support
+		CFG_CMD_I2C	* I2C serial bus support
+		CFG_CMD_IDE	* IDE harddisk support
+		CFG_CMD_IMI	  iminfo
+		CFG_CMD_IMMAP	* IMMR dump support
+		CFG_CMD_IRQ	* irqinfo
+		CFG_CMD_KGDB	* kgdb
+		CFG_CMD_LOADB	  loadb
+		CFG_CMD_LOADS	  loads
+		CFG_CMD_MEMORY	  md, mm, nm, mw, cp, cmp, crc, base,
+				  loop, mtest
+		CFG_CMD_MII	  MII utility commands
+		CFG_CMD_NET	  bootp, tftpboot, rarpboot
+		CFG_CMD_PCI	* pciinfo
+		CFG_CMD_PCMCIA	* PCMCIA support
+		CFG_CMD_REGINFO * Register dump
+		CFG_CMD_RUN	  run command in env variable
+		CFG_CMD_SCSI	* SCSI Support
+		CFG_CMD_SETGETDCR Support for DCR Register access (4xx only)
+		CFG_CMD_SPI	* SPI serial bus support
+		CFG_CMD_USB	* USB support
+		CFG_CMD_BSP	* Board SPecific functions
+		-----------------------------------------------
+		CFG_CMD_ALL	all
+
+		CFG_CMD_DFL	Default configuration; at the moment
+				this is includes all commands, except
+				the ones marked with "*" in the list
+				above.
+
+		If you don't define CONFIG_COMMANDS it defaults to
+		CFG_CMD_DFL in include/cmd_confdefs.h. A board can
+		override the default settings in the respective
+		include file.
+
+		EXAMPLE: If you want all functions except of network
+		support you can write:
+
+		#define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET)
+
+
+	Note:	Don't enable the "icache" and "dcache" commands
+                (configuration option CFG_CMD_CACHE) unless you know
+                what you (and your U-Boot users) are doing. Data
+                cache cannot be enabled on systems like the 8xx or
+                8260 (where accesses to the IMMR region must be
+                uncached), and it cannot be disabled on all other
+                systems where we (mis-) use the data cache to hold an
+                initial stack and some data.
+
+
+		XXX - this list needs to get updated!
+
+- Watchdog:
+		CONFIG_WATCHDOG
+		If this variable is defined, it enables watchdog
+		support. There must support in the platform specific
+		code for a watchdog. For the 8xx and 8260 CPUs, the
+		SIU Watchdog feature is enabled in the SYPCR
+		register.
+
+- Real-Time Clock:
+
+		When CFG_CMD_DATE is selected, the type of the RTC
+		has to be selected, too. Define exactly one of the
+		following options:
+
+		CONFIG_RTC_MPC8xx	- use internal RTC of MPC8xx
+		CONFIG_RTC_PCF8563	- use Philips PCF8563 RTC
+		CONFIG_RTC_MC146818	- use MC146818 RTC
+		CONFIG_RTC_DS1337	- use Maxim, Inc. DS1337 RTC
+
+- Timestamp Support:
+
+                When CONFIG_TIMESTAMP is selected, the timestamp
+                (date and time) of an image is printed by image
+                commands like bootm or iminfo. This option is
+                automatically enabled when you select CFG_CMD_DATE .
+
+- Partition Support:
+		CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION
+		and/or CONFIG_ISO_PARTITION
+
+		If IDE or SCSI support	is  enabled  (CFG_CMD_IDE  or
+		CFG_CMD_SCSI) you must configure support for at least
+		one partition type as well.
+
+- IDE Reset method:
+		CONFIG_IDE_RESET_ROUTINE
+
+		Set this to define that instead of a reset Pin, the
+		routine ide_set_reset(int idereset) will be used.
+
+- ATAPI Support:
+		CONFIG_ATAPI
+
+		Set this to enable ATAPI support.
+
+- SCSI Support:
+		At the moment only there is only support for the
+		SYM53C8XX SCSI controller; define
+		CONFIG_SCSI_SYM53C8XX to enable it.
+
+		CFG_SCSI_MAX_LUN [8], CFG_SCSI_MAX_SCSI_ID [7] and
+		CFG_SCSI_MAX_DEVICE [CFG_SCSI_MAX_SCSI_ID *
+		CFG_SCSI_MAX_LUN] can be adjusted to define the
+		maximum numbers of LUNs, SCSI ID's and target
+		devices.
+		CFG_SCSI_SYM53C8XX_CCF to fix clock timing (80Mhz)
+
+- NETWORK Support (PCI):
+		CONFIG_EEPRO100
+		Support for Intel 82557/82559/82559ER chips.
+		Optional CONFIG_EEPRO100_SROM_WRITE enables eeprom
+		write routine for first time initialisation.
+
+		CONFIG_TULIP
+		Support for Digital 2114x chips.
+		Optional CONFIG_TULIP_SELECT_MEDIA for board specific
+		modem chip initialisation (KS8761/QS6611).
+
+		CONFIG_NATSEMI
+		Support for National dp83815 chips.
+
+		CONFIG_NS8382X
+		Support for National dp8382[01] gigabit chips.
+
+- USB Support:
+		At the moment only the UHCI host controller is
+		supported (PIP405, MIP405); define
+		CONFIG_USB_UHCI to enable it.
+		define CONFIG_USB_KEYBOARD to enable the USB Keyboard
+		end define CONFIG_USB_STORAGE to enable the USB
+		storage devices.
+		Note:
+		Supported are USB Keyboards and USB Floppy drives
+		(TEAC FD-05PUB).
+
+- Keyboard Support:
+		CONFIG_ISA_KEYBOARD
+
+		Define this to enable standard (PC-Style) keyboard
+		support
+
+		CONFIG_I8042_KBD
+		Standard PC keyboard driver with US (is default) and
+		GERMAN key layout (switch via environment 'keymap=de') support.
+		Export function i8042_kbd_init, i8042_tstc and i8042_getc
+		for cfb_console. Supports cursor blinking.
+
+- Video support:
+		CONFIG_VIDEO
+
+		Define this to enable video support (for output to
+		video).
+
+		CONFIG_VIDEO_CT69000
+
+		Enable Chips & Technologies 69000 Video chip
+
+		CONFIG_VIDEO_SMI_LYNXEM
+		Enable Silicon Motion SMI 712/710/810 Video chip
+		Videomode are selected via environment 'videomode' with
+		standard LiLo mode numbers.
+		Following modes are supported  (* is default):
+
+                            800x600  1024x768  1280x1024
+              256  (8bit)     303*      305       307
+            65536 (16bit)     314       317       31a
+        16,7 Mill (24bit)     315       318       31b
+		(i.e. setenv videomode 317; saveenv; reset;)
+
+- LCD Support:	CONFIG_LCD
+
+		Define this to enable LCD support (for output to LCD
+		display); also select one of the supported displays
+		by defining one of these:
+
+		CONFIG_NEC_NL6648AC33:
+
+			NEC NL6648AC33-18. Active, color, single scan.
+
+		CONFIG_NEC_NL6648BC20
+
+			NEC NL6648BC20-08. 6.5", 640x480.
+			Active, color, single scan.
+
+		CONFIG_SHARP_16x9
+
+			Sharp 320x240. Active, color, single scan.
+			It isn't 16x9, and I am not sure what it is.
+
+		CONFIG_SHARP_LQ64D341
+
+			Sharp LQ64D341 display, 640x480.
+			Active, color, single scan.
+
+		CONFIG_HLD1045
+
+			HLD1045 display, 640x480.
+			Active, color, single scan.
+
+		CONFIG_OPTREX_BW
+
+			Optrex	 CBL50840-2 NF-FW 99 22 M5
+			or
+			Hitachi	 LMG6912RPFC-00T
+			or
+			Hitachi	 SP14Q002
+
+			320x240. Black & white.
+
+		Normally display is black on white background; define
+		CFG_WHITE_ON_BLACK to get it inverted.
+
+- Ethernet address:
+		CONFIG_ETHADDR
+		CONFIG_ETH2ADDR
+		CONFIG_ETH3ADDR
+
+		Define a default value for ethernet address to use
+		for the respective ethernet interface, in case this
+		is not determined automatically.
+
+- IP address:
+		CONFIG_IPADDR
+
+		Define a default value for the IP address to use for
+		the default ethernet interface, in case this is not
+		determined through e.g. bootp.
+
+- Server IP address:
+		CONFIG_SERVERIP
+
+		Defines a default value for theIP address of a TFTP
+		server to contact when using the "tftboot" command.
+
+- BOOTP Recovery Mode:
+		CONFIG_BOOTP_RANDOM_DELAY
+
+		If you have many targets in a network that try to
+		boot using BOOTP, you may want to avoid that all
+		systems send out BOOTP requests at precisely the same
+		moment (which would happen for instance at recovery
+		from a power failure, when all systems will try to
+		boot, thus flooding the BOOTP server. Defining
+		CONFIG_BOOTP_RANDOM_DELAY causes a random delay to be
+		inserted before sending out BOOTP requests. The
+		following delays are insterted then:
+
+		1st BOOTP request:	delay 0 ... 1 sec
+		2nd BOOTP request:	delay 0 ... 2 sec
+		3rd BOOTP request:	delay 0 ... 4 sec
+		4th and following
+		BOOTP requests:		delay 0 ... 8 sec
+
+- Status LED:	CONFIG_STATUS_LED
+
+		Several configurations allow to display the current
+		status using a LED. For instance, the LED will blink
+		fast while running U-Boot code, stop blinking as
+		soon as a reply to a BOOTP request was received, and
+		start blinking slow once the Linux kernel is running
+		(supported by a status LED driver in the Linux
+		kernel). Defining CONFIG_STATUS_LED enables this
+		feature in U-Boot.
+
+- CAN Support:	CONFIG_CAN_DRIVER
+
+		Defining CONFIG_CAN_DRIVER enables CAN driver support
+		on those systems that support this (optional)
+		feature, like the TQM8xxL modules.
+
+- I2C Support:	CONFIG_HARD_I2C | CONFIG_SOFT_I2C
+
+		Enables I2C serial bus commands.  If this is selected,
+		either CONFIG_HARD_I2C or CONFIG_SOFT_I2C must be defined
+		to include the appropriate I2C driver.
+
+                See also: common/cmd_i2c.c for a description of the
+                command line interface.
+
+
+		CONFIG_HARD_I2C
+
+		Selects the CPM hardware driver for I2C.
+
+		CONFIG_SOFT_I2C
+
+		Use software (aka bit-banging) driver instead of CPM
+		or similar hardware support for I2C.  This is configured
+		via the following defines.
+
+		I2C_INIT
+
+                (Optional). Any commands necessary to enable I2C
+                controller or configure ports.
+
+		I2C_PORT
+
+                (Only for MPC8260 CPU). The I/O port to use (the code
+                assumes both bits are on the same port). Valid values
+                are 0..3 for ports A..D.
+
+		I2C_ACTIVE
+
+		The code necessary to make the I2C data line active
+		(driven).  If the data line is open collector, this
+		define can be null.
+
+		I2C_TRISTATE
+
+		The code necessary to make the I2C data line tri-stated
+		(inactive).  If the data line is open collector, this
+		define can be null.
+
+		I2C_READ
+
+		Code that returns TRUE if the I2C data line is high,
+		FALSE if it is low.
+
+		I2C_SDA(bit)
+
+		If <bit> is TRUE, sets the I2C data line high. If it
+		is FALSE, it clears it (low).
+
+		I2C_SCL(bit)
+
+		If <bit> is TRUE, sets the I2C clock line high. If it
+		is FALSE, it clears it (low).
+
+		I2C_DELAY
+
+		This delay is invoked four times per clock cycle so this
+		controls the rate of data transfer.  The data rate thus
+		is 1 / (I2C_DELAY * 4).
+
+- SPI Support:	CONFIG_SPI
+
+		Enables SPI driver (so far only tested with
+		SPI EEPROM, also an instance works with Crystal A/D and
+		D/As on the SACSng board)
+
+		CONFIG_SPI_X
+
+		Enables extended (16-bit) SPI EEPROM addressing.
+		(symmetrical to CONFIG_I2C_X)
+
+		CONFIG_SOFT_SPI
+
+                Enables a software (bit-bang) SPI driver rather than
+                using hardware support. This is a general purpose
+                driver that only requires three general I/O port pins
+                (two outputs, one input) to function. If this is
+                defined, the board configuration must define several
+                SPI configuration items (port pins to use, etc). For
+                an example, see include/configs/sacsng.h.
+
+- FPGA Support: CONFIG_FPGA_COUNT
+
+                Specify the number of FPGA devices to support.
+
+                CONFIG_FPGA
+
+                Used to specify the types of FPGA devices. For
+		example,
+ 		#define CONFIG_FPGA  CFG_XILINX_VIRTEX2
+
+ 		CFG_FPGA_PROG_FEEDBACK
+
+                Enable printing of hash marks during FPGA
+		configuration.
+
+		CFG_FPGA_CHECK_BUSY
+
+                Enable checks on FPGA configuration interface busy
+                status by the configuration function. This option
+                will require a board or device specific function to
+                be written.
+
+		CONFIG_FPGA_DELAY
+
+                If defined, a function that provides delays in the
+                FPGA configuration driver.
+
+		CFG_FPGA_CHECK_CTRLC
+
+		Allow Control-C to interrupt FPGA configuration
+
+		CFG_FPGA_CHECK_ERROR
+
+                Check for configuration errors during FPGA bitfile
+                loading. For example, abort during Virtex II
+                configuration if the INIT_B line goes low (which
+                indicated a CRC error).
+
+		CFG_FPGA_WAIT_INIT
+
+                Maximum time to wait for the INIT_B line to deassert
+                after PROB_B has been deasserted during a Virtex II
+                FPGA configuration sequence. The default time is 500 mS.
+
+		CFG_FPGA_WAIT_BUSY
+
+                Maximum time to wait for BUSY to deassert during
+                Virtex II FPGA configuration. The default is 5 mS.
+
+		CFG_FPGA_WAIT_CONFIG
+
+                Time to wait after FPGA configuration. The default is
+		200 mS.
+
+- FPGA Support:	CONFIG_FPGA_COUNT
+
+ 		Specify the number of FPGA devices to support.
+
+ 		CONFIG_FPGA
+
+ 		Used to specify the types of FPGA devices.  For example,
+ 		#define CONFIG_FPGA  CFG_XILINX_VIRTEX2
+
+ 		CFG_FPGA_PROG_FEEDBACK
+
+ 		Enable printing of hash marks during FPGA configuration.
+
+		CFG_FPGA_CHECK_BUSY
+
+                Enable checks on FPGA configuration interface busy
+                status by the configuration function. This option
+                will require a board or device specific function to
+                be written.
+
+		CONFIG_FPGA_DELAY
+
+		If defined, a function that provides delays in the FPGA
+		configuration driver.
+
+		CFG_FPGA_CHECK_CTRLC
+		Allow Control-C to interrupt FPGA configuration
+
+		CFG_FPGA_CHECK_ERROR
+
+                Check for configuration errors during FPGA bitfile
+                loading. For example, abort during Virtex II
+                configuration if the INIT_B line goes low (which
+                indicated a CRC error).
+
+		CFG_FPGA_WAIT_INIT
+
+                Maximum time to wait for the INIT_B line to deassert
+                after PROB_B has been deasserted during a Virtex II
+                FPGA configuration sequence. The default time is 500
+                mS.
+
+		CFG_FPGA_WAIT_BUSY
+
+                Maximum time to wait for BUSY to deassert during
+                Virtex II FPGA configuration. The default is 5 mS.
+
+		CFG_FPGA_WAIT_CONFIG
+
+                Time to wait after FPGA configuration. The default is
+                200 mS.
+
+- Configuration Management:
+		CONFIG_IDENT_STRING
+
+                If defined, this string will be added to the U-Boot
+                version information (U_BOOT_VERSION)
+
+- Vendor Parameter Protection:
+
+                U-Boot considers the values of the environment
+                variables "serial#" (Board Serial Number) and
+                "ethaddr" (Ethernet Address) to bb parameters that
+                are set once by the board vendor / manufacturer, and
+                protects these variables from casual modification by
+                the user. Once set, these variables are read-only,
+                and write or delete attempts are rejected. You can
+                change this behviour:
+
+		If CONFIG_ENV_OVERWRITE is #defined in your config
+		file, the write protection for vendor parameters is
+		completely disabled. Anybody can change or delte
+		these parameters.
+
+		Alternatively, if you #define _both_ CONFIG_ETHADDR
+		_and_ CONFIG_OVERWRITE_ETHADDR_ONCE, a default
+		ethernet address is installed in the environment,
+		which can be changed exactly ONCE by the user. [The
+		serial# is unaffected by this, i. e. it remains
+		read-only.]
+
+- Protected RAM:
+		CONFIG_PRAM
+
+		Define this variable to enable the reservation of
+		"protected RAM", i. e. RAM which is not overwritten
+		by U-Boot. Define CONFIG_PRAM to hold the number of
+		kB you want to reserve for pRAM. You can overwrite
+		this default value by defining an environment
+		variable "pram" to the number of kB you want to
+		reserve. Note that the board info structure will
+		still show the full amount of RAM. If pRAM is
+		reserved, a new environment variable "mem" will
+		automatically be defined to hold the amount of
+		remaining RAM in a form that can be passed as boot
+		argument to Linux, for instance like that:
+
+			setenv bootargs ... mem=\$(mem)
+			saveenv
+
+		This way you can tell Linux not to use this memory,
+		either, which results in a memory region that will
+		not be affected by reboots.
+
+		*WARNING* If your board configuration uses automatic
+		detection of the RAM size, you must make sure that
+		this memory test is non-destructive. So far, the
+		following board configurations are known to be
+		"pRAM-clean":
+
+			ETX094, IVMS8, IVML24, SPD8xx, TQM8xxL,
+			HERMES, IP860, RPXlite, LWMON, LANTEC,
+			PCU_E, FLAGADM, TQM8260
+
+- Error Recovery:
+		CONFIG_PANIC_HANG
+
+		Define this variable to stop the system in case of a
+		fatal error, so that you have to reset it manually.
+		This is probably NOT a good idea for an embedded
+		system where you want to system to reboot
+		automatically as fast as possible, but it may be
+		useful during development since you can try to debug
+		the conditions that lead to the situation.
+
+		CONFIG_NET_RETRY_COUNT
+
+                This variable defines the number of retries for
+                network operations like ARP, RARP, TFTP, or BOOTP
+                before giving up the operation. If not defined, a
+                default value of 5 is used.
+
+- Command Interpreter:
+		CFG_HUSH_PARSER
+
+		Define this variable to enable the "hush" shell (from
+		Busybox) as command line interpreter, thus enabling
+		powerful command line syntax like
+		if...then...else...fi conditionals or `&&' and '||'
+		constructs ("shell scripts").
+
+		If undefined, you get the old, much simpler behaviour
+		with a somewhat smaller memory footprint.
+
+
+		CFG_PROMPT_HUSH_PS2
+
+		This defines the secondary prompt string, which is
+		printed when the command interpreter needs more input
+		to complete a command. Usually "> ".
+
+	Note:
+
+                In the current implementation, the local variables
+                space and global environment variables space are
+                separated. Local variables are those you define by
+                simply typing like `name=value'. To access a local
+                variable later on, you have write `$name' or
+                `${name}'; variable directly by typing say `$name' at
+                the command prompt.
+
+                Global environment variables are those you use
+                setenv/printenv to work with. To run a command stored
+                in such a variable, you need to use the run command,
+                and you must not use the '$' sign to access them.
+
+		To store commands and special characters in a
+		variable, please use double quotation marks
+		surrounding the whole text of the variable, instead
+		of the backslashes before semicolons and special
+		symbols.
+
+- Default Environment
+		CONFIG_EXTRA_ENV_SETTINGS
+
+                Define this to contain any number of null terminated
+                strings (variable = value pairs) that will be part of
+                the default enviroment compiled into the boot image.
+                For example, place something like this in your
+                board's config file:
+
+		#define CONFIG_EXTRA_ENV_SETTINGS \
+			"myvar1=value1\0" \
+			"myvar2=value2\0"
+
+                Warning: This method is based on knowledge about the
+                internal format how the environment is stored by the
+                U-Boot code. This is NOT an official, expoerted
+                interface! Although it is unlikely that this format
+                will change soon, there is no guarantee either.
+		You better know what you are doing here.
+
+                Note: overly (ab)use of the default environment is
+                discouraged. Make sure to check other ways to preset
+                the environment like the autoscript function or the
+                boot command first.
+
+- Show boot progress
+		CONFIG_SHOW_BOOT_PROGRESS
+
+                Defining this option allows to add some board-
+                specific code (calling a user-provided function
+                "show_boot_progress(int)") that enables you to show
+                the system's boot progress on some display (for
+                example, some LED's) on your board. At the moment,
+                the following checkpoints are implemented:
+
+  Arg	Where			When
+    1	common/cmd_bootm.c	before attempting to boot an image
+   -1	common/cmd_bootm.c	Image header has bad     magic number
+    2	common/cmd_bootm.c	Image header has correct magic number
+   -2	common/cmd_bootm.c	Image header has bad     checksum
+    3	common/cmd_bootm.c	Image header has correct checksum
+   -3	common/cmd_bootm.c	Image data   has bad     checksum
+    4	common/cmd_bootm.c	Image data   has correct checksum
+   -4	common/cmd_bootm.c	Image is for unsupported architecture
+    5	common/cmd_bootm.c	Architecture check OK
+   -5	common/cmd_bootm.c	Wrong Image Type (not kernel, multi, standalone)
+    6	common/cmd_bootm.c	Image Type check OK
+   -6	common/cmd_bootm.c	gunzip uncompression error
+   -7	common/cmd_bootm.c	Unimplemented compression type
+    7	common/cmd_bootm.c	Uncompression OK
+   -8	common/cmd_bootm.c	Wrong Image Type (not kernel, multi, standalone)
+    8	common/cmd_bootm.c	Image Type check OK
+   -9	common/cmd_bootm.c	Unsupported OS (not Linux, BSD, VxWorks, QNX)
+    9	common/cmd_bootm.c	Start initial ramdisk verification
+  -10	common/cmd_bootm.c	Ramdisk header has bad     magic number
+  -11	common/cmd_bootm.c	Ramdisk header has bad     checksum
+   10	common/cmd_bootm.c	Ramdisk header is OK
+  -12	common/cmd_bootm.c	Ramdisk data   has bad     checksum
+   11	common/cmd_bootm.c	Ramdisk data   has correct checksum
+   12	common/cmd_bootm.c	Ramdisk verification complete, start loading
+  -13	common/cmd_bootm.c	Wrong Image Type (not PPC Linux Ramdisk)
+   13	common/cmd_bootm.c	Start multifile image verification
+   14	common/cmd_bootm.c	No initial ramdisk, no multifile, continue.
+   15	common/cmd_bootm.c	All preparation done, transferring control to OS
+
+   -1	common/cmd_doc.c	Bad usage of "doc" command
+   -1	common/cmd_doc.c	No boot device
+   -1	common/cmd_doc.c	Unknown Chip ID on boot device
+   -1	common/cmd_doc.c	Read Error on boot device
+   -1	common/cmd_doc.c	Image header has bad magic number
+
+   -1	common/cmd_ide.c	Bad usage of "ide" command
+   -1	common/cmd_ide.c	No boot device
+   -1	common/cmd_ide.c	Unknown boot device
+   -1	common/cmd_ide.c	Unknown partition table
+   -1	common/cmd_ide.c	Invalid partition type
+   -1	common/cmd_ide.c	Read Error on boot device
+   -1	common/cmd_ide.c	Image header has bad magic number
+
+   -1	common/cmd_nvedit.c	Environment not changable, but has bad CRC
+
+
+Modem Support:
+--------------
+
+[so far only for SMDK2400 board]
+
+- Modem support endable:
+		CONFIG_MODEM_SUPPORT
+
+- RTS/CTS Flow control enable:
+		CONFIG_HWFLOW
+
+- Modem debug support:
+		CONFIG_MODEM_SUPPORT_DEBUG
+
+                Enables debugging stuff (char screen[1024], dbg())
+                for modem support. Useful only with BDI2000.
+
+- General:
+
+                In the target system modem support is enabled when a
+                specific key (key combination) is pressed during
+                power-on. Otherwise U-Boot will boot normally
+                (autoboot). The key_pressed() fuction is called from
+                board_init(). Currently key_pressed() is a dummy
+                function, returning 1 and thus enabling modem
+                initialization.
+
+                If there are no modem init strings in the
+                environment, U-Boot proceed to autoboot; the
+                previous output (banner, info printfs) will be
+                supressed, though.
+
+		See also: doc/README.Modem
+
+
+
+
+Configuration Settings:
+-----------------------
+
+- CFG_LONGHELP: Defined when you want long help messages included;
+		undefine this when you're short of memory.
+
+- CFG_PROMPT:	This is what U-Boot prints on the console to
+		prompt for user input.
+
+- CFG_CBSIZE:	Buffer size for input from the Console
+
+- CFG_PBSIZE:	Buffer size for Console output
+
+- CFG_MAXARGS:	max. Number of arguments accepted for monitor commands
+
+- CFG_BARGSIZE: Buffer size for Boot Arguments which are passed to
+		the application (usually a Linux kernel) when it is
+		booted
+
+- CFG_BAUDRATE_TABLE:
+		List of legal baudrate settings for this board.
+
+- CFG_CONSOLE_INFO_QUIET
+ 		Suppress display of console information at boot.
+
+- CFG_CONSOLE_IS_IN_ENV
+ 		If the board specific function
+ 			extern int overwrite_console (void);
+ 		returns 1, the stdin, stderr and stdout are switched to the
+		serial port, else the settings in the environment are used.
+
+- CFG_CONSOLE_OVERWRITE_ROUTINE
+ 		Enable the call to overwrite_console().
+
+- CFG_CONSOLE_ENV_OVERWRITE
+		Enable overwrite of previous console environment settings.
+
+- CFG_MEMTEST_START, CFG_MEMTEST_END:
+		Begin and End addresses of the area used by the
+		simple memory test.
+
+- CFG_ALT_MEMTEST:
+ 		Enable an alternate, more extensive memory test.
+
+- CFG_TFTP_LOADADDR:
+		Default load address for network file downloads
+
+- CFG_LOADS_BAUD_CHANGE:
+		Enable temporary baudrate change while serial download
+
+- CFG_SDRAM_BASE:
+		Physical start address of SDRAM. _Must_ be 0 here.
+
+- CFG_MBIO_BASE:
+		Physical start address of Motherboard I/O (if using a
+		Cogent motherboard)
+
+- CFG_FLASH_BASE:
+		Physical start address of Flash memory.
+
+- CFG_MONITOR_BASE:
+		Physical start address of boot monitor code (set by
+		make config files to be same as the text base address
+		(TEXT_BASE) used when linking) - same as
+		CFG_FLASH_BASE when booting from flash.
+
+- CFG_MONITOR_LEN:
+		Size of memory reserved for monitor code
+
+- CFG_MALLOC_LEN:
+		Size of DRAM reserved for malloc() use.
+
+- CFG_BOOTMAPSZ:
+		Maximum size of memory mapped by the startup code of
+		the Linux kernel; all data that must be processed by
+		the Linux kernel (bd_info, boot arguments, eventually
+		initrd image) must be put below this limit.
+
+- CFG_MAX_FLASH_BANKS:
+		Max number of Flash memory banks
+
+- CFG_MAX_FLASH_SECT:
+		Max number of sectors on a Flash chip
+
+- CFG_FLASH_ERASE_TOUT:
+		Timeout for Flash erase operations (in ms)
+
+- CFG_FLASH_WRITE_TOUT:
+		Timeout for Flash write operations (in ms)
+
+- CFG_DIRECT_FLASH_TFTP:
+
+		Enable TFTP transfers directly to flash memory;
+		without this option such a download has to be
+		performed in two steps: (1) download to RAM, and (2)
+		copy from RAM to flash.
+
+		The two-step approach is usually more reliable, since
+		you can check if the download worked before you erase
+		the flash, but in some situations (when sytem RAM is
+		too limited to allow for a tempory copy of the
+		downloaded image) this option may be very useful.
+
+- CFG_FLASH_CFI:
+                Define if the flash driver uses extra elements in the
+                common flash structure for storing flash geometry
+
+The following definitions that deal with the placement and management
+of environment data (variable area); in general, we support the
+following configurations:
+
+- CFG_ENV_IS_IN_FLASH:
+
+	Define this if the environment is in flash memory.
+
+	a) The environment occupies one whole flash sector, which is
+	   "embedded" in the text segment with the U-Boot code. This
+	   happens usually with "bottom boot sector" or "top boot
+	   sector" type flash chips, which have several smaller
+	   sectors at the start or the end. For instance, such a
+	   layout can have sector sizes of 8, 2x4, 16, Nx32 kB. In
+	   such a case you would place the environment in one of the
+	   4 kB sectors - with U-Boot code before and after it. With
+	   "top boot sector" type flash chips, you would put the
+	   environment in one of the last sectors, leaving a gap
+	   between U-Boot and the environment.
+
+	- CFG_ENV_OFFSET:
+
+	   Offset of environment data (variable area) to the
+	   beginning of flash memory; for instance, with bottom boot
+	   type flash chips the second sector can be used: the offset
+	   for this sector is given here.
+
+	   CFG_ENV_OFFSET is used relative to CFG_FLASH_BASE.
+
+	- CFG_ENV_ADDR:
+
+	   This is just another way to specify the start address of
+	   the flash sector containing the environment (instead of
+	   CFG_ENV_OFFSET).
+
+	- CFG_ENV_SECT_SIZE:
+
+	   Size of the sector containing the environment.
+
+
+	b) Sometimes flash chips have few, equal sized, BIG sectors.
+	   In such a case you don't want to spend a whole sector for
+	   the environment.
+
+	- CFG_ENV_SIZE:
+
+	   If you use this in combination with CFG_ENV_IS_IN_FLASH
+	   and CFG_ENV_SECT_SIZE, you can specify to use only a part
+	   of this flash sector for the environment. This saves
+	   memory for the RAM copy of the environment.
+
+	   It may also save flash memory if you decide to use this
+	   when your environment is "embedded" within U-Boot code,
+	   since then the remainder of the flash sector could be used
+	   for U-Boot code. It should be pointed out that this is
+	   STRONGLY DISCOURAGED from a robustness point of view:
+	   updating the environment in flash makes it always
+	   necessary to erase the WHOLE sector. If something goes
+	   wrong before the contents has been restored from a copy in
+	   RAM, your target system will be dead.
+
+	- CFG_ENV_ADDR_REDUND
+	  CFG_ENV_SIZE_REDUND
+
+           These settings describe a second storage area used to hold
+           a redundand copy of the environment data, so that there is
+           a valid backup copy in case there is a power failur during
+           a "saveenv" operation.
+
+BE CAREFUL! Any changes to the flash layout, and some changes to the
+source code will make it necessary to adapt <board>/u-boot.lds*
+accordingly!
+
+
+- CFG_ENV_IS_IN_NVRAM:
+
+	Define this if you have some non-volatile memory device
+	(NVRAM, battery buffered SRAM) which you want to use for the
+	environment.
+
+	- CFG_ENV_ADDR:
+	- CFG_ENV_SIZE:
+
+	  These two #defines are used to determin the memory area you
+	  want to use for environment. It is assumed that this memory
+	  can just be read and written to, without any special
+	  provision.
+
+BE CAREFUL! The first access to the environment happens quite early
+in U-Boot initalization (when we try to get the setting of for the
+console baudrate). You *MUST* have mappend your NVRAM area then, or
+U-Boot will hang.
+
+Please note that even with NVRAM we still use a copy of the
+environment in RAM: we could work on NVRAM directly, but we want to
+keep settings there always unmodified except somebody uses "saveenv"
+to save the current settings.
+
+
+- CFG_ENV_IS_IN_EEPROM:
+
+	Use this if you have an EEPROM or similar serial access
+	device and a driver for it.
+
+	- CFG_ENV_OFFSET:
+	- CFG_ENV_SIZE:
+
+	  These two #defines specify the offset and size of the
+	  environment area within the total memory of your EEPROM.
+
+	- CFG_I2C_EEPROM_ADDR:
+	  If defined, specified the chip address of the EEPROM device.
+	  The default address is zero.
+
+	- CFG_EEPROM_PAGE_WRITE_BITS:
+	  If defined, the number of bits used to address bytes in a
+	  single page in the EEPROM device.  A 64 byte page, for example
+	  would require six bits.
+
+	- CFG_EEPROM_PAGE_WRITE_DELAY_MS:
+	  If defined, the number of milliseconds to delay between
+	  page writes.  The default is zero milliseconds.
+
+	- CFG_I2C_EEPROM_ADDR_LEN:
+	  The length in bytes of the EEPROM memory array address.  Note
+	  that this is NOT the chip address length!
+
+	- CFG_EEPROM_SIZE:
+	  The size in bytes of the EEPROM device.
+
+	- CFG_I2C_EEPROM_ADDR:
+	  If defined, specified the chip address of the EEPROM device.
+	  The default address is zero.
+
+	- CFG_EEPROM_PAGE_WRITE_BITS:
+	  If defined, the number of bits used to address bytes in a
+	  single page in the EEPROM device.  A 64 byte page, for example
+	  would require six bits.
+
+	- CFG_EEPROM_PAGE_WRITE_DELAY_MS:
+	  If defined, the number of milliseconds to delay between
+	  page writes.  The default is zero milliseconds.
+
+	- CFG_I2C_EEPROM_ADDR_LEN:
+	  The length in bytes of the EEPROM memory array address.  Note
+	  that this is NOT the chip address length!
+
+	- CFG_EEPROM_SIZE:
+	  The size in bytes of the EEPROM device.
+
+- CFG_SPI_INIT_OFFSET
+
+	Defines offset to the initial SPI buffer area in DPRAM. The
+	area is used at an early stage (ROM part) if the environment
+	is configured to reside in the SPI EEPROM: We need a 520 byte
+	scratch DPRAM area. It is used between the two initialization
+	calls (spi_init_f() and spi_init_r()). A value of 0xB00 seems
+	to be a good choice since it makes it far enough from the
+	start of the data area as well as from the stack pointer.
+
+Please note that the environment is read-only as long as the monitor
+has been relocated to RAM and a RAM copy of the environment has been
+created; also, when using EEPROM you will have to use getenv_r()
+until then to read environment variables.
+
+The environment is now protected by a CRC32 checksum. Before the
+monitor is relocated into RAM, as a result of a bad CRC you will be
+working with the compiled-in default environment - *silently*!!!
+[This is necessary, because the first environment variable we need is
+the "baudrate" setting for the console - if we have a bad CRC, we
+don't have any device yet where we could complain.]
+
+Note: once the monitor has been relocated, then it will complain if
+the default environment is used; a new CRC is computed as soon as you
+use the "setenv" command to modify / delete / add any environment
+variable [even when you try to delete a non-existing variable!].
+
+Note2: you must edit your u-boot.lds file to reflect this
+configuration.
+
+
+Many of the options are named exactly as the corresponding Linux
+kernel configuration options. The intention is to make it easier to
+build a config tool - later.
+
+Low Level (hardware related) configuration options:
+
+- CFG_CACHELINE_SIZE:
+		Cache Line Size of the CPU.
+
+- CFG_DEFAULT_IMMR:
+		Default address of the IMMR after system reset.
+		Needed on some 8260 systems (MPC8260ADS and RPXsuper)
+		to be able to adjust the position of the IMMR
+		register after a reset.
+
+- CFG_IMMR:	Physical address of the Internal Memory Mapped
+		Register; DO NOT CHANGE! (11-4)
+		[MPC8xx systems only]
+
+- CFG_INIT_RAM_ADDR:
+
+		Start address of memory area tha can be used for
+		initial data and stack; please note that this must be
+		writable memory that is working WITHOUT special
+		initialization, i. e. you CANNOT use normal RAM which
+		will become available only after programming the
+		memory controller and running certain initialization
+		sequences.
+
+		U-Boot uses the following memory types:
+		- MPC8xx and MPC8260: IMMR (internal memory of the CPU)
+		- MPC824X: data cache
+		- PPC4xx:  data cache
+
+- CFG_INIT_DATA_OFFSET:
+
+		Offset of the initial data structure in the memory
+		area defined by CFG_INIT_RAM_ADDR. Usually
+		CFG_INIT_DATA_OFFSET is chosen such that the initial
+		data is located at the end of the available space
+		(sometimes written as (CFG_INIT_RAM_END -
+		CFG_INIT_DATA_SIZE), and the initial stack is just
+		below that area (growing from (CFG_INIT_RAM_ADDR +
+		CFG_INIT_DATA_OFFSET) downward.
+
+	Note:
+		On the MPC824X (or other systems that use the data
+		cache for initial memory) the address chosen for
+		CFG_INIT_RAM_ADDR is basically arbitrary - it must
+		point to an otherwise UNUSED address space between
+		the top of RAM and the start of the PCI space.
+
+- CFG_SIUMCR:	SIU Module Configuration (11-6)
+
+- CFG_SYPCR:	System Protection Control (11-9)
+
+- CFG_TBSCR:	Time Base Status and Control (11-26)
+
+- CFG_PISCR:	Periodic Interrupt Status and Control (11-31)
+
+- CFG_PLPRCR:	PLL, Low-Power, and Reset Control Register (15-30)
+
+- CFG_SCCR:	System Clock and reset Control Register (15-27)
+
+- CFG_OR_TIMING_SDRAM:
+		SDRAM timing
+
+- CFG_MAMR_PTA:
+		periodic timer for refresh
+
+- CFG_DER:	Debug Event Register (37-47)
+
+- FLASH_BASE0_PRELIM, FLASH_BASE1_PRELIM, CFG_REMAP_OR_AM,
+  CFG_PRELIM_OR_AM, CFG_OR_TIMING_FLASH, CFG_OR0_REMAP,
+  CFG_OR0_PRELIM, CFG_BR0_PRELIM, CFG_OR1_REMAP, CFG_OR1_PRELIM,
+  CFG_BR1_PRELIM:
+		Memory Controller Definitions: BR0/1 and OR0/1 (FLASH)
+
+- SDRAM_BASE2_PRELIM, SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE,
+  CFG_OR_TIMING_SDRAM, CFG_OR2_PRELIM, CFG_BR2_PRELIM,
+  CFG_OR3_PRELIM, CFG_BR3_PRELIM:
+		Memory Controller Definitions: BR2/3 and OR2/3 (SDRAM)
+
+- CFG_MAMR_PTA, CFG_MPTPR_2BK_4K, CFG_MPTPR_1BK_4K, CFG_MPTPR_2BK_8K,
+  CFG_MPTPR_1BK_8K, CFG_MAMR_8COL, CFG_MAMR_9COL:
+		Machine Mode Register and Memory Periodic Timer
+		Prescaler definitions (SDRAM timing)
+
+- CFG_I2C_UCODE_PATCH, CFG_I2C_DPMEM_OFFSET [0x1FC0]:
+		enable I2C microcode relocation patch (MPC8xx);
+		define relocation offset in DPRAM [DSP2]
+
+- CFG_SPI_UCODE_PATCH, CFG_SPI_DPMEM_OFFSET [0x1FC0]:
+		enable SPI microcode relocation patch (MPC8xx);
+		define relocation offset in DPRAM [SCC4]
+
+- CFG_USE_OSCCLK:
+		Use OSCM clock mode on MBX8xx board. Be careful,
+		wrong setting might damage your board. Read
+		doc/README.MBX before setting this variable!
+
+Building the Software:
+======================
+
+Building U-Boot has been tested in native PPC environments (on a
+PowerBook G3 running LinuxPPC 2000) and in cross environments
+(running RedHat 6.x and 7.x Linux on x86, Solaris 2.6 on a SPARC, and
+NetBSD 1.5 on x86).
+
+If you are not using a native PPC environment, it is assumed that you
+have the GNU cross compiling tools available in your path and named
+with a prefix of "powerpc-linux-". If this is not the case, (e.g. if
+you are using Monta Vista's Hard Hat Linux CDK 1.2) you must change
+the definition of CROSS_COMPILE in Makefile. For HHL on a 4xx CPU,
+change it to:
+
+	CROSS_COMPILE = ppc_4xx-
+
+
+U-Boot is intended to be  simple  to  build.  After  installing  the
+sources	 you must configure U-Boot for one specific board type. This
+is done by typing:
+
+	make NAME_config
+
+where "NAME_config" is the name of one of the existing
+configurations; the following names are supported:
+
+    ADCIOP_config	  GTH_config		TQM850L_config
+    ADS860_config	  IP860_config		TQM855L_config
+    AR405_config	  IVML24_config		TQM860L_config
+    CANBT_config	  IVMS8_config		WALNUT405_config
+    CPCI405_config	  LANTEC_config		cogent_common_config
+    CPCIISER4_config	  MBX_config		cogent_mpc8260_config
+    CU824_config	  MBX860T_config	cogent_mpc8xx_config
+    ESTEEM192E_config	  RPXlite_config	hermes_config
+    ETX094_config	  RPXsuper_config	hymod_config
+    FADS823_config	  SM850_config		lwmon_config
+    FADS850SAR_config	  SPD823TS_config	pcu_e_config
+    FADS860T_config	  SXNI855T_config	rsdproto_config
+    FPS850L_config	  Sandpoint8240_config	sbc8260_config
+    GENIETV_config	  TQM823L_config	PIP405_config
+    GEN860T_config	  EBONY_config
+
+Note: for some board special configuration names may exist; check  if
+      additional  information is available from the board vendor; for
+      instance, the TQM8xxL systems run normally at 50 MHz and use  a
+      SCC  for	10baseT	 ethernet; there are also systems with 80 MHz
+      CPU clock, and an optional Fast Ethernet	module	is  available
+      for  CPU's  with FEC. You can select such additional "features"
+      when chosing the configuration, i. e.
+
+      make TQM860L_config
+	- will configure for a plain TQM860L, i. e. 50MHz, no FEC
+
+      make TQM860L_FEC_config
+	- will configure for a TQM860L at 50MHz with FEC for ethernet
+
+      make TQM860L_80MHz_config
+	- will configure for a TQM860L at 80 MHz, with normal 10baseT
+	  interface
+
+      make TQM860L_FEC_80MHz_config
+	- will configure for a TQM860L at 80 MHz with FEC for ethernet
+
+      make TQM823L_LCD_config
+	- will configure for a TQM823L with U-Boot console on LCD
+
+      make TQM823L_LCD_80MHz_config
+	- will configure for a TQM823L at 80 MHz with U-Boot console on LCD
+
+      etc.
+
+
+
+Finally, type "make all", and you should  get  some  working  U-Boot
+images ready for downlod to / installation on your system:
+
+- "u-boot.bin" is a raw binary image
+- "u-boot" is an image in ELF binary format
+- "u-boot.srec" is in Motorola S-Record format
+
+
+Please be aware that the Makefiles assume you are using GNU make, so
+for instance on NetBSD you might need to use "gmake" instead of
+native "make".
+
+
+If the system board that you have is not listed, then you will need
+to port U-Boot to your hardware platform. To do this, follow these
+steps:
+
+1.  Add a new configuration option for your board to the toplevel
+    "Makefile", using the existing entries as examples.
+2.  Create a new directory to hold your board specific code. Add any
+    files you need.
+3.  If you're porting U-Boot to a new CPU, then also create a new
+    directory to hold your CPU specific code. Add any files you need.
+4.  Run "make config_name" with your new name.
+5.  Type "make", and you should get a working "u-boot.srec" file
+    to be installed on your target system.
+    [Of course, this last step is much harder than it sounds.]
+
+
+Testing of U-Boot Modifications, Ports to New Hardware, etc.:
+==============================================================
+
+If you have modified U-Boot sources (for instance added a new	board
+or  support  for  new  devices,	 a new CPU, etc.) you are expected to
+provide feedback to the other developers. The feedback normally takes
+the form of a "patch", i. e. a context diff against a certain (latest
+official or latest in CVS) version of U-Boot sources.
+
+But before you submit such a patch, please verify that	your  modifi-
+cation	did not break existing code. At least make sure that *ALL* of
+the supported boards compile WITHOUT ANY compiler warnings. To do so,
+just run the "MAKEALL" script, which will configure and build U-Boot
+for ALL supported system. Be warned, this will take a while. You  can
+select	which  (cross)	compiler  to use py passing a `CROSS_COMPILE'
+environment variable to the script, i. e. to use the cross tools from
+MontaVista's Hard Hat Linux you can type
+
+	CROSS_COMPILE=ppc_8xx- MAKEALL
+
+or to build on a native PowerPC system you can type
+
+	CROSS_COMPILE=' ' MAKEALL
+
+See also "U-Boot Porting Guide" below.
+
+
+
+Monitor Commands - Overview:
+============================
+
+go	- start application at address 'addr'
+run	- run commands in an environment variable
+bootm	- boot application image from memory
+bootp	- boot image via network using BootP/TFTP protocol
+tftpboot- boot image via network using TFTP protocol
+	       and env variables "ipaddr" and "serverip"
+	       (and eventually "gatewayip")
+rarpboot- boot image via network using RARP/TFTP protocol
+diskboot- boot from IDE devicebootd   - boot default, i.e., run 'bootcmd'
+loads	- load S-Record file over serial line
+loadb	- load binary file over serial line (kermit mode)
+md	- memory display
+mm	- memory modify (auto-incrementing)
+nm	- memory modify (constant address)
+mw	- memory write (fill)
+cp	- memory copy
+cmp	- memory compare
+crc32	- checksum calculation
+imd     - i2c memory display
+imm     - i2c memory modify (auto-incrementing)
+inm     - i2c memory modify (constant address)
+imw     - i2c memory write (fill)
+icrc32  - i2c checksum calculation
+iprobe  - probe to discover valid I2C chip addresses
+iloop   - infinite loop on address range
+isdram  - print SDRAM configuration information
+sspi    - SPI utility commands
+base	- print or set address offset
+printenv- print environment variables
+setenv	- set environment variables
+saveenv - save environment variables to persistent storage
+protect - enable or disable FLASH write protection
+erase	- erase FLASH memory
+flinfo	- print FLASH memory information
+bdinfo	- print Board Info structure
+iminfo	- print header information for application image
+coninfo - print console devices and informations
+ide	- IDE sub-system
+loop	- infinite loop on address range
+mtest	- simple RAM test
+icache	- enable or disable instruction cache
+dcache	- enable or disable data cache
+reset	- Perform RESET of the CPU
+echo	- echo args to console
+version - print monitor version
+help	- print online help
+?	- alias for 'help'
+
+
+Monitor Commands - Detailed Description:
+========================================
+
+TODO.
+
+For now: just type "help <command>".
+
+
+Environment Variables:
+======================
+
+U-Boot supports user configuration using Environment Variables which
+can be made persistent by saving to Flash memory.
+
+Environment Variables are set using "setenv", printed using
+"printenv", and saved to Flash using "saveenv". Using "setenv"
+without a value can be used to delete a variable from the
+environment. As long as you don't save the environment you are
+working with an in-memory copy. In case the Flash area containing the
+environment is erased by accident, a default environment is provided.
+
+Some configuration options can be set using Environment Variables:
+
+  baudrate	- see CONFIG_BAUDRATE
+
+  bootdelay	- see CONFIG_BOOTDELAY
+
+  bootcmd	- see CONFIG_BOOTCOMMAND
+
+  bootargs	- Boot arguments when booting an RTOS image
+
+  bootfile	- Name of the image to load with TFTP
+
+  autoload	- if set to "no" (any string beginning with 'n'),
+		  "bootp" will just load perform a lookup of the
+		  configuration from the BOOTP server, but not try to
+		  load any image using TFTP
+
+  autostart	- if set to "yes", an image loaded using the "bootp",
+		  "rarpboot", "tftpboot" or "diskboot" commands will
+		  be automatically started (by internally calling
+		  "bootm")
+
+  initrd_high	- restrict positioning of initrd images:
+		  If this variable is not set, initrd images will be
+		  copied to the highest possible address in RAM; this
+		  is usually what you want since it allows for
+		  maximum initrd size. If for some reason you want to
+		  make sure that the initrd image is loaded below the
+		  CFG_BOOTMAPSZ limit, you can set this environment
+		  variable to a value of "no" or "off" or "0".
+		  Alternatively, you can set it to a maximum upper
+		  address to use (U-Boot will still check that it
+		  does not overwrite the U-Boot stack and data).
+
+		  For instance, when you have a system with 16 MB
+		  RAM, and want to reseve 4 MB from use by Linux,
+		  you can do this by adding "mem=12M" to the value of
+		  the "bootargs" variable. However, now you must make
+		  sure, that the initrd image is placed in the first
+		  12 MB as well - this can be done with
+
+		  setenv initrd_high 00c00000
+
+  ipaddr	- IP address; needed for tftpboot command
+
+  loadaddr	- Default load address for commands like "bootp",
+		  "rarpboot", "tftpboot" or "diskboot"
+
+  loads_echo	- see CONFIG_LOADS_ECHO
+
+  serverip	- TFTP server IP address; needed for tftpboot command
+
+  bootretry	- see CONFIG_BOOT_RETRY_TIME
+
+  bootdelaykey	- see CONFIG_AUTOBOOT_DELAY_STR
+
+  bootstopkey	- see CONFIG_AUTOBOOT_STOP_STR
+
+
+The following environment variables may be used and automatically
+updated by the network boot commands ("bootp" and "rarpboot"),
+depending the information provided by your boot server:
+
+  bootfile	- see above
+  dnsip		- IP address of your Domain Name Server
+  gatewayip	- IP address of the Gateway (Router) to use
+  hostname	- Target hostname
+  ipaddr	- see above
+  netmask	- Subnet Mask
+  rootpath	- Pathname of the root filesystem on the NFS server
+  serverip	- see above
+
+
+There are two special Environment Variables:
+
+  serial#	- contains hardware identification information such
+		  as type string and/or serial number
+  ethaddr	- Ethernet address
+
+These variables can be set only once (usually during manufacturing of
+the board). U-Boot refuses to delete or overwrite these variables
+once they have been set once.
+
+
+Please note that changes to some configuration parameters may take
+only effect after the next boot (yes, that's just like Windoze :-).
+
+
+Note for Redundant Ethernet Interfaces:
+=======================================
+
+Some boards come with redundand ethernet interfaces; U-Boot supports
+such configurations and is capable of automatic selection of a
+"working" interface when needed. MAC assignemnt works as follows:
+
+Network interfaces are numbered eth0, eth1, eth2, ... Corresponding
+MAC addresses can be stored in the environment as "ethaddr" (=>eth0),
+"eth1addr" (=>eth1), "eth2addr", ...
+
+If the network interface stores some valid MAC address (for instance
+in SROM), this is used as default address if there is NO correspon-
+ding setting in the environment; if the corresponding environment
+variable is set, this overrides the settings in the card; that means:
+
+o If the SROM has a valid MAC address, and there is no address in the
+  environment, the SROM's address is used.
+
+o If there is no valid address in the SROM, and a definition in the
+  environment exists, then the value from the environment variable is
+  used.
+
+o If both the SROM and the environment contain a MAC address, and
+  both addresses are the same, this MAC address is used.
+
+o If both the SROM and the environment contain a MAC address, and the
+  addresses differ, the value from the environment is used and a
+  warning is printed.
+
+o If neither SROM nor the environment contain a MAC address, an error
+  is raised.
+
+
+
+Image Formats:
+==============
+
+The "boot" commands of this monitor operate on "image" files which
+can be basicly anything, preceeded by a special header; see the
+definitions in include/image.h for details; basicly, the header
+defines the following image properties:
+
+* Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD,
+  4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,
+  LynxOS, pSOS, QNX;
+  Currently supported: Linux, NetBSD, VxWorks, QNX).
+* Target CPU Architecture (Provisions for Alpha, ARM, Intel x86,
+  IA64, MIPS, MIPS, PowerPC, IBM S390, SuperH, Sparc, Sparc 64 Bit;
+  Currently supported: PowerPC).
+* Compression Type (Provisions for uncompressed, gzip, bzip2;
+  Currently supported: uncompressed, gzip).
+* Load Address
+* Entry Point
+* Image Name
+* Image Timestamp
+
+The header is marked by a special Magic Number, and both the header
+and the data portions of the image are secured against corruption by
+CRC32 checksums.
+
+
+Linux Support:
+==============
+
+Although U-Boot should support any OS or standalone application
+easily, Linux has always been in the focus during the design of
+U-Boot.
+
+U-Boot includes many features that so far have been part of some
+special "boot loader" code within the Linux kernel. Also, any
+"initrd" images to be used are no longer part of one big Linux image;
+instead, kernel and "initrd" are separate images. This implementation
+serves serveral purposes:
+
+- the same features can be used for other OS or standalone
+  applications (for instance: using compressed images to reduce the
+  Flash memory footprint)
+
+- it becomes much easier to port new Linux kernel versions because
+  lots of low-level, hardware dependend stuff are done by U-Boot
+
+- the same Linux kernel image can now be used with different "initrd"
+  images; of course this also means that different kernel images can
+  be run with the same "initrd". This makes testing easier (you don't
+  have to build a new "zImage.initrd" Linux image when you just
+  change a file in your "initrd"). Also, a field-upgrade of the
+  software is easier now.
+
+
+Linux HOWTO:
+============
+
+Porting Linux to U-Boot based systems:
+---------------------------------------
+
+U-Boot cannot save you from doing all the necessary modifications to
+configure the Linux device drivers for use with your target hardware
+(no, we don't intend to provide a full virtual machine interface to
+Linux :-).
+
+But now you can ignore ALL boot loader code (in arch/ppc/mbxboot).
+
+Just make sure your machine specific header file (for instance
+include/asm-ppc/tqm8xx.h) includes the same definition of the Board
+Information structure as we define in include/u-boot.h, and make
+sure that your definition of IMAP_ADDR uses the same value as your
+U-Boot configuration in CFG_IMMR.
+
+
+Configuring the Linux kernel:
+-----------------------------
+
+No specific requirements for U-Boot. Make sure you have some root
+device (initial ramdisk, NFS) for your target system.
+
+
+Building a Linux Image:
+-----------------------
+
+No specific requirements for U-Boot. There is no need to add a
+"ramdisk.image.gz" file when building the kernel, even when you
+intend to run it with initial ramdisk.
+
+Example:
+
+	make TQM850L_config
+	make oldconfig
+	make dep
+	make zImage
+
+However, we don't use the 'zImage' (= 'arch/ppc/mbxboot/zvmlinux') we
+build this way. The 'zImage' includes the old boot loader code which
+we don't ned any more. Instead, we use the raw (compressed) Linux
+kernel image in 'arch/ppc/coffboot/vmlinux.gz'.
+
+There is a special tool (in 'tools/mkimage') to encapsulate this
+image with header information, CRC32 checksum etc. for use with
+U-Boot:
+
+In the first form (with "-l" option) mkimage  lists  the  information
+contained  in  the header of an existing U-Boot image; this includes
+checksum verification:
+
+	tools/mkimage -l image
+	  -l ==> list image header information
+
+The second form (with "-d" option) is used to build a U-Boot image
+from a "data file" which is used as image payload:
+
+	tools/mkimage -A arch -O os -T type -C comp -a addr -e ep \
+		      -n name -d data_file image
+	  -A ==> set architecture to 'arch'
+	  -O ==> set operating system to 'os'
+	  -T ==> set image type to 'type'
+	  -C ==> set compression type 'comp'
+	  -a ==> set load address to 'addr' (hex)
+	  -e ==> set entry point to 'ep' (hex)
+	  -n ==> set image name to 'name'
+	  -d ==> use image data from 'datafile'
+
+Right now, all Linux kernels use the same load address	(0x00000000),
+but the entry point address depends on the kernel version:
+
+- 2.2.x kernels have the entry point at 0x0000000C,
+- 2.3.x and 2.4.x kernels have the entry point at 0x00000000.
+
+So a typical call to build a U-Boot image would read:
+
+	-> tools/mkimage -n '2.2.13 for initrd on TQM850L' \
+	> -A ppc -O linux -T kernel -C gzip -a 00000000 -e 0000000C \
+	> -d /opt/mpc8xx/src/linux-2.2.13/arch/ppc/coffboot/vmlinux.gz \
+	> examples/image-2.2.13-initrd
+	Image Name:   2.2.13 for initrd on TQM850L
+	Created:      Wed Jul 19 02:34:59 2000
+	Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+	Data Size:    335725 Bytes = 327.86 kB = 0.32 MB
+	Load Address: 0x00000000
+	Entry Point:  0x0000000c
+
+To verify the contents of the image (or check for corruption):
+
+	-> tools/mkimage -l examples/image-2.2.13-initrd
+	Image Name:   2.2.13 for initrd on TQM850L
+	Created:      Wed Jul 19 02:34:59 2000
+	Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+	Data Size:    335725 Bytes = 327.86 kB = 0.32 MB
+	Load Address: 0x00000000
+	Entry Point:  0x0000000c
+
+NOTE: for embedded systems where boot time is critical you can trade
+speed for memory and install an UNCOMPRESSED image instead: this
+needs more space in Flash, but boots much faster since it does not
+need to be uncompressed:
+
+	-> gunzip /opt/mpc8xx/src/linux-2.2.13/arch/ppc/coffboot/vmlinux.gz
+	-> tools/mkimage -n '2.2.13 for initrd on TQM850L' \
+	> -A ppc -O linux -T kernel -C none -a 00000000 -e 0000000C \
+	> -d /opt/mpc8xx/src/linux-2.2.13/arch/ppc/coffboot/vmlinux \
+	> examples/image-2.2.13-initrd-uncompressed
+	Image Name:   2.2.13 for initrd on TQM850L
+	Created:      Wed Jul 19 02:34:59 2000
+	Image Type:   PowerPC Linux Kernel Image (uncompressed)
+	Data Size:    792160 Bytes = 773.59 kB = 0.76 MB
+	Load Address: 0x00000000
+	Entry Point:  0x0000000c
+
+
+Similar you can build U-Boot images from a 'ramdisk.image.gz' file
+when your kernel is intended to use an initial ramdisk:
+
+	-> tools/mkimage -n 'Simple Ramdisk Image' \
+	> -A ppc -O linux -T ramdisk -C gzip \
+	> -d /LinuxPPC/images/SIMPLE-ramdisk.image.gz examples/simple-initrd
+	Image Name:   Simple Ramdisk Image
+	Created:      Wed Jan 12 14:01:50 2000
+	Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
+	Data Size:    566530 Bytes = 553.25 kB = 0.54 MB
+	Load Address: 0x00000000
+	Entry Point:  0x00000000
+
+
+Installing a Linux Image:
+-------------------------
+
+To downloading a U-Boot image over the serial (console) interface,
+you must convert the image to S-Record format:
+
+	objcopy -I binary -O srec examples/image examples/image.srec
+
+The 'objcopy' does not understand the information in the U-Boot
+image header, so the resulting S-Record file will be relative to
+address 0x00000000. To load it to a given address, you need to
+specify the target address as 'offset' parameter with the 'loads'
+command.
+
+Example: install the image to address 0x40100000 (which on the
+TQM8xxL is in the first Flash bank):
+
+	=> erase 40100000 401FFFFF
+
+	.......... done
+	Erased 8 sectors
+
+	=> loads 40100000
+	## Ready for S-Record download ...
+	~>examples/image.srec
+	1 2 3 4 5 6 7 8 9 10 11 12 13 ...
+	...
+	15989 15990 15991 15992
+	[file transfer complete]
+	[connected]
+	## Start Addr = 0x00000000
+
+
+You can check the success of the download using the 'iminfo' command;
+this includes a checksum verification so you  can  be  sure  no	 data
+corruption happened:
+
+	=> imi 40100000
+
+	## Checking Image at 40100000 ...
+	   Image Name:	 2.2.13 for initrd on TQM850L
+	   Image Type:	 PowerPC Linux Kernel Image (gzip compressed)
+	   Data Size:	 335725 Bytes = 327 kB = 0 MB
+	   Load Address: 00000000
+	   Entry Point:	 0000000c
+	   Verifying Checksum ... OK
+
+
+
+Boot Linux:
+-----------
+
+The "bootm" command is used to boot an application that is stored in
+memory (RAM or Flash). In case of a Linux kernel image, the contents
+of the "bootargs" environment variable is passed to the kernel as
+parameters. You can check and modify this variable using the
+"printenv" and "setenv" commands:
+
+
+	=> printenv bootargs
+	bootargs=root=/dev/ram
+
+	=> setenv bootargs root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
+
+	=> printenv bootargs
+	bootargs=root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
+
+	=> bootm 40020000
+	## Booting Linux kernel at 40020000 ...
+	   Image Name:	 2.2.13 for NFS on TQM850L
+	   Image Type:	 PowerPC Linux Kernel Image (gzip compressed)
+	   Data Size:	 381681 Bytes = 372 kB = 0 MB
+	   Load Address: 00000000
+	   Entry Point:	 0000000c
+	   Verifying Checksum ... OK
+	   Uncompressing Kernel Image ... OK
+	Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:35:17 MEST 2000
+	Boot arguments: root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
+	time_init: decrementer frequency = 187500000/60
+	Calibrating delay loop... 49.77 BogoMIPS
+	Memory: 15208k available (700k kernel code, 444k data, 32k init) [c0000000,c1000000]
+	...
+
+If you want to boot a Linux kernel with initial ram disk, you pass
+the memory addreses of both the kernel and the initrd image (PPBCOOT
+format!) to the "bootm" command:
+
+	=> imi 40100000 40200000
+
+	## Checking Image at 40100000 ...
+	   Image Name:	 2.2.13 for initrd on TQM850L
+	   Image Type:	 PowerPC Linux Kernel Image (gzip compressed)
+	   Data Size:	 335725 Bytes = 327 kB = 0 MB
+	   Load Address: 00000000
+	   Entry Point:	 0000000c
+	   Verifying Checksum ... OK
+
+	## Checking Image at 40200000 ...
+	   Image Name:	 Simple Ramdisk Image
+	   Image Type:	 PowerPC Linux RAMDisk Image (gzip compressed)
+	   Data Size:	 566530 Bytes = 553 kB = 0 MB
+	   Load Address: 00000000
+	   Entry Point:	 00000000
+	   Verifying Checksum ... OK
+
+	=> bootm 40100000 40200000
+	## Booting Linux kernel at 40100000 ...
+	   Image Name:	 2.2.13 for initrd on TQM850L
+	   Image Type:	 PowerPC Linux Kernel Image (gzip compressed)
+	   Data Size:	 335725 Bytes = 327 kB = 0 MB
+	   Load Address: 00000000
+	   Entry Point:	 0000000c
+	   Verifying Checksum ... OK
+	   Uncompressing Kernel Image ... OK
+	## Loading RAMDisk Image at 40200000 ...
+	   Image Name:	 Simple Ramdisk Image
+	   Image Type:	 PowerPC Linux RAMDisk Image (gzip compressed)
+	   Data Size:	 566530 Bytes = 553 kB = 0 MB
+	   Load Address: 00000000
+	   Entry Point:	 00000000
+	   Verifying Checksum ... OK
+	   Loading Ramdisk ... OK
+	Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:32:08 MEST 2000
+	Boot arguments: root=/dev/ram
+	time_init: decrementer frequency = 187500000/60
+	Calibrating delay loop... 49.77 BogoMIPS
+	...
+	RAMDISK: Compressed image found at block 0
+	VFS: Mounted root (ext2 filesystem).
+
+	bash#
+
+
+Standalone HOWTO:
+=================
+
+One of the features of U-Boot is that you can dynamically load and
+run "standalone" applications, which can use some resources of
+U-Boot like console I/O functions or interrupt services.
+
+Two simple examples are included with the sources:
+
+"Hello World" Demo:
+-------------------
+
+'examples/hello_world.c' contains a small "Hello World" Demo
+application; it is automatically compiled when you build U-Boot.
+It's configured to run at address 0x00040004, so you can play with it
+like that:
+
+	=> loads
+	## Ready for S-Record download ...
+	~>examples/hello_world.srec
+	1 2 3 4 5 6 7 8 9 10 11 ...
+	[file transfer complete]
+	[connected]
+	## Start Addr = 0x00040004
+
+	=> go 40004 Hello World! This is a test.
+	## Starting application at 0x00040004 ...
+	Hello World
+	argc = 7
+	argv[0] = "40004"
+	argv[1] = "Hello"
+	argv[2] = "World!"
+	argv[3] = "This"
+	argv[4] = "is"
+	argv[5] = "a"
+	argv[6] = "test."
+	argv[7] = "<NULL>"
+	Hit any key to exit ...
+
+	## Application terminated, rc = 0x0
+
+Another example, which demonstrates how to register a CPM interrupt
+handler with the U-Boot code, can be found in 'examples/timer.c'.
+Here, a CPM timer is set up to generate an interrupt every second.
+The interrupt service routine is trivial, just printing a '.'
+character, but this is just a demo program. The application can be
+controlled by the following keys:
+
+	? - print current values og the CPM Timer registers
+	b - enable interrupts and start timer
+	e - stop timer and disable interrupts
+	q - quit application
+
+	=> loads
+	## Ready for S-Record download ...
+	~>examples/timer.srec
+	1 2 3 4 5 6 7 8 9 10 11 ...
+	[file transfer complete]
+	[connected]
+	## Start Addr = 0x00040004
+
+	=> go 40004
+	## Starting application at 0x00040004 ...
+	TIMERS=0xfff00980
+	Using timer 1
+	  tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0
+
+Hit 'b':
+	[q, b, e, ?] Set interval 1000000 us
+	Enabling timer
+Hit '?':
+	[q, b, e, ?] ........
+	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0xef6, ter=0x0
+Hit '?':
+	[q, b, e, ?] .
+	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x2ad4, ter=0x0
+Hit '?':
+	[q, b, e, ?] .
+	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x1efc, ter=0x0
+Hit '?':
+	[q, b, e, ?] .
+	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x169d, ter=0x0
+Hit 'e':
+	[q, b, e, ?] ...Stopping timer
+Hit 'q':
+	[q, b, e, ?] ## Application terminated, rc = 0x0
+
+
+NetBSD Notes:
+=============
+
+Starting at version 0.9.2, U-Boot supports NetBSD both as host
+(build U-Boot) and target system (boots NetBSD/mpc8xx).
+
+Building requires a cross environment; it is known to work on
+NetBSD/i386 with the cross-powerpc-netbsd-1.3 package (you will also
+need gmake since the Makefiles are not compatible with BSD make).
+Note that the cross-powerpc package does not install include files;
+attempting to build U-Boot will fail because <machine/ansi.h> is
+missing.  This file has to be installed and patched manually:
+
+	# cd /usr/pkg/cross/powerpc-netbsd/include
+	# mkdir powerpc
+	# ln -s powerpc machine
+	# cp /usr/src/sys/arch/powerpc/include/ansi.h powerpc/ansi.h
+	# ${EDIT} powerpc/ansi.h	## must remove __va_list, _BSD_VA_LIST
+
+Native builds *don't* work due to incompatibilities between native
+and U-Boot include files.
+
+Booting assumes that (the first part of) the image booted is a
+stage-2 loader which in turn loads and then invokes the kernel
+proper. Loader sources will eventually appear in the NetBSD source
+tree (probably in sys/arc/mpc8xx/stand/u-boot_stage2/); in the
+meantime, send mail to bruno@exet-ag.de and/or wd@denx.de for
+details.
+
+
+Implementation Internals:
+=========================
+
+The following is not intended to be a complete description of every
+implementation detail. However, it should help to understand the
+inner workings of U-Boot and make it easier to port it to custom
+hardware.
+
+
+Initial Stack, Global Data:
+---------------------------
+
+The implementation of U-Boot is complicated by the fact that U-Boot
+starts running out of ROM (flash memory), usually without access to
+system RAM (because the memory controller is not initialized yet).
+This means that we don't have writable Data or BSS segments, and BSS
+is not initialized as zero. To be able to get a C environment working
+at all, we have to allocate at least a minimal stack. Implementation
+options for this are defined and restricted by the CPU used: Some CPU
+models provide on-chip memory (like the IMMR area on MPC8xx and
+MPC826x processors), on others (parts of) the data cache can be
+locked as (mis-) used as memory, etc.
+
+It is essential to remember this, since it has some impact on the C
+code for the initialization procedures:
+
+* Initialized global data (data segment) is read-only. Do not attempt
+  to write it.
+
+* Do not use any unitialized global data (or implicitely initialized
+  as zero data - BSS segment) at all - this is undefined, initiali-
+  zation is performed later (when relocationg to RAM).
+
+* Stack space is very limited. Avoid big data buffers or things  like
+  that.
+
+Having only the stack as writable memory limits means we cannot use
+normal global data to share information beween the code. But it
+turned out that the implementation of U-Boot can be greatly
+simplified by making a global data structure (gd_t) available to all
+functions. We could pass a pointer to this data as argument to _all_
+functions, but this would bloat the code. Instead we use a feature of
+the GCC compiler (Global Register Variables) to share the data: we
+place a pointer (gd) to the global data into a register which we
+reserve for this purpose.
+
+When chosing a register for such a purpose we are restricted  by  the
+relevant  (E)ABI  specifications for the current architecture, and by
+GCC's implementation.
+
+For PowerPC, the following registers have specific use:
+	R1:	stack pointer
+	R2:	TOC pointer
+	R3-R4:	parameter passing and return values
+	R5-R10:	parameter passing
+	R13:	small data area pointer
+	R30:	GOT pointer
+	R31:	frame pointer
+
+	(U-Boot also uses R14 as internal GOT pointer.)
+
+    ==> U-Boot will use R29 to hold a pointer to the global data
+
+    Note: on PPC, we could use a static initializer (since the
+    address of the global data structure is known at compile time),
+    but it turned out that reserving a register results in somewhat
+    smaller code - although the code savings are not that big (on
+    average for all boards 752 bytes for the whole U-Boot image,
+    624 text + 127 data).
+
+On ARM, the following registers are used:
+
+	R0:	function argument word/integer result
+	R1-R3:	function argument word
+	R9:	GOT pointer
+	R10:	stack limit (used only if stack checking if enabled)
+	R11:	argument (frame) pointer
+	R12:	temporary workspace
+	R13:	stack pointer
+	R14:	link register
+	R15:	program counter
+
+    ==> U-Boot will use R8 to hold a pointer to the global data
+
+
+
+Memory Management:
+------------------
+
+U-Boot runs in system state and uses physical addresses, i.e. the
+MMU is not used either for address mapping nor for memory protection.
+
+The available memory is mapped to fixed addresses using the memory
+controller. In this process, a contiguous block is formed for each
+memory type (Flash, SDRAM, SRAM), even when it consists of several
+physical memory banks.
+
+U-Boot is installed in the first 128 kB of the first Flash bank (on
+TQM8xxL modules this is the range 0x40000000 ... 0x4001FFFF). After
+booting and sizing and initializing DRAM, the code relocates itself
+to the upper end of DRAM. Immediately below the U-Boot code some
+memory is reserved for use by malloc() [see CFG_MALLOC_LEN
+configuration setting]. Below that, a structure with global Board
+Info data is placed, followed by the stack (growing downward).
+
+Additionally, some exception handler code is copied to the low 8 kB
+of DRAM (0x00000000 ... 0x00001FFF).
+
+So a typical memory configuration with 16 MB of DRAM could look like
+this:
+
+	0x0000 0000	Exception Vector code
+	      :
+	0x0000 1FFF
+	0x0000 2000	Free for Application Use
+	      :
+	      :
+
+	      :
+	      :
+	0x00FB FF20	Monitor Stack (Growing downward)
+	0x00FB FFAC	Board Info Data and permanent copy of global data
+	0x00FC 0000	Malloc Arena
+	      :
+	0x00FD FFFF
+	0x00FE 0000	RAM Copy of Monitor Code
+	...		eventually: LCD or video framebuffer
+	...		eventually: pRAM (Protected RAM - unchanged by reset)
+	0x00FF FFFF	[End of RAM]
+
+
+System Initialization:
+----------------------
+
+In the reset configuration, U-Boot starts at the reset entry point
+(on most PowerPC systens at address 0x00000100). Because of the reset
+configuration for CS0# this is a mirror of the onboard Flash memory.
+To be able to re-map memory U-Boot then jumps to it's link address.
+To be able to implement the initialization code in C, a (small!)
+initial stack is set up in the internal Dual Ported RAM (in case CPUs
+which provide such a feature like MPC8xx or MPC8260), or in a locked
+part of the data cache. After that, U-Boot initializes the CPU core,
+the caches and the SIU.
+
+Next, all (potentially) available memory banks are mapped using a
+preliminary mapping. For example, we put them on 512 MB boundaries
+(multiples of 0x20000000: SDRAM on 0x00000000 and 0x20000000, Flash
+on 0x40000000 and 0x60000000, SRAM on 0x80000000). Then UPM A is
+programmed for SDRAM access. Using the temporary configuration, a
+simple memory test is run that determines the size of the SDRAM
+banks.
+
+When there is more than one SDRAM bank, and the banks are of
+different size, the larger is mapped first. For equal size, the first
+bank (CS2#) is mapped first. The first mapping is always for address
+0x00000000, with any additional banks following immediately to create
+contiguous memory starting from 0.
+
+Then, the monitor installs itself at the upper end of the SDRAM area
+and allocates memory for use by malloc() and for the global Board
+Info data; also, the exception vector code is copied to the low RAM
+pages, and the final stack is set up.
+
+Only after this relocation will you have a "normal" C environment;
+until that you are restricted in several ways, mostly because you are
+running from ROM, and because the code will have to be relocated to a
+new address in RAM.
+
+
+U-Boot Porting Guide:
+----------------------
+
+[Based on messages by Jerry Van Baren in the U-Boot-Users mailing
+list, Octover 2002]
+
+
+int main (int argc, char *argv[])
+{
+	sighandler_t no_more_time;
+
+	signal (SIGALRM, no_more_time);
+	alarm (PROJECT_DEADLINE - toSec (3 * WEEK));
+
+	if (available_money > available_manpower) {
+		pay consultant to port U-Boot;
+		return 0;
+	}
+
+	Download latest U-Boot source;
+
+	if (clueless) {
+		email ("Hi, I am new to U-Boot, how do I get started?");
+	}
+
+	while (learning) {
+		Read the README file in the top level directory;
+		Read http://www.denx.de/re/DPLG.html
+		Read the source, Luke;
+	}
+
+	if (available_money > toLocalCurrency ($2500)) {
+		Buy a BDI2000;
+	} else {
+		Add a lot of aggravation and time;
+	}
+
+	Create your own board support subdirectory;
+
+	while (!running) {
+		do {
+			Add / modify source code;
+		} until (compiles);
+		Debug;
+		if (clueless)
+			email ("Hi, I am having problems...");
+	}
+	Send patch file to Wolfgang;
+
+	return 0;
+}
+
+void no_more_time (int sig)
+{
+      hire_a_guru();
+}
+
+
+
+Coding Standards:
+-----------------
+
+All contributions to U-Boot should conform to the Linux kernel
+coding style; see the file "Documentation/CodingStyle" in your Linux
+kernel source directory.
+
+Please note that U-Boot is implemented in C (and to some small parts
+in Assembler); no C++ is used, so please do not use C++ style
+comments (//) in your code.
+
+Submissions which do not conform to the standards may be returned
+with a request to reformat the changes.
+
+
+Submitting Patches:
+-------------------
+
+Since the number of patches for U-Boot is growing, we need to
+establish some rules. Submissions which do not conform to these rules
+may be rejected, even when they contain important and valuable stuff.
+
+
+When you send a patch, please include the following information with
+it:
+
+* For bug fixes: a description of the bug and how your patch fixes
+  this bug. Please try to include a way of demonstrating that the
+  patch actually fixes something.
+
+* For new features: a description of the feature and your
+  implementation.
+
+* A CHANGELOG entry as plaintext (separate from the patch)
+
+* For major contributions, your entry to the CREDITS file
+
+* When you add support for a new board, don't forget to add this
+  board to the MAKEALL script, too.
+
+* If your patch adds new configuration options, don't forget to
+  document these in the README file.
+
+* The patch itself. If you are accessing the CVS repository use "cvs
+  update; cvs diff -puRN"; else, use "diff -purN OLD NEW". If your
+  version of diff does not support these options, then get the latest
+  version of GNU diff.
+
+  We accept patches as plain text, MIME attachments or as uuencoded
+  gzipped text.
+
+Notes:
+
+* Before sending the patch, run the MAKEALL script on your patched
+  source tree and make sure that no errors or warnings are reported
+  for any of the boards.
+
+* Keep your modifications to the necessary minimum: A patch
+  containing several unrelated changes or arbitrary reformats will be
+  returned with a request to re-formatting / split it.
+
+* If you modify existing code, make sure that your new code does not
+  add to the memory footprint of the code ;-) Small is beautiful!
+  When adding new features, these should compile conditionally only
+  (using #ifdef), and the resulting code with the new feature
+  disabled must not need more memory than the old code without your
+  modification.
diff --git a/board/cogent/serial.c b/board/cogent/serial.c
new file mode 100644
index 0000000..4c20017
--- /dev/null
+++ b/board/cogent/serial.c
@@ -0,0 +1,190 @@
+/*
+ * Simple serial driver for Cogent motherboard serial ports
+ * for use during boot
+ */
+
+#include <common.h>
+#include <board/cogent/serial.h>
+
+#if (CMA_MB_CAPS & CMA_MB_CAP_SERPAR)
+
+#if (defined(CONFIG_8xx) && defined(CONFIG_8xx_CONS_NONE)) || \
+     (defined(CONFIG_8260) && defined(CONFIG_CONS_NONE))
+
+#if CONFIG_CONS_INDEX == 1
+#define CMA_MB_SERIAL_BASE	CMA_MB_SERIALA_BASE
+#elif CONFIG_CONS_INDEX == 2
+#define CMA_MB_SERIAL_BASE	CMA_MB_SERIALB_BASE
+#elif CONFIG_CONS_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_SERIAL_BASE	CMA_MB_SER2A_BASE
+#elif CONFIG_CONS_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_SERIAL_BASE	CMA_MB_SER2B_BASE
+#else
+#error CONFIG_CONS_INDEX must be configured for Cogent motherboard serial
+#endif
+
+int serial_init (void)
+{
+/*  DECLARE_GLOBAL_DATA_PTR; */
+
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    cma_mb_reg_write(&mbsp->ser_ier, 0x00);	/* turn off interrupts */
+    serial_setbrg ();
+    cma_mb_reg_write(&mbsp->ser_lcr, 0x03);	/* 8 data, 1 stop, no parity */
+    cma_mb_reg_write(&mbsp->ser_mcr, 0x03);	/* RTS/DTR */
+    cma_mb_reg_write(&mbsp->ser_fcr, 0x07);	/* Clear & enable FIFOs */
+
+    return (0);
+}
+
+void
+serial_setbrg (void)
+{
+    DECLARE_GLOBAL_DATA_PTR;
+
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+    unsigned int divisor;
+    unsigned char lcr;
+
+    if ((divisor = br_to_div(gd->baudrate)) == 0)
+	divisor = DEFDIV;
+
+    lcr = cma_mb_reg_read(&mbsp->ser_lcr);
+    cma_mb_reg_write(&mbsp->ser_lcr, lcr|0x80);/* Access baud rate(set DLAB)*/
+    cma_mb_reg_write(&mbsp->ser_brl, divisor & 0xff);
+    cma_mb_reg_write(&mbsp->ser_brh, (divisor >> 8) & 0xff);
+    cma_mb_reg_write(&mbsp->ser_lcr, lcr);	/* unset DLAB */
+}
+
+void
+serial_putc(const char c)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    if (c == '\n')
+	serial_putc('\r');
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_THRE) == 0)
+	;
+
+    cma_mb_reg_write(&mbsp->ser_thr, c);
+}
+
+void
+serial_puts(const char *s)
+{
+    while (*s != '\0')
+	serial_putc(*s++);
+}
+
+int
+serial_getc(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) == 0)
+	;
+
+    return ((int)cma_mb_reg_read(&mbsp->ser_rhr) & 0x7f);
+}
+
+int
+serial_tstc(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    return ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) != 0);
+}
+
+#endif /* CONS_NONE */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && \
+    defined(CONFIG_KGDB_NONE)
+
+#if CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
+#error Console and kgdb are on the same serial port - this is not supported
+#endif
+
+#if CONFIG_KGDB_INDEX == 1
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SERIALA_BASE
+#elif CONFIG_KGDB_INDEX == 2
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SERIALB_BASE
+#elif CONFIG_KGDB_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SER2A_BASE
+#elif CONFIG_KGDB_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SER2B_BASE
+#else
+#error CONFIG_KGDB_INDEX must be configured for Cogent motherboard serial
+#endif
+
+void
+kgdb_serial_init(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+    unsigned int divisor;
+
+    if ((divisor = br_to_div(CONFIG_KGDB_BAUDRATE)) == 0)
+	divisor = DEFDIV;
+
+    cma_mb_reg_write(&mbsp->ser_ier, 0x00);	/* turn off interrupts */
+    cma_mb_reg_write(&mbsp->ser_lcr, 0x80);	/* Access baud rate(set DLAB)*/
+    cma_mb_reg_write(&mbsp->ser_brl, divisor & 0xff);
+    cma_mb_reg_write(&mbsp->ser_brh, (divisor >> 8) & 0xff);
+    cma_mb_reg_write(&mbsp->ser_lcr, 0x03);	/* 8 data, 1 stop, no parity */
+    cma_mb_reg_write(&mbsp->ser_mcr, 0x03);	/* RTS/DTR */
+    cma_mb_reg_write(&mbsp->ser_fcr, 0x07);	/* Clear & enable FIFOs */
+
+    printf("[on cma10x serial port B] ");
+}
+
+void
+putDebugChar(int c)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_THRE) == 0)
+	;
+
+    cma_mb_reg_write(&mbsp->ser_thr, c & 0xff);
+}
+
+void
+putDebugStr(const char *str)
+{
+    while (*str != '\0') {
+	if (*str == '\n')
+	    putDebugChar('\r');
+	putDebugChar(*str++);
+    }
+}
+
+int
+getDebugChar(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) == 0)
+	;
+
+    return ((int)cma_mb_reg_read(&mbsp->ser_rhr) & 0x7f);
+}
+
+void
+kgdb_interruptible(int yes)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+    if (yes == 1) {
+	printf("kgdb: turning serial ints on\n");
+	cma_mb_reg_write(&mbsp->ser_ier, 0xf);
+    }
+    else {
+	printf("kgdb: turning serial ints off\n");
+	cma_mb_reg_write(&mbsp->ser_ier, 0x0);
+    }
+}
+
+#endif /* KGDB && KGDB_NONE */
+
+#endif /* CAPS & SERPAR */
diff --git a/board/cu824/cu824.c b/board/cu824/cu824.c
new file mode 100644
index 0000000..20aaea2
--- /dev/null
+++ b/board/cu824/cu824.c
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2001, 2002
+ * 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 <mpc824x.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+#define BOARD_REV_REG 0xFE80002B
+
+int checkboard (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	char  revision = *(volatile char *)(BOARD_REV_REG);
+	char  buf[32];
+
+	puts ("Board: CU824 ");
+	printf("Revision %d ", revision);
+	printf("Local Bus at %s MHz\n", strmhz(buf, gd->bus_clk));
+
+	return 0;
+}
+
+long int initdram(int board_type)
+{
+	int              i, cnt;
+	volatile uchar * base      = CFG_SDRAM_BASE;
+	volatile ulong * addr;
+	ulong            save[32];
+	ulong            val, ret  = 0;
+
+	for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+		addr = (volatile ulong *)base + cnt;
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	addr = (volatile ulong *)base;
+	save[i] = *addr;
+	*addr = 0;
+
+	if (*addr != 0) {
+		*addr = save[i];
+		goto Done;
+	}
+
+	for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+		addr = (volatile ulong *)base + cnt;
+		val = *addr;
+		*addr = save[--i];
+		if (val != ~cnt) {
+			ulong new_bank0_end = cnt * sizeof(long) - 1;
+			ulong mear1  = mpc824x_mpc107_getreg(MEAR1);
+			ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+			mear1 =  (mear1  & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+			emear1 = (emear1 & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+			mpc824x_mpc107_setreg(MEAR1,  mear1);
+			mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+			ret = cnt * sizeof(long);
+			goto Done;
+		}
+	}
+
+	ret = CFG_MAX_RAM_SIZE;
+Done:
+	return ret;
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
+	  pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
+				       0,
+				       PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
+	{ }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/dnp1110/u-boot.lds b/board/dnp1110/u-boot.lds
new file mode 100644
index 0000000..f4b0ade
--- /dev/null
+++ b/board/dnp1110/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/sa1100/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/ebony/ebony.c b/board/ebony/ebony.c
new file mode 100644
index 0000000..723fad3
--- /dev/null
+++ b/board/ebony/ebony.c
@@ -0,0 +1,301 @@
+/*
+ *  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.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
+ */
+
+
+extern long int spd_sdram (void);
+
+#include <common.h>
+#include "ebony.h"
+#include <asm/processor.h>
+
+#define BOOT_SMALL_FLASH	32	/* 00100000 */
+#define FLASH_ONBD_N		2	/* 00000010 */
+#define FLASH_SRAM_SEL		1	/* 00000001 */
+
+long int fixed_sdram (void);
+
+int board_pre_init (void)
+{
+	uint reg;
+	unsigned char *fpga_base = (unsigned char *) CFG_FPGA_BASE;
+	unsigned char status;
+
+
+	/*--------------------------------------------------------------------
+	 * Setup the external bus controller/chip selects
+	 *-------------------------------------------------------------------*/
+	mtdcr (ebccfga, xbcfg);
+	reg = mfdcr (ebccfgd);
+	mtdcr (ebccfgd, reg | 0x04000000);	/* Set ATC */
+
+	mtebc (pb1ap, 0x02815480);	/* NVRAM/RTC */
+	mtebc (pb1cr, 0x48018000);	/* BA=0x480 1MB R/W 8-bit */
+	mtebc (pb7ap, 0x01015280);	/* FPGA registers */
+	mtebc (pb7cr, 0x48318000);	/* BA=0x483 1MB R/W 8-bit */
+
+	/* read FPGA_REG0  and set the bus controller */
+	status = *fpga_base;
+	if ((status & BOOT_SMALL_FLASH) && !(status & FLASH_ONBD_N)) {
+		mtebc (pb0ap, 0x9b015480);	/* FLASH/SRAM */
+		mtebc (pb0cr, 0xfff18000);	/* BAS=0xfff 1MB R/W 8-bit */
+		mtebc (pb2ap, 0x9b015480);	/* 4MB FLASH */
+		mtebc (pb2cr, 0xff858000);	/* BAS=0xff8 4MB R/W 8-bit */
+	} else {
+		mtebc (pb0ap, 0x9b015480);	/* 4MB FLASH */
+		mtebc (pb0cr, 0xffc58000);	/* BAS=0xffc 4MB R/W 8-bit */
+
+		/* set CS2 if FLASH_ONBD_N == 0 */
+		if (!(status & FLASH_ONBD_N)) {
+			mtebc (pb2ap, 0x9b015480);	/* FLASH/SRAM */
+			mtebc (pb2cr, 0xff818000);	/* BAS=0xff8 4MB R/W 8-bit */
+		}
+	}
+
+	/*--------------------------------------------------------------------
+	 * Setup the interrupt controller polarities, triggers, etc.
+	 *-------------------------------------------------------------------*/
+	mtdcr (uic0sr, 0xffffffff);	/* clear all */
+	mtdcr (uic0er, 0x00000000);	/* disable all */
+	mtdcr (uic0cr, 0x00000009);	/* SMI & UIC1 crit are critical */
+	mtdcr (uic0pr, 0xfffffe13);	/* per ref-board manual */
+	mtdcr (uic0tr, 0x01c00008);	/* per ref-board manual */
+	mtdcr (uic0vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr (uic0sr, 0xffffffff);	/* clear all */
+
+	mtdcr (uic1sr, 0xffffffff);	/* clear all */
+	mtdcr (uic1er, 0x00000000);	/* disable all */
+	mtdcr (uic1cr, 0x00000000);	/* all non-critical */
+	mtdcr (uic1pr, 0xffffe0ff);	/* per ref-board manual */
+	mtdcr (uic1tr, 0x00ffc000);	/* per ref-board manual */
+	mtdcr (uic1vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr (uic1sr, 0xffffffff);	/* clear all */
+
+	return 0;
+}
+
+
+
+int checkboard (void)
+{
+	sys_info_t sysinfo;
+
+	get_sys_info (&sysinfo);
+
+	printf ("Board: IBM 440GP Evaluation Board (Ebony)\n");
+	printf ("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz / 1000000);
+	printf ("\tCPU: %lu MHz\n", sysinfo.freqProcessor / 1000000);
+	printf ("\tPLB: %lu MHz\n", sysinfo.freqPLB / 1000000);
+	printf ("\tOPB: %lu MHz\n", sysinfo.freqOPB / 1000000);
+	printf ("\tEPB: %lu MHz\n", sysinfo.freqEPB / 1000000);
+	return (0);
+}
+
+
+long int initdram (int board_type)
+{
+	long dram_size = 0;
+	extern long spd_sdram (void);
+
+#if defined(CONFIG_SPD_EEPROM)
+	dram_size = spd_sdram ();
+#else
+	dram_size = fixed_sdram ();
+#endif
+	return dram_size;
+}
+
+
+#if defined(CFG_DRAM_TEST)
+int testdram (void)
+{
+	uint *pstart = (uint *) 0x00000000;
+	uint *pend = (uint *) 0x08000000;
+	uint *p;
+
+	for (p = pstart; p < pend; p++)
+		*p = 0xaaaaaaaa;
+
+	for (p = pstart; p < pend; p++) {
+		if (*p != 0xaaaaaaaa) {
+			printf ("SDRAM test fails at: %08x\n", (uint) p);
+			return 1;
+		}
+	}
+
+	for (p = pstart; p < pend; p++)
+		*p = 0x55555555;
+
+	for (p = pstart; p < pend; p++) {
+		if (*p != 0x55555555) {
+			printf ("SDRAM test fails at: %08x\n", (uint) p);
+			return 1;
+		}
+	}
+	return 0;
+}
+#endif
+
+#if !defined(CONFIG_SPD_EEPROM)
+/*************************************************************************
+ *  fixed sdram init -- doesn't use serial presence detect.
+ *
+ *  Assumes:    128 MB, non-ECC, non-registered
+ *              PLB @ 133 MHz
+ *
+ ************************************************************************/
+long int fixed_sdram (void)
+{
+	uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup some default
+	 *------------------------------------------------------------------*/
+	mtsdram (mem_uabba, 0x00000000);	/* ubba=0 (default)             */
+	mtsdram (mem_slio, 0x00000000);		/* rdre=0 wrre=0 rarw=0         */
+	mtsdram (mem_devopt, 0x00000000);	/* dll=0 ds=0 (normal)          */
+	mtsdram (mem_wddctr, 0x00000000);	/* wrcp=0 dcd=0                 */
+	mtsdram (mem_clktr, 0x40000000);	/* clkp=1 (90 deg wr) dcdt=0    */
+
+	/*--------------------------------------------------------------------
+	 * Setup for board-specific specific mem
+	 *------------------------------------------------------------------*/
+	/*
+	 * Following for CAS Latency = 2.5 @ 133 MHz PLB
+	 */
+	mtsdram (mem_b0cr, 0x000a4001);	/* SDBA=0x000 128MB, Mode 3, enabled */
+	mtsdram (mem_tr0, 0x410a4012);	/* WR=2  WD=1 CL=2.5 PA=3 CP=4 LD=2 */
+	/* RA=10 RD=3                       */
+	mtsdram (mem_tr1, 0x8080082f);	/* SS=T2 SL=STAGE 3 CD=1 CT=0x02f   */
+	mtsdram (mem_rtr, 0x08200000);	/* Rate 15.625 ns @ 133 MHz PLB     */
+	mtsdram (mem_cfg1, 0x00000000);	/* Self-refresh exit, disable PM    */
+	udelay (400);			/* Delay 200 usecs (min)            */
+
+	/*--------------------------------------------------------------------
+	 * Enable the controller, then wait for DCEN to complete
+	 *------------------------------------------------------------------*/
+	mtsdram (mem_cfg0, 0x86000000);	/* DCEN=1, PMUD=1, 64-bit           */
+	for (;;) {
+		mfsdram (mem_mcsts, reg);
+		if (reg & 0x80000000)
+			break;
+	}
+
+	return (128 * 1024 * 1024);	/* 128 MB                           */
+}
+#endif	/* !defined(CONFIG_SPD_EEPROM) */
+
+
+/*************************************************************************
+ *  pci_pre_init
+ *
+ *  This routine is called just prior to registering the hose and gives
+ *  the board the opportunity to check things. Returning a value of zero
+ *  indicates that things are bad & PCI initialization should be aborted.
+ *
+ *	Different boards may wish to customize the pci controller structure
+ *	(add regions, override default access routines, etc) or perform
+ *	certain pre-initialization actions.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)
+int pci_pre_init(struct pci_controller * hose )
+{
+    unsigned long strap;
+
+	/*--------------------------------------------------------------------------+
+     *	The ebony board is always configured as the host & requires the
+     *	PCI arbiter to be enabled.
+	 *--------------------------------------------------------------------------*/
+    strap = mfdcr(cpc0_strp1);
+    if( (strap & 0x00100000) == 0 ){
+        printf("PCI: CPC0_STRP1[PAE] not set.\n");
+        return 0;
+    }
+
+    return 1;
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ *  pci_target_init
+ *
+ *	The bootstrap configuration provides default settings for the pci
+ *	inbound map (PIM). But the bootstrap config choices are limited and
+ *	may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller * hose )
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/*--------------------------------------------------------------------------+
+	 * Disable everything
+	 *--------------------------------------------------------------------------*/
+	out32r( PCIX0_PIM0SA, 0 ); /* disable */
+	out32r( PCIX0_PIM1SA, 0 ); /* disable */
+	out32r( PCIX0_PIM2SA, 0 ); /* disable */
+	out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */
+
+	/*--------------------------------------------------------------------------+
+	 * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 strapping
+     * options to not support sizes such as 128/256 MB.
+	 *--------------------------------------------------------------------------*/
+	out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE );
+	out32r( PCIX0_PIM0LAH, 0 );
+	out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 );
+
+	out32r( PCIX0_BAR0, 0 );
+
+	/*--------------------------------------------------------------------------+
+	 * Program the board's subsystem id/vendor id
+	 *--------------------------------------------------------------------------*/
+    out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+    out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID );
+
+	out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY );
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+
+/*************************************************************************
+ *  is_pci_host
+ *
+ *	This routine is called to determine if a pci scan should be
+ *	performed. With various hardware environments (especially cPCI and
+ *	PPMC) it's insufficient to depend on the state of the arbiter enable
+ *	bit in the strap register, or generic host/adapter assumptions.
+ *
+ *	Rather than hard-code a bad assumption in the general 440 code, the
+ *	440 pci code requires the board to decide at runtime.
+ *
+ *	Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+int is_pci_host(struct pci_controller *hose)
+{
+    /* The ebony board is always configured as host. */
+    return(1);
+}
+#endif /* defined(CONFIG_PCI) */
diff --git a/board/ebony/init.S b/board/ebony/init.S
new file mode 100644
index 0000000..3ae93d6
--- /dev/null
+++ b/board/ebony/init.S
@@ -0,0 +1,98 @@
+/*
+*  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.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
+*/
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID   0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K	    0x00000000
+#define SZ_4K	    0x00000010
+#define SZ_16K	    0x00000020
+#define SZ_64K	    0x00000030
+#define SZ_256K	    0x00000040
+#define SZ_1M	    0x00000050
+#define SZ_16M	    0x00000070
+#define SZ_256M	    0x00000090
+
+/* Storage attributes */
+#define SA_W	    0x00000800	    /* Write-through */
+#define SA_I	    0x00000400	    /* Caching inhibited */
+#define SA_M	    0x00000200	    /* Memory coherence */
+#define SA_G	    0x00000100	    /* Guarded */
+#define SA_E	    0x00000080	    /* Endian */
+
+/* Access control */
+#define AC_X	    0x00000024	    /* Execute */
+#define AC_W	    0x00000012	    /* Write */
+#define AC_R	    0x00000009	    /* Read */
+
+/* Some handy macros */
+
+#define EPN(e)		((e) & 0xfffffc00)
+#define TLB0(epn,sz)	( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn)	( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a)		( (a)&0x00000fbf )
+
+#define tlbtab_start\
+	mflr    r1  ;\
+	bl 0f	    ;
+
+#define tlbtab_end\
+	.long 0, 0, 0	;   \
+0:	mflr    r0	;   \
+	mtlr    r1	;   \
+	blr		;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+	.long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ *  Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+    .section .bootpg,"ax"
+    .globl tlbtab
+
+tlbtab:
+    tlbtab_start
+    tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+    tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+    tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
+    tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I )
+    tlbtab_end
+
+
diff --git a/board/eltec/bab7xx/asm_init.S b/board/eltec/bab7xx/asm_init.S
new file mode 100644
index 0000000..d739b81
--- /dev/null
+++ b/board/eltec/bab7xx/asm_init.S
@@ -0,0 +1,1487 @@
+/*
+ * (C) Copyright 2001 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * ELTEC BAB PPC RAM initialization
+ *
+ * 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 <config.h>
+#include <mpc75x.h>
+#include <mpc106.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+/*
+ * This following contains the entry code for the initialization code
+ * for the MPC 106, a PCI Bridge/Memory Controller.
+ * Register usage:
+ * r0  = ramtest scratch register, toggleError loop counter
+ * r1  = 0xfec0 0cf8 CONFIG_ADDRESS
+ * r2  = 0xfee0 0cfc CONFIG_DATA
+ * r3  = scratch register, subroutine argument and return value, ramtest size
+ * r4  = scratch register, spdRead clock mask, OutHex loop count
+ * r5  = ramtest scratch register
+ * r6  = toggleError 1st value, spdRead port mask
+ * r7  = toggleError 2nd value, ramtest scratch register,
+ *       spdRead scratch register (0x00)
+ * r8  = ramtest scratch register, spdRead scratch register (0x80)
+ * r9  = ramtest scratch register, toggleError loop end, OutHex digit
+ * r10 = ramtest scratch register, spdWriteByte parameter,
+ *        spdReadByte return value, printf pointer to COM1
+ * r11 = startType
+ * r12 = ramtest scratch register, spdRead data mask
+ * r13 = pointer to message block
+ * r14 = pointer to GOT
+ * r15 = scratch register, SPD save
+ * r16 = bank0 size, total memory size
+ * r17 = bank1 size
+ * r18 = bank2 size
+ * r19 = bank3 size
+ * r20 = MCCR1, MSAR1
+ * r21 = MCCR3, MEAR1
+ * r22 = MCCR4, MBER
+ * r23 = EMSAR1
+ * r24 = EMEAR1
+ * r25 = save link register 1st level
+ * r26 = save link register 2nd level
+ * r27 = save link register 3rd level
+ * r30 = pointer to GPIO for spdRead
+ */
+
+
+.globl board_asm_init
+board_asm_init:
+/*
+ * setup pointer to message block
+ */
+    mflr    r25             /* save away link register */
+    bl      get_lnk_reg     /* r3=addr of next instruction */
+    subi    r4, r3, 8       /* r4=board_asm_init addr */
+    addi    r13, r4, (MessageBlock-board_asm_init)
+/*
+ * dcache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, HID0_DCE
+    andc    r3, r3, r4
+    mr      r2, r3
+    ori     r3, r3, HID0_DCI
+    sync
+    mtspr   HID0, r3
+    mtspr   HID0, r2
+    isync
+    sync
+/*
+ * icache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, 0
+    ori     r4, r4, HID0_ICE
+    andc    r3, r3, r4
+    sync
+    mtspr   HID0, r3
+/*
+ * invalidate caches
+ */
+    ori     r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
+    or      r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    andc    r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    isync
+/*
+ * icache_enable
+ */
+    mfspr   r3, HID0
+    ori     r3, r3, (HID0_ICE | HID0_ICFI)
+    sync
+    mtspr   HID0, r3
+
+    lis     r1, 0xfec0
+    ori     r1, r1, 0x0cf8
+    lis     r2, 0xfee0
+    ori     r2, r2, 0xcfc
+
+#ifdef CFG_ADDRESS_MAP_A
+/*
+ * Switch to address map A if necessary.
+ */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, PCI_PICR1
+    stwbrx  r3, 0, r1
+    sync
+    lwbrx   r4, 0, r2
+    sync
+    lis     r0, PICR1_XIO_MODE@h
+    ori     r0, r0, PICR1_XIO_MODE@l
+    andc    r4, r4, r0
+    lis     r0, PICR1_ADDRESS_MAP@h
+    ori     r0, r0, PICR1_ADDRESS_MAP@l
+    or      r4, r4, r0
+    stwbrx  r4, 0, r2
+    sync
+#endif
+
+/*
+ * Do the init for the SIO.
+ */
+    bl      .sioInit
+
+    addi    r3, r13, (MinitLogo-MessageBlock)
+    bl      Printf
+
+    addi    r3, r13, (Mspd01-MessageBlock)
+    bl      Printf
+/*
+ * Memory cofiguration using SPD information stored on the SODIMMs
+ */
+    li      r17, 0
+    li      r18, 0
+    li      r19, 0
+
+    li      r3, 0x0002          /* get RAM type from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    bne     noSpdError
+
+    addi    r3, r13, (Mfail-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x00
+    b       toggleError         /* fail - loop forever */
+
+noSpdError:
+    mr      r15, r3             /* save r3 */
+
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+
+    cmpli   0, 0, r15, 0x0001   /* FPM ? */
+    beq     configFPM
+    cmpli   0, 0, r15, 0x0002   /* EDO ? */
+    beq     configEDO
+    cmpli   0, 0, r15, 0x0004   /* SDRAM ? */
+    beq     configSDRAM
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x01
+    b       toggleError         /* fail - loop forever */
+
+configSDRAM:
+    addi    r3, r13, (MsdRam-MessageBlock)
+    bl      Printf
+/*
+ * set the Memory Configuration Reg. 1
+ */
+    li      r3, 0x001f          /* get bank size from spd bank0/1 */
+    bl      spdRead
+
+    andi.   r3, r3, 0x0038
+    beq     SD16MB2B
+
+    li      r3, 0x0011          /* get number of internal banks */
+                                /* from spd for bank0/1 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x02
+    beq     SD64MB2B
+
+    cmpli   0, 0, r3, 0x04
+    beq     SD64MB4B
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x02
+    b       toggleError         /* fail - loop forever */
+
+SD64MB2B:
+    li      r20, 0x0005         /* 64-Mbit SDRAM 2 banks */
+    b       SDRow2nd
+
+SD64MB4B:
+    li      r20, 0x0000         /* 64-Mbit SDRAM 4 banks */
+    b       SDRow2nd
+
+SD16MB2B:
+    li      r20, 0x000f         /* 16-Mbit SDRAM 2 banks */
+
+SDRow2nd:
+    li      r3, 0x0102          /* get RAM type spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x0004
+    bne     S2D64MB4B           /* bank2/3 isn't present or no SDRAM */
+
+    li      r3, 0x011f          /* get bank size from spd bank2/3 */
+    bl      spdRead
+
+    andi.   r3, r3, 0x0038
+    beq     S2D16MB2B
+/*
+ * set the Memory Configuration Reg. 2
+ */
+    li      r3, 0x0111          /* get number of internal banks */
+                                /* from spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x02
+    beq     S2D64MB2B
+
+    cmpli   0, 0, r3, 0x04
+    beq     S2D64MB4B
+
+    li      r6, 0xe0            /* error codes in r6 and r7 */
+    li      r7, 0x03
+    b       toggleError         /* fail - loop forever */
+
+S2D64MB2B:
+    ori     r20, r20, 0x0050    /* 64-Mbit SDRAM 2 banks */
+    b       S2D64MB4B
+
+S2D16MB2B:
+    ori     r20, r20, 0x00f0    /* 16-Mbit SDRAM 2 banks */
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+S2D64MB4B:
+    lis     r21, 0x8630         /* BSTOPRE = 0x80, REFREC = 6, */
+                                /* RDLAT = 3 */
+
+/*
+ * set the Memory Configuration Reg. 4
+ */
+    lis     r22, 0x2430         /* PRETOACT = 2, ACTOPRE = 4, */
+                                /* WCBUF = 1, RCBUF = 1 */
+    ori     r22, r22, 0x2220    /* SDMODE = 0x022, ACTORW = 2 */
+
+/*
+ * get the size of bank 0-3
+ */
+    li      r3, 0x001f          /* get bank size from spd bank0/1 */
+    bl      spdRead
+
+    rlwinm  r16, r3, 2, 24, 29  /* calculate size in MByte */
+                                /* (128 MB max.) */
+
+    li      r3, 0x0005          /* get number of banks from spd */
+                                /* for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     SDRAMnobank1
+
+    mr      r17, r16
+
+SDRAMnobank1:
+    addi    r3, r13, (Mspd23-MessageBlock)
+    bl      Printf
+
+    li      r3, 0x0102          /* get RAM type spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x0001    /* FPM ? */
+    bne     noFPM23             /* handle as EDO */
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MfpmRam-MessageBlock)
+    bl      Printf
+    b       configRAMcommon
+noFPM23:
+    cmpli   0, 0, r3, 0x0002    /* EDO ? */
+    bne     noEDO23
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MedoRam-MessageBlock)
+    bl      Printf
+    b       configRAMcommon
+noEDO23:
+    cmpli   0, 0, r3, 0x0004    /* SDRAM ? */
+    bne    noSDRAM23
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MsdRam-MessageBlock)
+    bl      Printf
+    b       configSDRAM23
+noSDRAM23:
+    addi    r3, r13, (Mna-MessageBlock)
+    bl      Printf
+    b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
+
+configSDRAM23:
+    li      r3, 0x011f          /* get bank size from spd bank2/3 */
+    bl      spdRead
+
+    rlwinm  r18, r3, 2, 24, 29  /* calculate size in MByte */
+                                /* (128 MB max.) */
+
+    li      r3, 0x0105          /* get number of banks from */
+                                /* spd bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     SDRAMnobank3
+
+    mr    r19, r18
+
+SDRAMnobank3:
+    b       configRAMcommon
+
+configFPM:
+    addi    r3, r13, (MfpmRam-MessageBlock)
+    bl      Printf
+    b       configEDO0
+/*
+ * set the Memory Configuration Reg. 1
+ */
+configEDO:
+    addi    r3, r13, (MedoRam-MessageBlock)
+    bl      Printf
+configEDO0:
+    lis     r20, MCCR1_TYPE_EDO@h
+
+getSpdRowBank01:
+    li      r3, 0x0003          /* get number of row bits from */
+                                /* spd from bank0/1 */
+    bl      spdRead
+    ori     r20, r20, (MCCR1_BK0_9BITS | MCCR1_BK1_9BITS)
+    cmpli   0, 0, r3, 0x0009    /* bank0 -  9 row bits */
+    beq     getSpdRowBank23
+
+    ori     r20, r20, (MCCR1_BK0_10BITS | MCCR1_BK1_10BITS)
+    cmpli   0, 0, r3, 0x000a    /* bank0 -  10 row bits */
+    beq     getSpdRowBank23
+
+    ori     r20, r20, (MCCR1_BK0_11BITS | MCCR1_BK1_11BITS)
+    cmpli   0, 0, r3, 0x000b    /* bank0 -  11 row bits */
+    beq     getSpdRowBank23
+
+    ori     r20, r20, (MCCR1_BK0_12BITS | MCCR1_BK1_12BITS)
+    cmpli   0, 0, r3, 0x000c    /* bank0 -  12 row bits */
+    beq     getSpdRowBank23
+
+    cmpli   0, 0, r3, 0x000d    /* bank0 -  13 row bits */
+    beq     getSpdRowBank23
+
+    li      r6, 0xe0            /* error codes in r6 and r7 */
+    li      r7, 0x10
+    b       toggleError         /* fail - loop forever */
+
+getSpdRowBank23:
+    li     r3, 0x0103           /* get number of row bits from */
+                                /* spd for bank2/3 */
+    bl      spdRead
+
+    ori     r20, r20, (MCCR1_BK2_9BITS | MCCR1_BK3_9BITS)
+    cmpli   0, 0, r3, 0x0009    /* bank0 -  9 row bits */
+    beq     writeRowBits
+
+    ori     r20, r20, (MCCR1_BK2_10BITS | MCCR1_BK3_10BITS)
+    cmpli   0, 0, r3, 0x000a    /* bank0 -  10 row bits */
+    beq     writeRowBits
+
+    ori     r20, r20, (MCCR1_BK2_11BITS | MCCR1_BK3_11BITS)
+    cmpli   0, 0, r3, 0x000b    /* bank0 -  11 row bits */
+    beq     writeRowBits
+
+    ori     r20, r20, (MCCR1_BK2_12BITS | MCCR1_BK3_12BITS)
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+writeRowBits:
+    lis     r21, 0x000a         /* CPX = 1, RAS6P = 4 */
+    ori     r21, r21, 0x2293    /* CAS5 = 2, CP4 = 1, */
+                                /* CAS3 = 2, RCD2 = 2, RP = 3 */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+    lis     r22, 0x0010         /* all SDRAM parameter 0, */
+                                /* WCBUF flow through, */
+                                /* RCBUF registered */
+/*
+ * get the size of bank 0-3
+ */
+    li      r3, 0x0003          /* get row bits from spd  bank0/1 */
+    bl      spdRead
+
+    li      r16, 0              /* bank size is: */
+                                /* (8*2^row*2^column)/0x100000 MB */
+    ori     r16, r16, 0x8000
+    rlwnm   r16, r16, r3, 0, 31
+
+    li      r3, 0x0004          /* get column bits from spd bank0/1 */
+    bl      spdRead
+
+    rlwnm   r16, r16, r3, 0, 31
+
+    li      r3, 0x0005          /* get number of banks from */
+                                /* spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     EDOnobank1
+
+    mr      r17, r16
+
+EDOnobank1:
+    addi    r3, r13, (Mspd23-MessageBlock)
+    bl      Printf
+
+    li      r3, 0x0102          /* get RAM type spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x0001    /* FPM ? */
+    bne     noFPM231            /* handle as EDO */
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MfpmRam-MessageBlock)
+    bl      Printf
+    b       EDObank2
+noFPM231:
+    cmpli   0, 0, r3, 0x0002    /* EDO ? */
+    bne     noEDO231
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MedoRam-MessageBlock)
+    bl      Printf
+    b       EDObank2
+noEDO231:
+    cmpli   0, 0, r3, 0x0004    /* SDRAM ? */
+    bne     noSDRAM231
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MsdRam-MessageBlock)
+    bl      Printf
+    b       configRAMcommon
+noSDRAM231:
+    addi    r3, r13, (Mfail-MessageBlock)
+    bl      Printf
+    b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
+
+EDObank2:
+    li      r3, 0x0103          /* get row bits from spd for bank2/3 */
+    bl      spdRead
+
+    li      r18, 0              /* bank size is: */
+                                /* (8*2^row*2^column)/0x100000 MB */
+    ori     r18, r18, 0x8000
+    rlwnm   r18, r18, r3, 0, 31
+
+    li      r3, 0x0104          /* get column bits from spd bank2/3 */
+    bl      spdRead
+
+    rlwnm   r18, r18, r3, 0, 31
+
+    li      r3, 0x0105          /* get number of banks from */
+                                /* spd for bank2/3 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     configRAMcommon
+
+    mr      r19, r18
+
+configRAMcommon:
+    lis     r1, MPC106_REG_ADDR@h
+    ori     r1, r1, MPC106_REG_ADDR@l
+    lis     r2, MPC106_REG_DATA@h
+    ori     r2, r2, MPC106_REG_DATA@l
+
+    li      r0, 0
+
+/*
+ * If we are already running in RAM (debug mode), we should
+ * NOT reset the MEMGO flag. Otherwise we will stop all memory
+ * accesses.
+ */
+#ifdef IN_RAM
+    lis     r4, MCCR1_MEMGO@h
+    ori     r4, r4, MCCR1_MEMGO@l
+    or      r20, r20, r4
+#endif
+
+/*
+ * set the Memory Configuration Reg. 1
+ */
+    lis     r3, MPC106_REG@h        /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
+    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+    eieio                           /* make sure mem. access is complete */
+    stwbrx  r20, r0, r2             /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 3
+ */
+    lis     r3, MPC106_REG@h        /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR3    /* register number 0xf8 */
+    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+    eieio                           /* make sure mem. access is complete */
+    stwbrx    r21, r0, r2           /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+    lis     r3, MPC106_REG@h        /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR4    /* register number 0xfc */
+    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+    eieio                           /* make sure mem. access is complete */
+    stwbrx  r22, r0, r2             /* write data to CONFIG_DATA */
+/*
+ * set the memory boundary registers for bank 0-3
+ */
+    li      r20, 0
+    li      r23, 0
+    li      r24, 0
+    subi    r21, r16, 1         /* calculate end address bank0 */
+    li      r22, (MBER_BANK0)
+
+    cmpi    0, 0, r17, 0        /* bank1 present ? */
+    beq     nobank1
+
+    rlwinm  r3, r16, 8, 16, 23  /* calculate start address of bank1 */
+    or      r20, r20, r3
+    add     r16, r16, r17       /* add to total memory size */
+    subi    r3, r16, 1          /* calculate end address of bank1 */
+    rlwinm  r3, r3, 8, 16, 23
+    or      r21, r21, r3
+    ori     r22, r22, (MBER_BANK1)      /* enable bank1 */
+    b       bank2
+
+nobank1:
+    ori     r23, r23, 0x0300    /* set bank1 start to unused area */
+    ori     r24, r24, 0x0300    /* set bank1 end to unused area */
+
+bank2:
+    cmpi    0, 0, r18, 0        /* bank2 present ? */
+    beq     nobank2
+
+    andi.   r3, r16, 0x00ff     /* calculate start address of bank2 */
+    andi.   r4, r16, 0x0300
+    rlwinm  r3, r3, 16, 8, 15
+    or      r20, r20, r3
+    rlwinm  r3, r4, 8, 8, 15
+    or      r23, r23, r3
+    add     r16, r16, r18       /* add to total memory size */
+    subi    r3, r16, 1          /* calculate end address of bank2 */
+    andi.   r4, r3, 0x0300
+    andi.   r3, r3, 0x00ff
+    rlwinm  r3, r3, 16, 8, 15
+    or      r21, r21, r3
+    rlwinm  r3, r4, 8, 8, 15
+    or      r24, r24, r3
+    ori     r22, r22, (MBER_BANK2)    /* enable bank2 */
+    b       bank3
+
+nobank2:
+    lis     r3, 0x0003
+    or      r23, r23, r3        /* set bank2 start to unused area */
+    or      r24, r24, r3        /* set bank2 end to unused area */
+
+bank3:
+    cmpi    0, 0, r19, 0        /* bank3 present ? */
+    beq     nobank3
+
+    andi.   r3, r16, 0x00ff     /* calculate start address of bank3 */
+    andi.   r4, r16, 0x0300
+    rlwinm  r3, r3, 24, 0, 7
+    or      r20, r20, r3
+    rlwinm  r3, r4, 16, 0, 7
+    or      r23, r23, r3
+    add     r16, r16, r19       /* add to total memory size */
+    subi    r3, r16, 1          /* calculate end address of bank3 */
+    andi.   r4, r3, 0x0300
+    andi.   r3, r3, 0x00ff
+    rlwinm  r3, r3, 24, 0, 7
+    or      r21, r21, r3
+    rlwinm  r3, r4, 16, 0, 7
+    or      r24, r24, r3
+    ori     r22, r22, (MBER_BANK3)    /* enable bank3 */
+    b       writebound
+
+nobank3:
+    lis     r3, 0x0300
+    or      r23, r23, r3        /* set bank3 start to unused area */
+    or      r24, r24, r3        /* set bank3 end to unused area */
+
+writebound:
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MSAR1    /* register number 0x80 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r20, r0, r2         /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MEAR1    /* register number 0x90 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r21, r0, r2         /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMSAR1    /* register number 0x88 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r23, r0, r2         /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMEAR1    /* register number 0x98 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r24, r0, r2         /* write data to CONFIG_DATA */
+
+/*
+ * set boundaries of unused banks to unused address space
+ */
+    lis     r4, 0x0303
+    ori     r4, r4, 0x0303      /* bank 4-7 start and end adresses */
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMSAR2    /* register number 0x8C */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMEAR2    /* register number 0x9C */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */
+
+/*
+ * set the Memory Configuration Reg. 2
+ */
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR2    /* register number 0xf4 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+
+    li      r3, 0x000c          /* get refresh from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    bne     common1
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x20
+    b       toggleError         /* fail - loop forever */
+
+common1:
+    andi.   r15, r3, 0x007f     /* mask selfrefresh bit */
+    li      r3, 0x010c          /* get refresh from spd for bank2/3 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    beq     common2
+    andi.   r3, r3, 0x007f      /* mask selfrefresh bit */
+    cmp     0, 0, r3, r15       /* find the lower */
+    blt     common3
+
+common2:
+    mr      r3, r15
+
+common3:
+    li      r4, 0x1010          /* refesh cycle 1028 clocks */
+                                /*  left shifted 2 */
+    cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x0808          /* refesh cycle 514 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x2020          /* refesh cycle 2056 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x4040          /* refesh cycle 4112 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0004    /* 62.5 us ? */
+    beq     writeRefresh
+
+    li      r4, 0
+    ori     r4, r4, 0x8080      /* refesh cycle 8224 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0005    /* 125 us ? */
+    beq     writeRefresh
+
+    li      r6, 0xe0            /* error codes in r6 and r7 */
+    li      r7, 0x21
+    b       toggleError         /* fail - loop forever */
+
+writeRefresh:
+    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */
+
+/*
+ * DRAM BANKS SHOULD BE ENABLED
+ */
+    addi    r3, r13, (Mactivate-MessageBlock)
+    bl      Printf
+    mr      r3, r16
+    bl      OutDec
+    addi    r3, r13, (Mmbyte-MessageBlock)
+    bl      Printf
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MBER /* register number 0xa0 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stb     r22, 0(r2)          /* write data to CONFIG_DATA */
+    li      r8, 0x63            /* PGMAX = 99 */
+    stb     r8, 3(r2)           /* write data to CONFIG_DATA */
+
+/*
+ *  DRAM SHOULD NOW BE CONFIGURED AND ENABLED
+ *  MUST WAIT 200us BEFORE ACCESSING
+ */
+    li      r0, 0x7800
+    mtctr   r0
+
+wait200us:
+    bdnz    wait200us
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+
+    lwbrx   r4, r0, r2          /* load r4 from CONFIG_DATA */
+
+    lis     r0, MCCR1_MEMGO@h   /* MEMGO=1 */
+    ori     r0, r0, MCCR1_MEMGO@l
+    or      r4, r4, r0          /* set the MEMGO bit */
+    stwbrx  r4, r0, r2          /* write mdfd data to CONFIG_DATA */
+
+    li      r0, 0x7000
+    mtctr   r0
+
+wait8ref:
+    bdnz    wait8ref
+
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+
+    mtlr    r25
+    blr
+
+/*
+ * Infinite loop called in case of an error during RAM initialisation.
+ * error codes in r6 and r7.
+ */
+toggleError:
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError1:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError1
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError2:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError2
+    b       toggleError
+
+
+/******************************************************************************
+ * This function performs a basic initialisation of the superio chip
+ * to enable basic console output and SPD access during RAM initialisation.
+ *
+ * Upon completion, SIO resource registers are mapped as follows:
+ * Resource     Enabled         Address
+ * UART1        Yes             3F8-3FF COM1
+ * UART2        Yes             2F8-2FF COM2
+ * GPIO         Yes             220-227
+ */
+.set    SIO_LUNINDEX, 0x07      /* SIO LUN index register */
+.set    SIO_CNFG1, 0x21         /* SIO configuration #1 register */
+.set    SIO_PCSCI, 0x23         /* SIO PCS configuration index reg */
+.set    SIO_PCSCD, 0x24         /* SIO PCS configuration data reg */
+.set    SIO_ACTIVATE, 0x30      /* SIO activate register */
+.set    SIO_IOBASEHI, 0x60      /* SIO I/O port base address, 15:8 */
+.set    SIO_IOBASELO, 0x61      /* SIO I/O port base address, 7:0 */
+.set    SIO_LUNENABLE, 0x01     /* SIO LUN enable */
+
+.sioInit:
+    mfspr   r7, 8               /* save link register */
+
+.sioInit_87308:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+    lis     r6, CFG_ISA_IO@h
+    ori     r6, r6, CFG_ISA_IO@l
+
+/*
+ * Set offset to base address for config registers.
+ */
+#if defined(CFG_NS87308_BADDR_0x)
+    addi    r4, r0, 0x0279
+#elif defined(CFG_NS87308_BADDR_10)
+    addi    r4, r0, 0x015C
+#elif defined(CFG_NS87308_BADDR_11)
+    addi    r4, r0, 0x002E
+#endif
+    add     r6, r6, r4          /* add offset to base */
+    or      r3, r6, r6          /* make a copy */
+
+/*
+ * PMC (LUN 8)
+ */
+    addi    r4, r0, SIO_LUNINDEX    /* select PMC LUN */
+    addi    r5, r0, 0x8
+    bl      .sio_bw
+    addi    r4, r0, SIO_IOBASEHI    /* initialize PMC address to 0x460 */
+    addi    r5, r0, 0x04
+    bl      .sio_bw
+    addi    r4, r0, SIO_IOBASELO
+    addi    r5, r0, 0x60
+    bl      .sio_bw
+    addi    r4, r0, SIO_ACTIVATE    /* enable PMC */
+    addi    r5, r0, SIO_LUNENABLE
+    bl      .sio_bw
+
+    lis     r8, CFG_ISA_IO@h
+    ori     r8, r8, 0x0460
+    li      r9, 0x03
+    stb     r9, 0(r8)               /* select PMC2 register */
+    eieio
+    li      r9, 0x00
+    stb     r9, 1(r8)               /* SuperI/O clock src: 24MHz via X1 */
+    eieio
+
+/*
+ * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
+ */
+    addi    r4, r0, SIO_LUNINDEX    /* select COM1 LUN */
+    addi    r5, r0, 0x6
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASEHI    /* initialize COM1 address to 0x3F8 */
+    addi    r5, r0, 0x03
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASELO
+    addi    r5, r0, 0xF8
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_ACTIVATE    /* enable COM1 */
+    addi    r5, r0, SIO_LUNENABLE
+    bl      .sio_bw
+
+/*
+ * Init COM1 for polled output
+ */
+    lis     r8, CFG_ISA_IO@h
+    ori     r8, r8, 0x03f8
+    li      r9, 0x00
+    stb     r9, 1(r8)           /* int disabled */
+    eieio
+    li      r9, 0x00
+    stb     r9, 4(r8)           /* modem ctrl */
+    eieio
+    li      r9, 0x80
+    stb     r9, 3(r8)           /* link ctrl, bank select */
+    eieio
+    li      r9, 115200/CONFIG_BAUDRATE
+    stb     r9, 0(r8)           /* baud rate (LSB)*/
+    eieio
+    rotrwi  r9, r9, 8
+    stb     r9, 1(r8)           /* baud rate (MSB) */
+    eieio
+    li      r9, 0x03
+    stb     r9, 3(r8)           /* 8 data bits, 1 stop bit, */
+                                /* no parity */
+    eieio
+    li      r9, 0x0b
+    stb     r9, 4(r8)           /* enable the receiver and transmitter */
+    eieio
+
+waitEmpty:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty
+    li      r9, 0x47
+    stb     r9, 3(r8)           /* send break, 8 data bits, */
+                                /* 2 stop bits, no parity */
+    eieio
+
+    lis     r0, 0x0001
+    mtctr   r0
+
+waitCOM1:
+    lwz     r0, 5(r8)           /* load from port for delay */
+    bdnz    waitCOM1
+
+waitEmpty1:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty1
+    li      r9, 0x07
+    stb     r9, 3(r8)           /* 8 data bits, 2 stop bits, */
+                                /* no parity */
+    eieio
+
+/*
+ * GPIO (LUN 7)
+ */
+    addi    r4, r0, SIO_LUNINDEX    /* select GPIO LUN */
+    addi    r5, r0, 0x7
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASEHI    /* initialize GPIO address to 0x220 */
+    addi    r5, r0, 0x02
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASELO
+    addi    r5, r0, 0x20
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_ACTIVATE    /* enable GPIO */
+    addi    r5, r0, SIO_LUNENABLE
+    bl      .sio_bw
+
+.sioInit_done:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+    lis     r3, CFG_ISA_IO@h
+    ori     r3, r3, CFG_ISA_IO@l
+
+    addi    r3, r3, 0x015C      /* adjust to superI/O 87308 base */
+    or      r6, r3, r3          /* make a copy */
+/*
+ * CS0
+ */
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x01
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x76
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x02
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x40
+    bl      .sio_bw
+/*
+ * CS1
+ */
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x05
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x05
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x70
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x06
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x1C
+    bl      .sio_bw
+/*
+ * CS2
+ */
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x08
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x09
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x71
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x0A
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x1C
+    bl      .sio_bw
+
+    mtspr   8, r7               /* restore link register */
+    bclr    20, 0               /* return to caller */
+
+/*
+ * this function writes a register to the SIO chip
+ */
+.sio_bw:
+    stb     r4, 0(r3)           /* write index register with register offset */
+    eieio
+    sync
+    stb     r5, 1(r3)           /* 1st write */
+    eieio
+    sync
+    stb     r5, 1(r3)           /* 2nd write */
+    eieio
+    sync
+    bclr    20, 0               /* return to caller */
+/*
+ * this function reads a register from the SIO chip
+ */
+.sio_br:
+    stb     r4, 0(r3)           /* write index register with register offset */
+    eieio
+    sync
+    lbz     r3, 1(r3)           /* retrieve specified reg offset contents */
+    eieio
+    sync
+    bclr    20, 0               /* return to caller */
+
+/*
+ * Print a message to COM1 in polling mode
+ * r10=COM1 port, r3=(char*)string
+ */
+.globl Printf
+Printf:
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+
+WaitChr:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, WaitChr        /* wait till empty */
+    lbzx    r0, r0, r3          /* get char */
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addi    r3, r3, 1           /* next char */
+    lbzx    r0, r0, r3          /* get char */
+    cmpwi   cr1, r0, 0          /* end of string ? */
+    bne     cr1, WaitChr
+    blr
+
+/*
+ * Print 8/4/2 digits hex value to COM1 in polling mode
+ * r10=COM1 port, r3=val
+ */
+OutHex2:
+    li      r9, 4               /* shift reg for 2 digits */
+    b       OHstart
+OutHex4:
+    li      r9, 12              /* shift reg for 4 digits */
+    b       OHstart
+    .globl OutHex
+OutHex:
+    li      r9, 28              /* shift reg for 8 digits */
+OHstart:
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+OutDig:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDig
+    sraw    r0, r3, r9
+    clrlwi  r0, r0, 28
+    cmpwi   cr1, r0, 9
+    ble     cr1, digIsNum
+    addic   r0, r0, 55
+    b       nextDig
+digIsNum:
+    addic   r0, r0, 48
+nextDig:
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addic.  r9, r9, -4
+    bge     OutDig
+    blr
+/*
+ * Print 3 digits hdec value to COM1 in polling mode
+ * r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch
+ */
+.globl OutDec
+OutDec:
+    li      r6, 10
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r9 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r9, r10, r3
+
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r8 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r8, r10, r3
+
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r7 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r7, r10, r3
+
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+
+    or.     r7, r7, r7
+    bne     noblank1
+    li      r3, 0x20
+    b       OutDec4
+
+noblank1:
+    addi    r3, r7, 48          /* convert to ASCII */
+
+OutDec4:
+    lbz     r0, 0(r13)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec4
+    stb     r3, 0(r10)          /* x00 to transmit */
+    eieio
+
+    or.     r7, r7, r8
+    beq     OutDec5
+
+    addi    r3, r8, 48          /* convert to ASCII */
+OutDec5:
+    lbz     r0, 0(r13)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec5
+    stb     r3, 0(r10)          /* x0  to transmit */
+    eieio
+
+    addi    r3, r9, 48          /* convert to ASCII */
+OutDec6:
+    lbz     r0, 0(r13)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec6
+    stb     r3, 0(r10)          /* x   to transmit */
+    eieio
+    blr
+/*
+ * Print a char to COM1 in polling mode
+ * r10=COM1 port, r3=char
+ */
+.globl    OutChr
+OutChr:
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+
+OutChr1:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutChr1        /* wait till empty */
+    stb     r3, 0(r10)          /* write to transmit reg */
+    eieio
+    blr
+/*
+ * Input:  r3 adr to read
+ * Output: r3 val or -1 for error
+ */
+spdRead:
+    mfspr   r26, 8              /* save link register */
+
+    lis     r30, CFG_ISA_IO@h
+    ori     r30, r30, 0x220     /* GPIO Port 1 */
+    li      r7, 0x00
+    li      r8, 0x100
+    and.    r5, r3, r8
+    beq     spdbank0
+    li      r12, 0x08
+    li      r4, 0x10
+    li      r6, 0x18
+    b       spdRead1
+
+spdbank0:
+    li      r12, 0x20           /* set I2C data */
+    li      r4, 0x40            /* set I2C clock */
+    li      r6, 0x60            /* set I2C clock and data */
+
+spdRead1:
+    li      r8, 0x80
+
+    bl      spdStart            /* access I2C bus as master */
+    li      r10, 0xa0           /* write to SPD */
+    bl      spdWriteByte
+    bl      spdReadAck          /* ACK returns in r10 */
+    cmpw    cr0, r10, r7
+    bne     AckErr              /* r10 must be 0, if ACK received */
+    mr      r10, r3             /* adr to read */
+    bl      spdWriteByte
+    bl      spdReadAck
+    cmpw    cr0, r10, r7
+    bne     AckErr
+    bl      spdStart
+    li      r10, 0xa1           /* read from SPD */
+    bl      spdWriteByte
+    bl      spdReadAck
+    cmpw    cr0, r10, r7
+    bne     AckErr
+    bl      spdReadByte         /* return val in r10 */
+    bl      spdWriteAck
+    bl      spdStop             /* release I2C bus */
+    mr      r3, r10
+    mtspr   8, r26              /* restore link register */
+    blr
+/*
+ * ACK error occurred
+ */
+AckErr:
+    bl      spdStop
+    orc     r3, r0, r0          /* return -1 */
+    mtspr   8, r26              /* restore link register */
+    blr
+
+/*
+ * Routines to read from RAM spd.
+ * r30 - GPIO Port1 address in all cases.
+ * r4 - clock mask for SPD
+ * r6 - port mask for SPD
+ * r12 - data mask for SPD
+ */
+waitSpd:
+    li      r0, 0x1000
+    mtctr   r0
+wSpd:
+    bdnz    wSpd
+    bclr    20, 0               /* return to caller */
+
+/*
+ * establish START condition on I2C bus
+ */
+spdStart:
+    mfspr   r27, 8              /* save link register */
+    stb     r6, 0(r30)          /* set SDA and SCL */
+    eieio
+    stb     r6, 1(r30)          /* switch GPIO to output */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* reset SDA */
+    eieio
+    bl      waitSpd
+    stb     r7, 0(r30)          /* reset SCL */
+    eieio
+    bl      waitSpd
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+/*
+ * establish STOP condition on I2C bus
+ */
+spdStop:
+    mfspr   r27, 8              /* save link register */
+    stb     r7, 0(r30)          /* reset SCL and SDA */
+    eieio
+    stb     r6, 1(r30)          /* switch GPIO to output */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* set SCL */
+    eieio
+    bl      waitSpd
+    stb     r6, 0(r30)          /* set SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r7, 1(r30)          /* switch GPIO to input */
+    eieio
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+spdReadByte:
+    mfspr   r27, 8
+    stb     r4, 1(r30)          /* set GPIO for SCL output */
+    eieio
+    li      r9, 0x08
+    li      r10, 0x00
+loopRB:
+    stb     r7, 0(r30)          /* reset SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* set SCL */
+    eieio
+    bl      waitSpd
+    lbz     r5, 0(r30)          /* read from GPIO Port1 */
+    rlwinm  r10, r10, 1, 0, 31
+    and.    r5, r5, r12
+    beq     clearBit
+    ori     r10, r10, 0x01      /* append _1_ */
+clearBit:
+    stb     r7, 0(r30)          /* reset SCL */
+    eieio
+    bl      waitSpd
+    addic.  r9, r9, -1
+    bne     loopRB
+    mtspr   8, r27
+    bclr    20, 0               /* return (r10) to caller */
+
+/*
+ * spdWriteByte writes bits 24 - 31 of r10 to I2C.
+ * r8 contains bit mask 0x80
+ */
+spdWriteByte:
+    mfspr   r27, 8              /* save link register */
+    li      r9, 0x08            /* write octet */
+    and.    r5, r10, r8
+    bne     sWB1
+    stb     r7, 0(r30)          /* set SDA to _0_ */
+    eieio
+    b       sWB2
+sWB1:
+    stb     r12, 0(r30)         /* set SDA to _1_ */
+    eieio
+sWB2:
+    stb     r6, 1(r30)          /* set GPIO to output */
+    eieio
+loopWB:
+    and.    r5, r10, r8
+    bne     sWB3
+    stb     r7, 0(r30)          /* set SDA to _0_ */
+    eieio
+    b       sWB4
+sWB3:
+    stb     r12, 0(r30)         /* set SDA to _1_ */
+    eieio
+sWB4:
+    bl      waitSpd
+    and.    r5, r10, r8
+    bne     sWB5
+    stb     r4, 0(r30)          /* set SDA to _0_ and SCL */
+    eieio
+    b       sWB6
+sWB5:
+    stb     r6, 0(r30)          /* set SDA to _1_ and SCL */
+    eieio
+sWB6:
+    bl      waitSpd
+    and.    r5, r10, r8
+    bne     sWB7
+    stb     r7, 0(r30)          /* set SDA to _0_ and reset SCL */
+    eieio
+    b       sWB8
+sWB7:
+    stb     r12, 0(r30)         /* set SDA to _1_ and reset SCL */
+    eieio
+sWB8:
+    bl      waitSpd
+    rlwinm  r10, r10, 1, 0, 31  /* next bit */
+    addic.  r9, r9, -1
+    bne     loopWB
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+/*
+ * Read ACK from SPD, return value in r10
+ */
+spdReadAck:
+    mfspr   r27, 8              /* save link register */
+    stb     r4, 1(r30)          /* set GPIO to output */
+    eieio
+    stb     r7, 0(r30)          /* reset SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* set SCL */
+    eieio
+    bl      waitSpd
+    lbz     r10, 0(r30)         /* read GPIO Port 1 and mask SDA */
+    and     r10, r10, r12
+    bl      waitSpd
+    stb     r7, 0(r30)          /* reset SDA and SCL */
+    eieio
+    bl      waitSpd
+    mtspr   8, r27
+    bclr    20, 0               /* return (r10) to caller */
+
+spdWriteAck:
+    mfspr   r27, 8
+    stb     r12, 0(r30)         /* set SCL */
+    eieio
+    stb     r6, 1(r30)          /* set GPIO to output */
+    eieio
+    bl      waitSpd
+    stb     r6, 0(r30)          /* SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r12, 0(r30)         /* reset SCL */
+    eieio
+    bl      waitSpd
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+get_lnk_reg:
+    mflr    r3                  /* return link reg */
+    blr
+
+/*
+ * Messages for console output
+ */
+.globl MessageBlock
+MessageBlock:
+Mok:
+    .ascii  "OK\015\012\000"
+Mfail:
+    .ascii  "FAILED\015\012\000"
+Mna:
+    .ascii  "NA\015\012\000"
+MinitLogo:
+    .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
+    .ascii  "\015\012Initialising RAM\015\012\000"
+Mspd01:
+    .ascii  "       Reading SPD of bank0/1 ..... \000"
+Mspd23:
+    .ascii  "       Reading SPD of bank2/3 ..... \000"
+MfpmRam:
+    .ascii  "       RAM-Type: FPM \015\012\000"
+MedoRam:
+    .ascii  "       RAM-Type: EDO \015\012\000"
+MsdRam:
+    .ascii  "       RAM-Type: SDRAM \015\012\000"
+Mactivate:
+    .ascii  "       Activating \000"
+Mmbyte:
+    .ascii  " MB .......... \000"
+    .align  4
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/board/eltec/bab7xx/el_srom.c b/board/eltec/bab7xx/el_srom.c
new file mode 100644
index 0000000..56abdc7
--- /dev/null
+++ b/board/eltec/bab7xx/el_srom.c
@@ -0,0 +1,292 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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 "srom.h"
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  START sequence
+ *        _ _________
+ *  SCLK  _>         \____
+ *        _ ____
+ *  SDIO  _>    \_________
+ *         :    :    :
+ */
+static void eepStart (void)
+{
+    out8(I2C_BUS_DAT, 0x60);     /* SCLK = high  SDIO = high */
+    out8(I2C_BUS_DIR, 0x60);     /* set output direction for SCLK/SDIO */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x40);     /* SCLK = high  SDIO = low */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x00);     /* SCLK = low   SDIO = low */
+    udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  STOP sequence
+ *              _______
+ *  SCLK  _____/
+ *        _         ___
+ *  SDIO  _>_______/
+ *         :   :   :
+ */
+static void eepStop (void)
+{
+    out8(I2C_BUS_DAT, 0x00);      /* SCLK = low   SDIO = low */
+    out8(I2C_BUS_DIR, 0x60);      /* set output direction for SCLK/SDIO */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x40);      /* SCLK = high  SDIO = low */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x60);      /* SCLK = high  SDIO = high */
+    udelay(10);
+    out8(I2C_BUS_DIR, 0x00);      /* reset to input direction */
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Read one byte from EEPROM
+ *            ___     ___     ___     ___     ___     ___     ___     ___
+ *  SCLK  ___/   \___/   \___/   \___/   \___/   \___/   \___/   \___/   \
+ *        _________________________________________________________________
+ *  SDIO  >     ^       ^       ^       ^       ^       ^       ^       ^
+ *        :  :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :
+ */
+static unsigned char eepReadByte (void)
+{
+    register unsigned char buf = 0x00;
+    register int i;
+
+    out8(I2C_BUS_DIR, 0x40);
+
+    for (i = 0; i < 8; i++)
+    {
+        out8(I2C_BUS_DAT, 0x00);    /* SCLK = low   SDIO = high */
+        udelay(10);
+        out8(I2C_BUS_DAT, 0x40);    /* SCLK = high  SDIO = high */
+        udelay(15);
+        buf <<= 1;
+        buf = (in8(I2C_BUS_DAT) & 0x20) ? (buf | 0x01) : (buf & 0xFE);
+        out8(I2C_BUS_DAT, 0x00);    /* SCLK = low   SDIO = high */
+        udelay(10);
+    }
+    return(buf);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Write one byte to EEPROM
+ *           ___     ___     ___     ___     ___     ___     ___     ___
+ *  SCLK  __/   \___/   \___/   \___/   \___/   \___/   \___/   \___/   \__
+ *         _______ _______ _______ _______ _______ _______ _______ ________
+ *  SDIO  X_______X_______X_______X_______X_______X_______X_______X________
+ *      :   7   :   6   :   5   :   4   :   3   :   2   :   1   :   0
+ */
+static void eepWriteByte (register unsigned char buf)
+{
+    register int    i;
+
+    (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00);     /* SCLK = low   SDIO = data */
+    out8(I2C_BUS_DIR, 0x60);
+
+    for (i = 7; i >= 0; i--)
+    {
+        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low  SDIO=data */
+        udelay(10);
+        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK=high SDIO=data */
+        udelay(15);
+        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low  SDIO=data */
+        udelay(10);
+        buf <<= 1;
+    }
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Read data acknowledge of EEPROM
+ *             _______
+ *  SCLK  ____/       \___
+ *         _______________
+ *  SDIO  >
+ *        :   :   ^   :
+ */
+static int eepReadAck (void)
+{
+    int retval;
+
+    out8(I2C_BUS_DIR, 0x40);
+    out8(I2C_BUS_DAT, 0x00);            /* SCLK = low   SDIO = high */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x40);            /* SCLK = high  SDIO = high */
+    udelay(10);
+    retval = (in8(I2C_BUS_DAT) & 0x20) ? ERROR : 0;
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x00);            /* SCLK = low   SDIO = high */
+    udelay(10);
+
+    return(retval);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Write data acknowledge to EEPROM
+ *             _______
+ *  SCLK  ____/       \___
+ *
+ *  SDIO  >_______________
+ *        :   :       :
+ */
+static void eepWriteAck (unsigned char ack)
+{
+    ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low   SDIO = ack */
+    out8(I2C_BUS_DIR, 0x60);
+    udelay(10);
+    ack ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK = high  SDIO = ack */
+    udelay(15);
+    ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low   SDIO = ack */
+    udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read bytes from EEPROM
+ */
+int el_srom_load (addr, buf, cnt, device, block)
+unsigned char addr;
+unsigned char *buf;
+int cnt;
+unsigned char device;
+unsigned char block;
+{
+    register int i;
+
+    for (i=0;i<cnt;i++)
+    {
+        eepStart();
+        eepWriteByte(0xA0 | device | block);
+        if (eepReadAck() == ERROR)
+        {
+           eepStop();
+            return(ERROR);
+        }
+        eepWriteByte(addr++);
+        if (eepReadAck() == ERROR)
+        {
+            eepStop();
+            return(ERROR);
+        }
+        eepStart();
+
+        eepWriteByte(0xA1 | device | block);
+        if (eepReadAck() == ERROR)
+        {
+            eepStop();
+            return(ERROR);
+        }
+
+        *buf++ = eepReadByte();
+        eepWriteAck(1);
+        eepStop();
+
+        if ((addr == 0) && (i != (cnt-1)))    /* is it the same block ? */
+        {
+            if (block == FIRST_BLOCK)
+                block = SECOND_BLOCK;
+            else
+                return(ERROR);
+        }
+    }
+    return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *
+ * Write bytes to EEPROM
+ *
+ */
+int el_srom_store (addr, buf, cnt, device, block)
+unsigned char    addr, *buf, device, block;
+int        cnt;
+{
+    register int i, retVal;
+
+    for (i=0;i<cnt;i++)
+    {
+        retVal = ERROR;
+        do
+        {
+            eepStart();
+            eepWriteByte(0xA0 | device | block);
+            if ((retVal = eepReadAck()) == ERROR)
+                eepStop();
+        } while (retVal == ERROR);
+
+        eepWriteByte(addr++);
+        if (eepReadAck() == ERROR)  return(ERROR);
+
+        if ((addr == 0) && (i != (cnt-1)))    /* is it the same block ? */
+        {
+            if (block == FIRST_BLOCK)
+                block = SECOND_BLOCK;
+            else
+            return(ERROR);
+        }
+
+        eepWriteByte(*buf++);
+        if (eepReadAck() == ERROR)
+            return(ERROR);
+
+        eepStop();
+    }
+    return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * calculate checksum for ELTEC revision srom
+ */
+unsigned long el_srom_checksum (ptr, size)
+register unsigned char *ptr;
+unsigned long size;
+{
+    u_long f, accu = 0;
+    u_int  i;
+    u_char byte;
+
+    for (; size; size--)
+    {
+        byte = *ptr++;
+        for (i = 8; i; i--)
+        {
+            f =  ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
+            accu >>= 1; accu ^= f;
+            byte >>= 1;
+        }
+    }
+    return(accu);
+}
+
+/*----------------------------------------------------------------------------*/
diff --git a/board/eltec/bab7xx/u-boot.lds b/board/eltec/bab7xx/u-boot.lds
new file mode 100644
index 0000000..7b10c0d
--- /dev/null
+++ b/board/eltec/bab7xx/u-boot.lds
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/74xx_7xx/start.o	(.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/*    . = env_offset; */
+/*    common/environment.o(.text) */
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/eltec/elppc/asm_init.S b/board/eltec/elppc/asm_init.S
new file mode 100644
index 0000000..a5605b7
--- /dev/null
+++ b/board/eltec/elppc/asm_init.S
@@ -0,0 +1,877 @@
+/*
+ * (C) Copyright 2001 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * ELTEC ELPPC RAM initialization
+ *
+ * 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 <config.h>
+#include <version.h>
+#include <mpc106.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+.globl board_asm_init
+board_asm_init:
+
+/*
+ * setup pointer to message block
+ */
+    mflr    r13                 /* save away link register */
+    bl      get_lnk_reg         /* r3=addr of next instruction */
+    subi    r4, r3, 8           /* r4=board_asm_init addr */
+    addi    r29, r4, (MessageBlock-board_asm_init)
+
+/*
+ * dcache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, HID0_DCE
+    andc    r3, r3, r4
+    mr      r2, r3
+    ori     r3, r3, HID0_DCI
+    sync
+    mtspr   HID0, r3
+    mtspr   HID0, r2
+    isync
+    sync
+/*
+ * icache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, 0
+    ori     r4, r4, HID0_ICE
+    andc    r3, r3, r4
+    sync
+    mtspr   HID0, r3
+/*
+ * invalidate caches
+ */
+    ori     r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
+    or      r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    andc    r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    isync
+/*
+ * icache_enable
+ */
+    mfspr   r3, HID0
+    ori     r3, r3, (HID0_ICE | HID0_ICFI)
+    sync
+    mtspr   HID0, r3
+
+
+/*
+ * setup memory controller
+ */
+    lis     r1, MPC106_REG_ADDR@h
+    ori     r1, r1, MPC106_REG_ADDR@l
+    lis     r2, MPC106_REG_DATA@h
+    ori     r2, r2, MPC106_REG_DATA@l
+
+    /* Configure PICR1 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, PCI_PICR1
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFF14
+    ori     r3, r3, 0x1CC8
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure PICR2 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, PCI_PICR2
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0000
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure EUMBAR */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, 0x0078      /* offest of EUMBAR in PCI config space */
+    stwbrx  r3, 0, r1
+    lis     r3, MPC107_EUMB_ADDR@h
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure Address Map B Option Reg */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, 0x00e0      /* offest of AMBOR in PCI config space */
+    stwbrx  r3, 0, r1
+    lis     r3, 0
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure I2C Controller */
+    lis     r14, MPC107_I2C_ADDR@h  /* base of I2C controller */
+    ori     r14, r14, MPC107_I2C_ADDR@l
+    lis     r3, 0x2b10          /* I2C clock = 100MHz/1024 */
+    stw     r3, 4(r14)
+    li      r3, 0               /* clear arbitration */
+    eieio
+    stw     r3, 12(r14)
+
+    /* Configure MCCR1 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR1
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0660      /* don't set MEMGO now ! */
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure MCCR2 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR2
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0400
+    ori     r3, r3, 0x1800
+    eieio
+    stwbrx  r3, 0, r2
+
+
+    /* Configure MCCR3 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR3
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0230
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure MCCR4 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR4
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x2532
+    ori     r3, r3, 0x2220
+    eieio
+    stwbrx  r3, 0, r2
+
+/*
+ * configure memory interface (MICRs)
+ */
+    addis   r3, r0, 0x8000      /* ADDR_80 */
+    ori     r3, r3, 0x0080      /* SMEMADD1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0x4000
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_84 */
+    ori     r3, r3, 0x0084      /* SMEMADD2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0xFFFF
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_88 */
+    ori     r3, r3, 0x0088      /* EXTSMEM1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_8C */
+    ori     r3, r3, 0x008c      /* EXTSMEM2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0303
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_90 */
+    ori     r3, r3, 0x0090      /* EMEMADD1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0x7F3F
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_94 */
+    ori     r3, r3, 0x0094      /* EMEMADD2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0xFFFF
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_98 */
+    ori     r3, r3, 0x0098      /* EXTEMEM1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_9C */
+    ori     r3, r3, 0x009c      /* EXTEMEM2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0303
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_A0 */
+    ori     r3, r3, 0x00a0      /* MEMBNKEN */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0000
+    ori     r3, r3, 0x0003
+    eieio
+    stwbrx  r3, 0, r2
+
+/*
+ * must wait at least 100us after HRESET to issue a MEMGO
+ */
+    lis     r0, 1
+    mtctr   r0
+memStartWait:
+    bdnz    memStartWait
+
+/*
+ * enable RAM Operations through MCCR1 (MEMGO)
+ */
+    lis     r3, 0x8000
+    ori     r3, r3, 0x00f0
+    stwbrx  r3, r0, r1
+    sync
+    lwbrx   r3, 0, r2
+    lis     r0, 0x0008
+    or      r3, r0, r3
+    stwbrx  r3, 0, r2
+    sync
+
+/*
+ * set LEDs first time
+ */
+    li      r3, 0x1
+    lis     r30, CFG_USR_LED_BASE@h
+    stb     r3, 2(r30)
+    sync
+
+/*
+ * init COM1 for polled output
+ */
+    lis     r8, CFG_NS16550_COM1@h  /* COM1 base address*/
+    ori     r8, r8, CFG_NS16550_COM1@l
+    li      r9, 0x00
+    stb     r9, 1(r8)           /* int disabled */
+    eieio
+    li      r9, 0x00
+    stb     r9, 4(r8)           /* modem ctrl */
+    eieio
+    li      r9, 0x80
+    stb     r9, 3(r8)           /* link ctrl */
+    eieio
+    li      r9, (CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE)
+    stb     r9, 0(r8)           /* baud rate (LSB)*/
+    eieio
+    li      r9, ((CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8)
+    stb     r9, 1(r8)           /* baud rate (MSB) */
+    eieio
+    li      r9, 0x07
+    stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */
+    eieio
+    li      r9, 0x0b
+    stb     r9, 4(r8)           /* enable the receiver and transmitter (modem ctrl) */
+    eieio
+waitEmpty:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty
+    li      r9, 0x47
+    stb     r9, 3(r8)           /* send break, 8 data bits, 2 stop bit, no parity */
+    eieio
+
+    lis     r0, 0x0001
+    mtctr   r0
+waitCOM1:
+    lwz     r0, 5(r8)           /* load from port for delay */
+    bdnz    waitCOM1
+
+waitEmpty1:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty1
+    li      r9, 0x07
+    stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */
+    eieio
+
+/*
+ * intro message from message block
+ */
+    addi    r3, r29, (MnewLine-MessageBlock)
+    bl      Printf
+    addi    r3, r29, (MinitLogo-MessageBlock)
+    bl      Printf
+
+/*
+ * memory cofiguration using SPD information stored on the SODIMMs
+ */
+    addi    r3, r29, (Mspd01-MessageBlock)
+    bl      Printf
+
+    li      r17, 0
+
+    li      r3, 0x0002          /* get RAM type from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    bne     noSpdError
+
+    addi    r3, r29, (Mfail-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xe             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+
+noSpdError:
+    mr      r15, r3             /* save r3 */
+
+    addi    r3, r29, (Mok-MessageBlock)
+    bl      Printf
+
+    cmpli   0, 0, r15, 0x0004   /* SDRAM ? */
+    beq     isSDRAM
+
+    addi    r3, r29, (MramTyp-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xd             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+
+isSDRAM:
+    li      r3, 0x0012          /* get supported CAS latencies from byte 18 */
+    bl      spdRead
+    mr      r15, r3
+    li      r3, 0x09
+    andi.   r0, r15, 0x04
+    bne     maxCLis3
+    li      r3, 0x17
+maxCLis3:
+    andi.   r0, r15, 0x02
+    bne     CL2
+
+    addi    r3, r29, (MramTyp-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xc             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+CL2:
+    bl      spdRead
+    cmpli   0, 0, r3, 0xa1      /* cycle time must be 10ns max. */
+    blt     speedOk
+
+    addi    r3, r29, (MramTyp-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xb             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+speedOk:
+    lis     r20, 0x06e8         /* preset MCR1 value */
+
+    li      r3, 0x0011          /* get number of internal banks from spd for bank0/1 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x02
+    beq     SD_2B
+    cmpli   0, 0, r3, 0x04
+    beq     SD_4B
+memConfErr:
+    addi    r3, r29, (MramConfErr-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xa             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+
+SD_2B:
+    li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */
+    bl      spdRead
+    cmpli   0, 0, r3, 0x0b
+    beq     row11x2
+    cmpli   0, 0, r3, 0x0c
+    beq     row12x2or13x2
+    cmpli   0, 0, r3, 0x0d
+    beq     row12x2or13x2
+    b       memConfErr
+SD_4B:
+    li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */
+    bl      spdRead
+    cmpli   0, 0, r3, 0x0b
+    beq     row11x4or12x4
+    cmpli   0, 0, r3, 0x0c
+    beq     row11x4or12x4
+    cmpli   0, 0, r3, 0x0d
+    beq     row13x4
+    b       memConfErr
+row12x2or13x2:
+    ori     r20, r20, 0x05
+    b       row11x4or12x4
+row13x4:
+    ori     r20, r20, 0x0a
+    b       row11x4or12x4
+row11x2:
+    ori     r20, r20, 0x0f
+row11x4or12x4:
+    /* get the size of bank 0-1 */
+
+    li      r3, 0x001f          /* get bank size from spd for bank0/1 */
+    bl      spdRead
+
+    rlwinm  r16, r3, 2, 24, 29  /* calculate size in MByte (128 MB max.) */
+
+    li      r3, 0x0005          /* get number of banks from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     SDRAMnobank1
+
+    mr      r17, r16
+
+SDRAMnobank1:
+    li      r3, 0x000c          /* get refresh from spd for bank0/1 */
+    bl      spdRead
+    andi.   r3, r3, 0x007f      /* mask selfrefresh bit */
+    li      r4, 0x1800          /* refesh cycle 1536 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x0c00          /* refesh cycle 768 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x3000          /* refesh cycle 3072 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x6000          /* refesh cycle 6144 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0004    /* 62.5 us ? */
+    beq     writeRefresh
+
+    li      r4, 0
+    ori     r4, r4, 0xc000      /* refesh cycle 8224 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0005    /* 125 us ? */
+    beq     writeRefresh
+
+    b       memConfErr
+
+writeRefresh:
+    lis     r21, 0x0400         /* preset MCCR2 value */
+    or      r21, r21, r4
+
+    /* Overwrite MCCR1 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR1
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r20, 0, r2
+
+    /* Overwrite MCCR2 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR2
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r21, 0, r2
+
+    /* set the memory boundary registers for bank 0-3 */
+    li      r20, 0
+    lis     r23, 0x0303
+    lis     r24, 0x0303
+    subi    r21, r16, 1         /* calculate end address bank0 */
+    li      r22, 1
+
+    cmpi    0, 0, r17, 0        /* bank1 present ? */
+    beq     nobank1
+
+    andi.   r3, r16, 0x00ff     /* calculate start address of bank1 */
+    andi.   r4, r16, 0x0300
+    rlwinm  r3, r3, 8, 16, 23
+    or      r20, r20, r3
+    or      r23, r23, r4
+
+    add     r16, r16, r17       /* add to total memory size */
+
+    subi    r3, r16, 1          /* calculate end address of bank1 */
+    andi.   r4, r3, 0x0300
+    andi.   r3, r3, 0x00ff
+    rlwinm  r3, r3, 8, 16, 23
+    or      r21, r21, r3
+    or      r24, r24, r4
+
+    ori     r22, r22, 2         /* enable bank1 */
+    b       bankOk
+nobank1:
+    ori     r23, r23, 0x0300    /* set bank1 start to unused area */
+    ori     r24, r24, 0x0300    /* set bank1 end to unused area */
+bankOk:
+    addi    r3, r29, (Mactivate-MessageBlock)
+    bl      Printf
+    mr      r3, r16
+    bl      OutDec
+    addi    r3, r29, (Mact0123e-MessageBlock)
+    bl      Printf
+
+/*
+ * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1
+ */
+    addis   r3, r0, 0x8000      /* ADDR_80 */
+    ori     r3, r3, 0x0080      /* MSAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r20, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_88 */
+    ori     r3, r3, 0x0088      /* EMSAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r23, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_90 */
+    ori     r3, r3, 0x0090      /* MEAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r21, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_98 */
+    ori     r3, r3, 0x0098      /* EMEAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r24, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_A0 */
+    ori     r3, r3, 0x00a0      /* MBER */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r22, 0, r2
+
+/*
+ * delay to let SDRAM go through several initialization/refresh cycles
+ */
+    lis     r3, 3
+    mtctr   r3
+memStartWait_1:
+    bdnz    memStartWait_1
+    eieio
+
+/*
+ * set LEDs end
+ */
+    li      r3, 0xf
+    lis     r30, CFG_USR_LED_BASE@h
+    stb     r3, 2(r30)
+    sync
+
+    mtlr    r13
+    blr                         /* EXIT board_asm_init ... */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string)
+ */
+
+Printf:
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+WaitChr:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, WaitChr        /* wait till empty */
+    lbzx    r0, r0, r3          /* get char */
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addi    r3, r3, 1           /* next char */
+    lbzx    r0, r0, r3          /* get char */
+    cmpwi   cr1, r0, 0          /* end of string ? */
+    bne     cr1, WaitChr
+    blr
+
+/*
+ * print a char to COM1 in polling mode (r10=COM1 port, r3=char)
+ */
+OutChr:
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+OutChr1:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutChr1        /* wait till empty */
+    stb     r3, 0(r10)          /* write to transmit reg */
+    eieio
+    blr
+
+/*
+ * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val)
+ */
+OutHex2:
+    li      r9, 4               /* shift reg for 2 digits */
+    b       OHstart
+OutHex4:
+    li      r9, 12              /* shift reg for 4 digits */
+    b       OHstart
+OutHex:
+    li      r9, 28              /* shift reg for 8 digits */
+OHstart:
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+OutDig:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDig
+    sraw    r0, r3, r9
+    clrlwi  r0, r0, 28
+    cmpwi   cr1, r0, 9
+    ble     cr1, digIsNum
+    addic   r0, r0, 55
+    b       nextDig
+digIsNum:
+    addic   r0, r0, 48
+nextDig:
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addic.  r9, r9, -4
+    bge     OutDig
+    blr
+
+/*
+ * print 3 digits hdec value to COM1 in polling mode
+ * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch)
+ */
+OutDec:
+    li      r6, 10
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r9 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r9, r10, r3
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r8 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r8, r10, r3
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r7 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r7, r10, r3
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+    or.     r7, r7, r7
+    bne     noblank1
+    li      r3, 0x20
+    b       OutDec4
+noblank1:
+    addi    r3, r7, 48          /* convert to ASCII */
+OutDec4:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec4
+    stb     r3, 0(r10)          /* x00 to transmit */
+    eieio
+    or.     r7, r7, r8
+    beq     OutDec5
+    addi    r3, r8, 48          /* convert to ASCII */
+OutDec5:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec5
+    stb     r3, 0(r10)          /* x0  to transmit */
+    eieio
+    addi    r3, r9, 48          /* convert to ASCII */
+OutDec6:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec6
+    stb     r3, 0(r10)          /* x   to transmit */
+    eieio
+    blr
+
+/*
+ * hang endless loop
+ */
+toggleError:                    /* fail type in r6, r7=0xff, toggle LEDs */
+    stb     r7, 2(r30)          /* r7 to LED */
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError1:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError1
+    stb     r6, 2(r30)          /* r6 to LED */
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError2:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError2
+    b       toggleError
+
+/*
+ * routines to read from ram spd
+ */
+spdWaitIdle:
+    lis     r0, 0x1             /* timeout for about 100us */
+    mtctr   r0
+iSpd:
+    lbz     r10, 12(r14)
+    andi.   r10, r10, 0x20      /* mask and test MBB */
+    beq     idle
+    bdnz    iSpd
+    orc.    r10, r0, r0         /* return -1 to caller */
+idle:
+    bclr    20, 0               /* return to caller */
+
+waitSpd:
+    lis     r0, 0x10            /* timeout for about 1.5ms */
+    mtctr   r0
+wSpd:
+    lbz     r10, 12(r14)
+    andi.   r10, r10, 0x82
+    cmpli   0, 0, r10, 0x82     /* test MCF and MIF set */
+    beq     wend
+    bdnz    wSpd
+    orc.    r10, r0, r0         /* return -1 to caller */
+    bclr    20, 0               /* return to caller */
+
+wend:
+    li      r10, 0
+    stb     r10, 12(r14)        /* clear status */
+    bclr    20, 0               /* return to caller */
+
+/*
+ * spdread
+ * in:  r3 adr to read
+ * out: r3 val or -1 for error
+ * uses r10, assumes that r14 points to I2C controller
+ */
+spdRead:
+    mfspr   r25, 8              /* save link register */
+
+    bl      spdWaitIdle
+    bne     spdErr
+
+    li      r10, 0x80           /* start with MEN */
+    stb     r10, 8(r14)
+    eieio
+
+    li      r10, 0xb0           /* start as master */
+    stb     r10, 8(r14)
+    eieio
+
+    li      r10, 0xa0           /* write device 0xA0 */
+    stb     r10, 16(r14)
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+    lbz     r10, 12(r14)        /* test ACK */
+    andi.   r10, r10, 0x01
+    bne     gotNoAck
+
+    stb     r3, 16(r14)         /* data address */
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+
+    li      r10, 0xb4           /* switch to read - restart */
+    stb     r10, 8(r14)
+    eieio
+
+    li      r10, 0xa1           /* read device 0xA0 */
+    stb     r10, 16(r14)
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+    li      r10, 0xa8           /* no ACK */
+    stb     r10, 8(r14)
+    eieio
+
+    lbz     r10, 16(r14)        /* trigger read next byte */
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+    li      r10, 0x88           /* generate STOP condition */
+    stb     r10, 8(r14)
+    eieio
+
+    lbz     r3, 16(r14)         /* return read byte */
+
+    mtspr   8, r25              /* restore link register */
+    blr
+
+gotNoAck:
+    li      r10, 0x80           /* generate STOP condition */
+    stb     r10, 8(r14)
+    eieio
+spdErr:
+    orc     r3, r0, r0          /* return -1 */
+    mtspr   8, r25              /* restore link register */
+    blr
+
+get_lnk_reg:
+    mflr    r3                  /* return link reg */
+    blr
+
+MessageBlock:
+
+MinitLogo:
+    .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
+    .ascii  "\015\012Initialising RAM\015\012\000"
+Mspd01:
+    .ascii  "       Reading SPD of SODIMM ...... \000"
+MramTyp:
+    .ascii  "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000"
+MramConfErr:
+    .ascii  "\015\012\Unsupported SODIMM Configuration!\015\012\000"
+Mactivate:
+    .ascii  "       Activating \000"
+Mact0123e:
+    .ascii  " MByte.\015\012\000"
+Mok:
+    .ascii  "OK \015\012\000"
+Mfail:
+    .ascii  "FAILED \015\012\000"
+MnewLine:
+    .ascii  "\015\012\000"
+    .align 4
diff --git a/board/eltec/elppc/u-boot.lds b/board/eltec/elppc/u-boot.lds
new file mode 100644
index 0000000..7b10c0d
--- /dev/null
+++ b/board/eltec/elppc/u-boot.lds
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/74xx_7xx/start.o	(.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/*    . = env_offset; */
+/*    common/environment.o(.text) */
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/ep7312/flash.c b/board/ep7312/flash.c
new file mode 100644
index 0000000..373d238
--- /dev/null
+++ b/board/ep7312/flash.c
@@ -0,0 +1,341 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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>
+
+#define FLASH_BANK_SIZE 0x1000000
+#define MAIN_SECT_SIZE  0x20000
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init (void)
+{
+	int i, j;
+	ulong size = 0;
+
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+		ulong flashbase = 0;
+
+		flash_info[i].flash_id =
+				(INTEL_MANUFACT & FLASH_VENDMASK) |
+				(INTEL_ID_28F128J3 & FLASH_TYPEMASK);
+		flash_info[i].size = FLASH_BANK_SIZE;
+		flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+		memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+		if (i == 0)
+			flashbase = PHYS_FLASH_1;
+		else
+			panic ("configured to many flash banks!\n");
+		for (j = 0; j < flash_info[i].sector_count; j++) {
+			flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;
+		}
+		size += flash_info[i].size;
+	}
+
+	/* Protect monitor and environment sectors
+	 */
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_FLASH_BASE,
+			CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
+			&flash_info[0]);
+
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_ENV_ADDR,
+			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+
+	return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+	int i;
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case (INTEL_MANUFACT & FLASH_VENDMASK):
+		printf ("Intel: ");
+		break;
+	default:
+		printf ("Unknown Vendor ");
+		break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
+		printf ("28F128J3 (128Mbit)\n");
+		break;
+	default:
+		printf ("Unknown Chip Type\n");
+		goto Done;
+		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");
+
+  Done:
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+	int flag, prot, sect;
+	int rc = ERR_OK;
+
+	if (info->flash_id == FLASH_UNKNOWN)
+		return ERR_UNKNOWN_FLASH_TYPE;
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		return ERR_INVAL;
+	}
+
+	if ((info->flash_id & FLASH_VENDMASK) !=
+		(INTEL_MANUFACT & FLASH_VENDMASK)) {
+		return ERR_UNKNOWN_FLASH_VENDOR;
+	}
+
+	prot = 0;
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+	if (prot)
+		return ERR_PROTECTED;
+
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	flag = disable_interrupts ();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+
+		printf ("Erasing sector %2d ... ", sect);
+
+		/* arm simple, non interrupt dependent timer */
+		reset_timer_masked ();
+
+		if (info->protect[sect] == 0) {	/* not protected */
+			vu_short *addr = (vu_short *) (info->start[sect]);
+
+			*addr = 0x20;		/* erase setup */
+			*addr = 0xD0;		/* erase confirm */
+
+			while ((*addr & 0x80) != 0x80) {
+				if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+					*addr = 0xB0;	/* suspend erase */
+					*addr = 0xFF;	/* reset to read mode */
+					rc = ERR_TIMOUT;
+					goto outahere;
+				}
+			}
+
+			/* clear status register command */
+			*addr = 0x50;
+			/* reset to read mode */
+			*addr = 0xFF;
+		}
+		printf ("ok.\n");
+	}
+	if (ctrlc ())
+		printf ("User Interrupt!\n");
+
+  outahere:
+
+	/* allow flash to settle - wait 10 ms */
+	udelay_masked (10000);
+
+	if (flag)
+		enable_interrupts ();
+
+	return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_word (flash_info_t * info, ulong dest, ushort data)
+{
+	vu_short *addr = (vu_short *) dest, val;
+	int rc = ERR_OK;
+	int flag;
+
+	/* Check if Flash is (sufficiently) erased
+	 */
+	if ((*addr & data) != data)
+		return ERR_NOT_ERASED;
+
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	flag = disable_interrupts ();
+
+	/* clear status register command */
+	*addr = 0x50;
+
+	/* program set-up command */
+	*addr = 0x40;
+
+	/* latch address/data */
+	*addr = data;
+
+	/* arm simple, non interrupt dependent timer */
+	reset_timer_masked ();
+
+	/* wait while polling the status register */
+	while (((val = *addr) & 0x80) != 0x80) {
+		if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+			rc = ERR_TIMOUT;
+			/* suspend program command */
+			*addr = 0xB0;
+			goto outahere;
+		}
+	}
+
+	if (val & 0x1A) {			/* check for error */
+		printf ("\nFlash write error %02x at address %08lx\n",
+				(int) val, (unsigned long) dest);
+		if (val & (1 << 3)) {
+			printf ("Voltage range error.\n");
+			rc = ERR_PROG_ERROR;
+			goto outahere;
+		}
+		if (val & (1 << 1)) {
+			printf ("Device protect error.\n");
+			rc = ERR_PROTECTED;
+			goto outahere;
+		}
+		if (val & (1 << 4)) {
+			printf ("Programming error.\n");
+			rc = ERR_PROG_ERROR;
+			goto outahere;
+		}
+		rc = ERR_PROG_ERROR;
+		goto outahere;
+	}
+
+  outahere:
+	/* read array command */
+	*addr = 0xFF;
+
+	if (flag)
+		enable_interrupts ();
+
+	return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+	ulong cp, wp;
+	ushort data;
+	int l;
+	int i, rc;
+
+	wp = (addr & ~1);			/* 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 << 8);
+		}
+		for (; i < 2 && cnt > 0; ++i) {
+			data = (data >> 8) | (*src++ << 8);
+			--cnt;
+			++cp;
+		}
+		for (; cnt == 0 && i < 2; ++i, ++cp) {
+			data = (data >> 8) | (*(uchar *) cp << 8);
+		}
+
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += 2;
+	}
+
+	/*
+	 * handle word aligned part
+	 */
+	while (cnt >= 2) {
+		data = *((vu_short *) src);
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		src += 2;
+		wp += 2;
+		cnt -= 2;
+	}
+
+	if (cnt == 0) {
+		return ERR_OK;
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
+		data = (data >> 8) | (*src++ << 8);
+		--cnt;
+	}
+	for (; i < 2; ++i, ++cp) {
+		data = (data >> 8) | (*(uchar *) cp << 8);
+	}
+
+	return write_word (info, wp, data);
+}
diff --git a/board/ep7312/u-boot.lds b/board/ep7312/u-boot.lds
new file mode 100644
index 0000000..0849648
--- /dev/null
+++ b/board/ep7312/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm720t/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/esd/common/fpga.c b/board/esd/common/fpga.c
new file mode 100644
index 0000000..666b490
--- /dev/null
+++ b/board/esd/common/fpga.c
@@ -0,0 +1,262 @@
+/*
+ * (C) Copyright 2001
+ * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef FPGA_DEBUG
+#define DBG(x...) printf(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+#define MAX_ONES               226
+
+#define IBM405GP_GPIO0_OR      0xef600700  /* GPIO Output */
+#define IBM405GP_GPIO0_TCR     0xef600704  /* GPIO Three-State Control */
+#define IBM405GP_GPIO0_ODR     0xef600718  /* GPIO Open Drain */
+#define IBM405GP_GPIO0_IR      0xef60071c  /* GPIO Input */
+
+#ifdef CFG_FPGA_PRG
+# define FPGA_PRG              CFG_FPGA_PRG /* FPGA program pin (ppc output)*/
+# define FPGA_CLK              CFG_FPGA_CLK /* FPGA clk pin (ppc output)    */
+# define FPGA_DATA             CFG_FPGA_DATA /* FPGA data pin (ppc output)  */
+# define FPGA_DONE             CFG_FPGA_DONE /* FPGA done pin (ppc input)   */
+# define FPGA_INIT             CFG_FPGA_INIT /* FPGA init pin (ppc input)   */
+#else
+# define FPGA_PRG              0x04000000  /* FPGA program pin (ppc output) */
+# define FPGA_CLK              0x02000000  /* FPGA clk pin (ppc output)     */
+# define FPGA_DATA             0x01000000  /* FPGA data pin (ppc output)    */
+# define FPGA_DONE             0x00800000  /* FPGA done pin (ppc input)     */
+# define FPGA_INIT             0x00400000  /* FPGA init pin (ppc input)     */
+#endif
+
+#define ERROR_FPGA_PRG_INIT_LOW  -1        /* Timeout after PRG* asserted   */
+#define ERROR_FPGA_PRG_INIT_HIGH -2        /* Timeout after PRG* deasserted */
+#define ERROR_FPGA_PRG_DONE      -3        /* Timeout after programming     */
+
+#define SET_FPGA(data)         out32(IBM405GP_GPIO0_OR, data)
+
+#define FPGA_WRITE_1 {                                                    \
+        SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
+        SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set data to 1  */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* set clock to 1 */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1  */
+
+#define FPGA_WRITE_0 {                                                    \
+        SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
+        SET_FPGA(FPGA_PRG);                         /* set data to 0  */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK);              /* set clock to 1 */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1  */
+
+
+static int fpga_boot(unsigned char *fpgadata, int size)
+{
+  int i,index,len;
+  int count;
+#ifdef CFG_FPGA_SPARTAN2
+  int j;
+#else
+  unsigned char b;
+  int bit;
+#endif
+
+  /* display infos on fpgaimage */
+  index = 15;
+  for (i=0; i<4; i++)
+    {
+      len = fpgadata[index];
+      DBG("FPGA: %s\n", &(fpgadata[index+1]));
+      index += len+3;
+    }
+
+#ifdef CFG_FPGA_SPARTAN2
+  /* search for preamble 0xFFFFFFFF */
+  while (1)
+    {
+      if ((fpgadata[index] == 0xff) && (fpgadata[index+1] == 0xff) &&
+          (fpgadata[index+2] == 0xff) && (fpgadata[index+3] == 0xff))
+        break; /* preamble found */
+      else
+        index++;
+    }
+#else
+  /* search for preamble 0xFF2X */
+  for (index = 0; index < size-1 ; index++)
+    {
+      if ((fpgadata[index] == 0xff) && ((fpgadata[index+1] & 0xf0) == 0x30))
+	break;
+    }
+  index += 2;
+#endif
+
+  DBG("FPGA: configdata starts at position 0x%x\n",index);
+  DBG("FPGA: length of fpga-data %d\n", size-index);
+
+  /*
+   * Setup port pins for fpga programming
+   */
+  out32(IBM405GP_GPIO0_ODR, 0x00000000);                       /* no open drain pins      */
+  out32(IBM405GP_GPIO0_TCR, FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* setup for output        */
+  out32(IBM405GP_GPIO0_OR,  FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* set output pins to high */
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  /*
+   * Init fpga by asserting and deasserting PROGRAM*
+   */
+  SET_FPGA(FPGA_CLK | FPGA_DATA);
+
+  /* Wait for FPGA init line low */
+  count = 0;
+  while (in32(IBM405GP_GPIO0_IR) & FPGA_INIT)
+    {
+      udelay(1000); /* wait 1ms */
+      /* Check for timeout - 100us max, so use 3ms */
+      if (count++ > 3)
+        {
+          DBG("FPGA: Booting failed!\n");
+          return ERROR_FPGA_PRG_INIT_LOW;
+        }
+    }
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  /* deassert PROGRAM* */
+  SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
+
+  /* Wait for FPGA end of init period .  */
+  count = 0;
+  while (!(in32(IBM405GP_GPIO0_IR) & FPGA_INIT))
+    {
+      udelay(1000); /* wait 1ms */
+      /* Check for timeout */
+      if (count++ > 3)
+        {
+          DBG("FPGA: Booting failed!\n");
+          return ERROR_FPGA_PRG_INIT_HIGH;
+        }
+    }
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  DBG("write configuration data into fpga\n");
+  /* write configuration-data into fpga... */
+
+#ifdef CFG_FPGA_SPARTAN2
+  /*
+   * Load uncompressed image into fpga
+   */
+  for (i=index; i<size; i++)
+    {
+      for (j=0; j<8; j++)
+        {
+          if ((fpgadata[i] & 0x80) == 0x80)
+	    {
+              FPGA_WRITE_1;
+	    }
+          else
+	    {
+              FPGA_WRITE_0;
+	    }
+          fpgadata[i] <<= 1;
+        }
+    }
+#else
+  /* send 0xff 0x20 */
+  FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
+  FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
+  FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_1; FPGA_WRITE_0;
+  FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0;
+
+  /*
+  ** Bit_DeCompression
+  **   Code 1           .. maxOnes     : n                 '1's followed by '0'
+  **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0'
+  **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1'
+  **        255                        :                   '1'
+  */
+
+  for (i=index; i<size; i++)
+    {
+      b = fpgadata[i];
+      if ((b >= 1) && (b <= MAX_ONES))
+	{
+	  for(bit=0; bit<b; bit++)
+            {
+              FPGA_WRITE_1;
+            }
+	  FPGA_WRITE_0;
+	}
+      else if (b == (MAX_ONES+1))
+	{
+	  for(bit=1; bit<b; bit++)
+            {
+              FPGA_WRITE_1;
+            }
+	}
+      else if ((b >= (MAX_ONES+2)) && (b <= 254))
+	{
+	  for(bit=0; bit<(b-(MAX_ONES+2)); bit++)
+            {
+              FPGA_WRITE_0;
+            }
+          FPGA_WRITE_1;
+	}
+      else if (b == 255)
+        {
+          FPGA_WRITE_1;
+        }
+    }
+#endif
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  /*
+   * Check if fpga's DONE signal - correctly booted ?
+   */
+
+  /* Wait for FPGA end of programming period .  */
+  count = 0;
+  while (!(in32(IBM405GP_GPIO0_IR) & FPGA_DONE))
+    {
+      udelay(1000); /* wait 1ms */
+      /* Check for timeout */
+      if (count++ > 3)
+        {
+          DBG("FPGA: Booting failed!\n");
+          return ERROR_FPGA_PRG_DONE;
+        }
+    }
+
+  DBG("FPGA: Booting successful!\n");
+  return 0;
+}
diff --git a/board/esd/common/pci.c b/board/esd/common/pci.c
new file mode 100644
index 0000000..f8f180c
--- /dev/null
+++ b/board/esd/common/pci.c
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+
+u_long pci9054_iobase;
+
+
+#define PCI_PRIMARY_CAR	(0x500000dc) /* PCI config address reg */
+#define PCI_PRIMARY_CDR	(0x80000000) /* PCI config data    reg */
+
+
+/*-----------------------------------------------------------------------------+
+|  Subroutine:  pci9054_read_config_dword
+|  Description: Read a PCI configuration register
+|  Inputs:
+|               hose            PCI Controller
+|               dev             PCI Bus+Device+Function number
+|               offset          Configuration register number
+|               value           Address of the configuration register value
+|  Return value:
+|               0               Successful
++-----------------------------------------------------------------------------*/
+int pci9054_read_config_dword(struct pci_controller *hose,
+			      pci_dev_t dev, int offset, u32* value)
+{
+  unsigned long      conAdrVal;
+  unsigned long      val;
+
+  /* generate coded value for CON_ADR register */
+  conAdrVal = dev | (offset & 0xfc) | 0x80000000;
+
+  /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
+  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
+
+  /* Note: *pResult comes back as -1 if machine check happened */
+  val = in32r(PCI_PRIMARY_CDR);
+
+  *value = (unsigned long) val;
+
+  out32r(PCI_PRIMARY_CAR, 0);
+
+  if ((*(unsigned long *)0x50000304) & 0x60000000)
+    {
+      /* clear pci master/target abort bits */
+      *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
+    }
+
+  return 0;
+}
+
+/*-----------------------------------------------------------------------------+
+|  Subroutine:  pci9054_write_config_dword
+|  Description: Write a PCI configuration register.
+|  Inputs:
+|               hose            PCI Controller
+|               dev             PCI Bus+Device+Function number
+|               offset          Configuration register number
+|               Value           Configuration register value
+|  Return value:
+|               0               Successful
+| Updated for pass2 errata #6. Need to disable interrupts and clear the
+| PCICFGADR reg after writing the PCICFGDATA reg.
++-----------------------------------------------------------------------------*/
+int pci9054_write_config_dword(struct pci_controller *hose,
+			       pci_dev_t dev, int offset, u32 value)
+{
+  unsigned long      conAdrVal;
+
+  conAdrVal = dev | (offset & 0xfc) | 0x80000000;
+
+  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
+
+  out32r(PCI_PRIMARY_CDR, value);
+
+  out32r(PCI_PRIMARY_CAR, 0);
+
+  /* clear pci master/target abort bits */
+  *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
+
+  return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+#ifdef CONFIG_DASA_SIM
+static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev,
+					struct pci_config_table *_)
+{
+  unsigned int iobase;
+  unsigned short status = 0;
+  unsigned char timer;
+
+  /*
+   * Configure PLX PCI9054
+   */
+  pci_read_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, &status);
+  status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+  pci_write_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, status);
+
+  /* Check the latency timer for values >= 0x60.
+   */
+  pci_read_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer);
+  if (timer < 0x60)
+    {
+      pci_write_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60);
+    }
+
+  /* Set I/O base register.
+   */
+  pci_write_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CFG_PCI9054_IOBASE);
+  pci_read_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase);
+
+  pci9054_iobase = pci_mem_to_phys(CFG_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK);
+
+  if (pci9054_iobase == 0xffffffff)
+    {
+      printf("Error: Can not set I/O base register.\n");
+      return;
+    }
+}
+#endif
+
+static struct pci_config_table pci9054_config_table[] = {
+#ifndef CONFIG_PCI_PNP
+  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+    PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
+    pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
+				 CFG_ETH_IOBASE,
+				 PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
+#ifdef CONFIG_DASA_SIM
+  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+    PCI_BUS(CFG_PCI9054_DEV_FN), PCI_DEV(CFG_PCI9054_DEV_FN), PCI_FUNC(CFG_PCI9054_DEV_FN),
+    pci_dasa_sim_config_pci9054 },
+#endif
+#endif
+  { }
+};
+
+static struct pci_controller pci9054_hose = {
+  config_table: pci9054_config_table,
+};
+
+void pci_init(void)
+{
+  struct pci_controller *hose = &pci9054_hose;
+
+  /*
+   * Register the hose
+   */
+  hose->first_busno = 0;
+  hose->last_busno = 0xff;
+
+  /* System memory space */
+  pci_set_region(hose->regions + 0,
+		 0x00000000, 0x00000000, 0x01000000,
+		 PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+  /* PCI Memory space */
+  pci_set_region(hose->regions + 1,
+		 0x00000000, 0xc0000000, 0x10000000,
+		 PCI_REGION_MEM);
+
+  pci_set_ops(hose,
+	      pci_hose_read_config_byte_via_dword,
+	      pci_hose_read_config_word_via_dword,
+	      pci9054_read_config_dword,
+	      pci_hose_write_config_byte_via_dword,
+	      pci_hose_write_config_word_via_dword,
+	      pci9054_write_config_dword);
+
+  hose->region_count = 2;
+
+  pci_register_hose(hose);
+
+  hose->last_busno = pci_hose_scan(hose);
+}
diff --git a/board/esd/cpci405/cpci405.c b/board/esd/cpci405/cpci405.c
new file mode 100644
index 0000000..2dda8fa
--- /dev/null
+++ b/board/esd/cpci405/cpci405.c
@@ -0,0 +1,451 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <malloc.h>
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+/* fpga configuration data - generated by bin2cc */
+const unsigned char fpgadata[] =
+{
+#ifdef CONFIG_CPCI405_VER2
+# include "fpgadata_cpci4052.c"
+#else
+# include "fpgadata_cpci405.c"
+#endif
+};
+
+/*
+ * include common fpga code (for esd boards)
+ */
+#include "../common/fpga.c"
+
+
+/* Prototypes */
+int version2(void);
+int gunzip(void *, int, unsigned char *, int *);
+
+
+int board_pre_init (void)
+{
+#ifndef CONFIG_CPCI405_VER2
+	int index, len, i;
+	int status;
+#endif
+
+#ifdef FPGA_DEBUG
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* set up serial port with default baudrate */
+	(void) get_clocks ();
+	gd->baudrate = CONFIG_BAUDRATE;
+	serial_init ();
+	console_init_f();
+#endif
+
+	/*
+	 * First pull fpga-prg pin low, to disable fpga logic (on version 2 board)
+	 */
+	out32(IBM405GP_GPIO0_ODR, 0x00000000);        /* no open drain pins      */
+	out32(IBM405GP_GPIO0_TCR, CFG_FPGA_PRG);      /* setup for output        */
+	out32(IBM405GP_GPIO0_OR,  CFG_FPGA_PRG);      /* set output pins to high */
+	out32(IBM405GP_GPIO0_OR, 0);                  /* pull prg low            */
+
+	/*
+	 * Boot onboard FPGA
+	 */
+#ifndef CONFIG_CPCI405_VER2
+	if (!version2()) {
+		status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata));
+		if (status != 0) {
+			/* booting FPGA failed */
+#ifndef FPGA_DEBUG
+			DECLARE_GLOBAL_DATA_PTR;
+
+			/* set up serial port with default baudrate */
+			(void) get_clocks ();
+			gd->baudrate = CONFIG_BAUDRATE;
+			serial_init ();
+			console_init_f();
+#endif
+			printf("\nFPGA: Booting failed ");
+			switch (status) {
+			case ERROR_FPGA_PRG_INIT_LOW:
+				printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_INIT_HIGH:
+				printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_DONE:
+				printf("(Timeout: DONE not high after programming FPGA)\n ");
+				break;
+			}
+
+			/* display infos on fpgaimage */
+			index = 15;
+			for (i=0; i<4; i++) {
+				len = fpgadata[index];
+				printf("FPGA: %s\n", &(fpgadata[index+1]));
+				index += len+3;
+			}
+			putc ('\n');
+			/* delayed reboot */
+			for (i=20; i>0; i--) {
+				printf("Rebooting in %2d seconds \r",i);
+				for (index=0;index<1000;index++)
+					udelay(1000);
+			}
+			putc ('\n');
+			do_reset(NULL, 0, 0, NULL);
+		}
+	}
+#endif /* !CONFIG_CPCI405_VER2 */
+
+	/*
+	 * IRQ 0-15  405GP internally generated; active high; level sensitive
+	 * IRQ 16    405GP internally generated; active low; level sensitive
+	 * IRQ 17-24 RESERVED
+	 * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
+	 * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052) ; active low; level sensitive
+	 * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
+	 * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
+	 * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+	 * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
+	 * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
+	 */
+	mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
+	mtdcr(uicer, 0x00000000);       /* disable all ints */
+	mtdcr(uiccr, 0x00000000);       /* set all to be non-critical*/
+	mtdcr(uicpr, 0xFFFFFF81);       /* set int polarities */
+	mtdcr(uictr, 0x10000000);       /* set int trigger levels */
+	mtdcr(uicvcr, 0x00000001);      /* set vect base=0,INT0 highest priority*/
+	mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int ctermm2(void)
+{
+#ifdef CONFIG_CPCI405_VER2
+	return 0;                       /* no, board is cpci405 */
+#else
+	if ((*(unsigned char *)0xf0000400 == 0x00) &&
+	    (*(unsigned char *)0xf0000401 == 0x01))
+		return 0;               /* no, board is cpci405 */
+	else
+		return -1;              /* yes, board is cterm-m2 */
+#endif
+}
+
+
+int cpci405_host(void)
+{
+	if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+		return -1;              /* yes, board is cpci405 host */
+	else
+		return 0;               /* no, board is cpci405 adapter */
+}
+
+
+int version2(void)
+{
+	unsigned long cntrl0Reg;
+	unsigned long value;
+
+	/*
+	 * Setup GPIO pins (CS2/GPIO11 as GPIO)
+	 */
+	cntrl0Reg = mfdcr(cntrl0);
+	mtdcr(cntrl0, cntrl0Reg | 0x02000000);
+
+	udelay(1000);                   /* wait some time before reading input */
+	value = in32(IBM405GP_GPIO0_IR) & 0x00100000; /* test GPIO11 */
+
+	/*
+	 * Setup GPIO pins (CS2/GPIO11 as CS again)
+	 */
+	mtdcr(cntrl0, cntrl0Reg);
+
+	if (value)
+		return 0;               /* no, board is version 1.x */
+	else
+		return -1;              /* yes, board is version 2.x */
+}
+
+
+int misc_init_f (void)
+{
+	return 0;  /* dummy implementation */
+}
+
+
+int misc_init_r (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	bd_t *bd = gd->bd;
+	char *	tmp;                    /* Temporary char pointer      */
+
+#ifdef CONFIG_CPCI405_VER2
+	unsigned char *dst;
+	ulong len = sizeof(fpgadata);
+	int status;
+	int index;
+	int i;
+	unsigned long cntrl0Reg;
+
+	/*
+	 * On CPCI-405 version 2 the environment is saved in eeprom!
+	 * FPGA can be gzip compressed (malloc) and booted this late.
+	 */
+
+	if (version2()) {
+		/*
+		 * Setup GPIO pins (CS6+CS7 as GPIO)
+		 */
+		cntrl0Reg = mfdcr(cntrl0);
+		mtdcr(cntrl0, cntrl0Reg | 0x00300000);
+
+		dst = malloc(CFG_FPGA_MAX_SIZE);
+		if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
+			printf ("GUNZIP ERROR - must RESET board to recover\n");
+			do_reset (NULL, 0, 0, NULL);
+		}
+
+		status = fpga_boot(dst, len);
+		if (status != 0) {
+			printf("\nFPGA: Booting failed ");
+			switch (status) {
+			case ERROR_FPGA_PRG_INIT_LOW:
+				printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_INIT_HIGH:
+				printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_DONE:
+				printf("(Timeout: DONE not high after programming FPGA)\n ");
+				break;
+			}
+
+			/* display infos on fpgaimage */
+			index = 15;
+			for (i=0; i<4; i++) {
+				len = dst[index];
+				printf("FPGA: %s\n", &(dst[index+1]));
+				index += len+3;
+			}
+			putc ('\n');
+			/* delayed reboot */
+			for (i=20; i>0; i--) {
+				printf("Rebooting in %2d seconds \r",i);
+				for (index=0;index<1000;index++)
+					udelay(1000);
+			}
+			putc ('\n');
+			do_reset(NULL, 0, 0, NULL);
+		}
+
+		/* restore gpio/cs settings */
+		mtdcr(cntrl0, cntrl0Reg);
+
+		puts("FPGA:  ");
+
+		/* display infos on fpgaimage */
+		index = 15;
+		for (i=0; i<4; i++) {
+			len = dst[index];
+			printf("%s ", &(dst[index+1]));
+			index += len+3;
+		}
+		putc ('\n');
+
+		free(dst);
+	}
+	else {
+		printf("\n*** U-Boot Version does not match Board Version!\n");
+		printf("*** CPCI-405 Version 2.x detected!\n");
+		printf("*** Please use correct U-Boot version (CPCI4052)!\n\n");
+	}
+
+#else /* CONFIG_CPCI405_VER2 */
+
+	/*
+	 * Generate last byte of ip-addr from code-plug @ 0xf0000400
+	 */
+	if (ctermm2()) {
+		char str[32];
+		unsigned char ipbyte = *(unsigned char *)0xf0000400;
+
+		/*
+		 * Only overwrite ip-addr with allowed values
+		 */
+		if ((ipbyte != 0x00) && (ipbyte != 0xff)) {
+			bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte;
+			sprintf(str, "%ld.%ld.%ld.%ld",
+				(bd->bi_ip_addr & 0xff000000) >> 24,
+				(bd->bi_ip_addr & 0x00ff0000) >> 16,
+				(bd->bi_ip_addr & 0x0000ff00) >> 8,
+				(bd->bi_ip_addr & 0x000000ff));
+			setenv("ipaddr", str);
+		}
+	}
+
+	if (version2()) {
+		printf("\n*** U-Boot Version does not match Board Version!\n");
+		printf("*** CPCI-405 Board Version 1.x detected!\n");
+		printf("*** Please use correct U-Boot version (CPCI405)!\n\n");
+	}
+
+#endif /* CONFIG_CPCI405_VER2 */
+
+	/*
+	 * Write ethernet addr in NVRAM for VxWorks
+	 */
+	tmp = (char *)CFG_NVRAM_BASE_ADDR + CFG_NVRAM_VXWORKS_OFFS;
+	memcpy( (char *)tmp, (char *)&bd->bi_enetaddr[0], 6 );
+	return (0);
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+#ifndef CONFIG_CPCI405_VER2
+	int index;
+	int len;
+#endif
+	unsigned char str[64];
+	int i = getenv_r ("serial#", str, sizeof(str));
+
+	puts ("Board: ");
+
+	if (i == -1) {
+		puts ("### No HW ID - assuming CPCI405");
+	} else {
+		puts(str);
+	}
+
+	if (version2())
+		puts (" (Ver 2.x, ");
+	else
+		puts (" (Ver 1.x, ");
+
+#if 0
+	if ((*(unsigned short *)((unsigned long)CFG_FPGA_BASE_ADDR) + CFG_FPGA_STATUS)
+	    & CFG_FPGA_STATUS_FLASH)
+		puts ("FLASH Bank A, ");
+	else
+		puts ("FLASH Bank B, ");
+#endif
+
+	if (ctermm2()) {
+		printf("CTERM-M2 - Id=0x%02x)", *(unsigned char *)0xf0000400);
+	} else {
+		if (cpci405_host()) {
+			puts ("PCI Host Version)");
+		} else {
+			puts ("PCI Adapter Version)");
+		}
+	}
+
+#ifndef CONFIG_CPCI405_VER2
+	puts ("\nFPGA:  ");
+
+	/* display infos on fpgaimage */
+	index = 15;
+	for (i=0; i<4; i++) {
+		len = fpgadata[index];
+		printf("%s ", &(fpgadata[index+1]));
+		index += len+3;
+	}
+#endif
+
+	putc ('\n');
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+	unsigned long val;
+
+	mtdcr(memcfga, mem_mb0cf);
+	val = mfdcr(memcfgd);
+
+#if 0
+	printf("\nmb0cf=%x\n", val); /* test-only */
+	printf("strap=%x\n", mfdcr(strap)); /* test-only */
+#endif
+
+	return (4*1024*1024 << ((val & 0x000e0000) >> 17));
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("test: 16 MB - ok\n");
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_CPCI405_VER2
+#ifdef CONFIG_IDE_RESET
+
+void ide_set_reset(int on)
+{
+	volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
+
+	/*
+	 * Assert or deassert CompactFlash Reset Pin
+	 */
+	if (on) {		/* assert RESET */
+		*fpga_mode &= ~(CFG_FPGA_MODE_CF_RESET);
+	} else {		/* release RESET */
+		*fpga_mode |= CFG_FPGA_MODE_CF_RESET;
+	}
+}
+
+#endif /* CONFIG_IDE_RESET */
+#endif /* CONFIG_CPCI405_VER2 */
+
+/* ------------------------------------------------------------------------- */
diff --git a/board/esd/cpci440/cpci440.c b/board/esd/cpci440/cpci440.c
new file mode 100644
index 0000000..51a5edd
--- /dev/null
+++ b/board/esd/cpci440/cpci440.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2002
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+
+#include <common.h>
+#include <asm/processor.h>
+
+
+long int fixed_sdram( void );
+
+int board_pre_init (void)
+{
+	uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup the external bus controller/chip selects
+	 *-------------------------------------------------------------------*/
+	mtdcr( ebccfga, xbcfg );
+	reg = mfdcr( ebccfgd );
+	mtdcr( ebccfgd, reg | 0x04000000 );	/* Set ATC */
+
+	mtebc( pb0ap, 0x92015480 );	/* FLASH/SRAM */
+	mtebc( pb0cr, 0xFF87A000 ); /* BAS=0xff8 8MB R/W 16-bit */
+	/* test-only: other regs still missing... */
+
+	/*--------------------------------------------------------------------
+	 * Setup the interrupt controller polarities, triggers, etc.
+	 *-------------------------------------------------------------------*/
+	mtdcr( uic0sr, 0xffffffff );    /* clear all */
+	mtdcr( uic0er, 0x00000000 );    /* disable all */
+	mtdcr( uic0cr, 0x00000009 );    /* SMI & UIC1 crit are critical */
+	mtdcr( uic0pr, 0xfffffe13 );    /* per ref-board manual */
+	mtdcr( uic0tr, 0x01c00008 );    /* per ref-board manual */
+	mtdcr( uic0vr, 0x00000001 );    /* int31 highest, base=0x000 */
+	mtdcr( uic0sr, 0xffffffff );    /* clear all */
+
+	mtdcr( uic1sr, 0xffffffff );    /* clear all */
+	mtdcr( uic1er, 0x00000000 );    /* disable all */
+	mtdcr( uic1cr, 0x00000000 );    /* all non-critical */
+	mtdcr( uic1pr, 0xffffe0ff );    /* per ref-board manual */
+	mtdcr( uic1tr, 0x00ffc000 );    /* per ref-board manual */
+	mtdcr( uic1vr, 0x00000001 );    /* int31 highest, base=0x000 */
+	mtdcr( uic1sr, 0xffffffff );    /* clear all */
+
+	return 0;
+}
+
+
+
+int checkboard (void)
+{
+	sys_info_t sysinfo;
+	get_sys_info(&sysinfo);
+
+	printf("Board: esd CPCI-440\n");
+	printf("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz/1000000);
+	printf("\tCPU: %lu MHz\n", sysinfo.freqProcessor/1000000);
+	printf("\tPLB: %lu MHz\n", sysinfo.freqPLB/1000000);
+	printf("\tOPB: %lu MHz\n", sysinfo.freqOPB/1000000);
+	printf("\tEPB: %lu MHz\n", sysinfo.freqEPB/1000000);
+	return (0);
+}
+
+
+long int initdram (int board_type)
+{
+	long    dram_size = 0;
+
+	dram_size = fixed_sdram();
+	return dram_size;
+}
+
+
+/*************************************************************************
+ *  fixed sdram init -- doesn't use serial presence detect.
+ *
+ *  Assumes:    64 MB, non-ECC, non-registered
+ *              PLB @ 133 MHz
+ *
+ ************************************************************************/
+long int fixed_sdram( void )
+{
+	uint    reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup some default
+	 *------------------------------------------------------------------*/
+	mtsdram( mem_uabba, 0x00000000 );   /* ubba=0 (default)             */
+	mtsdram( mem_slio,  0x00000000 );   /* rdre=0 wrre=0 rarw=0         */
+	mtsdram( mem_devopt,0x00000000 );   /* dll=0 ds=0 (normal)          */
+	mtsdram( mem_wddctr,0x40000000 );   /* wrcp=0 dcd=0                 */
+	mtsdram( mem_clktr, 0x40000000 );   /* clkp=1 (90 deg wr) dcdt=0    */
+
+	/*--------------------------------------------------------------------
+	 * Setup for board-specific specific mem
+	 *------------------------------------------------------------------*/
+	/*
+	 * Following for CAS Latency = 2.5 @ 133 MHz PLB
+	 */
+	mtsdram( mem_b0cr, 0x00082001 );/* SDBA=0x000, 64MB, Mode 2, enabled*/
+	mtsdram( mem_tr0,  0x410a4012 );/* WR=2  WD=1 CL=2.5 PA=3 CP=4 LD=2 */
+	/* RA=10 RD=3                       */
+	mtsdram( mem_tr1,  0x8080082f );/* SS=T2 SL=STAGE 3 CD=1 CT=0x02f   */
+	mtsdram( mem_rtr,  0x08200000 );/* Rate 15.625 ns @ 133 MHz PLB     */
+	mtsdram( mem_cfg1, 0x00000000 );/* Self-refresh exit, disable PM    */
+	udelay( 400 );                  /* Delay 200 usecs (min)            */
+
+	/*--------------------------------------------------------------------
+	 * Enable the controller, then wait for DCEN to complete
+	 *------------------------------------------------------------------*/
+	mtsdram( mem_cfg0, 0x86000000 );/* DCEN=1, PMUD=1, 64-bit           */
+	for(;;)
+	{
+		mfsdram( mem_mcsts, reg );
+		if( reg & 0x80000000 )
+			break;
+	}
+
+	return( 64 * 1024 * 1024 );      /* 64 MB                           */
+}
diff --git a/board/esd/cpci440/init.S b/board/esd/cpci440/init.S
new file mode 100644
index 0000000..2dab9f9
--- /dev/null
+++ b/board/esd/cpci440/init.S
@@ -0,0 +1,96 @@
+/*
+*  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.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
+*/
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID   0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K	    0x00000000
+#define SZ_4K	    0x00000010
+#define SZ_16K	    0x00000020
+#define SZ_64K	    0x00000030
+#define SZ_256K	    0x00000040
+#define SZ_1M	    0x00000050
+#define SZ_16M	    0x00000070
+#define SZ_256M	    0x00000090
+
+/* Storage attributes */
+#define SA_W	    0x00000800	    /* Write-through */
+#define SA_I	    0x00000400	    /* Caching inhibited */
+#define SA_M	    0x00000200	    /* Memory coherence */
+#define SA_G	    0x00000100	    /* Guarded */
+#define SA_E	    0x00000080	    /* Endian */
+
+/* Access control */
+#define AC_X	    0x00000024	    /* Execute */
+#define AC_W	    0x00000012	    /* Write */
+#define AC_R	    0x00000009	    /* Read */
+
+/* Some handy macros */
+
+#define EPN(e)		((e) & 0xfffffc00)
+#define TLB0(epn,sz)	( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn)	( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a)		( (a)&0x00000fbf )
+
+#define tlbtab_start\
+	mflr    r1  ;\
+	bl 0f	    ;
+
+#define tlbtab_end\
+	.long 0, 0, 0	;   \
+0:	mflr    r0	;   \
+	mtlr    r1	;   \
+	blr		;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+	.long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ *  Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+    .section .bootpg,"ax"
+    .globl tlbtab
+
+tlbtab:
+    tlbtab_start
+    tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+    tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+    tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X )
+    tlbtab_end
+
+
diff --git a/board/esd/pci405/pci405.c b/board/esd/pci405/pci405.c
new file mode 100644
index 0000000..ed86c02
--- /dev/null
+++ b/board/esd/pci405/pci405.c
@@ -0,0 +1,254 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <malloc.h>
+#include <pci.h>
+#include <405gp_pci.h>
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+#define PCI_RECONFIG_MAGIC       0x07081967
+
+
+struct pci_config_regs {
+	unsigned short  command;
+	unsigned char   latency_timer;
+	unsigned char   int_line;
+	unsigned long   bar1;
+	unsigned long   bar2;
+	unsigned long   magic;
+};
+
+
+/* fpga configuration data - generated by bin2cc */
+const unsigned char fpgadata[] =
+{
+#include "fpgadata.c"
+};
+
+/*
+ * include common fpga code (for esd boards)
+ */
+#include "../common/fpga.c"
+
+
+/* Prototypes */
+int gunzip(void *, int, unsigned char *, int *);
+
+
+int board_pre_init (void)
+{
+	unsigned long cntrl0Reg;
+
+	/*
+	 * IRQ 0-15  405GP internally generated; active high; level sensitive
+	 * IRQ 16    405GP internally generated; active low; level sensitive
+	 * IRQ 17-24 RESERVED
+	 * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
+	 * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive
+	 * IRQ 27 (EXT IRQ 2) CAN2; active low; level sensitive
+	 * IRQ 28 (EXT IRQ 3) CAN3; active low; level sensitive
+	 * IRQ 29 (EXT IRQ 4) unused; active low; level sensitive
+	 * IRQ 30 (EXT IRQ 5) FPGA Timestamp; active low; level sensitive
+	 * IRQ 31 (EXT IRQ 6) PCI Reset; active low; level sensitive
+	 */
+	mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
+	mtdcr(uicer, 0x00000000);        /* disable all ints */
+	mtdcr(uiccr, 0x00000000);        /* set all to be non-critical*/
+	mtdcr(uicpr, 0xFFFFFF80);        /* set int polarities */
+	mtdcr(uictr, 0x10000000);        /* set int trigger levels */
+	mtdcr(uicvcr, 0x00000001);       /* set vect base=0,INT0 highest priority*/
+	mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
+
+	/*
+	 * Setup GPIO pins (IRQ4/GPIO21 as GPIO)
+	 */
+	cntrl0Reg = mfdcr(cntrl0);
+	mtdcr(cntrl0, cntrl0Reg | 0x00008000);
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_f (void)
+{
+	return 0;  /* dummy implementation */
+}
+
+
+int misc_init_r (void)
+{
+	unsigned char *dst;
+	ulong len = sizeof(fpgadata);
+	int status;
+	int index;
+	int i;
+	struct pci_config_regs *pci_regs;
+
+	/*
+	 * On PCI-405 the environment is saved in eeprom!
+	 * FPGA can be gzip compressed (malloc) and booted this late.
+	 */
+
+	dst = malloc(CFG_FPGA_MAX_SIZE);
+	if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
+		printf ("GUNZIP ERROR - must RESET board to recover\n");
+		do_reset (NULL, 0, 0, NULL);
+	}
+
+	status = fpga_boot(dst, len);
+	if (status != 0) {
+		printf("\nFPGA: Booting failed ");
+		switch (status) {
+		case ERROR_FPGA_PRG_INIT_LOW:
+			printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+			break;
+		case ERROR_FPGA_PRG_INIT_HIGH:
+			printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+			break;
+		case ERROR_FPGA_PRG_DONE:
+			printf("(Timeout: DONE not high after programming FPGA)\n ");
+			break;
+		}
+
+		/* display infos on fpgaimage */
+		index = 15;
+		for (i=0; i<4; i++) {
+			len = dst[index];
+			printf("FPGA: %s\n", &(dst[index+1]));
+			index += len+3;
+		}
+		putc ('\n');
+		/* delayed reboot */
+		for (i=20; i>0; i--) {
+			printf("Rebooting in %2d seconds \r",i);
+			for (index=0;index<1000;index++)
+				udelay(1000);
+		}
+		putc ('\n');
+		do_reset(NULL, 0, 0, NULL);
+	}
+
+	puts("FPGA:  ");
+
+	/* display infos on fpgaimage */
+	index = 15;
+	for (i=0; i<4; i++) {
+		len = dst[index];
+		printf("%s ", &(dst[index+1]));
+		index += len+3;
+	}
+	putc ('\n');
+
+	/*
+	 * Rewrite pci config regs (only after soft-reset with magic set)
+	 */
+	pci_regs = (struct pci_config_regs *)0x10;
+	if (pci_regs->magic == PCI_RECONFIG_MAGIC) {
+		puts("PCI:   Found magic, rewriting config regs...\n");
+		pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND,
+				      pci_regs->command);
+		pci_write_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER,
+				      pci_regs->latency_timer);
+		pci_write_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE,
+				      pci_regs->int_line);
+		pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1,
+				       pci_regs->bar1);
+		pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2,
+				       pci_regs->bar2);
+	}
+	pci_regs->magic = 0; /* clear magic again */
+
+#if 0 /* test-only */
+	pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &(pci_regs->command));
+	pci_read_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER, &(pci_regs->latency_timer));
+	pci_read_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE, &(pci_regs->int_line));
+	pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, &(pci_regs->bar1));
+	pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, &(pci_regs->bar2));
+	pci_regs->magic = PCI_RECONFIG_MAGIC; /* set magic */
+#endif
+
+	free(dst);
+	return (0);
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+	unsigned char str[64];
+	int i = getenv_r ("serial#", str, sizeof(str));
+
+	puts ("Board: ");
+
+	if (i == -1) {
+		puts ("### No HW ID - assuming CPCI405");
+	} else {
+		puts (str);
+	}
+	putc ('\n');
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+	unsigned long val;
+
+	mtdcr(memcfga, mem_mb0cf);
+	val = mfdcr(memcfgd);
+
+#if 0
+	printf("\nmb0cf=%x\n", val); /* test-only */
+	printf("strap=%x\n", mfdcr(strap)); /* test-only */
+#endif
+
+	return (4*1024*1024 << ((val & 0x000e0000) >> 17));
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("test: 16 MB - ok\n");
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/board/evb64260/eth_addrtbl.c b/board/evb64260/eth_addrtbl.c
new file mode 100644
index 0000000..ea4925a
--- /dev/null
+++ b/board/evb64260/eth_addrtbl.c
@@ -0,0 +1,225 @@
+#include <common.h>
+#include <malloc.h>
+#include <galileo/gt64260R.h>
+#include <galileo/core.h>
+#include <asm/cache.h>
+#include "eth.h"
+#include "eth_addrtbl.h"
+
+#define TRUE 1
+#define FALSE 0
+
+#define PRINTF printf
+
+#ifdef CONFIG_GT_USE_MAC_HASH_TABLE
+
+static u32           addressTableHashMode[ GAL_ETH_DEVS ] = { 0, };
+static u32           addressTableHashSize[ GAL_ETH_DEVS ] = { 0, };
+static addrTblEntry *addressTableBase[     GAL_ETH_DEVS ] = { 0, };
+static void         *realAddrTableBase[    GAL_ETH_DEVS ] = { 0, };
+
+static const u32 hashLength[ 2 ] = {
+    (0x8000),             /* 8K * 4 entries */
+    (0x8000/16),          /* 512 * 4 entries */
+};
+
+/* Initialize the address table for a port, if needed */
+unsigned int initAddressTable( u32 port, u32 hashMode, u32 hashSizeSelector)
+{
+    unsigned int tableBase;
+
+    if( port < 0 || port >= GAL_ETH_DEVS ) {
+		printf("%s: Invalid port number %d\n", __FUNCTION__, port );
+		return 0;
+	}
+
+	if (hashMode > 1) {
+		printf("%s: Invalid Hash Mode %d\n", __FUNCTION__, port );
+		return 0;
+	}
+
+	if ( realAddrTableBase[port] &&
+		( addressTableHashSize[port] != hashSizeSelector )) {
+		/* we have been here before,
+		 * but now we want a different sized table
+		 */
+		free( realAddrTableBase[port] );
+		realAddrTableBase[port] = 0;
+		addressTableBase[port] = 0;
+
+	}
+
+	tableBase = (unsigned int)addressTableBase[port];
+	/* we get called for every probe, so only do this once */
+	if ( !tableBase ) {
+    	int bytes = hashLength[hashSizeSelector] * sizeof(addrTblEntry);
+
+		tableBase = (unsigned int)realAddrTableBase[port] = malloc(bytes+64);
+
+	    if(!tableBase)
+		{
+			printf("%s: alloc memory failed \n", __FUNCTION__);
+			return 0;
+		}
+
+    	/* align to octal byte */
+	    if(tableBase&63) tableBase=(tableBase+63) & ~63;
+
+    	addressTableHashMode[port] = hashMode;
+	    addressTableHashSize[port] = hashSizeSelector;
+    	addressTableBase[port] = (addrTblEntry *)tableBase;
+
+	    memset((void *)tableBase,0,bytes);
+	}
+
+    return tableBase;
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will calculate the hash function of the address.
+ * depends on the hash mode and hash size.
+ * Inputs
+ * macH             - the 2 most significant bytes of the MAC address.
+ * macL             - the 4 least significant bytes of the MAC address.
+ * hashMode         - hash mode 0 or hash mode 1.
+ * hashSizeSelector - indicates number of hash table entries (0=0x8000,1=0x800)
+ * Outputs
+ * return the calculated entry.
+ */
+u32
+hashTableFunction( u32 macH, u32 macL, u32 HashSize, u32 hash_mode)
+{
+    u32 hashResult;
+    u32 addrH;
+    u32 addrL;
+    u32 addr0;
+    u32 addr1;
+    u32 addr2;
+    u32 addr3;
+    u32 addrHSwapped;
+    u32 addrLSwapped;
+
+
+    addrH = NIBBLE_SWAPPING_16_BIT( macH );
+    addrL = NIBBLE_SWAPPING_32_BIT( macL );
+
+    addrHSwapped =   FLIP_4_BITS(  addrH        & 0xf )
+                 + ((FLIP_4_BITS( (addrH >>  4) & 0xf)) <<  4)
+                 + ((FLIP_4_BITS( (addrH >>  8) & 0xf)) <<  8)
+                 + ((FLIP_4_BITS( (addrH >> 12) & 0xf)) << 12);
+
+    addrLSwapped =   FLIP_4_BITS(  addrL        & 0xf )
+                 + ((FLIP_4_BITS( (addrL >>  4) & 0xf)) <<  4)
+                 + ((FLIP_4_BITS( (addrL >>  8) & 0xf)) <<  8)
+                 + ((FLIP_4_BITS( (addrL >> 12) & 0xf)) << 12)
+                 + ((FLIP_4_BITS( (addrL >> 16) & 0xf)) << 16)
+                 + ((FLIP_4_BITS( (addrL >> 20) & 0xf)) << 20)
+                 + ((FLIP_4_BITS( (addrL >> 24) & 0xf)) << 24)
+                 + ((FLIP_4_BITS( (addrL >> 28) & 0xf)) << 28);
+
+    addrH = addrHSwapped;
+    addrL = addrLSwapped;
+
+    if( hash_mode == 0 )  {
+        addr0 =  (addrL >>  2) & 0x03f;
+        addr1 =  (addrL        & 0x003) | ((addrL >> 8) & 0x7f) << 2;
+        addr2 =  (addrL >> 15) & 0x1ff;
+        addr3 = ((addrL >> 24) & 0x0ff) | ((addrH &  1)         << 8);
+    } else  {
+        addr0 = FLIP_6_BITS(    addrL        & 0x03f );
+        addr1 = FLIP_9_BITS(  ((addrL >>  6) & 0x1ff));
+        addr2 = FLIP_9_BITS(   (addrL >> 15) & 0x1ff);
+        addr3 = FLIP_9_BITS( (((addrL >> 24) & 0x0ff) | ((addrH & 0x1) << 8)));
+    }
+
+    hashResult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
+
+    if( HashSize == _8K_TABLE )  {
+        hashResult = hashResult & 0xffff;
+    } else  {
+        hashResult = hashResult & 0x07ff;
+    }
+
+    return( hashResult );
+}
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will add an entry to the address table.
+ * depends on the hash mode and hash size that was initialized.
+ * Inputs
+ * port - ETHERNET port number.
+ * macH - the 2 most significant bytes of the MAC address.
+ * macL - the 4 least significant bytes of the MAC address.
+ * skip - if 1, skip this address.
+ * rd   - the RD field in the address table.
+ * Outputs
+ * address table entry is added.
+ * TRUE if success.
+ * FALSE if table full
+ */
+int
+addAddressTableEntry(
+    u32           port,
+    u32           macH,
+    u32           macL,
+    u32           rd,
+    u32           skip         )
+{
+    addrTblEntry *entry;
+    u32           newHi;
+    u32           newLo;
+    u32           i;
+
+    newLo = (((macH >>  4) & 0xf) << 15)
+          | (((macH >>  0) & 0xf) << 11)
+          | (((macH >> 12) & 0xf) <<  7)
+          | (((macH >>  8) & 0xf) <<  3)
+          | (((macL >> 20) & 0x1) << 31)
+          | (((macL >> 16) & 0xf) << 27)
+          | (((macL >> 28) & 0xf) << 23)
+          | (((macL >> 24) & 0xf) << 19)
+          |   (skip << SKIP_BIT)  |  (rd << 2) | VALID;
+
+    newHi = (((macL >>  4) & 0xf) << 15)
+          | (((macL >>  0) & 0xf) << 11)
+          | (((macL >> 12) & 0xf) <<  7)
+          | (((macL >>  8) & 0xf) <<  3)
+          | (((macL >> 21) & 0x7) <<  0);
+
+    /*
+     * Pick the appropriate table, start scanning for free/reusable
+     * entries at the index obtained by hashing the specified MAC address
+     */
+    entry  = addressTableBase[port];
+    entry += hashTableFunction( macH, macL, addressTableHashSize[port],
+                                            addressTableHashMode[port]  );
+    for( i = 0;  i < HOP_NUMBER;  i++, entry++ )  {
+        if( !(entry->lo & VALID)   /*|| (entry->lo & SKIP)*/   )  {
+            break;
+        } else  {                    /* if same address put in same position */
+            if(   ((entry->lo & 0xfffffff8) == (newLo & 0xfffffff8))
+                && (entry->hi               ==  newHi) )
+            {
+                    break;
+            }
+        }
+    }
+
+    if( i == HOP_NUMBER )  {
+        PRINTF( "addGT64260addressTableEntry: table section is full\n" );
+        return( FALSE );
+    }
+
+    /*
+     * Update the selected entry
+     */
+    entry->hi = newHi;
+    entry->lo = newLo;
+    DCACHE_FLUSH_N_SYNC( (u32)entry, MAC_ENTRY_SIZE );
+    return( TRUE );
+}
+
+#endif /* CONFIG_GT_USE_MAC_HASH_TABLE */
diff --git a/board/evb64260/pci.c b/board/evb64260/pci.c
new file mode 100644
index 0000000..8e9178d
--- /dev/null
+++ b/board/evb64260/pci.c
@@ -0,0 +1,691 @@
+/* PCI.c - PCI functions */
+
+/* Copyright - Galileo technology. */
+
+#include <common.h>
+#include <pci.h>
+
+#include <galileo/pci.h>
+
+static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
+#ifdef CONFIG_ZUMA_V2
+    {0,0,0,0,0,0,0,29, [8 ... PCI_MAX_DEVICES-1]=0},
+    {0,0,0,0,0,0,0,28, [8 ... PCI_MAX_DEVICES-1]=0}
+#else	/* EVB??? This is a guess */
+    {0,0,0,0,0,0,0,27,27, [9 ... PCI_MAX_DEVICES-1]=0},
+    {0,0,0,0,0,0,0,29,29, [9 ... PCI_MAX_DEVICES-1]=0}
+#endif
+};
+
+static const unsigned int pci_p2p_configuration_reg[]={
+    PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
+
+static const unsigned int pci_configuration_address[]={
+    PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS};
+
+static const unsigned int pci_configuration_data[]={
+    PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+    PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER};
+
+static const unsigned int pci_error_cause_reg[]={
+    PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE};
+
+static const unsigned int pci_arbiter_control[]={
+    PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL};
+
+static const unsigned int pci_snoop_control_base_0_low[]={
+    PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW};
+static const unsigned int pci_snoop_control_top_0[]={
+    PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0};
+
+static const unsigned int pci_access_control_base_0_low[]={
+    PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW};
+static const unsigned int pci_access_control_top_0[]={
+    PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0};
+
+static const unsigned int pci_scs_bank_size[2][4] = {
+    {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
+     PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
+    {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
+     PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}};
+
+static const unsigned int pci_p2p_configuration[] = {
+    PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
+
+/********************************************************************
+* pciWriteConfigReg - Write to a PCI configuration register
+*                    - Make sure the GT is configured as a master before writing
+*                      to another device on the PCI.
+*                    - The function takes care of Big/Little endian conversion.
+*
+*
+* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec
+*                   (or any other PCI device spec)
+*           pciDevNum: The device number needs to be addressed.
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum,unsigned int data)
+{
+    volatile unsigned int DataForAddrReg;
+    unsigned int functionNum;
+    unsigned int busNum = 0;
+    unsigned int addr;
+
+    if(pciDevNum > 32) /* illegal device Number */
+        return;
+    if(pciDevNum == SELF) /* configure our configuration space. */
+    {
+        pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
+        busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
+    }
+    functionNum =  regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xfc;
+    DataForAddrReg = ( regOffset | pciDevNum | functionNum | busNum) | BIT31;
+    GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
+    GT_REG_READ(pci_configuration_address[host], &addr);
+    if (addr != DataForAddrReg) return;
+    GT_REG_WRITE(pci_configuration_data[host],data);
+}
+
+/********************************************************************
+* pciReadConfigReg  - Read from a PCI0 configuration register
+*                    - Make sure the GT is configured as a master before reading
+*                     from another device on the PCI.
+*                   - The function takes care of Big/Little endian conversion.
+* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+*                        spec)
+*           pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+*                 cause register to make sure the data is valid
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum)
+{
+    volatile unsigned int DataForAddrReg;
+   	unsigned int data;
+    unsigned int functionNum;
+    unsigned int busNum = 0;
+
+    if(pciDevNum > 32) /* illegal device Number */
+        return 0xffffffff;
+    if(pciDevNum == SELF) /* configure our configuration space. */
+    {
+        pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
+        busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
+    }
+    functionNum = regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xfc;
+    DataForAddrReg = (regOffset | pciDevNum | functionNum | busNum) | BIT31 ;
+    GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
+    GT_REG_READ(pci_configuration_address[host], &data);
+    if (data != DataForAddrReg)
+        return 0xffffffff;
+    GT_REG_READ(pci_configuration_data[host], &data);
+    return data;
+}
+
+/********************************************************************
+* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
+*                               the agent is placed on another Bus. For more
+*                               information read P2P in the PCI spec.
+*
+* Inputs:   unsigned int regOffset - The register offset as it apears in the
+*           GT spec (or any other PCI device spec).
+*           unsigned int pciDevNum - The device number needs to be addressed.
+*           unsigned int busNum - On which bus does the Target agent connect
+*                                 to.
+*           unsigned int data - data to be written.
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|01|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*  The configuration Address is configure as type-I (bits[1:0] = '01') due to
+*   PCI spec referring to P2P.
+*
+*********************************************************************/
+void pciOverBridgeWriteConfigReg(PCI_HOST host,
+				 unsigned int regOffset,
+                                 unsigned int pciDevNum,
+                                 unsigned int busNum,unsigned int data)
+{
+   	unsigned int   DataForReg;
+    unsigned int   functionNum;
+
+   	functionNum =  regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xff;
+    busNum = busNum << 16;
+    if(pciDevNum == SELF) /* This board */
+    {
+        DataForReg = ( regOffset | pciDevNum | functionNum) | BIT0;
+    }
+    else
+    {
+        DataForReg = ( regOffset | pciDevNum | functionNum | busNum) |
+            BIT31 | BIT0;
+    }
+    GT_REG_WRITE(pci_configuration_address[host],DataForReg);
+    if(pciDevNum == SELF) /* This board */
+    {
+        GT_REG_WRITE(pci_configuration_data[host],data);
+    }
+    else /* configuration Transaction over the pci. */
+    {
+        /* The PCI is working in LE Mode So it swap the Data. */
+        GT_REG_WRITE(pci_configuration_data[host],WORD_SWAP(data));
+    }
+}
+
+
+/********************************************************************
+* pciOverBridgeReadConfigReg  - Read from a PCIn configuration register where
+*                               the agent target locate on another PCI bus.
+*                             - Make sure the GT is configured as a master
+*                               before reading from another device on the PCI.
+*                             - The function takes care of Big/Little endian
+*                               conversion.
+* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+*                        spec). (configuration register offset.)
+*           pciDevNum: The device number needs to be addressed.
+*           busNum: the Bus number where the agent is place.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+*                 cause register to make sure the data is valid
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|01|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+unsigned int pciOverBridgeReadConfigReg(PCI_HOST host,
+					unsigned int regOffset,
+                                        unsigned int pciDevNum,
+                                        unsigned int busNum)
+{
+    unsigned int DataForReg;
+    unsigned int data;
+    unsigned int functionNum;
+
+    functionNum = regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xff;
+    busNum = busNum << 16;
+    if (pciDevNum == SELF) /* This board */
+    {
+        DataForReg = (regOffset | pciDevNum | functionNum) | BIT31 ;
+    }
+    else /* agent on another bus */
+    {
+        DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
+        BIT0 | BIT31 ;
+    }
+    GT_REG_WRITE(pci_configuration_address[host],DataForReg);
+    if (pciDevNum == SELF) /* This board */
+   	{
+        GT_REG_READ(pci_configuration_data[host], &data);
+    	return data;
+    }
+    else /* The PCI is working in LE Mode So it swap the Data. */
+    {
+        GT_REG_READ(pci_configuration_data[host], &data);
+    	return WORD_SWAP(data);
+    }
+}
+
+/********************************************************************
+* pciGetRegOffset - Gets the register offset for this region config.
+*
+* INPUT:   Bus, Region - The bus and region we ask for its base address.
+* OUTPUT:   N/A
+* RETURNS: PCI register base address
+*********************************************************************/
+static unsigned int pciGetRegOffset(PCI_HOST host, PCI_REGION region)
+{
+    switch (host)
+    {
+	case PCI_HOST0:
+	    switch(region) {
+		case PCI_IO:		return PCI_0I_O_LOW_DECODE_ADDRESS;
+		case PCI_REGION0:	return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+		case PCI_REGION1:	return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
+		case PCI_REGION2:	return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
+		case PCI_REGION3:	return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
+	    }
+	case PCI_HOST1:
+	    switch(region) {
+		case PCI_IO:		return PCI_1I_O_LOW_DECODE_ADDRESS;
+		case PCI_REGION0:	return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
+		case PCI_REGION1:	return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
+		case PCI_REGION2:	return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
+		case PCI_REGION3:	return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
+	    }
+    }
+    return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+}
+
+static unsigned int pciGetRemapOffset(PCI_HOST host, PCI_REGION region)
+{
+    switch (host)
+    {
+	case PCI_HOST0:
+	    switch(region) {
+		case PCI_IO:		return PCI_0I_O_ADDRESS_REMAP;
+		case PCI_REGION0:	return PCI_0MEMORY0_ADDRESS_REMAP;
+		case PCI_REGION1:	return PCI_0MEMORY1_ADDRESS_REMAP;
+		case PCI_REGION2:	return PCI_0MEMORY2_ADDRESS_REMAP;
+		case PCI_REGION3:	return PCI_0MEMORY3_ADDRESS_REMAP;
+	    }
+	case PCI_HOST1:
+	    switch(region) {
+		case PCI_IO:		return PCI_1I_O_ADDRESS_REMAP;
+		case PCI_REGION0:	return PCI_1MEMORY0_ADDRESS_REMAP;
+		case PCI_REGION1:	return PCI_1MEMORY1_ADDRESS_REMAP;
+		case PCI_REGION2:	return PCI_1MEMORY2_ADDRESS_REMAP;
+		case PCI_REGION3:	return PCI_1MEMORY3_ADDRESS_REMAP;
+	    }
+    }
+    return PCI_0MEMORY0_ADDRESS_REMAP;
+}
+
+bool pciMapSpace(PCI_HOST host, PCI_REGION region, unsigned int remapBase, unsigned int bankBase,unsigned int bankLength)
+{
+    unsigned int low=0xfff;
+    unsigned int high=0x0;
+    unsigned int regOffset=pciGetRegOffset(host, region);
+    unsigned int remapOffset=pciGetRemapOffset(host, region);
+
+    if(bankLength!=0) {
+	low = (bankBase >> 20) & 0xfff;
+	high=((bankBase+bankLength)>>20)-1;
+    }
+
+    GT_REG_WRITE(regOffset, low | (1<<24));	/* no swapping */
+    GT_REG_WRITE(regOffset+8, high);
+
+    if(bankLength!=0) {	/* must do AFTER writing maps */
+	GT_REG_WRITE(remapOffset, remapBase>>20);	/* sorry, 32 bits only.
+							   dont support upper 32
+							   in this driver */
+    }
+    return true;
+}
+
+unsigned int pciGetSpaceBase(PCI_HOST host, PCI_REGION region)
+{
+    unsigned int low;
+    unsigned int regOffset=pciGetRegOffset(host, region);
+    GT_REG_READ(regOffset,&low);
+    return (low&0xfff)<<20;
+}
+
+unsigned int pciGetSpaceSize(PCI_HOST host, PCI_REGION region)
+{
+    unsigned int low,high;
+    unsigned int regOffset=pciGetRegOffset(host, region);
+    GT_REG_READ(regOffset,&low);
+    GT_REG_READ(regOffset+8,&high);
+    high&=0xfff;
+    low&=0xfff;
+    if(high<=low) return 0;
+    return (high+1-low)<<20;
+}
+
+/********************************************************************
+* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
+*
+* Inputs: base and size of PCI SCS
+*********************************************************************/
+void pciMapMemoryBank(PCI_HOST host, MEMORY_BANK bank, unsigned int pciDramBase,unsigned int pciDramSize)
+{
+  	pciDramBase = pciDramBase & 0xfffff000;
+    pciDramBase = pciDramBase | (pciReadConfigReg(host,
+        PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF) & 0x00000fff);
+    pciWriteConfigReg(host,PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF,pciDramBase);
+    if(pciDramSize == 0)
+        pciDramSize ++;
+    GT_REG_WRITE(pci_scs_bank_size[host][bank], pciDramSize-1);
+}
+
+
+/********************************************************************
+* pciSetRegionFeatures - This function modifys one of the 8 regions with
+*                         feature bits given as an input.
+*                       - Be advised to check the spec before modifying them.
+* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
+*         unsigned int features - See file: pci.h there are defintion for those
+*                                 region features.
+*         unsigned int baseAddress - The region base Address.
+*         unsigned int topAddress - The region top Address.
+* Returns: false if one of the parameters is erroneous true otherwise.
+*********************************************************************/
+bool pciSetRegionFeatures(PCI_HOST host, PCI_ACCESS_REGIONS region,unsigned int features,
+                           unsigned int baseAddress,unsigned int regionLength)
+{
+    unsigned int accessLow;
+    unsigned int accessHigh;
+    unsigned int accessTop = baseAddress + regionLength;
+
+    if(regionLength == 0) /* close the region. */
+    {
+        pciDisableAccessRegion(host, region);
+        return true;
+    }
+    /* base Address is store is bits [11:0] */
+    accessLow = (baseAddress & 0xfff00000) >> 20;
+    /* All the features are update according to the defines in pci.h (to be on
+       the safe side we disable bits: [11:0] */
+    accessLow = accessLow | (features & 0xfffff000);
+    /* write to the Low Access Region register */
+    GT_REG_WRITE( pci_access_control_base_0_low[host] + 0x10*region,accessLow);
+
+    accessHigh = (accessTop & 0xfff00000) >> 20;
+
+    /* write to the High Access Region register */
+    GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,accessHigh - 1);
+    return true;
+}
+
+/********************************************************************
+* pciDisableAccessRegion - Disable The given Region by writing MAX size
+*                           to its low Address and MIN size to its high Address.
+*
+* Inputs:   PCI_ACCESS_REGIONS region - The region we to be Disabled.
+* Returns:  N/A.
+*********************************************************************/
+void pciDisableAccessRegion(PCI_HOST host, PCI_ACCESS_REGIONS region)
+{
+    /* writing back the registers default values. */
+    GT_REG_WRITE(pci_access_control_base_0_low[host] + 0x10*region,0x01001fff);
+    GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,0);
+}
+
+/********************************************************************
+* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
+*
+* Inputs:   N/A
+* Returns:  true.
+*********************************************************************/
+bool pciArbiterEnable(PCI_HOST host)
+{
+    unsigned int regData;
+
+    GT_REG_READ(pci_arbiter_control[host],&regData);
+    GT_REG_WRITE(pci_arbiter_control[host],regData | BIT31);
+    return true;
+}
+
+/********************************************************************
+* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
+*
+* Inputs:   N/A
+* Returns:  true
+*********************************************************************/
+bool pciArbiterDisable(PCI_HOST host)
+{
+    unsigned int regData;
+
+    GT_REG_READ(pci_arbiter_control[host],&regData);
+    GT_REG_WRITE(pci_arbiter_control[host],regData & 0x7fffffff);
+    return true;
+}
+
+/********************************************************************
+* pciParkingDisable - Park on last option disable, with this function you can
+*                      disable the park on last mechanism for each agent.
+*                      disabling this option for all agents results parking
+*                      on the internal master.
+*
+* Inputs: PCI_AGENT_PARK internalAgent -  parking Disable for internal agent.
+*         PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
+*         PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
+*         PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
+*         PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
+*         PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
+*         PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
+* Returns:  true
+*********************************************************************/
+bool pciParkingDisable(PCI_HOST host, PCI_AGENT_PARK internalAgent,
+                        PCI_AGENT_PARK externalAgent0,
+                        PCI_AGENT_PARK externalAgent1,
+                        PCI_AGENT_PARK externalAgent2,
+                        PCI_AGENT_PARK externalAgent3,
+                        PCI_AGENT_PARK externalAgent4,
+                        PCI_AGENT_PARK externalAgent5)
+{
+    unsigned int regData;
+    unsigned int writeData;
+
+    GT_REG_READ(pci_arbiter_control[host],&regData);
+    writeData = (internalAgent << 14) + (externalAgent0 << 15) +     \
+                (externalAgent1 << 16) + (externalAgent2 << 17) +    \
+                (externalAgent3 << 18) + (externalAgent4 << 19) +    \
+                (externalAgent5 << 20);
+    regData = (regData & ~(0x7f<<14)) | writeData;
+    GT_REG_WRITE(pci_arbiter_control[host],regData);
+    return true;
+}
+
+/********************************************************************
+* pciSetRegionSnoopMode - This function modifys one of the 4 regions which
+*                          supports Cache Coherency in the PCI_n interface.
+* Inputs: region - One of the four regions.
+*         snoopType - There is four optional Types:
+*                        1. No Snoop.
+*                        2. Snoop to WT region.
+*                        3. Snoop to WB region.
+*                        4. Snoop & Invalidate to WB region.
+*         baseAddress - Base Address of this region.
+*         regionLength - Region length.
+* Returns: false if one of the parameters is wrong otherwise return true.
+*********************************************************************/
+bool pciSetRegionSnoopMode(PCI_HOST host, PCI_SNOOP_REGION region,PCI_SNOOP_TYPE snoopType,
+                            unsigned int baseAddress,
+                            unsigned int regionLength)
+{
+    unsigned int snoopXbaseAddress;
+    unsigned int snoopXtopAddress;
+    unsigned int data;
+    unsigned int snoopHigh = baseAddress + regionLength;
+
+    if( (region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB) )
+        return false;
+    snoopXbaseAddress = pci_snoop_control_base_0_low[host] + 0x10 * region;
+    snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
+    if(regionLength == 0) /* closing the region */
+    {
+        GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
+        GT_REG_WRITE(snoopXtopAddress,0);
+        return true;
+    }
+    baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
+    data = (baseAddress >> 20) | snoopType << 12;
+    GT_REG_WRITE(snoopXbaseAddress,data);
+    snoopHigh = (snoopHigh & 0xfff00000) >> 20;
+    GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
+    return true;
+}
+
+/*
+ *
+ */
+
+static int gt_read_config_dword(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset, u32* value)
+{
+    *value = pciReadConfigReg((PCI_HOST) hose->cfg_addr, offset, PCI_DEV(dev));
+    return 0;
+}
+
+static int gt_write_config_dword(struct pci_controller *hose,
+				 pci_dev_t dev,
+				 int offset, u32 value)
+{
+    pciWriteConfigReg((PCI_HOST)hose->cfg_addr, offset, PCI_DEV(dev), value);
+    return 0;
+}
+
+/*
+ *
+ */
+
+static void gt_setup_ide(struct pci_controller *hose,
+			 pci_dev_t dev, struct pci_config_table *entry)
+{
+    static const int ide_bar[]={8,4,8,4,0,0};
+    u32 bar_response, bar_value;
+    int bar;
+
+    for (bar=0; bar<6; bar++)
+    {
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, 0x0);
+	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, &bar_response);
+
+	pciauto_region_allocate(bar_response & PCI_BASE_ADDRESS_SPACE_IO ?
+				hose->pci_io : hose->pci_mem, ide_bar[bar], &bar_value);
+
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, bar_value);
+    }
+}
+
+static void gt_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+    unsigned char pin, irq;
+
+    pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+    if(pin == 1) {	/* only allow INT A */
+	irq = pci_irq_swizzle[(PCI_HOST)hose->cfg_addr][PCI_DEV(dev)];
+	if(irq)
+	    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+    }
+}
+
+struct pci_config_table gt_config_table[] = {
+    { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
+      PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
+
+    { }
+};
+
+struct pci_controller pci0_hose = {
+    fixup_irq: gt_fixup_irq,
+    config_table: gt_config_table,
+};
+
+struct pci_controller pci1_hose = {
+    fixup_irq: gt_fixup_irq,
+    config_table: gt_config_table,
+};
+
+void
+pci_init(void)
+{
+    unsigned int command;
+
+    pci0_hose.first_busno = 0;
+    pci0_hose.last_busno = 0xff;
+
+    /* PCI memory space */
+    pci_set_region(pci0_hose.regions + 0,
+		   CFG_PCI0_0_MEM_SPACE,
+		   CFG_PCI0_0_MEM_SPACE,
+		   CFG_PCI0_MEM_SIZE,
+		   PCI_REGION_MEM);
+
+    /* PCI I/O space */
+    pci_set_region(pci0_hose.regions + 1,
+		   CFG_PCI0_IO_SPACE_PCI,
+		   CFG_PCI0_IO_SPACE,
+		   CFG_PCI0_IO_SIZE,
+		   PCI_REGION_IO);
+
+    pci_set_ops(&pci0_hose,
+		pci_hose_read_config_byte_via_dword,
+		pci_hose_read_config_word_via_dword,
+		gt_read_config_dword,
+		pci_hose_write_config_byte_via_dword,
+		pci_hose_write_config_word_via_dword,
+		gt_write_config_dword);
+
+    pci0_hose.region_count = 2;
+
+    pci0_hose.cfg_addr = (unsigned int*) PCI_HOST0;
+
+    pci_register_hose(&pci0_hose);
+
+    pciArbiterEnable(PCI_HOST0);
+    pciParkingDisable(PCI_HOST0,1,1,1,1,1,1,1);
+
+    command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MASTER;
+    pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
+
+    pci0_hose.last_busno = pci_hose_scan(&pci0_hose);
+
+    command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MEMORY;
+    pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
+
+    pci1_hose.first_busno = pci0_hose.last_busno + 1;
+    pci1_hose.last_busno = 0xff;
+
+    /* PCI memory space */
+    pci_set_region(pci1_hose.regions + 0,
+		   CFG_PCI1_0_MEM_SPACE,
+		   CFG_PCI1_0_MEM_SPACE,
+		   CFG_PCI1_MEM_SIZE,
+		   PCI_REGION_MEM);
+
+    /* PCI I/O space */
+    pci_set_region(pci1_hose.regions + 1,
+		   CFG_PCI1_IO_SPACE_PCI,
+		   CFG_PCI1_IO_SPACE,
+		   CFG_PCI1_IO_SIZE,
+		   PCI_REGION_IO);
+
+    pci_set_ops(&pci1_hose,
+		pci_hose_read_config_byte_via_dword,
+		pci_hose_read_config_word_via_dword,
+		gt_read_config_dword,
+		pci_hose_write_config_byte_via_dword,
+		pci_hose_write_config_word_via_dword,
+		gt_write_config_dword);
+
+    pci1_hose.region_count = 2;
+
+    pci1_hose.cfg_addr = (unsigned int*) PCI_HOST1;
+
+    pci_register_hose(&pci1_hose);
+
+    pciArbiterEnable(PCI_HOST1);
+    pciParkingDisable(PCI_HOST1,1,1,1,1,1,1,1);
+
+    command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MASTER;
+    pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
+
+    pci1_hose.last_busno = pci_hose_scan(&pci1_hose);
+
+    command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MEMORY;
+    pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
+}
diff --git a/board/evb64260/sdram_init.c b/board/evb64260/sdram_init.c
new file mode 100644
index 0000000..ff98e4d
--- /dev/null
+++ b/board/evb64260/sdram_init.c
@@ -0,0 +1,629 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/* sdram_init.c - automatic memory sizing */
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include <galileo/memory.h>
+#include <galileo/pci.h>
+#include <galileo/gt64260R.h>
+#include <net.h>
+
+#include "eth.h"
+#include "mpsc.h"
+#include "i2c.h"
+#include "64260.h"
+
+/* #define	DEBUG */
+#define	MAP_PCI
+
+#ifdef DEBUG
+#define DP(x) x
+#else
+#define DP(x)
+#endif
+
+#define GB         (1 << 30)
+
+/* structure to store the relevant information about an sdram bank */
+typedef struct sdram_info {
+	uchar drb_size;
+	uchar registered, ecc;
+	uchar tpar;
+	uchar tras_clocks;
+	uchar burst_len;
+	uchar banks, slot;
+	int size;	/* detected size, not from I2C but from dram_size() */
+} sdram_info_t;
+
+#ifdef DEBUG
+void dump_dimm_info(struct sdram_info *d)
+{
+    static const char *ecc_legend[]={""," Parity"," ECC"};
+    printf("dimm%s %sDRAM: %dMibytes:\n",
+	    ecc_legend[d->ecc],
+	    d->registered?"R":"",
+	    (d->size>>20));
+    printf("  drb=%d tpar=%d tras=%d burstlen=%d banks=%d slot=%d\n",
+	    d->drb_size, d->tpar, d->tras_clocks, d->burst_len,
+	    d->banks, d->slot);
+}
+#endif
+
+static int
+memory_map_bank(unsigned int bankNo,
+		unsigned int bankBase,
+		unsigned int bankLength)
+{
+#ifdef DEBUG
+	if (bankLength > 0) {
+		printf("mapping bank %d at %08x - %08x\n",
+		       bankNo, bankBase, bankBase + bankLength - 1);
+	} else {
+		printf("unmapping bank %d\n", bankNo);
+	}
+#endif
+
+	memoryMapBank(bankNo, bankBase, bankLength);
+
+	return 0;
+}
+
+#ifdef MAP_PCI
+static int
+memory_map_bank_pci(unsigned int bankNo,
+		unsigned int bankBase,
+		unsigned int bankLength)
+{
+	PCI_HOST host;
+	for (host=PCI_HOST0;host<=PCI_HOST1;host++) {
+		const int features=
+			PREFETCH_ENABLE |
+			DELAYED_READ_ENABLE |
+			AGGRESSIVE_PREFETCH |
+			READ_LINE_AGGRESSIVE_PREFETCH |
+			READ_MULTI_AGGRESSIVE_PREFETCH |
+			MAX_BURST_4 |
+			PCI_NO_SWAP;
+
+		pciMapMemoryBank(host, bankNo, bankBase, bankLength);
+
+		pciSetRegionSnoopMode(host, bankNo, PCI_SNOOP_WB, bankBase,
+				bankLength);
+
+		pciSetRegionFeatures(host, bankNo, features, bankBase, bankLength);
+	}
+	return 0;
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* much of this code is based on (or is) the code in the pip405 port */
+/* thanks go to the authors of said port - Josh */
+
+
+/*
+ * translate ns.ns/10 coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short
+NS10to10PS(unsigned char spd_byte)
+{
+	unsigned short ns, ns10;
+
+	/* isolate upper nibble */
+	ns = (spd_byte >> 4) & 0x0F;
+	/* isolate lower nibble */
+	ns10 = (spd_byte & 0x0F);
+
+	return(ns*100 + ns10*10);
+}
+
+/*
+ * translate ns coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short
+NSto10PS(unsigned char spd_byte)
+{
+	return(spd_byte*100);
+}
+
+#ifdef CONFIG_ZUMA_V2
+static int
+check_dimm(uchar slot, sdram_info_t *info)
+{
+        /* assume 2 dimms, 2 banks each 256M - we dont have an
+	 * dimm i2c so rely on the detection routines later */
+
+	memset(info, 0, sizeof(*info));
+
+	info->slot = slot;
+	info->banks = 2;	/* Detect later */
+	    info->registered = 0;
+	info->drb_size = 32;	/* 16 - 256MBit, 32 - 512MBit
+				   but doesn't matter, both do same
+				   thing in setup_sdram() */
+	    info->tpar = 3;
+	    info->tras_clocks = 5;
+	    info->burst_len = 4;
+#ifdef CONFIG_ECC
+	info->ecc = 0;		/* Detect later */
+#endif /* CONFIG_ECC */
+	return 0;
+}
+
+#else /* ! CONFIG_ZUMA_V2 */
+
+/* This code reads the SPD chip on the sdram and populates
+ * the array which is passed in with the relevant information */
+static int
+check_dimm(uchar slot, sdram_info_t *info)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	uchar addr = slot == 0 ? DIMM0_I2C_ADDR : DIMM1_I2C_ADDR;
+	int ret;
+	uchar rows, cols, sdram_banks, supp_cal, width, cal_val;
+	ulong tmemclk;
+	uchar trp_clocks, trcd_clocks;
+	uchar data[128];
+
+	get_clocks ();
+
+ 	tmemclk = 1000000000 / (gd->bus_clk / 100);  /* in 10 ps units */
+
+#ifdef CONFIG_EVB64260_750CX
+	if (0 != slot) {
+		printf("check_dimm: The EVB-64260-750CX only has 1 DIMM,");
+		printf("            called with slot=%d insetad!\n", slot);
+		return 0;
+	}
+#endif
+	DP(puts("before i2c read\n"));
+
+	ret = i2c_read(addr, 0, 128, data, 0);
+
+	DP(puts("after i2c read\n"));
+
+	/* zero all the values */
+	memset(info, 0, sizeof(*info));
+
+	if (ret) {
+		DP(printf("No DIMM in slot %d [err = %x]\n", slot, ret));
+		return 0;
+	}
+
+	/* first, do some sanity checks */
+	if (data[2] != 0x4) {
+		printf("Not SDRAM in slot %d\n", slot);
+		return 0;
+	}
+
+	/* get various information */
+	rows = data[3];
+	cols = data[4];
+	info->banks = data[5];
+	sdram_banks = data[17];
+	width = data[13] & 0x7f;
+
+	DP(printf("sdram_banks: %d, banks: %d\n", sdram_banks, info->banks));
+
+	/* check if the memory is registered */
+	if (data[21] & (BIT1 | BIT4))
+		info->registered = 1;
+
+#ifdef CONFIG_ECC
+	/* check for ECC/parity [0 = none, 1 = parity, 2 = ecc] */
+	info->ecc = (data[11] & 2) >> 1;
+#endif
+
+	/* bit 1 is CL2, bit 2 is CL3 */
+	supp_cal = (data[18] & 0x6) >> 1;
+
+	/* compute the relevant clock values */
+	trp_clocks = (NSto10PS(data[27])+(tmemclk-1)) / tmemclk;
+	trcd_clocks = (NSto10PS(data[29])+(tmemclk-1)) / tmemclk;
+	info->tras_clocks = (NSto10PS(data[30])+(tmemclk-1)) / tmemclk;
+
+	DP(printf("trp = %d\ntrcd_clocks = %d\ntras_clocks = %d\n",
+		  trp_clocks, trcd_clocks, info->tras_clocks));
+
+	/* try a CAS latency of 3 first... */
+	cal_val = 0;
+	if (supp_cal & 3) {
+		if (NS10to10PS(data[9]) <= tmemclk)
+			cal_val = 3;
+	}
+
+	/* then 2... */
+	if (supp_cal & 2) {
+		if (NS10to10PS(data[23]) <= tmemclk)
+			cal_val = 2;
+	}
+
+	DP(printf("cal_val = %d\n", cal_val));
+
+	/* bummer, did't work... */
+	if (cal_val == 0) {
+		DP(printf("Couldn't find a good CAS latency\n"));
+		return 0;
+	}
+
+	/* get the largest delay -- these values need to all be the same
+	 * see Res#6 */
+	info->tpar = cal_val;
+	if (trp_clocks > info->tpar)
+		info->tpar = trp_clocks;
+	if (trcd_clocks > info->tpar)
+		info->tpar = trcd_clocks;
+
+	DP(printf("tpar set to: %d\n", info->tpar));
+
+#ifdef CFG_BROKEN_CL2
+	if (info->tpar == 2){
+		info->tpar = 3;
+	        DP(printf("tpar fixed-up to: %d\n", info->tpar));
+	}
+#endif
+	/* compute the module DRB size */
+	info->drb_size = (((1 << (rows + cols)) * sdram_banks) * width) / _16M;
+
+	DP(printf("drb_size set to: %d\n", info->drb_size));
+
+	/* find the burst len */
+	info->burst_len = data[16] & 0xf;
+	if ((info->burst_len & 8) == 8) {
+		info->burst_len = 1;
+	} else if ((info->burst_len & 4) == 4) {
+		info->burst_len = 0;
+	} else {
+		return 0;
+	}
+
+	info->slot = slot;
+	return 0;
+}
+#endif /* ! CONFIG_ZUMA_V2 */
+
+static int
+setup_sdram_common(sdram_info_t info[2])
+{
+    	ulong tmp;
+	int tpar=2, tras_clocks=5, registered=1, ecc=2;
+
+	if(!info[0].banks && !info[1].banks) return 0;
+
+	if(info[0].banks) {
+	    if(info[0].tpar>tpar) tpar=info[0].tpar;
+	    if(info[0].tras_clocks>tras_clocks) tras_clocks=info[0].tras_clocks;
+	    if(!info[0].registered) registered=0;
+	    if(info[0].ecc!=2) ecc=0;
+	}
+
+	if(info[1].banks) {
+	    if(info[1].tpar>tpar) tpar=info[1].tpar;
+	    if(info[1].tras_clocks>tras_clocks) tras_clocks=info[1].tras_clocks;
+	    if(!info[1].registered) registered=0;
+	    if(info[1].ecc!=2) ecc=0;
+	}
+
+	/* SDRAM configuration */
+	tmp = GTREGREAD(SDRAM_CONFIGURATION);
+
+	/* Turn on physical interleave if both DIMMs
+	 * have even numbers of banks. */
+	if( (info[0].banks == 0 || info[0].banks == 2) &&
+	    (info[1].banks == 0 || info[1].banks == 2) ) {
+	    /* physical interleave on */
+	    tmp &= ~(1 << 15);
+	} else {
+	    /* physical interleave off */
+	    tmp |= (1 << 15);
+	}
+
+	tmp |= (registered << 17);
+
+	/* Use buffer 1 to return read data to the CPU
+	 * See Res #12 */
+	tmp |= (1 << 26);
+
+	GT_REG_WRITE(SDRAM_CONFIGURATION, tmp);
+	DP(printf("SDRAM config: %08x\n",
+		GTREGREAD(SDRAM_CONFIGURATION)));
+
+	/* SDRAM timing */
+	tmp = (((tpar == 3) ? 2 : 1) |
+	       (((tpar == 3) ? 2 : 1) << 2) |
+	       (((tpar == 3) ? 2 : 1) << 4) |
+	       (tras_clocks << 8));
+
+#ifdef CONFIG_ECC
+	/* Setup ECC */
+	if (ecc == 2) tmp |= 1<<13;
+#endif /* CONFIG_ECC */
+
+	GT_REG_WRITE(SDRAM_TIMING, tmp);
+	DP(printf("SDRAM timing: %08x (%d,%d,%d,%d)\n",
+		GTREGREAD(SDRAM_TIMING), tpar,tpar,tpar,tras_clocks));
+
+	/* SDRAM address decode register */
+	/* program this with the default value */
+	GT_REG_WRITE(SDRAM_ADDRESS_DECODE, 0x2);
+	DP(printf("SDRAM decode: %08x\n",
+		GTREGREAD(SDRAM_ADDRESS_DECODE)));
+
+	return 0;
+}
+
+/* sets up the GT properly with information passed in */
+static int
+setup_sdram(sdram_info_t *info)
+{
+	ulong tmp, check;
+	ulong *addr = 0;
+	int i;
+
+	/* sanity checking */
+	if (! info->banks) return 0;
+
+	/* ---------------------------- */
+	/* Program the GT with the discovered data */
+
+	/* bank parameters */
+	tmp = (0xf<<16);	/* leave all virt bank pages open */
+
+	DP(printf("drb_size: %d\n", info->drb_size));
+	switch (info->drb_size) {
+	case 1:
+		tmp |= (1 << 14);
+		break;
+	case 4:
+	case 8:
+		tmp |= (2 << 14);
+		break;
+	case 16:
+	case 32:
+		tmp |= (3 << 14);
+		break;
+	default:
+		printf("Error in dram size calculation\n");
+		return 1;
+	}
+
+	/* SDRAM bank parameters */
+	/* the param registers for slot 1 (banks 2+3) are offset by 0x8 */
+	GT_REG_WRITE(SDRAM_BANK0PARAMETERS + (info->slot * 0x8), tmp);
+	GT_REG_WRITE(SDRAM_BANK1PARAMETERS + (info->slot * 0x8), tmp);
+	DP(printf("SDRAM bankparam slot %d (bank %d+%d): %08lx\n", info->slot, info->slot*2, (info->slot*2)+1, tmp));
+
+	/* set the SDRAM configuration for each bank */
+	for (i = info->slot * 2; i < ((info->slot * 2) + info->banks); i++) {
+		DP(printf("*** Running a MRS cycle for bank %d ***\n", i));
+
+		/* map the bank */
+		memory_map_bank(i, 0, GB/4);
+
+		/* set SDRAM mode */
+		GT_REG_WRITE(SDRAM_OPERATION_MODE, 0x3);
+		check = GTREGREAD(SDRAM_OPERATION_MODE);
+
+		/* dummy write */
+		*addr = 0;
+
+		/* wait for the command to complete */
+		while ((GTREGREAD(SDRAM_OPERATION_MODE) & (1 << 31)) == 0)
+			;
+
+		/* switch back to normal operation mode */
+		GT_REG_WRITE(SDRAM_OPERATION_MODE, 0);
+		check = GTREGREAD(SDRAM_OPERATION_MODE);
+
+		/* unmap the bank */
+		memory_map_bank(i, 0, 0);
+		DP(printf("*** MRS cycle for bank %d done ***\n", i));
+	}
+
+	return 0;
+}
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+static long int
+dram_size(long int *base, long int maxsize)
+{
+    volatile long int	 *addr, *b=base;
+    long int	 cnt, val, save1, save2;
+
+#define STARTVAL (1<<20)	/* start test at 1M */
+    for (cnt = STARTVAL/sizeof(long); cnt < maxsize/sizeof(long); cnt <<= 1) {
+	    addr = base + cnt;	/* pointer arith! */
+
+	    save1=*addr;	/* save contents of addr */
+	    save2=*b;		/* save contents of base */
+
+	    *addr=cnt;		/* write cnt to addr */
+	    *b=0;		/* put null at base */
+
+	    /* check at base address */
+	    if ((*b) != 0) {
+		*addr=save1;	/* restore *addr */
+		*b=save2;	/* restore *b */
+		return (0);
+	    }
+	    val = *addr;	/* read *addr */
+
+	    *addr=save1;
+	    *b=save2;
+
+	    if (val != cnt) {
+		    /* fix boundary condition.. STARTVAL means zero */
+		    if(cnt==STARTVAL/sizeof(long)) cnt=0;
+		    return (cnt * sizeof(long));
+	    }
+    }
+    return maxsize;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* U-Boot interface function to SDRAM init - this is where all the
+ * controlling logic happens */
+long int
+initdram(int board_type)
+{
+	ulong checkbank[4] = { [0 ... 3] = 0 };
+	int bank_no;
+        ulong total;
+	int nhr;
+	sdram_info_t dimm_info[2];
+
+
+	/* first, use the SPD to get info about the SDRAM */
+
+	/* check the NHR bit and skip mem init if it's already done */
+	nhr = get_hid0() & (1 << 16);
+
+	if (nhr) {
+		printf("Skipping SDRAM setup due to NHR bit being set\n");
+	} else {
+		/* DIMM0 */
+		check_dimm(0, &dimm_info[0]);
+
+		/* DIMM1 */
+#ifndef CONFIG_EVB64260_750CX /* EVB64260_750CX has only 1 DIMM */
+		check_dimm(1, &dimm_info[1]);
+#else /* CONFIG_EVB64260_750CX */
+		memset(&dimm_info[1], 0, sizeof(sdram_info_t));
+#endif
+
+		/* unmap all banks */
+		memory_map_bank(0, 0, 0);
+		memory_map_bank(1, 0, 0);
+		memory_map_bank(2, 0, 0);
+		memory_map_bank(3, 0, 0);
+
+		/* Now, program the GT with the correct values */
+		if (setup_sdram_common(dimm_info)) {
+			printf("Setup common failed.\n");
+		}
+
+		if (setup_sdram(&dimm_info[0])) {
+			printf("Setup for DIMM1 failed.\n");
+		}
+
+		if (setup_sdram(&dimm_info[1])) {
+			printf("Setup for DIMM2 failed.\n");
+		}
+
+		/* set the NHR bit */
+		set_hid0(get_hid0() | (1 << 16));
+	}
+	/* next, size the SDRAM banks */
+
+	total = 0;
+	if (dimm_info[0].banks > 0) checkbank[0] = 1;
+	if (dimm_info[0].banks > 1) checkbank[1] = 1;
+	if (dimm_info[0].banks > 2)
+		printf("Error, SPD claims DIMM1 has >2 banks\n");
+
+	if (dimm_info[1].banks > 0) checkbank[2] = 1;
+	if (dimm_info[1].banks > 1) checkbank[3] = 1;
+	if (dimm_info[1].banks > 2)
+		printf("Error, SPD claims DIMM2 has >2 banks\n");
+
+	/* Generic dram sizer: works even if we don't have i2c DIMMs,
+	 * as long as the timing settings are more or less correct */
+
+	/*
+	 * pass 1: size all the banks, using first bat (0-256M)
+	 * 	   limitation: we only support 256M per bank due to
+	 *  	   us only having 1 BAT for all DRAM
+	 */
+	for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
+		/* skip over banks that are not populated */
+		if (! checkbank[bank_no])
+			continue;
+
+		DP(printf("checking bank %d\n", bank_no));
+
+		memory_map_bank(bank_no, 0, GB/4);
+		checkbank[bank_no] = dram_size(NULL, GB/4);
+		memory_map_bank(bank_no, 0, 0);
+
+		DP(printf("bank %d %08lx\n", bank_no, checkbank[bank_no]));
+	}
+
+	/*
+	 * pass 2: contiguously map each bank into physical address
+	 * 	   space.
+	 */
+	dimm_info[0].banks=dimm_info[1].banks=0;
+	for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
+		if(!checkbank[bank_no]) continue;
+
+		dimm_info[bank_no/2].banks++;
+		dimm_info[bank_no/2].size+=checkbank[bank_no];
+
+		memory_map_bank(bank_no, total, checkbank[bank_no]);
+#ifdef MAP_PCI
+		memory_map_bank_pci(bank_no, total, checkbank[bank_no]);
+#endif
+		total += checkbank[bank_no];
+	}
+
+#ifdef CONFIG_ECC
+#ifdef CONFIG_ZUMA_V2
+	/*
+	 * We always enable ECC when bank 2 and 3 are unpopulated
+	 * If we 2 or 3 are populated, we CAN'T support ECC.
+	 * (Zuma boards only support ECC in banks 0 and 1; assume that
+	 * in that configuration, ECC chips are mounted, even for stacked
+	 * chips)
+	 */
+	if (checkbank[2]==0 && checkbank[3]==0) {
+	    	dimm_info[0].ecc=2;
+		GT_REG_WRITE(SDRAM_TIMING, GTREGREAD(SDRAM_TIMING) | (1 << 13));
+		/* TODO: do we have to run MRS cycles again? */
+	}
+#endif /* CONFIG_ZUMA_V2 */
+
+	if (GTREGREAD(SDRAM_TIMING) & (1 << 13)) {
+		puts("[ECC] ");
+	}
+#endif /* CONFIG_ECC */
+
+#ifdef DEBUG
+	dump_dimm_info(&dimm_info[0]);
+	dump_dimm_info(&dimm_info[1]);
+#endif
+	/* TODO: return at MOST 256M? */
+        /* return total > GB/4 ? GB/4 : total; */
+	return total;
+}
diff --git a/board/evb64260/serial.c b/board/evb64260/serial.c
new file mode 100644
index 0000000..d9c7a15
--- /dev/null
+++ b/board/evb64260/serial.c
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * serial.c - serial support for the gal ev board
+ */
+
+/* supports both the 16650 duart and the MPSC */
+
+#include <common.h>
+#include <command.h>
+#include <galileo/memory.h>
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+#include <ns16550.h>
+#endif
+
+#include "serial.h"
+
+#include "mpsc.h"
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1,
+				(NS16550_t) CFG_NS16550_COM2 };
+#endif
+
+#ifdef CONFIG_MPSC
+
+int serial_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+	int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+#endif
+
+	mpsc_init(gd->baudrate);
+
+	/* init the DUART chans so that KGDB in the kernel can use them */
+#ifdef CFG_INIT_CHAN1
+	NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+	return (0);
+}
+
+void
+serial_putc(const char c)
+{
+	if (c == '\n')
+		mpsc_putchar('\r');
+
+	mpsc_putchar(c);
+}
+
+int
+serial_getc(void)
+{
+	return mpsc_getchar();
+}
+
+int
+serial_tstc(void)
+{
+	return mpsc_test_char();
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	galbrg_set_baudrate(CONFIG_MPSC_PORT, gd->baudrate);
+}
+
+#else /* ! CONFIG_MPSC */
+
+int serial_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+	(void)NS16550_init(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	(void)NS16550_init(COM_PORTS[1], clock_divisor);
+#endif
+
+	return (0);
+}
+
+void
+serial_putc(const char c)
+{
+	if (c == '\n')
+		NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+
+	NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+	return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+	return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+	NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+}
+
+#endif /* CONFIG_MPSC */
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar (int c)
+{
+	serial_putc (c);
+}
+
+void
+putDebugStr (const char *str)
+{
+	serial_puts (str);
+}
+
+int
+getDebugChar (void)
+{
+	return serial_getc();
+}
+
+void
+kgdb_interruptible (int yes)
+{
+	return;
+}
+#endif	/* CFG_CMD_KGDB	*/
diff --git a/board/gen860t/README b/board/gen860t/README
new file mode 100644
index 0000000..761ceed
--- /dev/null
+++ b/board/gen860t/README
@@ -0,0 +1,142 @@
+
+This directory contains board specific code for a generic MPC860T based
+embedded computer, called 'GEN860T'.  The design is generic in the sense that
+common, readily available components are used and that the architecture of the
+system is i(relatively) straightforward:
+
+	One eight bit wide boot (FLASH) memory
+	32 bit main memory using SDRAM
+	DOC 2000+
+	Ethernet PHY
+	Some I2C peripheral devices: Atmel AT24C256 EEPROM, Maxim DS1337 RTC.
+	Some other miscellaneous peripherals
+
+NOTE: There are references to a XIlinx FPGA and Mil-Std 1553 databus in this
+port.  I guess the computer is not as generic as I first said 8)  However,
+these extras can be safely ignored.
+
+Given the GEN860T files, it should be pretty easy to reverse engineer the
+hardware configuration, if that's useful to you.  Hopefully, this code will
+be useful to someone as a basis for a port to a new system or as a head start
+on a custom design.  If you end up using any of this, I would appreciate
+hearing from you, especially if you discover bugs or find ways to improve the
+quality of this U-Boot port.
+
+Here are the salient features of the system:
+Clock						:	33 Mhz oscillator
+Processor core frequency	:	66 Mhz  if in 1:2:1 mode; can also run 1:1
+Bus frequency				:	33 Mhz
+
+Main memory:
+	Type	: SDRAM
+	Width	: 32 bits
+	Size	: 64 megabytes
+	Chip	: Two Micron MT48LC16M16A2TG-7E
+	CS		: MPC860T CS1*/UPMA
+	UPMA CONNECTIONS:
+		SDRAM A10	: GPLA0*
+		SDRAM CAS*	: GPLA2*
+		SDRAM WE*	: GPLA3*
+		SDRAM RAS*	: GPLA4*
+
+Boot memory:
+	Type	: FLASH
+	Width	: 8 bits
+	Size	: 16 megabytes
+	Chip	: One Intel 28F128J3A (StrataFlash)
+	CS		: MPC860T CS0*/GPCM (this is the "boot" chip select)
+
+EEPROM memory:
+	Type	: Serial I2C EEPROM
+	Width	: 8 bits
+	Size	: 32 kibibytes
+	Chip	: One Atmel AT25C256
+	CS		: 0x50 (external I2C address pins on device are tied to GND)
+
+Filesystem memory:
+	Type	: NAND FLASH (Toshiba)
+	Width	: 8 bits (i.e. interface to DOC is 8 bits)
+	Size	: 32 megabytes
+	Chip	: One DiskOnCHip Millenium Plus (DOC 2000+)
+	CS		: MPC860T CS2*/GPCM
+
+Network support:
+	MAC		: MPC86OT FEC (Fast Ethernet Controller)
+	PHY		: Intel LXT971A
+	MII Addr: 0x0 (hardwired on the board)
+	MII IRQ	:
+
+Console:
+	RS-232 on SMC1 (Maxim MAX3232 LVCMOS-RS232 level shifter)
+
+Real Time Clock:
+	Type	: Low power, I2C interface
+	Chip	: Maxim DS1337
+	CS		: Address 0x68 on I2C bus
+
+	The MPC860T's internal RTC has a defect in Mask rev D that increases
+	the current drain on the KAPWR line to 10 mA.  Since this is an
+	unreasonable amount of current draw for a RTC, and Motorola does not
+	plan to fix this in future mask revisions, a serial (I2C) RTC that
+	works has been included instead.  NOTE that the DS1337 can be
+	configured to output a 32768 Hz clock while the main power is on.
+	This clock output has been routed to the MPC860T's EXTAL pin to allow
+	the internal RTC to be used.  NOTE also that due to yet another
+	defect in the rev D mask, the RTC does not operate reliably when the
+	internal RTC divisor is set to use a 32768 Hz reference.  So just use
+	the I2C RTC.
+
+Miscellaneous:
+	Xilinx Virtex FPGA on CS3*/GPCM.
+	Virtex FPGA slave SelectMap interface on cs4*/UPMB.
+	Mil-Std 1553 databus interface on CS5*/GPCM.
+	Audio sounder (beeper) with digital volume control connected to SPKROUT.
+
+Issues:
+	The DOC 2000+ returns 0x40 as its device ID when probed using the method
+	desxribed in the DOC datasheet.  Unfortunately, the U-Boot DOC driver
+	does not recognize this device.  As of this writing, it seems that MTD
+	does not support the DOC 2000+ either.
+
+Status:
+	Everything appears to work except DOC support. As of this writing,
+	David Woodhouse has stated on the MTD mailing list that he has no
+	knowledge of the DOC Millineum Plus and therfore there is no support
+	in MTD for this device.  I wish I had known this sooner :(
+
+The GEN860T board specific files and configuration is based on the work
+of others who have contributed to U-Boot. The copright and license notices
+of these authors have been retained wherever their code has been reused.
+All new code to support the GEN860T board is:
+
+	(C) Copyright 2001-2002
+	Keith Outwater (keith_outwater@mvis.com)
+
+and the following license applies:
+
+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,
+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
+
+Thanks to Wolfgang Denk for a great software package and to everyone
+who contributed to its development.
+
+Keith Outwater
+Sr. Staff Engineer
+Microvision, Inc.
+<keith_outwater@mvis.com>
+<outwater@eskimo.com>
+
+vim: set ts=4 sw=4 tw=78:
+
diff --git a/board/gen860t/beeper.c b/board/gen860t/beeper.c
new file mode 100644
index 0000000..46fe66b
--- /dev/null
+++ b/board/gen860t/beeper.c
@@ -0,0 +1,213 @@
+/*
+ * (C) Copyright 2002
+ * Keith Outwater, keith_outwater@mvis.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
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <linux/ctype.h>
+
+/*
+ * Basic beeper support for the GEN860T board.  The GEN860T includes
+ * an audio sounder driven by a Phillips TDA8551 amplifier.  The
+ * TDA8551 features a digital volume control which uses a "trinary"
+ * input (high/high-Z/low) to set volume.  The 860's SPKROUT pin
+ * drives the amplifier input.
+ */
+
+
+/*
+ * Initialize beeper-related hardware. Initialize timer 1 for use with
+ * the beeper. Use 66 Mhz internal clock with prescale of 33 to get
+ * 1 uS period per count.
+ * FIXME: we should really compute the prescale based on the reported
+ * core clock frequency.
+ */
+void
+init_beeper(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_RST1 | TGCR_STP1;
+	immap->im_cpmtimer.cpmt_tmr1 = ((33 << TMR_PS_SHIFT) & TMR_PS_MSK)
+								 | TMR_OM | TMR_FRR | TMR_ICLK_IN_GEN;
+	immap->im_cpmtimer.cpmt_tcn1 = 0;
+	immap->im_cpmtimer.cpmt_ter1 = 0xffff;
+	immap->im_cpmtimer.cpmt_tgcr |= TGCR_RST1;
+}
+
+
+/*
+ * Set beeper frequency.  Max allowed frequency is 2.5 KHz.  This limit
+ * is mostly arbitrary, but the beeper isn't really much good beyond this
+ * frequency.
+ */
+void
+set_beeper_frequency(uint frequency)
+{
+#define FREQ_LIMIT	2500
+
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	/*
+	 * Compute timer ticks given desired frequency.  The timer is set up
+	 * to count 0.5 uS per tick and it takes two ticks per cycle (Hz).
+	 */
+	if (frequency > FREQ_LIMIT) frequency = FREQ_LIMIT;
+	frequency = 1000000/frequency;
+	immap->im_cpmtimer.cpmt_trr1 = (ushort)frequency;
+}
+
+
+/*
+ * Turn the beeper on
+ */
+void
+beeper_on(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_STP1;
+}
+
+
+/*
+ * Turn the beeper off
+ */
+void
+beeper_off(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	immap->im_cpmtimer.cpmt_tgcr |= TGCR_STP1;
+}
+
+
+/*
+ * Increase or decrease the beeper volume.  Volume can be set
+ * from off to full in 64 steps.  To increase volume, the output
+ * pin is actively driven high, then returned to tristate.
+ * To decrease volume, output a low on the port pin (no need to
+ * change pin mode to tristate) then output a high to go back to
+ * tristate.
+ */
+void
+set_beeper_volume(int steps)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+	int i;
+
+	if (steps >= 0) {
+		for (i = 0; i < (steps >= 64 ? 64 : steps); i++) {
+			immap->im_cpm.cp_pbodr &= ~(0x80000000 >> 19);
+			udelay(1);
+			immap->im_cpm.cp_pbodr |= (0x80000000 >> 19);
+			udelay(1);
+		}
+	}
+	else {
+		for (i = 0; i > (steps <= -64 ? -64 : steps); i--) {
+			immap->im_cpm.cp_pbdat &= ~(0x80000000 >> 19);
+			udelay(1);
+			immap->im_cpm.cp_pbdat |= (0x80000000 >> 19);
+			udelay(1);
+		}
+	}
+}
+
+
+/*
+ * Check the environment to see if the beeper needs beeping.
+ * Controlled by a sequence of the form:
+ * freq/delta volume/on time/off time;... where:
+ * freq 		= frequency in Hz (0 - 2500)
+ * delta volume = volume steps up or down (-64 <= vol <= 64)
+ * on time		= time in mS
+ * off time		= time in mS
+ *
+ * Return 1 on success, 0 on failure
+ */
+int
+do_beeper(char *sequence)
+{
+#define DELIMITER	';'
+
+int args[4];
+int i;
+int val;
+char *p = sequence;
+char *tp;
+
+	/*
+	 * Parse the control sequence.  This is a really simple parser
+	 * without any real error checking.  You can probably blow it
+	 * up really easily.
+	 */
+	if (*p == '\0' || !isdigit(*p)) {
+		printf("%s:%d: null or invalid string (%s)\n",
+				__FILE__, __LINE__, p);
+		return 0;
+	}
+
+	i = 0;
+	while (*p != '\0') {
+		while (*p != DELIMITER) {
+			if (i > 3) i = 0;
+			val = (int) simple_strtol(p, &tp, 0);
+			if (tp == p) {
+				printf("%s:%d: no digits or bad format\n",
+								__FILE__,__LINE__);
+				return 0;
+			}
+			else {
+				args[i] = val;
+			}
+
+			i++;
+			if (*tp == DELIMITER)
+				p = tp;
+			else
+				p = ++tp;
+		}
+		p++;
+
+		/*
+		 * Well, we got something that has a chance of being correct
+		 */
+#if 0
+		for (i = 0; i < 4; i++) {
+			printf("%s:%d:arg %d = %d\n", __FILE__, __LINE__, i, args[i]);
+		}
+		printf("\n");
+#endif
+
+		set_beeper_frequency(args[0]);
+		set_beeper_volume(args[1]);
+		beeper_on();
+		udelay(1000 * args[2]);
+		beeper_off();
+		udelay(1000 * args[3]);
+	}
+	return 1;
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/flash.c b/board/gen860t/flash.c
new file mode 100644
index 0000000..902b1b0
--- /dev/null
+++ b/board/gen860t/flash.c
@@ -0,0 +1,644 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvsi.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
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+#if defined(CFG_ENV_IS_IN_FLASH)
+# 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
+# ifndef  CFG_ENV_SECT_SIZE
+#  define CFG_ENV_SECT_SIZE  CFG_ENV_SIZE
+# endif
+#endif
+
+/*
+ * Use buffered writes to flash by default - they are about 32x faster than
+ * single byte writes.
+ */
+#ifndef  CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#endif
+
+/*
+ * Max time to wait (in mS) for flash device to allocate a write buffer.
+ */
+#ifndef CFG_FLASH_ALLOC_BUFFER_TOUT
+#define CFG_FLASH_ALLOC_BUFFER_TOUT		100
+#endif
+
+/*
+ * These functions support a single Intel StrataFlash device (28F128J3A)
+ * in byte mode only!.  The flash routines are very basic and simple
+ * since there isn't really any remapping necessary.
+ */
+
+/*
+ * Intel SCS (Scalable Command Set) command definitions
+ * (taken from 28F128J3A datasheet)
+ */
+#define SCS_READ_CMD				0xff
+#define SCS_READ_ID_CMD				0x90
+#define SCS_QUERY_CMD				0x98
+#define SCS_READ_STATUS_CMD			0x70
+#define SCS_CLEAR_STATUS_CMD		0x50
+#define SCS_WRITE_BUF_CMD			0xe8
+#define SCS_PROGRAM_CMD				0x40
+#define SCS_BLOCK_ERASE_CMD			0x20
+#define SCS_BLOCK_ERASE_RESUME_CMD	0xd0
+#define SCS_PROGRAM_RESUME_CMD		0xd0
+#define SCS_BLOCK_ERASE_SUSPEND_CMD	0xb0
+#define SCS_SET_BLOCK_LOCK_CMD		0x60
+#define SCS_CLR_BLOCK_LOCK_CMD		0x60
+
+/*
+ * SCS status/extended status register bit definitions
+ */
+#define  SCS_SR7					0x80
+#define  SCS_XSR7					0x80
+
+/*---------------------------------------------------------------------*/
+#if 0
+#define DEBUG_FLASH
+#endif
+
+#ifdef DEBUG_FLASH
+#define PRINTF(fmt,args...) printf(fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+flash_info_t	flash_info[CFG_MAX_FLASH_BANKS];
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_char *addr, flash_info_t *info);
+static int write_data8 (flash_info_t *info, ulong dest, uchar data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ * Initialize the flash memory.
+ */
+unsigned long
+flash_init (void)
+{
+	volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	unsigned long size_b0;
+	int i;
+
+	for (i= 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+	}
+
+	/*
+	 * The gen860t board only has one FLASH memory device, so the
+	 * FLASH Bank configuration is done statically.
+	 */
+	PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM);
+	size_b0 = flash_get_size((vu_char *)FLASH_BASE0_PRELIM, &flash_info[0]);
+	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+		printf ("## Unknown FLASH on Bank 0: "
+				"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
+				flash_info[0].flash_id,size_b0, size_b0 << 20);
+	}
+
+	PRINTF("## Before remap:\n"
+		   "  BR0: 0x%08x    OR0: 0x%08x\n  BR1: 0x%08x    OR1: 0x%08x\n",
+		   memctl->memc_br0, memctl->memc_or0,
+		   memctl->memc_br1, memctl->memc_or1);
+
+	/*
+	 * Remap FLASH according to real size
+	 */
+	memctl->memc_or0 |= (-size_b0 & 0xFFFF8000);
+	memctl->memc_br0 |= (CFG_FLASH_BASE & BR_BA_MSK);
+
+	PRINTF("## After remap:\n"
+		   "  BR0: 0x%08x    OR0: 0x%08x\n", memctl->memc_br0, memctl->memc_or0);
+
+	/*
+	 * Re-do sizing to get full correct info
+	 */
+	size_b0 = flash_get_size ((vu_char *)CFG_FLASH_BASE, &flash_info[0]);
+	flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+	flash_info[0].size = size_b0;
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+	/*
+	 * Monitor protection is 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
+	/*
+	 * Environment protection ON by default
+	 */
+	flash_protect(FLAG_PROTECT_SET,
+		      	  CFG_ENV_ADDR,
+		      	  CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+		      	  &flash_info[0]);
+#endif
+
+	PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0);
+	return (size_b0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Fill in the FLASH offset table
+ */
+static void
+flash_get_offsets (ulong base, flash_info_t *info)
+{
+	int i;
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		return;
+	}
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+		case FLASH_MAN_INTEL:
+	    	for (i = 0; i < info->sector_count; i++) {
+				info->start[i] = base;
+				base += 1024 * 128;
+	    	}
+	    	return;
+
+		default:
+	   		printf ("Don't know sector offsets for FLASH"
+			        " type 0x%lx\n", info->flash_id);
+	    return;
+	}
+}
+
+
+/*-----------------------------------------------------------------------
+ * Display FLASH device info
+ */
+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_INTEL:
+			printf ("Intel ");
+			break;
+	default:
+			printf ("Unknown Vendor ");
+			break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_28F128J3A:
+			printf ("28F128J3A (128Mbit = 128K x 128)\n");
+			break;
+	default:
+			printf ("Unknown Chip Type\n");
+			break;
+	}
+
+	if (info->size >= (1024 * 1024)) {
+		i = 20;
+	} else {
+		i = 10;
+	}
+	printf ("  Size: %ld %cB in %d Sectors\n",
+			info->size >> i,
+			(i == 20) ? 'M' : 'k',
+			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;
+}
+
+
+/*-----------------------------------------------------------------------
+ * Get size and other information for a FLASH device.
+ * NOTE: The following code cannot be run from FLASH!
+ */
+static
+ulong flash_get_size (vu_char *addr, flash_info_t *info)
+{
+#define NO_FLASH	0
+
+	vu_char value[2];
+
+	/*
+	 * Try to read the manufacturer ID
+	 */
+	addr[0] = SCS_READ_CMD;
+	addr[0] = SCS_READ_ID_CMD;
+	value[0] = addr[0];
+	value[1] = addr[2];
+	addr[0] = SCS_READ_CMD;
+
+	PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong)addr, value[0]);
+	switch (value[0]) {
+		case (INTEL_MANUFACT & 0xff):
+			info->flash_id = FLASH_MAN_INTEL;
+			break;
+		default:
+			info->flash_id = FLASH_UNKNOWN;
+			info->sector_count = 0;
+			info->size = 0;
+			return (NO_FLASH);
+	}
+
+	/*
+	 * Read the device ID
+	 */
+	PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong)(&addr[2]), value[1]);
+	switch (value[1]) {
+		case (INTEL_ID_28F128J3A & 0xff):
+			info->flash_id += FLASH_28F128J3A;
+			info->sector_count = 128;
+			info->size = 16 * 1024 * 1024;
+			break;
+
+		default:
+			info->flash_id = FLASH_UNKNOWN;
+			return (NO_FLASH);
+	}
+
+	if (info->sector_count > CFG_MAX_FLASH_SECT) {
+		printf ("** ERROR: sector count %d > max (%d) **\n",
+				info->sector_count, CFG_MAX_FLASH_SECT);
+				info->sector_count = CFG_MAX_FLASH_SECT;
+	}
+	return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Erase the specified sectors in the specified FLASH device
+ */
+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;
+	}
+
+	if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
+		printf ("Can erase only Intel flash types - aborted\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 = get_timer (0);
+	last  = start;
+
+	/*
+	 * Start erase on unprotected sectors
+	 */
+	for (sect = s_first; sect<=s_last; sect++) {
+		if (info->protect[sect] == 0) {	/* not protected */
+			vu_char *addr = (uchar *)(info->start[sect]);
+			vu_char status;
+
+			/*
+			 * Disable interrupts which might cause a timeout
+			 */
+			flag = disable_interrupts();
+
+			*addr = SCS_CLEAR_STATUS_CMD;
+			*addr = SCS_BLOCK_ERASE_CMD;
+			*addr = SCS_BLOCK_ERASE_RESUME_CMD;
+
+			/*
+			 * Re-enable interrupts if necessary
+			 */
+			if (flag)
+				enable_interrupts();
+
+			/*
+			 * Wait at least 80us - let's wait 1 ms
+			 */
+			udelay (1000);
+
+			while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+				if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+					printf ("Timeout\n");
+					*addr = SCS_BLOCK_ERASE_SUSPEND_CMD;
+					*addr = SCS_READ_CMD;
+					return 1;
+				}
+
+				/*
+				 * Show that we're waiting
+				 */
+				if ((now - last) > 1000) {	/* 1 second */
+					putc ('.');
+					last = now;
+				}
+			}
+			*addr = SCS_READ_CMD;
+		}
+	}
+	printf (" done\n");
+	return 0;
+}
+
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+/*
+ * Allocate a flash buffer, fill it with data and write it to the flash.
+ * 0 - OK
+ * 1 - Timeout on buffer request
+ *
+ * NOTE: After the last call to this function, WSM status needs to be checked!
+ */
+static int
+write_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,
+				    uint count)
+{
+	vu_char *block_addr_p = NULL;
+	vu_char *start_addr_p = NULL;
+	ulong blocksize = info_p->size / (ulong)info_p->sector_count;
+
+	int i;
+	uint time = get_timer(0);
+
+	PRINTF("%s:%d: src: 0x%p dest: 0x%p  count: %d\n",
+		   __FUNCTION__, __LINE__, src_p, dest_p, count);
+
+	/*
+	 * What block are we in? We already know that the source address is
+	 * in the flash address range, but we also can't cross a block boundary.
+	 * We assume that the block does not cross a boundary (we'll check before
+	 * calling this function).
+	 */
+ 	for (i = 0; i < info_p->sector_count; ++i) {
+		if ( ((ulong)dest_p >= info_p->start[i]) &&
+		    ((ulong)dest_p < (info_p->start[i] + blocksize)) ) {
+			PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
+				   __FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);
+			block_addr_p = (vu_char *)info_p->start[i];
+			break;
+		}
+	}
+
+	/*
+	 * Request a buffer
+	 */
+	*block_addr_p = SCS_WRITE_BUF_CMD;
+	while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {
+		if (get_timer(time) >  CFG_FLASH_ALLOC_BUFFER_TOUT) {
+			PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
+				   __FUNCTION__, __LINE__, block_addr_p,
+				   CFG_FLASH_ALLOC_BUFFER_TOUT);
+			return 1;
+		}
+		*block_addr_p = SCS_WRITE_BUF_CMD;
+	}
+
+	/*
+	 * Fill the buffer with data
+	 */
+	start_addr_p = dest_p;
+	*block_addr_p = count - 1; /* flash device wants count - 1 */
+	PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
+		   __FUNCTION__, __LINE__, block_addr_p);
+	for (i = 0; i < count; i++) {
+		*start_addr_p++ = *src_p++;
+	}
+
+	/*
+	 * Flush buffer to flash
+	 */
+	*block_addr_p = SCS_PROGRAM_RESUME_CMD;
+#if 1
+	time = get_timer(0);
+	while ((*block_addr_p & SCS_SR7) != SCS_SR7) {
+		if (get_timer(time) >  CFG_FLASH_WRITE_TOUT) {
+			PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
+				   __FUNCTION__, __LINE__, block_addr_p, CFG_FLASH_WRITE_TOUT);
+			return 1;
+		}
+	}
+
+#endif
+	return 0;
+}
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+int
+write_buff(flash_info_t *info_p, uchar *src_p, ulong addr, ulong count)
+{
+	int rc = 0;
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define FLASH_WRITE_BUF_SIZE	0x00000020	/* 32 bytes */
+	int i;
+	uint bufs;
+	ulong buf_count;
+	vu_char *sp;
+	vu_char *dp;
+#else
+	ulong wp;
+#endif
+
+	PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
+		   __FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);
+
+	if (info_p->flash_id == FLASH_UNKNOWN) {
+		return 4;
+	}
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+	sp = src_p;
+	dp = (uchar *)addr;
+
+	/*
+	 * For maximum performance, we want to align the start address to
+	 * the beginning of a write buffer boundary (i.e. A4-A0 of the
+	 * start address = 0). See how many bytes are required to get to a
+	 * write-buffer-aligned address.  If that number is non-zero, do
+	 * non buffered writes of the non-aligned data.  By doing non-buffered
+	 * writes, we avoid the problem of crossing a block (sector) boundary
+	 * with buffered writes.
+	 */
+	buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));
+	if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */
+		buf_count = 0;
+	}
+	if (buf_count > count) { /* not a full buffers worth of data to write */
+		buf_count = count;
+	}
+	count -= buf_count;
+
+	PRINTF("%s:%d: Write buffer alignment count = %ld\n",
+		   __FUNCTION__, __LINE__, buf_count);
+	while (buf_count-- >= 1) {
+		if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0)  {
+			return (rc);
+		}
+	}
+
+	PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);
+	if (count == 0) { /* all done */
+		PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
+			   __FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);
+		return (rc);
+	}
+
+	/*
+	 * Now that we are write buffer aligned, write full or partial buffers.
+	 * The fact that we are write buffer aligned automatically avoids
+	 * crossing a block address during a write buffer operation.
+	 */
+	bufs = count / FLASH_WRITE_BUF_SIZE;
+	PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,
+		   bufs, bufs);
+	while (bufs >= 1) {
+		rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);
+		if (rc != 0) {
+			PRINTF("%s:%d: ** Error writing buf %d\n",
+				   __FUNCTION__, __LINE__, bufs);
+			return (rc);
+		}
+		bufs--;
+		sp += FLASH_WRITE_BUF_SIZE;
+		dp += FLASH_WRITE_BUF_SIZE;
+	}
+
+	/*
+	 * Do the leftovers
+	 */
+	i = count % FLASH_WRITE_BUF_SIZE;
+	PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);
+	if (i > 0) {
+		rc = write_flash_buffer8(info_p, sp, dp, i);
+	}
+
+	sp = (vu_char*)info_p->start[0];
+	*sp = SCS_READ_CMD;
+	return (rc);
+
+#else
+	wp = addr;
+	while (count-- >= 1) {
+		if((rc = write_data8(info_p, wp++, *src_p++)) != 0)
+			return (rc);
+	}
+	return 0;
+#endif
+}
+
+
+/*-----------------------------------------------------------------------
+ * Write a byte to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int
+write_data8 (flash_info_t *info, ulong dest, uchar data)
+{
+	vu_char *addr = (vu_char *)dest;
+	vu_char status;
+	ulong start;
+	int flag;
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*addr & data) != data) {
+		return (2);
+	}
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	*addr = SCS_PROGRAM_CMD;
+	*addr = data;
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	start = get_timer (0);
+
+	while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+			*addr = SCS_READ_CMD;
+			return (1);
+		}
+	}
+	*addr = SCS_READ_CMD;
+	return (0);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/fpga.c b/board/gen860t/fpga.c
new file mode 100644
index 0000000..2c4fbf1
--- /dev/null
+++ b/board/gen860t/fpga.c
@@ -0,0 +1,401 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * Keith Outwater, keith_outwater@mvis.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
+ *
+ */
+
+/*
+ * Virtex2 FPGA configuration support for the GEN860T computer
+ */
+
+#include <common.h>
+#include <virtex2.h>
+#include <command.h>
+#include "fpga.h"
+
+#if (CONFIG_FPGA)
+
+#if 0
+#define GEN860T_FPGA_DEBUG
+#endif
+
+#ifdef GEN860T_FPGA_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define	PRINTF(fmt,args...)
+#endif
+
+/*
+ * Port bit numbers for the Selectmap controls
+ */
+#define FPGA_INIT_BIT_NUM		22	/* PB22 */
+#define FPGA_RESET_BIT_NUM		11	/* PC11 */
+#define FPGA_DONE_BIT_NUM		16	/* PB16 */
+#define FPGA_PROGRAM_BIT_NUM	7	/* PA7  */
+
+/* Note that these are pointers to code that is in Flash.  They will be
+ * relocated at runtime.
+ */
+Xilinx_Virtex2_Slave_SelectMap_fns fpga_fns = {
+	fpga_pre_config_fn,
+	fpga_pgm_fn,
+	fpga_init_fn,
+	fpga_err_fn,
+	fpga_done_fn,
+	fpga_clk_fn,
+	fpga_cs_fn,
+	fpga_wr_fn,
+	fpga_read_data_fn,
+	fpga_write_data_fn,
+	fpga_busy_fn,
+	fpga_abort_fn,
+	fpga_post_config_fn
+};
+
+Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
+	{ Xilinx_Virtex2,
+	  slave_selectmap,
+	  XILINX_XC2V3000_SIZE,
+	  (void *)&fpga_fns,
+	  0
+	}
+};
+
+/*
+ * Display FPGA revision information
+ */
+void
+print_fpga_revision(void)
+{
+	vu_long *rev_p = (vu_long *)0x60000008;
+
+	printf("FPGA Revision 0x%.8lx"
+		   " (Date %.2lx/%.2lx/%.2lx, Status \"%.1lx\", Version %.3lu)\n",
+		   *rev_p,
+		   ((*rev_p >> 28) & 0xf),
+		   ((*rev_p >> 20) & 0xff),
+		   ((*rev_p >> 12) & 0xff),
+		   ((*rev_p >> 8) & 0xf),
+		   (*rev_p & 0xff));
+}
+
+
+/*
+ * Perform a simple test of the FPGA to processor interface using the FPGA's
+ * inverting bus test register.  The great thing about doing a read/write
+ * test on a register that inverts it's contents is that you avoid any
+ * problems with bus charging.
+ * Return 0 on failure, 1 on success.
+ */
+int
+test_fpga_ibtr(void)
+{
+	vu_long *ibtr_p = (vu_long *)0x60000010;
+	vu_long readback;
+	vu_long compare;
+	int i;
+	int j;
+	int k;
+	int pass = 1;
+
+	static const ulong bitpattern[] = {
+		0xdeadbeef,	/* magic ID pattern for debug	*/
+		0x00000001,	/* single bit					*/
+		0x00000003,	/* two adjacent bits			*/
+		0x00000007,	/* three adjacent bits			*/
+		0x0000000F,	/* four adjacent bits			*/
+		0x00000005,	/* two non-adjacent bits		*/
+		0x00000015,	/* three non-adjacent bits		*/
+		0x00000055,	/* four non-adjacent bits		*/
+		0xaaaaaaaa,	/* alternating 1/0				*/
+	};
+
+	for (i = 0; i < 1024; i++) {
+		for (j = 0; j < 31; j++) {
+			for (k = 0; k < sizeof(bitpattern)/sizeof(bitpattern[0]); k++) {
+				*ibtr_p = compare = (bitpattern[k] << j);
+				readback = *ibtr_p;
+				if (readback != ~compare) {
+					printf("%s:%d: FPGA test fail: expected 0x%.8lx"
+						   " actual 0x%.8lx\n",
+						   __FUNCTION__, __LINE__, ~compare, readback);
+					pass = 0;
+					break;
+				}
+			}
+			if (!pass) break;
+		}
+		if (!pass) break;
+	}
+	if (pass) {
+		printf("FPGA inverting bus test passed\n");
+		print_fpga_revision();
+	}
+	else {
+		printf("** FPGA inverting bus test failed\n");
+	}
+	return pass;
+}
+
+
+/*
+ * Set the active-low FPGA reset signal.
+ */
+void
+fpga_reset(int assert)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: RESET ", __FUNCTION__, __LINE__);
+	if (assert) {
+		immap->im_ioport.iop_pcdat &= ~(0x8000 >> FPGA_RESET_BIT_NUM);
+		PRINTF("asserted\n");
+	}
+	else {
+		immap->im_ioport.iop_pcdat |= (0x8000 >> FPGA_RESET_BIT_NUM);
+		PRINTF("deasserted\n");
+	}
+}
+
+
+/*
+ * Initialize the SelectMap interface.  We assume that the mode and the
+ * initial state of all of the port pins have already been set!
+ */
+void
+fpga_selectmap_init(void)
+{
+	PRINTF("%s:%d: Initialize SelectMap interface\n", __FUNCTION__, __LINE__);
+	fpga_pgm_fn(FALSE, FALSE, 0);   /* make sure program pin is inactive */
+}
+
+
+/*
+ * Initialize the fpga.  Return 1 on success, 0 on failure.
+ */
+int
+gen860t_init_fpga(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int i;
+
+	PRINTF("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n",
+			__FUNCTION__, __LINE__, gd->reloc_off);
+	fpga_init(gd->reloc_off);
+	fpga_selectmap_init();
+
+	for(i=0; i < CONFIG_FPGA_COUNT; i++) {
+		PRINTF("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
+		fpga_add(fpga_xilinx, &fpga[i]);
+	}
+ 	return 1;
+}
+
+
+/*
+ * Set the FPGA's active-low SelectMap program line to the specified level
+ */
+int
+fpga_pgm_fn(int assert, int flush, int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
+
+	if (assert) {
+		immap->im_ioport.iop_padat &= ~(0x8000 >> FPGA_PROGRAM_BIT_NUM);
+		PRINTF("asserted\n");
+	}
+	else {
+		immap->im_ioport.iop_padat |= (0x8000 >> FPGA_PROGRAM_BIT_NUM);
+		PRINTF("deasserted\n");
+	}
+	return assert;
+}
+
+
+/*
+ * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
+ * asserted (low).
+ */
+int
+fpga_init_fn(int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
+	if(immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_INIT_BIT_NUM)) {
+		PRINTF("high\n");
+		return 0;
+	}
+	else {
+		PRINTF("low\n");
+		return 1;
+	}
+}
+
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+int
+fpga_done_fn(int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
+	if (immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_DONE_BIT_NUM)) {
+		PRINTF("high\n");
+		return FPGA_SUCCESS;
+	}
+	else {
+		PRINTF("low\n");
+		return FPGA_FAIL;
+	}
+}
+
+
+/*
+ * Read FPGA SelectMap data.
+ */
+int
+fpga_read_data_fn(unsigned char *data, int cookie)
+{
+	vu_char *p = (vu_char *)SELECTMAP_BASE;
+
+	*data = *p;
+#if 0
+	PRINTF("%s: Read 0x%x into 0x%p\n", __FUNCTION__, (int)data, data);
+#endif
+	return (int)data;
+}
+
+
+/*
+ * Write data to the FPGA SelectMap port
+ */
+int
+fpga_write_data_fn(unsigned char data, int flush, int cookie)
+{
+	vu_char *p = (vu_char *)SELECTMAP_BASE;
+
+#if 0
+	PRINTF("%s: Write Data 0x%x\n", __FUNCTION__, (int)data);
+#endif
+	*p = data;
+	return (int)data;
+}
+
+
+/*
+ * Abort and FPGA operation
+ */
+int
+fpga_abort_fn(int cookie)
+{
+	PRINTF("%s:%d: FPGA program sequence aborted\n",
+		   __FUNCTION__, __LINE__);
+	return FPGA_FAIL;
+}
+
+
+/*
+ * FPGA pre-configuration function. Just make sure that
+ * FPGA reset is asserted to keep the FPGA from starting up after
+ * configuration.
+ */
+int
+fpga_pre_config_fn(int cookie)
+{
+	PRINTF("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
+	fpga_reset(TRUE);
+	return 0;
+}
+
+
+/*
+ * FPGA post configuration function. Blip the FPGA reset line and then see if
+ * the FPGA appears to be running.
+ */
+int
+fpga_post_config_fn(int cookie)
+{
+	int rc;
+
+	PRINTF("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
+	fpga_reset(TRUE);
+	udelay(1000);
+	fpga_reset(FALSE);
+	udelay (1000);
+
+	/*
+	 * Use the FPGA,s inverting bus test register to do a simple test of the
+	 * processor interface.
+	 */
+	rc = test_fpga_ibtr();
+	return rc;
+}
+
+
+/*
+ * Clock, chip select and write signal assert functions and error check
+ * and busy functions.  These are only stubs because the GEN860T selectmap
+ * interface handles sequencing of control signals automatically (it uses
+ * a memory-mapped interface to the FPGA SelectMap port).  The design of
+ * the interface guarantees that the SelectMap port cannot be overrun so
+ * no busy check is needed.  A configuration error is signalled by INIT
+ * going low during configuration, so there is no need for a separate error
+ * function.
+ */
+int
+fpga_clk_fn(int assert_clk, int flush, int cookie)
+{
+	return assert_clk;
+}
+
+int
+fpga_cs_fn(int assert_cs, int flush, int cookie)
+{
+	return assert_cs;
+}
+
+int
+fpga_wr_fn(int assert_write, int flush, int cookie)
+{
+	return assert_write;
+}
+
+int
+fpga_err_fn(int cookie)
+{
+	return 0;
+}
+
+int
+fpga_busy_fn(int cookie)
+{
+	return 0;
+}
+#endif
+
+/* vim: set ts=4 tw=78 sw=4: */
diff --git a/board/gen860t/gen860t.c b/board/gen860t/gen860t.c
new file mode 100644
index 0000000..16a3262
--- /dev/null
+++ b/board/gen860t/gen860t.c
@@ -0,0 +1,299 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.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
+ */
+
+#include <virtex2.h>
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include "beeper.h"
+#include "fpga.h"
+#include "ioport.h"
+
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
+
+#if defined(CFG_CMD_MII) && defined(CONFIG_MII)
+#include <net.h>
+#endif
+
+#if 0
+#define GEN860T_DEBUG
+#endif
+
+#ifdef GEN860T_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define	PRINTF(fmt,args...)
+#endif
+
+/*
+ * The following UPM init tables were generated automatically by
+ * Motorola's MCUINIT program. See the README file for UPM to
+ * SDRAM pin assignments if you want to type this data into
+ * MCUINIT in order to reverse engineer the waveforms.
+ */
+
+/*
+ * UPM initialization tables for MICRON MT48LC16M16A2TG SDRAM devices
+ * (UPMA) and Virtex FPGA SelectMap interface (UPMB).
+ * NOTE that unused areas of the table are used to hold NOP, precharge
+ * and mode register set sequences.
+ *
+ */
+#define	UPMA_NOP_ADDR			0x5
+#define	UPMA_PRECHARGE_ADDR		0x6
+#define UPMA_MRS_ADDR			0x12
+
+#define UPM_SINGLE_READ_ADDR	0x00
+#define UPM_BURST_READ_ADDR		0x08
+#define UPM_SINGLE_WRITE_ADDR	0x18
+#define UPM_BURST_WRITE_ADDR	0x20
+#define	UPM_REFRESH_ADDR		0x30
+
+const uint sdram_upm_table[] = {
+	/* single read   (offset 0x00 in upm ram) */
+	0x0e0fdc04, 0x01adfc04, 0x0fbffc00, 0x1fff5c05,
+	0xffffffff, 0x0fffffcd, 0x0fff0fce, 0xefcfffff,
+	/* burst read    (offset 0x08 in upm ram) */
+	0x0f0fdc04, 0x00fdfc04, 0xf0fffc00, 0xf0fffc00,
+	0xf1fffc00, 0xfffffc00, 0xfffffc05, 0xffffffff,
+	0xffffffff, 0xffffffff, 0x0ffffff4, 0x1f3d5ff4,
+	0xfffffff4, 0xfffffff5, 0xffffffff, 0xffffffff,
+	/* single write  (offset 0x18 in upm ram) */
+	0x0f0fdc04, 0x00ad3c00, 0x1fff5c05, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* burst write   (offset 0x20 in upm ram) */
+	0x0f0fdc00, 0x10fd7c00, 0xf0fffc00, 0xf0fffc00,
+	0xf1fffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xfffff7ff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* refresh       (offset 0x30 in upm ram) */
+	0x1ffddc84, 0xfffffc04, 0xfffffc04, 0xfffffc84,
+	0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* exception     (offset 0x3C in upm ram) */
+   };
+
+const uint selectmap_upm_table[] = {
+	/* single read   (offset 0x00 in upm ram) */
+	0x88fffc06, 0x00fff404, 0x00fffc04, 0x33fffc00,
+	0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* burst read    (offset 0x08 in upm ram) */
+	0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* single write  (offset 0x18 in upm ram) */
+	0x88fffc04, 0x00fff400, 0x77fffc05, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* burst write   (offset 0x20 in upm ram) */
+	0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* refresh       (offset 0x30 in upm ram) */
+	0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* exception     (offset 0x3C in upm ram) */
+	0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff
+};
+
+/*
+ * Check board identity.  Always successful (gives information only)
+ */
+int
+checkboard(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    unsigned char *s;
+    unsigned char buf[64];
+    int i;
+
+    i = getenv_r("board_id", buf, sizeof(buf));
+    s = (i>0) ? buf : NULL;
+
+	if (s) {
+		printf("%s ", s);
+	} else {
+		printf("<unknown> ");
+	}
+
+    i = getenv_r("serial#", buf, sizeof(buf));
+    s = (i>0) ? buf : NULL;
+
+	if (s) {
+		printf("S/N %s\n", s);
+	} else {
+		printf("S/N <unknown>\n");
+	}
+
+    printf("CPU at %s MHz, ",strmhz(buf, gd->cpu_clk));
+	printf("local bus at %s MHz\n", strmhz(buf, gd->bus_clk));
+    return (0);
+}
+
+/*
+ * Initialize SDRAM
+ */
+long int
+initdram(int board_type)
+{
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+    upmconfig(UPMA,
+			  (uint *)sdram_upm_table,
+			  sizeof(sdram_upm_table) / sizeof(uint)
+			 );
+
+    /*
+     * Setup MAMR register
+     */
+    memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+    memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+    /*
+     * Map CS1* to SDRAM bank
+     */
+    memctl->memc_or1 = CFG_OR1;
+    memctl->memc_br1 = CFG_BR1;
+
+	/*
+	 * Perform SDRAM initialization sequence:
+	 * 1. Apply at least one NOP command
+	 * 2. 100 uS delay (JEDEC standard says 200 uS)
+	 * 3. Issue 4 precharge commands
+	 * 4. Perform two refresh cycles
+	 * 5. Program mode register
+	 *
+	 * Program SDRAM for standard operation, sequential burst, burst length
+	 * of 4, CAS latency of 2.
+	 */
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(0) | UPMA_NOP_ADDR;
+	udelay(200);
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(4) | UPMA_PRECHARGE_ADDR;
+
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(2) | UPM_REFRESH_ADDR;
+
+    memctl->memc_mar = 0x00000088;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(1) | UPMA_MRS_ADDR;
+
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(0) | UPMA_NOP_ADDR;
+	/*
+	 * Enable refresh
+	 */
+    memctl->memc_mamr |= MAMR_PTAE;
+
+    return (SDRAM_SIZE);
+}
+
+/*
+ * Disk On Chip (DOC) Millenium initialization.
+ * The DOC lives in the CS2* space
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void
+doc_probe(ulong physadr);
+
+void
+doc_init(void)
+{
+	printf("Probing at 0x%.8x: ", DOC_BASE);
+	doc_probe(DOC_BASE);
+}
+#endif
+
+/*
+ * Miscellaneous intialization
+ */
+int
+misc_init_r (void)
+{
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+	/*
+	 * Set up UPMB to handle the Virtex FPGA SelectMap interface
+	 */
+	upmconfig(UPMB, (uint *)selectmap_upm_table,
+			  sizeof(selectmap_upm_table) / sizeof(uint));
+
+    memctl->memc_mbmr = 0x0;
+
+	config_mpc8xx_ioports(immr);
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+	mii_init();
+#endif
+
+#if (CONFIG_FPGA)
+	gen860t_init_fpga();
+#endif
+	return 0;
+}
+
+/*
+ * Final init hook before entering command loop.
+ */
+int
+last_stage_init(void)
+{
+	unsigned char buf[256];
+	int i;
+
+	/*
+	 * Set LEDs here since status LED init code has already run
+	 */
+	status_led_set(STATUS_LED_BIT1, STATUS_LED_ON);
+	status_led_set(STATUS_LED_BIT3, STATUS_LED_ON);
+
+	/*
+	 * Turn the beeper volume all the way down in case this is a warm
+	 * boot.
+	 */
+	set_beeper_volume(-64);
+	init_beeper();
+
+	/*
+	 * Read the environment to see what to do with the beeper
+	 */
+    i = getenv_r("beeper", buf, sizeof(buf));
+	if (i > 0) {
+		do_beeper(buf);
+	}
+	return 0;
+}
+/* vim: set ts=4 sw=4 tw=78 : */
diff --git a/board/gen860t/ioport.c b/board/gen860t/ioport.c
new file mode 100644
index 0000000..5d6524d
--- /dev/null
+++ b/board/gen860t/ioport.c
@@ -0,0 +1,276 @@
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include "ioport.h"
+
+#if 0
+#define IOPORT_DEBUG
+#endif
+
+#ifdef  IOPORT_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/*
+ * The ioport configuration table.
+ */
+const mpc8xx_iop_conf_t iop_conf_tab[NUM_PORTS][PORT_BITS] = {
+    /*
+	 * Port A configuration
+	 * Pin		Signal				Type	Active		Initial state
+	 * PA7 		fpgaProgramLowOut	Out		Low			High
+	 */
+    {	/*	    conf ppar psor pdir podr pdat pint	   function 		*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /* No pin			*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /* No pin			*/
+	/* PA15 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA12 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA11 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA10 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA9  */ { 1,   0,   0,   1,   0,   0,   0 }, /* grn bicolor LED 1*/
+	/* PA8  */ { 1,   0,   0,   1,   0,   0,   0 }, /* red bicolor LED 1*/
+	/* PA7  */ { 1,   0,   0,   1,   0,   1,   0 }, /* fpgaProgramLow	*/
+	/* PA6  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA5  */ { 1,   0,   0,   1,   0,   0,   0 }, /* grn bicolor LED 0*/
+	/* PA4  */ { 1,   0,   0,   1,   0,   0,   0 }, /* red bicolor LED 0*/
+	/* PA3  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA2  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA1  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA0  */ { 0,   0,   0,   0,   0,   0,   0 }  /*	*/
+    },
+
+	/*
+	 * Pin		Signal			Type		Active		Initial state
+	 * PB14		docBusyLowIn	In			Low			X
+	 * PB15		gpio1Sig		Out			High		Low
+	 * PB16		fpgaDoneBi		In			High		X
+	 * PB17		swBitOkLowOut	Out			Low			Low
+	 * PB19		speakerVolSig	Out/Hi-Z	High/Low	High (Hi-Z)
+	 * PB22		fpgaInitLowBi	In			Low			X
+	 * PB23		batteryOkSig	In			High		X
+     */
+    {	/*	    conf ppar psor pdir podr pdat pint 	  function			*/
+	/* PB31 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB30 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB29 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB28 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB27 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB26 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB25 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB24 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB23 */ { 1,   0,   0,   0,   0,   0,   0 }, /* batteryOk		*/
+	/* PB22 */ { 1,   0,   0,   0,   0,   0,   0 }, /* fpgaInitLowBi	*/
+	/* PB21 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB20 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB19 */ { 1,   0,   0,   1,   1,   1,   0 }, /* speakerVol		*/
+	/* PB18 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB17 */ { 1,   0,   0,   1,   0,   0,   0 }, /* swBitOkLow		*/
+	/* PB16 */ { 1,   0,   0,   0,   0,   0,   0 }, /* fpgaDone			*/
+	/* PB15 */ { 1,   0,   0,   1,   0,   0,   0 }, /* gpio1			*/
+	/* PB14 */ { 1,   0,   0,   0,   0,   0,   0 }  /* docBusyLow		*/
+    },
+
+	/*
+	 * Pin		Signal				Type	Active		Initial state
+	 * PC4		i2cBus1EnSig		Out		High		High
+	 * PC5		i2cBus2EnSig		Out		High		High
+	 * PC6		gpio0Sig			Out		High		Low
+	 * PC8		i2cBus3EnSig		Out		High		High
+	 * PC10		i2cBus4EnSig		Out		High		High
+	 * PC11		fpgaResetLowOut		Out		Low			High
+	 * PC12		systemBitOkIn		In		High		X
+	 * PC15		selfDreqLow			In		Low			X
+	 */
+    {	/*	    conf ppar psor pdir podr pdat pint 	  function			*/
+	/* N/A	*/ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A	*/ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC15 */ { 1,   0,   0,   0,   0,   0,   0 }, /* selfDreqLowIn	*/
+	/* PC14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC12 */ { 1,   0,   0,   0,   0,   0,   0 }, /* systemBitOkIn	*/
+	/* PC11 */ { 1,   0,   0,   1,   0,   1,   0 }, /* fpgaResetLowOut	*/
+	/* PC10 */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus4EnSig		*/
+	/* PC9  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC8  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus3EnSig		*/
+	/* PC7  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC6  */ { 1,   0,   0,   1,   0,   1,   0 }, /* gpio0			*/
+	/* PC5  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus2EnSig		*/
+	/* PC4  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus1EnSig		*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }  /*	*/
+    },
+
+    /* Port D configuration */
+    {	/*	    conf ppar psor pdir podr pdat pint 	   function			*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD15 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD12 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD11 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD10 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD9  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD8  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD7  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD6  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD5  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD4  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD3  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }  /*	*/
+    }
+};
+
+/*
+ * Configure the MPC8XX I/O ports per the ioport configuration table
+ * (taken from ./cpu/mpc8260/cpu_init.c)
+ */
+void
+config_mpc8xx_ioports(volatile immap_t *immr)
+{
+    int portnum;
+
+    for (portnum = 0; portnum < NUM_PORTS; portnum++) {
+		uint pmsk = 0, ppar = 0, psor = 0, pdir = 0;
+		uint podr = 0, pdat = 0, pint = 0;
+		uint msk = 1;
+		mpc8xx_iop_conf_t *iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][0];
+		mpc8xx_iop_conf_t *eiopc = iopc + PORT_BITS;
+
+		/*
+		 * For all ports except port B, ignore the two don't care entries
+		 * in the configuration tables.
+		 */
+		if (portnum != 1) {
+			iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][2];
+		}
+
+		/*
+		 * NOTE: index 0 refers to pin 17, index 17 refers to pin 0
+		 */
+		while (iopc < eiopc) {
+	    	if (iopc->conf) {
+				pmsk |= msk;
+				if (iopc->ppar) ppar |= msk;
+				if (iopc->psor) psor |= msk;
+				if (iopc->pdir) pdir |= msk;
+				if (iopc->podr) podr |= msk;
+				if (iopc->pdat) pdat |= msk;
+				if (iopc->pint) pint |= msk;
+		    }
+		    msk <<= 1;
+	  	  iopc++;
+		}
+
+		PRINTF("%s:%d:\n  portnum=%d ", __FUNCTION__, __LINE__, portnum);
+#ifdef IOPORT_DEBUG
+		switch(portnum) {
+			case 0: printf("(A)\n"); break;
+			case 1: printf("(B)\n"); break;
+			case 2: printf("(C)\n"); break;
+			case 3: printf("(D)\n"); break;
+			default: printf("(?)\n"); break;
+		}
+#endif
+		PRINTF("  ppar=0x%.8x  pdir=0x%.8x  podr=0x%.8x\n"
+			   "  pdat=0x%.8x  psor=0x%.8x  pint=0x%.8x  pmsk=0x%.8x\n",
+			   ppar, pdir, podr, pdat, psor, pint, pmsk);
+
+		/*
+		 * Have to handle the ioports on a port-by-port basis since there
+		 * are three different flavors.
+		 */
+		if (pmsk != 0) {
+		    uint tpmsk = ~pmsk;
+
+			if (0 == portnum) { /* port A */
+		    	immr->im_ioport.iop_papar &= tpmsk;
+		    	immr->im_ioport.iop_padat =
+					(immr->im_ioport.iop_padat & tpmsk) | pdat;
+		    	immr->im_ioport.iop_padir =
+					(immr->im_ioport.iop_padir & tpmsk) | pdir;
+		    	immr->im_ioport.iop_paodr =
+					(immr->im_ioport.iop_paodr & tpmsk) | podr;
+		    	immr->im_ioport.iop_papar |= ppar;
+			}
+			else if (1 == portnum) { /* port B */
+		    	immr->im_cpm.cp_pbpar &= tpmsk;
+		    	immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & tpmsk) | pdat;
+		    	immr->im_cpm.cp_pbdir = (immr->im_cpm.cp_pbdir & tpmsk) | pdir;
+		    	immr->im_cpm.cp_pbodr = (immr->im_cpm.cp_pbodr & tpmsk) | podr;
+		    	immr->im_cpm.cp_pbpar |= ppar;
+			}
+			else if (2 == portnum) { /* port C */
+		    	immr->im_ioport.iop_pcpar &= tpmsk;
+		    	immr->im_ioport.iop_pcdat =
+					(immr->im_ioport.iop_pcdat & tpmsk) | pdat;
+		    	immr->im_ioport.iop_pcdir =
+					(immr->im_ioport.iop_pcdir & tpmsk) | pdir;
+		    	immr->im_ioport.iop_pcint =
+					(immr->im_ioport.iop_pcint & tpmsk) | pint;
+		    	immr->im_ioport.iop_pcso =
+					(immr->im_ioport.iop_pcso & tpmsk) | psor;
+		    	immr->im_ioport.iop_pcpar |= ppar;
+			}
+			else if (3 == portnum) { /* port D */
+		    	immr->im_ioport.iop_pdpar &= tpmsk;
+		    	immr->im_ioport.iop_pddat =
+					(immr->im_ioport.iop_pddat & tpmsk) | pdat;
+		    	immr->im_ioport.iop_pddir =
+					(immr->im_ioport.iop_pddir & tpmsk) | pdir;
+		    	immr->im_ioport.iop_pdpar |= ppar;
+			}
+		}
+    }
+
+	PRINTF("%s:%d: Port A:\n  papar=0x%.4x  padir=0x%.4x"
+		   "  paodr=0x%.4x\n  padat=0x%.4x\n", __FUNCTION__, __LINE__,
+		   immr->im_ioport.iop_papar, immr->im_ioport.iop_padir,
+		   immr->im_ioport.iop_paodr, immr->im_ioport.iop_padat);
+	PRINTF("%s:%d: Port B:\n  pbpar=0x%.8x  pbdir=0x%.8x"
+		   "  pbodr=0x%.8x\n  pbdat=0x%.8x\n", __FUNCTION__, __LINE__,
+		   immr->im_cpm.cp_pbpar, immr->im_cpm.cp_pbdir,
+		   immr->im_cpm.cp_pbodr, immr->im_cpm.cp_pbdat);
+	PRINTF("%s:%d: Port C:\n  pcpar=0x%.4x  pcdir=0x%.4x"
+		   "  pcdat=0x%.4x\n  pcso=0x%.4x  pcint=0x%.4x\n  ",
+		   __FUNCTION__, __LINE__, immr->im_ioport.iop_pcpar,
+		   immr->im_ioport.iop_pcdir, immr->im_ioport.iop_pcdat,
+		   immr->im_ioport.iop_pcso, immr->im_ioport.iop_pcint);
+	PRINTF("%s:%d: Port D:\n  pdpar=0x%.4x  pddir=0x%.4x"
+		   "  pddat=0x%.4x\n", __FUNCTION__, __LINE__,
+		   immr->im_ioport.iop_pdpar, immr->im_ioport.iop_pddir,
+		   immr->im_ioport.iop_pddat);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/u-boot.lds b/board/gen860t/u-boot.lds
new file mode 100644
index 0000000..1b53c72
--- /dev/null
+++ b/board/gen860t/u-boot.lds
@@ -0,0 +1,135 @@
+/*
+ * Linker command file for the GEN860T board.
+ *
+ * (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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+SECTIONS
+{
+  /*
+   * Read-only sections, merged into text segment:
+   */
+  . = + SIZEOF_HEADERS;
+  .interp        : { *(.interp)		}
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)	}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)	}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)	}
+  .rela.got      : { *(.rela.got)	}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)	}
+  .rela.bss      : { *(.rela.bss)	}
+  .rel.plt       : { *(.rel.plt)	}
+  .rela.plt      : { *(.rela.plt)	}
+  .init          : { *(.init)		}
+  .plt           : { *(.plt)		}
+  .text :
+  {
+    cpu/mpc8xx/start.o		(.text)
+    common/dlmalloc.o		(.text)
+    lib_ppc/ppcstring.o		(.text)
+    lib_generic/vsprintf.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_generic/zlib.o		(.text)
+
+/*    . = env_offset;
+    common/environment.o(.text) */
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /*
+   * Read-write section, merged into data segment:
+   */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+
+  _end = . ;
+  PROVIDE (end = .);
+}
+
diff --git a/board/impa7/flash.c b/board/impa7/flash.c
new file mode 100644
index 0000000..c59ffb8
--- /dev/null
+++ b/board/impa7/flash.c
@@ -0,0 +1,365 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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>
+
+#define FLASH_BANK_SIZE 0x800000
+#define MAIN_SECT_SIZE  0x20000
+#define PARAM_SECT_SIZE 0x4000
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init(void)
+{
+    int i, j;
+    ulong size = 0;
+
+    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
+    {
+	ulong flashbase = 0;
+	flash_info[i].flash_id =
+	  (INTEL_MANUFACT & FLASH_VENDMASK) |
+	  (INTEL_ID_28F320B3T & FLASH_TYPEMASK);
+	flash_info[i].size = FLASH_BANK_SIZE;
+	flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+	memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+	if (i == 0)
+	  flashbase = PHYS_FLASH_1;
+	else if (i == 1)
+	  flashbase = PHYS_FLASH_2;
+	else
+	  panic("configured to many flash banks!\n");
+	for (j = 0; j < flash_info[i].sector_count; j++)
+	{
+	    if (j <= 7)
+	    {
+		flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;
+	    }
+	    else
+	    {
+		flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;
+	    }
+	}
+	size += flash_info[i].size;
+    }
+
+    /* Protect monitor and environment sectors
+     */
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_FLASH_BASE,
+		  CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
+		  &flash_info[0]);
+
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_ENV_ADDR,
+		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+		  &flash_info[0]);
+
+    return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+
+    switch (info->flash_id & FLASH_VENDMASK)
+    {
+    case (INTEL_MANUFACT & FLASH_VENDMASK):
+	printf("Intel: ");
+	break;
+    default:
+	printf("Unknown Vendor ");
+	break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK)
+    {
+    case (INTEL_ID_28F320B3T & FLASH_TYPEMASK):
+	printf("28F320F3B (16Mbit)\n");
+	break;
+    default:
+	printf("Unknown Chip Type\n");
+	goto Done;
+	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");
+
+Done:
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int	flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+    int flag, prot, sect;
+    int rc = ERR_OK;
+
+    if (info->flash_id == FLASH_UNKNOWN)
+	return ERR_UNKNOWN_FLASH_TYPE;
+
+    if ((s_first < 0) || (s_first > s_last)) {
+	return ERR_INVAL;
+    }
+
+    if ((info->flash_id & FLASH_VENDMASK) !=
+	(INTEL_MANUFACT & FLASH_VENDMASK)) {
+	return ERR_UNKNOWN_FLASH_VENDOR;
+    }
+
+    prot = 0;
+    for (sect=s_first; sect<=s_last; ++sect) {
+	if (info->protect[sect]) {
+	    prot++;
+	}
+    }
+    if (prot)
+	return ERR_PROTECTED;
+
+    /*
+     * Disable interrupts which might cause a timeout
+     * here. Remember that our exception vectors are
+     * at address 0 in the flash, and we don't want a
+     * (ticker) exception to happen while the flash
+     * chip is in programming mode.
+     */
+    flag = disable_interrupts();
+
+    /* Start erase on unprotected sectors */
+    for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
+
+	printf("Erasing sector %2d ... ", sect);
+
+	/* arm simple, non interrupt dependent timer */
+	reset_timer_masked();
+
+	if (info->protect[sect] == 0) {	/* not protected */
+	    vu_long *addr = (vu_long *)(info->start[sect]);
+
+	    *addr = 0x00200020;	/* erase setup */
+	    *addr = 0x00D000D0;	/* erase confirm */
+
+	    while ((*addr & 0x00800080) != 0x00800080) {
+		if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
+		    *addr = 0x00B000B0; /* suspend erase */
+		    *addr = 0x00FF00FF;	/* reset to read mode */
+		    rc = ERR_TIMOUT;
+		    goto outahere;
+		}
+	    }
+
+	    *addr = 0x00FF00FF;	/* reset to read mode */
+	}
+	printf("ok.\n");
+    }
+    if (ctrlc())
+      printf("User Interrupt!\n");
+
+outahere:
+
+    /* allow flash to settle - wait 10 ms */
+    udelay_masked(10000);
+
+    if (flag)
+      enable_interrupts();
+
+    return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+    vu_long *addr = (vu_long *)dest;
+    ulong barf;
+    int rc = ERR_OK;
+    int flag;
+
+    /* Check if Flash is (sufficiently) erased
+     */
+    if ((*addr & data) != data)
+        return ERR_NOT_ERASED;
+
+    /*
+     * Disable interrupts which might cause a timeout
+     * here. Remember that our exception vectors are
+     * at address 0 in the flash, and we don't want a
+     * (ticker) exception to happen while the flash
+     * chip is in programming mode.
+     */
+    flag = disable_interrupts();
+
+    /* clear status register command */
+    *addr = 0x00500050;
+
+    /* program set-up command */
+    *addr = 0x00400040;
+
+    /* latch address/data */
+    *addr = data;
+
+    /* arm simple, non interrupt dependent timer */
+    reset_timer_masked();
+
+    /* read status register command */
+    *addr = 0x00700070;
+
+    /* wait while polling the status register */
+    while((*addr & 0x00800080) != 0x00800080)
+    {
+	if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
+	    rc = ERR_TIMOUT;
+	    /* suspend program command */
+	    *addr = 0x00B000B0;
+	    goto outahere;
+	}
+
+	if( *addr & 0x003A003A) {	/* check for error */
+	    barf = *addr;
+	    if( barf & 0x003A0000) {
+		barf >>=16;
+	    } else {
+		barf &= 0x0000003A;
+	    }
+	    printf("\nFlash write error %02lx at address %08lx\n",
+		   barf, (unsigned long)dest);
+	    if(barf & 0x0002) {
+		printf("Block locked, not erased.\n");
+		rc = ERR_NOT_ERASED;
+		goto outahere;
+	    }
+	    if(barf & 0x0010) {
+		printf("Programming error.\n");
+		rc = ERR_PROG_ERROR;
+		goto outahere;
+	    }
+	    if(barf & 0x0008) {
+		printf("Vpp Low error.\n");
+		rc = ERR_PROG_ERROR;
+		goto outahere;
+	    }
+	    rc = ERR_PROG_ERROR;
+	    goto outahere;
+	}
+    }
+
+
+outahere:
+    /* read array command */
+    *addr = 0x00FF00FF;
+
+    if (flag)
+      enable_interrupts();
+
+    return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong cp, wp, data;
+    int l;
+    int i, 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 << 24);
+	}
+	for (; i<4 && cnt>0; ++i) {
+	    data = (data >> 8) | (*src++ << 24);
+	    --cnt;
+	    ++cp;
+	}
+	for (; cnt==0 && i<4; ++i, ++cp) {
+	    data = (data >> 8) | (*(uchar *)cp << 24);
+	}
+
+	if ((rc = write_word(info, wp, data)) != 0) {
+	    return (rc);
+	}
+	wp += 4;
+    }
+
+    /*
+     * handle word aligned part
+     */
+    while (cnt >= 4) {
+	data = *((vu_long*)src);
+	if ((rc = write_word(info, wp, data)) != 0) {
+	    return (rc);
+	}
+	src += 4;
+	wp  += 4;
+	cnt -= 4;
+    }
+
+    if (cnt == 0) {
+	return ERR_OK;
+    }
+
+    /*
+     * handle unaligned tail bytes
+     */
+    data = 0;
+    for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+	data = (data >> 8) | (*src++ << 24);
+	--cnt;
+    }
+    for (; i<4; ++i, ++cp) {
+	data = (data >> 8) | (*(uchar *)cp << 24);
+    }
+
+    return write_word(info, wp, data);
+}
diff --git a/board/impa7/u-boot.lds b/board/impa7/u-boot.lds
new file mode 100644
index 0000000..0849648
--- /dev/null
+++ b/board/impa7/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm720t/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/lart/u-boot.lds b/board/lart/u-boot.lds
new file mode 100644
index 0000000..f4b0ade
--- /dev/null
+++ b/board/lart/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/sa1100/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/mbx8xx/mbx8xx.c b/board/mbx8xx/mbx8xx.c
new file mode 100644
index 0000000..9a9bf80
--- /dev/null
+++ b/board/mbx8xx/mbx8xx.c
@@ -0,0 +1,379 @@
+/*
+ * (C) Copyright 2000
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Board specific routines for the MBX
+ *
+ * - initialisation
+ * - interface to VPD data (mac address, clock speeds)
+ * - memory controller
+ * - serial io initialisation
+ * - ethernet io initialisation
+ *
+ * -----------------------------------------------------------------
+ * 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 <commproc.h>
+#include <mpc8xx.h>
+#include "dimm.h"
+#include "vpd.h"
+#include "csr.h"
+
+/* ------------------------------------------------------------------------- */
+
+static const uint sdram_table_40[] = {
+	/* DRAM - single read. (offset 0 in upm RAM)
+	 */
+	0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
+	0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst read. (offset 8 in upm RAM)
+	 */
+	0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
+	0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
+	0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - single write. (offset 18 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x33FF4804,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst write. (offset 20 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* refresh  (offset 30 in upm RAM)
+	 */
+	0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+	0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* exception. (offset 3c in upm RAM)
+	 */
+	0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+};
+
+static const uint sdram_table_50[] = {
+	/* DRAM - single read. (offset 0 in upm RAM)
+	 */
+	0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
+	0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst read. (offset 8 in upm RAM)
+	 */
+	0xCFAFC004, 0X0FAFC404, 0X0CAF8C04, 0X00AF0C04,
+  /*	0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C04,	*/
+	0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08,
+	0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08, 0X0CAF0C04,
+  /*	0X10AF0C04, 0XF0AFC000, 0XF3FF4805, 0XFFFFC005,	*/
+	0X10AF0C04, 0XF0AFC000, 0XF3BF4805, 0XFFFFC005,
+
+	/* DRAM - single write. (offset 18 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
+	0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst write. (offset 20 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* refresh  (offset 30 in upm RAM)
+	 */
+	0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+	0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* exception. (offset 3c in upm RAM)
+	 */
+	0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned int get_reffreq(void);
+static unsigned int board_get_cpufreq(void);
+
+void mbx_init (void)
+{
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immr->im_memctl;
+	ulong speed, refclock, plprcr, sccr;
+	ulong br0_32 = memctl->memc_br0 & 0x400;
+
+	/* real-time clock status and control register */
+	immr->im_sitk.sitk_rtcsck = KAPWR_KEY;
+	immr->im_sit.sit_rtcsc = 0x00C3;
+
+	/* SIEL and SIMASK Registers (see MBX PRG 2-3) */
+	immr->im_siu_conf.sc_simask = 0x00000000;
+	immr->im_siu_conf.sc_siel = 0xAAAA0000;
+	immr->im_siu_conf.sc_tesr = 0xFFFFFFFF;
+
+	/*
+	 * Prepare access to i2c bus. The MBX offers 3 devices on the i2c bus:
+	 * 1. Vital Product Data (contains clock speeds, MAC address etc, see vpd.h)
+	 * 2. RAM  Specs (see dimm.h)
+	 * 2. DIMM Specs (see dimm.h)
+	 */
+	vpd_init ();
+
+	/* system clock and reset control register */
+	immr->im_clkrstk.cark_sccrk = KAPWR_KEY;
+	sccr = immr->im_clkrst.car_sccr;
+	sccr &= SCCR_MASK;
+	sccr |= CFG_SCCR;
+	immr->im_clkrst.car_sccr = sccr;
+
+	speed = board_get_cpufreq ();
+	refclock = get_reffreq ();
+
+#if ((CFG_PLPRCR & PLPRCR_MF_MSK) != 0)
+	plprcr = CFG_PLPRCR;
+#else
+	plprcr = immr->im_clkrst.car_plprcr;
+	plprcr &= PLPRCR_MF_MSK;	/* isolate MF field */
+	plprcr |= CFG_PLPRCR;		/* reset control bits   */
+#endif
+
+#ifdef CFG_USE_OSCCLK			/* See doc/README.MBX ! */
+	plprcr |= ((speed + refclock / 2) / refclock - 1) << 20;
+#endif
+
+	immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
+	immr->im_clkrst.car_plprcr = plprcr;
+
+	/*
+	 * preliminary setup of memory controller:
+	 * - map Flash, otherwise configuration/status
+	 *    registers won't be accessible when read
+	 *    by board_init_f.
+	 * - map NVRAM and configuation/status registers.
+	 * - map pci registers.
+	 * - DON'T map ram yet, this is done in initdram().
+	 */
+	switch (speed / 1000000) {
+	case 40:
+		memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+		memctl->memc_or0 = 0xFF800930;
+		memctl->memc_or4 = CFG_NVRAM_OR | 0x920;
+		memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+		break;
+	case 50:
+		memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+		memctl->memc_or0 = 0xFF800940;
+		memctl->memc_or4 = CFG_NVRAM_OR | 0x930;
+		memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+		break;
+	default:
+		hang ();
+		break;
+	}
+#ifdef CONFIG_USE_PCI
+	memctl->memc_or5 = CFG_PCIMEM_OR;
+	memctl->memc_br5 = CFG_PCIMEM_BASE | 0x001;
+	memctl->memc_or6 = CFG_PCIBRIDGE_OR;
+	memctl->memc_br6 = CFG_PCIBRIDGE_BASE | 0x001;
+#endif
+	/*
+	 * FIXME: I do not understand why I have to call this to
+	 * initialise the control register here before booting from
+	 * the PCMCIA card but if I do not the Linux kernel falls
+	 * over in a big heap. If you can answer this question I
+	 * would like to know about it.
+	 */
+	board_ether_init();
+}
+
+void board_serial_init (void)
+{
+	MBX_CSR1 &= ~(CSR1_COM1EN | CSR1_XCVRDIS);
+}
+
+void board_ether_init (void)
+{
+	MBX_CSR1 &= ~(CSR1_EAEN | CSR1_ELEN);
+	MBX_CSR1 |= CSR1_ETEN | CSR1_TPEN | CSR1_FDDIS;
+}
+
+static unsigned int board_get_cpufreq (void)
+{
+#ifndef CONFIG_8xx_GCLK_FREQ
+	vpd_packet_t *packet;
+
+	packet = vpd_find_packet (VPD_PID_ICS);
+	return *((ulong *) packet->data);
+#else
+	return((unsigned int)CONFIG_8xx_GCLK_FREQ );
+#endif /* CONFIG_8xx_GCLK_FREQ */
+}
+
+static unsigned int get_reffreq (void)
+{
+	vpd_packet_t *packet;
+
+	packet = vpd_find_packet (VPD_PID_RCS);
+	return *((ulong *) packet->data);
+}
+
+void board_get_enetaddr (uchar * addr)
+{
+	int i;
+	vpd_packet_t *packet;
+
+	packet = vpd_find_packet (VPD_PID_EA);
+	for (i = 0; i < 6; i++)
+		addr[i] = packet->data[i];
+}
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+	vpd_packet_t *packet;
+	int i;
+	const char *const fmt =
+		"\n	 *** Warning: Low Battery Status - %s Battery ***";
+
+	puts ("Board: ");
+
+	packet = vpd_find_packet (VPD_PID_PID);
+	for (i = 0; i < packet->size; i++) {
+		serial_putc (packet->data[i]);
+	}
+	packet = vpd_find_packet (VPD_PID_MT);
+	for (i = 0; i < packet->size; i++) {
+		serial_putc (packet->data[i]);
+	}
+	serial_putc ('(');
+	packet = vpd_find_packet (VPD_PID_FAN);
+	for (i = 0; i < packet->size; i++) {
+		serial_putc (packet->data[i]);
+	}
+	serial_putc (')');
+
+	if (!(MBX_CSR2 & SR2_BATGD))
+		printf (fmt, "On-Board");
+	if (!(MBX_CSR2 & SR2_NVBATGD))
+		printf (fmt, "NVRAM");
+
+	serial_putc ('\n');
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static ulong get_ramsize (dimm_t * dimm)
+{
+	ulong size = 0;
+
+	if (dimm->fmt == 1 || dimm->fmt == 2 || dimm->fmt == 3
+		|| dimm->fmt == 4) {
+		size = (1 << (dimm->n_row + dimm->n_col)) * dimm->n_banks *
+			((dimm->data_w_hi << 8 | dimm->data_w_lo) / 8);
+	}
+
+	return size;
+}
+
+long int initdram (int board_type)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	unsigned long ram_sz = 0;
+	unsigned long dimm_sz = 0;
+	dimm_t vpd_dimm, vpd_dram;
+	unsigned int speed = board_get_cpufreq () / 1000000;
+
+	if (vpd_read (0xa2, (uchar *) & vpd_dimm, sizeof (vpd_dimm), 0) > 0) {
+		dimm_sz = get_ramsize (&vpd_dimm);
+	}
+	if (vpd_read (0xa6, (uchar *) & vpd_dram, sizeof (vpd_dram), 0) > 0) {
+		ram_sz = get_ramsize (&vpd_dram);
+	}
+
+	/*
+	 * Only initialize memory controller when running from FLASH.
+	 * When running from RAM, don't touch it.
+	 */
+	if ((ulong) initdram & 0xff000000) {
+		ulong dimm_bank;
+		ulong br0_32 = memctl->memc_br0 & 0x400;
+
+		switch (speed) {
+		case 40:
+			upmconfig (UPMA, (uint *) sdram_table_40,
+					   sizeof (sdram_table_40) / sizeof (uint));
+			memctl->memc_mptpr = 0x0200;
+			memctl->memc_mamr = dimm_sz ? 0x06801000 : 0x13801000;
+			memctl->memc_or7 = 0xff800930;
+			memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+			break;
+		case 50:
+			upmconfig (UPMA, (uint *) sdram_table_50,
+					   sizeof (sdram_table_50) / sizeof (uint));
+			memctl->memc_mptpr = 0x0200;
+			memctl->memc_mamr = dimm_sz ? 0x08801000 : 0x1880100;
+			memctl->memc_or7 = 0xff800940;
+			memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+			break;
+		default:
+			hang ();
+			break;
+		}
+
+		/* now map ram and dimm, largest one first */
+		dimm_bank = dimm_sz / 2;
+		if (!dimm_sz) {
+			memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+			memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+			memctl->memc_br2 = 0;
+			memctl->memc_br3 = 0;
+		} else if (ram_sz > dimm_bank) {
+			memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+			memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+			memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br2 = (CFG_SDRAM_BASE + ram_sz) | 0x81;
+			memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br3 = (CFG_SDRAM_BASE + ram_sz + dimm_bank) \
+								     | 0x81;
+		} else {
+			memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br2 = CFG_SDRAM_BASE | 0x81;
+			memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br3 = (CFG_SDRAM_BASE + dimm_bank) | 0x81;
+			memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+			memctl->memc_br1 = (CFG_SDRAM_BASE + dimm_sz) | 0x81;
+		}
+	}
+
+	return ram_sz + dimm_sz;
+}
diff --git a/board/ml2/serial.c b/board/ml2/serial.c
new file mode 100644
index 0000000..dc9a8ea
--- /dev/null
+++ b/board/ml2/serial.c
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2002
+ * Peter De Schrijver (p2@mind.be), Mind Linux Solutions, NV.
+ *
+ * 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 <asm/u-boot.h>
+#include <asm/processor.h>
+#include <common.h>
+#include <command.h>
+#include <configs/ML2.h>
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+#include <ns16550.h>
+#endif
+
+#if 0
+#include "serial.h"
+#endif
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1,
+		                (NS16550_t) CFG_NS16550_COM2 };
+#endif
+
+int
+serial_init (void)
+{
+		DECLARE_GLOBAL_DATA_PTR;
+
+	    int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+	    (void)NS16550_init(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	    (void)NS16550_init(COM_PORTS[1], clock_divisor);
+#endif
+		return 0;
+
+}
+
+void
+serial_putc(const char c)
+{
+    if (c == '\n')
+        NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+
+    NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+    return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+    return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+    NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+    NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar (int c)
+{
+	serial_putc (c);
+}
+
+void
+putDebugStr (const char *str)
+{
+	serial_puts (str);
+}
+
+int
+getDebugChar (void)
+{
+	return serial_getc();
+}
+
+void
+kgdb_interruptible (int yes)
+{
+	return;
+}
+#endif	/* CFG_CMD_KGDB	*/
diff --git a/board/mousse/pci.c b/board/mousse/pci.c
new file mode 100644
index 0000000..89ca235
--- /dev/null
+++ b/board/mousse/pci.c
@@ -0,0 +1,283 @@
+/*
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * James Dougherty (jfd@cs.stanford.edu)
+ *
+ * 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
+ */
+
+/*
+ * PCI Configuration space access support for MPC824x/MPC107 PCI Bridge
+ */
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+#include "mousse.h"
+
+/*
+ * Promise ATA/66 support.
+ */
+#define XFER_PIO_4	0x0C	/* 0000|1100 */
+#define XFER_PIO_3	0x0B	/* 0000|1011 */
+#define XFER_PIO_2	0x0A	/* 0000|1010 */
+#define XFER_PIO_1	0x09	/* 0000|1001 */
+#define XFER_PIO_0	0x08	/* 0000|1000 */
+#define XFER_PIO_SLOW	0x00	/* 0000|0000 */
+
+/* Promise Regs */
+#define REG_A		0x01
+#define REG_B		0x02
+#define REG_C		0x04
+#define REG_D		0x08
+
+void
+pdc202xx_decode_registers (unsigned char registers, unsigned char value)
+{
+	unsigned char	bit = 0, bit1 = 0, bit2 = 0;
+	switch(registers) {
+		case REG_A:
+			bit2 = 0;
+			printf("  A Register ");
+			if (value & 0x80) printf("SYNC_IN ");
+			if (value & 0x40) printf("ERRDY_EN ");
+			if (value & 0x20) printf("IORDY_EN ");
+			if (value & 0x10) printf("PREFETCH_EN ");
+			if (value & 0x08) { printf("PA3 ");bit2 |= 0x08; }
+			if (value & 0x04) { printf("PA2 ");bit2 |= 0x04; }
+			if (value & 0x02) { printf("PA1 ");bit2 |= 0x02; }
+			if (value & 0x01) { printf("PA0 ");bit2 |= 0x01; }
+			printf("PIO(A) = %d ", bit2);
+			break;
+		case REG_B:
+			bit1 = 0;bit2 = 0;
+			printf("  B Register ");
+			if (value & 0x80) { printf("MB2 ");bit1 |= 0x80; }
+			if (value & 0x40) { printf("MB1 ");bit1 |= 0x40; }
+			if (value & 0x20) { printf("MB0 ");bit1 |= 0x20; }
+			printf("DMA(B) = %d ", bit1 >> 5);
+			if (value & 0x10) printf("PIO_FORCED/PB4 ");
+			if (value & 0x08) { printf("PB3 ");bit2 |= 0x08; }
+			if (value & 0x04) { printf("PB2 ");bit2 |= 0x04; }
+			if (value & 0x02) { printf("PB1 ");bit2 |= 0x02; }
+			if (value & 0x01) { printf("PB0 ");bit2 |= 0x01; }
+			printf("PIO(B) = %d ", bit2);
+			break;
+		case REG_C:
+			bit2 = 0;
+			printf("  C Register ");
+			if (value & 0x80) printf("DMARQp ");
+			if (value & 0x40) printf("IORDYp ");
+			if (value & 0x20) printf("DMAR_EN ");
+			if (value & 0x10) printf("DMAW_EN ");
+
+			if (value & 0x08) { printf("MC3 ");bit2 |= 0x08; }
+			if (value & 0x04) { printf("MC2 ");bit2 |= 0x04; }
+			if (value & 0x02) { printf("MC1 ");bit2 |= 0x02; }
+			if (value & 0x01) { printf("MC0 ");bit2 |= 0x01; }
+			printf("DMA(C) = %d ", bit2);
+			break;
+		case REG_D:
+			printf("  D Register ");
+			break;
+		default:
+			return;
+	}
+	printf("\n        %s ", (registers & REG_D) ? "DP" :
+				(registers & REG_C) ? "CP" :
+				(registers & REG_B) ? "BP" :
+				(registers & REG_A) ? "AP" : "ERROR");
+	for (bit=128;bit>0;bit/=2)
+		printf("%s", (value & bit) ? "1" : "0");
+	printf("\n");
+}
+
+/*
+ * Promise ATA/66 Support: configure Promise ATA66 card in specified mode.
+ */
+int
+pdc202xx_tune_chipset (pci_dev_t dev, int drive, unsigned char speed)
+{
+	unsigned short		drive_conf;
+	int			err = 0;
+	unsigned char			drive_pci, AP, BP, CP, DP;
+	unsigned char			TA = 0, TB = 0;
+
+	switch (drive) {
+		case 0: drive_pci = 0x60; break;
+		case 1: drive_pci = 0x64; break;
+		case 2: drive_pci = 0x68; break;
+		case 3: drive_pci = 0x6c; break;
+		default: return -1;
+	}
+
+	pci_read_config_word(dev, drive_pci, &drive_conf);
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+
+	if ((AP & 0x0F) || (BP & 0x07)) {
+	  /* clear PIO modes of lower 8421 bits of A Register */
+	  pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
+	  pci_read_config_byte(dev, (drive_pci), &AP);
+
+	  /* clear PIO modes of lower 421 bits of B Register */
+	  pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
+	  pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+
+	  pci_read_config_byte(dev, (drive_pci), &AP);
+	  pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	}
+
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+
+	switch(speed) {
+		case XFER_PIO_4:	TA = 0x01; TB = 0x04; break;
+		case XFER_PIO_3:	TA = 0x02; TB = 0x06; break;
+		case XFER_PIO_2:	TA = 0x03; TB = 0x08; break;
+		case XFER_PIO_1:	TA = 0x05; TB = 0x0C; break;
+		case XFER_PIO_0:
+		default:		TA = 0x09; TB = 0x13; break;
+	}
+
+	pci_write_config_byte(dev, (drive_pci), AP|TA);
+	pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
+
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+
+
+#ifdef PDC202XX_DEBUG
+	pdc202xx_decode_registers(REG_A, AP);
+	pdc202xx_decode_registers(REG_B, BP);
+	pdc202xx_decode_registers(REG_C, CP);
+	pdc202xx_decode_registers(REG_D, DP);
+#endif
+	return err;
+}
+/*
+ * Show/Init PCI devices on the specified bus number.
+ */
+
+void pci_mousse_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	unsigned int line;
+
+	switch(PCI_DEV(dev)) {
+	case 0x0d:
+		line = 0x00000101;
+		break;
+
+	case 0x0e:
+	default:
+		line = 0x00000303;
+		break;
+	}
+
+	pci_write_config_dword(dev, PCI_INTERRUPT_LINE, line);
+}
+
+void pci_mousse_setup_pdc202xx(struct pci_controller *hose, pci_dev_t dev,
+			       struct pci_config_table *_)
+{
+	unsigned short vendorId;
+	unsigned int mbar0, cmd;
+	int bar, a;
+
+	pci_read_config_word(dev, PCI_VENDOR_ID, &vendorId);
+
+	if(vendorId == PCI_VENDOR_ID_PROMISE || vendorId == PCI_VENDOR_ID_CMD){
+		/* PDC 202xx card is handled differently, it is a bootable
+		 * device and needs all 5 MBAR's configured
+		 */
+		for(bar = 0; bar < 5; bar++){
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, ~0);
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+#ifdef DEBUG
+			printf("  ATA_bar[%d] = %dbytes\n", bar,
+			       ~(mbar0 & PCI_BASE_ADDRESS_MEM_MASK) + 1);
+#endif
+		}
+
+		/* Program all BAR's */
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PROMISE_MBAR0);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, PROMISE_MBAR1);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_2,	PROMISE_MBAR2);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_3,	PROMISE_MBAR3);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_4,	PROMISE_MBAR4);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_5,	PROMISE_MBAR5);
+
+		for(bar = 0; bar < 5; bar++){
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+#ifdef DEBUG
+			printf("  ATA_bar[%d]@0x%x\n", bar, mbar0);
+#endif
+		}
+
+		/* Enable ROM Expansion base */
+		pci_write_config_dword(dev, PCI_ROM_ADDRESS, PROMISE_MBAR5|1);
+
+		/* Io enable, Memory enable, master enable */
+		pci_read_config_dword(dev, PCI_COMMAND, &cmd);
+		cmd &= ~0xffff0000;
+		cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+		pci_write_config_dword(dev, PCI_COMMAND, cmd);
+
+		/* Breath some life into the controller */
+		for( a = 0; a < 4; a++)
+			pdc202xx_tune_chipset(dev, a, XFER_PIO_0);
+	}
+}
+
+static struct pci_config_table pci_sandpoint_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0e, 0x00,
+	  pci_mousse_setup_pdc202xx },
+#ifndef CONFIG_PCI_PNP
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0d, 0x00,
+	  pci_cfgfunc_config_device, {PCI_ENET_IOADDR,
+				      PCI_ENET_MEMADDR,
+				      PCI_COMMAND_MEMORY |
+				      PCI_COMMAND_MASTER}},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, {PCI_SLOT_IOADDR,
+				      PCI_SLOT_MEMADDR,
+				      PCI_COMMAND_MEMORY |
+				      PCI_COMMAND_MASTER}},
+#endif
+	{ }
+};
+
+struct pci_controller hose = {
+	config_table: pci_sandpoint_config_table,
+	fixup_irq: pci_mousse_fixup_irq,
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c
new file mode 100644
index 0000000..60c49af
--- /dev/null
+++ b/board/mpl/common/common_util.c
@@ -0,0 +1,606 @@
+/*
+ * (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 <video_fb.h>
+#include "common_util.h"
+#include <asm/processor.h>
+#include <i2c.h>
+#include <devices.h>
+#include <pci.h>
+
+extern int  gunzip (void *, int, unsigned char *, int *);
+extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
+
+#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
+#define IMAGE_SIZE 0x80000
+
+extern flash_info_t flash_info[];	/* info for FLASH chips */
+
+image_header_t header;
+
+
+
+int mpl_prg(unsigned long src,unsigned long size)
+{
+	unsigned long start;
+	flash_info_t *info;
+	int i,rc;
+	unsigned long *magic = (unsigned long *)src;
+
+	info = &flash_info[0];
+  	start = 0 - size;
+	for(i=info->sector_count-1;i>0;i--)
+	{
+		info->protect[i] = 0; /* unprotect this sector */
+		if(start>=info->start[i])
+		break;
+	}
+	/* set-up flash location */
+	/* now erase flash */
+	if(magic[0]!=IH_MAGIC) {
+		printf("Bad Magic number\n");
+		return -1;
+	}
+	printf("Erasing at %lx (sector %d) (start %lx)\n",
+				start,i,info->start[i]);
+	flash_erase (info, i, info->sector_count-1);
+	printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
+	if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
+		puts ("ERROR ");
+		flash_perror (rc);
+		return (1);
+	}
+	puts ("OK programming done\n");
+	return 0;
+}
+
+
+int mpl_prg_image(unsigned long ld_addr)
+{
+	unsigned long data,len,checksum;
+	image_header_t *hdr=&header;
+	/* Copy header so we can blank CRC field for re-calculation */
+	memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
+	if (hdr->ih_magic  != IH_MAGIC) {
+		printf ("Bad Magic Number\n");
+		return 1;
+	}
+	print_image_hdr(hdr);
+	if (hdr->ih_os  != IH_OS_U_BOOT) {
+		printf ("No U-Boot Image\n");
+		return 1;
+	}
+	if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
+		printf ("No Firmware Image\n");
+		return 1;
+	}
+	data = (ulong)&header;
+	len  = sizeof(image_header_t);
+	checksum = hdr->ih_hcrc;
+	hdr->ih_hcrc = 0;
+	if (crc32 (0, (char *)data, len) != checksum) {
+		printf ("Bad Header Checksum\n");
+		return 1;
+	}
+	data = ld_addr + sizeof(image_header_t);
+	len  = hdr->ih_size;
+	printf ("Verifying Checksum ... ");
+	if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
+		printf ("Bad Data CRC\n");
+		return 1;
+	}
+	switch (hdr->ih_comp) {
+	case IH_COMP_NONE:
+		break;
+	case IH_COMP_GZIP:
+		printf ("  Uncompressing  ... ");
+		if (gunzip ((void *)(data+0x100000), 0x400000,
+			    (uchar *)data, (int *)&len) != 0) {
+			printf ("GUNZIP ERROR\n");
+			return 1;
+		}
+		data+=0x100000;
+		break;
+	default:
+		printf ("   Unimplemented compression type %d\n", hdr->ih_comp);
+		return 1;
+	}
+
+	printf ("  OK\n");
+	return(mpl_prg(data,len));
+}
+
+
+void get_backup_values(backup_t *buf)
+{
+	i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
+}
+
+void set_backup_values(int overwrite)
+{
+	backup_t back;
+	int i;
+
+	get_backup_values(&back);
+	if(!overwrite) {
+		if(strncmp(back.signature,"MPL\0",4)==0) {
+			printf("Not possible to write Backup\n");
+			return;
+		}
+	}
+	memcpy(back.signature,"MPL\0",4);
+	i=getenv_r("serial#",back.serial_name,16);
+	if(i==0) {
+		printf("Not possible to write Backup\n");
+		return;
+	}
+	back.serial_name[16]=0;
+	i=getenv_r("ethaddr",back.eth_addr,20);
+	if(i==0) {
+		printf("Not possible to write Backup\n");
+		return;
+	}
+	back.eth_addr[20]=0;
+	i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+}
+
+void clear_env_values(void)
+{
+	backup_t back;
+	unsigned char env_crc[4];
+
+	memset(&back,0xff,sizeof(backup_t));
+	memset(env_crc,0x00,4);
+	i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+	i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
+}
+
+/*
+ * check crc of "older" environment
+ */
+int check_env_old_size(ulong oldsize)
+{
+	ulong crc, len, new;
+	unsigned off;
+	uchar buf[64];
+
+	/* read old CRC */
+	eeprom_read (CFG_DEF_EEPROM_ADDR,
+		     CFG_ENV_OFFSET,
+		     (uchar *)&crc, sizeof(ulong));
+
+	new = 0;
+	len = oldsize;
+	off = sizeof(long);
+	len = oldsize-off;
+	while (len > 0) {
+		int n = (len > sizeof(buf)) ? sizeof(buf) : len;
+
+		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
+		new = crc32 (new, buf, n);
+		len -= n;
+		off += n;
+	}
+
+	return (crc == new);
+}
+
+static ulong oldsizes[] = {
+	0x200,
+	0x800,
+	0
+};
+
+void copy_old_env(ulong size)
+{
+	uchar name_buf[64];
+	uchar value_buf[0x800];
+	uchar c;
+	ulong len;
+	unsigned off;
+	uchar *name, *value;
+
+	name=&name_buf[0];
+	value=&value_buf[0];
+	len=size;
+	off = sizeof(long);
+	while (len > off) {
+		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
+		if(c != '=') {
+			*name++=c;
+			off++;
+		}
+		else {
+			*name++='\0';
+			off++;
+			do {
+				eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
+				*value++=c;
+				off++;
+				if(c == '\0')
+					break;
+			} while(len > off);
+			name=&name_buf[0];
+			value=&value_buf[0];
+			if(strncmp(name,"baudrate",8)!=0) {
+				setenv(name,value);
+			}
+
+		}
+	}
+}
+
+
+void check_env(void)
+{
+	unsigned char *s;
+	int i=0;
+	char buf[32];
+	backup_t back;
+
+	s=getenv("serial#");
+	if(!s) {
+		while(oldsizes[i]) {
+			if(check_env_old_size(oldsizes[i]))
+				break;
+			i++;
+		}
+		if(!oldsizes[i]) {
+			/* no old environment has been found */
+			get_backup_values (&back);
+			if (strncmp (back.signature, "MPL\0", 4) == 0) {
+				sprintf (buf, "%s", back.serial_name);
+				setenv ("serial#", buf);
+				sprintf (buf, "%s", back.eth_addr);
+				setenv ("ethaddr", buf);
+				printf ("INFO:  serial# and ethaddr recovered, use saveenv\n");
+				return;
+			}
+		}
+		else {
+			copy_old_env(oldsizes[i]);
+			printf ("INFO:  old environment ajusted, use saveenv\n");
+		}
+	}
+	else {
+		/* check if back up is set */
+		get_backup_values(&back);
+		if(strncmp(back.signature,"MPL\0",4)!=0) {
+			set_backup_values(0);
+		}
+	}
+}
+
+
+
+extern device_t *stdio_devices[];
+extern char *stdio_names[];
+
+void show_stdio_dev(void)
+{
+	/* Print informations */
+	printf ("In:    ");
+	if (stdio_devices[stdin] == NULL) {
+		printf ("No input devices available!\n");
+	} else {
+		printf ("%s\n", stdio_devices[stdin]->name);
+	}
+
+	printf ("Out:   ");
+	if (stdio_devices[stdout] == NULL) {
+		printf ("No output devices available!\n");
+	} else {
+		printf ("%s\n", stdio_devices[stdout]->name);
+	}
+
+	printf ("Err:   ");
+	if (stdio_devices[stderr] == NULL) {
+		printf ("No error devices available!\n");
+	} else {
+		printf ("%s\n", stdio_devices[stderr]->name);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+	/* switches the cs0 and the cs1 to the locations.
+	   When boot is TRUE, the the mapping is switched
+	   to the boot configuration, If it is FALSE, the
+	   flash will be switched in the boot area */
+
+#undef SW_CS_DBG
+#ifdef SW_CS_DBG
+#define	SW_CS_PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define SW_CS_PRINTF(fmt,args...)
+#endif
+
+
+int switch_cs(unsigned char boot)
+{
+  	unsigned long pbcr;
+	mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
+	pbcr = mfdcr(ebccfgd);
+	if((pbcr&0x00002000)==0) {
+		/* we need only to switch if boot from MPS */
+		/*printf(" MPS boot mode detected. ");*/
+		/* printf("cs0 cfg: %lx\n",pbcr); */
+		if(boot) {
+			/* switch to boot configuration */
+			/* this is a 8bit boot, switch cs0 to flash location */
+			SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
+			pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+			mtdcr(ebccfga, pb0cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
+			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+			pbcr = mfdcr(ebccfgd);
+			SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
+			pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+			mtdcr(ebccfga, pb1cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
+		}
+		else
+		{
+			/* map flash to boot area, */
+			SW_CS_PRINTF("map Flash to boot area\n");
+			pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+			mtdcr(ebccfga, pb0cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
+			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+			pbcr = mfdcr(ebccfgd);
+			SW_CS_PRINTF("  cs1 cfg: %lx\n",pbcr);
+			pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+			mtdcr(ebccfga, pb1cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs1 cfg: %lx Flash is on High Address\n",pbcr);
+		}
+		return 1;
+	}
+	else {
+		SW_CS_PRINTF("Normal boot, no switching necessary\n");
+		return 0;
+	}
+}
+
+
+int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ 	ulong size,src,ld_addr;
+	int result;
+	backup_t back;
+	char sw;
+	src = MULTI_PURPOSE_SOCKET_ADDR;
+	size = IMAGE_SIZE;
+
+	if (strcmp(argv[1], "flash") == 0)
+	{
+		sw = switch_cs(0); /* Switch flash to normal location */
+#if (CONFIG_COMMANDS & CFG_CMD_FDC)
+		if (strcmp(argv[2], "floppy") == 0) {
+ 			char *local_args[3];
+			extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
+			printf ("\nupdating bootloader image from floppy\n");
+			local_args[0] = argv[0];
+	    		if(argc==4) {
+				local_args[1] = argv[3];
+				local_args[2] = NULL;
+				ld_addr=simple_strtoul(argv[3], NULL, 16);
+				result=do_fdcboot(cmdtp, 0, 2, local_args);
+			}
+			else {
+				local_args[1] = NULL;
+				ld_addr=CFG_LOAD_ADDR;
+				result=do_fdcboot(cmdtp, 0, 1, local_args);
+			}
+			result=mpl_prg_image(ld_addr);
+			switch_cs(sw); /* Switch flash back */
+			return result;
+		}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
+		if (strcmp(argv[2], "mem") == 0) {
+	    		if(argc==4) {
+				ld_addr=simple_strtoul(argv[3], NULL, 16);
+			}
+			else {
+				ld_addr=load_addr;
+			}
+			printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
+			result=mpl_prg_image(ld_addr);
+			switch_cs(sw); /* Switch flash back */
+			return result;
+		}
+		if (strcmp(argv[2], "mps") == 0) {
+			printf ("\nupdating bootloader image from MSP\n");
+			result=mpl_prg(src,size);
+			switch_cs(sw); /* Switch flash back */
+			return result;
+		}
+		switch_cs(sw); /* Switch flash back */
+
+	}
+	if (strcmp(argv[1], "mem") == 0)
+	{
+		result=0;
+		if(argc==3)
+		{
+			result = (int)simple_strtol(argv[2], NULL, 16);
+	    }
+	    src=(unsigned long)&result;
+	    src-=CFG_MEMTEST_START;
+	    src-=(100*1024); /* - 100k */
+	    src&=0xfff00000;
+	    size=0;
+	    do {
+	    	size++;
+			printf("\n\nPass %ld\n",size);
+			mem_test(CFG_MEMTEST_START,src,1);
+			if(ctrlc())
+				break;
+			if(result>0)
+				result--;
+
+		}while(result);
+		return 0;
+	}
+	if (strcmp(argv[1], "clearenvvalues") == 0)
+	{
+ 		if (strcmp(argv[2], "yes") == 0)
+		{
+			clear_env_values();
+			return 0;
+		}
+	}
+	if (strcmp(argv[1], "getback") == 0) {
+		get_backup_values(&back);
+		back.signature[3]=0;
+		back.serial_name[16]=0;
+		back.eth_addr[20]=0;
+		printf("GetBackUp: signature: %s\n",back.signature);
+		printf("           serial#:   %s\n",back.serial_name);
+		printf("           ethaddr:   %s\n",back.eth_addr);
+		return 0;
+	}
+	if (strcmp(argv[1], "setback") == 0) {
+		set_backup_values(1);
+		return 0;
+	}
+	printf("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void doc_probe(ulong physadr);
+void doc_init (void)
+{
+  doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
+}
+#endif
+
+
+#ifdef CONFIG_VIDEO
+/******************************************************
+ * Routines to display the Board information
+ * to the screen (since the VGA will be initialized as last,
+ * we must resend the infos)
+ */
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern GraphicDevice ctfb;
+
+void video_get_info_str (int line_number, char *info)
+{
+	/* init video info strings for graphic console */
+	DECLARE_GLOBAL_DATA_PTR;
+	PPC405_SYS_INFO sys_info;
+	char rev;
+	int i;
+	unsigned long pvr;
+	char buf[64];
+	char tmp[16];
+	unsigned char *s, *e, bc, sw;
+	switch (line_number)
+	{
+	case 2:
+		/* CPU and board infos */
+		pvr=get_pvr();
+		get_sys_info (&sys_info);
+		switch (pvr) {
+			case PVR_405GP_RB: rev='B'; break;
+			case PVR_405GP_RC: rev='C'; break;
+			case PVR_405GP_RD: rev='D'; break;
+			case PVR_405GP_RE: rev='E'; break;
+			default:           rev='?'; break;
+		}
+		/* Board info */
+		i=0;
+		s=getenv ("serial#");
+#ifdef CONFIG_PIP405
+		if (!s || strncmp (s, "PIP405", 6)) {
+			sprintf(buf,"### No HW ID - assuming PIP405");
+		}
+#endif
+#ifdef CONFIG_MIP405
+		if (!s || strncmp (s, "MIP405", 6)) {
+			sprintf(buf,"### No HW ID - assuming MIP405");
+		}
+#endif
+		else {
+			for (e = s; *e; ++e) {
+				if (*e == ' ')
+					break;
+			}
+			for (; s < e; ++s) {
+				if (*s == '_') {
+					++s;
+					break;
+				}
+				buf[i++]=*s;
+			}
+			sprintf(&buf[i]," SN ");
+			i+=4;
+			for (; s < e; ++s) {
+				buf[i++]=*s;
+			}
+			buf[i++]=0;
+		}
+		sprintf (info," %s PPC405GP %c %s MHz (%lu/%lu/%lu MHz)",
+			buf,rev,
+			strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
+			sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
+			sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
+		return;
+	case 3:
+		/* Memory Info */
+		sw = switch_cs (0);
+		switch_cs (sw);
+		bc = in8 (CONFIG_PORT_ADDR);
+		sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
+			gd->bd->bi_memsize / 0x100000,
+			gd->bd->bi_flashsize / 0x100000,
+			bc,
+			sw ? "MPS boot" : "Flash boot",
+			ctfb.modeIdent);
+		return;
+	case 1:
+		sprintf	(buf, "%s",CONFIG_IDENT_STRING);
+		sprintf (info, " %s", &buf[1]);
+		return;
+    }
+    /* no more info lines */
+    *info = 0;
+    return;
+}
+#endif /* CONFIG_CONSOLE_EXTRA_INFO */
+
+#endif /* CONFIG_VIDEO */
diff --git a/board/mpl/common/pci.c b/board/mpl/common/pci.c
new file mode 100644
index 0000000..d1965f9
--- /dev/null
+++ b/board/mpl/common/pci.c
@@ -0,0 +1,102 @@
+/*-----------------------------------------------------------------------------+
+|
+|       This source code has been made available to you by IBM on an AS-IS
+|       basis.  Anyone receiving this source is licensed under IBM
+|       copyrights to use it in any way he or she deems fit, including
+|       copying it, modifying it, compiling it, and redistributing it either
+|       with or without modifications.  No license under IBM patents or
+|       patent applications is to be implied by the copyright license.
+|
+|       Any user of this software should understand that IBM cannot provide
+|       technical support for this software and will not be responsible for
+|       any consequences resulting from the use of this software.
+|
+|       Any person who transfers this source code or any derivative work
+|       must include the IBM copyright notice, this paragraph, and the
+|       preceding two paragraphs in the transferred software.
+|
+|       COPYRIGHT   I B M   CORPORATION 1995
+|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
++-----------------------------------------------------------------------------*/
+/*
+ * Adapted for PIP405 03.07.01
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * TODO: Clean-up
+ */
+
+#include <common.h>
+#include <pci.h>
+#include "isa.h"
+
+#ifdef CONFIG_405GP
+#ifdef CONFIG_PCI
+
+#undef DEBUG
+
+#include "piix4_pci.h"
+#include "pci_parts.h"
+
+void pci_pip405_write_regs(struct pci_controller *hose, pci_dev_t dev,
+			   struct pci_config_table *entry)
+{
+	struct pci_pip405_config_entry *table;
+	int i;
+
+	table = (struct pci_pip405_config_entry*) entry->priv[0];
+
+	for (i=0; table[i].width; i++)
+	{
+#ifdef DEBUG
+		printf("Reg 0x%02X Value 0x%08lX Width %02d written\n",
+		       table[i].index, table[i].val, table[i].width);
+#endif
+
+		switch(table[i].width)
+		{
+		case 1: pci_hose_write_config_byte(hose, dev, table[i].index, table[i].val); break;
+		case 2: pci_hose_write_config_word(hose, dev, table[i].index, table[i].val); break;
+		case 4: pci_hose_write_config_dword(hose, dev, table[i].index, table[i].val); break;
+		}
+	}
+}
+
+
+static void pci_pip405_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	unsigned char int_line = 0xff;
+	/*
+	 * Write pci interrupt line register
+	 */
+	if(PCI_DEV(dev)==0) /* Device0 = PPC405 -> skip */
+		return;
+	if(PCI_FUNC(dev)==0)
+	{
+		/* assuming all function 0 are using their INTA# Pin*/
+		int_line=PCI_IRQ_VECTOR(dev);
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
+#ifdef DEBUG
+		printf("Fixup IRQ: dev %d (%x) int line %d 0x%x\n",
+		       PCI_DEV(dev),dev,int_line,int_line);
+#endif
+	}
+}
+
+extern void pci_405gp_init(struct pci_controller *hose);
+
+
+static struct pci_controller hose = {
+  config_table: pci_pip405_config_table,
+  fixup_irq: pci_pip405_fixup_irq,
+};
+
+void pci_init(void)
+{
+	/*we want the ptrs to RAM not flash (ie don't use init list)*/
+	hose.fixup_irq    = pci_pip405_fixup_irq;
+	hose.config_table = pci_pip405_config_table;
+	pci_405gp_init(&hose);
+}
+
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_405GP */
diff --git a/board/mpl/common/pci_parts.h b/board/mpl/common/pci_parts.h
new file mode 100644
index 0000000..944585f
--- /dev/null
+++ b/board/mpl/common/pci_parts.h
@@ -0,0 +1,192 @@
+ /*
+ * (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
+ *
+ */
+#ifndef _PCI_PARTS_H_
+#define _PCI_PARTS_H_
+
+
+/* Board specific file containing:
+ * - PCI Memory Mapping
+ * - PCI IO Mapping
+ * - PCI Interrupt Mapping
+ */
+
+/* PIP405 PCI INT Routing:
+ *                      IRQ0  VECTOR
+ * PIXX4 IDSEL  = AD16  INTA#  28 (Function 2 USB is INTD# = 31)
+ * VGA   IDSEL  = AD17  INTB#  29
+ * SCSI  IDSEL  = AD18  INTC#  30
+ * PC104 IDSEL0 = AD20  INTA#  28
+ * PC104 IDSEL1 = AD21  INTB#  29
+ * PC104 IDSEL2 = AD22  INTC#  30
+ * PC104 IDSEL3 = AD23  INTD#  31
+ *
+ * busdevfunc = EXXX XXXX BBBB BBBB DDDD DFFF RRRR RR00
+ *              ^         ^         ^     ^   ^
+ *             31        23        15    10   7
+ * E = Enabled
+ * B = Bussnumber
+ * D = Devicenumber (Device0 = AD10)
+ * F = Functionnumber
+ * R = Registernumber
+ *
+ * Device = (busdevfunc>>11) + 10
+ * Vector = devicenumber % 4 + 28
+ *
+ */
+#define PCI_HIGHEST_ON_BOARD_ID	19
+/*#define PCI_DEV_NUMBER(x)	(((x>>11) & 0x1f) + 10) */
+#define PCI_IRQ_VECTOR(x)	((PCI_DEV(x) + 10) % 4) + 28
+
+
+
+/* PCI Device List for PIP405 */
+
+/* Mapping:
+ * +-------------+------------+------------+--------------------------------+
+ * ¦ PCI MemAddr | PCI IOAddr | Local Addr | Device / Function              |
+ * +-------------+------------+------------+--------------------------------+
+ * |  0x00000000 |            | 0xA0000000 | ISA Memory (hard wired)        |
+ * |  0x00FFFFFF |            | 0xA0FFFFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ * |             | 0x00000000 | 0xE8000000 | ISA IO (hard wired)            |
+ * |             | 0x0000FFFF | 0xE800FFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ * |  0x80000000 |            | 0x80000000 | VGA Controller Memory          |
+ * |  0x80FFFFFF |            | 0x80FFFFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ * |  0x81000000 |            | 0x81000000 | SCSI Controller Memory         |
+ * |  0x81FFFFFF |            | 0x81FFFFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ */
+
+struct pci_pip405_config_entry {
+	int 		index; 	/* address */
+	unsigned long 	val;	/* value */
+	int 		width;	/* data size */
+};
+
+extern void pci_pip405_write_regs(struct pci_controller *,
+				  pci_dev_t,
+				  struct pci_config_table *);
+
+/* PIIX4 ISA Bridge Function 0 */
+static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
+	{PCI_CFG_PIIX4_SERIRQ,	0xD0,		1}, /* enable Continous SERIRQ Pin */
+	{PCI_CFG_PIIX4_GENCFG,	0x00010041,	4}, /* enable SERIRQs, ISA, PNP	*/
+	{PCI_CFG_PIIX4_TOM,	0xFE,		1}, /* Top of Memory		*/
+	{PCI_CFG_PIIX4_XBCS,	0x02C4,		2}, /* disable all peri CS	*/
+	{PCI_CFG_PIIX4_RTCCFG,	0x21,		1}, /* enable RTC	   	*/
+#if defined(CONFIG_PIP405)
+	{PCI_CFG_PIIX4_MBDMA,	0x82,		1}, /* set MBDMA0 to DMA 2   	*/
+	{PCI_CFG_PIIX4_MBDMA+1,	0x83,		1}, /* set MBDMA1 to DMA 3   	*/
+#endif
+	{PCI_CFG_PIIX4_DLC,	0x0,		1}, /* disable passive release feature */
+	{ }				    	    /* end of device table	*/
+};
+
+/* PIIX4 IDE Controller Function 1 */
+static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
+	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/
+	{PCI_CFG_PIIX4_IDETIM,	0x80008000,	4}, /* enable Both IDE channels	*/
+	{ }					    /* end of device table 	*/
+};
+
+/* PIIX4 USB Controller Function 2 */
+static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
+	{PCI_INTERRUPT_LINE,	31,		1}, /* Int vector = 31 		*/
+	{PCI_BASE_ADDRESS_4,	0x0000E001,	4}, /* Set IO Address to 0xe000 to 0xe01F */
+	{PCI_LATENCY_TIMER,	0x80,		1}, /* Latency Timer 0x80 	*/
+	{0xC0,			0x2000,		2}, /* Legacy support 		*/
+	{PCI_COMMAND,		0x0005,		2}, /* enable IO access and Master */
+	{ }					    /* end of device table 	*/
+};
+
+/* PIIX4 Power Management Function 3 */
+static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = {
+	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/
+	{PCI_CFG_PIIX4_PMAB,	0x00004000,	4}, /* set PMBA to "valid" value */
+	{PCI_CFG_PIIX4_PMMISC,	0x01,		1}, /* enable PMBA IO access	*/
+	{PCI_CFG_PIIX4_SMBBA,	0x00005000,	4}, /* set SMBBA to "valid" value */
+	{ }					    /* end of device table 	*/
+};
+/* PPC405 Dummy only used to prevent autosetup on this host bridge */
+static struct pci_pip405_config_entry ibm405_dummy[] = {
+	{ }				    	    /* end of device table 	*/
+};
+
+void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
+			 struct pci_config_table *entry);
+
+
+static struct pci_config_table pci_pip405_config_table[]={
+	{PCI_VENDOR_ID_IBM, 			/* 405 dummy */
+	 PCI_DEVICE_ID_IBM_405GP,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 0,
+	 pci_pip405_write_regs, {(unsigned long) ibm405_dummy}},
+
+	{PCI_VENDOR_ID_INTEL, 			/* PIIX4 ISA Bridge Function 0 */
+	 PCI_DEVICE_ID_INTEL_82371AB_0,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 0,
+	 pci_pip405_write_regs, {(unsigned long) piix4_isa_bridge_f0}},
+
+	{PCI_VENDOR_ID_INTEL,			/* PIIX4 IDE Controller Function 1 */
+	 PCI_DEVICE_ID_INTEL_82371AB,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 1,
+	 pci_pip405_write_regs, {(unsigned long) piix4_ide_cntrl_f1}},
+
+	{PCI_VENDOR_ID_INTEL,			/* PIIX4 USB Controller Function 2 */
+	 PCI_DEVICE_ID_INTEL_82371AB_2,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 2,
+	 pci_pip405_write_regs, {(unsigned long) piix4_usb_cntrl_f2}},
+
+	{PCI_VENDOR_ID_INTEL,			/* PIIX4 USB Controller Function 3 */
+	 PCI_DEVICE_ID_INTEL_82371AB_3,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 3,
+	 pci_pip405_write_regs, {(unsigned long) piix4_pmm_cntrl_f3}},
+
+	{PCI_ANY_ID,
+	 PCI_ANY_ID,
+	 PCI_CLASS_DISPLAY_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	 pci_405gp_setup_vga},
+
+	{PCI_ANY_ID,
+	 PCI_ANY_ID,
+	 PCI_CLASS_NOT_DEFINED_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	 pci_405gp_setup_vga},
+
+	{ }
+};
+#endif /* _PCI_PARTS_H_ */
+
+
+
+
+
diff --git a/board/mpl/mip405/Makefile b/board/mpl/mip405/Makefile
new file mode 100644
index 0000000..839cafe
--- /dev/null
+++ b/board/mpl/mip405/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000, 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 $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o ../common/flash.o cmd_mip405.o ../common/pci.o \
+			../common/usb_uhci.o ../common/memtst.o ../common/common_util.o
+
+SOBJS	= init.o
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $^
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/mpl/pip405/Makefile b/board/mpl/pip405/Makefile
new file mode 100644
index 0000000..b6cc531
--- /dev/null
+++ b/board/mpl/pip405/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000, 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 $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o \
+	  ../common/flash.o cmd_pip405.o ../common/pci.o \
+	  ../common/isa.o ../common/kbd.o \
+	  ../common/usb_uhci.o \
+	  ../common/memtst.o ../common/common_util.o
+
+SOBJS	= init.o
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $^
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/musenki/musenki.c b/board/musenki/musenki.c
new file mode 100644
index 0000000..3b02f37
--- /dev/null
+++ b/board/musenki/musenki.c
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.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
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+int checkboard (void)
+{
+	ulong busfreq  = get_bus_freq(0);
+	char  buf[32];
+
+	printf("Board: MUSENKI Local Bus at %s MHz\n", strmhz(buf, busfreq));
+	return 0;
+
+}
+
+#if 0 	/* NOT USED */
+int checkflash (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("## Test not implemented yet ##\n");
+
+	return (0);
+}
+#endif
+
+long int initdram (int board_type)
+{
+	int              i, cnt;
+	volatile uchar * base= CFG_SDRAM_BASE;
+	volatile ulong * addr;
+	ulong            save[32];
+	ulong            val, ret  = 0;
+
+	for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+		addr = (volatile ulong *)base + cnt;
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	addr = (volatile ulong *)base;
+	save[i] = *addr;
+	*addr = 0;
+
+	if (*addr != 0) {
+		*addr = save[i];
+		goto Done;
+	}
+
+	for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+		addr = (volatile ulong *)base + cnt;
+		val = *addr;
+		*addr = save[--i];
+		if (val != ~cnt) {
+			ulong new_bank0_end = cnt * sizeof(long) - 1;
+			ulong mear1  = mpc824x_mpc107_getreg(MEAR1);
+			ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+			mear1 =  (mear1  & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+			emear1 = (emear1 & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+			mpc824x_mpc107_setreg(MEAR1,  mear1);
+			mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+			ret = cnt * sizeof(long);
+			goto Done;
+		}
+	}
+
+	ret = CFG_MAX_RAM_SIZE;
+Done:
+	return ret;
+}
+
+/*
+ * Initialize PCI Devices
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+#if 0
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  0x0, 0x0, 0x0, /* unknown eth0 divice */
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_IO |
+				       PCI_COMMAND_MEMORY |
+				       PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  0x0, 0x0, 0x0, /* unknown eth1 device */
+	  pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+				       PCI_ENET1_MEMADDR,
+				       PCI_COMMAND_IO |
+				       PCI_COMMAND_MEMORY |
+				       PCI_COMMAND_MASTER }},
+#endif
+	{ }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/mvs1/Makefile b/board/mvs1/Makefile
new file mode 100644
index 0000000..ef173d0
--- /dev/null
+++ b/board/mvs1/Makefile
@@ -0,0 +1,40 @@
+#
+# (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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o flash.o
+
+$(LIB):	.depend $(OBJS)
+	$(AR) crv $@ $^
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/netvia/Makefile b/board/netvia/Makefile
new file mode 100644
index 0000000..ef173d0
--- /dev/null
+++ b/board/netvia/Makefile
@@ -0,0 +1,40 @@
+#
+# (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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o flash.o
+
+$(LIB):	.depend $(OBJS)
+	$(AR) crv $@ $^
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/netvia/netvia.c b/board/netvia/netvia.c
new file mode 100644
index 0000000..504593e
--- /dev/null
+++ b/board/netvia/netvia.c
@@ -0,0 +1,374 @@
+/*
+ * (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
+ */
+
+/*
+ * Pantelis Antoniou, Intracom S.A., panto@intracom.gr
+ * U-Boot port on NetVia board
+ */
+
+#include <common.h>
+#include "mpc8xx.h"
+
+/* some sane bit macros */
+#define _BD(_b)				(1U << (31-(_b)))
+#define _BDR(_l, _h)			(((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
+
+#define _BW(_b)				(1U << (15-(_b)))
+#define _BWR(_l, _h)			(((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
+
+#define _BB(_b)				(1U << (7-(_b)))
+#define _BBR(_l, _h)			(((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
+
+#define _B(_b)				_BD(_b)
+#define _BR(_l, _h)			_BDR(_l, _h)
+
+/* ------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_	0xFFFFFFFF
+
+/* ------------------------------------------------------------------------- */
+
+#define CS_0000		0x00000000
+#define CS_0001		0x10000000
+#define CS_0010		0x20000000
+#define CS_0011		0x30000000
+#define CS_0100		0x40000000
+#define CS_0101		0x50000000
+#define CS_0110		0x60000000
+#define CS_0111		0x70000000
+#define CS_1000		0x80000000
+#define CS_1001		0x90000000
+#define CS_1010		0xA0000000
+#define CS_1011		0xB0000000
+#define CS_1100		0xC0000000
+#define CS_1101		0xD0000000
+#define CS_1110		0xE0000000
+#define CS_1111		0xF0000000
+
+#define BS_0000		0x00000000
+#define BS_0001		0x01000000
+#define BS_0010		0x02000000
+#define BS_0011		0x03000000
+#define BS_0100		0x04000000
+#define BS_0101		0x05000000
+#define BS_0110		0x06000000
+#define BS_0111		0x07000000
+#define BS_1000		0x08000000
+#define BS_1001		0x09000000
+#define BS_1010		0x0A000000
+#define BS_1011		0x0B000000
+#define BS_1100		0x0C000000
+#define BS_1101		0x0D000000
+#define BS_1110		0x0E000000
+#define BS_1111		0x0F000000
+
+#define A10_AAAA	0x00000000
+#define A10_AAA0	0x00200000
+#define A10_AAA1	0x00300000
+#define A10_000A	0x00800000
+#define A10_0000	0x00A00000
+#define A10_0001	0x00B00000
+#define A10_111A	0x00C00000
+#define A10_1110	0x00E00000
+#define A10_1111	0x00F00000
+
+#define RAS_0000	0x00000000
+#define RAS_0001	0x00040000
+#define RAS_1110	0x00080000
+#define RAS_1111	0x000C0000
+
+#define CAS_0000	0x00000000
+#define CAS_0001	0x00010000
+#define CAS_1110	0x00020000
+#define CAS_1111	0x00030000
+
+#define WE_0000		0x00000000
+#define WE_0001		0x00004000
+#define WE_1110		0x00008000
+#define WE_1111		0x0000C000
+
+#define GPL4_0000	0x00000000
+#define GPL4_0001	0x00001000
+#define GPL4_1110	0x00002000
+#define GPL4_1111	0x00003000
+
+#define GPL5_0000	0x00000000
+#define GPL5_0001	0x00000400
+#define GPL5_1110	0x00000800
+#define GPL5_1111	0x00000C00
+#define LOOP		0x00000080
+
+#define EXEN		0x00000040
+
+#define AMX_COL		0x00000000
+#define AMX_ROW		0x00000020
+#define AMX_MAR		0x00000030
+
+#define NA		0x00000008
+
+#define UTA		0x00000004
+
+#define TODT		0x00000002
+
+#define LAST		0x00000001
+
+const uint sdram_table[0x40] = {
+	/* RSS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* ACT   */
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_0000 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA,			/* READ  */
+	CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA,			/* PALL  */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST,	/* NOP   */
+	_NOT_USED_, _NOT_USED_,
+
+	/* RBS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* ACT   */
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_0001 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA,			/* READ  */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP	 */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP	 */
+	CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL,				/* PALL  */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST,		/* NOP	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* WSS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+	CS_0000 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL | UTA,
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* WBS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* ACT   */
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL,				/* WRITE */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_1111 | BS_0001 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA,			/* PALL  */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST,	/* NOP   */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* UPT */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_0001 | WE_1111 | AMX_COL | LOOP,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LOOP,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LAST,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_,
+
+	/* EXC */
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST,
+
+	/* REG */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1110 | AMX_MAR,
+	CS_0001 | BS_1111 | A10_0001 | RAS_0001 | CAS_0001 | WE_0001 | AMX_MAR | TODT | LAST,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Test ETX ID string (ETX_xxx...)
+ *
+ * Return 1 always.
+ */
+
+int checkboard(void)
+{
+	printf ("NETVIA\n");
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* 0xC8 = 0b11001000 , CAS3, >> 2 = 0b00 11 0 010 */
+#define MAR_SDRAM_INIT		0x000000C8LU
+
+#define MCR_OP(x)		((unsigned long)((x) & 3) << (31-1))
+#define MCR_OP_MASK		MCR_OP(3)
+
+#define MCR_UM(x)		((unsigned long)((x) & 1) << (31 - 8))
+#define MCR_UM_MASK		MCR_UM(1)
+#define MCR_UM_UPMA		MCR_UM(0)
+#define MCR_UM_UPMB		MCR_UM(1)
+
+#define MCR_MB(x)		((unsigned long)((x) & 7) << (31 - 18))
+#define MCR_MB_MASK		MCR_MB(7)
+#define MCR_MB_CS(x)		MCR_MB(x)
+
+#define MCR_MCLF(x)		((unsigned long)((x) & 15) << (31 - 23))
+#define MCR_MCLF_MASK		MCR_MCLF(15)
+
+long int initdram(int board_type)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	long int size;
+
+	upmconfig(UPMA, (uint *) sdram_table, sizeof(sdram_table) / sizeof(uint));
+
+	/*
+	 * Preliminary prescaler for refresh
+	 */
+	memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+
+	memctl->memc_mar = MAR_SDRAM_INIT;	/* 32-bit address to be output on the address bus if AMX = 0b11 */
+
+    /*
+     * Map controller bank 3 to the SDRAM bank at preliminary address.
+     */
+	memctl->memc_or3 = CFG_OR3_PRELIM;
+	memctl->memc_br3 = CFG_BR3_PRELIM;
+
+	memctl->memc_mamr = CFG_MAMR_9COL & ~MAMR_PTAE;	/* no refresh yet */
+
+	udelay(200);
+
+	/* perform SDRAM initialisation sequence */
+	memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3C);	/* precharge all			*/
+	udelay(1);
+	memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(0) | MCR_MAD(0x30); /* refresh 16 times(0)		*/
+	udelay(1);
+	memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3E);	/* exception program (write mar) */
+	udelay(1);
+
+	memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */
+
+	udelay(1000);
+
+	memctl->memc_mamr = CFG_MAMR_9COL;
+
+	size = SDRAM_MAX_SIZE;
+
+	udelay(10000);
+
+	/* do the ram test */
+	{
+		register unsigned long *rp;
+		register unsigned long v;
+
+		/* first fill */
+		for (rp = (unsigned long *)0; rp < (unsigned long *)SDRAM_MAX_SIZE; )
+		    *rp++ = (unsigned long)rp;
+
+		/* now check */
+		for (rp = (unsigned long *)0; rp < (unsigned long *)SDRAM_MAX_SIZE; rp++) {
+		    if ((v = *rp) != (unsigned long)rp) {
+			printf("ERROR at 0x%lx (0x%lx)\n", (unsigned long)rp, v);
+			return -1;
+		    }
+		}
+
+	}
+
+	return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_r(void)
+{
+	return(0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* bits that can have a special purpose or can be configured as inputs/outputs */
+#define PA_MASK		(_BWR(4, 9) | _BWR(12, 15))
+#define PA_ODR_MASK	(_BW(9) | _BW(12) | _BW(14))
+#define PA_ODR_VAL	0
+#define PA_GP_INMASK	0
+#define PA_GP_OUTMASK	(_BW(5) | _BW(14) | _BW(15))
+#define PA_SP_OUTMASK	0
+#define PA_GP_OUTVAL	_BW(5)
+#define PA_SP_OUTVAL	0
+
+#define PB_MASK		(_BR(16, 19) | _BR(22, 31))
+#define PB_ODR_MASK	PB_MASK
+#define PB_ODR_VAL	0
+#define PB_GP_INMASK	0
+#define PB_GP_OUTMASK	(_BR(16, 19) | _BR(26, 27) | _B(31))
+#define PB_SP_OUTMASK	_BR(28, 30)
+#define PB_SP_OUTVAL	_BR(28, 30)
+#define PB_GP_OUTVAL	(_BR(16, 19) | _BR(26, 27) | _B(31))
+
+#define PC_MASK		_BWR(4, 15)
+#define PC_SO_MASK	(_BWR(6, 11) | _BWR(14, 15))
+#define PC_SO_VAL	0
+#define PC_INT_MASK	PC_MASK
+#define PC_INT_VAL	0
+#define PC_GP_INMASK	(_BWR(5, 7) | _BWR(9, 10) | _BW(13))
+#define PC_GP_OUTMASK	_BW(12)
+#define PC_SP_OUTMASK	0
+#define PC_SP_OUTVAL	_BW(12)
+#define PC_GP_OUTVAL	0
+
+#define PD_MASK		_BWR(0, 15)
+#define PD_GP_INMASK	0
+#define PD_GP_OUTMASK	_BWR(3, 15)
+#define PD_SP_OUTMASK	0
+#define PD_GP_OUTVAL	(_BW(3) | _BW(5) | _BW(7) | _BWR(8, 15))
+#define PD_SP_OUTVAL	0
+
+int board_pre_init(void)
+{
+	register volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	register volatile iop8xx_t *ioport = &immap->im_ioport;
+	register volatile cpm8xx_t *cpm = &immap->im_cpm;
+
+	ioport->iop_padat = (ioport->iop_padat & ~PA_MASK)     | PA_SP_OUTVAL | PA_GP_OUTVAL;
+	ioport->iop_paodr = (ioport->iop_paodr & ~PA_ODR_MASK) | PA_ODR_VAL;
+	ioport->iop_padir = (ioport->iop_padir & ~PA_GP_INMASK)| PA_SP_OUTMASK | PA_GP_OUTMASK;
+	ioport->iop_papar = (ioport->iop_papar & ~(PA_GP_INMASK & PA_GP_OUTMASK));
+
+	cpm->cp_pbdat = (ioport->iop_padat & ~PB_MASK)     | PB_SP_OUTVAL | PB_GP_OUTVAL;
+	cpm->cp_pbodr = (ioport->iop_paodr & ~PB_ODR_MASK) | PB_ODR_VAL;
+	cpm->cp_pbdir = (ioport->iop_padir & ~PB_GP_INMASK)| PB_SP_OUTMASK | PB_GP_OUTMASK;
+	cpm->cp_pbpar = (ioport->iop_papar & ~(PB_GP_INMASK & PB_GP_OUTMASK));
+
+	ioport->iop_pcdat = (ioport->iop_pcdat & ~PC_MASK)     | PC_SP_OUTVAL | PC_GP_OUTVAL;
+	ioport->iop_pcdir = (ioport->iop_pcdir & ~PC_GP_INMASK)| PC_SP_OUTMASK | PC_GP_OUTMASK;
+	ioport->iop_pcso  = (ioport->iop_pcso  & ~PC_SO_MASK)  | PC_SO_VAL;
+	ioport->iop_pcint = (ioport->iop_pcint & ~PC_INT_MASK) | PC_INT_VAL;
+	ioport->iop_pcpar = (ioport->iop_pcpar & ~(PC_GP_INMASK & PC_GP_OUTMASK));
+
+	ioport->iop_pddat = (ioport->iop_pddat & ~PD_MASK)     | PD_SP_OUTVAL | PD_GP_OUTVAL;
+	ioport->iop_pddir = (ioport->iop_pddir & ~PD_GP_INMASK)| PD_SP_OUTMASK | PD_GP_OUTMASK;
+	ioport->iop_pdpar = (ioport->iop_pdpar & ~(PD_GP_INMASK & PD_GP_OUTMASK));
+
+	return 0;
+}
+
diff --git a/board/netvia/u-boot.lds b/board/netvia/u-boot.lds
new file mode 100644
index 0000000..e75f12c
--- /dev/null
+++ b/board/netvia/u-boot.lds
@@ -0,0 +1,132 @@
+/*
+ * (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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp		: { *(.interp)		}
+  .hash         : { *(.hash)		}
+  .dynsym       : { *(.dynsym)		}
+  .dynstr       : { *(.dynstr)		}
+  .rel.text     : { *(.rel.text)	}
+  .rela.text    : { *(.rela.text) 	}
+  .rel.data     : { *(.rel.data)	}
+  .rela.data    : { *(.rela.data) 	}
+  .rel.rodata   : { *(.rel.rodata) 	}
+  .rela.rodata  : { *(.rela.rodata)	}
+  .rel.got      : { *(.rel.got)		}
+  .rela.got     : { *(.rela.got)	}
+  .rel.ctors    : { *(.rel.ctors)	}
+  .rela.ctors   : { *(.rela.ctors)	}
+  .rel.dtors    : { *(.rel.dtors)	}
+  .rela.dtors   : { *(.rela.dtors)	}
+  .rel.bss      : { *(.rel.bss)		}
+  .rela.bss     : { *(.rela.bss)	}
+  .rel.plt      : { *(.rel.plt)		}
+  .rela.plt     : { *(.rela.plt)	}
+  .init         : { *(.init)		}
+  .plt			: { *(.plt) 		}
+  .text      	:
+  {
+    cpu/mpc8xx/start.o		(.text)
+    cpu/mpc8xx/traps.o		(.text)
+    common/dlmalloc.o		(.text)
+    lib_ppc/ppcstring.o		(.text)
+    lib_generic/vsprintf.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_generic/zlib.o		(.text)
+    lib_ppc/cache.o		(.text)
+    lib_ppc/time.o		(.text)
+
+    . = env_offset;
+    common/environment.o	(.ppcenv)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/netvia/u-boot.lds.debug b/board/netvia/u-boot.lds.debug
new file mode 100644
index 0000000..fa494fb
--- /dev/null
+++ b/board/netvia/u-boot.lds.debug
@@ -0,0 +1,131 @@
+/*
+ * (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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within	*/
+    /* the sector layout of our flash chips!	XXX FIXME XXX	*/
+
+    cpu/mpc8xx/start.o		(.text)
+    common/dlmalloc.o		(.text)
+    lib_generic/vsprintf.o	(.text)
+    lib_generic/crc32.o		(.text)
+
+    . = env_offset;
+    common/environment.o(.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
+
diff --git a/board/oxc/flash.c b/board/oxc/flash.c
new file mode 100644
index 0000000..4f0220e
--- /dev/null
+++ b/board/oxc/flash.c
@@ -0,0 +1,372 @@
+/*
+ * (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.
+ *
+ * Flash Routines for STM29W320DB/STM29W800D flash chips
+ *
+ *--------------------------------------------------------------------
+ * 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]; /* info for FLASH chips	*/
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+
+static ulong flash_get_size (vu_char *addr, flash_info_t *info);
+static int write_byte (flash_info_t *info, ulong dest, uchar data);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+    unsigned long size;
+    int i;
+
+    /* Init: no FLASHes known */
+    for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+	flash_info[i].flash_id = FLASH_UNKNOWN;
+    }
+
+    /*
+     * We use the following trick here: since flash is cyclically
+     * mapped in the 0xFF800000-0xFFFFFFFF area, we detect the type
+     * and the size of flash using 0xFF800000 as the base address,
+     * and then call flash_get_size() again to fill flash_info.
+     */
+    size = flash_get_size((vu_char *)CFG_FLASH_PRELIMBASE, &flash_info[0]);
+    if (size)
+    {
+	flash_get_size((vu_char *)(-size), &flash_info[0]);
+    }
+
+#if (CFG_MONITOR_BASE >= CFG_FLASH_PRELIMBASE)
+    /* monitor protection ON by default */
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_MONITOR_BASE,
+		  CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+		  &flash_info[0]);
+#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
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_ENV_ADDR,
+		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+		  &flash_info[0]);
+#endif
+
+    return (size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+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_STM:
+	printf ("ST ");
+	break;
+    default:
+	printf ("Unknown Vendor ");
+	break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+    case FLASH_STM320DB:
+	printf ("M29W320DB (32 Mbit)\n");
+	break;
+    case FLASH_STM800DB:
+	printf ("M29W800DB (8 Mbit, bottom boot block)\n");
+	break;
+    case FLASH_STM800DT:
+	printf ("M29W800DT (8 Mbit, top boot block)\n");
+	break;
+    default:
+	printf ("Unknown Chip Type\n");
+	break;
+    }
+
+    printf ("  Size: %ld KB in %d Sectors\n",
+	    info->size >> 10, 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_char *addr, flash_info_t *info)
+{
+    short i;
+    uchar vendor, devid;
+    ulong base = (ulong)addr;
+
+    /* Write auto select command: read Manufacturer ID */
+    addr[0x0AAA] = 0xAA;
+    addr[0x0555] = 0x55;
+    addr[0x0AAA] = 0x90;
+
+    udelay(1000);
+
+    vendor = addr[0];
+    devid = addr[2];
+
+    /* only support STM */
+    if ((vendor << 16) != FLASH_MAN_STM) {
+	return 0;
+    }
+
+    if (devid == FLASH_STM320DB) {
+    	/* MPC8240 can address maximum 2Mb of flash, that is why the MSB
+	 * lead is grounded and we can access only 2 first Mb */
+	info->flash_id     = vendor << 16 | devid;
+	info->sector_count = 32;
+	info->size         = info->sector_count * 0x10000;
+	for (i = 0; i < info->sector_count; i++) {
+	    info->start[i] = base + i * 0x10000;
+	}
+    }
+    else if (devid == FLASH_STM800DB) {
+	info->flash_id     = vendor << 16 | devid;
+	info->sector_count = 19;
+	info->size         = 0x100000;
+	info->start[0]     = 0x0000;
+	info->start[1]     = 0x4000;
+	info->start[2]     = 0x6000;
+	info->start[3]     = 0x8000;
+	for (i = 4; i < info->sector_count; i++) {
+	    info->start[i] = base + (i-3) * 0x10000;
+	}
+    }
+    else if (devid == FLASH_STM800DT) {
+	info->flash_id     = vendor << 16 | devid;
+	info->sector_count = 19;
+	info->size         = 0x100000;
+	for (i = 0; i < info->sector_count-4; i++) {
+	    info->start[i] = base + i * 0x10000;
+	}
+	info->start[i]     = base + i * 0x10000;
+	info->start[i+1]   = base + i * 0x10000 + 0x8000;
+	info->start[i+2]   = base + i * 0x10000 + 0xa000;
+	info->start[i+3]   = base + i * 0x10000 + 0xc000;
+    }
+    else {
+	return 0;
+    }
+
+    /* mark all sectors as unprotected */
+    for (i = 0; i < info->sector_count; i++) {
+	info->protect[i] = 0;
+    }
+
+    /* Issue the reset command */
+    if (info->flash_id != FLASH_UNKNOWN) {
+	addr[0] = 0xF0;	/* reset bank */
+    }
+
+    return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+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");
+    }
+
+    l_sect = -1;
+
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    addr[0x0AAA] = 0xAA;
+    addr[0x0555] = 0x55;
+    addr[0x0AAA] = 0x80;
+    addr[0x0AAA] = 0xAA;
+    addr[0x0555] = 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 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;
+	}
+    }
+
+    DONE:
+    /* reset to read mode */
+    addr = (volatile unsigned char *)info->start[0];
+    addr[0] = 0xF0;	/* reset bank */
+
+    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)
+{
+    int rc;
+
+    while (cnt > 0) {
+	if ((rc = write_byte(info, addr, *src)) != 0) {
+	    return (rc);
+	}
+	addr++;
+	src++;
+	cnt--;
+    }
+
+    return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * 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[0x0AAA] = 0xAA;
+    addr[0x0555] = 0x55;
+    addr[0x0AAA] = 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);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/oxc/oxc.c b/board/oxc/oxc.c
new file mode 100644
index 0000000..8aced84
--- /dev/null
+++ b/board/oxc/oxc.c
@@ -0,0 +1,237 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.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
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+#include <i2c.h>
+
+int checkboard (void)
+{
+	puts (	"Board: OXC8240\n" );
+	return 0;
+}
+
+long int initdram (int board_type)
+{
+#ifndef CFG_RAMBOOT
+	int		 i, cnt;
+	volatile uchar * base= CFG_SDRAM_BASE;
+	volatile ulong * addr;
+	ulong		 save[32];
+	ulong		 val, ret  = 0;
+
+	for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+		addr = (volatile ulong *)base + cnt;
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	addr = (volatile ulong *)base;
+	save[i] = *addr;
+	*addr = 0;
+
+	if (*addr != 0) {
+		*addr = save[i];
+		goto Done;
+	}
+
+	for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+		addr = (volatile ulong *)base + cnt;
+		val = *addr;
+		*addr = save[--i];
+		if (val != ~cnt) {
+			ulong new_bank0_end = cnt * sizeof(long) - 1;
+			ulong mear1  = mpc824x_mpc107_getreg(MEAR1);
+			ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+			mear1 =  (mear1  & 0xFFFFFF00) |
+			((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+			emear1 = (emear1 & 0xFFFFFF00) |
+			((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+			mpc824x_mpc107_setreg(MEAR1,  mear1);
+			mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+			ret = cnt * sizeof(long);
+			goto Done;
+		}
+	}
+
+	ret = CFG_MAX_RAM_SIZE;
+Done:
+	return ret;
+#else
+	/* if U-Boot starts from RAM, then suppose we have 16Mb of RAM */
+	return (16 << 20);
+#endif
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_oxc_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x14, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x15, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+				       PCI_ENET1_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ }
+};
+#endif
+
+static struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_oxc_config_table,
+#endif
+};
+
+void pci_init (void)
+{
+	pci_mpc824x_init(&hose);
+}
+
+int board_pre_init (void)
+{
+	*(volatile unsigned char *)(CFG_CPLD_RESET) = 0x89;
+	return 0;
+}
+
+#ifdef CONFIG_WATCHDOG
+void oxc_wdt_reset(void)
+{
+	*(volatile unsigned char *)(CFG_CPLD_WATCHDOG) = 0xff;
+}
+
+void watchdog_reset(void)
+{
+	int re_enable = disable_interrupts();
+
+	oxc_wdt_reset();
+	if (re_enable)
+		enable_interrupts();
+}
+#endif
+
+static int oxc_get_expander(unsigned char addr, unsigned char * val)
+{
+	return i2c_read(addr, 0, 0, val, 1);
+}
+
+static int oxc_set_expander(unsigned char addr, unsigned char val)
+{
+	return i2c_write(addr, 0, 0, &val, 1);
+}
+
+static int expander0alive = 0;
+
+#ifdef CONFIG_SHOW_ACTIVITY
+static int ledtoggle = 0;
+static int ledstatus = 1;
+
+void oxc_toggle_activeled(void)
+{
+	ledtoggle++;
+}
+
+void show_activity(int arg)
+{
+	static unsigned char led = 0;
+	unsigned char val;
+
+	if (!expander0alive) return;
+
+	if ((ledtoggle > (2 * arg)) && ledstatus) {
+		led ^= 0x80;
+		oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+		udelay(200);
+		oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, (val & 0x7F) | led);
+		ledtoggle = 0;
+	}
+}
+#endif
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress(int arg)
+{
+	unsigned char val;
+
+	if (!expander0alive) return;
+
+	if (arg > 0 && ledstatus) {
+		ledstatus = 0;
+		oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+		udelay(200);
+		oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, val | 0x80);
+	} else if (arg < 0) {
+		oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+		udelay(200);
+		oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, val & 0x7F);
+		ledstatus = 1;
+	}
+}
+#endif
+
+int misc_init_r (void)
+{
+	/* check whether the i2c expander #0 is accessible */
+	if (!oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, 0x7F)) {
+		udelay(200);
+		expander0alive = 1;
+	}
+
+#ifdef CFG_OXC_GENERATE_IP
+	{
+		DECLARE_GLOBAL_DATA_PTR;
+
+		char str[32];
+		unsigned long ip = CFG_OXC_IPMASK;
+		bd_t *bd = gd->bd;
+
+		if (expander0alive) {
+			unsigned char val;
+
+			if (!oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val)) {
+				ip = (ip & 0xffffff00) | ((val & 0x7c) >> 2);
+			}
+		}
+
+		if ((ip & 0xff) < 3) {
+			/* if fail, set x.x.x.254 */
+			ip = (ip & 0xffffff00) | 0xfe;
+		}
+
+		bd->bi_ip_addr = ip;
+		sprintf(str, "%ld.%ld.%ld.%ld",
+			(bd->bi_ip_addr & 0xff000000) >> 24,
+			(bd->bi_ip_addr & 0x00ff0000) >> 16,
+			(bd->bi_ip_addr & 0x0000ff00) >> 8,
+			(bd->bi_ip_addr & 0x000000ff));
+		setenv("ipaddr", str);
+		printf("ip:    %s\n", str);
+	}
+#endif
+	return (0);
+}
diff --git a/board/pcippc2/cpc710_init_ram.c b/board/pcippc2/cpc710_init_ram.c
new file mode 100644
index 0000000..57ed8f0
--- /dev/null
+++ b/board/pcippc2/cpc710_init_ram.c
@@ -0,0 +1,254 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <asm/io.h>
+
+#include "pcippc2.h"
+#include "i2c.h"
+
+typedef struct cpc710_mem_org_s
+{
+  u8		rows;
+  u8		cols;
+  u8		banks2;
+  u8		org;
+} cpc710_mem_org_t;
+
+static int		cpc710_compute_mcer	(u32 *		mcer,
+						 unsigned long *
+								size,
+						 unsigned int	sdram);
+static int		cpc710_eeprom_checksum	(unsigned int	sdram);
+static u8		cpc710_eeprom_read	(unsigned int	sdram,
+						 unsigned int	offset);
+
+static u32		cpc710_mcer_mem [] =
+{
+  0x000003f3,	/* 18 lines,    4 Mb */
+  0x000003e3,	/* 19 lines,    8 Mb */
+  0x000003c3,	/* 20 lines,   16 Mb */
+  0x00000383,	/* 21 lines,   32 Mb */
+  0x00000303,	/* 22 lines,   64 Mb */
+  0x00000203,	/* 23 lines,  128 Mb */
+  0x00000003,	/* 24 lines,  256 Mb */
+  0x00000002,	/* 25 lines,  512 Mb */
+  0x00000001	/* 26 lines, 1024 Mb */
+};
+static cpc710_mem_org_t	cpc710_mem_org [] =
+{
+  { 0x0c, 0x09, 0x02, 0x00 },	/* 0000: 12/ 9/2 */
+  { 0x0d, 0x09, 0x02, 0x00 },	/* 0000: 13/ 9/2 */
+  { 0x0d, 0x0a, 0x02, 0x00 },	/* 0000: 13/10/2 */
+  { 0x0d, 0x0b, 0x02, 0x00 },	/* 0000: 13/11/2 */
+  { 0x0d, 0x0c, 0x02, 0x00 },	/* 0000: 13/12/2 */
+  { 0x0e, 0x0c, 0x02, 0x00 },	/* 0000: 14/12/2 */
+  { 0x0b, 0x08, 0x02, 0x01 },	/* 0001: 11/ 8/2 */
+  { 0x0b, 0x09, 0x01, 0x02 },	/* 0010: 11/ 9/1 */
+  { 0x0b, 0x0a, 0x01, 0x03 },	/* 0011: 11/10/1 */
+  { 0x0c, 0x08, 0x02, 0x04 },	/* 0100: 12/ 8/2 */
+  { 0x0c, 0x0a, 0x02, 0x05 },	/* 0101: 12/10/2 */
+  { 0x0d, 0x08, 0x01, 0x06 },	/* 0110: 13/ 8/1 */
+  { 0x0d, 0x08, 0x02, 0x07 },	/* 0111: 13/ 8/2 */
+  { 0x0d, 0x09, 0x01, 0x08 },	/* 1000: 13/ 9/1 */
+  { 0x0d, 0x0a, 0x01, 0x09 },	/* 1001: 13/10/1 */
+  { 0x0b, 0x08, 0x01, 0x0a },	/* 1010: 11/ 8/1 */
+  { 0x0c, 0x08, 0x01, 0x0b },	/* 1011: 12/ 8/1 */
+  { 0x0c, 0x09, 0x01, 0x0c },	/* 1100: 12/ 9/1 */
+  { 0x0e, 0x09, 0x02, 0x0d },	/* 1101: 14/ 9/2 */
+  { 0x0e, 0x0a, 0x02, 0x0e },	/* 1110: 14/10/2 */
+  { 0x0e, 0x0b, 0x02, 0x0f } 	/* 1111: 14/11/2 */
+};
+
+unsigned long cpc710_ram_init (void)
+{
+  unsigned long 	memsize = 0;
+  unsigned long		bank_size;
+  u32			mcer;
+
+#ifndef CFG_RAMBOOT
+    /* Clear memory banks
+     */
+  out32(REG(SDRAM0, MCER0), 0);
+  out32(REG(SDRAM0, MCER1), 0);
+  out32(REG(SDRAM0, MCER2), 0);
+  out32(REG(SDRAM0, MCER3), 0);
+  out32(REG(SDRAM0, MCER4), 0);
+  out32(REG(SDRAM0, MCER5), 0);
+  out32(REG(SDRAM0, MCER6), 0);
+  out32(REG(SDRAM0, MCER7), 0);
+  iobarrier_rw();
+
+    /* Disable memory
+     */
+  out32(REG(SDRAM0,MCCR), 0x13b06000);
+  iobarrier_rw();
+#endif
+
+    /* Only the first memory bank is initialised now
+     */
+  if (! cpc710_compute_mcer(& mcer, & bank_size, 0))
+  {
+    puts("Unsupported SDRAM type !\n");
+    hang();
+  }
+  memsize += bank_size;
+#ifndef CFG_RAMBOOT
+    /* Enable bank, zero start
+     */
+  out32(REG(SDRAM0, MCER0), mcer | 0x80000000);
+  iobarrier_rw();
+#endif
+
+#ifndef CFG_RAMBOOT
+    /* Enable memory
+     */
+  out32(REG(SDRAM0, MCCR), in32(REG(SDRAM0, MCCR)) | 0x80000000);
+
+    /* Wait until initialisation finished
+     */
+  while (! (in32 (REG(SDRAM0, MCCR)) & 0x20000000))
+  {
+    iobarrier_rw();
+  }
+
+    /* Clear Memory Error Status and Address registers
+     */
+  out32(REG(SDRAM0, MESR), 0);
+  out32(REG(SDRAM0, MEAR), 0);
+  iobarrier_rw();
+
+    /* ECC is not configured now
+     */
+#endif
+
+    /* Memory size counter
+     */
+  out32(REG(CPC0, RGBAN1), memsize);
+
+  return memsize;
+}
+
+static int cpc710_compute_mcer (
+  u32 *			mcer,
+  unsigned long	*	size,
+  unsigned int		sdram)
+{
+  u8			rows;
+  u8			cols;
+  u8			banks2;
+  unsigned int		lines;
+  u32			mc = 0;
+  unsigned int		i;
+  cpc710_mem_org_t *	org = 0;
+
+
+  if (! i2c_reset())
+  {
+    puts("Can't reset I2C!\n");
+    hang();
+  }
+
+  if (! cpc710_eeprom_checksum(sdram))
+  {
+    puts("Invalid EEPROM checksum !\n");
+    hang();
+  }
+
+  rows   = cpc710_eeprom_read(sdram, 3);
+  cols   = cpc710_eeprom_read(sdram, 4);
+    /* Can be 2 or 4 banks; divide by 2
+     */
+  banks2 = cpc710_eeprom_read(sdram, 17) / 2;
+
+  lines = rows + cols + banks2;
+
+  if (lines < 18 || lines > 26)
+  {
+      /* Unsupported configuration
+       */
+    return 0;
+  }
+
+
+  mc |= cpc710_mcer_mem [lines - 18] << 6;
+
+  for (i = 0; i < sizeof(cpc710_mem_org) / sizeof(cpc710_mem_org_t); i++)
+  {
+    cpc710_mem_org_t *	corg = cpc710_mem_org + i;
+
+    if (corg->rows == rows && corg->cols == cols && corg->banks2 == banks2)
+    {
+      org = corg;
+
+      break;
+    }
+  }
+
+  if (! org)
+  {
+      /* Unsupported configuration
+       */
+    return 0;
+  }
+
+  mc |= (u32) org->org << 2;
+
+    /* Supported configuration
+     */
+  *mcer = mc;
+  *size = 1l << (lines + 4);
+
+  return 1;
+}
+
+static int cpc710_eeprom_checksum (
+  unsigned int		sdram)
+{
+  u8			sum = 0;
+  unsigned int		i;
+
+  for (i = 0; i < 63; i++)
+  {
+    sum += cpc710_eeprom_read(sdram, i);
+  }
+
+  return sum == cpc710_eeprom_read(sdram, 63);
+}
+
+static u8 cpc710_eeprom_read (
+  unsigned int		sdram,
+  unsigned int		offset)
+{
+  u8			dev = (sdram << 1) | 0xa0;
+  u8			data;
+
+  if (! i2c_read_byte(& data, dev,offset))
+  {
+    puts("I2C error !\n");
+    hang();
+  }
+
+  return data;
+}
diff --git a/board/pcippc2/cpc710_pci.c b/board/pcippc2/cpc710_pci.c
new file mode 100644
index 0000000..9975cda
--- /dev/null
+++ b/board/pcippc2/cpc710_pci.c
@@ -0,0 +1,309 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#include "hardware.h"
+#include "pcippc2.h"
+
+struct pci_controller local_hose, cpci_hose;
+
+static u32	cpc710_mapped_ram;
+
+  /* Enable PCI retry timeouts
+   */
+void cpc710_pci_enable_timeout (void)
+{
+  out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), 0x32000000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
+  iobarrier_rw();
+}
+
+void cpc710_pci_init (void)
+{
+  u32			sdram_size = pcippc2_sdram_size();
+
+  cpc710_mapped_ram = sdram_size < PCI_MEMORY_MAXSIZE ?
+                      sdram_size : PCI_MEMORY_MAXSIZE;
+
+    /* Select the local PCI
+     */
+  out32(REG(CPC0, PCICNFR), 0x80000002);
+  iobarrier_rw();
+
+  out32(REG(CPC0, PCIBAR), BRIDGE_LOCAL_PHYS);
+  iobarrier_rw();
+
+    /* Enable PCI bridge address decoding
+     */
+  out32(REG(CPC0, PCIENB), 0x80000000);
+  iobarrier_rw();
+
+    /* Select the CPCI bridge
+     */
+  out32(REG(CPC0, PCICNFR), 0x80000003);
+  iobarrier_rw();
+
+  out32(REG(CPC0, PCIBAR), BRIDGE_CPCI_PHYS);
+  iobarrier_rw();
+
+    /* Enable PCI bridge address decoding
+     */
+  out32(REG(CPC0, PCIENB), 0x80000000);
+  iobarrier_rw();
+
+    /* Disable configuration accesses
+     */
+  out32(REG(CPC0, PCICNFR), 0x80000000);
+  iobarrier_rw();
+
+    /* Initialise the local PCI
+     */
+  out32(BRIDGE(LOCAL, CRR), 0x7c000000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PCIDG), 0x40000000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PIBAR), BRIDGE_LOCAL_IO_BUS);
+  out32(BRIDGE(LOCAL, SIBAR), BRIDGE_LOCAL_IO_PHYS);
+  out32(BRIDGE(LOCAL, IOSIZE), -BRIDGE_LOCAL_IO_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PMBAR), BRIDGE_LOCAL_MEM_BUS);
+  out32(BRIDGE(LOCAL, SMBAR), BRIDGE_LOCAL_MEM_PHYS);
+  out32(BRIDGE(LOCAL, MSIZE), -BRIDGE_LOCAL_MEM_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PR), 0x00ffe000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, ACR), 0xfe000000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PSBAR), PCI_MEMORY_BUS >> 24);
+  out32(BRIDGE(LOCAL, BARPS), PCI_MEMORY_PHYS >> 24);
+  out32(BRIDGE(LOCAL, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
+  iobarrier_rw();
+
+    /* Initialise the CPCI bridge
+     */
+  out32(BRIDGE(CPCI, CRR), 0x7c000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PCIDG), 0xC0000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PIBAR), BRIDGE_CPCI_IO_BUS);
+  out32(BRIDGE(CPCI, SIBAR), BRIDGE_CPCI_IO_PHYS);
+  out32(BRIDGE(CPCI, IOSIZE), -BRIDGE_CPCI_IO_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PMBAR), BRIDGE_CPCI_MEM_BUS);
+  out32(BRIDGE(CPCI, SMBAR), BRIDGE_CPCI_MEM_PHYS);
+  out32(BRIDGE(CPCI, MSIZE), -BRIDGE_CPCI_MEM_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PR), 0x80ffe000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, ACR), 0xdf000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PSBAR), PCI_MEMORY_BUS >> 24);
+  out32(BRIDGE(CPCI, BARPS), PCI_MEMORY_PHYS >> 24);
+  out32(BRIDGE(CPCI, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
+  iobarrier_rw();
+
+    /* Local PCI
+     */
+
+  out32(BRIDGE(LOCAL, CFGADDR), 0x04000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), 0x56010000);
+  iobarrier_rw();
+
+  out32(BRIDGE(LOCAL, CFGADDR), 0x0c000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
+  iobarrier_rw();
+
+    /* Set bus and subbus numbers
+     */
+  out32(BRIDGE(LOCAL, CFGADDR), 0x40000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
+  iobarrier_rw();
+
+  out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
+  iobarrier_rw();
+    /* PCI retry timeouts will be enabled later
+     */
+  out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
+  iobarrier_rw();
+
+    /* CPCI
+     */
+
+    /* Set bus and subbus numbers
+     */
+  out32(BRIDGE(CPCI, CFGADDR), 0x40000080);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x01010000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x04000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x56010000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x0c000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
+  iobarrier_rw();
+
+    /* Write to the PSBAR */
+  out32(BRIDGE(CPCI, CFGADDR), 0x10000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), cpu_to_le32(PCI_MEMORY_BUS));
+  iobarrier_rw();
+
+    /* Set bus and subbus numbers
+     */
+  out32(BRIDGE(CPCI, CFGADDR), 0x40000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x01ff0000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
+    /* PCI retry timeouts will be enabled later
+     */
+  out32(BRIDGE(CPCI, CFGDATA), 0x00000000);
+  iobarrier_rw();
+
+    /* Remove reset on the PCI buses
+     */
+  out32(BRIDGE(LOCAL, CRR), 0xfc000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CRR), 0xfc000000);
+  iobarrier_rw();
+
+  local_hose.first_busno = 0;
+  local_hose.last_busno = 0xff;
+
+  /* System memory space */
+  pci_set_region(local_hose.regions + 0,
+		 PCI_MEMORY_BUS,
+		 PCI_MEMORY_PHYS,
+		 PCI_MEMORY_MAXSIZE,
+		 PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+  /* PCI memory space */
+  pci_set_region(local_hose.regions + 1,
+		 BRIDGE_LOCAL_MEM_BUS,
+		 BRIDGE_LOCAL_MEM_PHYS,
+		 BRIDGE_LOCAL_MEM_SIZE,
+		 PCI_REGION_MEM);
+
+  /* PCI I/O space */
+  pci_set_region(local_hose.regions + 2,
+		 BRIDGE_LOCAL_IO_BUS,
+		 BRIDGE_LOCAL_IO_PHYS,
+		 BRIDGE_LOCAL_IO_SIZE,
+		 PCI_REGION_IO);
+
+  local_hose.region_count = 3;
+
+  pci_setup_indirect(&local_hose,
+		     BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGADDR,
+		     BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGDATA);
+
+  pci_register_hose(&local_hose);
+
+  /* Initialize PCI32 bus registers */
+  pci_hose_write_config_byte(&local_hose,
+			  PCI_BDF(local_hose.first_busno,0,0),
+			  CPC710_BUS_NUMBER,
+			  local_hose.first_busno);
+  pci_hose_write_config_byte(&local_hose,
+			  PCI_BDF(local_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  local_hose.last_busno);
+
+  local_hose.last_busno = pci_hose_scan(&local_hose);
+
+  /* Write out correct max subordinate bus number for local hose */
+  pci_hose_write_config_byte(&local_hose,
+			  PCI_BDF(local_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  local_hose.last_busno);
+
+  cpci_hose.first_busno = local_hose.last_busno + 1;
+  cpci_hose.last_busno = 0xff;
+
+  /* System memory space */
+  pci_set_region(cpci_hose.regions + 0,
+		 PCI_MEMORY_BUS,
+		 PCI_MEMORY_PHYS,
+		 PCI_MEMORY_MAXSIZE,
+		 PCI_REGION_MEMORY);
+
+  /* PCI memory space */
+  pci_set_region(cpci_hose.regions + 1,
+		 BRIDGE_CPCI_MEM_BUS,
+		 BRIDGE_CPCI_MEM_PHYS,
+		 BRIDGE_CPCI_MEM_SIZE,
+		 PCI_REGION_MEM);
+
+  /* PCI I/O space */
+  pci_set_region(cpci_hose.regions + 2,
+		 BRIDGE_CPCI_IO_BUS,
+		 BRIDGE_CPCI_IO_PHYS,
+		 BRIDGE_CPCI_IO_SIZE,
+		 PCI_REGION_IO);
+
+  cpci_hose.region_count = 3;
+
+  pci_setup_indirect(&cpci_hose,
+		     BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGADDR,
+		     BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGDATA);
+
+  pci_register_hose(&cpci_hose);
+
+  /* Initialize PCI64 bus registers */
+  pci_hose_write_config_byte(&cpci_hose,
+			  PCI_BDF(cpci_hose.first_busno,0,0),
+			  CPC710_BUS_NUMBER,
+			  cpci_hose.first_busno);
+  pci_hose_write_config_byte(&cpci_hose,
+			  PCI_BDF(cpci_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  cpci_hose.last_busno);
+
+  cpci_hose.last_busno = pci_hose_scan(&cpci_hose);
+
+  /* Write out correct max subordinate bus number for cpci hose */
+  pci_hose_write_config_byte(&cpci_hose,
+			  PCI_BDF(cpci_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  cpci_hose.last_busno);
+}
diff --git a/board/pcippc2/i2c.c b/board/pcippc2/i2c.c
new file mode 100644
index 0000000..36b1d0f
--- /dev/null
+++ b/board/pcippc2/i2c.c
@@ -0,0 +1,257 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <asm/io.h>
+
+#include "hardware.h"
+#include "i2c.h"
+
+static void		i2c_start	(void);
+static void		i2c_stop	(void);
+static int		i2c_write	(u8		data);
+static void		i2c_read	(u8 *		data);
+
+static inline void	i2c_port_start  (void);
+static inline void	i2c_clock	(unsigned int	val);
+static inline void	i2c_data	(unsigned int	val);
+static inline unsigned int
+			i2c_in		(void);
+static inline void	i2c_write_bit	(unsigned int	val);
+static inline unsigned int
+			i2c_read_bit	(void);
+
+static inline void	i2c_udelay	(unsigned int	time);
+
+int i2c_read_byte (
+  u8 *			data,
+  u8			dev,
+  u8			offset)
+{
+  int			err = 0;
+
+  i2c_start();
+
+  err = ! i2c_write(dev);
+
+  if (! err)
+  {
+    err = ! i2c_write(offset);
+  }
+
+  if (! err)
+  {
+    i2c_start();
+  }
+
+  if (! err)
+  {
+    err = ! i2c_write(dev | 0x01);
+  }
+
+  if (! err)
+  {
+    i2c_read(data);
+  }
+
+  i2c_stop();
+
+  return ! err;
+}
+
+static inline void i2c_udelay (
+  unsigned int		time)
+{
+  int			v;
+
+  asm volatile("mtdec %0" : : "r" (time * ((CFG_BUS_CLK / 4) / 1000000)));
+
+  do
+  {
+    asm volatile("isync; mfdec %0" : "=r" (v));
+  } while (v >= 0);
+}
+
+  /* Low-level hardware access
+   */
+
+#define BIT_GPDATA		0x80000000
+#define BIT_GPCLK		0x40000000
+
+static inline void i2c_port_start (void)
+{
+  out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~(BIT_GPCLK | BIT_GPDATA));
+  out32(REG(CPC0, GPOUT), in32(REG(CPC0, GPOUT)) & ~(BIT_GPCLK | BIT_GPDATA));
+  iobarrier_rw();
+
+  i2c_udelay(1);
+}
+
+static inline void i2c_clock (
+  unsigned int		val)
+{
+  if (val)
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPCLK);
+  }
+  else
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPCLK);
+  }
+
+  iobarrier_rw();
+
+  i2c_udelay(1);
+}
+
+static inline void i2c_data (
+  unsigned int		val)
+{
+  if (val)
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPDATA);
+  }
+  else
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPDATA);
+  }
+
+  iobarrier_rw();
+
+  i2c_udelay(1);
+}
+
+static inline unsigned int i2c_in (void)
+{
+  unsigned int		val = ((in32(REG(CPC0, GPIN)) & BIT_GPDATA) != 0)?1:0;
+
+  iobarrier_rw();
+
+  return val;
+}
+
+
+  /* Protocol implementation
+   */
+
+static inline void i2c_write_bit (
+  unsigned int		val)
+{
+  i2c_data(val);
+  i2c_udelay(10);
+  i2c_clock(1);
+  i2c_udelay(10);
+  i2c_clock(0);
+  i2c_udelay(10);
+}
+
+static inline unsigned int i2c_read_bit (void)
+{
+  unsigned int		val;
+
+  i2c_data(1);
+  i2c_udelay(10);
+
+  i2c_clock(1);
+  i2c_udelay(10);
+
+  val = i2c_in();
+
+  i2c_clock(0);
+  i2c_udelay(10);
+
+  return val;
+}
+
+unsigned int i2c_reset (void)
+{
+  unsigned int		val;
+  int i;
+
+  i2c_port_start();
+
+  i=0;
+  do {
+    i2c_udelay(10);
+    i2c_clock(0);
+    i2c_udelay(10);
+    i2c_clock(1);
+    i2c_udelay(10);
+    val = i2c_in();
+    i++;
+  }  while ((i<9)&&(val==0));
+  return (val);
+}
+
+
+static void i2c_start (void)
+{
+  i2c_data(1);
+  i2c_clock(1);
+  i2c_udelay(10);
+  i2c_data(0);
+  i2c_udelay(10);
+  i2c_clock(0);
+  i2c_udelay(10);
+}
+
+static void i2c_stop (void)
+{
+  i2c_data(0);
+  i2c_udelay(10);
+  i2c_clock(1);
+  i2c_udelay(10);
+  i2c_data(1);
+  i2c_udelay(10);
+}
+
+static int i2c_write (
+  u8			data)
+{
+  unsigned int		i;
+
+  for (i = 0; i < 8; i++)
+  {
+    i2c_write_bit(data >> 7);
+    data <<= 1;
+  }
+
+  return i2c_read_bit() == 0;
+}
+
+static void i2c_read (
+  u8 *			data)
+{
+  unsigned int		i;
+  u8			val = 0;
+
+  for (i = 0; i < 8; i++)
+  {
+    val <<= 1;
+    val |= i2c_read_bit();
+  }
+
+  *data = val;
+  i2c_write_bit(1); /* NoAck */
+}
diff --git a/board/pcippc2/pcippc2.c b/board/pcippc2/pcippc2.c
new file mode 100644
index 0000000..e1b065b
--- /dev/null
+++ b/board/pcippc2/pcippc2.c
@@ -0,0 +1,214 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+#include <linux/mtd/doc2000.h>
+#include <watchdog.h>
+#include <pci.h>
+
+#include "hardware.h"
+#include "pcippc2.h"
+#include "sconsole.h"
+#include "fpga_serial.h"
+
+#if defined(CONFIG_WATCHDOG)
+
+static int pcippc2_wdt_init_done = 0;
+
+void pcippc2_wdt_init (void);
+
+#endif
+
+  /* Check board identity
+   */
+int checkboard (void)
+{
+#ifdef CONFIG_PCIPPC2
+	puts ("Board: Gespac PCIPPC-2\n");
+#else
+	puts ("Board: Gespac PCIPPC-6\n");
+#endif
+	return 0;
+}
+
+  /* RAM size is stored in CPC0_RGBAN1
+   */
+u32 pcippc2_sdram_size (void)
+{
+	return in32 (REG (CPC0, RGBAN1));
+}
+
+long initdram (int board_type)
+{
+	return cpc710_ram_init ();
+}
+
+void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+	out32 (REG (CPC0, SPOR), 0);
+	iobarrier_rw ();
+	while (1);
+}
+
+int board_pre_init (void)
+{
+	out32 (REG (CPC0, RSTR), 0xC0000000);
+	iobarrier_rw ();
+
+	out32 (REG (CPC0, RSTR), 0xF0000000);
+	iobarrier_rw ();
+
+	out32 (REG (CPC0, UCTL), 0x00F80000);
+
+	out32 (REG (CPC0, SIOC0), 0x30000000);
+
+	out32 (REG (CPC0, ABCNTL), 0x00000000);
+
+	out32 (REG (CPC0, SESR), 0x00000000);
+	out32 (REG (CPC0, SEAR), 0x00000000);
+
+	/* Detect IBM Avignon CPC710 Revision */
+	if ((in32 (REG (CPC0, UCTL)) & 0x000000F0) == CPC710_TYPE_100P)
+		out32 (REG (CPC0, PGCHP), 0xA0000040);
+	else
+		out32 (REG (CPC0, PGCHP), 0x80800040);
+
+
+	out32 (REG (CPC0, ATAS), 0x709C2508);
+
+	iobarrier_rw ();
+
+	return 0;
+}
+
+void after_reloc (ulong dest_addr)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* Jump to the main U-Boot board init code
+	 */
+	board_init_r (gd, dest_addr);
+}
+
+int misc_init_r (void)
+{
+	pcippc2_fpga_init ();
+
+#if defined(CONFIG_WATCHDOG)
+	pcippc2_wdt_init ();
+#endif
+
+	fpga_serial_init (sconsole_get_baudrate ());
+
+	sconsole_putc   = fpga_serial_putc;
+	sconsole_puts   = fpga_serial_puts;
+	sconsole_getc   = fpga_serial_getc;
+	sconsole_tstc   = fpga_serial_tstc;
+	sconsole_setbrg = fpga_serial_setbrg;
+
+	sconsole_flush ();
+	return (0);
+}
+
+void pci_init (void)
+{
+	cpc710_pci_init ();
+
+	/* FPGA requires no retry timeouts to be enabled
+	 */
+	cpc710_pci_enable_timeout ();
+}
+
+void doc_init (void)
+{
+	doc_probe (pcippc2_fpga1_phys + HW_FPGA1_DOC);
+}
+
+#if defined(CONFIG_WATCHDOG)
+
+void pcippc2_wdt_init (void)
+{
+	out16r (FPGA (WDT, PROG), 0xffff);
+	out8 (FPGA (WDT, CTRL), 0x1);
+
+	pcippc2_wdt_init_done = 1;
+}
+
+void pcippc2_wdt_done (void)
+{
+	out8 (FPGA (WDT, CTRL), 0x0);
+
+	pcippc2_wdt_init_done = 0;
+}
+
+void pcippc2_wdt_reset (void)
+{
+	if (pcippc2_wdt_init_done == 1)
+		out8 (FPGA (WDT, REFRESH), 0x56);
+}
+
+void watchdog_reset (void)
+{
+	int re_enable = disable_interrupts ();
+
+	pcippc2_wdt_reset ();
+	if (re_enable)
+		enable_interrupts ();
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+int do_wd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+	switch (argc) {
+	case 1:
+		printf ("Watchdog timer status is %s\n",
+			pcippc2_wdt_init_done == 1 ? "on" : "off");
+
+		return 0;
+	case 2:
+		if (!strcmp(argv[1],"on")) {
+			pcippc2_wdt_init();
+			printf("Watchdog timer now is on\n");
+
+			return 0;
+
+		} else if (!strcmp(argv[1],"off")) {
+			pcippc2_wdt_done();
+			printf("Watchdog timer now is off\n");
+
+			return 0;
+
+		} else
+			break;
+	default:
+		break;
+	}
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+}
+
+#endif	/* CFG_CMD_BSP */
+#endif	/* CONFIG_WATCHDOG */
diff --git a/board/pn62/cmd_pn62.c b/board/pn62/cmd_pn62.c
new file mode 100644
index 0000000..928f6c0
--- /dev/null
+++ b/board/pn62/cmd_pn62.c
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <cmd_autoscript.h>
+#include <cmd_bsp.h>
+
+#include "pn62.h"
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+/*
+ * Command led: controls the various LEDs 0..11 on the PN62 card.
+ */
+int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    unsigned int number, function;
+
+    if (argc != 3) {
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    }
+    number = simple_strtoul(argv[1], NULL, 10);
+    if (number > PN62_LED_MAX)
+	return 1;
+    function = simple_strtoul(argv[2], NULL, 16);
+    set_led (number, function);
+    return 0;
+}
+
+/*
+ * Command loadpci: loads a image over PCI.
+ */
+#define CMD_MOVE_WINDOW 0x1
+#define CMD_BOOT_IMAGE  0x2
+
+int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    char *s;
+    ulong addr = 0, count = 0;
+    u32 off;
+    int cmd, rcode = 0;
+
+    /* pre-set load_addr */
+    if ((s = getenv("loadaddr")) != NULL) {
+	addr = simple_strtoul(s, NULL, 16);
+    }
+
+    switch (argc) {
+    case 1:
+	break;
+    case 2:
+	addr = simple_strtoul(argv[1], NULL, 16);
+	break;
+    default:
+       printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    }
+
+    printf ("## Ready for image download ...\n");
+
+    show_startup_phase(12);
+
+    while (1) {
+	/* Alive indicator */
+	i2155x_write_scrapad(BOOT_PROTO, BOOT_PROTO_READY);
+
+	/* Toggle status LEDs */
+	cmd = (count / 200) % 4; /* downscale */
+	set_led(4, cmd == 0 ? LED_1 : LED_0);
+	set_led(5, cmd == 1 ? LED_1 : LED_0);
+	set_led(6, cmd == 2 ? LED_1 : LED_0);
+	set_led(7, cmd == 3 ? LED_1 : LED_0);
+	udelay(1000);
+	count++;
+
+	cmd = i2155x_read_scrapad(BOOT_CMD);
+
+	if (cmd == BOOT_CMD_MOVE) {
+	    off = i2155x_read_scrapad(BOOT_DATA);
+	    off += addr;
+	    i2155x_set_bar_base(3, off);
+	    printf ("## BAR3 Addr moved = 0x%08x\n", off);
+	    i2155x_write_scrapad(BOOT_CMD, ~cmd);
+	    show_startup_phase(13);
+	}
+	else if (cmd == BOOT_CMD_BOOT) {
+	    set_led(4, LED_1);
+	    set_led(5, LED_1);
+	    set_led(6, LED_1);
+	    set_led(7, LED_1);
+
+	    i2155x_write_scrapad(BOOT_CMD, ~cmd);
+	    show_startup_phase(14);
+	    break;
+	}
+
+	/* Abort if ctrl-c was pressed */
+	if (ctrlc()) {
+	    printf("\nAbort\n");
+	    return 0;
+	}
+
+    }
+
+    /* Repoint to the default shared memory */
+    i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+    load_addr = addr;
+    printf ("## Start Addr      = 0x%08lx\n", addr);
+
+    show_startup_phase(15);
+
+    /* Loading ok, check if we should attempt an auto-start */
+    if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
+	char *local_args[2];
+	local_args[0] = argv[0];
+	local_args[1] = NULL;
+
+	printf ("Automatic boot of image at addr 0x%08lX ...\n",
+		load_addr);
+	rcode = do_bootm (cmdtp, 0, 1, local_args);
+    }
+
+#ifdef CONFIG_AUTOSCRIPT
+    if (load_addr) {
+	char *s;
+
+	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
+	    printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
+	    rcode = autoscript (bd, load_addr);
+	}
+    }
+#endif
+    return rcode;
+}
+
+#endif
diff --git a/board/pn62/misc.c b/board/pn62/misc.c
new file mode 100644
index 0000000..4f71950
--- /dev/null
+++ b/board/pn62/misc.c
@@ -0,0 +1,235 @@
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@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 <mpc824x.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#include "pn62.h"
+
+typedef struct {
+    pci_dev_t    devno;
+    volatile u32 *csr;
+
+} i2155x_t;
+
+static i2155x_t i2155x = { 0, NULL };
+
+static struct pci_device_id i2155x_ids[] = {
+    { 0x1011, 0x0046 },		/* i21554 */
+    { 0x8086, 0xb555 }		/* i21555 */
+};
+
+int i2155x_init(void)
+{
+    pci_dev_t devno;
+    u32 val;
+    int i;
+
+    /*
+     * Find the Intel bridge.
+     */
+    if ((devno = pci_find_devices(i2155x_ids, 0)) < 0) {
+	printf("Error: Intel bridge 2155x not found!\n");
+	return -1;
+    }
+    i2155x.devno = devno;
+
+    /*
+     * Get auto-configured base address for CSR access.
+     */
+    pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &val);
+    if (val & PCI_BASE_ADDRESS_SPACE_IO) {
+	val &= PCI_BASE_ADDRESS_IO_MASK;
+	i2155x.csr = (volatile u32 *)(_IO_BASE + val);
+    } else {
+	val &= PCI_BASE_ADDRESS_MEM_MASK;
+	i2155x.csr =  (volatile u32 *)val;
+    }
+
+    /*
+     * Translate downstream memory 2 (bar3) to base of shared memory.
+     */
+    i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+    /*
+     * Enable memory space, I/O space and bus master bits
+     * in both Primary and Secondary command registers.
+     */
+    val = PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+    pci_write_config_word(devno, 0x44, val);
+    pci_write_config_word(devno, 0x04, val);
+
+    /*
+     * Clear scratchpad registers.
+     */
+    for (i = 0; i < (I2155X_SCRAPAD_MAX - 1); i++) {
+	i2155x_write_scrapad(i, 0x0);
+    }
+
+    /*
+     * Set interrupt line for Linux.
+     */
+    pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 3);
+
+    return 0;
+}
+
+/*
+ * Access the Scratchpad registers 0..7 of the Intel bridge.
+ */
+void i2155x_write_scrapad(int idx, u32 val)
+{
+    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+	out_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx, val);
+    else
+	printf("i2155x_write_scrapad: invalid index\n");
+}
+
+u32 i2155x_read_scrapad(int idx)
+{
+    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+	return in_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx);
+    else
+	printf("i2155x_read_scrapad: invalid index\n");
+    return -1;
+}
+
+void i2155x_set_bar_base(int bar, u32 base)
+{
+    if (bar >= 2 && bar <= 4) {
+	pci_write_config_dword(i2155x.devno,
+			       I2155X_BAR2_BASE + (bar - 2) * 4,
+			       base);
+    }
+}
+
+/*
+ * Read Vital Product Data (VPD) from the Serial EPROM attached
+ * to the Intel bridge.
+ */
+int i2155x_read_vpd(int offset, int size, unsigned char *data)
+{
+    int i, n;
+    u16 val16;
+
+    for (i = 0; i < size; i++) {
+	pci_write_config_word(i2155x.devno, I2155X_VPD_ADDR,
+			      offset + i - I2155X_VPD_START);
+	for (n = 10000; n > 0; n--) {
+	    pci_read_config_word(i2155x.devno, I2155X_VPD_ADDR, &val16);
+	    if ((val16 & 0x8000) != 0) /* wait for completion */
+		break;
+	    udelay(100);
+	}
+	if (n == 0) {
+	    printf("i2155x_read_vpd: TIMEOUT\n");
+	    return -1;
+	}
+
+	pci_read_config_byte(i2155x.devno, I2155X_VPD_DATA, &data[i]);
+    }
+
+    return i;
+}
+
+static struct pci_device_id am79c95x_ids [] = {
+        { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+        { }
+};
+
+
+/*
+ * Initialize the AMD ethernet controllers.
+ */
+int am79c95x_init(void)
+{
+    pci_dev_t devno;
+    int i;
+
+    /*
+     * Set interrupt line for Linux.
+     */
+    for (i = 0; i < 2; i++) {
+	if ((devno = pci_find_devices(am79c95x_ids, i)) < 0)
+	    break;
+	pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 2+i);
+    }
+    if (i < 2)
+	printf("Error: Only %d AMD Ethernet Controller found!\n", i);
+
+    return 0;
+}
+
+
+void set_led(unsigned int number, unsigned int function)
+{
+    volatile u8 *addr;
+
+    if ((number >= 0) && (number < PN62_LED_MAX) &&
+	(function >= 0) && (function <= LED_LAST_FUNCTION)) {
+	addr = (volatile u8 *)(PN62_LED_BASE + number * 8);
+	out_8(addr, function&0xff);
+    }
+}
+
+/*
+ * Show fatal error indicated by Kinght Rider(tm) effect
+ * in LEDS 0-7. LEDS 8-11 contain 4 bit error code.
+ * Note: this function will not terminate.
+ */
+void fatal_error(unsigned int error_code)
+{
+    int i, d;
+
+    for (i = 0; i < 12; i++) {
+	set_led(i, LED_0);
+    }
+
+    /*
+     * Write error code.
+     */
+    set_led(8,  (error_code & 0x01) ? LED_1 : LED_0);
+    set_led(9,  (error_code & 0x02) ? LED_1 : LED_0);
+    set_led(10, (error_code & 0x04) ? LED_1 : LED_0);
+    set_led(11, (error_code & 0x08) ? LED_1 : LED_0);
+
+    /*
+     * Yay - Knight Rider effect!
+     */
+    while(1) {
+	unsigned int delay = 2000;
+
+	for (i = 0; i < 8; i++) {
+	    set_led(i, LED_1);
+	    for (d = 0; d < delay; d++);
+	    set_led(i, LED_0);
+	}
+
+	for (i = 7; i > 0; i--) {
+	    set_led(i, LED_1);
+	    for (d = 0; d < delay; d++);
+	    set_led(i, LED_0);
+	}
+    }
+}
diff --git a/board/pn62/pn62.c b/board/pn62/pn62.c
new file mode 100644
index 0000000..4d87527
--- /dev/null
+++ b/board/pn62/pn62.c
@@ -0,0 +1,216 @@
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@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 <mpc824x.h>
+#include <pci.h>
+
+#include "pn62.h"
+
+
+static int get_serial_number (char *string, int size);
+static int get_mac_address (int id, u8 * mac, char *string, int size);
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress (int phase)
+{
+	/*
+	 * Show phases of the bootm command on the front panel
+	 * LEDs and the scratchpad register #3 as well. We use
+	 * blinking LEDs for logical "1".
+	 */
+	if (phase > 0) {
+		set_led (8, (phase & 0x1) ? LED_SLOW_CLOCK : LED_0);
+		set_led (9, (phase & 0x2) ? LED_SLOW_CLOCK : LED_0);
+		set_led (10, (phase & 0x4) ? LED_SLOW_CLOCK : LED_0);
+		set_led (11, (phase & 0x8) ? LED_SLOW_CLOCK : LED_0);
+	}
+	i2155x_write_scrapad (BOOT_STATUS, phase);
+	if (phase < 0)
+		i2155x_write_scrapad (BOOT_DONE, BOOT_DONE_ERROR);
+}
+#endif
+
+void show_startup_phase (int phase)
+{
+	/*
+	 * Show the phase of U-Boot startup on the front panel
+	 * LEDs and the scratchpad register #3 as well.
+	 */
+	if (phase > 0) {
+		set_led (8, (phase & 0x1) ? LED_1 : LED_0);
+		set_led (9, (phase & 0x2) ? LED_1 : LED_0);
+		set_led (10, (phase & 0x4) ? LED_1 : LED_0);
+		set_led (11, (phase & 0x8) ? LED_1 : LED_0);
+	}
+	i2155x_write_scrapad (BOOT_STATUS, phase);
+	if (phase < 0)
+		i2155x_write_scrapad (BOOT_DONE, BOOT_DONE_ERROR);
+}
+
+int checkboard (void)
+{
+	show_startup_phase (1);
+	puts ("Board: PN62\n");
+	return 0;
+}
+
+long int initdram (int board_type)
+{
+	int i, cnt;
+	volatile uchar *base = CFG_SDRAM_BASE;
+	volatile ulong *addr;
+	ulong save[32];
+	ulong val, ret = 0;
+
+	show_startup_phase (2);
+
+	for (i = 0, cnt = (CFG_MAX_RAM_SIZE / sizeof (long)) >> 1; cnt > 0;
+		 cnt >>= 1) {
+		addr = (volatile ulong *) base + cnt;
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	addr = (volatile ulong *) base;
+	save[i] = *addr;
+	*addr = 0;
+
+	if (*addr != 0) {
+		*addr = save[i];
+		goto Done;
+	}
+
+	for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof (long); cnt <<= 1) {
+		addr = (volatile ulong *) base + cnt;
+		val = *addr;
+		*addr = save[--i];
+		if (val != ~cnt) {
+			ulong new_bank0_end = cnt * sizeof (long) - 1;
+			ulong mear1 = mpc824x_mpc107_getreg (MEAR1);
+			ulong emear1 = mpc824x_mpc107_getreg (EMEAR1);
+
+			mear1 = (mear1 & 0xFFFFFF00) |
+					((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+			emear1 = (emear1 & 0xFFFFFF00) |
+					((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+			mpc824x_mpc107_setreg (MEAR1, mear1);
+			mpc824x_mpc107_setreg (EMEAR1, emear1);
+
+			ret = cnt * sizeof (long);
+			goto Done;
+		}
+	}
+
+	ret = CFG_MAX_RAM_SIZE;
+  Done:
+	show_startup_phase (3);
+	return ret;
+}
+
+/*
+ * Initialize PCI Devices. We rely on auto-configuration.
+ */
+#ifndef CONFIG_PCI_PNP
+#error "CONFIG_PCI_PNP is not defined, please correct!"
+#endif
+
+struct pci_controller hose = {
+};
+
+void pci_init (void)
+{
+	show_startup_phase (4);
+	pci_mpc824x_init (&hose);
+
+	show_startup_phase (5);
+	i2155x_init ();
+	show_startup_phase (6);
+	am79c95x_init ();
+	show_startup_phase (7);
+}
+
+int misc_init_r (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	char str[20];
+	u8 mac[6];
+
+	show_startup_phase (8);
+	/*
+	 * Get serial number and ethernet addresses if not already defined
+	 * and update the board info structure and the environment.
+	 */
+	if (getenv ("serial#") == NULL &&
+		get_serial_number (str, strlen (str)) > 0) {
+		setenv ("serial#", str);
+	}
+	show_startup_phase (9);
+
+	if (getenv ("ethaddr") == NULL &&
+		get_mac_address (0, mac, str, sizeof (str)) > 0) {
+		setenv ("ethaddr", str);
+		memcpy (gd->bd->bi_enetaddr, mac, 6);
+	}
+	show_startup_phase (10);
+
+	if (getenv ("eth1addr") == NULL &&
+		get_mac_address (1, mac, str, sizeof (str)) > 0) {
+		setenv ("eth1addr", str);
+		memcpy (gd->bd->bi_enet1addr, mac, 6);
+	}
+	show_startup_phase (11);
+
+	/* Tell everybody that U-Boot is up and runnig */
+	i2155x_write_scrapad (0, 0x12345678);
+	return (0);
+}
+
+static int get_serial_number (char *string, int size)
+{
+	int i;
+	char c;
+
+	if (size < I2155X_VPD_SN_SIZE)
+		size = I2155X_VPD_SN_SIZE;
+	for (i = 0; i < (size - 1); i++) {
+		i2155x_read_vpd (I2155X_VPD_SN_START + i, 1, &c);
+		if (c == '\0')
+			break;
+		string[i] = c;
+	}
+	string[i] = '\0';			/* make sure it's terminated */
+
+	return i;
+}
+
+static int get_mac_address (int id, u8 * mac, char *string, int size)
+{
+	if (size < 6 * 3)
+		return -1;
+
+	i2155x_read_vpd (I2155X_VPD_MAC0_START + 6 * id, 6, mac);
+	return sprintf (string, "%02x:%02x:%02x:%02x:%02x:%02x",
+				mac[0], mac[1], mac[2],
+				mac[3], mac[4], mac[5]);
+}
diff --git a/board/r360mpi/r360mpi.c b/board/r360mpi/r360mpi.c
new file mode 100644
index 0000000..d7b8873
--- /dev/null
+++ b/board/r360mpi/r360mpi.c
@@ -0,0 +1,423 @@
+/*
+ * (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 <config.h>
+#include <mpc8xx.h>
+#include <i2c.h>
+
+#include <commproc.h>
+#include <command.h>
+#include <cmd_bsp.h>
+#include <malloc.h>
+
+#include <linux/types.h>
+#include <linux/string.h>       /* for strdup */
+
+
+/*
+ *  Memory Controller Using
+ *
+ *  CS0 - Flash memory            (0x40000000)
+ *  CS1 - SDRAM                   (0x00000000}
+ *  CS2 -
+ *  CS3 -
+ *  CS4 -
+ *  CS5 -
+ *  CS6 - PCMCIA device
+ *  CS7 - PCMCIA device
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#define _not_used_	0xffffffff
+
+const uint sdram_table[]=
+{
+        /* single read. (offset 0 in upm RAM) */
+        0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+        0x1ff77c47,
+
+        /* MRS initialization (offset 5) */
+
+        0x1ff77c34, 0xefeabc34, 0x1fb57c35,
+
+        /* burst read. (offset 8 in upm RAM) */
+        0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+        0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* single write. (offset 18 in upm RAM) */
+        0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* burst write. (offset 20 in upm RAM) */
+        0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+        0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* refresh. (offset 30 in upm RAM) */
+        0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+        0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* exception. (offset 3c in upm RAM) */
+        0x7ffffc07, _not_used_, _not_used_, _not_used_ };
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+	puts ("Board: R360 MPI Board\n");
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	long int size8, size9;
+	long int size_b0 = 0;
+	unsigned long reg;
+
+	upmconfig (UPMA, (uint *) sdram_table,
+			   sizeof (sdram_table) / sizeof (uint));
+
+	/*
+	 * Preliminary prescaler for refresh (depends on number of
+	 * banks): This value is selected for four cycles every 62.4 us
+	 * with two SDRAM banks or four cycles every 31.2 us with one
+	 * bank. It will be adjusted after memory sizing.
+	 */
+	memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
+
+	memctl->memc_mar = 0x00000088;
+
+	/*
+	 * Map controller bank 1 to the SDRAM bank at
+	 * preliminary address - these have to be modified after the
+	 * SDRAM size has been determined.
+	 */
+	memctl->memc_or1 = CFG_OR1_PRELIM;
+	memctl->memc_br1 = CFG_BR1_PRELIM;
+
+	memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE));	/* no refresh yet */
+
+	udelay (200);
+
+	/* perform SDRAM initializsation sequence */
+
+	memctl->memc_mcr = 0x80002105;	/* SDRAM bank 0 */
+	udelay (200);
+	memctl->memc_mcr = 0x80002230;	/* SDRAM bank 0 - execute twice */
+	udelay (200);
+
+	memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */
+
+	udelay (1000);
+
+	/*
+	 * Check Bank 0 Memory Size for re-configuration
+	 *
+	 * try 8 column mode
+	 */
+	size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE1_PRELIM,
+					   SDRAM_MAX_SIZE);
+
+	udelay (1000);
+
+	/*
+	 * try 9 column mode
+	 */
+	size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE1_PRELIM,
+					   SDRAM_MAX_SIZE);
+
+	if (size8 < size9) {		/* leave configuration at 9 columns */
+		size_b0 = size9;
+/*	debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);	*/
+	} else {					/* back to 8 columns            */
+		size_b0 = size8;
+		memctl->memc_mamr = CFG_MAMR_8COL;
+		udelay (500);
+/*	debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);	*/
+	}
+
+	udelay (1000);
+
+	/*
+	 * Adjust refresh rate depending on SDRAM type, both banks
+	 * For types > 128 MBit leave it at the current (fast) rate
+	 */
+	if ((size_b0 < 0x02000000)) {
+		/* reduce to 15.6 us (62.4 us / quad) */
+		memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
+		udelay (1000);
+	}
+
+	/*
+	 * Final mapping
+	 */
+
+	memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+	memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+	/* adjust refresh rate depending on SDRAM type, one bank */
+	reg = memctl->memc_mptpr;
+	reg >>= 1;		/* reduce to CFG_MPTPR_1BK_8K / _4K */
+	memctl->memc_mptpr = reg;
+
+	udelay (10000);
+
+	return (size_b0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base,
+						   long int maxsize)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	volatile long int *addr;
+	ulong cnt, val;
+	ulong save[32];			/* to make test non-destructive */
+	unsigned char i = 0;
+
+	memctl->memc_mamr = mamr_value;
+
+	for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+		addr = base + cnt;	/* pointer arith! */
+
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	/* write 0 to base address */
+	addr = base;
+	save[i] = *addr;
+	*addr = 0;
+
+	/* check at base address */
+	if ((val = *addr) != 0) {
+		*addr = save[i];
+		return (0);
+	}
+
+	for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+		addr = base + cnt;	/* pointer arith! */
+		val = *addr;
+		*addr = save[--i];
+
+		if (val != (~cnt)) {
+			return (cnt * sizeof (long));
+		}
+	}
+	return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void r360_pwm_write (uchar reg, uchar val)
+{
+	if (i2c_write (CFG_I2C_PWM_ADDR, reg, 1, &val, 1)) {
+		printf ("Can't write PWM register 0x%02X.\n", reg);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+
+/* Number of bytes returned from Keyboard Controller */
+#define KEYBD_KEY_MAX		20				/* maximum key number */
+#define KEYBD_DATALEN		((KEYBD_KEY_MAX + 7) / 8)	/* normal key scan data */
+
+static uchar kbd_addr = CFG_I2C_KBD_ADDR;
+
+static uchar *key_match (uchar *);
+
+int misc_init_r (void)
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	uchar keybd_env[2 * KEYBD_DATALEN + 1];
+	uchar *str;
+	int i;
+
+	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+	for (i = 0; i < KEYBD_DATALEN; ++i) {
+		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+	}
+	setenv ("keybd", keybd_env);
+
+	str = strdup (key_match (kbd_data));	/* decode keys */
+
+#ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */
+	setenv ("preboot", str);	/* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+	if (str != NULL) {
+		free (str);
+	}
+
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Check if pressed key(s) match magic sequence,
+ * and return the command string associated with that key(s).
+ *
+ * If no key press was decoded, NULL is returned.
+ *
+ * Note: the first character of the argument will be overwritten with
+ * the "magic charcter code" of the decoded key(s), or '\0'.
+ *
+ *
+ * Note: the string points to static environment data and must be
+ * saved before you call any function that modifies the environment.
+ */
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static uchar *key_match (uchar * kbd_data)
+{
+	uchar compare[KEYBD_DATALEN];
+	uchar magic[sizeof (kbd_magic_prefix) + 1];
+	uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+	uchar key_mask;
+	uchar *str, *nxt, *suffix;
+	uchar *kbd_magic_keys;
+	char *cmd;
+	int i;
+
+	/*
+	 * The following string defines the characters that can pe appended
+	 * to "key_magic" to form the names of environment variables that
+	 * hold "magic" key codes, i. e. such key codes that can cause
+	 * pre-boot actions. If the string is empty (""), then only
+	 * "key_magic" is checked (old behaviour); the string "125" causes
+	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+	 */
+	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+		kbd_magic_keys = "";
+
+	/* loop over all magic keys;
+	 * use '\0' suffix in case of empty string
+	 */
+	for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix) {
+		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+#if 0
+		printf ("### Check magic \"%s\"\n", magic);
+#endif
+
+		memcpy(compare, kbd_data, KEYBD_DATALEN);
+
+		for (str = getenv(magic); str != NULL; str = (*nxt) ? nxt+1 : nxt) {
+			uchar c;
+
+			c = (uchar) simple_strtoul (str, (char **) (&nxt), 16);
+
+			if (str == nxt)				/* invalid character */
+				break;
+
+			if (c >= KEYBD_KEY_MAX)			/* bad key number */
+				goto next_magic;
+
+			key_mask = 0x80 >> (c % 8);
+
+			if (!(compare[c / 8] & key_mask))	/* key not pressed */
+				goto next_magic;
+
+			compare[c / 8] &= ~key_mask;
+		}
+
+		for (i=0; i<KEYBD_DATALEN; i++)
+			if (compare[i])			/* key(s) not released */
+				goto next_magic;
+
+		sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+
+		cmd = getenv (cmd_name);
+#if 0
+		printf ("### Set PREBOOT to $(%s): \"%s\"\n",
+			cmd_name, cmd ? cmd : "<<NULL>>");
+#endif
+		*kbd_data = *suffix;
+		return (cmd);
+
+	next_magic:;
+	}
+#if 0
+	printf ("### Delete PREBOOT\n");
+#endif
+	*kbd_data = '\0';
+	return (NULL);
+}
+#endif							/* CONFIG_PREBOOT */
+
+/* Read Keyboard status */
+int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	uchar keybd_env[2 * KEYBD_DATALEN + 1];
+	int i;
+
+	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+	/* Read keys */
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+	puts ("Keys:");
+	for (i = 0; i < KEYBD_DATALEN; ++i) {
+		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+		printf (" %02x", kbd_data[i]);
+	}
+	putc ('\n');
+	setenv ("keybd", keybd_env);
+	return 0;
+}
diff --git a/board/sacsng/clkinit.c b/board/sacsng/clkinit.c
new file mode 100644
index 0000000..1e851e1
--- /dev/null
+++ b/board/sacsng/clkinit.c
@@ -0,0 +1,884 @@
+/*
+ * (C) Copyright 2002
+ * Custom IDEAS, Inc. <www.cideas.com>
+ * Jon Diekema <diekema@cideas.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
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc8260.h>
+#include <asm/cpm_8260.h>
+#include <configs/sacsng.h>
+
+#include "clkinit.h"
+
+int Daq64xSampling = 0;
+
+
+void Daq_BRG_Reset(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     volatile uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+     *brg_ptr |=  CPM_BRG_RST;
+     *brg_ptr &= ~CPM_BRG_RST;
+}
+
+void Daq_BRG_Disable(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     volatile uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+     *brg_ptr &= ~CPM_BRG_EN;
+}
+
+void Daq_BRG_Enable(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     volatile uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+     *brg_ptr |= CPM_BRG_EN;
+}
+
+uint Daq_BRG_Get_Div16(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     if (*brg_ptr & CPM_BRG_DIV16) {
+         /* DIV16 active */
+         return (TRUE);
+     }
+     else {
+         /* DIV16 inactive */
+         return (FALSE);
+     }
+}
+
+void Daq_BRG_Set_Div16(uint brg, uint div16)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     if (div16) {
+         /* DIV16 active */
+         *brg_ptr |=  CPM_BRG_DIV16;
+     }
+     else {
+         /* DIV16 inactive */
+         *brg_ptr &= ~CPM_BRG_DIV16;
+     }
+}
+
+uint Daq_BRG_Get_Count(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+     uint brg_cnt;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     /* Get the clock divider
+      *
+      * Note: A clock divider of 0 means divide by 1,
+      *       therefore we need to add 1 to the count.
+      */
+     brg_cnt = (*brg_ptr & CPM_BRG_CD_MASK) >> CPM_BRG_DIV16_SHIFT;
+     brg_cnt++;
+     if (*brg_ptr & CPM_BRG_DIV16) {
+         brg_cnt *= 16;
+     }
+
+    return (brg_cnt);
+}
+
+void Daq_BRG_Set_Count(uint brg, uint brg_cnt)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     /*
+      * Note: A clock divider of 0 means divide by 1,
+      *	 therefore we need to subtract 1 from the count.
+      */
+     if (brg_cnt > 4096) {
+         /* Prescale = Divide by 16 */
+         *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK)   |
+	     (((brg_cnt / 16) - 1) << CPM_BRG_DIV16_SHIFT);
+	 *brg_ptr |= CPM_BRG_DIV16;
+     }
+     else {
+         /* Prescale = Divide by 1 */
+         *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK) |
+	     ((brg_cnt - 1) << CPM_BRG_DIV16_SHIFT);
+	 *brg_ptr &= ~CPM_BRG_DIV16;
+     }
+}
+
+uint Daq_BRG_Get_ExtClk(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     return ((*brg_ptr & CPM_BRG_EXTC_MASK) >> CPM_BRG_EXTC_SHIFT);
+}
+
+char* Daq_BRG_Get_ExtClk_Description(uint brg)
+{
+     uint extc;
+
+     extc = Daq_BRG_Get_ExtClk(brg);
+
+     switch (brg + 1) {
+         case 1:
+         case 2:
+         case 5:
+         case 6: {
+             switch (extc) {
+                 case 0: {
+                     return ("BRG_INT");
+                 }
+                 case 1: {
+                     return ("CLK3");
+                 }
+                 case 2: {
+                     return ("CLK5");
+                 }
+             }
+             return ("??1245??");
+         }
+         case 3:
+         case 4:
+         case 7:
+         case 8: {
+             switch (extc) {
+                 case 0: {
+                     return ("BRG_INT");
+                 }
+                 case 1: {
+                     return ("CLK9");
+                 }
+                 case 2: {
+                     return ("CLK15");
+                 }
+             }
+             return ("??3478??");
+         }
+     }
+     return ("??9876??");
+}
+
+void Daq_BRG_Set_ExtClk(uint brg, uint extc)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     *brg_ptr = (*brg_ptr & ~CPM_BRG_EXTC_MASK) |
+                ((extc << CPM_BRG_EXTC_SHIFT) & CPM_BRG_EXTC_MASK);
+}
+
+uint Daq_BRG_Rate(uint brg)
+{
+     DECLARE_GLOBAL_DATA_PTR;
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+     uint brg_cnt;
+     uint brg_freq = 0;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     brg_ptr += brg;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg_ptr += (brg - 4);
+     }
+
+    brg_cnt = Daq_BRG_Get_Count(brg);
+
+    switch (Daq_BRG_Get_ExtClk(brg)) {
+        case CPM_BRG_EXTC_CLK3:
+        case CPM_BRG_EXTC_CLK5: {
+	    brg_freq = brg_cnt;
+	    break;
+	}
+	default: {
+	    brg_freq = (uint)BRG_INT_CLK / brg_cnt;
+	}
+    }
+    return (brg_freq);
+}
+
+uint Daq_Get_SampleRate(void)
+
+{
+     /*
+      * Read the BRG's to return the actual sample rate.
+      */
+     return (Daq_BRG_Rate(MCLK_BRG) / (MCLK_DIVISOR * SCLK_DIVISOR));
+}
+
+uint Daq_Set_SampleRate(uint rate, uint force)
+
+{
+    DECLARE_GLOBAL_DATA_PTR;
+    uint mclk_divisor; /* MCLK divisor */
+    uint rate_curr;    /* Current sample rate */
+
+    /*
+     * Limit the sample rate to some sensible values.
+     */
+    if (Daq64xSampling) {
+      if (rate > MAX_64x_SAMPLE_RATE) {
+	  rate = MAX_64x_SAMPLE_RATE;
+      }
+    }
+    else {
+      if (rate > MAX_128x_SAMPLE_RATE) {
+	  rate = MAX_128x_SAMPLE_RATE;
+      }
+    }
+    if (rate < MIN_SAMPLE_RATE) {
+        rate = MIN_SAMPLE_RATE;
+    }
+
+    /* Check to see if we are really changing rates */
+    rate_curr = Daq_Get_SampleRate();
+    if ((rate != rate_curr) || force) {
+        /*
+	 * Dynamically adjust MCLK based on the new sample rate.
+	 */
+
+        /* Compute the divisors */
+        mclk_divisor = BRG_INT_CLK / (rate * MCLK_DIVISOR * SCLK_DIVISOR);
+
+	/* Setup MCLK */
+	Daq_BRG_Set_Count(MCLK_BRG, mclk_divisor);
+
+	/* Setup SCLK */
+#       ifdef RUN_SCLK_ON_BRG_INT
+	   Daq_BRG_Set_Count(SCLK_BRG, mclk_divisor * MCLK_DIVISOR);
+#       else
+	   Daq_BRG_Set_Count(SCLK_BRG, MCLK_DIVISOR);
+#       endif
+
+#       ifdef RUN_LRCLK_ON_BRG_INT
+	    Daq_BRG_Set_Count(LRCLK_BRG,
+			      mclk_divisor * MCLK_DIVISOR * SCLK_DIVISOR);
+#       else
+	    Daq_BRG_Set_Count(LRCLK_BRG, SCLK_DIVISOR);
+#       endif
+
+	/* Read the BRG's to return the actual sample rate. */
+	rate_curr = Daq_Get_SampleRate();
+    }
+
+    return (rate_curr);
+}
+
+void Daq_Init_Clocks(int sample_rate, int sample_64x)
+
+{
+    volatile ioport_t *iopa = ioport_addr((immap_t *)CFG_IMMR, 0 /* port A */);
+
+    /* Save off the clocking data */
+    Daq64xSampling = sample_64x;
+
+    /*
+     * Limit the sample rate to some sensible values.
+     */
+    if (Daq64xSampling) {
+      if (sample_rate > MAX_64x_SAMPLE_RATE) {
+	  sample_rate = MAX_64x_SAMPLE_RATE;
+      }
+    }
+    else {
+      if (sample_rate > MAX_128x_SAMPLE_RATE) {
+	  sample_rate = MAX_128x_SAMPLE_RATE;
+      }
+    }
+    if (sample_rate < MIN_SAMPLE_RATE) {
+        sample_rate = MIN_SAMPLE_RATE;
+    }
+
+    /*
+     * Initialize the MCLK/SCLK/LRCLK baud rate generators.
+     */
+
+    /* Setup MCLK */
+    Daq_BRG_Set_ExtClk(MCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+
+    /* Setup SCLK */
+#   ifdef RUN_SCLK_ON_BRG_INT
+        Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+#   else
+        Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_CLK9);
+#   endif
+
+    /* Setup LRCLK */
+#   ifdef RUN_LRCLK_ON_BRG_INT
+        Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+#   else
+        Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_CLK5);
+#   endif
+
+    /* Setup the BRG rates */
+    Daq_Set_SampleRate(sample_rate, TRUE);
+
+    /* Enable the clock drivers */
+    iopa->pdat &= ~SLRCLK_EN_MASK;
+}
+
+void Daq_Stop_Clocks(void)
+
+{
+#ifdef TIGHTEN_UP_BRG_TIMING
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+#   ifdef TIGHTEN_UP_BRG_TIMING
+        /*
+         * Reset MCLK BRG
+         */
+#       if (MCLK_BRG == 0)
+            immr->im_brgc1 |=  CPM_BRG_RST;
+            immr->im_brgc1 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 1)
+            immr->im_brgc2 |=  CPM_BRG_RST;
+            immr->im_brgc2 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 2)
+            immr->im_brgc3 |=  CPM_BRG_RST;
+            immr->im_brgc3 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 3)
+            immr->im_brgc4 |=  CPM_BRG_RST;
+            immr->im_brgc4 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 4)
+            immr->im_brgc5 |=  CPM_BRG_RST;
+            immr->im_brgc5 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 5)
+            immr->im_brgc6 |=  CPM_BRG_RST;
+            immr->im_brgc6 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 6)
+            immr->im_brgc7 |=  CPM_BRG_RST;
+            immr->im_brgc7 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 7)
+            immr->im_brgc8 |=  CPM_BRG_RST;
+            immr->im_brgc8 &= ~CPM_BRG_RST;
+#       endif
+
+        /*
+         * Reset SCLK BRG
+         */
+#       if (SCLK_BRG == 0)
+            immr->im_brgc1 |=  CPM_BRG_RST;
+            immr->im_brgc1 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 1)
+            immr->im_brgc2 |=  CPM_BRG_RST;
+            immr->im_brgc2 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 2)
+            immr->im_brgc3 |=  CPM_BRG_RST;
+            immr->im_brgc3 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 3)
+            immr->im_brgc4 |=  CPM_BRG_RST;
+            immr->im_brgc4 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 4)
+            immr->im_brgc5 |=  CPM_BRG_RST;
+            immr->im_brgc5 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 5)
+            immr->im_brgc6 |=  CPM_BRG_RST;
+            immr->im_brgc6 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 6)
+            immr->im_brgc7 |=  CPM_BRG_RST;
+            immr->im_brgc7 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 7)
+            immr->im_brgc8 |=  CPM_BRG_RST;
+            immr->im_brgc8 &= ~CPM_BRG_RST;
+#       endif
+
+        /*
+         * Reset LRCLK BRG
+         */
+#       if (LRCLK_BRG == 0)
+            immr->im_brgc1 |=  CPM_BRG_RST;
+            immr->im_brgc1 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 1)
+            immr->im_brgc2 |=  CPM_BRG_RST;
+            immr->im_brgc2 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 2)
+            immr->im_brgc3 |=  CPM_BRG_RST;
+            immr->im_brgc3 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 3)
+            immr->im_brgc4 |=  CPM_BRG_RST;
+            immr->im_brgc4 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 4)
+            immr->im_brgc5 |=  CPM_BRG_RST;
+            immr->im_brgc5 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 5)
+            immr->im_brgc6 |=  CPM_BRG_RST;
+            immr->im_brgc6 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 6)
+            immr->im_brgc7 |=  CPM_BRG_RST;
+            immr->im_brgc7 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 7)
+            immr->im_brgc8 |=  CPM_BRG_RST;
+            immr->im_brgc8 &= ~CPM_BRG_RST;
+#       endif
+#   else
+        /*
+         * Reset the clocks
+         */
+        Daq_BRG_Reset(MCLK_BRG);
+        Daq_BRG_Reset(SCLK_BRG);
+        Daq_BRG_Reset(LRCLK_BRG);
+#   endif
+}
+
+void Daq_Start_Clocks(int sample_rate)
+
+{
+#ifdef TIGHTEN_UP_BRG_TIMING
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+    uint          mclk_brg;       /* MCLK  BRG value */
+    uint          sclk_brg;       /* SCLK  BRG value */
+    uint          lrclk_brg;      /* LRCLK BRG value */
+    uint          temp_lrclk_brg; /* Temporary LRCLK BRG value */
+    uint	  real_lrclk_brg; /* Permanent LRCLK BRG value */
+    unsigned long flags;          /* Interrupt flags */
+    uint          sclk_cnt;       /* SCLK count */
+    uint          delay_cnt;      /* Delay count */
+#endif
+
+#   ifdef TIGHTEN_UP_BRG_TIMING
+        /*
+         * Obtain the enabled MCLK BRG value
+         */
+#       if (MCLK_BRG == 0)
+            mclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 1)
+            mclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 2)
+            mclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 3)
+            mclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 4)
+            mclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 5)
+            mclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 6)
+            mclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 7)
+            mclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+
+        /*
+         * Obtain the enabled SCLK BRG value
+         */
+#       if (SCLK_BRG == 0)
+            sclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 1)
+            sclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 2)
+            sclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 3)
+            sclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 4)
+            sclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 5)
+            sclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 6)
+            sclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 7)
+            sclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+
+        /*
+         * Obtain the enabled LRCLK BRG value
+         */
+#       if (LRCLK_BRG == 0)
+            lrclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 1)
+            lrclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 2)
+            lrclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 3)
+            lrclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 4)
+            lrclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 5)
+            lrclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 6)
+            lrclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 7)
+            lrclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+
+	/* Save off the real LRCLK value */
+	real_lrclk_brg = lrclk_brg;
+
+	/* Obtain the current SCLK count */
+	sclk_cnt  = ((sclk_brg & 0x00001FFE) >> 1) + 1;
+
+	/* Compute the delay as a function of SCLK count */
+        delay_cnt = ((sclk_cnt / 4) - 2) * 10 + 6;
+	if (sample_rate == 43402) {
+	  delay_cnt++;
+	}
+
+        /* Clear out the count */
+	temp_lrclk_brg = sclk_brg & ~0x00001FFE;
+
+        /* Insert the count */
+	temp_lrclk_brg |= ((delay_cnt + (sclk_cnt / 2) - 1) << 1) &  0x00001FFE;
+
+        /*
+         * Enable MCLK BRG
+         */
+#       if (MCLK_BRG == 0)
+            immr->im_brgc1 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 1)
+            immr->im_brgc2 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 2)
+            immr->im_brgc3 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 3)
+            immr->im_brgc4 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 4)
+            immr->im_brgc5 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 5)
+            immr->im_brgc6 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 6)
+            immr->im_brgc7 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 7)
+            immr->im_brgc8 = mclk_brg;
+#       endif
+
+        /*
+         * Enable SCLK BRG
+         */
+#       if (SCLK_BRG == 0)
+            immr->im_brgc1 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 1)
+            immr->im_brgc2 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 2)
+            immr->im_brgc3 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 3)
+            immr->im_brgc4 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 4)
+            immr->im_brgc5 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 5)
+            immr->im_brgc6 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 6)
+            immr->im_brgc7 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 7)
+            immr->im_brgc8 = sclk_brg;
+#       endif
+
+        /*
+         * Enable LRCLK BRG (1st time - temporary)
+         */
+#       if (LRCLK_BRG == 0)
+             immr->im_brgc1 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 1)
+             immr->im_brgc2 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 2)
+             immr->im_brgc3 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 3)
+             immr->im_brgc4 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 4)
+             immr->im_brgc5 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 5)
+             immr->im_brgc6 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 6)
+             immr->im_brgc7 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 7)
+             immr->im_brgc8 = temp_lrclk_brg;
+#       endif
+
+        /*
+         * Enable LRCLK BRG (2nd time - permanent)
+         */
+#       if (LRCLK_BRG == 0)
+             immr->im_brgc1 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 1)
+             immr->im_brgc2 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 2)
+             immr->im_brgc3 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 3)
+             immr->im_brgc4 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 4)
+             immr->im_brgc5 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 5)
+             immr->im_brgc6 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 6)
+             immr->im_brgc7 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 7)
+             immr->im_brgc8 = real_lrclk_brg;
+#       endif
+#   else
+        /*
+         * Enable the clocks
+         */
+        Daq_BRG_Enable(LRCLK_BRG);
+        Daq_BRG_Enable(SCLK_BRG);
+        Daq_BRG_Enable(MCLK_BRG);
+#   endif
+}
+
+void Daq_Display_Clocks(void)
+
+{
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+    uint mclk_divisor; /* Detected MCLK divisor */
+    uint sclk_divisor; /* Detected SCLK divisor */
+
+    printf("\nBRG:\n");
+    if (immr->im_brgc4 != 0) {
+        printf("\tbrgc4\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  MCLK\n",
+	       immr->im_brgc4,
+	       (uint)&(immr->im_brgc4),
+	       Daq_BRG_Get_Count(3),
+	       Daq_BRG_Get_ExtClk(3),
+	       Daq_BRG_Get_ExtClk_Description(3));
+    }
+    if (immr->im_brgc8 != 0) {
+        printf("\tbrgc8\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SCLK\n",
+	       immr->im_brgc8,
+	       (uint)&(immr->im_brgc8),
+	       Daq_BRG_Get_Count(7),
+	       Daq_BRG_Get_ExtClk(7),
+	       Daq_BRG_Get_ExtClk_Description(7));
+    }
+    if (immr->im_brgc6 != 0) {
+        printf("\tbrgc6\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  LRCLK\n",
+	       immr->im_brgc6,
+	       (uint)&(immr->im_brgc6),
+	       Daq_BRG_Get_Count(5),
+	       Daq_BRG_Get_ExtClk(5),
+	       Daq_BRG_Get_ExtClk_Description(5));
+    }
+    if (immr->im_brgc1 != 0) {
+        printf("\tbrgc1\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SMC1\n",
+	       immr->im_brgc1,
+	       (uint)&(immr->im_brgc1),
+	       Daq_BRG_Get_Count(0),
+	       Daq_BRG_Get_ExtClk(0),
+	       Daq_BRG_Get_ExtClk_Description(0));
+    }
+    if (immr->im_brgc2 != 0) {
+        printf("\tbrgc2\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SMC2\n",
+	       immr->im_brgc2,
+	       (uint)&(immr->im_brgc2),
+	       Daq_BRG_Get_Count(1),
+	       Daq_BRG_Get_ExtClk(1),
+	       Daq_BRG_Get_ExtClk_Description(1));
+    }
+    if (immr->im_brgc3 != 0) {
+        printf("\tbrgc3\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SCC1\n",
+	       immr->im_brgc3,
+	       (uint)&(immr->im_brgc3),
+	       Daq_BRG_Get_Count(2),
+	       Daq_BRG_Get_ExtClk(2),
+	       Daq_BRG_Get_ExtClk_Description(2));
+    }
+    if (immr->im_brgc5 != 0) {
+        printf("\tbrgc5\t0x%08x @ 0x%08x, %5d count, %d extc, %8s\n",
+	       immr->im_brgc5,
+	       (uint)&(immr->im_brgc5),
+	       Daq_BRG_Get_Count(4),
+	       Daq_BRG_Get_ExtClk(4),
+	       Daq_BRG_Get_ExtClk_Description(4));
+    }
+    if (immr->im_brgc7 != 0) {
+        printf("\tbrgc7\t0x%08x @ 0x%08x, %5d count, %d extc, %8s\n",
+	       immr->im_brgc7,
+	       (uint)&(immr->im_brgc7),
+	       Daq_BRG_Get_Count(6),
+	       Daq_BRG_Get_ExtClk(6),
+	       Daq_BRG_Get_ExtClk_Description(6));
+    }
+
+#   ifdef RUN_SCLK_ON_BRG_INT
+        mclk_divisor = Daq_BRG_Rate(MCLK_BRG) / Daq_BRG_Rate(SCLK_BRG);
+#   else
+        mclk_divisor = Daq_BRG_Get_Count(SCLK_BRG);
+#   endif
+#   ifdef RUN_LRCLK_ON_BRG_INT
+        sclk_divisor = Daq_BRG_Rate(SCLK_BRG) / Daq_BRG_Rate(LRCLK_BRG);
+#   else
+        sclk_divisor = Daq_BRG_Get_Count(LRCLK_BRG);
+#   endif
+
+    printf("\nADC/DAC Clocking (%d/%d):\n", sclk_divisor, mclk_divisor);
+    printf("\tMCLK  %8d Hz, or %3dx SCLK, or %3dx LRCLK\n",
+	   Daq_BRG_Rate(MCLK_BRG),
+	   mclk_divisor,
+	   mclk_divisor * sclk_divisor);
+#   ifdef RUN_SCLK_ON_BRG_INT
+        printf("\tSCLK  %8d Hz, or %3dx LRCLK\n",
+	       Daq_BRG_Rate(SCLK_BRG),
+	       sclk_divisor);
+#   else
+        printf("\tSCLK  %8d Hz, or %3dx LRCLK\n",
+	       Daq_BRG_Rate(MCLK_BRG) / mclk_divisor,
+	       sclk_divisor);
+#   endif
+#   ifdef RUN_LRCLK_ON_BRG_INT
+        printf("\tLRCLK %8d Hz\n",
+	       Daq_BRG_Rate(LRCLK_BRG));
+#   else
+#       ifdef RUN_SCLK_ON_BRG_INT
+            printf("\tLRCLK %8d Hz\n",
+		   Daq_BRG_Rate(SCLK_BRG) / sclk_divisor);
+#       else
+            printf("\tLRCLK %8d Hz\n",
+		   Daq_BRG_Rate(MCLK_BRG) / (mclk_divisor * sclk_divisor));
+#       endif
+#   endif
+    printf("\n");
+}
diff --git a/board/sacsng/ioconfig.h b/board/sacsng/ioconfig.h
new file mode 100644
index 0000000..6857f99
--- /dev/null
+++ b/board/sacsng/ioconfig.h
@@ -0,0 +1,218 @@
+/*
+ * I/O Port configuration table
+ *
+ * If conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ */
+
+#ifdef SKIP
+#undef SKIP
+#endif
+
+#ifdef CONF
+#undef CONF
+#endif
+
+#ifdef DIN
+#undef DIN
+#endif
+
+#ifdef DOUT
+#undef DOUT
+#endif
+
+#ifdef GPIO
+#undef GPIO
+#endif
+
+#ifdef SPEC
+#undef SPEC
+#endif
+
+#ifdef ACTV
+#undef ACTV
+#endif
+
+#ifdef OPEN
+#undef OPEN
+#endif
+
+#define SKIP 0  /* SKIP over this port */
+#define CONF 1  /* CONFiguration the port */
+
+#define DIN  0  /* PDIRx 0: Direction IN  */
+#define DOUT 1  /* PDIRx 1: Direction OUT */
+
+#define GPIO 0  /* PPARx 0: General Purpose I/O */
+#define SPEC 1  /* PPARx 1: dedicated to a peripheral function, */
+                /*          i.e. the port has a SPECial use. */
+
+#define ACTV 0  /* PODRx 0: ACTiVely driven as an output */
+#define OPEN 1  /* PODRx 1: OPEN-drain driver */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+    /* Port A configuration */
+    {	/*	     conf  ppar  psor  pdir  podr  pdat */
+	/* PA31 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS8*        */
+	/* PA30 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS7*        */
+	/* PA29 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS6*        */
+	/* PA28 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS5*        */
+	/* PA27 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS4*        */
+	/* PA26 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS3*        */
+	/* PA25 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS2*        */
+	/* PA24 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS1*        */
+	/* PA23 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* ODIS_EN*       */
+	/* PA22 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* STLED2_EN*     */
+	/* PA21 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* STLED1_EN*     */
+	/* PA20 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* PLED3_EN*      */
+	/* PA19 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* PLED2_EN*      */
+        /* PA18 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* PLED1_EN*      */
+	/* PA17 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PA16 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* DAC_RST*       */
+	/* PA15 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* CH34SDATA_PU   */
+        /* PA14 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* CH12SDATA_PU   */
+        /* PA13 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* SLRCLK_EN*     */
+	/* PA12 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_4ACDC*    */
+	/* PA11 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_4TEDS*    */
+	/* PA10 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_4XTDS*    */
+	/* PA9  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_3ACDC*    */
+	/* PA8  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_3TEDS*    */
+	/* PA7  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_3XTDS*    */
+	/* PA6  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_2ACDC*    */
+	/* PA5  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_2TEDS*    */
+	/* PA4  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_2XTDS*    */
+	/* PA3  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PA2  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_1ACDC*    */
+	/* PA1  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_1TEDS*    */
+	/* PA0  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }  /* MTRX_1XTDS*    */
+    },
+
+    /* Port B configuration */
+    {	/*	     conf  ppar  psor  pdir  podr  pdat */
+	/* PB31 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TX_ER */
+	/* PB30 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RX_DV */
+	/* PB29 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* FCC2 MII_TX_EN */
+	/* PB28 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RX_ER */
+	/* PB27 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_COL   */
+	/* PB26 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_CRS   */
+	/* PB25 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD3  */
+	/* PB24 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD2  */
+	/* PB23 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD1  */
+	/* PB22 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD0  */
+	/* PB21 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD0  */
+	/* PB20 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD1  */
+	/* PB19 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD2  */
+	/* PB18 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD3  */
+	/* PB17 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB16 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB15 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB14 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RXDC1,   BSDATA_ADC12 */
+	/* PB13 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB12 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RSYNCC1, LRCLK  */
+	/* PB11 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1TXDD1,   RSDATA_DAC12 */
+	/* PB10 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RXDD1,   BSDATA_ADC34 */
+	/* PB9  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB8  */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RSYNCD1, LRCLK  */
+	/* PB7  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB6  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* XCITE_SHDN     */
+	/* PB5  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* TRIGGER        */
+	/* PB4  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* ARM            */
+	/* PB3  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PB2  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PB1  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PB0  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }  /* pin doesn't exist */
+    },
+
+    /* Port C */
+    {	/*	      conf ppar  psor  pdir  podr  pdat */
+	/* PC31 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC30 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC29 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK3,  MCLK    */
+	/* PC28 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* TOUT2*         */
+#ifdef QQQ
+	/* PC28 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TOUT2*         */
+#endif
+	/* PC27 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK5,  SCLK    */
+	/* PC26 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC25 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK7,  SCLK    */
+	/* PC24 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC23 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK9,  MCLK    */
+	/* PC22 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC21 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* BRGO6 (LRCLK)  */
+	/* PC20 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC19 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK13, MII_RXCLK  */
+	/* PC18 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK14, MII_TXCLK  */
+        /* PC17 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* BRGO8 (SCLK)   */
+	/* PC16 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC15 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* SMC2_TX        */
+	/* PC14 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC13 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC12 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TDM_STRB3      */
+	/* PC11 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC10 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* TDM_STRB4      */
+	/* PC9  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BPDIS_IN3      */
+	/* PC8  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BPDIS_IN2      */
+	/* PC7  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BPDIS_IN1      */
+	/* PC6  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC5  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BTST_IN2*      */
+        /* PC4  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BTST_IN1*      */
+	/* PC3  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* MUSH_STAT      */
+	/* PC2  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* OUTDRV_STAT    */
+	/* PC1  */ { CONF, GPIO,   0,  DOUT, OPEN,   1   }, /* PHY_MDIO       */
+        /* PC0  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* PHY_MDC        */
+    },
+
+    /* Port D */
+    {	/*	      conf ppar  psor  pdir  podr  pdat */
+	/* PD31 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* SCC1_RX        */
+	/* PD30 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* SCC1_TX        */
+	/* PD29 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD28 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD27 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD26 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD25 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD24 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD23 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD22 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD21 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD20 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* SPI_ADC_CS*    */
+	/* PD19 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* SPI_DAC_CS*    */
+#if defined(CONFIG_SOFT_SPI)
+	/* PD18 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* SPI_CLK        */
+	/* PD17 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* SPI_MOSI       */
+	/* PD16 */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* SPI_MISO       */
+#else
+	/* PD18 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* SPI_CLK        */
+	/* PD17 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* SPI_MOSI       */
+	/* PD16 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* SPI_MISO       */
+#endif
+#if defined(CONFIG_SOFT_I2C)
+	/* PD15 */ { CONF, GPIO,   0,  DOUT, OPEN,   1   }, /* I2C_SDA        */
+	/* PD14 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* I2C_SCL        */
+#else
+#if defined(CONFIG_HARD_I2C)
+	/* PD15 */ { CONF, SPEC,   1,  DIN,  OPEN,   0   }, /* I2C_SDA        */
+	/* PD14 */ { CONF, SPEC,   1,  DIN,  OPEN,   0   }, /* I2C_SCL        */
+#else /* normal I/O port pins */
+	/* PD15 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* I2C_SDA        */
+	/* PD14 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* I2C_SCL        */
+#endif
+#endif
+	/* PD13 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TDM_STRB1      */
+	/* PD12 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TDM_STRB2      */
+	/* PD11 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD10 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* BRGO4 (MCLK)   */
+	/* PD9  */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* SMC1_TX        */
+	/* PD8  */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* SMC1_RX        */
+	/* PD7  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* N/C            */
+	/* PD6  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* N/C            */
+	/* PD5  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* N/C            */
+	/* PD4  */ { CONF, SPEC,   1,  DOUT, ACTV,   1   }, /* SMC2_RX        */
+	/* PD3  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PD2  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PD1  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PD0  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }  /* pin doesn't exist */
+    }
+};
+
diff --git a/board/sandpoint/sandpoint.c b/board/sandpoint/sandpoint.c
new file mode 100644
index 0000000..8d385f7
--- /dev/null
+++ b/board/sandpoint/sandpoint.c
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.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
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+int checkboard (void)
+{
+	/*TODO: Check processor type */
+
+	puts (	"Board: Sandpoint "
+#ifdef CONFIG_MPC8240
+		"8240"
+#endif
+#ifdef CONFIG_MPC8245
+		"8245"
+#endif
+		" Unity ##Test not implemented yet##\n");
+	return 0;
+}
+
+#if 0 	/* NOT USED */
+int checkflash (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("## Test not implemented yet ##\n");
+
+	return (0);
+}
+#endif
+
+long int initdram (int board_type)
+{
+	int		 i, cnt;
+	volatile uchar * base= CFG_SDRAM_BASE;
+	volatile ulong * addr;
+	ulong		 save[32];
+	ulong		 val, ret  = 0;
+
+	for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+		addr = (volatile ulong *)base + cnt;
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	addr = (volatile ulong *)base;
+	save[i] = *addr;
+	*addr = 0;
+
+	if (*addr != 0) {
+		*addr = save[i];
+		goto Done;
+	}
+
+	for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+		addr = (volatile ulong *)base + cnt;
+		val = *addr;
+		*addr = save[--i];
+		if (val != ~cnt) {
+			ulong new_bank0_end = cnt * sizeof(long) - 1;
+			ulong mear1  = mpc824x_mpc107_getreg(MEAR1);
+			ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+			mear1 =  (mear1  & 0xFFFFFF00) |
+			((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+			emear1 = (emear1 & 0xFFFFFF00) |
+			((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+			mpc824x_mpc107_setreg(MEAR1,  mear1);
+			mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+			ret = cnt * sizeof(long);
+			goto Done;
+		}
+	}
+
+	ret = CFG_MAX_RAM_SIZE;
+Done:
+	return ret;
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x10, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+				       PCI_ENET1_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/shannon/u-boot.lds b/board/shannon/u-boot.lds
new file mode 100644
index 0000000..f4b0ade
--- /dev/null
+++ b/board/shannon/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/sa1100/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/siemens/CCM/ccm.c b/board/siemens/CCM/ccm.c
new file mode 100644
index 0000000..079f38f
--- /dev/null
+++ b/board/siemens/CCM/ccm.c
@@ -0,0 +1,440 @@
+/*
+ * (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 <mpc8xx.h>
+#include <commproc.h>
+#include <command.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+void can_driver_enable (void);
+void can_driver_disable (void);
+
+int fpga_init(void);
+
+/* ------------------------------------------------------------------------- */
+
+#define	_NOT_USED_	0xFFFFFFFF
+
+const uint sdram_table[] =
+{
+	/*
+	 * Single Read. (Offset 0 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
+	0x1FF5FC47, /* last */
+	/*
+	 * SDRAM Initialization (offset 5 in UPMA RAM)
+	 *
+	 * This is no UPM entry point. The following definition uses
+	 * the remaining space to establish an initialization
+	 * sequence, which is executed by a RUN command.
+	 *
+	 */
+		    0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
+	/*
+	 * Burst Read. (Offset 8 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
+	0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Single Write. (Offset 18 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEABBC00, 0x01B27C04, 0x1FF5FC47, /* last */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Burst Write. (Offset 20 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
+	0xF0AFFC00, 0xE1BAFC04, 0x1FF5FC47, /* last */
+					    _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Refresh  (Offset 30 in UPMA RAM)
+	 */
+	0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
+	0xFFFFFC84, 0xFFFFFC07, /* last */
+				_NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Exception. (Offset 3c in UPMA RAM)
+	 */
+	0x7FFFFC07, /* last */
+		    _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Always return 1 (no second DRAM bank since based on TQM8xxL module)
+ */
+
+int checkboard (void)
+{
+    unsigned char *s;
+    unsigned char buf[64];
+
+    s = (getenv_r ("serial#", buf, sizeof(buf)) > 0) ? buf : NULL;
+
+    puts ("Board: Siemens CCM");
+
+    if (s) {
+	    puts (" (");
+
+	    for (; *s; ++s) {
+		if (*s == ' ')
+		    break;
+		putc (*s);
+	    }
+	    putc (')');
+    }
+
+    putc ('\n');
+
+    return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * If Power-On-Reset switch off the Red and Green LED: At reset, the
+ * data direction registers are cleared and must therefore be restored.
+ */
+#define RSR_CSRS	0x08000000
+
+int power_on_reset(void)
+{
+    /* Test Reset Status Register */
+    return ((volatile immap_t *)CFG_IMMR)->im_clkrst.car_rsr & RSR_CSRS ? 0:1;
+}
+
+#define PB_LED_GREEN	0x10000		/* red LED is on PB.15 */
+#define PB_LED_RED	0x20000		/* red LED is on PB.14 */
+#define PB_LEDS		(PB_LED_GREEN | PB_LED_RED);
+
+static void init_leds (void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+    immap->im_cpm.cp_pbpar &= ~PB_LEDS;
+    immap->im_cpm.cp_pbodr &= ~PB_LEDS;
+    immap->im_cpm.cp_pbdir |=  PB_LEDS;
+    /* Check stop reset status */
+    if (power_on_reset()) {
+	    immap->im_cpm.cp_pbdat &= ~PB_LEDS;
+    }
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+    long int size8, size9;
+    long int size = 0;
+    unsigned long reg;
+
+    upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+    /*
+     * Preliminary prescaler for refresh (depends on number of
+     * banks): This value is selected for four cycles every 62.4 us
+     * with two SDRAM banks or four cycles every 31.2 us with one
+     * bank. It will be adjusted after memory sizing.
+     */
+    memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
+
+    memctl->memc_mar  = 0x00000088;
+
+    /*
+     * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
+     * preliminary addresses - these have to be modified after the
+     * SDRAM size has been determined.
+     */
+    memctl->memc_or2 = CFG_OR2_PRELIM;
+    memctl->memc_br2 = CFG_BR2_PRELIM;
+
+    memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+    udelay(200);
+
+    /* perform SDRAM initializsation sequence */
+
+    memctl->memc_mcr  = 0x80004105;	/* SDRAM bank 0 */
+    udelay(1);
+    memctl->memc_mcr  = 0x80004230;	/* SDRAM bank 0 - execute twice */
+    udelay(1);
+
+    memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */
+
+    udelay (1000);
+
+    /*
+     * Check Bank 0 Memory Size for re-configuration
+     *
+     * try 8 column mode
+     */
+    size8 = dram_size (CFG_MAMR_8COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
+
+    udelay (1000);
+
+    /*
+     * try 9 column mode
+     */
+    size9 = dram_size (CFG_MAMR_9COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
+
+    if (size8 < size9) {		/* leave configuration at 9 columns	*/
+	size = size9;
+/*	debug ("SDRAM in 9 column mode: %ld MB\n", size >> 20);	*/
+    } else {				/* back to 8 columns			*/
+	size = size8;
+	memctl->memc_mamr = CFG_MAMR_8COL;
+	udelay(500);
+/*	debug ("SDRAM in 8 column mode: %ld MB\n", size >> 20);	*/
+    }
+
+    udelay (1000);
+
+    /*
+     * Adjust refresh rate depending on SDRAM type
+     * For types > 128 MBit leave it at the current (fast) rate
+     */
+    if (size < 0x02000000) {
+	/* reduce to 15.6 us (62.4 us / quad) */
+	memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
+	udelay(1000);
+    }
+
+    /*
+     * Final mapping
+     */
+
+    memctl->memc_or2 = ((-size) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+    memctl->memc_br2 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+
+    /* adjust refresh rate depending on SDRAM type, one bank */
+    reg = memctl->memc_mptpr;
+    reg >>= 1;	/* reduce to CFG_MPTPR_1BK_8K / _4K */
+    memctl->memc_mptpr = reg;
+
+    can_driver_enable ();
+    init_leds ();
+
+    udelay(10000);
+
+    return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Warning - both the PUMA load mode and the CAN driver use UPM B,
+ * so make sure only one of both is active.
+ */
+void can_driver_enable (void)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+    /* Initialize MBMR */
+    memctl->memc_mbmr = MAMR_GPL_B4DIS;	/* GPL_B4 ouput line Disable */
+
+    /* Initialize UPMB for CAN: single read */
+    memctl->memc_mdr = 0xFFFFC004;
+    memctl->memc_mcr = 0x0100 | UPMB;
+
+    memctl->memc_mdr = 0x0FFFD004;
+    memctl->memc_mcr = 0x0101 | UPMB;
+
+    memctl->memc_mdr = 0x0FFFC000;
+    memctl->memc_mcr = 0x0102 | UPMB;
+
+    memctl->memc_mdr = 0x3FFFC004;
+    memctl->memc_mcr = 0x0103 | UPMB;
+
+    memctl->memc_mdr = 0xFFFFDC05;
+    memctl->memc_mcr = 0x0104 | UPMB;
+
+    /* Initialize UPMB for CAN: single write */
+    memctl->memc_mdr = 0xFFFCC004;
+    memctl->memc_mcr = 0x0118 | UPMB;
+
+    memctl->memc_mdr = 0xCFFCD004;
+    memctl->memc_mcr = 0x0119 | UPMB;
+
+    memctl->memc_mdr = 0x0FFCC000;
+    memctl->memc_mcr = 0x011A | UPMB;
+
+    memctl->memc_mdr = 0x7FFCC004;
+    memctl->memc_mcr = 0x011B | UPMB;
+
+    memctl->memc_mdr = 0xFFFDCC05;
+    memctl->memc_mcr = 0x011C | UPMB;
+
+    /* Initialize OR3 / BR3 for CAN Bus Controller */
+    memctl->memc_or3 = CFG_OR3_CAN;
+    memctl->memc_br3 = CFG_BR3_CAN;
+}
+
+void can_driver_disable (void)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+    /* Reset OR3 / BR3 to disable  CAN Bus Controller */
+    memctl->memc_br3 = 0;
+    memctl->memc_or3 = 0;
+
+    memctl->memc_mbmr = 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base, long int maxsize)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+    volatile long int	 *addr;
+    ulong		  cnt, val;
+    ulong		  save[32];	/* to make test non-destructive */
+    unsigned char	  i = 0;
+
+    memctl->memc_mamr = mamr_value;
+
+    for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+	addr = base + cnt;	/* pointer arith! */
+
+	save[i++] = *addr;
+	*addr = ~cnt;
+    }
+
+    /* write 0 to base address */
+    addr = base;
+    save[i] = *addr;
+    *addr = 0;
+
+    /* check at base address */
+    if ((val = *addr) != 0) {
+	*addr = save[i];
+	return (0);
+    }
+
+    for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
+	addr = base + cnt;	/* pointer arith! */
+
+	val = *addr;
+	*addr = save[--i];
+
+	if (val != (~cnt)) {
+	    return (cnt * sizeof(long));
+	}
+    }
+    return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define	ETH_CFG_BITS	(CFG_PB_ETH_CFG1 | CFG_PB_ETH_CFG2  | CFG_PB_ETH_CFG3 )
+
+#define ETH_ALL_BITS	(ETH_CFG_BITS | CFG_PB_ETH_POWERDOWN)
+
+void	reset_phy(void)
+{
+	immap_t *immr = (immap_t *)CFG_IMMR;
+	ulong value;
+
+	/* Configure all needed port pins for GPIO */
+#if CFG_ETH_MDDIS_VALUE
+	immr->im_ioport.iop_padat |=   CFG_PA_ETH_MDDIS;
+#else
+	immr->im_ioport.iop_padat &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);	/* Set low */
+#endif
+	immr->im_ioport.iop_papar &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);	/* GPIO */
+	immr->im_ioport.iop_paodr &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);	/* active output */
+	immr->im_ioport.iop_padir |=   CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET;	/* output */
+
+	immr->im_cpm.cp_pbpar &= ~(ETH_ALL_BITS);	/* GPIO */
+	immr->im_cpm.cp_pbodr &= ~(ETH_ALL_BITS);	/* active output */
+
+	value  = immr->im_cpm.cp_pbdat;
+
+	/* Assert Powerdown and Reset signals */
+	value |=  CFG_PB_ETH_POWERDOWN;
+
+	/* PHY configuration includes MDDIS and CFG1 ... CFG3 */
+#if CFG_ETH_CFG1_VALUE
+	value |=   CFG_PB_ETH_CFG1;
+#else
+	value &= ~(CFG_PB_ETH_CFG1);
+#endif
+#if CFG_ETH_CFG2_VALUE
+	value |=   CFG_PB_ETH_CFG2;
+#else
+	value &= ~(CFG_PB_ETH_CFG2);
+#endif
+#if CFG_ETH_CFG3_VALUE
+	value |=   CFG_PB_ETH_CFG3;
+#else
+	value &= ~(CFG_PB_ETH_CFG3);
+#endif
+
+	/* Drive output signals to initial state */
+	immr->im_cpm.cp_pbdat  = value;
+	immr->im_cpm.cp_pbdir |= ETH_ALL_BITS;
+	udelay (10000);
+
+	/* De-assert Ethernet Powerdown */
+	immr->im_cpm.cp_pbdat &= ~(CFG_PB_ETH_POWERDOWN); /* Enable PHY power */
+	udelay (10000);
+
+	/* de-assert RESET signal of PHY */
+	immr->im_ioport.iop_padat |= CFG_PA_ETH_RESET;
+	udelay (1000);
+}
+
+
+int misc_init_r (void)
+{
+	fpga_init();
+	return (0);
+}
+/* ------------------------------------------------------------------------- */
diff --git a/board/siemens/CCM/fpga_ccm.c b/board/siemens/CCM/fpga_ccm.c
new file mode 100644
index 0000000..292387b
--- /dev/null
+++ b/board/siemens/CCM/fpga_ccm.c
@@ -0,0 +1,170 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <mpc8xx.h>
+#include <commproc.h>
+#include <common.h>
+
+#include "../common/fpga.h"
+
+fpga_t fpga_list[] = {
+    { "PUMA" , PUMA_CONF_BASE ,
+      CFG_PC_PUMA_INIT , CFG_PC_PUMA_PROG , CFG_PC_PUMA_DONE  }
+};
+int fpga_count = sizeof(fpga_list) / sizeof(fpga_t);
+
+void can_driver_enable (void);
+void can_driver_disable (void);
+
+#define	_NOT_USED_	0xFFFFFFFF
+
+/*
+ * PUMA access using UPM B
+ */
+const uint puma_table[] =
+{
+	/*
+	 * Single Read. (Offset 0 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_,
+	/*
+	 * Precharge and MRS
+	 */
+		    _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Burst Read. (Offset 8 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Single Write. (Offset 18 in UPM RAM)
+	 */
+	0x0FFCF804, 0x0FFCF400, 0x3FFDFC47, /* last */
+					    _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Burst Write. (Offset 20 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Refresh  (Offset 30 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Exception. (Offset 3c in UPM RAM)
+	 */
+	0x7FFFFC07, /* last */
+		    _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+
+ulong fpga_control (fpga_t* fpga, int cmd)
+{
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+    switch (cmd) {
+    case FPGA_INIT_IS_HIGH:
+	immr->im_ioport.iop_pcdir &= ~fpga->init_mask; /* input */
+	return (immr->im_ioport.iop_pcdat & fpga->init_mask) ? 1:0;
+
+    case FPGA_INIT_SET_LOW:
+	immr->im_ioport.iop_pcdir |=  fpga->init_mask; /* output */
+	immr->im_ioport.iop_pcdat &= ~fpga->init_mask;
+	break;
+
+    case FPGA_INIT_SET_HIGH:
+	immr->im_ioport.iop_pcdir |= fpga->init_mask; /* output */
+	immr->im_ioport.iop_pcdat |= fpga->init_mask;
+	break;
+
+    case FPGA_PROG_SET_LOW:
+	immr->im_ioport.iop_pcdat &= ~fpga->prog_mask;
+	break;
+
+    case FPGA_PROG_SET_HIGH:
+	immr->im_ioport.iop_pcdat |= fpga->prog_mask;
+	break;
+
+    case FPGA_DONE_IS_HIGH:
+	return (immr->im_ioport.iop_pcdat & fpga->done_mask) ? 1:0;
+
+    case FPGA_READ_MODE:
+	/* disable FPGA in memory controller */
+	memctl->memc_br4 = 0;
+	memctl->memc_or4 = PUMA_CONF_OR_READ;
+	memctl->memc_br4 = PUMA_CONF_BR_READ;
+
+	/* (re-) enable CAN drivers */
+	can_driver_enable ();
+
+	break;
+
+    case FPGA_LOAD_MODE:
+	/* disable FPGA in memory controller */
+	memctl->memc_br4 = 0;
+	/*
+	 * We must disable the CAN drivers first because
+	 * they use UPM B, too.
+	 */
+	can_driver_disable ();
+	/*
+	 * Configure UPMB for FPGA
+	 */
+	upmconfig(UPMB,(uint *)puma_table,sizeof(puma_table)/sizeof(uint));
+	memctl->memc_or4 = PUMA_CONF_OR_LOAD;
+	memctl->memc_br4 = PUMA_CONF_BR_LOAD;
+	break;
+
+    case FPGA_GET_ID:
+	return *(volatile ulong *)fpga->conf_base;
+
+    case FPGA_INIT_PORTS:
+	immr->im_ioport.iop_pcpar &= ~fpga->init_mask; /* INIT I/O */
+	immr->im_ioport.iop_pcso  &= ~fpga->init_mask;
+	immr->im_ioport.iop_pcdir &= ~fpga->init_mask;
+
+	immr->im_ioport.iop_pcpar &= ~fpga->prog_mask; /* PROG Output */
+	immr->im_ioport.iop_pcso  &= ~fpga->prog_mask;
+	immr->im_ioport.iop_pcdir |=  fpga->prog_mask;
+
+	immr->im_ioport.iop_pcpar &= ~fpga->done_mask; /* DONE Input */
+	immr->im_ioport.iop_pcso  &= ~fpga->done_mask;
+	immr->im_ioport.iop_pcdir &= ~fpga->done_mask;
+
+	break;
+
+    }
+    return 0;
+}
+
diff --git a/board/siemens/SCM/fpga_scm.c b/board/siemens/SCM/fpga_scm.c
new file mode 100644
index 0000000..3b93794
--- /dev/null
+++ b/board/siemens/SCM/fpga_scm.c
@@ -0,0 +1,104 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <mpc8260.h>
+#include <common.h>
+#include "../common/fpga.h"
+
+fpga_t fpga_list[] = {
+    { "FIOX" , CFG_FIOX_BASE ,
+      CFG_PD_FIOX_INIT , CFG_PD_FIOX_PROG , CFG_PD_FIOX_DONE  },
+    { "FDOHM", CFG_FDOHM_BASE,
+      CFG_PD_FDOHM_INIT, CFG_PD_FDOHM_PROG, CFG_PD_FDOHM_DONE }
+};
+int fpga_count = sizeof(fpga_list) / sizeof(fpga_t);
+
+
+ulong fpga_control (fpga_t* fpga, int cmd)
+{
+    volatile immap_t *immr  = (immap_t *)CFG_IMMR;
+
+    switch (cmd) {
+    case FPGA_INIT_IS_HIGH:
+	immr->im_ioport.iop_pdird &= ~fpga->init_mask; /* input */
+	return (immr->im_ioport.iop_pdatd & fpga->init_mask) ? 1:0;
+
+    case FPGA_INIT_SET_LOW:
+	immr->im_ioport.iop_pdird |=  fpga->init_mask; /* output */
+	immr->im_ioport.iop_pdatd &= ~fpga->init_mask;
+	break;
+
+    case FPGA_INIT_SET_HIGH:
+	immr->im_ioport.iop_pdird |= fpga->init_mask; /* output */
+	immr->im_ioport.iop_pdatd |= fpga->init_mask;
+	break;
+
+    case FPGA_PROG_SET_LOW:
+	immr->im_ioport.iop_pdatd &= ~fpga->prog_mask;
+	break;
+
+    case FPGA_PROG_SET_HIGH:
+	immr->im_ioport.iop_pdatd |= fpga->prog_mask;
+	break;
+
+    case FPGA_DONE_IS_HIGH:
+	return (immr->im_ioport.iop_pdatd & fpga->done_mask) ? 1:0;
+
+    case FPGA_READ_MODE:
+	break;
+
+    case FPGA_LOAD_MODE:
+	break;
+
+    case FPGA_GET_ID:
+	if (fpga->conf_base == CFG_FIOX_BASE) {
+	    ulong ver = *(volatile ulong *)(fpga->conf_base + 0x10);
+	    return ((ver >> 10) & 0xf) + ((ver >> 2) & 0xf0);
+	}
+	else if (fpga->conf_base == CFG_FDOHM_BASE) {
+	    return (*(volatile ushort *)fpga->conf_base) & 0xff;
+	}
+	else {
+	    return *(volatile ulong *)fpga->conf_base;
+	}
+
+    case FPGA_INIT_PORTS:
+	immr->im_ioport.iop_ppard &= ~fpga->init_mask; /* INIT I/O */
+	immr->im_ioport.iop_psord &= ~fpga->init_mask;
+	immr->im_ioport.iop_pdird &= ~fpga->init_mask;
+
+	immr->im_ioport.iop_ppard &= ~fpga->prog_mask; /* PROG Output */
+	immr->im_ioport.iop_psord &= ~fpga->prog_mask;
+	immr->im_ioport.iop_pdird |=  fpga->prog_mask;
+
+	immr->im_ioport.iop_ppard &= ~fpga->done_mask; /* DONE Input */
+	immr->im_ioport.iop_psord &= ~fpga->done_mask;
+	immr->im_ioport.iop_pdird &= ~fpga->done_mask;
+
+	break;
+
+    }
+    return 0;
+}
diff --git a/board/siemens/common/README b/board/siemens/common/README
new file mode 100644
index 0000000..d781903
--- /dev/null
+++ b/board/siemens/common/README
@@ -0,0 +1,27 @@
+CCM/SCM-Ergaenzungen fuer U-Boot und Linux:
+-------------------------------------------
+
+Es gibt nun ein gemeinsames Kommando zum Laden der FPGAs:
+
+  => help fpga
+  fpga fpga status [name] - print FPGA status
+  fpga reset  [name] - reset FPGA
+  fpga load [name] addr - load FPGA configuration data
+
+Der Name kann beim CCM-Module auch weggelassen werden.
+Die Laengenangabe und damit "puma_len" ist nicht mehr
+noetig:
+
+  => fpga load puma 40600000
+  FPGA load PUMA: addr 40600000: (00000005)... done
+
+Die MTD-Partitionierung kann nun mittels "bootargs" ueber-
+geben werden:
+
+  => printenv addmtd
+  addmtd=setenv bootargs $(bootargs)
+    mtdparts=0:256k(U-Boot)ro,768k(Kernel),-(Rest)\;1:-(myJFFS2)
+
+Die Portierung auf SMC ist natuerlich noch nicht getestet.
+
+Wolfgang Grandegger (04.06.2002)
diff --git a/board/siemens/common/fpga.c b/board/siemens/common/fpga.c
new file mode 100644
index 0000000..a17de5a
--- /dev/null
+++ b/board/siemens/common/fpga.c
@@ -0,0 +1,358 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <command.h>
+#include <linux/ctype.h>
+#include <common.h>
+#include <cmd_boot.h>
+#include <cmd_bsp.h>
+
+#include "fpga.h"
+
+int  power_on_reset(void);
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+
+static int fpga_get_version(fpga_t* fpga, char* name)
+{
+    char vname[12];
+    /*
+     * Net-list string format:
+     *     "vvvvvvvvddddddddn...".
+     *     Version Date    Name
+     *     "0000000322042002PUMA" = PUMA version 3 from 22.04.2002.
+     */
+    if (strlen(name) < (16 + strlen(fpga->name)))
+	goto failure;
+    /* Check FPGA name */
+    if (strcmp(&name[16], fpga->name) != 0)
+	goto failure;
+    /* Get version number */
+    memcpy(vname, name, 8);
+    vname[8] = '\0';
+    return simple_strtoul(vname, NULL, 16);
+
+ failure:
+    printf("Image name %s is invalid\n", name);
+    return -1;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+static fpga_t* fpga_get(char* fpga_name)
+{
+    char name[FPGA_NAME_LEN];
+    int i;
+
+    if (strlen(fpga_name) >= FPGA_NAME_LEN)
+	goto failure;
+    for (i = 0; i < strlen(fpga_name); i++)
+	name[i] = toupper(fpga_name[i]);
+    name[i] = '\0';
+    for (i = 0; i < fpga_count; i++) {
+	if (strcmp(name, fpga_list[i].name) == 0)
+	    return &fpga_list[i];
+    }
+ failure:
+    printf("FPGA: name %s is invalid\n", fpga_name);
+    return NULL;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+static void fpga_status (fpga_t* fpga)
+{
+    /* Check state */
+    if (fpga_control(fpga, FPGA_DONE_IS_HIGH))
+	printf ("%s is loaded (%08lx)\n",
+		fpga->name, fpga_control(fpga, FPGA_GET_ID));
+    else
+	printf ("%s is NOT loaded\n", fpga->name);
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+#define FPGA_RESET_TIMEOUT 100 /* = 10 ms */
+
+static int fpga_reset (fpga_t* fpga)
+{
+    int i;
+
+    /* Set PROG to low and wait til INIT goes low */
+    fpga_control(fpga, FPGA_PROG_SET_LOW);
+    for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
+	udelay (100);
+	if (!fpga_control(fpga, FPGA_INIT_IS_HIGH))
+	    break;
+    }
+    if (i == FPGA_RESET_TIMEOUT)
+	goto failure;
+
+    /* Set PROG to high and wait til INIT goes high */
+    fpga_control(fpga, FPGA_PROG_SET_HIGH);
+    for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
+	udelay (100);
+	if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
+	    break;
+    }
+    if (i == FPGA_RESET_TIMEOUT)
+	goto failure;
+
+    return 0;
+ failure:
+    return 1;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+#define FPGA_LOAD_TIMEOUT 100 /* = 10 ms */
+
+static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
+{
+    volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
+    image_header_t hdr;
+    ulong len, checksum;
+    uchar *data = (uchar *)&hdr;
+    char *s, msg[32];
+    int verify, i;
+
+    /*
+     * Check the image header and data of the net-list
+     */
+    memcpy (&hdr, (char *)addr, sizeof(image_header_t));
+
+    if (hdr.ih_magic != IH_MAGIC) {
+	strcpy (msg, "Bad Image Magic Number");
+        goto failure;
+    }
+
+    len  = sizeof(image_header_t);
+
+    checksum = hdr.ih_hcrc;
+    hdr.ih_hcrc = 0;
+
+    if (crc32 (0, data, len) != checksum) {
+	strcpy (msg, "Bad Image Header CRC");
+	goto failure;
+    }
+
+    data = (uchar*)(addr + sizeof(image_header_t));
+    len  = hdr.ih_size;
+
+    s = getenv ("verify");
+    verify = (s && (*s == 'n')) ? 0 : 1;
+    if (verify) {
+	if (crc32 (0, data, len) != hdr.ih_dcrc) {
+	    strcpy (msg, "Bad Image Data CRC");
+	    goto failure;
+	}
+    }
+
+    if (checkall && fpga_get_version(fpga, hdr.ih_name) < 0)
+	return 1;
+
+    /* align length */
+    if (len & 1)
+	++len;
+
+    /*
+     * Reset FPGA and wait for completion
+     */
+    if (fpga_reset(fpga)) {
+	strcpy (msg, "Reset Timeout");
+	goto failure;
+    }
+
+    printf ("(%s)... ", hdr.ih_name);
+    /*
+     * Copy data to FPGA
+     */
+    fpga_control (fpga, FPGA_LOAD_MODE);
+    while (len--) {
+	*fpga_addr = *data++;
+    }
+    fpga_control (fpga, FPGA_READ_MODE);
+
+    /*
+     * Wait for completion and check error status if timeout
+     */
+    for (i = 0; i < FPGA_LOAD_TIMEOUT; i++) {
+	udelay (100);
+	if (fpga_control (fpga, FPGA_DONE_IS_HIGH))
+	    break;
+    }
+    if (i == FPGA_LOAD_TIMEOUT) {
+	if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
+	    strcpy(msg, "Invalid Size");
+	else
+	    strcpy(msg, "CRC Error");
+	goto failure;
+    }
+
+    printf("done\n");
+    return 0;
+
+ failure:
+
+    printf("ERROR: %s\n", msg);
+    return 1;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    ulong addr = 0;
+    int i;
+    fpga_t* fpga;
+
+    if (argc < 2)
+	goto failure;
+
+    if (strncmp(argv[1], "stat", 4) == 0) {		/* status */
+	if (argc == 2) {
+	    for (i = 0; i < fpga_count; i++) {
+		fpga_status (&fpga_list[i]);
+	    }
+	}
+	else if (argc == 3) {
+	    if ((fpga = fpga_get(argv[2])) == 0)
+		goto failure;
+	    fpga_status (fpga);
+	}
+	else
+	    goto failure;
+    }
+    else if (strcmp(argv[1],"load") == 0) {		/* load */
+	if (argc == 3 && fpga_count == 1) {
+	    fpga = &fpga_list[0];
+	}
+	else if (argc == 4) {
+	    if ((fpga = fpga_get(argv[2])) == 0)
+		goto failure;
+	}
+	else
+	    goto failure;
+
+	addr = simple_strtoul(argv[argc-1], NULL, 16);
+
+	printf ("FPGA load %s: addr %08lx: ",
+		fpga->name, addr);
+	fpga_load (fpga, addr, 1);
+
+    }
+    else if (strncmp(argv[1], "rese", 4) == 0) {	/* reset */
+	if (argc == 2 && fpga_count == 1) {
+	    fpga = &fpga_list[0];
+	}
+	else if (argc == 3) {
+	    if ((fpga = fpga_get(argv[2])) == 0)
+		goto failure;
+	}
+	else
+	    goto failure;
+
+	printf ("FPGA reset %s: ", fpga->name);
+	if (fpga_reset(fpga))
+	    printf ("ERROR: Timeout\n");
+	else
+	    printf ("done\n");
+    }
+    else
+	goto failure;
+
+    return 0;
+
+ failure:
+    printf ("Usage:\n%s\n", cmdtp->usage);
+    return 1;
+}
+
+#endif	/* CONFIG_COMMANDS & CFG_CMD_BSP */
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+int fpga_init (void)
+{
+    ulong addr;
+    ulong new_id, old_id = 0;
+    image_header_t *hdr;
+    fpga_t* fpga;
+    int do_load, i, j;
+    char name[16], *s;
+
+    /*
+     *  Port setup for FPGA control
+     */
+    for (i = 0; i < fpga_count; i++) {
+	fpga_control(&fpga_list[i], FPGA_INIT_PORTS);
+    }
+
+    /*
+     * Load FPGA(s): a new net-list is loaded if the FPGA is
+     * empty, Power-on-Reset or the old one is not up-to-date
+     */
+    for (i = 0; i < fpga_count; i++) {
+	fpga = &fpga_list[i];
+	printf ("%s:  ", fpga->name);
+
+	for (j = 0; j < strlen(fpga->name); j++)
+	    name[j] = tolower(fpga->name[j]);
+	name[j] = '\0';
+	sprintf(name, "%s_addr", name);
+	addr = 0;
+	if ((s = getenv(name)) != NULL)
+	    addr = simple_strtoul(s, NULL, 16);
+
+	if (!addr) {
+	    printf ("env. variable %s undefined\n", name);
+	    return 1;
+	}
+
+	hdr = (image_header_t *)addr;
+	if ((new_id = fpga_get_version(fpga, hdr->ih_name)) == -1)
+	    return 1;
+
+	do_load = 1;
+
+	if (!power_on_reset() && fpga_control(fpga, FPGA_DONE_IS_HIGH)) {
+	    old_id = fpga_control(fpga, FPGA_GET_ID);
+	    if (new_id == old_id)
+		do_load = 0;
+	}
+
+	if (do_load) {
+	    printf ("loading ");
+	    fpga_load (fpga, addr, 0);
+	} else {
+	    printf ("loaded (%08lx)\n", old_id);
+	}
+    }
+
+    return 0;
+}
diff --git a/board/smdk2400/u-boot.lds b/board/smdk2400/u-boot.lds
new file mode 100644
index 0000000..8c9c218
--- /dev/null
+++ b/board/smdk2400/u-boot.lds
@@ -0,0 +1,54 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm920t/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/smdk2410/smdk2410.c b/board/smdk2410/smdk2410.c
new file mode 100644
index 0000000..7f983ef
--- /dev/null
+++ b/board/smdk2410/smdk2410.c
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.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 <s3c2410.h>
+
+/* ------------------------------------------------------------------------- */
+
+#define FCLK_SPEED 1
+
+#if FCLK_SPEED==0		/* Fout = 203MHz, Fin = 12MHz for Audio */
+#define M_MDIV	0xC3
+#define M_PDIV	0x4
+#define M_SDIV	0x1
+#elif FCLK_SPEED==1		/* Fout = 202.8MHz */
+#define M_MDIV	0xA1
+#define M_PDIV	0x3
+#define M_SDIV	0x1
+#endif
+
+#define USB_CLOCK 1
+
+#if USB_CLOCK==0
+#define U_M_MDIV	0xA1
+#define U_M_PDIV	0x3
+#define U_M_SDIV	0x1
+#elif USB_CLOCK==1
+#define U_M_MDIV	0x48
+#define U_M_PDIV	0x3
+#define U_M_SDIV	0x2
+#endif
+
+static inline void delay (unsigned long loops)
+{
+	__asm__ volatile ("1:\n"
+	  "subs %0, %1, #1\n"
+	  "bne 1b":"=r" (loops):"0" (loops));
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* to reduce PLL lock time, adjust the LOCKTIME register */
+	rLOCKTIME = 0xFFFFFF;
+
+	/* configure MPLL */
+	rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
+
+	/* some delay between MPLL and UPLL */
+	delay (4000);
+
+	/* configure UPLL */
+	rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
+
+	/* some delay between MPLL and UPLL */
+	delay (8000);
+
+	/* set up the I/O ports */
+	rGPACON = 0x007FFFFF;
+	rGPBCON = 0x00044555;
+	rGPBUP = 0x000007FF;
+	rGPCCON = 0xAAAAAAAA;
+	rGPCUP = 0x0000FFFF;
+	rGPDCON = 0xAAAAAAAA;
+	rGPDUP = 0x0000FFFF;
+	rGPECON = 0xAAAAAAAA;
+	rGPEUP = 0x0000FFFF;
+	rGPFCON = 0x000055AA;
+	rGPFUP = 0x000000FF;
+	rGPGCON = 0xFF95FFBA;
+	rGPGUP = 0x0000FFFF;
+	rGPHCON = 0x002AFAAA;
+	rGPHUP = 0x000007FF;
+
+	/* arch number of SMDK2410-Board */
+	gd->bd->bi_arch_number = 193;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = 0x30000100;
+
+	icache_enable();
+	dcache_enable();
+
+	return 0;
+}
+
+int dram_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	return 0;
+}
diff --git a/board/tqm8xx/flash.c b/board/tqm8xx/flash.c
new file mode 100644
index 0000000..2f74ccc
--- /dev/null
+++ b/board/tqm8xx/flash.c
@@ -0,0 +1,569 @@
+/*
+ * (C) Copyright 2000-2002
+ * 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 <mpc8xx.h>
+
+#ifndef	CFG_ENV_ADDR
+#define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET)
+#endif
+
+flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+	volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	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;
+	}
+
+	/* Static FLASH Bank configuration here - FIXME XXX */
+
+	size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &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_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+
+	if (size_b1 > size_b0) {
+		printf ("## ERROR: "
+			"Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
+			size_b1, size_b1<<20,
+			size_b0, size_b0<<20
+		);
+		flash_info[0].flash_id	= FLASH_UNKNOWN;
+		flash_info[1].flash_id	= FLASH_UNKNOWN;
+		flash_info[0].sector_count	= -1;
+		flash_info[1].sector_count	= -1;
+		flash_info[0].size		= 0;
+		flash_info[1].size		= 0;
+		return (0);
+	}
+
+	/* Remap FLASH according to real size */
+	memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
+	memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
+
+	/* Re-do sizing to get full correct info */
+	size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
+
+#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) {
+		memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
+		memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
+				    BR_MS_GPCM | BR_V;
+
+		/* Re-do sizing to get full correct info */
+		size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
+					  &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[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 {
+		memctl->memc_br1 = 0;		/* invalidate bank */
+
+		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;
+
+	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 & 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_long *addr, flash_info_t *info)
+{
+	short i;
+	ulong value;
+	ulong base = (ulong)addr;
+
+	/* Write auto select command: read Manufacturer ID */
+	addr[0x0555] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+	addr[0x0555] = 0x00900090;
+
+	value = addr[0];
+
+	switch (value) {
+	case AMD_MANUFACT:
+		info->flash_id = FLASH_MAN_AMD;
+		break;
+	case FUJ_MANUFACT:
+		info->flash_id = FLASH_MAN_FUJ;
+		break;
+	default:
+		info->flash_id = FLASH_UNKNOWN;
+		info->sector_count = 0;
+		info->size = 0;
+		return (0);			/* no or unknown flash	*/
+	}
+
+	value = addr[1];			/* device ID		*/
+
+	switch (value) {
+	case AMD_ID_LV400T:
+		info->flash_id += FLASH_AM400T;
+		info->sector_count = 11;
+		info->size = 0x00100000;
+		break;				/* => 1 MB		*/
+
+	case AMD_ID_LV400B:
+		info->flash_id += FLASH_AM400B;
+		info->sector_count = 11;
+		info->size = 0x00100000;
+		break;				/* => 1 MB		*/
+
+	case AMD_ID_LV800T:
+		info->flash_id += FLASH_AM800T;
+		info->sector_count = 19;
+		info->size = 0x00200000;
+		break;				/* => 2 MB		*/
+
+	case AMD_ID_LV800B:
+		info->flash_id += FLASH_AM800B;
+		info->sector_count = 19;
+		info->size = 0x00200000;
+		break;				/* => 2 MB		*/
+
+	case AMD_ID_LV160T:
+		info->flash_id += FLASH_AM160T;
+		info->sector_count = 35;
+		info->size = 0x00400000;
+		break;				/* => 4 MB		*/
+
+	case AMD_ID_LV160B:
+		info->flash_id += FLASH_AM160B;
+		info->sector_count = 35;
+		info->size = 0x00400000;
+		break;				/* => 4 MB		*/
+	case AMD_ID_LV320T:
+		info->flash_id += FLASH_AM320T;
+		info->sector_count = 71;
+		info->size = 0x00800000;
+		break;				/* => 8 MB		*/
+
+	case AMD_ID_LV320B:
+		info->flash_id += FLASH_AM320B;
+		info->sector_count = 71;
+		info->size = 0x00800000;
+		break;				/* => 8 MB		*/
+	default:
+		info->flash_id = FLASH_UNKNOWN;
+		return (0);			/* => no or unknown flash */
+	}
+
+	/* set up sector start address table */
+	switch (value) {
+	case AMD_ID_LV400B:
+	case AMD_ID_LV800B:
+	case AMD_ID_LV160B:
+		/* set sector offsets for bottom boot block type	*/
+		info->start[0] = base + 0x00000000;
+		info->start[1] = base + 0x00008000;
+		info->start[2] = base + 0x0000C000;
+		info->start[3] = base + 0x00010000;
+		for (i = 4; i < info->sector_count; i++) {
+			info->start[i] = base + (i * 0x00020000) - 0x00060000;
+		}
+		break;
+	case AMD_ID_LV400T:
+	case AMD_ID_LV800T:
+	case AMD_ID_LV160T:
+		/* set sector offsets for top boot block type		*/
+		i = info->sector_count - 1;
+		info->start[i--] = base + info->size - 0x00008000;
+		info->start[i--] = base + info->size - 0x0000C000;
+		info->start[i--] = base + info->size - 0x00010000;
+		for (; i >= 0; i--) {
+			info->start[i] = base + i * 0x00020000;
+		}
+		break;
+	case AMD_ID_LV320B:
+		for (i = 0; i < info->sector_count; i++) {
+			info->start[i] = base;
+			/*
+			 * The first 8 sectors are 8 kB,
+			 * all the other ones  are 64 kB
+			 */
+			base += (i < 8)
+				?  2 * ( 8 << 10)
+				:  2 * (64 << 10);
+		}
+		break;
+	case AMD_ID_LV320T:
+		for (i = 0; i < info->sector_count; i++) {
+			info->start[i] = base;
+			/*
+			 * The last 8 sectors are 8 kB,
+			 * all the other ones  are 64 kB
+			 */
+			base += (i < (info->sector_count - 8))
+				?  2 * (64 << 10)
+				:  2 * ( 8 << 10);
+		}
+		break;
+	default:
+		return (0);
+		break;
+	}
+
+	/* 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 long *)(info->start[i]);
+		info->protect[i] = addr[2] & 1;
+	}
+
+	/*
+	 * Prevent writes to uninitialized FLASH.
+	 */
+	if (info->flash_id != FLASH_UNKNOWN) {
+		addr = (volatile unsigned long *)info->start[0];
+
+		*addr = 0x00F000F0;	/* reset bank */
+	}
+
+	return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int	flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+	vu_long *addr = (vu_long*)(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] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+	addr[0x0555] = 0x00800080;
+	addr[0x0555] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect<=s_last; sect++) {
+		if (info->protect[sect] == 0) {	/* not protected */
+			addr = (vu_long*)(info->start[sect]);
+			addr[0] = 0x00300030;
+			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_long*)(info->start[l_sect]);
+	while ((addr[0] & 0x00800080) != 0x00800080) {
+		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 */
+			putc ('.');
+			last = now;
+		}
+	}
+
+DONE:
+	/* reset to read mode */
+	addr = (volatile unsigned long *)info->start[0];
+	addr[0] = 0x00F000F0;	/* reset bank */
+
+	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_long *addr = (vu_long*)(info->start[0]);
+	ulong start;
+	int flag;
+
+	/* 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();
+
+	addr[0x0555] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+	addr[0x0555] = 0x00A000A0;
+
+	*((vu_long *)dest) = data;
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	/* data polling for D7 */
+	start = get_timer (0);
+	while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
+		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+			return (1);
+		}
+	}
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/tqm8xx/load_sernum_ethaddr.c b/board/tqm8xx/load_sernum_ethaddr.c
new file mode 100644
index 0000000..98baf7f
--- /dev/null
+++ b/board/tqm8xx/load_sernum_ethaddr.c
@@ -0,0 +1,105 @@
+/*
+ * (C) Copyright 2000, 2001, 2002
+ * 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 <mpc8xx.h>
+
+/*-----------------------------------------------------------------------
+ * Process Hardware Information Block:
+ *
+ * If we boot on a system fresh from factory, check if the Hardware
+ * Information Block exists and save the information it contains.
+ *
+ * The TQM8xxL / TQM82xx Hardware Information Block is defined as
+ * follows:
+ * - located in first flash bank
+ * - starts at offset 0x0003FFC0
+ * - size 0x00000040
+ *
+ * Internal structure:
+ * - sequence of ASCII character strings
+ * - fields separated by a single space character (0x20)
+ * - last field terminated by NUL character (0x00)
+ * - remaining space filled with NUL characters (0x00)
+ *
+ * Fields in Hardware Information Block:
+ * 1) Module Type
+ * 2) Serial Number
+ * 3) First MAC Address
+ * 4) Number of additional MAC addresses
+ */
+
+void load_sernum_ethaddr (void)
+{
+	unsigned char *hwi;
+	unsigned char  serial [CFG_HWINFO_SIZE];
+	unsigned char  ethaddr[CFG_HWINFO_SIZE];
+	unsigned short ih, is, ie, part;
+
+	hwi = (unsigned char *)(CFG_FLASH_BASE + CFG_HWINFO_OFFSET);
+	ih = is = ie = 0;
+
+	if (*((unsigned long *)hwi) != (unsigned long)CFG_HWINFO_MAGIC) {
+		return;
+	}
+
+	part = 1;
+
+	/* copy serial # / MAC address */
+	while ((hwi[ih] != '\0') && (ih < CFG_HWINFO_SIZE)) {
+		if (hwi[ih] < ' ' || hwi[ih] > '~') { /* ASCII strings! */
+			return;
+		}
+		switch (part) {
+		default:		/* Copy serial # */
+			if (hwi[ih] == ' ') {
+				++part;
+			}
+			serial[is++] = hwi[ih];
+			break;
+		case 3:			/* Copy MAC address */
+			if (hwi[ih] == ' ') {
+				++part;
+				break;
+			}
+			ethaddr[ie++] = hwi[ih];
+			if ((ie % 3) == 2)
+				ethaddr[ie++] = ':';
+			break;
+		}
+		++ih;
+	}
+	serial[is]  = '\0';
+	if (ie && ethaddr[ie-1] == ':')
+		--ie;
+	ethaddr[ie] = '\0';
+
+	/* set serial# and ethaddr if not yet defined */
+	if (getenv("serial#") == NULL) {
+		setenv ("serial#", serial);
+	}
+
+	if (getenv("ethaddr") == NULL) {
+		setenv ("ethaddr", ethaddr);
+	}
+}
diff --git a/board/trab/README.kbd b/board/trab/README.kbd
new file mode 100644
index 0000000..3db00bc
--- /dev/null
+++ b/board/trab/README.kbd
@@ -0,0 +1,44 @@
+
+The TRAB keyboard implementation is similar to that for LWMON and
+R360MPI boards. The only difference concerns key naming. There are 4
+keys on TRAB: 1, 2, 3, 4.
+
+1) The "kbd" command provides information about the current state of
+   the keys. For example,
+
+	TRAB # kbd
+	Keys: 1 0 1 0
+
+   means that keys 1 and 3 are pressed. The keyboard status is also
+   stored in the "keybd" environment variable. In this example we get
+
+	keybd=1010
+
+2) The "preboot" variable is set according to current environment
+   settings and keys pressed. This is an example:
+
+	TRAB # setenv magic_keys XY
+	TRAB # setenv key_magicX 12
+	TRAB # setenv key_cmdX echo ## Keys 1 + 2 pressed ##\;echo
+	TRAB # setenv key_magicY 13
+	TRAB # setenv key_cmdY echo ## Keys 1 + 3 pressed ##\;echo
+
+   Here "magic_keys=XY" means that the "key_magicX" and "key_magicY"
+   variables will be checked for a match. Each variable "key_magic*"
+   defines a set of keys. In the our example, if keys 1 and 3 are
+   pressed during reset, then "key_magicY" matches, so the "preboot"
+   variable will be set to the contents of "key_cmdY":
+
+	preboot=echo ## Keys 1 + 3 pressed ##;echo
+
+3) The TRAB board has optional modem support. When a certain key
+   combination is pressed on the keyboard at power-on, the firmware
+   performs the necessary initialization of the modem and allows for
+   dial-in. The key combination is specified in the
+   "include/configs/trab.h" file. For example:
+
+	#define        CONFIG_MODEM_KEY_MAGIC  "23"
+
+   means that modem will be initialized if and only if both keys 2, 3
+   are pressed. Note that the format of this string is similar to the
+   format of "key_magic*" environment variables described above.
diff --git a/board/trab/trab.c b/board/trab/trab.c
new file mode 100644
index 0000000..3f9b198
--- /dev/null
+++ b/board/trab/trab.c
@@ -0,0 +1,301 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <cmd_bsp.h>
+#include <malloc.h>
+#include <s3c2400.h>
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int key_pressed(void);
+extern void disable_putc(void);
+extern int do_mdm_init; /* defined in common/main.c */
+
+/*
+ * We need a delay of at least 500 us after turning on the VFD clock
+ * before we can read any useful information for the CPLD controlling
+ * the keyboard switches. Let's play safe and wait 5 ms. The problem
+ * is that timers are not available yet, so we use a manually timed
+ * loop.
+ */
+#define KBD_MDELAY	100000	/* 1000 */
+static void mdelay_no_timer (int msec)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int i;
+	int delay = msec * 3;
+
+	for (i = 0; i < delay; i ++) gd->bd->bi_arch_number = 145;
+}
+#endif /* CONFIG_MODEM_SUPPORT */
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init ()
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* memory and cpu-speed are setup before relocation */
+#ifdef CONFIG_TRAB_50MHZ
+	/* change the clock to be 50 MHz 1:1:1 */
+	/* MDIV:0x5c PDIV:4 SDIV:2 */
+	rMPLLCON = 0x5c042;
+	rCLKDIVN = 0;
+#else
+	/* change the clock to be 133 MHz 1:2:4 */
+	/* MDIV:0x7d PDIV:4 SDIV:1 */
+	rMPLLCON = 0x7d041;
+	rCLKDIVN = 3;
+#endif
+
+	/* set up the I/O ports */
+	rPACON = 0x3ffff;
+	rPBCON = 0xaaaaaaaa;
+	rPBUP  = 0xffff;
+	/* INPUT nCTS0 nRTS0 TXD[1] TXD[0] RXD[1] RXD[0]	*/
+	/*  00,    10,      10,      10,      10,      10,      10 	*/
+	rPFCON = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
+#ifdef CONFIG_HWFLOW
+	/* do not pull up RXD0, RXD1, TXD0, TXD1, CTS0, RTS0 */
+	rPFUP  = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
+#else
+	/* do not pull up RXD0, RXD1, TXD0, TXD1 */
+	rPFUP  = (1<<0) | (1<<1) | (1<<2) | (1<<3);
+#endif
+	rPGCON = 0x0;
+	rPGUP  = 0x0;
+	rOPENCR= 0x0;
+
+	/* arch number of SAMSUNG-Board */
+	/* MACH_TYPE_SMDK2400 */
+	/* XXX this isn't really correct, but keep it for now */
+	gd->bd->bi_arch_number = 145;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = 0x0c000100;
+
+#ifdef CONFIG_MODEM_SUPPORT
+	/* This stuff is needed to get interrupts on stop-position
+	 * contact events.
+	 * (Copied from the LCD initialization routine.)
+	 */
+	if (rLCDCON1 == 0)
+	{
+		rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
+		rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
+#if 0
+		rPDCON = (rPDCON & 0xFFFFFF00)| 0x000000AA;
+#endif
+		rLCDCON2 = 0x000DC000;
+		rLCDCON3 = 0x0051000A;
+		rLCDCON4 = 0x00000001;
+		rLCDCON5 = 0x00000440;
+		rLCDCON1 = 0x00000B75;
+	}
+
+	mdelay_no_timer (KBD_MDELAY);
+
+	if (key_pressed()) {
+		disable_putc();	/* modem doesn't understand banner etc */
+		do_mdm_init = 1;
+	}
+#endif	/* CONFIG_MODEM_SUPPORT */
+
+	return 0;
+}
+
+int dram_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+
+/* Maximum key number */
+#define KEYBD_KEY_NUM		4
+
+#define KBD_DATA	(((*(volatile ulong *)0x04020000) >> 16) & 0xF)
+
+static uchar *key_match (ulong);
+
+int misc_init_r (void)
+{
+	ulong kbd_data = KBD_DATA;
+	uchar keybd_env[KEYBD_KEY_NUM + 1];
+	uchar *str;
+	int i;
+
+	for (i = 0; i < KEYBD_KEY_NUM; ++i) {
+		keybd_env[i] = '0' + ((kbd_data >> i) & 1);
+	}
+	keybd_env[i] = '\0';
+	debug ("** Setting keybd=\"%s\"\n", keybd_env);
+	setenv ("keybd", keybd_env);
+
+	str = strdup (key_match (kbd_data));	/* decode keys */
+
+#ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */
+	debug ("** Setting preboot=\"%s\"\n", str);
+	setenv ("preboot", str);	/* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+	if (str != NULL) {
+		free (str);
+	}
+
+	return (0);
+}
+
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static int compare_magic (ulong kbd_data, uchar *str)
+{
+	uchar key_mask;
+
+	debug ("compare_magic: kbd: %04lx  str: \"%s\"\n",kbd_data,str);
+	for (; *str; str++)
+	{
+		uchar c = *str - '1';
+
+		if (c >= KEYBD_KEY_NUM)		/* bad key number */
+			return -1;
+
+		key_mask = 1 << c;
+
+		if (!(kbd_data & key_mask)) {	/* key not pressed */
+			debug ( "compare_magic: "
+				"kbd: %04lx mask: %04lx - key not pressed\n",
+				kbd_data, key_mask );
+			return -1;
+		}
+
+		kbd_data &= ~key_mask;
+	}
+
+	if (kbd_data) {				/* key(s) not released */
+		debug ( "compare_magic: "
+			"kbd: %04lx - key(s) not released\n", kbd_data);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Check if pressed key(s) match magic sequence,
+ * and return the command string associated with that key(s).
+ *
+ * If no key press was decoded, NULL is returned.
+ *
+ * Note: the first character of the argument will be overwritten with
+ * the "magic charcter code" of the decoded key(s), or '\0'.
+ *
+ *
+ * Note: the string points to static environment data and must be
+ * saved before you call any function that modifies the environment.
+ */
+static uchar *key_match (ulong kbd_data)
+{
+	uchar magic[sizeof (kbd_magic_prefix) + 1];
+	uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+	uchar *suffix;
+	uchar *kbd_magic_keys;
+
+	/*
+	 * The following string defines the characters that can pe appended
+	 * to "key_magic" to form the names of environment variables that
+	 * hold "magic" key codes, i. e. such key codes that can cause
+	 * pre-boot actions. If the string is empty (""), then only
+	 * "key_magic" is checked (old behaviour); the string "125" causes
+	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+	 */
+	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+		kbd_magic_keys = "";
+
+	debug ("key_match: magic_keys=\"%s\"\n", kbd_magic_keys);
+
+	/* loop over all magic keys;
+	 * use '\0' suffix in case of empty string
+	 */
+	for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix)
+	{
+		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+
+		debug ("key_match: magic=\"%s\"\n",
+			getenv(magic) ? getenv(magic) : "<UNDEFINED>");
+
+		if (compare_magic(kbd_data, getenv(magic)) == 0)
+		{
+			sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+			debug ("key_match: cmdname %s=\"%s\"\n",
+				cmd_name,
+				getenv (cmd_name) ?
+					getenv (cmd_name) :
+					"<UNDEFINED>");
+			return (getenv (cmd_name));
+		}
+	}
+	debug ("key_match: no match\n");
+	return (NULL);
+}
+#endif							/* CONFIG_PREBOOT */
+
+/* Read Keyboard status */
+int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	ulong kbd_data = KBD_DATA;
+	uchar keybd_env[KEYBD_KEY_NUM + 1];
+	int i;
+
+	puts ("Keys:");
+	for (i = 0; i < KEYBD_KEY_NUM; ++i) {
+		keybd_env[i] = '0' + ((kbd_data >> i) & 1);
+		printf (" %c", keybd_env[i]);
+	}
+	keybd_env[i] = '\0';
+	putc ('\n');
+	setenv ("keybd", keybd_env);
+	return 0;
+}
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int key_pressed(void)
+{
+	return (compare_magic(KBD_DATA, CONFIG_MODEM_KEY_MAGIC) == 0);
+}
+#endif	/* CONFIG_MODEM_SUPPORT */
diff --git a/board/trab/u-boot.lds b/board/trab/u-boot.lds
new file mode 100644
index 0000000..59834af
--- /dev/null
+++ b/board/trab/u-boot.lds
@@ -0,0 +1,63 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm920t/start.o	(.text)
+	  lib_arm/_udivsi3.o	(.text)
+	  lib_arm/_umodsi3.o	(.text)
+	  lib_generic/zlib.o	(.text)
+	  lib_generic/crc32.o	(.text)
+	  lib_generic/string.o	(.text)
+
+	. = env_offset;
+	common/environment.o	(.ppcenv)
+
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/trab/vfd.c b/board/trab/vfd.c
new file mode 100644
index 0000000..1ea483f
--- /dev/null
+++ b/board/trab/vfd.c
@@ -0,0 +1,414 @@
+/*
+ * (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
+ */
+
+/************************************************************************/
+/* ** DEBUG SETTINGS							*/
+/************************************************************************/
+
+/* #define DEBUG	*/
+
+/************************************************************************/
+/* ** HEADER FILES							*/
+/************************************************************************/
+
+#include <config.h>
+#include <common.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <s3c2400.h>
+
+#ifdef CONFIG_VFD
+
+/************************************************************************/
+/* ** CONFIG STUFF -- should be moved to board config file		*/
+/************************************************************************/
+
+/************************************************************************/
+
+#ifndef PAGE_SIZE
+#define	PAGE_SIZE	4096
+#endif
+
+#define ROT	0x09
+#define BLAU	0x0C
+#define VIOLETT	0X0D
+
+ulong vfdbase;
+ulong frame_buf_size;
+#define frame_buf_offs 4
+
+/* taken from armboot/common/vfd.c */
+ulong         adr_vfd_table[112][18][2][4][2];
+unsigned char bit_vfd_table[112][18][2][4][2];
+
+/*
+ * initialize the values for the VFD-grid-control in the framebuffer
+ */
+void init_grid_ctrl(void)
+{
+	ulong adr, grid_cycle;
+	unsigned int bit, display;
+	unsigned char temp, bit_nr;
+
+	for (adr=vfdbase; adr<=(vfdbase+7168); adr+=4) /*clear frame buffer */
+		(*(volatile ulong*)(adr))=0;
+
+	for(display=0;display<=3;display++)
+	{
+		for(grid_cycle=0;grid_cycle<=55;grid_cycle++)
+		{
+			bit = grid_cycle*256*4+(grid_cycle+200)*4+frame_buf_offs+display;
+ 			/* wrap arround if offset (see manual S3C2400) */
+			if (bit>=frame_buf_size*8)
+				bit = bit-(frame_buf_size*8);
+			adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
+			bit_nr = bit%8;
+			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+			temp=(*(volatile unsigned char*)(adr));
+			temp|=(1<<bit_nr);
+			(*(volatile unsigned char*)(adr))=temp;
+
+			if(grid_cycle<55)
+				bit = grid_cycle*256*4+(grid_cycle+201)*4+frame_buf_offs+display;
+			else
+				bit = grid_cycle*256*4+200*4+frame_buf_offs+display-4; 	/* grid nr. 0 */
+			/* wrap arround if offset (see manual S3C2400) */
+			if (bit>=frame_buf_size*8)
+				bit = bit-(frame_buf_size*8);
+			adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
+			bit_nr = bit%8;
+			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+			temp=(*(volatile unsigned char*)(adr));
+			temp|=(1<<bit_nr);
+			(*(volatile unsigned char*)(adr))=temp;
+		}
+	}
+}
+
+/*
+ *create translation table for getting easy the right position in the
+ *physical framebuffer for some x/y-coordinates of the VFDs
+ */
+void create_vfd_table(void)
+{
+	unsigned int vfd_table[112][18][2][4][2];
+	ulong adr;
+	unsigned int x, y, color, display, entry, pixel, bit_nr;
+
+	/*
+	 * Create translation table for Noritake-T119C-VFD-specific
+	 * organized frame-buffer.
+	 * Created is the number of the bit in the framebuffer (the
+	 * first transferred pixel of each frame is bit 0).
+	 */
+	for(y=0;y<=17;y++)   /* Zeile */
+	{
+		for(x=0;x<=111;x++)  /* Spalten */
+		{
+			/*Display 0 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][0][0]=((x%4)*4+y*16+(x/4)*2048);
+			/*Display 0 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][0][0]=((x%4)*4+y*16+(x/4)*2048+512);
+			if(x<=1)
+			{
+				/*Display 0 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1024);
+				/*Display 0 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1024);
+			}
+			else
+			{
+				/*Display 0 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+1024);
+				/*Display 0 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1024);
+			}
+			/*Display 1 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][1][0]=((x%4)*4+y*16+(x/4)*2048+1);
+			/*Display 1 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][1][0]=((x%4)*4+y*16+(x/4)*2048+512+1);
+			if(x<=1)
+			{
+				/*Display 1 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1+1024);
+				/*Display 1 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1+1024);
+			}
+			else
+			{
+				/*Display 1 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+1+1024);
+				/*Display 1 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1+1024);
+			}
+			/*Display 2 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][2][0]=((x%4)*4+y*16+(x/4)*2048+2);
+			/*Display 2 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][2][0]=((x%4)*4+y*16+(x/4)*2048+512+2);
+			if(x<=1)
+			{
+				/*Display 2 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+2+1024);
+				/*Display 2 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+2+1024);
+			}
+			else
+			{
+				/*Display 2 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+2+1024);
+				/*Display 2 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+2+1024);
+			}
+			/*Display 3 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][3][0]=((x%4)*4+y*16+(x/4)*2048+3);
+			/*Display 3 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][3][0]=((x%4)*4+y*16+(x/4)*2048+512+3);
+			if(x<=1)
+			{
+				/*Display 3 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+3+1024);
+				/*Display 3 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+3+1024);
+			}
+			else
+			{
+				/*Display 3 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+3+1024);
+				/*Display 3 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+3+1024);
+			}
+		}
+	}
+
+	/*
+	 * Create translation table for Noritake-T119C-VFD-specific
+	 * organized frame-buffer
+	 * Create table with entries for physical byte adresses and
+	 * bit-number within the byte
+	 * from table with bit-numbers within the total framebuffer
+	 */
+	for(y=0;y<=17;y++)
+	{
+		for(x=0;x<=111;x++)
+		{
+			for(color=0;color<=1;color++)
+			{
+				for(display=0;display<=3;display++)
+				{
+					for(entry=0;entry<=1;entry++)
+					{
+						pixel  = vfd_table[x][y][color][display][entry] + frame_buf_offs;
+						 /*
+						  * wrap arround if offset
+						  * (see manual S3C2400)
+						  */
+						if (pixel>=frame_buf_size*8)
+							pixel = pixel-(frame_buf_size*8);
+						adr    = vfdbase+(pixel/32)*4+(3-(pixel%32)/8);
+						bit_nr = pixel%8;
+						bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+						adr_vfd_table[x][y][color][display][entry] = adr;
+						bit_vfd_table[x][y][color][display][entry] = bit_nr;
+					}
+				}
+			}
+		}
+	}
+}
+
+/*
+ * Set/clear pixel of the VFDs
+ */
+void set_vfd_pixel(unsigned char x, unsigned char y, unsigned char color, unsigned char display, unsigned char value)
+{
+	ulong adr;
+	unsigned char bit_nr, temp;
+
+	if (value!=0)
+	{
+		/* Pixel-Eintrag Nr. 1 */
+		adr = adr_vfd_table[x][y][color][display][0];
+		/* Pixel-Eintrag Nr. 1 */
+		bit_nr = bit_vfd_table[x][y][color][display][0];
+		temp=(*(volatile unsigned char*)(adr));
+		temp|=1<<bit_nr;
+		(*(volatile unsigned char*)(adr))=temp;
+
+		/* Pixel-Eintrag Nr. 2 */
+		adr = adr_vfd_table[x][y][color][display][1];
+		/* Pixel-Eintrag Nr. 2 */
+		bit_nr = bit_vfd_table[x][y][color][display][1];
+		temp=(*(volatile unsigned char*)(adr));
+		temp|=1<<bit_nr;
+		(*(volatile unsigned char*)(adr))=temp;
+	}
+	else
+	{
+		/* Pixel-Eintrag Nr. 1 */
+		adr = adr_vfd_table[x][y][color][display][0];
+		/* Pixel-Eintrag Nr. 1 */
+		bit_nr = bit_vfd_table[x][y][color][display][0];
+		temp=(*(volatile unsigned char*)(adr));
+		temp&=~(1<<bit_nr);
+		(*(volatile unsigned char*)(adr))=temp;
+
+		/* Pixel-Eintrag Nr. 2 */
+		adr = adr_vfd_table[x][y][color][display][1];
+		/* Pixel-Eintrag Nr. 2 */
+		bit_nr = bit_vfd_table[x][y][color][display][1];
+		temp=(*(volatile unsigned char*)(adr));
+		temp&=~(1<<bit_nr);
+		(*(volatile unsigned char*)(adr))=temp;
+	}
+}
+
+/*
+ * transfer image from BMP-File
+ */
+void transfer_pic(int display, unsigned char *adr, int height, int width)
+{
+	int x, y;
+	unsigned char temp;
+
+	for (; height > 0; height -= 18)
+	{
+		if (height > 18)
+			y = 18;
+		else
+			y = height;
+		for (; y > 0; y--)
+		{
+			for (x = 0; x < width; x += 2)
+			{
+				temp = *adr++;
+				set_vfd_pixel(x, y-1, 0, display, 0);
+				set_vfd_pixel(x, y-1, 1, display, 0);
+				if ((temp >> 4) == BLAU)
+					set_vfd_pixel(x, y-1, 0, display, 1);
+				else if ((temp >> 4) == ROT)
+					set_vfd_pixel(x, y-1, 1, display, 1);
+				else if ((temp >> 4) == VIOLETT)
+				{
+					set_vfd_pixel(x, y-1, 0, display, 1);
+					set_vfd_pixel(x, y-1, 1, display, 1);
+				}
+				set_vfd_pixel(x+1, y-1, 0, display, 0);
+				set_vfd_pixel(x+1, y-1, 1, display, 0);
+				if ((temp & 0x0F) == BLAU)
+					set_vfd_pixel(x+1, y-1, 0, display, 1);
+				else if ((temp & 0x0F) == ROT)
+					set_vfd_pixel(x+1, y-1, 1, display, 1);
+				else if ((temp & 0x0F) == VIOLETT)
+				{
+					set_vfd_pixel(x+1, y-1, 0, display, 1);
+					set_vfd_pixel(x+1, y-1, 1, display, 1);
+				}
+			}
+		}
+		display++;
+		if (display > 3)
+			display = 0;
+	}
+}
+
+/*
+ * initialize LCD-Controller of the S3C2400 for using VFDs
+ */
+int drv_vfd_init(void)
+{
+	ulong palette;
+
+	DECLARE_GLOBAL_DATA_PTR;
+
+	vfdbase = gd->fb_base;
+	create_vfd_table();
+	init_grid_ctrl();
+
+	/*
+	 * Hinweis: Der Framebuffer ist um genau ein Nibble verschoben
+	 * Das erste angezeigte Pixel wird aus dem zweiten Nibble geholt
+	 * das letzte angezeigte Pixel wird aus dem ersten Nibble geholt
+	 * (wrap around)
+	 * see manual S3C2400
+	 */
+	/* frame buffer startadr */
+	rLCDSADDR1 = vfdbase >> 1;
+ 	/* frame buffer endadr */
+	rLCDSADDR2 = (vfdbase + frame_buf_size) >> 1;
+	rLCDSADDR3 = ((256/4));
+
+	/* Port-Pins als LCD-Ausgang */
+	rPCCON =   (rPCCON & 0xFFFFFF00)| 0x000000AA;
+	/* Port-Pins als LCD-Ausgang */
+	rPDCON =   (rPDCON & 0xFFFFFF03)| 0x000000A8;
+#ifdef WITH_VFRAME
+	/* mit VFRAME zum Messen */
+	rPDCON =   (rPDCON & 0xFFFFFF00)| 0x000000AA;
+#endif
+
+	rLCDCON2 = 0x000DC000;
+	rLCDCON3 = 0x0051000A;
+	rLCDCON4 = 0x00000001;
+	rLCDCON5 = 0x00000440;
+	rLCDCON1 = 0x00000B75;
+
+	debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
+	debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
+	debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
+
+	for(palette=0;palette<=15;palette++)
+		(*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
+	for(palette=16;palette<=255;palette++)
+		(*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;
+
+	return 0;
+}
+
+/************************************************************************/
+/* ** ROM capable initialization part - needed to reserve FB memory	*/
+/************************************************************************/
+
+/*
+ * This is called early in the system initialization to grab memory
+ * for the VFD controller.
+ *
+ * Note that this is running from ROM, so no write access to global data.
+ */
+ulong vfd_setmem (ulong addr)
+{
+	ulong size;
+
+	/* MAGIC */
+	frame_buf_size = (256*4*56)/8;
+
+	/* Round up to nearest full page */
+	size = (frame_buf_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+
+	debug ("Reserving %ldk for VFD Framebuffer at: %08lx\n", size>>10, addr);
+
+	return (size);
+}
+
+#endif /* CONFIG_VFD */
diff --git a/board/utx8245/utx8245.c b/board/utx8245/utx8245.c
new file mode 100644
index 0000000..249862a
--- /dev/null
+++ b/board/utx8245/utx8245.c
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2002
+ * Gregory E. Allen, gallen@arlut.utexas.edu
+ * Matthew E. Karger, karger@arlut.utexas.edu
+ * Applied Research Laboratories, The University of Texas at Austin
+ *
+ * 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 <mpc824x.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define	SAVE_SZ	32
+
+
+int checkboard(void)
+{
+	ulong busfreq  = get_bus_freq(0);
+	char  buf[32];
+
+	printf("Board: UTX8245 Local Bus at %s MHz\n", strmhz(buf, busfreq));
+	return 0;
+}
+
+
+long int initdram(int board_type)
+{
+#if 1
+	int				i, cnt;
+	volatile uchar	*base =	CFG_SDRAM_BASE;
+	volatile ulong	*addr;
+	ulong			save[SAVE_SZ];
+	ulong			val, ret  = 0;
+
+	for (i=0; i<SAVE_SZ; i++)	{save[i] = 0;}		/* clear table */
+
+	for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1)
+	{
+		addr = (volatile ulong *)base + cnt;
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	addr = (volatile ulong *)base;
+	save[i] = *addr;
+	*addr = 0;
+
+	if (*addr != 0)
+	{
+		*addr = save[i];
+		goto Done;
+	}
+
+	for (cnt = 1; cnt < CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1)
+	{
+		addr = (volatile ulong *)base + cnt;
+		val = *addr;
+		*addr = save[--i];
+		if (val != ~cnt)
+		{
+			ulong new_bank0_end = cnt * sizeof(long) - 1;
+			ulong mear1  = mpc824x_mpc107_getreg(MEAR1);
+			ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+			mear1 =  (mear1  & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+			emear1 = (emear1 & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+			mpc824x_mpc107_setreg(MEAR1,  mear1);
+			mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+			ret = cnt * sizeof(long);
+			goto Done;
+		}
+	}
+
+	ret = CFG_MAX_RAM_SIZE;
+Done:
+	return ret;
+#else
+	return (CFG_MAX_RAM_SIZE);
+#endif
+
+}
+
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+
+static struct pci_config_table pci_utx8245_config_table[] = {
+#ifndef CONFIG_PCI_PNP
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_FIREWIRE_IOADDR,
+				       PCI_FIREWIRE_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+#endif /*CONFIG_PCI_PNP*/
+	{ }
+};
+
+
+static void pci_utx8245_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	if (PCI_DEV(dev) == 11)
+		/* assign serial interrupt line 9 (int25) to FireWire */
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 25);
+
+	else if (PCI_DEV(dev) == 12)
+		/* assign serial interrupt line 8 (int24) to Ethernet */
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 24);
+}
+
+static struct pci_controller utx8245_hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_utx8245_config_table,
+	fixup_irq: pci_utx8245_fixup_irq,
+	write_byte: pci_hose_write_config_byte
+#endif /*CONFIG_PCI_PNP*/
+};
+
+void pci_init (void)
+{
+	pci_mpc824x_init(&utx8245_hose);
+
+	icache_enable();
+}
+
diff --git a/board/w7o/flash.c b/board/w7o/flash.c
new file mode 100644
index 0000000..0048476
--- /dev/null
+++ b/board/w7o/flash.c
@@ -0,0 +1,941 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *  Based on code by:
+ * 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 <ppc4xx.h>
+#include <asm/processor.h>
+
+#include <watchdog.h>
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips    */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word8(flash_info_t *info, ulong dest, ulong data);
+static int write_word32 (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+    int i;
+    unsigned long size_b0, base_b0;
+    unsigned long size_b1, base_b1;
+
+    /* Init: no FLASHes known */
+    for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+        flash_info[i].flash_id = FLASH_UNKNOWN;
+    }
+
+    /* Get Size of Boot and Main Flashes */
+    size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &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);
+        return 0;
+    }
+    size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+    if (flash_info[1].flash_id == FLASH_UNKNOWN) {
+        printf ("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
+            size_b1, size_b1<<20);
+        return 0;
+    }
+
+    /* Calculate base addresses */
+    base_b0 = -size_b0;
+    base_b1 = -size_b1;
+
+    /* Setup offsets for Boot Flash */
+    flash_get_offsets (base_b0, &flash_info[0]);
+
+    /* Protect board level data */
+    (void)flash_protect(FLAG_PROTECT_SET,
+			base_b0,
+			flash_info[0].start[1] - 1,
+			&flash_info[0]);
+
+
+    /* Monitor protection ON by default */
+    (void)flash_protect(FLAG_PROTECT_SET,
+                        base_b0 + size_b0 - CFG_MONITOR_LEN,
+                        base_b0 + size_b0 - 1,
+                        &flash_info[0]);
+
+    /* Protect the FPGA image */
+    (void)flash_protect(FLAG_PROTECT_SET,
+                        FLASH_BASE1_PRELIM,
+                        FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN - 1,
+                        &flash_info[1]);
+
+    /* Protect the default boot image */
+    (void)flash_protect(FLAG_PROTECT_SET,
+                        FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN,
+                        FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN + 0x600000 - 1,
+                        &flash_info[1]);
+
+    /* Setup offsets for Main Flash */
+    flash_get_offsets (FLASH_BASE1_PRELIM, &flash_info[1]);
+
+    return (size_b0 + size_b1);
+} /* end flash_init() */
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+    int i;
+
+    /* set up sector start address table - FOR BOOT ROM ONLY!!! */
+    if ((info->flash_id & FLASH_TYPEMASK)  == FLASH_AM040) {
+        for (i = 0; i < info->sector_count; i++)
+            info->start[i] = base + (i * 0x00010000);
+    }
+} /* end flash_get_offsets() */
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+    int k;
+    int size;
+    int erased;
+    volatile unsigned long *flash;
+
+    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 ("1 x AMD ");    break;
+	case FLASH_MAN_STM:	printf ("1 x STM ");	break;
+        case FLASH_MAN_INTEL:   printf ("2 x Intel ");  break;
+        default:                printf ("Unknown Vendor ");
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_AM040:
+	    if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
+            	printf ("AM29LV040 (4096 Kbit, uniform sector size)\n");
+	    else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
+            	printf ("M29W040B (4096 Kbit, uniform block size)\n");
+	    else
+            	printf ("UNKNOWN 29x040x (4096 Kbit, uniform sector size)\n");
+            break;
+        case FLASH_28F320J3A:
+            printf ("28F320J3A (32 Mbit = 128K x 32)\n");
+            break;
+        case FLASH_28F640J3A:
+            printf ("28F640J3A (64 Mbit = 128K x 64)\n");
+            break;
+        case FLASH_28F128J3A:
+            printf ("28F128J3A (128 Mbit = 128K x 128)\n");
+            break;
+        default:
+            printf ("Unknown Chip Type\n");
+    }
+
+    if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) {
+    	printf ("  Size: %ld KB in %d Blocks\n",
+        	info->size >> 10, info->sector_count);
+    } else {
+    	printf ("  Size: %ld KB in %d Sectors\n",
+        	info->size >> 10, info->sector_count);
+    }
+
+    printf ("  Sector Start Addresses:");
+    for (i=0; i<info->sector_count; ++i) {
+        /*
+         * Check if whole sector is erased
+         */
+        if (i != (info->sector_count-1))
+            size = info->start[i+1] - info->start[i];
+        else
+            size = info->start[0] + info->size - info->start[i];
+        erased = 1;
+        flash = (volatile unsigned long *)info->start[i];
+        size = size >> 2;        /* divide by 4 for longword access */
+        for (k=0; k<size; k++)
+        {
+            if (*flash++ != 0xffffffff)
+            {
+                erased = 0;
+                break;
+            }
+        }
+
+        if ((i % 5) == 0)
+            printf ("\n   ");
+        printf (" %08lX%s%s",
+            info->start[i],
+            erased ? " E" : "  ",
+            info->protect[i] ? "RO " : "   "
+        );
+    }
+    printf ("\n");
+} /* end flash_print_info() */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+    short i;
+    ulong base = (ulong)addr;
+
+    /* Setup default type */
+    info->flash_id = FLASH_UNKNOWN;
+    info->sector_count =0;
+    info->size = 0;
+
+    /* Test for Boot Flash */
+    if (base == FLASH_BASE0_PRELIM) {
+        unsigned char value;
+        volatile unsigned char * addr2 = (unsigned char *)addr;
+
+        /* Write auto select command: read Manufacturer ID */
+        *(addr2 + 0x555) = 0xaa;
+        *(addr2 + 0x2aa) = 0x55;
+        *(addr2 + 0x555) = 0x90;
+
+        /* Manufacture ID */
+        value = *addr2;
+        switch (value) {
+            case (unsigned char)AMD_MANUFACT:
+                info->flash_id = FLASH_MAN_AMD;
+                break;
+	    case (unsigned char)STM_MANUFACT:
+		info->flash_id = FLASH_MAN_STM;
+		break;
+            default:
+                *addr2 = 0xf0;              /* no or unknown flash  */
+                return 0;
+        }
+
+        /* Device ID */
+        value = *(addr2 + 1);
+        switch (value) {
+            case (unsigned char)AMD_ID_LV040B:
+	    case (unsigned char)STM_ID_29W040B:
+                info->flash_id += FLASH_AM040;
+                info->sector_count = 8;
+                info->size = 0x00080000;
+                break;                       /* => 512Kb */
+            default:
+                *addr2 = 0xf0;               /* => no or unknown flash */
+                return 0;
+        }
+    }
+    else { /* MAIN Flash */
+        unsigned long value;
+        volatile unsigned long * addr2 = (unsigned long *)addr;
+
+        /* Write auto select command: read Manufacturer ID */
+        *addr2 = 0x90909090;
+
+        /* Manufacture ID */
+        value = *addr2;
+        switch (value) {
+            case (unsigned long)INTEL_MANUFACT:
+                info->flash_id = FLASH_MAN_INTEL;
+                break;
+            default:
+                *addr2 = 0xff;              /* no or unknown flash  */
+                return 0;
+        }
+
+        /* Device ID - This shit is interleaved... */
+        value = *(addr2 + 1);
+        switch (value) {
+            case (unsigned long)INTEL_ID_28F320J3A:
+                info->flash_id += FLASH_28F320J3A;
+                info->sector_count = 32;
+                info->size = 0x00400000 * 2;
+                break;                       /* => 2 X 4 MB */
+            case (unsigned long)INTEL_ID_28F640J3A:
+                info->flash_id += FLASH_28F640J3A;
+                info->sector_count = 64;
+                info->size = 0x00800000 * 2;
+                break;                       /* => 2 X 8 MB */
+            case (unsigned long)INTEL_ID_28F128J3A:
+                info->flash_id += FLASH_28F128J3A;
+                info->sector_count = 128;
+                info->size = 0x01000000 * 2;
+                break;                       /* => 2 X 16 MB */
+            default:
+                *addr2 = 0xff;               /* => no or unknown flash */
+        }
+    }
+
+    /* Make sure we don't exceed CFG_MAX_FLASH_SECT */
+    if (info->sector_count > CFG_MAX_FLASH_SECT) {
+        printf ("** ERROR: sector count %d > max (%d) **\n",
+                info->sector_count, CFG_MAX_FLASH_SECT);
+        info->sector_count = CFG_MAX_FLASH_SECT;
+    }
+
+    /* set up sector start address table */
+    switch (info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_AM040:
+            for (i = 0; i < info->sector_count; i++)
+                info->start[i] = base + (i * 0x00010000);
+            break;
+        case FLASH_28F320J3A:
+        case FLASH_28F640J3A:
+        case FLASH_28F128J3A:
+            for (i = 0; i < info->sector_count; i++)
+                info->start[i] = base + (i * 0x00020000 * 2); /* 2 Banks */
+            break;
+    }
+
+    /* Test for Boot Flash */
+    if (base == FLASH_BASE0_PRELIM) {
+        volatile unsigned char *addr2;
+        /* check for protected sectors */
+        for (i = 0; i < info->sector_count; i++) {
+            /* read sector protection at sector address, (AX .. A0) = 0x02 */
+            /* D0 = 1 if protected */
+            addr2 = (volatile unsigned char *)(info->start[i]);
+            info->protect[i] = *(addr2 + 2) & 1;
+        }
+
+        /* Restore read mode */
+        *(unsigned char *)base = 0xF0;       /* Reset NORMAL Flash */
+    }
+    else { /* Main Flash */
+        volatile unsigned long *addr2;
+        /* check for protected sectors */
+        for (i = 0; i < info->sector_count; i++) {
+            /* read sector protection at sector address, (AX .. A0) = 0x02 */
+            /* D0 = 1 if protected */
+            addr2 = (volatile unsigned long *)(info->start[i]);
+            info->protect[i] = *(addr2 + 2) & 0x1;
+        }
+
+        /* Restore read mode */
+        *(unsigned long *)base = 0xFFFFFFFF; /* Reset  Flash */
+    }
+
+    return (info->size);
+} /* end flash_get_size() */
+
+/*-----------------------------------------------------------------------
+ */
+
+static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
+{
+    int i;
+
+    volatile uchar *vaddr =  (uchar *)addr;
+
+    /* Loop X times */
+    for (i = 1; i <= (100 * tout); i++) {    /* Wait up to tout ms */
+        udelay(10);
+        /* Pause 10 us */
+
+        /* Check for completion */
+        if ((vaddr[0] & 0x80) == (cmp_val & 0x80)) {
+            return 0;
+        }
+
+        /* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */
+        if (!(i % 110000))
+            putc('.');
+
+        /* Kick the dog if needed */
+        WATCHDOG_RESET();
+    }
+
+    return 1;
+} /* wait_for_DQ7() */
+
+/*-----------------------------------------------------------------------
+ */
+
+static int flash_erase8(flash_info_t *info, int s_first, int s_last)
+{
+    int tcode, rcode = 0;
+    volatile uchar *addr = (uchar *)(info->start[0]);
+    volatile uchar *sector_addr;
+    int flag, prot, sect;
+
+    /* Validate arguments */
+    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;
+    }
+
+    /* Check for KNOWN flash type */
+    if (info->flash_id == FLASH_UNKNOWN) {
+        printf ("Can't erase unknown flash type - aborted\n");
+        return 1;
+    }
+
+    /* Check for protected sectors */
+    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++) {
+        if (info->protect[sect] == 0) {      /* not protected */
+            sector_addr = (uchar *)(info->start[sect]);
+
+    		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
+		    printf("Erasing block %p\n", sector_addr);
+		else
+		    printf("Erasing sector %p\n", sector_addr);
+
+            /* Disable interrupts which might cause Flash to timeout */
+            flag = disable_interrupts();
+
+            *(addr + 0x555) = (uchar)0xAA;
+            *(addr + 0x2aa) = (uchar)0x55;
+            *(addr + 0x555) = (uchar)0x80;
+            *(addr + 0x555) = (uchar)0xAA;
+            *(addr + 0x2aa) = (uchar)0x55;
+            *sector_addr = (uchar)0x30;      /* sector erase */
+
+            /*
+             * Wait for each sector to complete, it's more
+             * reliable.  According to AMD Spec, you must
+             * issue all erase commands within a specified
+             * timeout.  This has been seen to fail, especially
+             * if printf()s are included (for debug)!!
+             * Takes up to 6 seconds.
+             */
+            tcode  = wait_for_DQ7((ulong)sector_addr, 0x80, 6000);
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            /* Make sure we didn't timeout */
+            if (tcode) {
+                printf ("Timeout\n");
+                rcode = 1;
+            }
+        }
+    }
+
+    /* wait at least 80us - let's wait 1 ms */
+    udelay (1000);
+
+    /* reset to read mode */
+    addr = (uchar *)info->start[0];
+    *addr = (uchar)0xF0;                     /* reset bank */
+
+    printf (" done\n");
+    return rcode;
+} /* end flash_erase8() */
+
+static int flash_erase32(flash_info_t *info, int s_first, int s_last)
+{
+    int flag, sect;
+    ulong start, now, last;
+    int prot = 0;
+
+    /* Validate arguments */
+    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;
+    }
+
+    /* Check for KNOWN flash type */
+    if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
+        printf ("Can erase only Intel flash types - aborted\n");
+        return 1;
+    }
+
+    /* Check for protected sectors */
+    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 = get_timer (0);
+    last  = start;
+    /* Start erase on unprotected sectors */
+    for (sect = s_first; sect <= s_last; sect++) {
+        WATCHDOG_RESET();
+        if (info->protect[sect] == 0) {      /* not protected */
+            vu_long *addr = (vu_long *)(info->start[sect]);
+            unsigned long status;
+
+            /* Disable interrupts which might cause a timeout here */
+            flag = disable_interrupts();
+
+            *addr = 0x00500050;              /* clear status register */
+            *addr = 0x00200020;              /* erase setup */
+            *addr = 0x00D000D0;              /* erase confirm */
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            /* Wait at least 80us - let's wait 1 ms */
+            udelay (1000);
+
+            while (((status = *addr) & 0x00800080) != 0x00800080) {
+                if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                    printf ("Timeout\n");
+                    *addr = 0x00B000B0;      /* suspend erase      */
+                    *addr = 0x00FF00FF;      /* reset to read mode */
+                    return 1;
+                }
+
+                /* show that we're waiting */
+                if ((now - last) > 990) {   /* every second */
+                    putc ('.');
+                    last = now;
+                }
+            }
+            *addr = 0x00FF00FF;              /* reset to read mode */
+        }
+    }
+    printf (" done\n");
+    return 0;
+} /* end flash_erase32() */
+
+int flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+    if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
+        return flash_erase8(info, s_first, s_last);
+    else
+        return flash_erase32(info, s_first, s_last);
+} /* end flash_erase() */
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong cp, wp, data;
+    ulong start;
+    int i, l, rc;
+
+    start = get_timer (0);
+
+    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_word8(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_word8(info, wp, data)) != 0) {
+            return (rc);
+        }
+        wp  += 4;
+        cnt -= 4;
+        if (get_timer(start) > 1000) {   /* every second */
+           WATCHDOG_RESET();
+           putc ('.');
+           start = get_timer(0);
+        }
+    }
+
+    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_word8(info, wp, data));
+} /* end write_buff8() */
+
+#define	FLASH_WIDTH	4	/* flash bus width in bytes */
+static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+	ulong cp, wp, data;
+	int i, l, rc;
+	ulong start;
+
+	start = get_timer (0);
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		return 4;
+	}
+
+	wp = (addr & ~(FLASH_WIDTH-1));	/* get lower FLASH_WIDTH 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<FLASH_WIDTH && cnt>0; ++i) {
+			data = (data << 8) | *src++;
+			--cnt;
+			++cp;
+		}
+		for (; cnt==0 && i<FLASH_WIDTH; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *)cp);
+		}
+
+		if ((rc = write_word32(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += FLASH_WIDTH;
+	}
+
+	/*
+	 * handle FLASH_WIDTH aligned part
+	 */
+	while (cnt >= FLASH_WIDTH) {
+		data = 0;
+		for (i=0; i<FLASH_WIDTH; ++i) {
+			data = (data << 8) | *src++;
+		}
+		if ((rc = write_word32(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp  += FLASH_WIDTH;
+		cnt -= FLASH_WIDTH;
+          if (get_timer(start) > 990) {   /* every second */
+			putc ('.');
+			start = get_timer(0);
+		}
+	}
+
+	if (cnt == 0) {
+		return (0);
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i=0, cp=wp; i<FLASH_WIDTH && cnt>0; ++i, ++cp) {
+		data = (data << 8) | *src++;
+		--cnt;
+	}
+	for (; i<FLASH_WIDTH; ++i, ++cp) {
+		data = (data << 8) | (*(uchar *)cp);
+	}
+
+	return (write_word32(info, wp, data));
+} /* write_buff32() */
+
+int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    int retval;
+
+    if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
+        retval = write_buff8(info, src, addr, cnt);
+    else
+        retval = write_buff32(info, src, addr, cnt);
+
+    return retval;
+} /* end write_buff() */
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+static int write_word8(flash_info_t *info, ulong dest, ulong data)
+{
+    volatile uchar *addr2 = (uchar *)(info->start[0]);
+    volatile uchar *dest2 = (uchar *)dest;
+    volatile uchar *data2 = (uchar *)&data;
+    int flag;
+    int i, tcode, rcode = 0;
+
+    /* Check if Flash is (sufficently) erased */
+    if ((*((volatile uchar *)dest) &
+        (uchar)data) != (uchar)data) {
+        return (2);
+    }
+
+    for (i=0; i < (4 / sizeof(uchar)); i++) {
+        /* Disable interrupts which might cause a timeout here */
+        flag = disable_interrupts();
+
+        *(addr2 + 0x555) = (uchar)0xAA;
+        *(addr2 + 0x2aa) = (uchar)0x55;
+        *(addr2 + 0x555) = (uchar)0xA0;
+
+        dest2[i] = data2[i];
+
+        /* Wait for write to complete, up to 1ms */
+        tcode = wait_for_DQ7((ulong)&dest2[i], data2[i], 1);
+
+        /* re-enable interrupts if necessary */
+        if (flag)
+            enable_interrupts();
+
+        /* Make sure we didn't timeout */
+        if (tcode) {
+            rcode = 1;
+        }
+    }
+
+    return rcode;
+} /* end write_word8() */
+
+static int write_word32(flash_info_t *info, ulong dest, ulong data)
+{
+    vu_long *addr = (vu_long *)dest;
+    ulong status;
+    ulong start;
+    int flag;
+
+    /* 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;                      /* write setup */
+    *addr = data;
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+        enable_interrupts();
+
+    start = get_timer (0);
+
+    while (((status = *addr) & 0x00800080) != 0x00800080) {
+        WATCHDOG_RESET();
+        if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+            *addr = 0x00FF00FF;              /* restore read mode */
+            return (1);
+        }
+    }
+
+    *addr = 0x00FF00FF;                      /* restore read mode */
+
+    return (0);
+} /* end write_word32() */
+
+
+static int _flash_protect(flash_info_t *info, long sector)
+{
+    int i;
+    int flag;
+    ulong status;
+    int rcode = 0;
+    volatile long *addr = (unsigned long *)sector;
+
+    switch(info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_28F320J3A:
+        case FLASH_28F640J3A:
+        case FLASH_28F128J3A:
+            /* Disable interrupts which might cause Flash to timeout */
+            flag = disable_interrupts();
+
+            /* Issue command */
+            *addr = 0x00500050L;             /* Clear the status register */
+            *addr = 0x00600060L;             /* Set lock bit setup */
+            *addr = 0x00010001L;             /* Set lock bit confirm */
+
+            /* Wait for command completion */
+            for (i = 0; i < 10; i++) {       /* 75us timeout, wait 100us */
+                udelay(10);
+                if ((*addr & 0x00800080L) == 0x00800080L)
+                    break;
+            }
+
+            /* Not successful? */
+            status = *addr;
+            if (status != 0x00800080L) {
+                printf("Protect %x sector failed: %x\n",
+                       (uint)sector, (uint)status);
+                rcode = 1;
+            }
+
+            /* Restore read mode */
+            *addr = 0x00ff00ffL;
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            break;
+        case FLASH_AM040:                    /* No soft sector protection */
+            break;
+    }
+
+    /* Turn protection on for this sector */
+    for (i = 0; i < info->sector_count; i++) {
+        if (info->start[i] == sector) {
+            info->protect[i] = 1;
+            break;
+        }
+    }
+
+    return rcode;
+} /* end _flash_protect() */
+
+static int _flash_unprotect(flash_info_t *info, long sector)
+{
+    int i;
+    int flag;
+    ulong status;
+    int rcode = 0;
+    volatile long *addr = (unsigned long *)sector;
+
+    switch(info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_28F320J3A:
+        case FLASH_28F640J3A:
+        case FLASH_28F128J3A:
+            /* Disable interrupts which might cause Flash to timeout */
+            flag = disable_interrupts();
+
+            *addr = 0x00500050L;             /* Clear the status register */
+            *addr = 0x00600060L;             /* Clear lock bit setup */
+            *addr = 0x00D000D0L;             /* Clear lock bit confirm */
+
+            /* Wait for command completion */
+            for (i = 0; i < 80 ; i++) {      /* 700ms timeout, wait 800 */
+                udelay(10000);               /* Delay 10ms */
+                if ((*addr & 0x00800080L) == 0x00800080L)
+                    break;
+            }
+
+            /* Not successful? */
+            status = *addr;
+            if (status != 0x00800080L) {
+                printf("Un-protect %x sector failed: %x\n",
+                       (uint)sector, (uint)status);
+                *addr = 0x00ff00ffL;
+                rcode = 1;
+            }
+
+            /* restore read mode */
+            *addr = 0x00ff00ffL;
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            break;
+        case FLASH_AM040:                    /* No soft sector protection */
+            break;
+    }
+
+    /*
+     * Fix Intel's little red wagon.  Reprotect
+     * sectors that were protected before we undid
+     * protection on a specific sector.
+     */
+    for (i = 0; i < info->sector_count; i++) {
+        if (info->start[i] != sector) {
+            if (info->protect[i]) {
+                if (_flash_protect(info, info->start[i]))
+                    rcode = 1;
+	    }
+        }
+        else /* Turn protection off for this sector */
+            info->protect[i] = 0;
+    }
+
+    return rcode;
+} /* end _flash_unprotect() */
+
+
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+    int rcode;
+
+    if (prot)
+        rcode = _flash_protect(info, info->start[sector]);
+    else
+        rcode = _flash_unprotect(info, info->start[sector]);
+
+    return rcode;
+} /* end flash_real_protect() */
+
+/*-----------------------------------------------------------------------
+ */
+
diff --git a/board/w7o/fpga.c b/board/w7o/fpga.c
new file mode 100644
index 0000000..e84123b
--- /dev/null
+++ b/board/w7o/fpga.c
@@ -0,0 +1,380 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
+ *  and
+ * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
+ *
+ * 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 <config.h>
+#include <common.h>
+#include "w7o.h"
+#include <asm/processor.h>
+#include "errors.h"
+
+static void
+fpga_img_write(unsigned long *src, unsigned long len, unsigned short *daddr)
+{
+    unsigned long i;
+    volatile unsigned long val;
+    volatile unsigned short *dest = daddr;	/* volatile-bypass optimizer */
+
+    for (i = 0; i < len; i++, src++) {
+        val = *src;
+        *dest = (unsigned short)((val & 0xff000000L) >> 16);
+        *dest = (unsigned short)((val & 0x00ff0000L) >> 8);
+        *dest = (unsigned short)(val & 0x0000ff00L);
+        *dest = (unsigned short)((val & 0x000000ffL) << 8);
+    }
+
+    /* Terminate programming with 4 C clocks */
+    dest = daddr;
+    val = *(unsigned short *)dest;
+    val = *(unsigned short *)dest;
+    val = *(unsigned short *)dest;
+    val = *(unsigned short *)dest;
+
+}
+
+
+int
+fpgaDownload(unsigned char *saddr,
+	     unsigned long size,
+	     unsigned short *daddr)
+{
+    int i;					/* index, intr disable flag */
+    int start;					/* timer */
+    unsigned long greg, grego;			/* GPIO & output register */
+    unsigned long length;			/* image size in words */
+    unsigned long *source;			/* image source addr */
+    unsigned short *dest;			/* destination FPGA addr */
+    volatile unsigned short *ndest;		/* temp dest FPGA addr */
+    volatile unsigned short val;		/* temp val */
+    unsigned long cnfg = GPIO_XCV_CNFG;		/* FPGA CNFG */
+    unsigned long eirq = GPIO_XCV_IRQ;
+    int retval = -1;				/* Function return value */
+
+    /* Setup some basic values */
+    length = (size / 4) + 1;			/* size in words, rounding UP
+						    is OK */
+    source = (unsigned long *)saddr;
+    dest = (unsigned short *)daddr;
+
+    /* Get DCR output register */
+    grego = in32(IBM405GP_GPIO0_OR);
+
+    /* Reset FPGA */
+    grego &= ~GPIO_XCV_PROG;			/* PROG line low */
+    out32(IBM405GP_GPIO0_OR, grego);
+
+    /* Setup timeout timer */
+    start = get_timer(0);
+
+    /* Wait for FPGA init line */
+    while(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT) { /* Wait INIT line low */
+        /* Check for timeout - 100us max, so use 3ms */
+        if (get_timer(start) > 3) {
+            printf("     failed to start init.\n");
+            log_warn(ERR_XINIT0);		/* Don't halt */
+
+            /* Reset line stays low */
+            goto done;				/* I like gotos... */
+        }
+    }
+
+    /* Unreset FPGA */
+    grego |= GPIO_XCV_PROG;			/* PROG line high */
+    out32(IBM405GP_GPIO0_OR, grego);
+
+    /* Wait for FPGA end of init period .  */
+    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT)) { /* Wait for INIT hi */
+
+        /* Check for timeout */
+        if (get_timer(start) > 3) {
+            printf("     failed to exit init.\n");
+            log_warn(ERR_XINIT1);
+
+            /* Reset FPGA */
+            grego &= ~GPIO_XCV_PROG;		/* PROG line low */
+            out32(IBM405GP_GPIO0_OR, grego);
+
+            goto done;
+        }
+    }
+
+    /* Now program FPGA ... */
+    ndest = dest;
+    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+        /* Toggle IRQ/GPIO */
+        greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */
+        greg |= eirq;				/* toggle irq/gpio */
+        mtdcr(CPC0_CR0, greg);			/*  ... just do it */
+
+        /* turn on open drain for CNFG */
+        greg = in32(IBM405GP_GPIO0_ODR);	/* get open drain register */
+        greg |= cnfg;				/* CNFG open drain */
+        out32(IBM405GP_GPIO0_ODR, greg);	/*  .. just do it */
+
+        /* Turn output enable on for CNFG */
+        greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */
+        greg |= cnfg;				/* CNFG tristate inactive */
+        out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */
+
+        /* Setup FPGA for programming */
+        grego &= ~cnfg;				/* CONFIG line low */
+        out32(IBM405GP_GPIO0_OR, grego);
+
+        /*
+         * Program the FPGA
+         */
+        printf("\n       destination: 0x%lx ", (unsigned long)ndest);
+
+        fpga_img_write(source,  length,  (unsigned short *)ndest);
+
+        /* Done programming */
+        grego |= cnfg;				/* CONFIG line high */
+        out32(IBM405GP_GPIO0_OR, grego);
+
+        /* Turn output enable OFF for CNFG */
+        greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */
+        greg &= ~cnfg;				/* CNFG tristate inactive */
+        out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */
+
+        /* Toggle IRQ/GPIO */
+        greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */
+        greg &= ~eirq;				/* toggle irq/gpio */
+        mtdcr(CPC0_CR0, greg);			/*  ... just do it */
+
+        ndest = (unsigned short *)((char *)ndest + 0x00100000L); /* XXX - Next FPGA addr */
+        cnfg >>= 1;				/* XXX - Next  */
+        eirq >>= 1;
+    }
+
+    /* Terminate programming with 4 C clocks */
+    ndest = dest;
+    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+        val = *ndest;
+        val = *ndest;
+        val = *ndest;
+        val = *ndest;
+        ndest = (unsigned short *)((char *)ndest + 0x00100000L);
+    }
+
+    /* Setup timer */
+    start = get_timer(0);
+
+    /* Wait for FPGA end of programming period .  */
+    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_DONE)) { /* Test DONE low */
+
+        /* Check for timeout */
+        if (get_timer(start) > 3) {
+            printf("     done failed to come high.\n");
+            log_warn(ERR_XDONE1);
+
+            /* Reset FPGA */
+            grego &= ~GPIO_XCV_PROG;		/* PROG line low */
+            out32(IBM405GP_GPIO0_OR, grego);
+
+            goto done;
+        }
+    }
+
+    printf("\n       FPGA load succeeded\n");
+    retval = 0;					/* Program OK */
+
+done:
+    return retval;
+}
+
+/* FPGA image is stored in flash */
+extern flash_info_t    flash_info[];
+
+int init_fpga(void)
+{
+    unsigned int i,j,ptr;			/* General purpose */
+    unsigned char bufchar;			/* General purpose character */
+    unsigned char *buf;				/* Start of image pointer */
+    unsigned long len;				/* Length of image */
+    unsigned char *fn_buf;			/* Start of filename string */
+    unsigned int fn_len;			/* Length of filename string */
+    unsigned char *xcv_buf;			/* Pointer to start of image */
+    unsigned long xcv_len;			/* Length of image */
+    unsigned long crc;				/* 30bit crc in image */
+    unsigned long calc_crc;			/* Calc'd 30bit crc */
+    int retval = -1;
+
+    /* Tell the world what we are doing */
+    printf("FPGA:  ");
+
+    /*
+     * Get address of first sector where the FPGA
+     * image is stored.
+     */
+    buf = (unsigned char *)flash_info[1].start[0];
+
+    /*
+     * Get the stored image's CRC & length.
+     */
+    crc = *(unsigned long *)(buf+4);		/* CRC is first long word */
+    len = *(unsigned long *)(buf+8);		/* Image len is next long */
+
+    /* Pedantic */
+    if ((len < 0x133A4) || (len > 0x80000))
+        goto bad_image;
+
+    /*
+     * Get the file name pointer and length.
+     */
+    fn_len = (*(unsigned short *)(buf+12) & 0xff); /* filename length
+						      is next short */
+    fn_buf = buf + 14;
+
+    /*
+     * Get the FPGA image pointer and length length.
+     */
+    xcv_buf = fn_buf + fn_len;			/* pointer to fpga image */
+    xcv_len = len - 14 - fn_len;		/* fpga image length */
+
+    /* Check for uninitialized FLASH */
+    if ((strncmp(buf, "w7o", 3)!=0) || (len > 0x0007ffffL) || (len == 0))
+	goto bad_image;
+
+    /*
+     * Calculate and Check the image's CRC.
+     */
+    calc_crc = crc32(0, xcv_buf, xcv_len);
+    if (crc != calc_crc) {
+        printf("\nfailed - bad CRC\n");
+        goto done;
+    }
+
+    /* Output the file name */
+    printf("file name  : ");
+    for (i=0;i<fn_len;i++) {
+        bufchar = fn_buf[+i];
+        if (bufchar<' ' || bufchar>'~') bufchar = '.';
+        putc(bufchar);
+    }
+
+    /*
+     * find rest of display data
+     */
+    ptr = 15;					/* Offset to ncd filename
+						   length in fpga image */
+    j = xcv_buf[ptr];				/* Get len of ncd filename */
+    if (j > 32) goto bad_image;
+    ptr = ptr + j + 3;				/* skip ncd filename string +
+						   3 bytes more bytes */
+
+    /*
+     * output target device string
+     */
+    j = xcv_buf[ptr++] - 1;			/* len of targ str less term */
+    if (j > 32) goto bad_image;
+    printf("\n       target     : ");
+    for (i = 0; i < j; i++) {
+	bufchar = (xcv_buf[ptr++]);
+	if (bufchar<' ' || bufchar>'~') bufchar = '.';
+	putc(bufchar);
+    }
+
+    /*
+     * output compilation date string and time string
+     */
+    ptr += 3;					/* skip 2 bytes */
+    printf("\n       synth time : ");
+    j = (xcv_buf[ptr++] - 1);			/* len of date str less term */
+    if (j > 32) goto bad_image;
+    for (i = 0; i < j; i++) {
+	bufchar = (xcv_buf[ptr++]);
+	if (bufchar<' ' || bufchar>'~') bufchar = '.';
+	putc(bufchar);
+    }
+
+    ptr += 3;					/* Skip 2 bytes */
+    printf(" - ");
+    j = (xcv_buf[ptr++] - 1);			/* slen = targ dev str len */
+    if (j > 32) goto bad_image;
+    for (i = 0; i < j; i++) {
+	bufchar = (xcv_buf[ptr++]);
+	if (bufchar<' ' || bufchar>'~') bufchar = '.';
+	putc(bufchar);
+    }
+
+    /*
+     * output crc and length strings
+     */
+    printf("\n       len & crc  : 0x%lx  0x%lx", len, crc);
+
+    /*
+     * Program the FPGA.
+     */
+    retval = fpgaDownload((unsigned char*)xcv_buf, xcv_len,
+                          (unsigned short *)0xfd000000L);
+    return retval;
+
+bad_image:
+    printf("\n       BAD FPGA image format @ %lx\n", flash_info[1].start[0]);
+    log_warn(ERR_XIMAGE);
+done:
+    return retval;
+}
+
+void test_fpga(unsigned short *daddr)
+{
+    int i;
+    volatile unsigned short *ndest = daddr;
+
+    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+#if defined(CONFIG_W7OLMG)
+	ndest[0x7e] = 0x55aa;
+	if (ndest[0x7e] != 0x55aa)
+	    log_warn(ERR_XRW1 + i);
+	ndest[0x7e] = 0xaa55;
+	if (ndest[0x7e] != 0xaa55)
+	    log_warn(ERR_XRW1 + i);
+	ndest[0x7e] = 0xc318;
+	if (ndest[0x7e] != 0xc318)
+	    log_warn(ERR_XRW1 + i);
+
+#elif defined(CONFIG_W7OLMC)
+	ndest[0x800] = 0x55aa;
+	ndest[0x801] = 0xaa55;
+	ndest[0x802] = 0xc318;
+	ndest[0x4800] = 0x55aa;
+	ndest[0x4801] = 0xaa55;
+	ndest[0x4802] = 0xc318;
+	if ((ndest[0x800] != 0x55aa) ||
+	    (ndest[0x801] != 0xaa55) ||
+	    (ndest[0x802] != 0xc318))
+	    log_warn(ERR_XRW1 + (2 * i));       /* Auto gen error code */
+	if ((ndest[0x4800] != 0x55aa) ||
+	    (ndest[0x4801] != 0xaa55) ||
+	    (ndest[0x4802] != 0xc318))
+	    log_warn(ERR_XRW2 + (2 * i));       /* Auto gen error code */
+
+#else
+# error "Unknown W7O board configuration"
+#endif
+    }
+
+    printf("       FPGA ready\n");
+    return;
+}
+
diff --git a/board/w7o/init.S b/board/w7o/init.S
new file mode 100644
index 0000000..0abf21f
--- /dev/null
+++ b/board/w7o/init.S
@@ -0,0 +1,264 @@
+/******************************************************************************
+ *
+ *	 This source code has been made available to you by IBM on an AS-IS
+ *	 basis.	 Anyone receiving this source is licensed under IBM
+ *	 copyrights to use it in any way he or she deems fit, including
+ *	 copying it, modifying it, compiling it, and redistributing it either
+ *	 with or without modifications.	 No license under IBM patents or
+ *	 patent applications is to be implied by the copyright license.
+ *
+ *	 Any user of this software should understand that IBM cannot provide
+ *	 technical support for this software and will not be responsible for
+ *	 any consequences resulting from the use of this software.
+ *
+ *	 Any person who transfers this source code or any derivative work
+ *	 must include the IBM copyright notice, this paragraph, and the
+ *	 preceding two paragraphs in the transferred software.
+ *
+ *	 COPYRIGHT   I B M   CORPORATION 1995
+ *	 LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+ *
+ *****************************************************************************/
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/******************************************************************************
+ * Function:	ext_bus_cntlr_init
+ *
+ * Description:	Configures EBC Controller and a few basic chip selects.
+ *
+ *		CS0 is setup to get the Boot Flash out of the addresss range
+ *		so that we may setup a stack.  CS7 is setup so that we can
+ *		access and reset the hardware watchdog.
+ *
+ *		IMPORTANT: For pass1 this code must run from
+ *		cache since you can not reliably change a peripheral banks
+ *		timing register (pbxap) while running code from that bank.
+ *		For ex., since we are running from ROM on bank 0, we can NOT
+ *		execute the code that modifies bank 0 timings from ROM, so
+ *		we run it from cache.
+ *
+ * Notes:	Does NOT use the stack.
+ *****************************************************************************/
+	.section ".text"
+	.align	2
+	.globl	ext_bus_cntlr_init
+	.type	ext_bus_cntlr_init, @function
+ext_bus_cntlr_init:
+	mflr	r0
+	/********************************************************************
+	 * Prefetch entire ext_bus_cntrl_init function into the icache.
+	 * This is necessary because we are going to change the same CS we
+	 * are executing from.  Otherwise a CPU lockup may occur.
+	 *******************************************************************/
+	bl	..getAddr
+..getAddr:
+	mflr	r3			/* get address of ..getAddr */
+
+	/* Calculate number of cache lines for this function */
+	addi	r4, 0, (((.Lfe0 - ..getAddr) / CFG_CACHELINE_SIZE) + 2)
+	mtctr	r4
+..ebcloop:
+	icbt	r0, r3			/* prefetch cache line for addr in r3*/
+	addi	r3, r3, CFG_CACHELINE_SIZE /* move to next cache line */
+	bdnz	..ebcloop		/* continue for $CTR cache lines */
+
+	/********************************************************************
+	 * Delay to ensure all accesses to ROM are complete before changing
+	 * bank 0 timings. 200usec should be enough.
+	 * 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles.
+	 *******************************************************************/
+	addis	r3, 0, 0x0
+	ori	r3, r3, 0xA000		/* wait 200us from reset */
+	mtctr	r3
+..spinlp:
+	bdnz	..spinlp		/* spin loop */
+
+	/********************************************************************
+	 * Setup External Bus Controller (EBC).
+	 *******************************************************************/
+	addi	r3, 0, epcr
+	mtdcr	ebccfga, r3
+	addis	r4, 0, 0xb040		/* Device base timeout = 1024 cycles */
+	ori	r4, r4, 0x0		/* Drive CS with external master */
+	mtdcr	ebccfgd, r4
+
+	/********************************************************************
+	 * Change PCIINT signal to PerWE
+	 *******************************************************************/
+	mfdcr	r4, cntrl1
+	ori	r4, r4, 0x4000
+	mtdcr	cntrl1, r4
+
+	/********************************************************************
+	 * Memory Bank 0 (Flash Bank 0) initialization
+	 *******************************************************************/
+	addi	r3, 0, pb0ap
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB0AP@h
+	ori	r4, r4, CFG_W7O_EBC_PB0AP@l
+	mtdcr	ebccfgd, r4
+
+	addi	r3, 0, pb0cr
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB0CR@h
+	ori	r4, r4, CFG_W7O_EBC_PB0CR@l
+	mtdcr	ebccfgd, r4
+
+	/********************************************************************
+	 * Memory Bank 7 LEDs - NEEDED BECAUSE OF HW WATCHDOG AND LEDs.
+	 *******************************************************************/
+	addi	r3, 0, pb7ap
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB7AP@h
+	ori	r4, r4, CFG_W7O_EBC_PB7AP@l
+	mtdcr	ebccfgd, r4
+
+	addi	r3, 0, pb7cr
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB7CR@h
+	ori	r4, r4, CFG_W7O_EBC_PB7CR@l
+	mtdcr	ebccfgd, r4
+
+	/* We are all done */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+.Lfe0:	.size	ext_bus_cntlr_init,.Lfe0-ext_bus_cntlr_init
+/* end ext_bus_cntlr_init() */
+
+/******************************************************************************
+ * Function:	sdram_init
+ *
+ * Description:	Configures SDRAM memory banks.
+ *
+ *		Serial Presence Detect, "SPD," reads the SDRAM EEPROM
+ *		via the IIC bus and then configures the SDRAM memory
+ *		banks appropriately. If Auto Memory Configuration is
+ *		is not used, it is assumed that a 4MB 11x8x2, non-ECC,
+ *		SDRAM is soldered down.
+ *
+ * Notes:	Expects that the stack is already setup.
+ *****************************************************************************/
+	.section ".text"
+	.align	2
+	.globl	sdram_init
+	.type	sdram_init, @function
+sdram_init:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -8(r1)		/* Save back chain and move SP */
+	stw	r0, +12(r1)		/* Save link register */
+
+	/*
+	 * First call spd_sdram to try to init SDRAM according to the
+	 * contents of the SPD EEPROM.  If the SPD EEPROM is blank or
+	 * erronious, spd_sdram returns 0 in R3.
+	 */
+	bl	spd_sdram
+	addic.	r3, r3, 0		/* Check for error, save dram size */
+	bne	..sdri_done		/* If it worked, we're done... */
+
+	/********************************************************************
+	 * If SPD detection fails, we'll default to 4MB, 11x8x2, as this
+	 * is the SMALLEST SDRAM size the 405 supports.  We can do this
+	 * because W7O boards have soldered on RAM, and there will always
+	 * be some amount present.  If we were using DIMMs, we should hang
+	 * the board instead, since it doesn't have any RAM to continue
+	 * running with.
+	 *******************************************************************/
+
+	/*
+	 * Disable memory controller to allow
+	 * values to be changed.
+	 */
+	addi    r3, 0, mem_mcopt1
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x0
+	ori     r4, r4, 0x0
+	mtdcr   memcfgd, r4
+
+	/*
+	 * Set MB0CF for ext bank 0. (0-4MB) Address Mode 5 since 11x8x2
+	 * All other banks are disabled.
+	 */
+	addi	r3, 0, mem_mb0cf
+	mtdcr	memcfga, r3
+	addis	r4, 0, 0x0000		/* BA=0x0, SZ=4MB */
+	ori	r4, r4, 0x8001		/* Mode is 5, 11x8x2or4, BE=Enabled */
+	mtdcr	memcfgd, r4
+
+	/* Clear MB1CR,MB2CR,MB3CR to turn other banks off */
+	addi	r4, 0, 0		/* Zero the data reg */
+
+	addi	r3, r3, 4		/* Point to MB1CF reg */
+	mtdcr	memcfga, r3		/* Set the address */
+	mtdcr	memcfgd, r4		/* Zero the reg */
+
+	addi	r3, r3, 4		/* Point to MB2CF reg */
+	mtdcr	memcfga, r3		/* Set the address */
+	mtdcr	memcfgd, r4		/* Zero the reg */
+
+	addi	r3, r3, 4		/* Point to MB3CF reg */
+	mtdcr	memcfga, r3		/* Set the address */
+	mtdcr	memcfgd, r4		/* Zero the reg */
+
+	/********************************************************************
+	 * Set the SDRAM Timing reg, SDTR1 and the refresh timer reg, RTR.
+	 * To set the appropriate timings, we assume sdram is
+	 * 100MHz (pc100 compliant).
+	 *******************************************************************/
+
+	/*
+	 * Set up SDTR1
+	 */
+	addi    r3, 0, mem_sdtr1
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x0086		/* SDTR1 value for 100Mhz */
+	ori     r4, r4, 0x400D
+	mtdcr   memcfgd, r4
+
+	/*
+	 * Set RTR
+	 */
+	addi    r3, 0, mem_rtr
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x05F0		/* RTR refresh val = 15.625ms@100Mhz */
+	mtdcr   memcfgd, r4
+
+	/********************************************************************
+	 * Delay to ensure 200usec have elapsed since reset. Assume worst
+	 * case that the core is running 200Mhz:
+	 *	  200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles
+	 *******************************************************************/
+	addis   r3, 0, 0x0000
+	ori     r3, r3, 0xA000		/* Wait 200us from reset */
+	mtctr   r3
+..spinlp2:
+	bdnz    ..spinlp2		/* spin loop */
+
+	/********************************************************************
+	 * Set memory controller options reg, MCOPT1.
+	 *******************************************************************/
+	addi    r3, 0, mem_mcopt1
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x80E0		/* DC_EN=1,SRE=0,PME=0,MEMCHK=0 */
+	ori     r4, r4, 0x0000		/* REGEN=0,DRW=00,BRPF=01,ECCDD=1 */
+	mtdcr   memcfgd, r4		/* EMDULR=1 */
+
+..sdri_done:
+	/* restore and return */
+	lwz	r0, +12(r1)		/* Get saved link register */
+	addi	r1, r1, +8		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+.Lfe1:	.size	sdram_init,.Lfe1-sdram_init
+/* end sdram_init() */
+
diff --git a/board/w7o/post1.S b/board/w7o/post1.S
new file mode 100644
index 0000000..d510cca
--- /dev/null
+++ b/board/w7o/post1.S
@@ -0,0 +1,745 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
+ *  and
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+/*
+ * Description:
+ *	Routine to exercise memory for the bringing up of our boards.
+ */
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1       /* avoid reading Linux autoconf.h file  */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#include <watchdog.h>
+
+#include "errors.h"
+
+#define _ASMLANGUAGE
+
+	.globl	test_sdram
+	.globl	test_led
+	.globl	log_stat
+	.globl	log_warn
+	.globl	log_err
+	.globl  temp_uart_init
+	.globl  post_puts
+	.globl  disp_hex
+
+/*****************************************************
+*******   Text Strings for low level printing   ******
+*******          In section got2               *******
+*****************************************************/
+
+/*
+ * Define the text strings for errors and warnings.
+ * Switch to .data section.
+ */
+	.section ".data"
+err_str: 	.asciz "*** POST ERROR   = "
+warn_str:	.asciz "*** POST WARNING = "
+end_str:  .asciz "\r\n"
+
+/*
+ * Enter the labels in Global Entry Table (GOT).
+ * Switch to .got2 section.
+ */
+	START_GOT
+	GOT_ENTRY(err_str)
+	GOT_ENTRY(warn_str)
+	GOT_ENTRY(end_str)
+	END_GOT
+
+/*
+ * Switch  back to .text section.
+ */
+	.text
+
+/****************************************
+ ****************************************
+ ********    LED register test   ********
+ ****************************************
+ ***************************************/
+test_led:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	WATCHDOG_RESET        		/* Reset the watchdog */
+
+	addi    r3, 0, ERR_FF		/* first test value is ffff */
+	addi	r4, r3, 0		/* save copy of pattern */
+	bl	set_led			/* store first test value */
+	bl	get_led			/* read it back */
+	xor.	r4, r4, r3		/* compare to original */
+#if defined(CONFIG_W7OLMC)
+	andi.   r4, r4, 0x00ff		/* lmc has 8 bits */
+#else
+	andi.   r4, r4, 0xffff		/* lmg has 16 bits */
+#endif
+	beq     LED2			/* next test */
+	addi    r3, 0, ERR_LED		/* error code = 1 */
+	bl	log_err			/* display error and halt */
+LED2:	addi    r3, 0, ERR_00		/* 2nd test value is 0000 */
+	addi	r4, r3, 0		/* save copy of pattern */
+	bl	set_led			/* store first test value */
+	bl	get_led			/* read it back */
+	xor.	r4, r4, r3		/* compare to original */
+#if defined(CONFIG_W7OLMC)
+	andi.   r4, r4, 0x00ff		/* lmc has 8 bits */
+#else
+	andi.   r4, r4, 0xffff		/* lmg has 16 bits */
+#endif
+	beq     LED3			/* next test */
+	addi    r3, 0, ERR_LED		/* error code = 1 */
+	bl	log_err			/* display error and halt */
+
+LED3:	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/****************************************
+ ****************************************
+ ********     SDRAM TESTS        ********
+ ****************************************
+ ***************************************/
+test_sdram:
+	/* called with mem size in r3 */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stmw	r30, +8(r1)		/* save R30,R31 */
+					/* r30 is log2(mem size) */
+					/* r31 is mem size */
+
+	/* take log2 of total mem size */
+	addi	r31, r3, 0		/* save total mem size */
+	addi	r30, 0, 0		/* clear r30 */
+l2_loop:
+	srwi.	r31, r31, 1		/* shift right 1 */
+	addi	r30, r30, 1		/* count shifts */
+	bne	l2_loop			/* loop till done */
+	addi	r30, r30, -1		/* correct for over count */
+	addi	r31, r3, 0		/* save original size */
+
+	/* now kick the dog and test the mem */
+	WATCHDOG_RESET        		/* Reset the watchdog */
+	bl	Data_Buster		/* test crossed/shorted data lines */
+	addi	r3, r30, 0		/* get log2(memsize) */
+	addi	r4, r31, 0		/* get memsize */
+	bl	Ghost_Buster		/* test crossed/shorted addr lines */
+	addi	r3, r31, 0		/* get mem size */
+	bl	Bit_Buster		/* check for bad internal bits */
+
+	/* restore stack and return */
+	lmw	r30, +8(r1)		/* Restore r30, r31 */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+
+/****************************************
+ ********  sdram data bus test   ********
+ ***************************************/
+Data_Buster:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -24(r1)		/* Save back chain and move SP */
+	stw	r0, +28(r1)		/* Save link register */
+	stmw	r28, 8(r1)		/* save r28 - r31 on stack */
+					/* r31 i/o register */
+					/* r30 sdram base address */
+					/* r29 5555 syndrom */
+					/* r28 aaaa syndrom */
+
+	/* set up led register for this test */
+	addi    r3, 0, ERR_RAMG		/* set led code to 1 */
+	bl	log_stat		/* store test value */
+	/* now test the dram data bus */
+	xor	r30, r30, r30		/* load r30 with base addr of sdram */
+	addis	r31, 0, 0x5555		/* load r31 with test value */
+	ori	r31, r31, 0x5555
+	stw	r31,0(r30)		/* sto the value */
+	lwz	r29,0(r30)		/* read it back */
+	xor	r29,r31,r29		/* compare it to original */
+	addis	r31, 0, 0xaaaa		/* load r31 with test value */
+	ori	r31, r31, 0xaaaa
+	stw	r31,0(r30)		/* sto the value */
+	lwz	r28,0(r30)		/* read it back */
+	xor	r28,r31,r28		/* compare it to original */
+	or	r3,r28,r29		/* or together both error terms */
+	/*
+	 * Now that we have the error bits,
+	 * we have to decide which part they are in.
+	 */
+	bl	get_idx			/* r5 is now index to error */
+	addi	r3, r3, ERR_RAMG
+	cmpwi	r3, ERR_RAMG		/* check for errors */
+	beq	db_done			/* skip if no errors */
+	bl	log_err			/* log the error */
+
+db_done:
+	lmw	r28, 8(r1)		/* restore r28 - r31 from stack */
+	lwz	r0, +28(r1)		/* Get saved link register */
+	addi	r1, r1, +24		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+/****************************************************
+ ********  test for address ghosting in dram ********
+ ***************************************************/
+
+Ghost_Buster:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -36(r1)		/* Save back chain and move SP */
+	stw	r0, +40(r1)		/* Save link register */
+	stmw	r25, 8(r1)		/* save r25 - r31 on stack */
+					/* r31 = scratch register */
+					/* r30 is main referance loop counter,
+					   0 to 23 */
+					/* r29 is ghost loop count, 0 to 22 */
+					/* r28 is referance address */
+					/* r27 is ghost address */
+					/* r26 is log2 (mem size) =
+					     number of byte addr bits */
+					/* r25 is mem size */
+
+	/* save the log2(mem size) and mem size */
+	addi	r26, r3, 0		/* r26 is number of byte addr bits */
+	addi	r25, r4, 0		/* r25 is mem size in bytes */
+
+	/* set the leds for address ghost test */
+	addi	r3, 0, ERR_ADDG
+	bl	set_led
+
+	/* first fill memory with zeros */
+	srwi	r31, r25, 2		/* convert bytes to longs */
+	mtctr	r31			/* setup byte counter */
+	addi	r28, 0, 0		/* start at address at 0 */
+	addi	r31, 0, 0		/* data value = 0 */
+clr_loop:
+	stw	r31, 0(r28)		/* Store zero value */
+	addi	r28, r28, 4		/* Increment to next word */
+	andi.	r27, r28, 0xffff	/* check for 2^16 loops */
+	bne	clr_skip		/* if not there, then skip */
+	WATCHDOG_RESET   		/* kick the dog every now and then */
+clr_skip:
+	bdnz	clr_loop		/* Round and round... */
+
+	/* now do main test */
+	addi	r30, 0, 0		/* start referance counter at 0 */
+outside:
+	/*
+	 * Calculate the referance address
+	 *   the referance address is calculated by setting the (r30-1)
+	 *   bit of the base address
+	 * when r30=0, the referance address is the base address.
+	 * thus the sequence 0,1,2,4,8,..,2^(n-1)
+	 * setting the bit is done with the following shift functions.
+	 */
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	addi	r31, 0, 1		/* r31 = 1 */
+	slw	r28, r31, r30		/* set bit coresponding to loop cnt */
+	srwi	r28, r28, 1		/* then shift it right one so  */
+					/*   we start at location 0 */
+	/* fill referance address with Fs */
+	addi	r31, 0, 0x00ff		/* r31 = one byte of set bits */
+	stb     r31,0(r28)		/* save ff in referance address */
+
+        /* ghost (inner) loop, now check all posible ghosted addresses */
+	addi	r29, 0, 0		/* start ghosted loop counter at 0 */
+inside:
+	/*
+	 * Calculate the ghost address by flipping one
+	 *  bit of referance address.  This gives the
+	 *  sequence 1,2,4,8,...,2^(n-1)
+	 */
+	addi	r31, 0, 1		/* r31 = 1 */
+	slw     r27, r31, r29		/* set  bit coresponding to loop cnt */
+	xor	r27, r28, r27		/* ghost address = ref addr with
+					     bit flipped*/
+
+	/* now check for ghosting */
+	lbz     r31,0(r27)		/* get content of ghost addr */
+	cmpwi   r31, 0			/* compare read value to 0 */
+	bne	Casper			/*   we found a ghost! */
+
+	/* now close ghost ( inner ) loop */
+	addi 	r29, r29, 1		/* increment inner loop counter */
+	cmpw 	r29, r26		/* check for last inner loop */
+	blt		inside		/* do more inner loops */
+
+	/* now close referance ( outer ) loop */
+	addi 	r31, 0, 0 		/* r31 = zero */
+	stb	r31, 0(28)		/* zero out the altered address loc. */
+	/*
+	 * Increment and check for end, count is zero based.
+	 * With the ble, this gives us one more loops than
+	 * address bits for sequence 0,1,2,4,8,...2^(n-1)
+	*/
+	addi 	r30, r30, 1		/* increment outer loop counter */
+	cmpw 	r30, r26		/* check for last inner loop */
+	ble	outside			/* do more outer loops */
+
+	/* were done, lets go home */
+	b	gb_done
+Casper:					/* we found a ghost !! */
+	addi	r3, 0, ERR_ADDF		/* get indexed error message */
+	bl	log_err			/* log error led error code */
+gb_done: /*  pack your bags, and go home */
+        lmw     r25, 8(r1)              /* restore r25 - r31 from stack */
+        lwz     r0, +40(r1)             /* Get saved link register */
+        addi    r1, r1, +36             /* Remove frame from stack */
+        mtlr    r0                      /* Restore link register */
+        blr                             /* Return to calling function */
+
+/****************************************************
+ ********      SDRAM data fill tests       **********
+ ***************************************************/
+Bit_Buster:
+	/* called with mem size in r3 */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+	stw	r5, +12(r1)		/* save r5 */
+
+	addis	r5, r3, 0		/* save mem size */
+
+	/* Test 55555555 */
+	addi	r3, 0, ERR_R55G		/* set up error code in case we fail */
+	bl	log_stat		/* store test value */
+	addis	r4, 0, 0x5555
+	ori	r4, r4, 0x5555
+	bl	fill_test
+
+	/* Test aaaaaaaa  */
+	addi	r3, 0, ERR_RAAG		/* set up error code in case we fail */
+	bl	log_stat		/* store test value */
+	addis	r4, 0, 0xAAAA
+	ori	r4, r4, 0xAAAA
+	bl	fill_test
+
+	/* Test 00000000  */
+	addi	r3, 0, ERR_R00G		/* set up error code in case we fail */
+	bl	log_stat		/* store test value */
+	addis	r4, 0, 0
+	ori	r4, r4, 0
+	bl	fill_test
+
+	/* restore stack and return */
+	lwz	r5, +12(r1)		/* restore r4 */
+	lwz	r4, +8(r1)		/* restore r4 */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+
+/****************************************************
+ ********             fill test              ********
+ ***************************************************/
+/*	tests memory by filling with value, and reading back */
+/*	r5 = Size of memory in bytes */
+/*	r4 = Value to write */
+/*	r3 = Error code */
+fill_test:
+        mflr    r0                      /* Get link register */
+        stwu    r1, -32(r1)             /* Save back chain and move SP */
+        stw     r0, +36(r1)             /* Save link register */
+        stmw    r27, 8(r1)              /* save r27 - r31 on stack */
+                                        /* r31 - scratch register */
+                                        /* r30 - memory address */
+	mr	r27, r3
+	mr	r28, r4
+	mr	r29, r5
+
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	/* first fill memory with Value */
+	srawi	r31, r29, 2		/* convert bytes to longs */
+	mtctr	r31			/* setup counter */
+	addi	r30, 0, 0		/* Make r30 = addr 0 */
+ft_0:	stw	r28, 0(r30)		/* Store value */
+	addi	r30, r30, 4		/* Increment to next word */
+	andi.	r31, r30, 0xffff	/* check for 2^16 loops */
+	bne	ft_0a			/* if not there, then skip */
+	WATCHDOG_RESET   		/* kick the dog every now and then */
+ft_0a:	bdnz	ft_0			/* Round and round... */
+
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	/* Now confirm Value is in memory */
+	srawi	r31, r29, 2		/* convert bytes to longs */
+	mtctr	r31			/* setup counter */
+	addi	r30, 0, 0		/* Make r30 = addr 0 */
+ft_1:	lwz	r31, 0(r30)		/* get value from memory */
+        xor.	r31, r31, r28		/* Writen = Read ? */
+        bne	ft_err			/* If bad, than halt */
+	addi	r30, r30, 4		/* Increment to next word */
+	andi.	r31, r30, 0xffff	/* check for 2^16 loops*/
+	bne	ft_1a			/* if not there, then skip */
+	WATCHDOG_RESET			/* kick the dog every now and then */
+ft_1a:	bdnz	ft_1			/* Round and round... */
+
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	b	fill_done		/* restore and return */
+
+ft_err:	addi	r29, r27, 0		/* save current led code */
+	addi	r27, r31, 0		/* get pattern in r27 */
+	bl	get_idx			/* get index from r27 */
+	add	r27, r27, r29		/* add index to old led code */
+	bl	log_err			/* output led err code, halt CPU */
+
+fill_done:
+        lmw     r27, 8(r1)              /* restore r27 - r31 from stack */
+        lwz     r0, +36(r1)             /* Get saved link register */
+        addi    r1, r1, +32             /* Remove frame from stack */
+        mtlr    r0                      /* Restore link register */
+        blr                             /* Return to calling function */
+
+
+/****************************************************
+ *******  get error index from r3 pattern    ********
+ ***************************************************/
+get_idx:				/* r3 = (MSW(r3) !=0)*2 +
+					    (LSW(r3) !=0) */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	andi.	r4, r3, 0xffff		/* check for lower bits */
+	beq	gi2			/* skip if no bits set */
+	andis.	r4, r3, 0xffff		/* check for upper bits */
+	beq	gi3			/* skip if no bits set */
+	addi	r3, 0, 3		/* both upper and lower bits set */
+	b	gi_done
+gi2:	andis.	r4, r3, 0xffff		/* check for upper bits*/
+	beq	gi4			/* skip if no bits set */
+	addi	r3, 0, 2		/* only upper bits set */
+	b	gi_done
+gi3:	addi	r3, 0, 1		/* only lower bits set */
+	b	gi_done
+gi4:	addi	r3, 0, 0		/* no bits set */
+gi_done:
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/****************************************************
+ ********       set LED to R5 and hang       ********
+ ***************************************************/
+log_stat:				/* output a led code and continue */
+set_led:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	addis	r4, 0, 0xfe00		/* LED buffer is at 0xfe000000 */
+#if defined(CONFIG_W7OLMG)		/* only on gateway, invert outputs */
+	xori	r3,r3, 0xffff		/* complement led code, active low */
+	sth	r3, 0(r4)		/* store first test value */
+	xori	r3,r3, 0xffff		/* complement led code, active low */
+#else					/* if not gateway, then don't invert */
+	sth	r3, 0(r4)		/* store first test value */
+#endif
+
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+get_led:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	addis	r4, 0, 0xfe00		/* LED buffer is at 0xfe000000 */
+	lhz	r3, 0(r4)		/* store first test value */
+#if defined(CONFIG_W7OLMG)		/* only on gateway, invert inputs */
+	xori	r3,r3, 0xffff		/* complement led code, active low */
+#endif
+
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+log_err:	/* output the error and hang the board ( for now ) */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r3, +8(r1)		/* save a copy of error code */
+	bl	set_led			/* set the led pattern */
+	GET_GOT				/* get GOT address in r14 */
+	lwz	r3,GOT(err_str)		/* get address of string */
+	bl	post_puts		/* output the warning string */
+	lwz	r3, +8(r1)		/* get error code */
+	addi	r4, 0, 2		/* set disp length to 2 nibbles */
+	bl	disp_hex		/* output the error code */
+	lwz	r3,GOT(end_str)		/* get address of string */
+	bl	post_puts		/* output the warning string */
+halt:
+	b	halt			/* hang */
+
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+log_warn:	/* output a warning, then continue with operations */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stw	r3, +8(r1)		/* save a copy of error code */
+	stw	r14, +12(r1)		/* save a copy of r14 (used by GOT) */
+
+	bl	set_led			/* set the led pattern */
+	GET_GOT				/* get GOT address in r14 */
+	lwz	r3,GOT(warn_str)	/* get address of string */
+	bl	post_puts		/* output the warning string */
+	lwz	r3, +8(r1)		/* get error code */
+	addi	r4, 0, 2		/* set disp length to 2 nibbles */
+	bl	disp_hex		/* output the error code */
+	lwz	r3,GOT(end_str)		/* get address of string */
+	bl	post_puts		/* output the warning string */
+
+	addis	r3, 0, 64		/* has a long delay */
+	mtctr	r3
+log_2:
+	WATCHDOG_RESET			/* this keeps dog from barking, */
+				     	/*   and takes time */
+	bdnz	log_2			/* loop till time expires */
+
+	/* restore stack and return */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	lwz	r14, +12(r1)		/* restore r14 */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/*******************************************************************
+ *	temp_uart_init
+ *	Temporary UART initialization routine
+ *	Sets up UART0 to run at 9600N81 off of the internal clock.
+ *	R3-R4 are used.
+ ******************************************************************/
+temp_uart_init:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -8(r1)		/* Save back chain and move SP */
+	stw	r0, +12(r1)		/* Save link register */
+
+        addis   r3, 0, 0xef60
+        ori     r3, r3, 0x0303          /* r3 = UART0_LCR */
+        addi    r4, 0, 0x83             /* n81 format, divisor regs enabled */
+        stb     r4, 0(r3)
+
+	/* set baud rate to use internal clock,
+	   baud = (200e6/16)/31/42 = 9600 */
+
+        addis   r3, 0, 0xef60		/* Address of baud divisor reg */
+        ori     r3, r3, 0x0300		/*   UART0_DLM */
+        addi    r4, 0, +42		/* uart baud divisor LSB = 93 */
+        stb     r4, 0(r3)               /* baud = (200 /16)/14/93 */
+
+        addi    r3, r3, 0x0001		/* uart baud divisor addr */
+        addi    r4, 0, 0
+        stb     r4, 0(r3)               /* Divisor Latch MSB = 0 */
+
+        addis   r3, 0, 0xef60
+        ori     r3, r3, 0x0303          /* r3 = UART0_LCR */
+        addi    r4, 0, 0x03             /* n81 format, tx/rx regs enabled */
+        stb     r4, 0(r3)
+
+	/* output a few line feeds */
+	addi	r3, 0, '\n'		/* load line feed */
+	bl 	post_putc		/* output the char */
+	addi	r3, 0, '\n'		/* load line feed */
+	bl 	post_putc		/* output the char */
+
+        /* restore stack and return */
+	lwz	r0, +12(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +8		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/**********************************************************************
+ **	post_putc
+ **	outputs charactor in R3
+ **	r3 returns the error code ( -1 if there is an error )
+ *********************************************************************/
+
+post_putc:
+
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -20(r1)		/* Save back chain and move SP */
+	stw	r0, +24(r1)		/* Save link register */
+	stmw	r29, 8(r1)		/* save	r29 - r31 on stack
+					   r31 - uart base address
+       					   r30 - delay counter
+					   r29 - scratch reg */
+
+     addis   r31, 0, 0xef60		/* Point to uart base */
+     ori     r31, r31, 0x0300
+     addis   r30, 0, 152 		/* Load about 10,000,000 ticks. */
+pputc_lp:
+	lbz     r29, 5(r31) 		/* Read Line Status Register */
+	andi.   r29, r29, 0x20		/* Check THRE status */
+	bne     thre_set		/* Branch if FIFO empty */
+	addic.  r30, r30, -1		/* Decrement and check if empty. */
+	bne     pputc_lp		/* Try, try again */
+	addi    r3, 0, -1		/* Load error code for timeout */
+	b       pputc_done 		/* Bail out with error code set */
+thre_set:
+	stb     r3, 0(r31)		/* Store character to UART */
+	addi	r3, 0, 0		/* clear error code */
+pputc_done:
+	lmw	r29, 8(r1)		/*restore r29 - r31 from stack */
+	lwz	r0, +24(r1)		/* Get saved link register */
+	addi	r1, r1, +20		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+/****************************************************************
+    post_puts
+    Accepts a null-terminated string pointed to by R3
+    Outputs to the serial port until 0x00 is found.
+    r3 returns the error code ( -1 if there is an error )
+*****************************************************************/
+post_puts:
+
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r31, 8(r1)		/* save r31 - char pointer */
+
+	addi 	r31, r3, 0              /* move pointer to R31 */
+pputs_nxt:
+	lbz	r3, 0(r31)		/* Get next character */
+	addic.  r3, r3, 0		/* Check for zero */
+	beq	pputs_term		/* bail out if zero */
+	bl	post_putc		/* output the char */
+	addic.	r3, r3, 0		/* check for error */
+	bne	pputs_err
+	addi 	r31, r31, 1		/* point to next char */
+	b	pputs_nxt 		/* loop till term */
+pputs_err:
+	addi 	r3, 0, -1		/* set error code */
+	b	pputs_end		/* were outa here */
+pputs_term:
+	addi 	r3, 0, 1		/* set success code */
+ 	/* restore stack and return */
+pputs_end:
+	lwz	r31, 8(r1)		/* restore r27 - r31 from stack */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+
+/********************************************************************
+ *****	disp_hex
+ *****	Routine to display a hex value from a register.
+ *****	R3 is value to display
+ *****	R4 is number of nibbles to display ie 2 for byte 8 for (long)word
+ *****	Returns -1 in R3 if there is an error ( ie serial port hangs )
+ *****	Returns 0 in R3 if no error
+ *******************************************************************/
+disp_hex:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stmw	r30, 8(r1)		/* save r30 - r31 on stack */
+					/* r31 output char */
+					/* r30 uart base address */
+	addi 	r30, 0, 8               /* Go through 8 nibbles. */
+	addi 	r31, r3, 0
+pputh_nxt:
+	rlwinm	r31, r31, 4, 0, 31	/* Rotate next nibble into position */
+	andi. 	r3, r31, 0x0f		/* Get nibble. */
+	addi 	r3, r3, 0x30		/* Add zero's ASCII code. */
+	cmpwi	r3, 0x03a
+	blt	pputh_out
+	addi 	r3, r3, 0x07            /* 0x27 for lower case. */
+pputh_out:
+	cmpw 	r30, r4
+	bgt	pputh_skip
+	bl	post_putc
+	addic. 	r3, r3, 0 		/* check for error */
+	bne	pputh_err
+pputh_skip:
+	addic.	r30, r30, -1
+	bne	pputh_nxt
+	xor	r3, r3, r3		/* Clear error code */
+	b	pputh_done
+pputh_err:
+	addi 	r3, 0, -1 		/* set error code */
+pputh_done:
+        /* restore stack and return */
+	lmw	r30, 8(r1)		/*  restore r30 - r31 from stack */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
diff --git a/board/w7o/post2.c b/board/w7o/post2.c
new file mode 100644
index 0000000..271c197
--- /dev/null
+++ b/board/w7o/post2.c
@@ -0,0 +1,109 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
+ *   and
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+
+#include <common.h>
+#include <config.h>
+#include <rtc.h>
+#include "errors.h"
+#include "dtt.h"
+
+#if defined(CONFIG_RTC_M48T35A)
+void rtctest(void)
+{
+    volatile uchar *tchar = (uchar*)(CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 9);
+    struct rtc_time tmp;
+
+    /* set up led code for RTC tests */
+    log_stat(ERR_RTCG);
+
+    /*
+     * Do RTC battery test. The first write after power up
+     * fails if battery is low.
+     */
+    *tchar = 0xaa;
+    if ((*tchar ^ 0xaa) != 0x0) log_warn(ERR_RTCBAT);
+    *tchar = 0x55;				/* Reset test address */
+
+    /*
+     * Now lets check the validity of the values in the RTC.
+     */
+    rtc_get(&tmp);
+    if ((tmp.tm_sec < 0)	| (tmp.tm_sec  > 59)   |
+	(tmp.tm_min < 0)	| (tmp.tm_min  > 59)   |
+	(tmp.tm_hour < 0)	| (tmp.tm_hour > 23)   |
+	(tmp.tm_mday < 1 )	| (tmp.tm_mday > 31)   |
+	(tmp.tm_mon < 1 )	| (tmp.tm_mon  > 12)   |
+	(tmp.tm_year < 2000)	| (tmp.tm_year > 2500) |
+	(tmp.tm_wday < 1 )	| (tmp.tm_wday > 7)) {
+	log_warn(ERR_RTCTIM);
+	rtc_reset();
+    }
+
+    /*
+     * Now lets do a check to see if the NV RAM is there.
+     */
+    *tchar = 0xaa;
+    if ((*tchar ^ 0xaa) != 0x0) log_err(ERR_RTCVAL);
+    *tchar = 0x55;				/* Reset test address */
+
+} /* rtctest() */
+#endif	/* CONFIG_RTC_M48T35A */
+
+
+#ifdef CONFIG_DTT_LM75
+int dtt_test(int sensor)
+{
+    short temp, trip, hyst;
+
+    /* get values */
+    temp = dtt_read(sensor, DTT_READ_TEMP) / 256;
+    trip = dtt_read(sensor, DTT_TEMP_SET) / 256;
+    hyst = dtt_read(sensor, DTT_TEMP_HYST) / 256;
+
+    /* check values */
+    if ((hyst != (CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS)) ||
+	(trip != CFG_DTT_MAX_TEMP) ||
+	(temp < CFG_DTT_LOW_TEMP) || (temp > CFG_DTT_MAX_TEMP))
+	return 1;
+
+    return 0;
+} /* dtt_test() */
+#endif /* CONFIG_DTT_LM75 */
+
+/*****************************************/
+
+void post2(void)
+{
+#if defined(CONFIG_RTC_M48T35A)
+    rtctest();
+#endif	/* CONFIG_RTC_M48T35A */
+
+#ifdef CONFIG_DTT_LM75
+    log_stat(ERR_TempG);
+    if(dtt_test(2) != 0) log_warn(ERR_Ttest0);
+    if(dtt_test(4) != 0) log_warn(ERR_Ttest1);
+#endif /* CONFIG_DTT_LM75 */
+} /* post2() */
+
diff --git a/board/w7o/vpd.c b/board/w7o/vpd.c
new file mode 100644
index 0000000..c24b127
--- /dev/null
+++ b/board/w7o/vpd.c
@@ -0,0 +1,408 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+
+#if defined(VXWORKS)
+# include <stdio.h>
+# include <string.h>
+# define CFG_DEF_EEPROM_ADDR 0xa0
+extern char iicReadByte( char, char );
+extern ulong_t crc32( unsigned char *, unsigned long );
+#else
+#include <common.h>
+#endif
+
+#include "vpd.h"
+
+/*
+ * vpd_reader() - reads VPD data from I2C EEPROMS.
+ *                returns pointer to buffer or NULL.
+ */
+static unsigned char *
+vpd_reader(unsigned char *buf, unsigned dev_addr, unsigned off, unsigned count)
+{
+    unsigned offset = off;			/* Calculated offset */
+
+    /*
+     * The main board EEPROM contains
+     * SDRAM SPD in the first 128 bytes,
+     * so skew the offset.
+     */
+    if (dev_addr == CFG_DEF_EEPROM_ADDR)
+	offset += SDRAM_SPD_DATA_SIZE;
+
+    /* Try to read the I2C EEPROM */
+#if defined(VXWORKS)
+    {
+	int i;
+	for( i = 0; i < count; ++i ) {
+	    buf[ i ] = iicReadByte( dev_addr, offset+i );
+	}
+    }
+#else
+    if (eeprom_read(dev_addr, offset, buf, count)) {
+	printf("Failed to read %d bytes from VPD EEPROM 0x%x @ 0x%x\n",
+	       count, dev_addr, offset);
+	return NULL;
+    }
+#endif
+
+    return buf;
+} /* vpd_reader() */
+
+
+/*
+ * vpd_get_packet() - returns next VPD packet or NULL.
+ */
+static vpd_packet_t *vpd_get_packet(vpd_packet_t *vpd_packet)
+{
+    vpd_packet_t *packet = vpd_packet;
+
+    if (packet != NULL) {
+	if (packet->identifier == VPD_PID_TERM)
+	    return NULL;
+	else
+	    packet = (vpd_packet_t *)((char *)packet + packet->size + 2);
+    }
+
+    return packet;
+} /* vpd_get_packet() */
+
+
+/*
+ * vpd_find_packet() - Locates and returns the specified
+ *		       VPD packet or NULL on error.
+ */
+static vpd_packet_t *vpd_find_packet(vpd_t *vpd, unsigned char ident)
+{
+    vpd_packet_t *packet = (vpd_packet_t *)&vpd->packets;
+
+    /* Guaranteed illegal */
+    if (ident == VPD_PID_GI)
+	return NULL;
+
+    /* Scan tuples looking for a match */
+    while ((packet->identifier != ident) &&
+	   (packet->identifier != VPD_PID_TERM))
+	packet = vpd_get_packet(packet);
+
+    /* Did we find it? */
+    if ((packet->identifier) && (packet->identifier != ident))
+	return NULL;
+    return packet;
+}
+
+
+/*
+ * vpd_is_valid() - Validates contents of VPD data
+ *		    in I2C EEPROM.  Returns 1 for
+ *		    success or 0 for failure.
+ */
+static int vpd_is_valid(unsigned dev_addr, unsigned char *buf)
+{
+    unsigned	    num_bytes;
+    vpd_packet_t    *packet;
+    vpd_t	    *vpd = (vpd_t *)buf;
+    unsigned short  stored_crc16, calc_crc16 = 0xffff;
+
+    /* Check Eyecatcher */
+    if (strncmp(vpd->header.eyecatcher, VPD_EYECATCHER, VPD_EYE_SIZE) != 0) {
+	unsigned offset = 0;
+	if (dev_addr == CFG_DEF_EEPROM_ADDR)
+	    offset += SDRAM_SPD_DATA_SIZE;
+	printf("Error: VPD EEPROM 0x%x corrupt @ 0x%x\n", dev_addr, offset);
+
+	return 0;
+    }
+
+    /* Check Length */
+    if (vpd->header.size> VPD_MAX_EEPROM_SIZE) {
+	printf("Error: VPD EEPROM 0x%x contains bad size 0x%x\n",
+	       dev_addr, vpd->header.size);
+	return 0;
+    }
+
+    /* Now find the termination packet */
+    if ((packet = vpd_find_packet(vpd, VPD_PID_TERM)) == NULL) {
+	printf("Error: VPD EEPROM 0x%x missing termination packet\n",
+	       dev_addr);
+	return 0;
+    }
+
+    /* Calculate data size */
+    num_bytes = (unsigned long)((unsigned char *)packet -
+				(unsigned char *)vpd + sizeof(vpd_packet_t));
+
+    /* Find stored CRC and clear it */
+    if ((packet = vpd_find_packet(vpd, VPD_PID_CRC)) == NULL) {
+	printf("Error: VPD EEPROM 0x%x missing CRC\n", dev_addr);
+	return 0;
+    }
+    stored_crc16 = *((ushort *)packet->data);
+    *(ushort *)packet->data = 0;
+
+    /* OK, lets calculate the CRC and check it */
+#if defined(VXWORKS)
+    calc_crc16 = (0xffff & crc32(buf, num_bytes));
+#else
+    calc_crc16 = (0xffff & crc32(0, buf, num_bytes));
+#endif
+    *(ushort *)packet->data = stored_crc16;     /* Now restore the CRC */
+    if (stored_crc16 != calc_crc16) {
+	printf("Error: VPD EEPROM 0x%x has bad CRC 0x%x\n",
+	       dev_addr, stored_crc16);
+	return 0;
+    }
+
+    return 1;
+} /* vpd_is_valid() */
+
+
+/*
+ * size_ok() - Check to see if packet size matches
+ *	       size of data we want. Returns 1 for
+ *	       good match or 0 for failure.
+ */
+static int size_ok(vpd_packet_t *packet, unsigned long size)
+{
+    if (packet->size != size) {
+	printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+	return 0;
+    }
+    return 1;
+} /* size_ok() */
+
+
+/*
+ * strlen_ok() - Check to see if packet size matches
+ *		 strlen of the string we want to populate.
+ *		 Returns 1 for valid length or 0 for failure.
+ */
+static int strlen_ok(vpd_packet_t *packet, unsigned long length)
+{
+    if (packet->size >= length) {
+	printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+	return 0;
+    }
+    return 1;
+} /* strlen_ok() */
+
+
+/*
+ * get_vpd_data() - populates the passed VPD structure 'vpdInfo'
+ *		    with data obtained from the specified
+ *		    I2C EEPROM 'dev_addr'.  Returns 0 for
+ *		    success or 1 for failure.
+ */
+int vpd_get_data(unsigned char dev_addr, VPD *vpdInfo)
+{
+    unsigned char buf[VPD_EEPROM_SIZE];
+    vpd_t *vpd = (vpd_t *)buf;
+    vpd_packet_t *packet;
+
+    if (vpdInfo == NULL)
+	return 1;
+
+     /*
+      * Fill vpdInfo with 0s to blank out
+      * unused fields, fill vpdInfo->ethAddrs
+      * with all 0xffs so that other's code can
+      * determine how many real Ethernet addresses
+      * there are.  OUIs starting with 0xff are
+      * broadcast addresses, and would never be
+      * permantely stored.
+      */
+    memset((void *)vpdInfo, 0, sizeof(VPD));
+    memset((void *)&vpdInfo->ethAddrs, 0xff, sizeof(vpdInfo->ethAddrs));
+    vpdInfo->_devAddr = dev_addr;
+
+    /* Read the minimum size first */
+    if (vpd_reader(buf, dev_addr, 0, VPD_EEPROM_SIZE) == NULL) {
+	return 1;
+    }
+
+    /* Check validity of VPD data */
+    if (!vpd_is_valid(dev_addr, buf)) {
+	printf("VPD Data is INVALID!\n");
+	return 1;
+    }
+
+    /*
+      * Walk all the packets and populate
+      * the VPD info structure.
+      */
+    packet = (vpd_packet_t *)&vpd->packets;
+    do {
+	switch (packet->identifier) {
+	    case VPD_PID_GI:
+		printf("Error: Illegal VPD value\n");
+		break;
+	    case VPD_PID_PID:
+		if (strlen_ok(packet, MAX_PROD_ID)) {
+		    strncpy(vpdInfo->productId,
+			    packet->data, packet->size);
+		}
+		break;
+	    case VPD_PID_REV:
+		if (size_ok(packet, sizeof(char)))
+		    vpdInfo->revisionId = *packet->data;
+		break;
+	    case VPD_PID_SN:
+		if (size_ok(packet, sizeof(unsigned long))) {
+		    vpdInfo->serialNum =
+			*(unsigned long *)packet->data;
+		}
+		break;
+	    case VPD_PID_MANID:
+		if (size_ok(packet, sizeof(unsigned char)))
+		    vpdInfo->manuID = *packet->data;
+		break;
+	    case VPD_PID_PCO:
+		if (size_ok(packet, sizeof(unsigned long))) {
+		    vpdInfo->configOpt =
+			*(unsigned long *)packet->data;
+		}
+		break;
+	    case VPD_PID_SYSCLK:
+		if (size_ok(packet, sizeof(unsigned long)))
+		    vpdInfo->sysClk = *(unsigned long *)packet->data;
+		break;
+	    case VPD_PID_SERCLK:
+		if (size_ok(packet, sizeof(unsigned long)))
+		    vpdInfo->serClk = *(unsigned long *)packet->data;
+		break;
+	    case VPD_PID_FLASH:
+		if (size_ok(packet, 9)) {	/* XXX - hardcoded,
+						   padding in struct */
+		    memcpy(&vpdInfo->flashCfg, packet->data, 9);
+		}
+		break;
+	    case VPD_PID_ETHADDR:
+		memcpy(vpdInfo->ethAddrs, packet->data, packet->size);
+		break;
+	    case VPD_PID_POTS:
+		if (size_ok(packet, sizeof(char)))
+		    vpdInfo->numPOTS = (unsigned)*packet->data;
+		break;
+	    case VPD_PID_DS1:
+		if (size_ok(packet, sizeof(char)))
+		    vpdInfo->numDS1 = (unsigned)*packet->data;
+	    case VPD_PID_GAL:
+	    case VPD_PID_CRC:
+	    case VPD_PID_TERM:
+		break;
+	    default:
+		printf("Warning: Found unknown VPD packet ID 0x%x\n",
+		       packet->identifier);
+		break;
+	}
+    } while ((packet = vpd_get_packet(packet)));
+
+    return 0;
+} /* end get_vpd_data() */
+
+
+/*
+ * vpd_init() - Initialize default VPD environment
+ */
+int vpd_init(unsigned char dev_addr)
+{
+    return (0);
+} /* vpd_init() */
+
+
+/*
+ * vpd_print() - Pretty print the VPD data.
+ */
+void vpd_print(VPD *vpdInfo)
+{
+    const char *const sp    = "";
+    const char *const sfmt  = "%4s%-20s: \"%s\"\n";
+    const char *const cfmt  = "%4s%-20s: '%c'\n";
+    const char *const dfmt  = "%4s%-20s: %ld\n";
+    const char *const hfmt  = "%4s%-20s: %08lX\n";
+    const char *const dsfmt = "%4s%-20s: %d\n";
+    const char *const hsfmt = "%4s%-20s: %04X\n";
+    const char *const dhfmt = "%4s%-20s: %ld (%lX)\n";
+
+    printf("VPD read from I2C device: %02X\n", vpdInfo->_devAddr);
+
+    if (vpdInfo->productId[0])
+	printf(sfmt, sp, "Product ID", vpdInfo->productId);
+    else
+	printf(sfmt, sp, "Product ID", "UNKNOWN");
+
+    if (vpdInfo->revisionId)
+	printf(cfmt, sp, "Revision ID", vpdInfo->revisionId);
+
+    if (vpdInfo->serialNum)
+	printf(dfmt, sp, "Serial Number", vpdInfo->serialNum);
+
+    if (vpdInfo->manuID)
+	printf(dfmt, sp, "Manufacture ID", (long)vpdInfo->manuID);
+
+    if (vpdInfo->configOpt)
+	printf(hfmt, sp, "Configuration", vpdInfo->configOpt);
+
+    if (vpdInfo->sysClk)
+	printf(dhfmt, sp, "System Clock", vpdInfo->sysClk, vpdInfo->sysClk);
+
+    if (vpdInfo->serClk)
+	printf(dhfmt, sp, "Serial Clock", vpdInfo->serClk, vpdInfo->serClk);
+
+    if (vpdInfo->numPOTS)
+	printf(dfmt, sp, "Number of POTS lines", vpdInfo->numPOTS);
+
+    if (vpdInfo->numDS1)
+	printf(dfmt, sp, "Number of DS1s", vpdInfo->numDS1);
+
+    /* Print Ethernet Addresses */
+    if (vpdInfo->ethAddrs[0][0] != 0xff) {
+	int i, j;
+	printf("%4sEtherNet Address(es): ", sp);
+	for (i = 0; i < MAX_ETH_ADDRS; i++) {
+	    if (vpdInfo->ethAddrs[i][0] != 0xff) {
+		for (j = 0; j < 6; j++) {
+		    printf("%02X", vpdInfo->ethAddrs[i][j]);
+		    if (((j + 1) % 6) != 0)
+			printf(":");
+		    else
+			printf(" ");
+		}
+		if (((i + 1) % 3) == 0) printf("\n%24s: ", sp);
+	    }
+	}
+	printf("\n");
+    }
+
+    if (vpdInfo->flashCfg.mfg && vpdInfo->flashCfg.dev) {
+	printf("Main Flash Configuration:\n");
+	printf(hsfmt, sp, "Manufacture ID", vpdInfo->flashCfg.mfg);
+	printf(hsfmt, sp, "Device ID",      vpdInfo->flashCfg.dev);
+	printf(dsfmt, sp, "Device Width",   vpdInfo->flashCfg.devWidth);
+	printf(dsfmt, sp, "Num. Devices",   vpdInfo->flashCfg.numDevs);
+	printf(dsfmt, sp, "Num. Columns",   vpdInfo->flashCfg.numCols);
+	printf(dsfmt, sp, "Column Width",   vpdInfo->flashCfg.colWidth);
+	printf(dsfmt, sp, "WE Data Width",  vpdInfo->flashCfg.weDataWidth);
+    }
+} /* vpd_print() */
+
diff --git a/board/w7o/vpd.h b/board/w7o/vpd.h
new file mode 100644
index 0000000..35bbe3e
--- /dev/null
+++ b/board/w7o/vpd.h
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+
+#ifndef _VPD_H_
+#define _VPD_H_
+
+/*
+ * Main Flash Configuration.
+ */
+typedef struct flashCfg_s {
+    unsigned short mfg;				/* Manufacture ID */
+    unsigned short dev;				/* Device ID */
+    unsigned char devWidth;			/* Device Width */
+    unsigned char numDevs;			/* Number of devices */
+    unsigned char numCols;			/* Number of columns */
+    unsigned char colWidth;			/* Width of a column */
+    unsigned char weDataWidth;			/* Write/Erase Data Width */
+} flashCfg_t;
+
+/*
+ * Vital Product Data - VPD
+ */
+#define MAX_PROD_ID		15
+#define MAX_ETH_ADDRS		10
+typedef unsigned char EthAddr[6];
+typedef struct vpd {
+    unsigned char _devAddr;			/* Device address during read */
+    char productId[MAX_PROD_ID];		/* Product ID */
+    char revisionId;				/* Revision ID as a char */
+    unsigned long serialNum;			/* Serial number */
+    unsigned char  manuID;			/* Manufact ID - byte int */
+    unsigned long configOpt;			/* Config Option - bit field */
+    unsigned long sysClk;			/* System clock in Hertz */
+    unsigned long serClk;			/* Ext. clock in Hertz */
+    flashCfg_t flashCfg;			/* Flash configuration */
+    unsigned long numPOTS;			/* Number of POTS lines */
+    unsigned long numDS1;			/* Number of DS1 circuits */
+    EthAddr ethAddrs[MAX_ETH_ADDRS];		/* Ethernet MAC, 1st = craft */
+} VPD;
+
+
+#define VPD_MAX_EEPROM_SIZE	512		/* Max size VPD EEPROM */
+#define SDRAM_SPD_DATA_SIZE	128		/* Size SPD in VPD EEPROM */
+
+/*
+ * PIDs - Packet Identifiers
+ */
+#define VPD_PID_GI		0x0		/* Guaranted Illegal */
+#define VPD_PID_PID		0x1		/* Product Identifier */
+#define VPD_PID_REV		0x2		/* Product Revision */
+#define VPD_PID_SN		0x3		/* Serial Number */
+#define VPD_PID_MANID		0x4		/* Manufacture ID */
+#define VPD_PID_PCO		0x5		/* Product configuration */
+#define VPD_PID_SYSCLK		0x6		/* System Clock */
+#define VPD_PID_SERCLK		0x7		/* Ser. Clk. Speed in Hertz */
+#define VPD_PID_CRC		0x8		/* VPD CRC */
+#define VPD_PID_FLASH		0x9		/* Flash Configuration */
+#define VPD_PID_ETHADDR		0xA		/* Ethernet Address(es) */
+#define VPD_PID_GAL		0xB		/* Galileo Switch Config */
+#define VPD_PID_POTS		0xC		/* Number of POTS Lines */
+#define VPD_PID_DS1		0xD		/* Number of DS1s */
+#define VPD_PID_TERM		0xFF		/* Termination packet */
+
+/*
+ * VPD - Eyecatcher/Magic
+ */
+#define VPD_EYECATCHER		"W7O"
+#define VPD_EYE_SIZE		3
+typedef struct vpd_header {
+    unsigned char eyecatcher[VPD_EYE_SIZE];	/* eyecatcher - "W7O" */
+    unsigned short size __attribute__((packed)); /* size of EEPROM */
+} vpd_header_t;
+
+
+#define VPD_DATA_SIZE (VPD_MAX_EEPROM_SIZE - SDRAM_SPD_DATA_SIZE - \
+                        sizeof(vpd_header_t))
+typedef struct vpd_s {
+    vpd_header_t header;
+    unsigned char packets[VPD_DATA_SIZE];
+} vpd_t;
+
+typedef struct vpd_packet {
+    unsigned char identifier;
+    unsigned char size;
+    unsigned char data[1];
+} vpd_packet_t;
+
+/*
+ * VPD configOpt bit mask
+ */
+#define VPD_HAS_BBRAM		0x1		/* Battery backed SRAM */
+#define VPD_HAS_RTC		0x2		/* Battery backed RTC */
+#define VPD_HAS_EXT_SER_CLK	0x4		/* External serial clock */
+#define VPD_HAS_SER_TRANS_1	0x8		/* COM1 transceiver */
+#define VPD_HAS_SER_TRANS_2	0x10		/* COM2 transceiver */
+#define VPD_HAS_CRAFT_PHY	0x20		/* CRAFT Ethernet */
+#define VPD_HAS_DTT_1		0x40		/* I2C Digital therm. #1 */
+#define VPD_HAS_DTT_2		0x80		/* I2C Digital therm. #2 */
+#define VPD_HAS_1000_UP_LASER	0x100		/* GMM - 1000Mbit Uplink */
+#define VPD_HAS_70KM_UP_LASER	0x200		/* CMM - 70KM Uplink laser */
+#define VPD_HAS_2_UPLINKS	0x400		/* CMM - 2 uplink lasers */
+#define VPD_HAS_FPGA		0x800		/* Has 1 or more FPGAs */
+#define VPD_HAS_DFA		0x1000		/* CLM - Has 2 Fiber Inter. */
+#define VPD_HAS_GAL_SWITCH	0x2000		/* GMM - Has a Gal switch */
+#define VPD_HAS_POTS_LINES	0x4000		/* GMM - Has POTS lines */
+#define VPD_HAS_DS1_CHANNELS	0x8000		/* GMM - Has DS1 channels */
+#define VPD_HAS_CABLE_RETURN	0x10000		/* GBM/GBR - Cable ret. path */
+
+#define VPD_EEPROM_SIZE         (256 - SDRAM_SPD_DATA_SIZE) /* Size EEPROM */
+
+extern int vpd_get_data(unsigned char dev_addr, VPD *vpd);
+extern void vpd_print(VPD *vpdInfo);
+
+#endif /* _VPD_H_ */
+
diff --git a/board/w7o/w7o.c b/board/w7o/w7o.c
new file mode 100644
index 0000000..b404d61
--- /dev/null
+++ b/board/w7o/w7o.c
@@ -0,0 +1,271 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+
+#include <common.h>
+#include "w7o.h"
+#include <asm/processor.h>
+
+#include "vpd.h"
+#include "errors.h"
+#include <watchdog.h>
+
+unsigned long get_dram_size(void);
+
+/*
+ * Macros to transform values
+ * into environment strings.
+ */
+#define XMK_STR(x)	#x
+#define MK_STR(x)	XMK_STR(x)
+
+/* ------------------------------------------------------------------------- */
+
+int board_pre_init (void)
+{
+#if defined(CONFIG_W7OLMG)
+    /*
+     * Setup GPIO pins - reset devices.
+     */
+    out32(IBM405GP_GPIO0_ODR, 0x10000000);	/* one open drain pin */
+    out32(IBM405GP_GPIO0_OR, 0x3E000000);	/* set output pins to default */
+    out32(IBM405GP_GPIO0_TCR, 0x7f800000);	/* setup for output */
+
+    /*
+     * IRQ 0-15  405GP internally generated; active high; level sensitive
+     * IRQ 16    405GP internally generated; active low; level sensitive
+     * IRQ 17-24 RESERVED
+     * IRQ 25 (EXT IRQ 0) XILINX; active low; level sensitive
+     * IRQ 26 (EXT IRQ 1) PCI INT A; active low; level sensitive
+     * IRQ 27 (EXT IRQ 2) PCI INT B; active low; level sensitive
+     * IRQ 28 (EXT IRQ 3) SAM 2; active low; level sensitive
+     * IRQ 29 (EXT IRQ 4) Battery Bad; active low; level sensitive
+     * IRQ 30 (EXT IRQ 5) Level One PHY; active low; level sensitive
+     * IRQ 31 (EXT IRQ 6) SAM 1; active high; level sensitive
+     */
+    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
+    mtdcr(uicer, 0x00000000);			/* disable all ints */
+
+    mtdcr(uiccr, 0x00000000);			/* set all to be non-critical*/
+    mtdcr(uicpr, 0xFFFFFF80);			/* set int polarities */
+    mtdcr(uictr, 0x10000000);			/* set int trigger levels */
+    mtdcr(uicvcr, 0x00000001);			/* set vect base=0,
+						   INT0 highest priority*/
+
+    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
+
+#elif defined(CONFIG_W7OLMC)
+    /*
+     * Setup GPIO pins
+     */
+    out32(IBM405GP_GPIO0_ODR, 0x01800000);	/* XCV Done Open Drain */
+    out32(IBM405GP_GPIO0_OR,  0x03800000);	/* set out pins to default */
+    out32(IBM405GP_GPIO0_TCR, 0x66C00000);	/* setup for output */
+
+    /*
+     * IRQ 0-15  405GP internally generated; active high; level sensitive
+     * IRQ 16    405GP internally generated; active low; level sensitive
+     * IRQ 17-24 RESERVED
+     * IRQ 25 (EXT IRQ 0) DBE 0; active low; level sensitive
+     * IRQ 26 (EXT IRQ 1) DBE 1; active low; level sensitive
+     * IRQ 27 (EXT IRQ 2) DBE 2; active low; level sensitive
+     * IRQ 28 (EXT IRQ 3) DBE Common; active low; level sensitive
+     * IRQ 29 (EXT IRQ 4) PCI; active low; level sensitive
+     * IRQ 30 (EXT IRQ 5) RCMM Reset; active low; level sensitive
+     * IRQ 31 (EXT IRQ 6) PHY; active high; level sensitive
+     */
+    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
+    mtdcr(uicer, 0x00000000);			/* disable all ints */
+
+    mtdcr(uiccr, 0x00000000);			/* set all to be non-critical*/
+    mtdcr(uicpr, 0xFFFFFF80);			/* set int polarities */
+    mtdcr(uictr, 0x10000000);			/* set int trigger levels */
+    mtdcr(uicvcr, 0x00000001);			/* set vect base=0,
+						   INT0 highest priority*/
+
+    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
+
+#else /* Unknown */
+#    error "Unknown W7O board configuration"
+#endif
+
+    WATCHDOG_RESET();				/* Reset the watchdog */
+    temp_uart_init();				/* init the uart for debug */
+    WATCHDOG_RESET();				/* Reset the watchdog */
+    test_led();					/* test the LEDs */
+    test_sdram(get_dram_size());		/* test the dram */
+    log_stat(ERR_POST1);			/* log status,post1 complete */
+    return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+int checkboard (void)
+{
+    VPD vpd;
+
+    puts ("Board: ");
+
+    /* VPD data present in I2C EEPROM */
+    if (vpd_get_data(CFG_DEF_EEPROM_ADDR, &vpd) == 0) {
+	/*
+	 * Known board type.
+	 */
+	if (vpd.productId[0] &&
+	    ((strncmp(vpd.productId, "GMM", 3) == 0) ||
+	     (strncmp(vpd.productId, "CMM", 3) == 0))) {
+
+	    /* Output board information on startup */
+	    printf("\"%s\", revision '%c', serial# %ld, manufacturer %u\n",
+		   vpd.productId, vpd.revisionId, vpd.serialNum, vpd.manuID);
+	    return (0);
+	}
+    }
+
+    puts ("### Unknown HW ID - assuming NOTHING\n");
+    return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+    return get_dram_size();
+}
+
+unsigned long get_dram_size (void)
+{
+    int tmp, i, regs[4];
+    int size = 0;
+
+    /* Get bank Size registers */
+    mtdcr(memcfga, mem_mb0cf);			/* get bank 0 config reg */
+    regs[0] = mfdcr(memcfgd);
+
+    mtdcr(memcfga, mem_mb1cf);			/* get bank 1 config reg */
+    regs[1] = mfdcr(memcfgd);
+
+    mtdcr(memcfga, mem_mb2cf);			/* get bank 2 config reg */
+    regs[2] = mfdcr(memcfgd);
+
+    mtdcr(memcfga, mem_mb3cf);			/* get bank 3 config reg */
+    regs[3] = mfdcr(memcfgd);
+
+    /* compute the size, add each bank if enabled */
+    for(i = 0; i < 4; i++) {
+	if (regs[i] & 0x0001) {			/* if enabled, */
+	    tmp = ((regs[i] >> (31 - 14)) & 0x7); /* get size bits */
+	    tmp = 0x400000 << tmp;		/* Size bits X 4MB = size */
+	    size += tmp;
+	}
+    }
+
+    return size;
+}
+
+int misc_init_f (void)
+{
+    return 0;
+}
+
+static void
+w7o_env_init(VPD *vpd)
+{
+    /*
+     * Read VPD
+     */
+    if (vpd_get_data(CFG_DEF_EEPROM_ADDR, vpd) != 0)
+	return;
+
+     /*
+      * Known board type.
+      */
+    if (vpd->productId[0] &&
+	((strncmp(vpd->productId, "GMM", 3) == 0) ||
+	 (strncmp(vpd->productId, "CMM", 3) == 0))) {
+	char buf[30];
+	char *eth;
+	unsigned char *serial = getenv("serial#");
+	unsigned char *ethaddr = getenv("ethaddr");
+
+	/* Set 'serial#' envvar if serial# isn't set */
+	if (!serial) {
+	    sprintf(buf, "%s-%ld", vpd->productId, vpd->serialNum);
+	    setenv("serial#", buf);
+	}
+
+	/* Set 'ethaddr' envvar if 'ethaddr' envvar is the default */
+	eth = vpd->ethAddrs[0];
+	if (ethaddr && (strcmp(ethaddr, MK_STR(CONFIG_ETHADDR)) == 0)) {
+	    /* Now setup ethaddr */
+	    sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+		    eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
+	    setenv("ethaddr", buf);
+	}
+    }
+} /* w7o_env_init() */
+
+
+int misc_init_r (void)
+{
+    VPD vpd;					/* VPD information */
+
+#if defined(CONFIG_W7OLMG)
+    unsigned long greg;				/* GPIO Register */
+
+    greg = in32(IBM405GP_GPIO0_OR);
+
+    /*
+     * XXX - Unreset devices - this should be moved into VxWorks driver code
+     */
+    greg |= 0x41800000L;			/* SAM, PHY, Galileo */
+
+    out32(IBM405GP_GPIO0_OR, greg);		/* set output pins to default */
+#endif /* CONFIG_W7OLMG */
+
+    /*
+     * Initialize W7O environment variables
+     */
+    w7o_env_init(&vpd);
+
+    /*
+     * Initialize the FPGA(s).
+     */
+    if (init_fpga() == 0)
+	test_fpga((unsigned short *)CONFIG_FPGAS_BASE);
+
+    /* More POST testing. */
+    post2();
+
+    /* Done with hardware initialization and POST. */
+    log_stat(ERR_POSTOK);
+
+    /* Call silly, fail safe boot init routine */
+    init_fsboot();
+
+	return (0);
+}
+
diff --git a/common/cmd_doc.c b/common/cmd_doc.c
new file mode 100644
index 0000000..37d0fbd
--- /dev/null
+++ b/common/cmd_doc.c
@@ -0,0 +1,1563 @@
+/*
+ * Driver for Disk-On-Chip 2000 and Millennium
+ * (c) 1999 Machine Vision Holdings, Inc.
+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
+ *
+ * $Id: doc2000.c,v 1.46 2001/10/02 15:05:13 dwmw2 Exp $
+ */
+
+#include <common.h>
+#include <config.h>
+#include <command.h>
+#include <malloc.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+# define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg)
+#else
+# define SHOW_BOOT_PROGRESS(arg)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ids.h>
+#include <linux/mtd/doc2000.h>
+#include <linux/mtd/nftl.h>
+
+#ifdef CFG_DOC_SUPPORT_2000
+#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
+#else
+#define DoC_is_2000(doc) (0)
+#endif
+
+#ifdef CFG_DOC_SUPPORT_MILLENNIUM
+#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
+#else
+#define DoC_is_Millennium(doc) (0)
+#endif
+
+/* CFG_DOC_PASSIVE_PROBE:
+   In order to ensure that the BIOS checksum is correct at boot time, and
+   hence that the onboard BIOS extension gets executed, the DiskOnChip
+   goes into reset mode when it is read sequentially: all registers
+   return 0xff until the chip is woken up again by writing to the
+   DOCControl register.
+
+   Unfortunately, this means that the probe for the DiskOnChip is unsafe,
+   because one of the first things it does is write to where it thinks
+   the DOCControl register should be - which may well be shared memory
+   for another device. I've had machines which lock up when this is
+   attempted. Hence the possibility to do a passive probe, which will fail
+   to detect a chip in reset mode, but is at least guaranteed not to lock
+   the machine.
+
+   If you have this problem, uncomment the following line:
+#define CFG_DOC_PASSIVE_PROBE
+*/
+
+#undef	DOC_DEBUG
+#undef	ECC_DEBUG
+#undef	PSYCHO_DEBUG
+#undef	NFTL_DEBUG
+
+static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE];
+
+/* Current DOC Device	*/
+static int curr_device = -1;
+
+/* ------------------------------------------------------------------------- */
+
+int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    int rcode = 0;
+
+    switch (argc) {
+    case 0:
+    case 1:
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    case 2:
+        if (strcmp(argv[1],"info") == 0) {
+		int i;
+
+		putc ('\n');
+
+		for (i=0; i<CFG_MAX_DOC_DEVICE; ++i) {
+			if(doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN)
+				continue; /* list only known devices */
+			printf ("Device %d: ", i);
+			doc_print(&doc_dev_desc[i]);
+		}
+		return 0;
+
+	} else if (strcmp(argv[1],"device") == 0) {
+		if ((curr_device < 0) || (curr_device >= CFG_MAX_DOC_DEVICE)) {
+			puts ("\nno devices available\n");
+			return 1;
+		}
+		printf ("\nDevice %d: ", curr_device);
+		doc_print(&doc_dev_desc[curr_device]);
+		return 0;
+	}
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    case 3:
+	if (strcmp(argv[1],"device") == 0) {
+		int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+		printf ("\nDevice %d: ", dev);
+		if (dev >= CFG_MAX_DOC_DEVICE) {
+			puts ("unknown device\n");
+			return 1;
+		}
+		doc_print(&doc_dev_desc[dev]);
+		/*doc_print (dev);*/
+
+		if (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN) {
+			return 1;
+		}
+
+		curr_device = dev;
+
+		puts ("... is now current device\n");
+
+		return 0;
+	}
+
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    default:
+	/* at least 4 args */
+
+	if (strcmp(argv[1],"read") == 0 || strcmp(argv[1],"write") == 0) {
+		ulong addr = simple_strtoul(argv[2], NULL, 16);
+		ulong off  = simple_strtoul(argv[3], NULL, 16);
+		ulong size = simple_strtoul(argv[4], NULL, 16);
+		int cmd    = (strcmp(argv[1],"read") == 0);
+		int ret, total;
+
+		printf ("\nDOC %s: device %d offset %ld, size %ld ... ",
+			cmd ? "read" : "write", curr_device, off, size);
+
+		ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size,
+			     &total, (u_char*)addr);
+
+		printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write",
+			ret ? "ERROR" : "OK");
+
+		return ret;
+	} else if (strcmp(argv[1],"erase") == 0) {
+		ulong off = simple_strtoul(argv[2], NULL, 16);
+		ulong size = simple_strtoul(argv[3], NULL, 16);
+		int ret;
+
+		printf ("\nDOC erase: device %d offset %ld, size %ld ... ",
+			curr_device, off, size);
+
+		ret = doc_erase (doc_dev_desc + curr_device, off, size);
+
+		printf("%s\n", ret ? "ERROR" : "OK");
+
+		return ret;
+	} else {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		rcode = 1;
+	}
+
+	return rcode;
+    }
+}
+
+int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	char *boot_device = NULL;
+	char *ep;
+	int dev;
+	ulong cnt;
+	ulong addr;
+	ulong offset = 0;
+	image_header_t *hdr;
+	int rcode = 0;
+
+	switch (argc) {
+	case 1:
+		addr = CFG_LOAD_ADDR;
+		boot_device = getenv ("bootdevice");
+		break;
+	case 2:
+		addr = simple_strtoul(argv[1], NULL, 16);
+		boot_device = getenv ("bootdevice");
+		break;
+	case 3:
+		addr = simple_strtoul(argv[1], NULL, 16);
+		boot_device = argv[2];
+		break;
+	case 4:
+		addr = simple_strtoul(argv[1], NULL, 16);
+		boot_device = argv[2];
+		offset = simple_strtoul(argv[3], NULL, 16);
+		break;
+	default:
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	if (!boot_device) {
+		puts ("\n** No boot device **\n");
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	dev = simple_strtoul(boot_device, &ep, 16);
+
+	if ((dev >= CFG_MAX_DOC_DEVICE) ||
+	    (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) {
+		printf ("\n** Device %d not available\n", dev);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n",
+		dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr,
+		offset);
+
+	if (doc_rw (doc_dev_desc + dev, 1, offset,
+		    SECTORSIZE, NULL, (u_char *)addr)) {
+		printf ("** Read error on %d\n", dev);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	hdr = (image_header_t *)addr;
+
+	if (hdr->ih_magic == IH_MAGIC) {
+
+		print_image_hdr (hdr);
+
+		cnt = (hdr->ih_size + sizeof(image_header_t));
+		cnt -= SECTORSIZE;
+	} else {
+		puts ("\n** Bad Magic Number **\n");
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
+		    NULL, (u_char *)(addr+SECTORSIZE))) {
+		printf ("** Read error on %d\n", dev);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	/* Loading ok, update default load address */
+
+	load_addr = addr;
+
+	/* Check if we should attempt an auto-start */
+	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+		char *local_args[2];
+		extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+		local_args[0] = argv[0];
+		local_args[1] = NULL;
+
+		printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+
+		do_bootm (cmdtp, 0, 1, local_args);
+		rcode = 1;
+	}
+	return rcode;
+}
+
+int doc_rw (struct DiskOnChip* this, int cmd,
+	    loff_t from, size_t len,
+	    size_t * retlen, u_char * buf)
+{
+	int noecc, ret = 0, n, total = 0;
+	char eccbuf[6];
+
+	while(len) {
+		/* The ECC will not be calculated correctly if
+		   less than 512 is written or read */
+		noecc = (from != (from | 0x1ff) + 1) ||	(len < 0x200);
+
+		if (cmd)
+			ret = doc_read_ecc(this, from, len,
+					   &n, (u_char*)buf,
+					   noecc ? NULL : eccbuf);
+		else
+			ret = doc_write_ecc(this, from, len,
+					    &n, (u_char*)buf,
+					    noecc ? NULL : eccbuf);
+
+		if (ret)
+			break;
+
+		from  += n;
+		buf   += n;
+		total += n;
+		len   -= n;
+	}
+
+	if (retlen)
+		*retlen = total;
+
+	return ret;
+}
+
+void doc_print(struct DiskOnChip *this) {
+	printf("%s at 0x%lX,\n"
+	       "\t  %d chip%s %s, size %d MB, \n"
+	       "\t  total size %ld MB, sector size %ld kB\n",
+	       this->name, this->physadr, this->numchips,
+	       this->numchips>1 ? "s" : "", this->chips_name,
+	       1 << (this->chipshift - 20),
+	       this->totlen >> 20, this->erasesize >> 10);
+
+	if (this->nftl_found) {
+		struct NFTLrecord *nftl = &this->nftl;
+		unsigned long bin_size, flash_size;
+
+		bin_size = nftl->nb_boot_blocks * this->erasesize;
+		flash_size = (nftl->nb_blocks - nftl->nb_boot_blocks) * this->erasesize;
+
+		printf("\t  NFTL boot record:\n"
+		       "\t    Binary partition: size %ld%s\n"
+		       "\t    Flash disk partition: size %ld%s, offset 0x%lx\n",
+		       bin_size > (1 << 20) ? bin_size >> 20 : bin_size >> 10,
+		       bin_size > (1 << 20) ? "MB" : "kB",
+		       flash_size > (1 << 20) ? flash_size >> 20 : flash_size >> 10,
+		       flash_size > (1 << 20) ? "MB" : "kB", bin_size);
+	} else {
+		puts ("\t  No NFTL boot record found.\n");
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* This function is needed to avoid calls of the __ashrdi3 function. */
+static int shr(int val, int shift) {
+	return val >> shift;
+}
+
+/* Perform the required delay cycles by reading from the appropriate register */
+static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
+{
+	volatile char dummy;
+	int i;
+
+	for (i = 0; i < cycles; i++) {
+		if (DoC_is_Millennium(doc))
+			dummy = ReadDOC(doc->virtadr, NOP);
+		else
+			dummy = ReadDOC(doc->virtadr, DOCStatus);
+	}
+
+}
+
+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
+static int _DoC_WaitReady(struct DiskOnChip *doc)
+{
+	unsigned long docptr = doc->virtadr;
+	unsigned long start = get_timer(0);
+
+#ifdef PSYCHO_DEBUG
+	puts ("_DoC_WaitReady called for out-of-line wait\n");
+#endif
+
+	/* Out-of-line routine to wait for chip response */
+	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+#ifdef CFG_DOC_SHORT_TIMEOUT
+		/* it seems that after a certain time the DoC deasserts
+		 * the CDSN_CTRL_FR_B although it is not ready...
+		 * using a short timout solve this (timer increments every ms) */
+		if (get_timer(start) > 10) {
+			return DOC_ETIMEOUT;
+		}
+#else
+		if (get_timer(start) > 10 * 1000) {
+			puts ("_DoC_WaitReady timed out.\n");
+			return DOC_ETIMEOUT;
+		}
+#endif
+		udelay(1);
+        }
+
+	return 0;
+}
+
+static int DoC_WaitReady(struct DiskOnChip *doc)
+{
+	unsigned long docptr = doc->virtadr;
+	/* This is inline, to optimise the common case, where it's ready instantly */
+	int ret = 0;
+
+	/* 4 read form NOP register should be issued in prior to the read from CDSNControl
+	   see Software Requirement 11.4 item 2. */
+	DoC_Delay(doc, 4);
+
+	if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
+		/* Call the out-of-line routine to wait */
+		ret = _DoC_WaitReady(doc);
+
+	/* issue 2 read from NOP register after reading from CDSNControl register
+	   see Software Requirement 11.4 item 2. */
+	DoC_Delay(doc, 2);
+
+	return ret;
+}
+
+/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
+   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command,
+			      unsigned char xtraflags)
+{
+	unsigned long docptr = doc->virtadr;
+
+	if (DoC_is_2000(doc))
+		xtraflags |= CDSN_CTRL_FLASH_IO;
+
+	/* Assert the CLE (Command Latch Enable) line to the flash chip */
+	WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	if (DoC_is_Millennium(doc))
+		WriteDOC(command, docptr, CDSNSlowIO);
+
+	/* Send the command */
+	WriteDOC_(command, docptr, doc->ioreg);
+
+	/* Lower the CLE line */
+	WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
+	return DoC_WaitReady(doc);
+}
+
+/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
+   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
+		       unsigned char xtraflags1, unsigned char xtraflags2)
+{
+	unsigned long docptr;
+	int i;
+
+	docptr = doc->virtadr;
+
+	if (DoC_is_2000(doc))
+		xtraflags1 |= CDSN_CTRL_FLASH_IO;
+
+	/* Assert the ALE (Address Latch Enable) line to the flash chip */
+	WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
+
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Send the address */
+	/* Devices with 256-byte page are addressed as:
+	   Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
+	   * there is no device on the market with page256
+	   and more than 24 bits.
+	   Devices with 512-byte page are addressed as:
+	   Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
+	   * 25-31 is sent only if the chip support it.
+	   * bit 8 changes the read command to be sent
+	   (NAND_CMD_READ0 or NAND_CMD_READ1).
+	 */
+
+	if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
+		if (DoC_is_Millennium(doc))
+			WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+		WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
+	}
+
+	if (doc->page256) {
+		ofs = ofs >> 8;
+	} else {
+		ofs = ofs >> 9;
+	}
+
+	if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
+		for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
+			if (DoC_is_Millennium(doc))
+				WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+			WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
+		}
+	}
+
+	DoC_Delay(doc, 2);	/* Needed for some slow flash chips. mf. */
+
+	/* FIXME: The SlowIO's for millennium could be replaced by
+	   a single WritePipeTerm here. mf. */
+
+	/* Lower the ALE line */
+	WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
+		 CDSNControl);
+
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Wait for the chip to respond - Software requirement 11.4.1 */
+	return DoC_WaitReady(doc);
+}
+
+/* Read a buffer from DoC, taking care of Millennium odditys */
+static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
+{
+	volatile int dummy;
+	int modulus = 0xffff;
+	unsigned long docptr;
+	int i;
+
+	docptr = doc->virtadr;
+
+	if (len <= 0)
+		return;
+
+	if (DoC_is_Millennium(doc)) {
+		/* Read the data via the internal pipeline through CDSN IO register,
+		   see Pipelined Read Operations 11.3 */
+		dummy = ReadDOC(docptr, ReadPipeInit);
+
+		/* Millennium should use the LastDataRead register - Pipeline Reads */
+		len--;
+
+		/* This is needed for correctly ECC calculation */
+		modulus = 0xff;
+	}
+
+	for (i = 0; i < len; i++)
+		buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
+
+	if (DoC_is_Millennium(doc)) {
+		buf[i] = ReadDOC(docptr, LastDataRead);
+	}
+}
+
+/* Write a buffer to DoC, taking care of Millennium odditys */
+static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
+{
+	unsigned long docptr;
+	int i;
+
+	docptr = doc->virtadr;
+
+	if (len <= 0)
+		return;
+
+	for (i = 0; i < len; i++)
+		WriteDOC_(buf[i], docptr, doc->ioreg + i);
+
+	if (DoC_is_Millennium(doc)) {
+		WriteDOC(0x00, docptr, WritePipeTerm);
+	}
+}
+
+
+/* DoC_SelectChip: Select a given flash chip within the current floor */
+
+static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
+{
+	unsigned long docptr = doc->virtadr;
+
+	/* Software requirement 11.4.4 before writing DeviceSelect */
+	/* Deassert the CE line to eliminate glitches on the FCE# outputs */
+	WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Select the individual flash chip requested */
+	WriteDOC(chip, docptr, CDSNDeviceSelect);
+	DoC_Delay(doc, 4);
+
+	/* Reassert the CE line */
+	WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
+		 CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Wait for it to be ready */
+	return DoC_WaitReady(doc);
+}
+
+/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
+
+static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
+{
+	unsigned long docptr = doc->virtadr;
+
+	/* Select the floor (bank) of chips required */
+	WriteDOC(floor, docptr, FloorSelect);
+
+	/* Wait for the chip to be ready */
+	return DoC_WaitReady(doc);
+}
+
+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
+
+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
+{
+	int mfr, id, i;
+	volatile char dummy;
+
+	/* Page in the required floor/chip */
+	DoC_SelectFloor(doc, floor);
+	DoC_SelectChip(doc, chip);
+
+	/* Reset the chip */
+	if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
+#ifdef DOC_DEBUG
+		printf("DoC_Command (reset) for %d,%d returned true\n",
+		       floor, chip);
+#endif
+		return 0;
+	}
+
+
+	/* Read the NAND chip ID: 1. Send ReadID command */
+	if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
+#ifdef DOC_DEBUG
+		printf("DoC_Command (ReadID) for %d,%d returned true\n",
+		       floor, chip);
+#endif
+		return 0;
+	}
+
+	/* Read the NAND chip ID: 2. Send address byte zero */
+	DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
+
+	/* Read the manufacturer and device id codes from the device */
+
+	/* CDSN Slow IO register see Software Requirement 11.4 item 5. */
+	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+	DoC_Delay(doc, 2);
+	mfr = ReadDOC_(doc->virtadr, doc->ioreg);
+
+	/* CDSN Slow IO register see Software Requirement 11.4 item 5. */
+	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+	DoC_Delay(doc, 2);
+	id = ReadDOC_(doc->virtadr, doc->ioreg);
+
+	/* No response - return failure */
+	if (mfr == 0xff || mfr == 0)
+		return 0;
+
+	/* Check it's the same as the first chip we identified.
+	 * M-Systems say that any given DiskOnChip device should only
+	 * contain _one_ type of flash part, although that's not a
+	 * hardware restriction. */
+	if (doc->mfr) {
+		if (doc->mfr == mfr && doc->id == id)
+			return 1;	/* This is another the same the first */
+		else
+			printf("Flash chip at floor %d, chip %d is different:\n",
+			       floor, chip);
+	}
+
+	/* Print and store the manufacturer and ID codes. */
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (mfr == nand_flash_ids[i].manufacture_id &&
+		    id == nand_flash_ids[i].model_id) {
+#ifdef DOC_DEBUG
+			printf("Flash chip found: Manufacturer ID: %2.2X, "
+			       "Chip ID: %2.2X (%s)\n", mfr, id,
+			       nand_flash_ids[i].name);
+#endif
+			if (!doc->mfr) {
+				doc->mfr = mfr;
+				doc->id = id;
+				doc->chipshift =
+				    nand_flash_ids[i].chipshift;
+				doc->page256 = nand_flash_ids[i].page256;
+				doc->pageadrlen =
+				    nand_flash_ids[i].pageadrlen;
+				doc->erasesize =
+				    nand_flash_ids[i].erasesize;
+				doc->chips_name =
+				    nand_flash_ids[i].name;
+				return 1;
+			}
+			return 0;
+		}
+	}
+
+
+#ifdef DOC_DEBUG
+	/* We haven't fully identified the chip. Print as much as we know. */
+	printf("Unknown flash chip found: %2.2X %2.2X\n",
+	       id, mfr);
+#endif
+
+	return 0;
+}
+
+/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
+
+static void DoC_ScanChips(struct DiskOnChip *this)
+{
+	int floor, chip;
+	int numchips[MAX_FLOORS];
+	int maxchips = MAX_CHIPS;
+	int ret = 1;
+
+	this->numchips = 0;
+	this->mfr = 0;
+	this->id = 0;
+
+	if (DoC_is_Millennium(this))
+		maxchips = MAX_CHIPS_MIL;
+
+	/* For each floor, find the number of valid chips it contains */
+	for (floor = 0; floor < MAX_FLOORS; floor++) {
+		ret = 1;
+		numchips[floor] = 0;
+		for (chip = 0; chip < maxchips && ret != 0; chip++) {
+
+			ret = DoC_IdentChip(this, floor, chip);
+			if (ret) {
+				numchips[floor]++;
+				this->numchips++;
+			}
+		}
+	}
+
+	/* If there are none at all that we recognise, bail */
+	if (!this->numchips) {
+		puts ("No flash chips recognised.\n");
+		return;
+	}
+
+	/* Allocate an array to hold the information for each chip */
+	this->chips = malloc(sizeof(struct Nand) * this->numchips);
+	if (!this->chips) {
+		puts ("No memory for allocating chip info structures\n");
+		return;
+	}
+
+	ret = 0;
+
+	/* Fill out the chip array with {floor, chipno} for each
+	 * detected chip in the device. */
+	for (floor = 0; floor < MAX_FLOORS; floor++) {
+		for (chip = 0; chip < numchips[floor]; chip++) {
+			this->chips[ret].floor = floor;
+			this->chips[ret].chip = chip;
+			this->chips[ret].curadr = 0;
+			this->chips[ret].curmode = 0x50;
+			ret++;
+		}
+	}
+
+	/* Calculate and print the total size of the device */
+	this->totlen = this->numchips * (1 << this->chipshift);
+
+#ifdef DOC_DEBUG
+	printf("%d flash chips found. Total DiskOnChip size: %ld MB\n",
+	       this->numchips, this->totlen >> 20);
+#endif
+}
+
+/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
+ *	various device information of the NFTL partition and Bad Unit Table. Update
+ *	the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
+ *	is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
+ */
+static int find_boot_record(struct NFTLrecord *nftl)
+{
+	struct nftl_uci1 h1;
+	struct nftl_oob oob;
+	unsigned int block, boot_record_count = 0;
+	int retlen;
+	u8 buf[SECTORSIZE];
+	struct NFTLMediaHeader *mh = &nftl->MediaHdr;
+	unsigned int i;
+
+	nftl->MediaUnit = BLOCK_NIL;
+	nftl->SpareMediaUnit = BLOCK_NIL;
+
+	/* search for a valid boot record */
+	for (block = 0; block < nftl->nb_blocks; block++) {
+		int ret;
+
+		/* Check for ANAND header first. Then can whinge if it's found but later
+		   checks fail */
+		if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
+					&retlen, buf, NULL))) {
+			static int warncount = 5;
+
+			if (warncount) {
+				printf("Block read at 0x%x failed\n", block * nftl->EraseSize);
+				if (!--warncount)
+					puts ("Further failures for this block will not be printed\n");
+			}
+			continue;
+		}
+
+		if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
+			/* ANAND\0 not found. Continue */
+#ifdef PSYCHO_DEBUG
+			printf("ANAND header not found at 0x%x\n", block * nftl->EraseSize);
+#endif
+			continue;
+		}
+
+#ifdef NFTL_DEBUG
+		printf("ANAND header found at 0x%x\n", block * nftl->EraseSize);
+#endif
+
+		/* To be safer with BIOS, also use erase mark as discriminant */
+		if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
+				8, &retlen, (char *)&h1) < 0)) {
+#ifdef NFTL_DEBUG
+			printf("ANAND header found at 0x%x, but OOB data read failed\n",
+			       block * nftl->EraseSize);
+#endif
+			continue;
+		}
+
+		/* OK, we like it. */
+
+		if (boot_record_count) {
+			/* We've already processed one. So we just check if
+			   this one is the same as the first one we found */
+			if (memcmp(mh, buf, sizeof(struct NFTLMediaHeader))) {
+#ifdef NFTL_DEBUG
+				printf("NFTL Media Headers at 0x%x and 0x%x disagree.\n",
+				       nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
+#endif
+				/* if (debug) Print both side by side */
+				return -1;
+			}
+			if (boot_record_count == 1)
+				nftl->SpareMediaUnit = block;
+
+			boot_record_count++;
+			continue;
+		}
+
+		/* This is the first we've seen. Copy the media header structure into place */
+		memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
+
+		/* Do some sanity checks on it */
+		if (mh->UnitSizeFactor != 0xff) {
+			puts ("Sorry, we don't support UnitSizeFactor "
+			      "of != 1 yet.\n");
+			return -1;
+		}
+
+		nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
+		if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
+			printf ("NFTL Media Header sanity check failed:\n"
+				"nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
+				nftl->nb_boot_blocks, nftl->nb_blocks);
+			return -1;
+		}
+
+		nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
+		if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
+			printf ("NFTL Media Header sanity check failed:\n"
+				"numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
+				nftl->numvunits,
+				nftl->nb_blocks,
+				nftl->nb_boot_blocks);
+			return -1;
+		}
+
+		nftl->nr_sects  = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
+
+		/* If we're not using the last sectors in the device for some reason,
+		   reduce nb_blocks accordingly so we forget they're there */
+		nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN);
+
+		/* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
+		for (i = 0; i < nftl->nb_blocks; i++) {
+			if ((i & (SECTORSIZE - 1)) == 0) {
+				/* read one sector for every SECTORSIZE of blocks */
+				if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize +
+						       i + SECTORSIZE, SECTORSIZE,
+						       &retlen, buf, (char *)&oob)) < 0) {
+					puts ("Read of bad sector table failed\n");
+					return -1;
+				}
+			}
+			/* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
+			if (buf[i & (SECTORSIZE - 1)] != 0xff)
+				nftl->ReplUnitTable[i] = BLOCK_RESERVED;
+		}
+
+		nftl->MediaUnit = block;
+		boot_record_count++;
+
+	} /* foreach (block) */
+
+	return boot_record_count?0:-1;
+}
+
+/* This routine is made available to other mtd code via
+ * inter_module_register.  It must only be accessed through
+ * inter_module_get which will bump the use count of this module.  The
+ * addresses passed back in mtd are valid as long as the use count of
+ * this module is non-zero, i.e. between inter_module_get and
+ * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
+ */
+static void DoC2k_init(struct DiskOnChip* this)
+{
+	struct NFTLrecord *nftl;
+
+	switch (this->ChipID) {
+	case DOC_ChipID_Doc2k:
+		this->name = "DiskOnChip 2000";
+		this->ioreg = DoC_2k_CDSN_IO;
+		break;
+	case DOC_ChipID_DocMil:
+		this->name = "DiskOnChip Millennium";
+		this->ioreg = DoC_Mil_CDSN_IO;
+		break;
+	}
+
+#ifdef DOC_DEBUG
+	printf("%s found at address 0x%lX\n", this->name,
+	       this->physadr);
+#endif
+
+	this->totlen = 0;
+	this->numchips = 0;
+
+	this->curfloor = -1;
+	this->curchip = -1;
+
+	/* Ident all the chips present. */
+	DoC_ScanChips(this);
+
+	nftl = &this->nftl;
+
+	/* Get physical parameters */
+	nftl->EraseSize = this->erasesize;
+        nftl->nb_blocks = this->totlen / this->erasesize;
+	nftl->mtd = this;
+
+	if (find_boot_record(nftl) != 0)
+		this->nftl_found = 0;
+	else
+		this->nftl_found = 1;
+
+	printf("%s @ 0x%lX, %ld MB\n", this->name, this->physadr, this->totlen >> 20);
+}
+
+int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
+		 size_t * retlen, u_char * buf, u_char * eccbuf)
+{
+	unsigned long docptr;
+	struct Nand *mychip;
+	unsigned char syndrome[6];
+	volatile char dummy;
+	int i, len256 = 0, ret=0;
+
+	docptr = this->virtadr;
+
+	/* Don't allow read past end of device */
+	if (from >= this->totlen) {
+		puts ("Out of flash\n");
+		return DOC_EINVAL;
+	}
+
+	/* Don't allow a single read to cross a 512-byte block boundary */
+	if (from + len > ((from | 0x1ff) + 1))
+		len = ((from | 0x1ff) + 1) - from;
+
+	/* The ECC will not be calculated correctly if less than 512 is read */
+	if (len != 0x200 && eccbuf)
+		printf("ECC needs a full sector read (adr: %lx size %lx)\n",
+		       (long) from, (long) len);
+
+#ifdef PHYCH_DEBUG
+	printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len);
+#endif
+
+	/* Find the chip which is to be used and select it */
+	mychip = &this->chips[shr(from, this->chipshift)];
+
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	DoC_Command(this,
+		    (!this->page256
+		     && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
+		    CDSN_CTRL_WP);
+	DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
+		    CDSN_CTRL_ECC_IO);
+
+	if (eccbuf) {
+		/* Prime the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_EN, docptr, ECCConf);
+	} else {
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+	}
+
+	/* treat crossing 256-byte sector for 2M x 8bits devices */
+	if (this->page256 && from + len > (from | 0xff) + 1) {
+		len256 = (from | 0xff) + 1 - from;
+		DoC_ReadBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
+		DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
+			    CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
+	}
+
+	DoC_ReadBuf(this, &buf[len256], len - len256);
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+
+	if (eccbuf) {
+		/* Read the ECC data through the DiskOnChip ECC logic */
+		/* Note: this will work even with 2M x 8bit devices as   */
+		/*       they have 8 bytes of OOB per 256 page. mf.      */
+		DoC_ReadBuf(this, eccbuf, 6);
+
+		/* Flush the pipeline */
+		if (DoC_is_Millennium(this)) {
+			dummy = ReadDOC(docptr, ECCConf);
+			dummy = ReadDOC(docptr, ECCConf);
+			i = ReadDOC(docptr, ECCConf);
+		} else {
+			dummy = ReadDOC(docptr, 2k_ECCStatus);
+			dummy = ReadDOC(docptr, 2k_ECCStatus);
+			i = ReadDOC(docptr, 2k_ECCStatus);
+		}
+
+		/* Check the ECC Status */
+		if (i & 0x80) {
+			int nb_errors;
+			/* There was an ECC error */
+#ifdef ECC_DEBUG
+			printf("DiskOnChip ECC Error: Read at %lx\n", (long)from);
+#endif
+			/* Read the ECC syndrom through the DiskOnChip ECC logic.
+			   These syndrome will be all ZERO when there is no error */
+			for (i = 0; i < 6; i++) {
+				syndrome[i] =
+				    ReadDOC(docptr, ECCSyndrome0 + i);
+			}
+                        nb_errors = doc_decode_ecc(buf, syndrome);
+
+#ifdef ECC_DEBUG
+			printf("Errors corrected: %x\n", nb_errors);
+#endif
+                        if (nb_errors < 0) {
+				/* We return error, but have actually done the read. Not that
+				   this can be told to user-space, via sys_read(), but at least
+				   MTD-aware stuff can know about it by checking *retlen */
+				printf("ECC Errors at %lx\n", (long)from);
+				ret = DOC_EECC;
+                        }
+		}
+
+#ifdef PSYCHO_DEBUG
+		printf("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+			     (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
+			     eccbuf[3], eccbuf[4], eccbuf[5]);
+#endif
+
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
+	}
+
+	/* according to 11.4.1, we need to wait for the busy line
+         * drop if we read to the end of the page.  */
+	if(0 == ((from + *retlen) & 0x1ff))
+	{
+	    DoC_WaitReady(this);
+	}
+
+	return ret;
+}
+
+int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len,
+		  size_t * retlen, const u_char * buf,
+		  u_char * eccbuf)
+{
+	int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
+	unsigned long docptr;
+	volatile char dummy;
+	int len256 = 0;
+	struct Nand *mychip;
+
+	docptr = this->virtadr;
+
+	/* Don't allow write past end of device */
+	if (to >= this->totlen) {
+		puts ("Out of flash\n");
+		return DOC_EINVAL;
+	}
+
+	/* Don't allow a single write to cross a 512-byte block boundary */
+	if (to + len > ((to | 0x1ff) + 1))
+		len = ((to | 0x1ff) + 1) - to;
+
+	/* The ECC will not be calculated correctly if less than 512 is written */
+	if (len != 0x200 && eccbuf)
+		printf("ECC needs a full sector write (adr: %lx size %lx)\n",
+		       (long) to, (long) len);
+
+	/* printf("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
+
+	/* Find the chip which is to be used and select it */
+	mychip = &this->chips[shr(to, this->chipshift)];
+
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Set device to main plane of flash */
+	DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
+	DoC_Command(this,
+		    (!this->page256
+		     && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
+		    CDSN_CTRL_WP);
+
+	DoC_Command(this, NAND_CMD_SEQIN, 0);
+	DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
+
+	if (eccbuf) {
+		/* Prime the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
+	} else {
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+	}
+
+	/* treat crossing 256-byte sector for 2M x 8bits devices */
+	if (this->page256 && to + len > (to | 0xff) + 1) {
+		len256 = (to | 0xff) + 1 - to;
+		DoC_WriteBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+
+		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+		/* There's an implicit DoC_WaitReady() in DoC_Command */
+
+		dummy = ReadDOC(docptr, CDSNSlowIO);
+		DoC_Delay(this, 2);
+
+		if (ReadDOC_(docptr, this->ioreg) & 1) {
+			puts ("Error programming flash\n");
+			/* Error in programming */
+			*retlen = 0;
+			return DOC_EIO;
+		}
+
+		DoC_Command(this, NAND_CMD_SEQIN, 0);
+		DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
+			    CDSN_CTRL_ECC_IO);
+	}
+
+	DoC_WriteBuf(this, &buf[len256], len - len256);
+
+	if (eccbuf) {
+		WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
+			 CDSNControl);
+
+		if (DoC_is_Millennium(this)) {
+			WriteDOC(0, docptr, NOP);
+			WriteDOC(0, docptr, NOP);
+			WriteDOC(0, docptr, NOP);
+		} else {
+			WriteDOC_(0, docptr, this->ioreg);
+			WriteDOC_(0, docptr, this->ioreg);
+			WriteDOC_(0, docptr, this->ioreg);
+		}
+
+		/* Read the ECC data through the DiskOnChip ECC logic */
+		for (di = 0; di < 6; di++) {
+			eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
+		}
+
+		/* Reset the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+
+#ifdef PSYCHO_DEBUG
+		printf
+		    ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+		     (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+		     eccbuf[4], eccbuf[5]);
+#endif
+	}
+
+	DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+
+	DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+	/* There's an implicit DoC_WaitReady() in DoC_Command */
+
+	dummy = ReadDOC(docptr, CDSNSlowIO);
+	DoC_Delay(this, 2);
+
+	if (ReadDOC_(docptr, this->ioreg) & 1) {
+		puts ("Error programming flash\n");
+		/* Error in programming */
+		*retlen = 0;
+		return DOC_EIO;
+	}
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+
+	if (eccbuf) {
+		unsigned char x[8];
+		size_t dummy;
+		int ret;
+
+		/* Write the ECC data to flash */
+		for (di=0; di<6; di++)
+			x[di] = eccbuf[di];
+
+		x[6]=0x55;
+		x[7]=0x55;
+
+		ret = doc_write_oob(this, to, 8, &dummy, x);
+		return ret;
+	}
+	return 0;
+}
+
+int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
+		 size_t * retlen, u_char * buf)
+{
+	int len256 = 0, ret;
+	unsigned long docptr;
+	struct Nand *mychip;
+
+	docptr = this->virtadr;
+
+	mychip = &this->chips[shr(ofs, this->chipshift)];
+
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* update address for 2M x 8bit devices. OOB starts on the second */
+	/* page to maintain compatibility with doc_read_ecc. */
+	if (this->page256) {
+		if (!(ofs & 0x8))
+			ofs += 0x100;
+		else
+			ofs -= 0x8;
+	}
+
+	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
+
+	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
+	/* Note: datasheet says it should automaticaly wrap to the */
+	/*       next OOB block, but it didn't work here. mf.      */
+	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
+		len256 = (ofs | 0x7) + 1 - ofs;
+		DoC_ReadBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
+			    CDSN_CTRL_WP, 0);
+	}
+
+	DoC_ReadBuf(this, &buf[len256], len - len256);
+
+	*retlen = len;
+	/* Reading the full OOB data drops us off of the end of the page,
+         * causing the flash device to go into busy mode, so we need
+         * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
+
+	ret = DoC_WaitReady(this);
+
+	return ret;
+
+}
+
+int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
+		  size_t * retlen, const u_char * buf)
+{
+	int len256 = 0;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[shr(ofs, this->chipshift)];
+	volatile int dummy;
+
+#ifdef PSYCHO_DEBUG
+	printf("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
+	       (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
+	       buf[8], buf[9], buf[14],buf[15]);
+#endif
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* disable the ECC engine */
+	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
+
+	/* issue the Read2 command to set the pointer to the Spare Data Area. */
+	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+
+	/* update address for 2M x 8bit devices. OOB starts on the second */
+	/* page to maintain compatibility with doc_read_ecc. */
+	if (this->page256) {
+		if (!(ofs & 0x8))
+			ofs += 0x100;
+		else
+			ofs -= 0x8;
+	}
+
+	/* issue the Serial Data In command to initial the Page Program process */
+	DoC_Command(this, NAND_CMD_SEQIN, 0);
+	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
+
+	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
+	/* Note: datasheet says it should automaticaly wrap to the */
+	/*       next OOB block, but it didn't work here. mf.      */
+	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
+		len256 = (ofs | 0x7) + 1 - ofs;
+		DoC_WriteBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+		DoC_Command(this, NAND_CMD_STATUS, 0);
+		/* DoC_WaitReady() is implicit in DoC_Command */
+
+		dummy = ReadDOC(docptr, CDSNSlowIO);
+		DoC_Delay(this, 2);
+
+		if (ReadDOC_(docptr, this->ioreg) & 1) {
+			puts ("Error programming oob data\n");
+			/* There was an error */
+			*retlen = 0;
+			return DOC_EIO;
+		}
+		DoC_Command(this, NAND_CMD_SEQIN, 0);
+		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
+	}
+
+	DoC_WriteBuf(this, &buf[len256], len - len256);
+
+	DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+	DoC_Command(this, NAND_CMD_STATUS, 0);
+	/* DoC_WaitReady() is implicit in DoC_Command */
+
+	dummy = ReadDOC(docptr, CDSNSlowIO);
+	DoC_Delay(this, 2);
+
+	if (ReadDOC_(docptr, this->ioreg) & 1) {
+		puts ("Error programming oob data\n");
+		/* There was an error */
+		*retlen = 0;
+		return DOC_EIO;
+	}
+
+	*retlen = len;
+	return 0;
+
+}
+
+int doc_erase(struct DiskOnChip* this, loff_t ofs, size_t len)
+{
+	volatile int dummy;
+	unsigned long docptr;
+	struct Nand *mychip;
+
+	if (ofs & (this->erasesize-1) || len & (this->erasesize-1)) {
+		puts ("Offset and size must be sector aligned\n");
+		return DOC_EINVAL;
+	}
+
+	docptr = this->virtadr;
+
+	/* FIXME: Do this in the background. Use timers or schedule_task() */
+	while(len) {
+		mychip = &this->chips[shr(ofs, this->chipshift)];
+
+		if (this->curfloor != mychip->floor) {
+			DoC_SelectFloor(this, mychip->floor);
+			DoC_SelectChip(this, mychip->chip);
+		} else if (this->curchip != mychip->chip) {
+			DoC_SelectChip(this, mychip->chip);
+		}
+		this->curfloor = mychip->floor;
+		this->curchip = mychip->chip;
+
+		DoC_Command(this, NAND_CMD_ERASE1, 0);
+		DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
+		DoC_Command(this, NAND_CMD_ERASE2, 0);
+
+		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+
+		dummy = ReadDOC(docptr, CDSNSlowIO);
+		DoC_Delay(this, 2);
+
+		if (ReadDOC_(docptr, this->ioreg) & 1) {
+			printf("Error erasing at 0x%lx\n", (long)ofs);
+			/* There was an error */
+			goto callback;
+		}
+		ofs += this->erasesize;
+		len -= this->erasesize;
+	}
+
+ callback:
+	return 0;
+}
+
+static inline int doccheck(unsigned long potential, unsigned long physadr)
+{
+	unsigned long window=potential;
+	unsigned char tmp, ChipID;
+#ifndef DOC_PASSIVE_PROBE
+	unsigned char tmp2;
+#endif
+
+	/* Routine copied from the Linux DOC driver */
+
+#ifdef CFG_DOCPROBE_55AA
+	/* Check for 0x55 0xAA signature at beginning of window,
+	   this is no longer true once we remove the IPL (for Millennium */
+	if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
+		return 0;
+#endif /* CFG_DOCPROBE_55AA */
+
+#ifndef DOC_PASSIVE_PROBE
+	/* It's not possible to cleanly detect the DiskOnChip - the
+	 * bootup procedure will put the device into reset mode, and
+	 * it's not possible to talk to it without actually writing
+	 * to the DOCControl register. So we store the current contents
+	 * of the DOCControl register's location, in case we later decide
+	 * that it's not a DiskOnChip, and want to put it back how we
+	 * found it.
+	 */
+	tmp2 = ReadDOC(window, DOCControl);
+
+	/* Reset the DiskOnChip ASIC */
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+		 window, DOCControl);
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+		 window, DOCControl);
+
+	/* Enable the DiskOnChip ASIC */
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+		 window, DOCControl);
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+		 window, DOCControl);
+#endif /* !DOC_PASSIVE_PROBE */
+
+	ChipID = ReadDOC(window, ChipID);
+
+	switch (ChipID) {
+	case DOC_ChipID_Doc2k:
+		/* Check the TOGGLE bit in the ECC register */
+		tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
+		if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
+				return ChipID;
+		break;
+
+	case DOC_ChipID_DocMil:
+		/* Check the TOGGLE bit in the ECC register */
+		tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
+		if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
+				return ChipID;
+		break;
+
+	default:
+#ifndef CFG_DOCPROBE_55AA
+/*
+ * if the ID isn't the DoC2000 or DoCMillenium ID, so we can assume
+ * the DOC is missing
+ */
+# if 0
+		printf("Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
+		       ChipID, physadr);
+# endif
+#endif
+#ifndef DOC_PASSIVE_PROBE
+		/* Put back the contents of the DOCControl register, in case it's not
+		 * actually a DiskOnChip.
+		 */
+		WriteDOC(tmp2, window, DOCControl);
+#endif
+		return 0;
+	}
+
+	puts ("DiskOnChip failed TOGGLE test, dropping.\n");
+
+#ifndef DOC_PASSIVE_PROBE
+	/* Put back the contents of the DOCControl register: it's not a DiskOnChip */
+	WriteDOC(tmp2, window, DOCControl);
+#endif
+	return 0;
+}
+
+void doc_probe(unsigned long physadr)
+{
+	struct DiskOnChip *this = NULL;
+	int i=0, ChipID;
+
+	if ((ChipID = doccheck(physadr, physadr))) {
+
+		for (i=0; i<CFG_MAX_DOC_DEVICE; i++) {
+			if (doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) {
+				this = doc_dev_desc + i;
+				break;
+			}
+		}
+
+		if (!this) {
+			puts ("Cannot allocate memory for data structures.\n");
+			return;
+		}
+
+		if (curr_device == -1)
+			curr_device = i;
+
+		memset((char *)this, 0, sizeof(struct DiskOnChip));
+
+		this->virtadr = physadr;
+		this->physadr = physadr;
+		this->ChipID = ChipID;
+
+		DoC2k_init(this);
+	} else {
+		puts ("No DiskOnChip found\n");
+	}
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
new file mode 100644
index 0000000..9cbfe1b
--- /dev/null
+++ b/common/cmd_ide.c
@@ -0,0 +1,1563 @@
+/*
+ * (C) Copyright 2000-2002
+ * 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
+ *
+ */
+
+/*
+ * IDE support
+ */
+#include <common.h>
+#include <config.h>
+#include <watchdog.h>
+#include <command.h>
+#include <image.h>
+#include <asm/byteorder.h>
+#if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA)
+# include <pcmcia.h>
+#endif
+#ifdef CONFIG_8xx
+# include <mpc8xx.h>
+#endif
+#include <ide.h>
+#include <ata.h>
+#include <cmd_ide.h>
+#include <cmd_disk.h>
+#ifdef CONFIG_STATUS_LED
+# include <status_led.h>
+#endif
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+# define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg)
+#else
+# define SHOW_BOOT_PROGRESS(arg)
+#endif
+
+
+#undef	IDE_DEBUG
+
+#ifdef	IDE_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_IDE)
+
+/* Timings for IDE Interface
+ *
+ * SETUP / LENGTH / HOLD - cycles valid for 50 MHz clk
+ * 70	   165	    30	   PIO-Mode 0, [ns]
+ *  4	     9	     2		       [Cycles]
+ * 50	   125	    20	   PIO-Mode 1, [ns]
+ *  3	     7	     2		       [Cycles]
+ * 30	   100	    15	   PIO-Mode 2, [ns]
+ *  2	     6	     1		       [Cycles]
+ * 30	    80	    10	   PIO-Mode 3, [ns]
+ *  2	     5	     1		       [Cycles]
+ * 25	    70	    10	   PIO-Mode 4, [ns]
+ *  2	     4	     1		       [Cycles]
+ */
+
+const static pio_config_t pio_config_ns [IDE_MAX_PIO_MODE+1] =
+{
+    /*	Setup  Length  Hold  */
+	{ 70,	165,	30 },		/* PIO-Mode 0, [ns]	*/
+	{ 50,	125,	20 },		/* PIO-Mode 1, [ns]	*/
+	{ 30,	101,	15 },		/* PIO-Mode 2, [ns]	*/
+	{ 30,	 80,	10 },		/* PIO-Mode 3, [ns]	*/
+	{ 25,	 70,	10 },		/* PIO-Mode 4, [ns]	*/
+};
+
+static pio_config_t pio_config_clk [IDE_MAX_PIO_MODE+1];
+
+#ifndef	CFG_PIO_MODE
+#define	CFG_PIO_MODE	0		/* use a relaxed default */
+#endif
+static int pio_mode = CFG_PIO_MODE;
+
+/* Make clock cycles and always round up */
+
+#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U )
+
+/* ------------------------------------------------------------------------- */
+
+/* Current I/O Device	*/
+static int curr_device = -1;
+
+/* Current offset for IDE0 / IDE1 bus access	*/
+ulong ide_bus_offset[CFG_IDE_MAXBUS] = {
+#if defined(CFG_ATA_IDE0_OFFSET)
+	CFG_ATA_IDE0_OFFSET,
+#endif
+#if defined(CFG_ATA_IDE1_OFFSET) && (CFG_IDE_MAXBUS > 1)
+	CFG_ATA_IDE1_OFFSET,
+#endif
+};
+
+#define	ATA_CURR_BASE(dev)	(CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)])
+
+static int	    ide_bus_ok[CFG_IDE_MAXBUS];
+
+static  block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_LED
+static void  ide_led   (uchar led, uchar status);
+#else
+#define ide_led(a,b)	/* dummy */
+#endif
+
+#ifdef CONFIG_IDE_RESET
+static void  ide_reset (void);
+#else
+#define ide_reset()	/* dummy */
+#endif
+
+static void  ide_ident (block_dev_desc_t *dev_desc);
+static uchar ide_wait  (int dev, ulong t);
+
+#define IDE_TIME_OUT	2000	/* 2 sec timeout */
+
+#define ATAPI_TIME_OUT	7000	/* 7 sec timeout (5 sec seems to work...) */
+
+#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
+
+static void __inline__ outb(int dev, int port, unsigned char val);
+static unsigned char __inline__ inb(int dev, int port);
+static void input_swap_data(int dev, ulong *sect_buf, int words);
+static void input_data(int dev, ulong *sect_buf, int words);
+static void output_data(int dev, ulong *sect_buf, int words);
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
+
+
+#ifdef CONFIG_ATAPI
+static void	atapi_inquiry(block_dev_desc_t *dev_desc);
+ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer);
+#endif
+
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+static void set_pcmcia_timing (int pmode);
+#else
+#define set_pcmcia_timing(a)	/* dummy */
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    int rcode = 0;
+
+    switch (argc) {
+    case 0:
+    case 1:
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    case 2:
+	if (strncmp(argv[1],"res",3) == 0) {
+		puts ("\nReset IDE"
+#ifdef CONFIG_IDE_8xx_DIRECT
+			" on PCMCIA " PCMCIA_SLOT_MSG
+#endif
+			": ");
+
+		ide_init ();
+		return 0;
+	} else if (strncmp(argv[1],"inf",3) == 0) {
+		int i;
+
+		putc ('\n');
+
+		for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
+			if (ide_dev_desc[i].type==DEV_TYPE_UNKNOWN)
+				continue; /* list only known devices */
+			printf ("IDE device %d: ", i);
+			dev_print(&ide_dev_desc[i]);
+		}
+		return 0;
+
+	} else if (strncmp(argv[1],"dev",3) == 0) {
+		if ((curr_device < 0) || (curr_device >= CFG_IDE_MAXDEVICE)) {
+			puts ("\nno IDE devices available\n");
+			return 1;
+		}
+		printf ("\nIDE device %d: ", curr_device);
+		dev_print(&ide_dev_desc[curr_device]);
+		return 0;
+	} else if (strncmp(argv[1],"part",4) == 0) {
+		int dev, ok;
+
+		for (ok=0, dev=0; dev<CFG_IDE_MAXDEVICE; ++dev) {
+			if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
+				++ok;
+				if (dev)
+					putc ('\n');
+				print_part(&ide_dev_desc[dev]);
+			}
+		}
+		if (!ok) {
+			puts ("\nno IDE devices available\n");
+			rcode ++;
+		}
+		return rcode;
+	}
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    case 3:
+	if (strncmp(argv[1],"dev",3) == 0) {
+		int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+		printf ("\nIDE device %d: ", dev);
+		if (dev >= CFG_IDE_MAXDEVICE) {
+			puts ("unknown device\n");
+			return 1;
+		}
+		dev_print(&ide_dev_desc[dev]);
+		/*ide_print (dev);*/
+
+		if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
+			return 1;
+		}
+
+		curr_device = dev;
+
+		puts ("... is now current device\n");
+
+		return 0;
+	} else if (strncmp(argv[1],"part",4) == 0) {
+		int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+		if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
+				print_part(&ide_dev_desc[dev]);
+		} else {
+			printf ("\nIDE device %d not available\n", dev);
+			rcode = 1;
+		}
+		return rcode;
+#if 0
+	} else if (strncmp(argv[1],"pio",4) == 0) {
+		int mode = (int)simple_strtoul(argv[2], NULL, 10);
+
+		if ((mode >= 0) && (mode <= IDE_MAX_PIO_MODE)) {
+			puts ("\nSetting ");
+			pio_mode = mode;
+			ide_init ();
+		} else {
+			printf ("\nInvalid PIO mode %d (0 ... %d only)\n",
+				mode, IDE_MAX_PIO_MODE);
+		}
+		return;
+#endif
+	}
+
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    default:
+	/* at least 4 args */
+
+	if (strcmp(argv[1],"read") == 0) {
+		ulong addr = simple_strtoul(argv[2], NULL, 16);
+		ulong blk  = simple_strtoul(argv[3], NULL, 16);
+		ulong cnt  = simple_strtoul(argv[4], NULL, 16);
+		ulong n;
+
+		printf ("\nIDE read: device %d block # %ld, count %ld ... ",
+			curr_device, blk, cnt);
+
+		n = ide_dev_desc[curr_device].block_read (curr_device,
+							  blk, cnt,
+							  (ulong *)addr);
+		/* flush cache after read */
+		flush_cache (addr, cnt*ide_dev_desc[curr_device].blksz);
+
+		printf ("%ld blocks read: %s\n",
+			n, (n==cnt) ? "OK" : "ERROR");
+		if (n==cnt) {
+			return 0;
+		} else {
+			return 1;
+		}
+	} else if (strcmp(argv[1],"write") == 0) {
+		ulong addr = simple_strtoul(argv[2], NULL, 16);
+		ulong blk  = simple_strtoul(argv[3], NULL, 16);
+		ulong cnt  = simple_strtoul(argv[4], NULL, 16);
+		ulong n;
+
+		printf ("\nIDE write: device %d block # %ld, count %ld ... ",
+			curr_device, blk, cnt);
+
+		n = ide_write (curr_device, blk, cnt, (ulong *)addr);
+
+		printf ("%ld blocks written: %s\n",
+			n, (n==cnt) ? "OK" : "ERROR");
+		if (n==cnt) {
+			return 0;
+		} else {
+			return 1;
+		}
+	} else {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		rcode = 1;
+	}
+
+	return rcode;
+    }
+}
+
+int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	char *boot_device = NULL;
+	char *ep;
+	int dev, part = 0;
+	ulong cnt;
+	ulong addr;
+	disk_partition_t info;
+	image_header_t *hdr;
+	int rcode = 0;
+
+	switch (argc) {
+	case 1:
+		addr = CFG_LOAD_ADDR;
+		boot_device = getenv ("bootdevice");
+		break;
+	case 2:
+		addr = simple_strtoul(argv[1], NULL, 16);
+		boot_device = getenv ("bootdevice");
+		break;
+	case 3:
+		addr = simple_strtoul(argv[1], NULL, 16);
+		boot_device = argv[2];
+		break;
+	default:
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	if (!boot_device) {
+		puts ("\n** No boot device **\n");
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	dev = simple_strtoul(boot_device, &ep, 16);
+
+	if (ide_dev_desc[dev].type==DEV_TYPE_UNKNOWN) {
+		printf ("\n** Device %d not available\n", dev);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	if (*ep) {
+		if (*ep != ':') {
+			puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+			SHOW_BOOT_PROGRESS (-1);
+			return 1;
+		}
+		part = simple_strtoul(++ep, NULL, 16);
+	}
+	if (get_partition_info (&ide_dev_desc[dev], part, &info)) {
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+	if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
+		printf ("\n** Invalid partition type \"%.32s\""
+			" (expect \"" BOOT_PART_TYPE "\")\n",
+			info.type);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	printf ("\nLoading from IDE device %d, partition %d: "
+		"Name: %.32s  Type: %.32s\n",
+		dev, part, info.name, info.type);
+
+	PRINTF ("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
+		info.start, info.size, info.blksz);
+
+	if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) {
+		printf ("** Read error on %d:%d\n", dev, part);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	hdr = (image_header_t *)addr;
+
+	if (ntohl(hdr->ih_magic) == IH_MAGIC) {
+
+		print_image_hdr (hdr);
+
+		cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
+		cnt += info.blksz - 1;
+		cnt /= info.blksz;
+		cnt -= 1;
+	} else {
+		printf("\n** Bad Magic Number **\n");
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+	if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt,
+		      (ulong *)(addr+info.blksz)) != cnt) {
+		printf ("** Read error on %d:%d\n", dev, part);
+		SHOW_BOOT_PROGRESS (-1);
+		return 1;
+	}
+
+
+	/* Loading ok, update default load address */
+
+	load_addr = addr;
+
+	/* Check if we should attempt an auto-start */
+	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+		char *local_args[2];
+		extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+		local_args[0] = argv[0];
+		local_args[1] = NULL;
+
+		printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+
+		do_bootm (cmdtp, 0, 1, local_args);
+		rcode = 1;
+	}
+	return rcode;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void ide_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
+#endif
+	unsigned char c;
+	int i, bus;
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+	extern int pcmcia_on (void);
+
+	WATCHDOG_RESET();
+
+	/* initialize the PCMCIA IDE adapter card */
+	if (pcmcia_on())
+		return;
+	udelay (1000000);	/* 1 s */
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+
+	WATCHDOG_RESET();
+
+	/* Initialize PIO timing tables */
+	for (i=0; i <= IDE_MAX_PIO_MODE; ++i) {
+	    pio_config_clk[i].t_setup  = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
+							    gd->bus_clk);
+	    pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
+							    gd->bus_clk);
+	    pio_config_clk[i].t_hold   = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
+							    gd->bus_clk);
+	    PRINTF ("PIO Mode %d: setup=%2d ns/%d clk"
+		    "  len=%3d ns/%d clk"
+		    "  hold=%2d ns/%d clk\n",
+		    i,
+		    pio_config_ns[i].t_setup,  pio_config_clk[i].t_setup,
+		    pio_config_ns[i].t_length, pio_config_clk[i].t_length,
+		    pio_config_ns[i].t_hold,   pio_config_clk[i].t_hold);
+	}
+
+	/* Reset the IDE just to be sure.
+	 * Light LED's to show
+	 */
+	ide_led ((LED_IDE1 | LED_IDE2), 1);		/* LED's on	*/
+	ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+	/* PCMCIA / IDE initialization for common mem space */
+	pcmp->pcmc_pgcrb = 0;
+#endif
+
+	/* start in PIO mode 0 - most relaxed timings */
+	pio_mode = 0;
+	set_pcmcia_timing (pio_mode);
+
+	/*
+	 * Wait for IDE to get ready.
+	 * According to spec, this can take up to 31 seconds!
+	 */
+	for (bus=0; bus<CFG_IDE_MAXBUS; ++bus) {
+		int dev = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
+
+		printf ("Bus %d: ", bus);
+
+		ide_bus_ok[bus] = 0;
+
+		/* Select device
+		 */
+		udelay (100000);		/* 100 ms */
+		outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
+		udelay (100000);		/* 100 ms */
+
+		i = 0;
+		do {
+			udelay (10000);		/* 10 ms */
+
+			c = inb (dev, ATA_STATUS);
+			i++;
+			if (i > (ATA_RESET_TIME * 100)) {
+				puts ("** Timeout **\n");
+				ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
+				return;
+			}
+			if ((i >= 100) && ((i%100)==0)) {
+				putc ('.');
+			}
+		} while (c & ATA_STAT_BUSY);
+
+		if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
+			puts ("not available  ");
+			PRINTF ("Status = 0x%02X ", c);
+#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
+		} else  if ((c & ATA_STAT_READY) == 0) {
+			puts ("not available  ");
+			PRINTF ("Status = 0x%02X ", c);
+#endif
+		} else {
+			puts ("OK ");
+			ide_bus_ok[bus] = 1;
+		}
+		WATCHDOG_RESET();
+	}
+	putc ('\n');
+
+	ide_led ((LED_IDE1 | LED_IDE2), 0);	/* LED's off	*/
+
+	curr_device = -1;
+	for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
+#ifdef CONFIG_IDE_LED
+		int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
+#endif
+		ide_dev_desc[i].if_type=IF_TYPE_IDE;
+		ide_dev_desc[i].dev=i;
+		ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
+		ide_dev_desc[i].blksz=0;
+		ide_dev_desc[i].lba=0;
+		ide_dev_desc[i].block_read=ide_read;
+		if (!ide_bus_ok[IDE_BUS(i)])
+			continue;
+		ide_led (led, 1);		/* LED on	*/
+		ide_ident(&ide_dev_desc[i]);
+		ide_led (led, 0);		/* LED off	*/
+		dev_print(&ide_dev_desc[i]);
+/*		ide_print (i); */
+		if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
+			init_part (&ide_dev_desc[i]);			/* initialize partition type */
+			if (curr_device < 0)
+				curr_device = i;
+		}
+	}
+	WATCHDOG_RESET();
+}
+
+/* ------------------------------------------------------------------------- */
+
+block_dev_desc_t * ide_get_dev(int dev)
+{
+	return ((block_dev_desc_t *)&ide_dev_desc[dev]);
+}
+
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+
+static void
+set_pcmcia_timing (int pmode)
+{
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
+	ulong timings;
+
+	PRINTF ("Set timing for PIO Mode %d\n", pmode);
+
+	timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold)
+		| PCMCIA_SST(pio_config_clk[pmode].t_setup)
+		| PCMCIA_SL (pio_config_clk[pmode].t_length)
+		;
+
+	/* IDE 0
+	 */
+	pcmp->pcmc_pbr0 = CFG_PCMCIA_PBR0;
+	pcmp->pcmc_por0 = CFG_PCMCIA_POR0
+#if (CFG_PCMCIA_POR0 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR0: %08x  POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0);
+
+	pcmp->pcmc_pbr1 = CFG_PCMCIA_PBR1;
+	pcmp->pcmc_por1 = CFG_PCMCIA_POR1
+#if (CFG_PCMCIA_POR1 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR1: %08x  POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1);
+
+	pcmp->pcmc_pbr2 = CFG_PCMCIA_PBR2;
+	pcmp->pcmc_por2 = CFG_PCMCIA_POR2
+#if (CFG_PCMCIA_POR2 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR2: %08x  POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2);
+
+	pcmp->pcmc_pbr3 = CFG_PCMCIA_PBR3;
+	pcmp->pcmc_por3 = CFG_PCMCIA_POR3
+#if (CFG_PCMCIA_POR3 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR3: %08x  POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3);
+
+	/* IDE 1
+	 */
+	pcmp->pcmc_pbr4 = CFG_PCMCIA_PBR4;
+	pcmp->pcmc_por4 = CFG_PCMCIA_POR4
+#if (CFG_PCMCIA_POR4 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR4: %08x  POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4);
+
+	pcmp->pcmc_pbr5 = CFG_PCMCIA_PBR5;
+	pcmp->pcmc_por5 = CFG_PCMCIA_POR5
+#if (CFG_PCMCIA_POR5 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR5: %08x  POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5);
+
+	pcmp->pcmc_pbr6 = CFG_PCMCIA_PBR6;
+	pcmp->pcmc_por6 = CFG_PCMCIA_POR6
+#if (CFG_PCMCIA_POR6 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR6: %08x  POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6);
+
+	pcmp->pcmc_pbr7 = CFG_PCMCIA_PBR7;
+	pcmp->pcmc_por7 = CFG_PCMCIA_POR7
+#if (CFG_PCMCIA_POR7 != 0)
+			| timings
+#endif
+			;
+	PRINTF ("PBR7: %08x  POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7);
+
+}
+
+#endif	/* CONFIG_IDE_8xx_DIRECT */
+
+/* ------------------------------------------------------------------------- */
+
+static void __inline__
+outb(int dev, int port, unsigned char val)
+{
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	*((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
+#if 0
+	printf ("OUTB: 0x%08lx <== 0x%02x\n", ATA_CURR_BASE(dev)+port, val);
+#endif
+}
+
+static unsigned char __inline__
+inb(int dev, int port)
+{
+	uchar val;
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	val = *((uchar *)(ATA_CURR_BASE(dev)+port));
+#if 0
+	printf ("INB: 0x%08lx ==> 0x%02x\n", ATA_CURR_BASE(dev)+port, val);
+#endif
+	return (val);
+}
+
+__inline__ unsigned ld_le16(const volatile unsigned short *addr)
+{
+	unsigned val;
+
+	__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr));
+	return val;
+}
+
+static void
+input_swap_data(int dev, ulong *sect_buf, int words)
+{
+	volatile ushort	*pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+	ushort	*dbuf = (ushort *)sect_buf;
+
+	while (words--) {
+		*dbuf++ = ld_le16(pbuf);
+		*dbuf++ = ld_le16(pbuf);
+	}
+}
+
+static void
+output_data(int dev, ulong *sect_buf, int words)
+{
+	ushort	*dbuf;
+	volatile ushort	*pbuf;
+
+	pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+	dbuf = (ushort *)sect_buf;
+	while (words--) {
+		__asm__ volatile ("eieio");
+		*pbuf = *dbuf++;
+		__asm__ volatile ("eieio");
+		*pbuf = *dbuf++;
+	}
+}
+
+static void
+input_data(int dev, ulong *sect_buf, int words)
+{
+	ushort	*dbuf;
+	volatile ushort	*pbuf;
+
+	pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+	dbuf = (ushort *)sect_buf;
+	while (words--) {
+		__asm__ volatile ("eieio");
+		*dbuf++ = *pbuf;
+		__asm__ volatile ("eieio");
+		*dbuf++ = *pbuf;
+	}
+}
+
+/* -------------------------------------------------------------------------
+ */
+static void ide_ident (block_dev_desc_t *dev_desc)
+{
+	ulong iobuf[ATA_SECTORWORDS];
+	unsigned char c;
+	hd_driveid_t *iop = (hd_driveid_t *)iobuf;
+
+#if 0
+	int mode, cycle_time;
+#endif
+	int device;
+	device=dev_desc->dev;
+	printf ("  Device %d: ", device);
+
+	ide_led (DEVICE_LED(device), 1);	/* LED on	*/
+	/* Select device
+	 */
+	outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+	dev_desc->if_type=IF_TYPE_IDE;
+#ifdef CONFIG_ATAPI
+	/* check signature */
+	if ((inb(device,ATA_SECT_CNT)==0x01) &&
+		 (inb(device,ATA_SECT_NUM)==0x01) &&
+		 (inb(device,ATA_CYL_LOW)==0x14) &&
+		 (inb(device,ATA_CYL_HIGH)==0xEB)) {
+		/* ATAPI Signature found */
+		dev_desc->if_type=IF_TYPE_ATAPI;
+		/* Start Ident Command
+		 */
+		outb (device, ATA_COMMAND, ATAPI_CMD_IDENT);
+		/*
+		 * Wait for completion - ATAPI devices need more time
+		 * to become ready
+		 */
+		c = ide_wait (device, ATAPI_TIME_OUT);
+	}
+	else
+#endif
+	{
+		/* Start Ident Command
+		 */
+		outb (device, ATA_COMMAND, ATA_CMD_IDENT);
+
+		/* Wait for completion
+		 */
+		c = ide_wait (device, IDE_TIME_OUT);
+	}
+	ide_led (DEVICE_LED(device), 0);	/* LED off	*/
+
+	if (((c & ATA_STAT_DRQ) == 0) ||
+	    ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) {
+		dev_desc->type=DEV_TYPE_UNKNOWN;
+		return;
+	}
+
+	input_swap_data (device, iobuf, ATA_SECTORWORDS);
+
+	ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
+	ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
+	ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
+
+	if ((iop->config & 0x0080)==0x0080)
+		dev_desc->removable = 1;
+	else
+		dev_desc->removable = 0;
+
+#if 0
+	/*
+	 * Drive PIO mode autoselection
+	 */
+	mode = iop->tPIO;
+
+	printf ("tPIO = 0x%02x = %d\n",mode, mode);
+	if (mode > 2) {		/* 2 is maximum allowed tPIO value */
+		mode = 2;
+		PRINTF ("Override tPIO -> 2\n");
+	}
+	if (iop->field_valid & 2) {	/* drive implements ATA2? */
+		PRINTF ("Drive implements ATA2\n");
+		if (iop->capability & 8) {	/* drive supports use_iordy? */
+			cycle_time = iop->eide_pio_iordy;
+		} else {
+			cycle_time = iop->eide_pio;
+		}
+		PRINTF ("cycle time = %d\n", cycle_time);
+		mode = 4;
+		if (cycle_time > 120) mode = 3;	/* 120 ns for PIO mode 4 */
+		if (cycle_time > 180) mode = 2;	/* 180 ns for PIO mode 3 */
+		if (cycle_time > 240) mode = 1;	/* 240 ns for PIO mode 4 */
+		if (cycle_time > 383) mode = 0;	/* 383 ns for PIO mode 4 */
+	}
+	printf ("PIO mode to use: PIO %d\n", mode);
+#endif /* 0 */
+
+#ifdef CONFIG_ATAPI
+	if (dev_desc->if_type==IF_TYPE_ATAPI) {
+		atapi_inquiry(dev_desc);
+		return;
+	}
+#endif /* CONFIG_ATAPI */
+
+	/* swap shorts */
+	dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);
+	/* assuming HD */
+	dev_desc->type=DEV_TYPE_HARDDISK;
+	dev_desc->blksz=ATA_BLOCKSIZE;
+	dev_desc->lun=0; /* just to fill something in... */
+
+#if 0 	/* only used to test the powersaving mode,
+	 * if enabled, the drive goes after 5 sec
+	 * in standby mode */
+	outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+	c = ide_wait (device, IDE_TIME_OUT);
+	outb (device, ATA_SECT_CNT, 1);
+	outb (device, ATA_LBA_LOW,  0);
+	outb (device, ATA_LBA_MID,  0);
+	outb (device, ATA_LBA_HIGH, 0);
+	outb (device, ATA_DEV_HD,   ATA_LBA		|
+				    ATA_DEVICE(device));
+	outb (device, ATA_COMMAND,  0xe3);
+	udelay (50);
+	c = ide_wait (device, IDE_TIME_OUT);	/* can't take over 500 ms */
+#endif
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+	ulong n = 0;
+	unsigned char c;
+	unsigned char pwrsave=0; /* power save */
+
+	PRINTF ("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",
+		device, blknr, blkcnt, (ulong)buffer);
+
+	ide_led (DEVICE_LED(device), 1);	/* LED on	*/
+
+	/* Select device
+	 */
+	outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+	c = ide_wait (device, IDE_TIME_OUT);
+
+	if (c & ATA_STAT_BUSY) {
+		printf ("IDE read: device %d not ready\n", device);
+		goto IDE_READ_E;
+	}
+
+	/* first check if the drive is in Powersaving mode, if yes,
+	 * increase the timeout value */
+	outb (device, ATA_COMMAND,  ATA_CMD_CHK_PWR);
+	udelay (50);
+
+	c = ide_wait (device, IDE_TIME_OUT);	/* can't take over 500 ms */
+
+	if (c & ATA_STAT_BUSY) {
+		printf ("IDE read: device %d not ready\n", device);
+		goto IDE_READ_E;
+	}
+	if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+		printf ("No Powersaving mode %X\n", c);
+	} else {
+		c = inb(device,ATA_SECT_CNT);
+		PRINTF("Powersaving %02X\n",c);
+		if(c==0)
+			pwrsave=1;
+	}
+
+
+	while (blkcnt-- > 0) {
+
+		c = ide_wait (device, IDE_TIME_OUT);
+
+		if (c & ATA_STAT_BUSY) {
+			printf ("IDE read: device %d not ready\n", device);
+			break;
+		}
+
+		outb (device, ATA_SECT_CNT, 1);
+		outb (device, ATA_LBA_LOW,  (blknr >>  0) & 0xFF);
+		outb (device, ATA_LBA_MID,  (blknr >>  8) & 0xFF);
+		outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+		outb (device, ATA_DEV_HD,   ATA_LBA		|
+					    ATA_DEVICE(device)	|
+					    ((blknr >> 24) & 0xF) );
+		outb (device, ATA_COMMAND,  ATA_CMD_READ);
+
+		udelay (50);
+
+		if(pwrsave) {
+			c = ide_wait (device, IDE_SPIN_UP_TIME_OUT);	/* may take up to 4 sec */
+			pwrsave=0;
+		} else {
+			c = ide_wait (device, IDE_TIME_OUT);	/* can't take over 500 ms */
+		}
+
+		if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
+			printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
+				device, blknr, c);
+			break;
+		}
+
+		input_data (device, buffer, ATA_SECTORWORDS);
+		(void) inb (device, ATA_STATUS);	/* clear IRQ */
+
+		++n;
+		++blknr;
+		buffer += ATA_SECTORWORDS;
+	}
+IDE_READ_E:
+	ide_led (DEVICE_LED(device), 0);	/* LED off	*/
+	return (n);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+ulong ide_write (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+	ulong n = 0;
+	unsigned char c;
+
+	ide_led (DEVICE_LED(device), 1);	/* LED on	*/
+
+	/* Select device
+	 */
+	outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+
+	while (blkcnt-- > 0) {
+
+		c = ide_wait (device, IDE_TIME_OUT);
+
+		if (c & ATA_STAT_BUSY) {
+			printf ("IDE read: device %d not ready\n", device);
+			goto WR_OUT;
+		}
+
+		outb (device, ATA_SECT_CNT, 1);
+		outb (device, ATA_LBA_LOW,  (blknr >>  0) & 0xFF);
+		outb (device, ATA_LBA_MID,  (blknr >>  8) & 0xFF);
+		outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+		outb (device, ATA_DEV_HD,   ATA_LBA		|
+					    ATA_DEVICE(device)	|
+					    ((blknr >> 24) & 0xF) );
+		outb (device, ATA_COMMAND,  ATA_CMD_WRITE);
+
+		udelay (50);
+
+		c = ide_wait (device, IDE_TIME_OUT);	/* can't take over 500 ms */
+
+		if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
+			printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
+				device, blknr, c);
+			goto WR_OUT;
+		}
+
+		output_data (device, buffer, ATA_SECTORWORDS);
+		c = inb (device, ATA_STATUS);	/* clear IRQ */
+		++n;
+		++blknr;
+		buffer += ATA_SECTORWORDS;
+	}
+WR_OUT:
+	ide_led (DEVICE_LED(device), 0);	/* LED off	*/
+	return (n);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * copy src to dest, skipping leading and trailing blanks and null
+ * terminate the string
+ */
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
+{
+	int start,end;
+
+	start=0;
+	while (start<len) {
+		if (src[start]!=' ')
+			break;
+		start++;
+	}
+	end=len-1;
+	while (end>start) {
+		if (src[end]!=' ')
+			break;
+		end--;
+	}
+	for ( ; start<=end; start++) {
+		*dest++=src[start];
+	}
+	*dest='\0';
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Wait until Busy bit is off, or timeout (in ms)
+ * Return last status
+ */
+static uchar ide_wait (int dev, ulong t)
+{
+	ulong delay = 10 * t;		/* poll every 100 us */
+	uchar c;
+
+	while ((c = inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
+		udelay (100);
+		if (delay-- == 0) {
+			break;
+		}
+	}
+	return (c);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_RESET
+extern void ide_set_reset(int idereset);
+
+static void ide_reset (void)
+{
+#if defined(CFG_PB_12V_ENABLE) || defined(CFG_PB_IDE_MOTOR)
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+	int i;
+
+	curr_device = -1;
+	for (i=0; i<CFG_IDE_MAXBUS; ++i)
+		ide_bus_ok[i] = 0;
+	for (i=0; i<CFG_IDE_MAXDEVICE; ++i)
+		ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+
+	ide_set_reset (1); /* assert reset */
+
+	WATCHDOG_RESET();
+
+#ifdef CFG_PB_12V_ENABLE
+	immr->im_cpm.cp_pbdat &= ~(CFG_PB_12V_ENABLE);	/* 12V Enable output OFF */
+	immr->im_cpm.cp_pbpar &= ~(CFG_PB_12V_ENABLE);
+	immr->im_cpm.cp_pbodr &= ~(CFG_PB_12V_ENABLE);
+	immr->im_cpm.cp_pbdir |=   CFG_PB_12V_ENABLE;
+
+	/* wait 500 ms for the voltage to stabilize
+	 */
+	for (i=0; i<500; ++i) {
+		udelay (1000);
+	}
+
+	immr->im_cpm.cp_pbdat |=   CFG_PB_12V_ENABLE;	/* 12V Enable output ON */
+#endif	/* CFG_PB_12V_ENABLE */
+
+#ifdef CFG_PB_IDE_MOTOR
+	/* configure IDE Motor voltage monitor pin as input */
+	immr->im_cpm.cp_pbpar &= ~(CFG_PB_IDE_MOTOR);
+	immr->im_cpm.cp_pbodr &= ~(CFG_PB_IDE_MOTOR);
+	immr->im_cpm.cp_pbdir &= ~(CFG_PB_IDE_MOTOR);
+
+	/* wait up to 1 s for the motor voltage to stabilize
+	 */
+	for (i=0; i<1000; ++i) {
+		if ((immr->im_cpm.cp_pbdat & CFG_PB_IDE_MOTOR) != 0) {
+			break;
+		}
+		udelay (1000);
+	}
+
+	if (i == 1000) {	/* Timeout */
+		printf ("\nWarning: 5V for IDE Motor missing\n");
+# ifdef CONFIG_STATUS_LED
+#  ifdef STATUS_LED_YELLOW
+		status_led_set  (STATUS_LED_YELLOW, STATUS_LED_ON );
+#  endif
+#  ifdef STATUS_LED_GREEN
+		status_led_set  (STATUS_LED_GREEN,  STATUS_LED_OFF);
+#  endif
+# endif	/* CONFIG_STATUS_LED */
+	}
+#endif	/* CFG_PB_IDE_MOTOR */
+
+	WATCHDOG_RESET();
+
+	/* de-assert RESET signal */
+	ide_set_reset(0);
+
+	/* wait 250 ms */
+	for (i=0; i<250; ++i) {
+		udelay (1000);
+	}
+}
+
+#endif	/* CONFIG_IDE_RESET */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_LED
+
+static	uchar	led_buffer = 0;		/* Buffer for current LED status	*/
+
+static void ide_led (uchar led, uchar status)
+{
+	uchar *led_port = LED_PORT;
+
+	if (status)	{		/* switch LED on	*/
+		led_buffer |=  led;
+	} else {			/* switch LED off	*/
+		led_buffer &= ~led;
+	}
+
+	*led_port = led_buffer;
+}
+
+#endif	/* CONFIG_IDE_LED */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATAPI
+/****************************************************************************
+ * ATAPI Support
+ */
+
+
+
+#undef	ATAPI_DEBUG
+
+#ifdef	ATAPI_DEBUG
+#define	AT_PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define AT_PRINTF(fmt,args...)
+#endif
+
+/* since ATAPI may use commands with not 4 bytes alligned length
+ * we have our own transfer functions, 2 bytes alligned */
+static void
+output_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+	ushort	*dbuf;
+	volatile ushort	*pbuf;
+
+	pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+	dbuf = (ushort *)sect_buf;
+	while (shorts--) {
+		__asm__ volatile ("eieio");
+		*pbuf = *dbuf++;
+	}
+}
+
+static void
+input_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+	ushort	*dbuf;
+	volatile ushort	*pbuf;
+
+	pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+	dbuf = (ushort *)sect_buf;
+	while (shorts--) {
+		__asm__ volatile ("eieio");
+		*dbuf++ = *pbuf;
+	}
+}
+
+/*
+ * Wait until (Status & mask) == res, or timeout (in ms)
+ * Return last status
+ * This is used since some ATAPI CD ROMs clears their Busy Bit first
+ * and then they set their DRQ Bit
+ */
+static uchar atapi_wait_mask (int dev, ulong t,uchar mask, uchar res)
+{
+	ulong delay = 10 * t;		/* poll every 100 us */
+	uchar c;
+
+	c = inb(dev,ATA_DEV_CTL); /* prevents to read the status before valid */
+	while (((c = inb(dev, ATA_STATUS)) & mask)
+			!= res) {
+		/* break if error occurs (doesn't make sense to wait more) */
+		if((c & ATA_STAT_ERR)==ATA_STAT_ERR)
+			break;
+		udelay (100);
+		if (delay-- == 0) {
+			break;
+		}
+	}
+	return (c);
+}
+
+/*
+ * issue an atapi command
+ */
+unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen)
+{
+	unsigned char c,err,mask,res;
+	int n;
+	ide_led (DEVICE_LED(device), 1);	/* LED on	*/
+
+	/* Select device
+	 */
+	mask = ATA_STAT_BUSY|ATA_STAT_DRQ;
+	res = 0;
+	outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+	c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+	if ((c & mask) != res) {
+		printf ("ATAPI_ISSUE: device %d not ready status %X\n", device,c);
+		err=0xFF;
+		goto AI_OUT;
+	}
+	/* write taskfile */
+	outb (device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */
+	outb (device, ATA_CYL_LOW,  (unsigned char)(buflen & 0xFF));
+	outb (device, ATA_CYL_HIGH, (unsigned char)((buflen<<8) & 0xFF));
+	outb (device, ATA_DEV_HD,   ATA_LBA | ATA_DEVICE(device));
+
+	outb (device, ATA_COMMAND,  ATAPI_CMD_PACKET);
+	udelay (50);
+
+	mask = ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR;
+	res = ATA_STAT_DRQ;
+	c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+
+	if ((c & mask) != res) { /* DRQ must be 1, BSY 0 */
+		printf ("ATTAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",device,c);
+		err=0xFF;
+		goto AI_OUT;
+	}
+
+	output_data_shorts (device, (unsigned short *)ccb,ccblen/2); /* write command block */
+ 	/* ATAPI Command written wait for completition */
+	udelay (5000); /* device must set bsy */
+
+	mask = ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR;
+	/* if no data wait for DRQ = 0 BSY = 0
+	 * if data wait for DRQ = 1 BSY = 0 */
+	res=0;
+	if(buflen)
+		res = ATA_STAT_DRQ;
+	c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+	if ((c & mask) != res ) {
+		if (c & ATA_STAT_ERR) {
+			err=(inb(device,ATA_ERROR_REG))>>4;
+			AT_PRINTF("atapi_issue 1 returned sense key %X status %02X\n",err,c);
+		} else {
+			printf ("ATTAPI_ISSUE: (no DRQ) after sending ccb (%x)  status 0x%02x\n", ccb[0],c);
+			err=0xFF;
+		}
+		goto AI_OUT;
+	}
+	n=inb(device, ATA_CYL_HIGH);
+	n<<=8;
+	n+=inb(device, ATA_CYL_LOW);
+	if(n>buflen) {
+		printf("ERROR, transfer bytes %d requested only %d\n",n,buflen);
+		err=0xff;
+		goto AI_OUT;
+	}
+	if((n==0)&&(buflen<0)) {
+		printf("ERROR, transfer bytes %d requested %d\n",n,buflen);
+		err=0xff;
+		goto AI_OUT;
+	}
+	if(n!=buflen) {
+		AT_PRINTF("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen);
+	}
+	if(n!=0) { /* data transfer */
+		AT_PRINTF("ATAPI_ISSUE: %d Bytes to transfer\n",n);
+		 /* we transfer shorts */
+		n>>=1;
+		/* ok now decide if it is an in or output */
+		if ((inb(device, ATA_SECT_CNT)&0x02)==0) {
+			AT_PRINTF("Write to device\n");
+			output_data_shorts(device,(unsigned short *)buffer,n);
+		} else {
+			AT_PRINTF("Read from device @ %p shorts %d\n",buffer,n);
+			input_data_shorts(device,(unsigned short *)buffer,n);
+		}
+	}
+	udelay(5000); /* seems that some CD ROMs need this... */
+	mask = ATA_STAT_BUSY|ATA_STAT_ERR;
+	res=0;
+	c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+	if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+		err=(inb(device,ATA_ERROR_REG) >> 4);
+		AT_PRINTF("atapi_issue 2 returned sense key %X status %X\n",err,c);
+	} else {
+		err = 0;
+	}
+AI_OUT:
+	ide_led (DEVICE_LED(device), 0);	/* LED off	*/
+	return (err);
+}
+
+/*
+ * sending the command to atapi_issue. If an status other than good
+ * returns, an request_sense will be issued
+ */
+
+#define ATAPI_DRIVE_NOT_READY 	100
+#define ATAPI_UNIT_ATTN		10
+
+unsigned char atapi_issue_autoreq (int device,
+				   unsigned char* ccb,
+				   int ccblen,
+				   unsigned char *buffer,
+				   int buflen)
+{
+	unsigned char sense_data[18],sense_ccb[12];
+	unsigned char res,key,asc,ascq;
+	int notready,unitattn;
+
+	unitattn=ATAPI_UNIT_ATTN;
+	notready=ATAPI_DRIVE_NOT_READY;
+
+retry:
+	res= atapi_issue(device,ccb,ccblen,buffer,buflen);
+	if (res==0)
+		return (0); /* Ok */
+
+	if (res==0xFF)
+		return (0xFF); /* error */
+
+	AT_PRINTF("(auto_req)atapi_issue returned sense key %X\n",res);
+
+	memset(sense_ccb,0,sizeof(sense_ccb));
+	memset(sense_data,0,sizeof(sense_data));
+	sense_ccb[0]=ATAPI_CMD_REQ_SENSE;
+	sense_ccb[4]=18; /* allocation Legnth */
+
+	res=atapi_issue(device,sense_ccb,12,sense_data,18);
+	key=(sense_data[2]&0xF);
+	asc=(sense_data[12]);
+	ascq=(sense_data[13]);
+
+	AT_PRINTF("ATAPI_CMD_REQ_SENSE returned %x\n",res);
+	AT_PRINTF(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
+		sense_data[0],
+		key,
+		asc,
+		ascq);
+
+	if((key==0))
+		return 0; /* ok device ready */
+
+	if((key==6)|| (asc==0x29) || (asc==0x28)) { /* Unit Attention */
+		if(unitattn-->0) {
+			udelay(200*1000);
+			goto retry;
+		}
+		printf("Unit Attention, tried %d\n",ATAPI_UNIT_ATTN);
+		goto error;
+	}
+	if((asc==0x4) && (ascq==0x1)) { /* not ready, but will be ready soon */
+		if (notready-->0) {
+			udelay(200*1000);
+			goto retry;
+		}
+		printf("Drive not ready, tried %d times\n",ATAPI_DRIVE_NOT_READY);
+		goto error;
+	}
+	if(asc==0x3a) {
+		AT_PRINTF("Media not present\n");
+		goto error;
+	}
+	printf ("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq);
+error:
+	AT_PRINTF ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq);
+	return (0xFF);
+}
+
+
+
+static void	atapi_inquiry(block_dev_desc_t * dev_desc)
+{
+	unsigned char ccb[12]; /* Command descriptor block */
+	unsigned char iobuf[64]; /* temp buf */
+	unsigned char c;
+	int device;
+
+	device=dev_desc->dev;
+	dev_desc->type=DEV_TYPE_UNKNOWN; /* not yet valid */
+	dev_desc->block_read=atapi_read;
+
+	memset(ccb,0,sizeof(ccb));
+	memset(iobuf,0,sizeof(iobuf));
+
+	ccb[0]=ATAPI_CMD_INQUIRY;
+	ccb[4]=40; /* allocation Legnth */
+	c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40);
+
+	AT_PRINTF("ATAPI_CMD_INQUIRY returned %x\n",c);
+	if (c!=0)
+		return;
+
+	/* copy device ident strings */
+	ident_cpy(dev_desc->vendor,&iobuf[8],8);
+	ident_cpy(dev_desc->product,&iobuf[16],16);
+	ident_cpy(dev_desc->revision,&iobuf[32],5);
+
+	dev_desc->lun=0;
+	dev_desc->lba=0;
+	dev_desc->blksz=0;
+	dev_desc->type=iobuf[0] & 0x1f;
+
+	if ((iobuf[1]&0x80)==0x80)
+		dev_desc->removable = 1;
+	else
+		dev_desc->removable = 0;
+
+	memset(ccb,0,sizeof(ccb));
+	memset(iobuf,0,sizeof(iobuf));
+	ccb[0]=ATAPI_CMD_START_STOP;
+	ccb[4]=0x03; /* start */
+
+	c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0);
+
+	AT_PRINTF("ATAPI_CMD_START_STOP returned %x\n",c);
+	if (c!=0)
+		return;
+
+	memset(ccb,0,sizeof(ccb));
+	memset(iobuf,0,sizeof(iobuf));
+	c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0);
+
+	AT_PRINTF("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c);
+	if (c!=0)
+		return;
+
+	memset(ccb,0,sizeof(ccb));
+	memset(iobuf,0,sizeof(iobuf));
+	ccb[0]=ATAPI_CMD_READ_CAP;
+	c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8);
+	AT_PRINTF("ATAPI_CMD_READ_CAP returned %x\n",c);
+	if (c!=0)
+		return;
+
+	AT_PRINTF("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
+		iobuf[0],iobuf[1],iobuf[2],iobuf[3],
+		iobuf[4],iobuf[5],iobuf[6],iobuf[7]);
+
+	dev_desc->lba  =((unsigned long)iobuf[0]<<24) +
+			((unsigned long)iobuf[1]<<16) +
+			((unsigned long)iobuf[2]<< 8) +
+			((unsigned long)iobuf[3]);
+	dev_desc->blksz=((unsigned long)iobuf[4]<<24) +
+			((unsigned long)iobuf[5]<<16) +
+			((unsigned long)iobuf[6]<< 8) +
+			((unsigned long)iobuf[7]);
+	return;
+}
+
+
+/*
+ * atapi_read:
+ * we transfer only one block per command, since the multiple DRQ per
+ * command is not yet implemented
+ */
+#define ATAPI_READ_MAX_BYTES	2048	/* we read max 2kbytes */
+#define ATAPI_READ_BLOCK_SIZE	2048	/* assuming CD part */
+#define ATAPI_READ_MAX_BLOCK ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE	/* max blocks */
+
+ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+	ulong n = 0;
+	unsigned char ccb[12]; /* Command descriptor block */
+	ulong cnt;
+
+	AT_PRINTF("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",
+		device, blknr, blkcnt, (ulong)buffer);
+
+	do {
+		if (blkcnt>ATAPI_READ_MAX_BLOCK) {
+			cnt=ATAPI_READ_MAX_BLOCK;
+		} else {
+			cnt=blkcnt;
+		}
+		ccb[0]=ATAPI_CMD_READ_12;
+		ccb[1]=0; /* reserved */
+		ccb[2]=(unsigned char) (blknr>>24) & 0xFF; /* MSB Block */
+		ccb[3]=(unsigned char) (blknr>>16) & 0xFF; /*  */
+		ccb[4]=(unsigned char) (blknr>> 8) & 0xFF;
+		ccb[5]=(unsigned char)  blknr      & 0xFF; /* LSB Block */
+		ccb[6]=(unsigned char) (cnt  >>24) & 0xFF; /* MSB Block count */
+		ccb[7]=(unsigned char) (cnt  >>16) & 0xFF;
+		ccb[8]=(unsigned char) (cnt  >> 8) & 0xFF;
+		ccb[9]=(unsigned char)  cnt	   & 0xFF; /* LSB Block */
+		ccb[10]=0; /* reserved */
+		ccb[11]=0; /* reserved */
+
+		if (atapi_issue_autoreq(device,ccb,12,
+					(unsigned char *)buffer,
+					cnt*ATAPI_READ_BLOCK_SIZE) == 0xFF) {
+			return (n);
+		}
+		n+=cnt;
+		blkcnt-=cnt;
+		blknr+=cnt;
+		buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong blocksize in ulong */
+	} while (blkcnt > 0);
+	return (n);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* CONFIG_ATAPI */
+
+#endif	/* CONFIG_COMMANDS & CFG_CMD_IDE */
diff --git a/common/cmd_immap.c b/common/cmd_immap.c
new file mode 100644
index 0000000..443335b
--- /dev/null
+++ b/common/cmd_immap.c
@@ -0,0 +1,578 @@
+/*
+ * (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
+ */
+
+/*
+ * MPC8xx/MPC8260 Internal Memory Map Functions
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cmd_immap.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_IMMAP) && \
+    (defined(CONFIG_8xx) || defined(CONFIG_8260))
+
+#if defined(CONFIG_8xx)
+#include <asm/8xx_immap.h>
+#include <commproc.h>
+#elif defined(CONFIG_8260)
+#include <asm/immap_8260.h>
+#include <asm/cpm_8260.h>
+#include <asm/iopin_8260.h>
+#endif
+
+static void
+unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	printf ("Sorry, but the '%s' command has not been implemented\n",
+		cmdtp->name);
+}
+
+int
+do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+	volatile sysconf8xx_t *sc = &immap->im_siu_conf;
+#elif defined(CONFIG_8260)
+	volatile sysconf8260_t *sc = &immap->im_siu_conf;
+#endif
+
+	printf ("SIUMCR= %08x SYPCR = %08x\n", sc->sc_siumcr, sc->sc_sypcr);
+#if defined(CONFIG_8xx)
+	printf ("SWT   = %08x\n", sc->sc_swt);
+	printf ("SIPEND= %08x SIMASK= %08x\n", sc->sc_sipend, sc->sc_simask);
+	printf ("SIEL  = %08x SIVEC = %08x\n", sc->sc_siel, sc->sc_sivec);
+	printf ("TESR  = %08x SDCR  = %08x\n", sc->sc_tesr, sc->sc_sdcr);
+#elif defined(CONFIG_8260)
+	printf ("BCR   = %08x\n", sc->sc_bcr);
+	printf ("P_ACR =       %02x P_ALRH= %08x P_ALRL= %08x\n",
+		sc->sc_ppc_acr, sc->sc_ppc_alrh, sc->sc_ppc_alrl);
+	printf ("L_ACR =       %02x L_ALRH= %08x L_ALRL= %08x\n",
+		sc->sc_lcl_acr, sc->sc_lcl_alrh, sc->sc_lcl_alrl);
+	printf ("PTESR1= %08x PTESR2= %08x\n", sc->sc_tescr1, sc->sc_tescr2);
+	printf ("LTESR1= %08x LTESR2= %08x\n", sc->sc_ltescr1, sc->sc_ltescr2);
+	printf ("PDTEA = %08x PDTEM =       %02x\n", sc->sc_pdtea, sc->sc_pdtem);
+	printf ("LDTEA = %08x LDTEM =       %02x\n", sc->sc_ldtea, sc->sc_ldtem);
+#endif
+	return 0;
+}
+
+int
+do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	int nbanks = 8;
+#elif defined(CONFIG_8260)
+	volatile memctl8260_t *memctl = &immap->im_memctl;
+	int nbanks = 12;
+#endif
+	volatile uint *p = &memctl->memc_br0;
+	int i;
+
+	for (i = 0; i < nbanks; i++, p += 2) {
+		if (i < 10) {
+			printf ("BR%d   = %08x OR%d   = %08x\n",
+				i, p[0], i, p[1]);
+		} else {
+			printf ("BR%d  = %08x OR%d  = %08x\n",
+				i, p[0], i, p[1]);
+		}
+	}
+
+	printf ("MAR   = %08x", memctl->memc_mar);
+#if defined(CONFIG_8xx)
+	printf (" MCR   = %08x\n", memctl->memc_mcr);
+#elif defined(CONFIG_8260)
+	printf ("\n");
+#endif
+	printf ("MAMR  = %08x MBMR  = %08x",
+		memctl->memc_mamr, memctl->memc_mbmr);
+#if defined(CONFIG_8xx)
+	printf ("\nMSTAT =     %04x\n", memctl->memc_mstat);
+#elif defined(CONFIG_8260)
+	printf (" MCMR  = %08x\n", memctl->memc_mcmr);
+#endif
+	printf ("MPTPR =     %04x MDR   = %08x\n",
+		memctl->memc_mptpr, memctl->memc_mdr);
+#if defined(CONFIG_8260)
+	printf ("PSDMR = %08x LSDMR = %08x\n",
+		memctl->memc_psdmr, memctl->memc_lsdmr);
+	printf ("PURT  =       %02x PSRT  =       %02x\n",
+		memctl->memc_purt, memctl->memc_psrt);
+	printf ("LURT  =       %02x LSRT  =       %02x\n",
+		memctl->memc_lurt, memctl->memc_lsrt);
+	printf ("IMMR  = %08x\n", memctl->memc_immr);
+#endif
+	return 0;
+}
+
+int
+do_sitinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+#ifdef CONFIG_8260
+int
+do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+#endif
+
+int
+do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+static int counter;
+
+static void
+header(void)
+{
+	char *data = "\
+       --------------------------------        --------------------------------\
+       00000000001111111111222222222233        00000000001111111111222222222233\
+       01234567890123456789012345678901        01234567890123456789012345678901\
+       --------------------------------        --------------------------------\
+    ";
+	int i;
+
+	if (counter % 2)
+	putc('\n');
+	counter = 0;
+
+	for (i = 0; i < 4; i++, data += 79)
+		printf("%.79s\n", data);
+}
+
+static void binary (char *label, uint value, int nbits)
+{
+	uint mask = 1 << (nbits - 1);
+	int i, second = (counter++ % 2);
+
+	if (second)
+		putc (' ');
+	puts (label);
+	for (i = 32 + 1; i != nbits; i--)
+		putc (' ');
+
+	while (mask != 0) {
+		if (value & mask)
+			putc ('1');
+		else
+			putc ('0');
+		mask >>= 1;
+	}
+
+	if (second)
+		putc ('\n');
+}
+
+#if defined(CONFIG_8xx)
+#define PA_NBITS	16
+#define PA_NB_ODR	 8
+#define PB_NBITS	18
+#define PB_NB_ODR	16
+#define PC_NBITS	12
+#define PD_NBITS	13
+#elif defined(CONFIG_8260)
+#define PA_NBITS	32
+#define PA_NB_ODR	32
+#define PB_NBITS	28
+#define PB_NB_ODR	28
+#define PC_NBITS	32
+#define PD_NBITS	28
+#endif
+
+int
+do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+	volatile iop8xx_t *iop = &immap->im_ioport;
+	volatile ushort *l, *r;
+#elif defined(CONFIG_8260)
+	volatile iop8260_t *iop = &immap->im_ioport;
+	volatile uint *l, *r;
+#endif
+	volatile uint *R;
+
+	counter = 0;
+	header ();
+
+	/*
+	 * Ports A & B
+	 */
+
+#if defined(CONFIG_8xx)
+	l = &iop->iop_padir;
+	R = &immap->im_cpm.cp_pbdir;
+#elif defined(CONFIG_8260)
+	l = &iop->iop_pdira;
+	R = &iop->iop_pdirb;
+#endif
+	binary ("PA_DIR", *l++, PA_NBITS);
+	binary ("PB_DIR", *R++, PB_NBITS);
+	binary ("PA_PAR", *l++, PA_NBITS);
+	binary ("PB_PAR", *R++, PB_NBITS);
+#if defined(CONFIG_8260)
+	binary ("PA_SOR", *l++, PA_NBITS);
+	binary ("PB_SOR", *R++, PB_NBITS);
+#endif
+	binary ("PA_ODR", *l++, PA_NB_ODR);
+	binary ("PB_ODR", *R++, PB_NB_ODR);
+	binary ("PA_DAT", *l++, PA_NBITS);
+	binary ("PB_DAT", *R++, PB_NBITS);
+
+	header ();
+
+	/*
+	 * Ports C & D
+	 */
+
+#if defined(CONFIG_8xx)
+	l = &iop->iop_pcdir;
+	r = &iop->iop_pddir;
+#elif defined(CONFIG_8260)
+	l = &iop->iop_pdirc;
+	r = &iop->iop_pdird;
+#endif
+	binary ("PC_DIR", *l++, PC_NBITS);
+	binary ("PD_DIR", *r++, PD_NBITS);
+	binary ("PC_PAR", *l++, PC_NBITS);
+	binary ("PD_PAR", *r++, PD_NBITS);
+#if defined(CONFIG_8xx)
+	binary ("PC_SO ", *l++, PC_NBITS);
+	binary ("      ", 0, 0);
+	r++;
+#elif defined(CONFIG_8260)
+	binary ("PC_SOR", *l++, PC_NBITS);
+	binary ("PD_SOR", *r++, PD_NBITS);
+	binary ("PC_ODR", *l++, PC_NBITS);
+	binary ("PD_ODR", *r++, PD_NBITS);
+#endif
+	binary ("PC_DAT", *l++, PC_NBITS);
+	binary ("PD_DAT", *r++, PD_NBITS);
+#if defined(CONFIG_8xx)
+	binary ("PC_INT", *l++, PC_NBITS);
+#endif
+
+	header ();
+	return 0;
+}
+
+/*
+ * set the io pins
+ * this needs a clean up for smaller tighter code
+ * use *uint and set the address based on cmd + port
+ */
+int
+do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#if defined(CONFIG_8260)
+	uint rcode = 0;
+	static uint port = 0;
+	static uint pin = 0;
+	static uint value = 0;
+	static enum { DIR, PAR, SOR, ODR, DAT } cmd = DAT;
+	iopin_t iopin;
+
+	if (argc != 5) {
+		printf ("iopset PORT PIN CMD VALUE\n");
+		return 1;
+	}
+	port = argv[1][0] - 'A';
+	if (port > 3)
+		port -= 0x20;
+	if (port > 3)
+		rcode = 1;
+	pin = simple_strtol (argv[2], NULL, 10);
+	if (pin > 31)
+		rcode = 1;
+
+
+	switch (argv[3][0]) {
+	case 'd':
+		if (argv[3][1] == 'a')
+			cmd = DAT;
+		else if (argv[3][1] == 'i')
+			cmd = DIR;
+		else
+			rcode = 1;
+		break;
+	case 'p':
+		cmd = PAR;
+		break;
+	case 'o':
+		cmd = ODR;
+		break;
+	case 's':
+		cmd = SOR;
+		break;
+	default:
+		printf ("iopset: unknown command %s\n", argv[3]);
+		rcode = 1;
+	}
+	if (argv[4][0] == '1')
+		value = 1;
+	else if (argv[4][0] == '0')
+		value = 0;
+	else
+		rcode = 1;
+	if (rcode == 0) {
+		iopin.port = port;
+		iopin.pin = pin;
+		switch (cmd) {
+		case DIR:
+			if (value)
+				iopin_set_out (&iopin);
+			else
+				iopin_set_in (&iopin);
+			break;
+		case PAR:
+			if (value)
+				iopin_set_ded (&iopin);
+			else
+				iopin_set_gen (&iopin);
+			break;
+		case SOR:
+			if (value)
+				iopin_set_opt2 (&iopin);
+			else
+				iopin_set_opt1 (&iopin);
+			break;
+		case ODR:
+			if (value)
+				iopin_set_odr (&iopin);
+			else
+				iopin_set_act (&iopin);
+			break;
+		case DAT:
+			if (value)
+				iopin_set_high (&iopin);
+			else
+				iopin_set_low (&iopin);
+			break;
+		}
+
+	}
+	return rcode;
+#else
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+#endif
+}
+
+int
+do_dmainfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+int
+do_fccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+static void prbrg (int n, uint val)
+{
+	uint extc = (val >> 14) & 3;
+	uint cd = (val & CPM_BRG_CD_MASK) >> 1;
+	uint div16 = (val & CPM_BRG_DIV16) != 0;
+
+#if defined(CONFIG_8xx)
+	DECLARE_GLOBAL_DATA_PTR;
+	ulong clock = gd->cpu_clk;
+#elif defined(CONFIG_8260)
+	DECLARE_GLOBAL_DATA_PTR;
+	ulong clock = gd->brg_clk;
+#endif
+
+	printf ("BRG%d:", n);
+
+	if (val & CPM_BRG_RST)
+		puts (" RESET");
+	else
+		puts ("      ");
+
+	if (val & CPM_BRG_EN)
+		puts ("  ENABLED");
+	else
+		puts (" DISABLED");
+
+	printf (" EXTC=%d", extc);
+
+	if (val & CPM_BRG_ATB)
+		puts (" ATB");
+	else
+		puts ("    ");
+
+	printf (" DIVIDER=%4d", cd);
+	if (extc == 0 && cd != 0) {
+		uint baudrate;
+
+		if (div16)
+			baudrate = (clock / 16) / (cd + 1);
+		else
+			baudrate = clock / (cd + 1);
+
+		printf ("=%6d bps", baudrate);
+	} else {
+		puts ("           ");
+	}
+
+	if (val & CPM_BRG_DIV16)
+		puts (" DIV16");
+	else
+		puts ("      ");
+
+	putc ('\n');
+}
+
+int
+do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+	volatile cpm8xx_t *cp = &immap->im_cpm;
+	volatile uint *p = &cp->cp_brgc1;
+#elif defined(CONFIG_8260)
+	volatile uint *p = &immap->im_brgc1;
+#endif
+	int i = 1;
+
+	while (i <= 4)
+		prbrg (i++, *p++);
+
+#if defined(CONFIG_8260)
+	p = &immap->im_brgc5;
+	while (i <= 8)
+		prbrg (i++, *p++);
+#endif
+	return 0;
+}
+
+int
+do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+	volatile i2c8xx_t *i2c = &immap->im_i2c;
+	volatile cpm8xx_t *cp = &immap->im_cpm;
+	volatile iic_t *iip = (iic_t *) & cp->cp_dparam[PROFF_IIC];
+#elif defined(CONFIG_8260)
+	volatile i2c8260_t *i2c = &immap->im_i2c;
+	volatile iic_t *iip;
+	uint dpaddr;
+
+	dpaddr = *((unsigned short *) (&immap->im_dprambase[PROFF_I2C_BASE]));
+	if (dpaddr == 0)
+		iip = NULL;
+	else
+		iip = (iic_t *) & immap->im_dprambase[dpaddr];
+#endif
+
+	printf ("I2MOD = %02x I2ADD = %02x\n", i2c->i2c_i2mod, i2c->i2c_i2add);
+	printf ("I2BRG = %02x I2COM = %02x\n", i2c->i2c_i2brg, i2c->i2c_i2com);
+	printf ("I2CER = %02x I2CMR = %02x\n", i2c->i2c_i2cer, i2c->i2c_i2cmr);
+
+	if (iip == NULL)
+		printf ("i2c parameter ram not allocated\n");
+	else {
+		printf ("RBASE = %08x TBASE = %08x\n",
+			iip->iic_rbase, iip->iic_tbase);
+		printf ("RFCR  =       %02x TFCR  =       %02x\n",
+			iip->iic_rfcr, iip->iic_tfcr);
+		printf ("MRBLR =     %04x\n", iip->iic_mrblr);
+		printf ("RSTATE= %08x RDP   = %08x\n",
+			iip->iic_rstate, iip->iic_rdp);
+		printf ("RBPTR =     %04x RBC   =     %04x\n",
+			iip->iic_rbptr, iip->iic_rbc);
+		printf ("RXTMP = %08x\n", iip->iic_rxtmp);
+		printf ("TSTATE= %08x TDP   = %08x\n",
+			iip->iic_tstate, iip->iic_tdp);
+		printf ("TBPTR =     %04x TBC   =     %04x\n",
+			iip->iic_tbptr, iip->iic_tbc);
+		printf ("TXTMP = %08x\n", iip->iic_txtmp);
+	}
+	return 0;
+}
+
+int
+do_sccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+int
+do_smcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+int
+do_spiinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+int
+do_muxinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+int
+do_siinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+
+int
+do_mccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unimplemented (cmdtp, flag, argc, argv);
+	return 0;
+}
+#endif	/* CFG_CMD_IMMAP && (CONFIG_8xx || CONFIG_8260) */
diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c
new file mode 100644
index 0000000..fc1d9c4
--- /dev/null
+++ b/common/cmd_jffs2.c
@@ -0,0 +1,179 @@
+/*
+ * (C) Copyright 2002
+ * 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
+ */
+
+/*
+ * Boot support
+ */
+#include <common.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <cmd_autoscript.h>
+#include <s_record.h>
+#include <net.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
+
+#include <jffs2/jffs2.h>
+static int part_num=0;
+
+#ifndef CFG_JFFS_CUSTOM_PART
+
+static struct part_info part;
+
+struct part_info*
+jffs2_part_info(int part_num)
+{
+	extern flash_info_t flash_info[];	/* info for FLASH chips */
+	int i;
+
+	if(part_num==0){
+
+		if(part.usr_priv==(void*)1)
+			return &part;
+
+		memset(&part, 0, sizeof(part));
+
+#if defined(CFG_JFFS2_FIRST_SECTOR)
+		part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
+#else
+		part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+#endif
+
+		/* Figure out flash partition size */
+		for (i = CFG_JFFS2_FIRST_BANK; i < CFG_JFFS2_NUM_BANKS+CFG_JFFS2_FIRST_BANK; i++)
+			part.size += flash_info[i].size;
+
+#if defined(CFG_JFFS2_FIRST_SECTOR) && (CFG_JFFS2_FIRST_SECTOR > 0)
+		part.size -=
+			flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] -
+			flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+#endif
+
+		/* unused in current jffs2 loader */
+		part.erasesize = 0;
+
+		/* Mark the struct as ready */
+		part.usr_priv=(void*)1;
+
+		return &part;
+	}
+	return 0;
+}
+#endif /* ifndef CFG_JFFS_CUSTOM_PART */
+int
+do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	char *filename = "pImage";
+	ulong offset = CFG_LOAD_ADDR;
+	int size;
+	struct part_info *part;
+
+	if (argc == 2) {
+		filename = argv[1];
+	}
+	if (argc == 3) {
+		offset = simple_strtoul(argv[1], NULL, 16);
+		filename = argv[2];
+	}
+
+	if (0 != (part=jffs2_part_info(part_num))){
+
+		printf("### JFFS2 loading '%s' to 0x%lx\n", filename, offset);
+		size = jffs2_1pass_load((char *)offset, part, filename);
+
+		if (size > 0) {
+			char buf[10];
+			printf("### JFFS2 load complete: %d bytes loaded to 0x%lx\n",
+				size, offset);
+			sprintf(buf, "%x", size);
+			setenv("filesize", buf);
+		} else {
+			printf("### JFFS2 LOAD ERROR<%x> for %s!\n", size, filename);
+		}
+
+		return !(size > 0);
+	}
+	printf("Active partition not valid\n");
+	return 0;
+}
+
+int
+do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	char *filename = "/";
+	int ret;
+	struct part_info *part;
+
+	if (argc == 2)
+		filename = argv[1];
+
+	if (0 != (part=jffs2_part_info(part_num))){
+
+		ret = jffs2_1pass_ls(jffs2_part_info(part_num), filename);
+
+		return (ret == 1);
+	}
+	printf("Active partition not valid\n");
+	return 0;
+}
+
+int
+do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	int ret;
+	struct part_info *part;
+
+	if (0 != (part=jffs2_part_info(part_num))){
+
+		ret = jffs2_1pass_info(jffs2_part_info(part_num));
+
+		return (ret == 1);
+	}
+	printf("Active partition not valid\n");
+	return 0;
+}
+
+int
+do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	int tmp_part;
+
+	if (argc >= 2) {
+		tmp_part = simple_strtoul(argv[1], NULL, 16);
+	}else{
+		printf("Need partition number in argument list\n");
+		return 0;
+
+	}
+
+	if (jffs2_part_info(tmp_part)){
+		printf("Partiton changed to %d\n",tmp_part);
+		part_num=tmp_part;
+		return 0;
+	}
+
+	printf("Partition %d is not valid partiton\n",tmp_part);
+	return 0;
+
+}
+#endif /* CFG_CMD_JFFS2 */
diff --git a/common/cmd_pci.c b/common/cmd_pci.c
new file mode 100644
index 0000000..22e4b9a
--- /dev/null
+++ b/common/cmd_pci.c
@@ -0,0 +1,477 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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
+ */
+
+/*
+ * PCI routines
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <command.h>
+#include <cmd_boot.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <cmd_pci.h>
+#include <pci.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCI)
+
+extern int cmd_get_data_size(char* arg, int default_size);
+
+unsigned char	ShortPCIListing = 1;
+
+/*
+ * Follows routines for the output of infos about devices on PCI bus.
+ */
+
+void pci_header_show(pci_dev_t dev);
+void pci_header_show_brief(pci_dev_t dev);
+
+/*
+ * Subroutine:  pciinfo
+ *
+ * Description: Show information about devices on PCI bus.
+ *				Depending on the define CFG_SHORT_PCI_LISTING
+ *				the output will be more or less exhaustive.
+ *
+ * Inputs:	bus_no		the number of the bus to be scanned.
+ *
+ * Return:      None
+ *
+ */
+void pciinfo(int BusNum, int ShortPCIListing)
+{
+	int Device;
+	int Function;
+	unsigned char HeaderType;
+	unsigned short VendorID;
+	pci_dev_t dev;
+
+	printf("Scanning PCI devices on bus %d\n", BusNum);
+
+	if (ShortPCIListing) {
+		printf("BusDevFun  VendorId   DeviceId   Device Class       Sub-Class\n");
+		printf("_____________________________________________________________\n");
+	}
+
+	for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) {
+		HeaderType = 0;
+		VendorID = 0;
+		for (Function = 0; Function < PCI_MAX_PCI_FUNCTIONS; Function++) {
+			/*
+			 * If this is not a multi-function device, we skip the rest.
+			 */
+			if (Function && !(HeaderType & 0x80))
+				break;
+
+			dev = PCI_BDF(BusNum, Device, Function);
+
+			pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID);
+			if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
+				continue;
+
+			pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType);
+
+			if (ShortPCIListing)
+			{
+				printf("%02x.%02x.%02x   ", BusNum, Device, Function);
+				pci_header_show_brief(dev);
+			}
+			else
+			{
+				printf("\nFound PCI device %02x.%02x.%02x:\n",
+				       BusNum, Device, Function);
+				pci_header_show(dev);
+			}
+	    }
+    }
+}
+
+char* pci_classes_str(u8 class)
+{
+	static char *pci_classes[] = {
+		"Build before PCI Rev2.0",
+		"Mass storage controller",
+		"Network controller     ",
+		"Display controller     ",
+		"Multimedia device      ",
+		"Memory controller      ",
+		"Bridge device          ",
+		"Simple comm. controller",
+		"Base system peripheral ",
+		"Input device           ",
+		"Docking station        ",
+		"Processor              ",
+		"Serial bus controller  ",
+		"Reserved entry         ",
+		"Does not fit any class "
+	};
+
+	if (class < (sizeof pci_classes / sizeof *pci_classes))
+		return pci_classes[(int) class];
+
+	return  "???                    ";
+}
+
+/*
+ * Subroutine:  pci_header_show_brief
+ *
+ * Description: Reads and prints the header of the
+ * 		specified PCI device in short form.
+ *
+ * Inputs:	dev      Bus+Device+Function number
+ *
+ * Return:      None
+ *
+ */
+void pci_header_show_brief(pci_dev_t dev)
+{
+	u16 vendor, device;
+	u8 class, subclass;
+
+	pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
+	pci_read_config_word(dev, PCI_DEVICE_ID, &device);
+	pci_read_config_byte(dev, PCI_CLASS_CODE, &class);
+	pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &subclass);
+
+	printf("0x%.4x     0x%.4x     %s 0x%.2x\n",
+	       vendor, device,
+	       pci_classes_str(class), subclass);
+}
+
+/*
+ * Subroutine:  PCI_Header_Show
+ *
+ * Description: Reads the header of the specified PCI device.
+ *
+ * Inputs:		BusDevFunc      Bus+Device+Function number
+ *
+ * Return:      None
+ *
+ */
+void pci_header_show(pci_dev_t dev)
+{
+	u8 _byte, header_type;
+	u16 _word;
+	u32 _dword;
+
+#define PRINT(msg, type, reg) \
+	pci_read_config_##type(dev, reg, &_##type); \
+	printf(msg, _##type)
+
+#define PRINT2(msg, type, reg, func) \
+	pci_read_config_##type(dev, reg, &_##type); \
+	printf(msg, _##type, func(_##type))
+
+	pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
+
+	PRINT ("  vendor ID =                   0x%.4x\n", word, PCI_VENDOR_ID);
+	PRINT ("  device ID =                   0x%.4x\n", word, PCI_DEVICE_ID);
+	PRINT ("  command register =            0x%.4x\n", word, PCI_COMMAND);
+	PRINT ("  status register =             0x%.4x\n", word, PCI_STATUS);
+	PRINT ("  revision ID =                 0x%.2x\n", byte, PCI_REVISION_ID);
+	PRINT2("  class code =                  0x%.2x (%s)\n", byte, PCI_CLASS_CODE,
+	       							pci_classes_str);
+	PRINT ("  sub class code =              0x%.2x\n", byte, PCI_CLASS_SUB_CODE);
+	PRINT ("  programming interface =       0x%.2x\n", byte, PCI_CLASS_PROG);
+	PRINT ("  cache line =                  0x%.2x\n", byte, PCI_CACHE_LINE_SIZE);
+	PRINT ("  latency time =                0x%.2x\n", byte, PCI_LATENCY_TIMER);
+	PRINT ("  header type =                 0x%.2x\n", byte, PCI_HEADER_TYPE);
+	PRINT ("  BIST =                        0x%.2x\n", byte, PCI_BIST);
+	PRINT ("  base address 0 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_0);
+	PRINT ("  base address 1 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_1);
+
+	if (header_type & 0x01) {		/* PCI-to-PCI bridge */
+		PRINT ("  primary bus number =          0x%.2x\n", byte, PCI_PRIMARY_BUS);
+		PRINT ("  secondary bus number =        0x%.2x\n", byte, PCI_SECONDARY_BUS);
+		PRINT ("  subordinate bus number =      0x%.2x\n", byte, PCI_SUBORDINATE_BUS);
+		PRINT ("  secondary latency timer =     0x%.2x\n", byte, PCI_SEC_LATENCY_TIMER);
+		PRINT ("  IO base =                     0x%.2x\n", byte, PCI_IO_BASE);
+		PRINT ("  IO limit =                    0x%.2x\n", byte, PCI_IO_LIMIT);
+		PRINT ("  secondary status =            0x%.4x\n", word, PCI_SEC_STATUS);
+		PRINT ("  memory base =                 0x%.4x\n", word, PCI_MEMORY_BASE);
+		PRINT ("  memory limit =                0x%.4x\n", word, PCI_MEMORY_LIMIT);
+		PRINT ("  prefetch memory base =        0x%.4x\n", word, PCI_PREF_MEMORY_BASE);
+		PRINT ("  prefetch memory limit =       0x%.4x\n", word, PCI_PREF_MEMORY_LIMIT);
+		PRINT ("  prefetch memory base upper =  0x%.8x\n", dword, PCI_PREF_BASE_UPPER32);
+		PRINT ("  prefetch memory limit upper = 0x%.8x\n", dword, PCI_PREF_LIMIT_UPPER32);
+		PRINT ("  IO base upper 16 bits =       0x%.4x\n", word, PCI_IO_BASE_UPPER16);
+		PRINT ("  IO limit upper 16 bits =      0x%.4x\n", word, PCI_IO_LIMIT_UPPER16);
+		PRINT ("  expansion ROM base address =  0x%.8x\n", dword, PCI_ROM_ADDRESS1);
+		PRINT ("  interrupt line =              0x%.2x\n", byte, PCI_INTERRUPT_LINE);
+		PRINT ("  interrupt pin =               0x%.2x\n", byte, PCI_INTERRUPT_PIN);
+		PRINT ("  bridge control =              0x%.4x\n", word, PCI_BRIDGE_CONTROL);
+    } else {					/* PCI device */
+		PRINT("  base address 2 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_2);
+		PRINT("  base address 3 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_3);
+		PRINT("  base address 4 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_4);
+		PRINT("  base address 5 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_5);
+		PRINT("  cardBus CIS pointer =         0x%.8x\n", dword, PCI_CARDBUS_CIS);
+		PRINT("  sub system vendor ID =        0x%.4x\n", word, PCI_SUBSYSTEM_VENDOR_ID);
+		PRINT("  sub system ID =               0x%.4x\n", word, PCI_SUBSYSTEM_ID);
+		PRINT("  expansion ROM base address =  0x%.8x\n", dword, PCI_ROM_ADDRESS);
+		PRINT("  interrupt line =              0x%.2x\n", byte, PCI_INTERRUPT_LINE);
+		PRINT("  interrupt pin =               0x%.2x\n", byte, PCI_INTERRUPT_PIN);
+		PRINT("  min Grant =                   0x%.2x\n", byte, PCI_MIN_GNT);
+		PRINT("  max Latency =                 0x%.2x\n", byte, PCI_MAX_LAT);
+    }
+
+#undef PRINT
+#undef PRINT2
+}
+
+/* Convert the "bus.device.function" identifier into a number.
+ */
+static pci_dev_t get_pci_dev(char* name)
+{
+	char cnum[12];
+	int len, i, iold, n;
+	int bdfs[3] = {0,0,0};
+
+	len = strlen(name);
+	if (len > 8)
+		return -1;
+	for (i = 0, iold = 0, n = 0; i < len; i++) {
+		if (name[i] == '.') {
+			memcpy(cnum, &name[iold], i - iold);
+			cnum[i - iold] = '\0';
+			bdfs[n++] = simple_strtoul(cnum, NULL, 16);
+			iold = i + 1;
+		}
+	}
+	strcpy(cnum, &name[iold]);
+	if (n == 0)
+		n = 1;
+	bdfs[n] = simple_strtoul(cnum, NULL, 16);
+	return PCI_BDF(bdfs[0], bdfs[1], bdfs[2]);
+}
+
+static int pci_cfg_display(pci_dev_t bdf, ulong addr, ulong size, ulong length)
+{
+#define DISP_LINE_LEN	16
+	ulong i, nbytes, linebytes;
+	int rc = 0;
+
+	if (length == 0)
+		length = 0x40 / size; /* Standard PCI configuration space */
+
+	/* Print the lines.
+	 * once, and all accesses are with the specified bus width.
+	 */
+	nbytes = length * size;
+	do {
+		uint	val4;
+		ushort  val2;
+		u_char	val1;
+
+		printf("%08lx:", addr);
+		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
+		for (i=0; i<linebytes; i+= size) {
+			if (size == 4) {
+				pci_read_config_dword(bdf, addr, &val4);
+				printf(" %08x", val4);
+			} else if (size == 2) {
+				pci_read_config_word(bdf, addr, &val2);
+				printf(" %04x", val2);
+			} else {
+				pci_read_config_byte(bdf, addr, &val1);
+				printf(" %02x", val1);
+			}
+			addr += size;
+		}
+		printf("\n");
+		nbytes -= linebytes;
+		if (ctrlc()) {
+			rc = 1;
+			break;
+		}
+	} while (nbytes > 0);
+
+	return (rc);
+}
+
+static int pci_cfg_write (pci_dev_t bdf, ulong addr, ulong size, ulong value)
+{
+	if (size == 4) {
+		pci_write_config_dword(bdf, addr, value);
+	}
+	else if (size == 2) {
+		ushort val = value & 0xffff;
+		pci_write_config_word(bdf, addr, val);
+	}
+	else {
+		u_char val = value & 0xff;
+		pci_write_config_byte(bdf, addr, val);
+	}
+	return 0;
+}
+
+static int
+pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag)
+{
+	ulong	i;
+	int	nbytes;
+	extern char console_buffer[];
+	uint	val4;
+	ushort  val2;
+	u_char	val1;
+
+	/* Print the address, followed by value.  Then accept input for
+	 * the next value.  A non-converted value exits.
+	 */
+	do {
+		printf("%08lx:", addr);
+		if (size == 4) {
+			pci_read_config_dword(bdf, addr, &val4);
+			printf(" %08x", val4);
+		}
+		else if (size == 2) {
+			pci_read_config_word(bdf, addr, &val2);
+			printf(" %04x", val2);
+		}
+		else {
+			pci_read_config_byte(bdf, addr, &val1);
+			printf(" %02x", val1);
+		}
+
+		nbytes = readline (" ? ");
+		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
+			/* <CR> pressed as only input, don't modify current
+			 * location and move to next. "-" pressed will go back.
+			 */
+			if (incrflag)
+				addr += nbytes ? -size : size;
+			nbytes = 1;
+#ifdef CONFIG_BOOT_RETRY_TIME
+			reset_cmd_timeout(); /* good enough to not time out */
+#endif
+		}
+#ifdef CONFIG_BOOT_RETRY_TIME
+		else if (nbytes == -2) {
+			break;	/* timed out, exit the command	*/
+		}
+#endif
+		else {
+			char *endp;
+			i = simple_strtoul(console_buffer, &endp, 16);
+			nbytes = endp - console_buffer;
+			if (nbytes) {
+#ifdef CONFIG_BOOT_RETRY_TIME
+				/* good enough to not time out
+				 */
+				reset_cmd_timeout();
+#endif
+				pci_cfg_write (bdf, addr, size, i);
+				if (incrflag)
+					addr += size;
+			}
+		}
+	} while (nbytes);
+
+	return 0;
+}
+
+/* PCI Configuration Space access commands
+ *
+ * Syntax:
+ *	pci display[.b, .w, .l] bus.device.function} [addr] [len]
+ *	pci next[.b, .w, .l] bus.device.function [addr]
+ *      pci modify[.b, .w, .l] bus.device.function [addr]
+ *      pci write[.b, .w, .l] bus.device.function addr value
+ */
+int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	ulong addr = 0, value = 0, size = 0;
+	pci_dev_t bdf = 0;
+	char cmd = 's';
+
+	if (argc > 1)
+		cmd = argv[1][0];
+
+	switch (cmd) {
+	case 'd':		/* display */
+	case 'n':		/* next */
+	case 'm':		/* modify */
+	case 'w':		/* write */
+		/* Check for a size specification. */
+		size = cmd_get_data_size(argv[1], 4);
+		if (argc > 3)
+			addr = simple_strtoul(argv[3], NULL, 16);
+		if (argc > 4)
+			value = simple_strtoul(argv[4], NULL, 16);
+	case 'h':		/* header */
+		if (argc < 3)
+			goto usage;
+		if ((bdf = get_pci_dev(argv[2])) == -1)
+			return 1;
+		break;
+	default:		/* scan bus */
+		value = 1; /* short listing */
+		bdf = 0;   /* bus number  */
+		if (argc > 1) {
+			if (argv[argc-1][0] == 'l') {
+				value = 0;
+				argc--;
+			}
+			if (argc > 1)
+				bdf = simple_strtoul(argv[1], NULL, 16);
+		}
+		pciinfo(bdf, value);
+		return 0;
+	}
+
+	switch (argv[1][0]) {
+	case 'h':		/* header */
+		pci_header_show(bdf);
+		return 0;
+	case 'd':		/* display */
+		return pci_cfg_display(bdf, addr, size, value);
+	case 'n':		/* next */
+		if (argc < 4)
+			goto usage;
+		return pci_cfg_modify(bdf, addr, size, value, 0);
+	case 'm':		/* modify */
+		if (argc < 4)
+			goto usage;
+		return pci_cfg_modify(bdf, addr, size, value, 1);
+	case 'w':		/* write */
+		if (argc < 5)
+			goto usage;
+		return pci_cfg_write(bdf, addr, size, value);
+	}
+
+	return 1;
+ usage:
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_PCI) */
+
+#endif /* CONFIG_PCI */
diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c
new file mode 100644
index 0000000..ccf21a9
--- /dev/null
+++ b/common/cmd_pcmcia.c
@@ -0,0 +1,2243 @@
+/*
+ * (C) Copyright 2000-2002
+ * 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
+ *
+ ********************************************************************
+ *
+ * Lots of code copied from:
+ *
+ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
+ * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
+ *
+ * "The ExCA standard specifies that socket controllers should provide
+ * two IO and five memory windows per socket, which can be independently
+ * configured and positioned in the host address space and mapped to
+ * arbitrary segments of card address space. " - David A Hinds. 1999
+ *
+ * This controller does _not_ meet the ExCA standard.
+ *
+ * m8xx pcmcia controller brief info:
+ * + 8 windows (attrib, mem, i/o)
+ * + up to two slots (SLOT_A and SLOT_B)
+ * + inputpins, outputpins, event and mask registers.
+ * - no offset register. sigh.
+ *
+ * Because of the lacking offset register we must map the whole card.
+ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
+ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
+ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
+ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
+ * They are maximum 64KByte each...
+ */
+
+/* #define DEBUG	1	*/
+
+/*
+ * PCMCIA support
+ */
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <pcmcia.h>
+#include <cmd_pcmcia.h>
+#if defined(CONFIG_IDE_8xx_PCCARD) && defined(CONFIG_8xx)
+#include <mpc8xx.h>
+#endif
+#if defined(CONFIG_LWMON)
+#include <i2c.h>
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
+    ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
+
+int pcmcia_on (void);
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int  pcmcia_off (void);
+static int  hardware_disable(int slot);
+#endif
+static int  hardware_enable (int slot);
+static int  voltage_set(int slot, int vcc, int vpp);
+#ifdef CONFIG_IDE_8xx_PCCARD
+static void print_funcid (int func);
+static void print_fixed  (volatile uchar *p);
+static int  identify     (volatile uchar *p);
+static int  check_ide_device (void);
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+
+static u_int m8xx_get_graycode(u_int size);
+#if 0
+static u_int m8xx_get_speed(u_int ns, u_int is_io);
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* look up table for pgcrx registers */
+
+static u_int *pcmcia_pgcrx[2] = {
+	&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
+	&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
+};
+
+#define PCMCIA_PGCRX(slot)	(*pcmcia_pgcrx[slot])
+
+const char *indent = "\t   ";
+
+/* ------------------------------------------------------------------------- */
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	int rcode = 0;
+
+	if (argc != 2) {
+		printf ("Usage: pinit {on | off}\n");
+		return 1;
+	}
+	if (strcmp(argv[1],"on") == 0) {
+	     	rcode = pcmcia_on ();
+	} else if (strcmp(argv[1],"off") == 0) {
+		rcode = pcmcia_off ();
+	} else {
+		printf ("Usage: pinit {on | off}\n");
+		return 1;
+	}
+
+	return rcode;
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_LWMON)
+# define  CFG_PCMCIA_TIMING	(PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
+#else
+# define  CFG_PCMCIA_TIMING	(PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
+#endif
+
+int pcmcia_on (void)
+{
+	int i;
+	u_long reg, base;
+	pcmcia_win_t *win;
+
+	debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
+
+	/* intialize the fixed memory windows */
+	win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
+	base = CFG_PCMCIA_MEM_ADDR;
+
+	if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
+		printf ("Cannot set window size to 0x%08x\n",
+			CFG_PCMCIA_MEM_SIZE);
+		return (1);
+	}
+
+	for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
+		win->br = base;
+
+		switch (i) {
+#ifdef CONFIG_IDE_8xx_PCCARD
+		case 0:	{	/* map attribute memory */
+			win->or = (	PCMCIA_BSIZE_64M
+				|	PCMCIA_PPS_8
+				|	PCMCIA_PRS_ATTR
+				|	PCMCIA_SLOT_x
+				|	PCMCIA_PV
+				|	CFG_PCMCIA_TIMING );
+			break;
+		    }
+
+		case 1: {	/* map I/O window for data reg */
+			win->or = (	PCMCIA_BSIZE_1K
+				|	PCMCIA_PPS_16
+				|	PCMCIA_PRS_IO
+				|	PCMCIA_SLOT_x
+				|	PCMCIA_PV
+				|	CFG_PCMCIA_TIMING );
+			break;
+		    }
+
+		case 2: {	/* map I/O window for command/ctrl reg block */
+			win->or = (	PCMCIA_BSIZE_1K
+				|	PCMCIA_PPS_8
+				|	PCMCIA_PRS_IO
+				|	PCMCIA_SLOT_x
+				|	PCMCIA_PV
+				|	CFG_PCMCIA_TIMING );
+			break;
+		    }
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+		default:	/* set to not valid */
+			win->or = 0;
+			break;
+		}
+
+		debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
+			i, win->br, win->or);
+		base += CFG_PCMCIA_MEM_SIZE;
+		++win;
+	}
+
+	/* turn off voltage */
+	if (voltage_set(_slot_, 0, 0))
+		return (1);
+
+	/* Enable external hardware */
+	if (hardware_enable(_slot_))
+		return (1);
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+	if (check_ide_device())
+		return (1);
+#endif
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+static int pcmcia_off (void)
+{
+	int i;
+	pcmcia_win_t *win;
+
+	printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
+
+	/* clear interrupt state, and disable interrupts */
+	((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
+	((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+	/* turn off interrupt and disable CxOE */
+	PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
+
+	/* turn off memory windows */
+	win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
+
+	for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
+		/* disable memory window */
+		win->or = 0;
+		++win;
+	}
+
+	/* turn off voltage */
+	voltage_set(_slot_, 0, 0);
+
+	/* disable external hardware */
+	printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
+	hardware_disable(_slot_);
+	return 0;
+}
+
+#endif	/* CFG_CMD_PCMCIA */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+
+#define	MAX_TUPEL_SZ	512
+#define MAX_FEATURES	4
+
+static int check_ide_device (void)
+{
+	volatile uchar *ident = NULL;
+	volatile uchar *feature_p[MAX_FEATURES];
+	volatile uchar *p, *start;
+	int n_features = 0;
+	uchar func_id = ~0;
+	uchar code, len;
+	ushort config_base = 0;
+	int found = 0;
+	int i;
+
+	debug ("PCMCIA MEM: %08X\n", CFG_PCMCIA_MEM_ADDR);
+
+	start = p = (volatile uchar *) CFG_PCMCIA_MEM_ADDR;
+
+	while ((p - start) < MAX_TUPEL_SZ) {
+
+		code = *p; p += 2;
+
+		if (code == 0xFF) { /* End of chain */
+			break;
+		}
+
+		len = *p; p += 2;
+#if defined(DEBUG) && (DEBUG > 1)
+		{ volatile uchar *q = p;
+			printf ("\nTuple code %02x  length %d\n\tData:",
+				code, len);
+
+			for (i = 0; i < len; ++i) {
+				printf (" %02x", *q);
+				q+= 2;
+			}
+		}
+#endif	/* DEBUG */
+		switch (code) {
+		case CISTPL_VERS_1:
+			ident = p + 4;
+			break;
+		case CISTPL_FUNCID:
+			/* Fix for broken SanDisk which may have 0x80 bit set */
+			func_id = *p & 0x7F;
+			break;
+		case CISTPL_FUNCE:
+			if (n_features < MAX_FEATURES)
+				feature_p[n_features++] = p;
+			break;
+		case CISTPL_CONFIG:
+			config_base = (*(p+6) << 8) + (*(p+4));
+			debug ("\n## Config_base = %04x ###\n", config_base);
+		default:
+			break;
+		}
+		p += 2 * len;
+	}
+
+	found = identify (ident);
+
+	if (func_id != ((uchar)~0)) {
+		print_funcid (func_id);
+
+		if (func_id == CISTPL_FUNCID_FIXED)
+			found = 1;
+		else
+			return (1);	/* no disk drive */
+	}
+
+	for (i=0; i<n_features; ++i) {
+		print_fixed (feature_p[i]);
+	}
+
+	if (!found) {
+		printf ("unknown card type\n");
+		return (1);
+	}
+
+	/* set I/O area in config reg -> only valid for ARGOSY D5!!! */
+	*((uchar *)(CFG_PCMCIA_MEM_ADDR + config_base)) = 1;
+
+	return (0);
+}
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+
+/* ---------------------------------------------------------------------------- */
+/* board specific stuff:							*/
+/* voltage_set(), hardware_enable() and hardware_disable()			*/
+/* ---------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------- */
+/* RPX Boards from Embedded Planet						*/
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+
+/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
+ * SYPCR is write once only, therefore must the slowest memory be faster
+ * than the bus monitor or we will get a machine check due to the bus timeout.
+ */
+
+#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
+
+#undef PCMCIA_BMT_LIMIT
+#define PCMCIA_BMT_LIMIT (6*8)
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	u_long reg = 0;
+
+	switch(vcc) {
+	case 0: break;
+	case 33: reg |= BCSR1_PCVCTL4; break;
+	case 50: reg |= BCSR1_PCVCTL5; break;
+	default: return 1;
+	}
+
+	switch(vpp) {
+	case 0: break;
+	case 33:
+	case 50:
+		if(vcc == vpp)
+			reg |= BCSR1_PCVCTL6;
+		else
+			return 1;
+		break;
+	case 120:
+		reg |= BCSR1_PCVCTL7;
+	default: return 1;
+	}
+
+	if(vcc == 120)
+	   return 1;
+
+	/* first, turn off all power */
+
+	*((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
+				     | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
+
+	/* enable new powersettings */
+
+	*((uint *)RPX_CSR_ADDR) |= reg;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+static int hardware_enable (int slot)
+{
+	return 0;	/* No hardware to enable */
+}
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	return 0;	/* No hardware to disable */
+}
+#endif	/* CFG_CMD_PCMCIA */
+#endif	/* CONFIG_RPXCLASSIC */
+
+/* ---------------------------------------------------------------------------- */
+/* (F)ADS Boards from Motorola							*/
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
+
+#ifdef CONFIG_ADS
+#define PCMCIA_BOARD_MSG "ADS"
+#define PCMCIA_GLITCHY_CD  /* My ADS board needs this */
+#else
+#define PCMCIA_BOARD_MSG "FADS"
+#endif
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	u_long reg = 0;
+
+	switch(vpp) {
+	case 0: reg = 0; break;
+	case 50: reg = 1; break;
+	case 120: reg = 2; break;
+	default: return 1;
+	}
+
+	switch(vcc) {
+	case 0: reg = 0; break;
+#ifdef CONFIG_ADS
+	case 50: reg = BCSR1_PCCVCCON; break;
+#endif
+#ifdef CONFIG_FADS
+	case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
+	case 50: reg = BCSR1_PCCVCC1; break;
+#endif
+	default: return 1;
+	}
+
+	/* first, turn off all power */
+
+#ifdef CONFIG_ADS
+	*((uint *)BCSR1) |= BCSR1_PCCVCCON;
+#endif
+#ifdef CONFIG_FADS
+	*((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
+#endif
+	*((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
+
+	/* enable new powersettings */
+
+#ifdef CONFIG_ADS
+	*((uint *)BCSR1) &= ~reg;
+#endif
+#ifdef CONFIG_FADS
+	*((uint *)BCSR1) |= reg;
+#endif
+
+ 	*((uint *)BCSR1) |= reg << 20;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static int hardware_enable(int slot)
+{
+	*((uint *)BCSR1) &= ~BCSR1_PCCEN;
+	return 0;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	*((uint *)BCSR1) &= ~BCSR1_PCCEN;
+	return 0;
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+#endif	/* (F)ADS */
+
+/* ---------------------------------------------------------------------------- */
+/* TQM8xxL Boards by TQ Components						*/
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_TQM8xxL)
+
+#define PCMCIA_BOARD_MSG "TQM8xxL"
+
+
+static int hardware_enable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	volatile sysconf8xx_t	*sysp;
+	uint reg, mask;
+
+	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	udelay(10000);
+
+	immap = (immap_t *)CFG_IMMR;
+	sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/*
+	 * Configure SIUMCR to enable PCMCIA port B
+	 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+	 */
+	sysp->sc_siumcr &= ~SIUMCR_DBGC11;	/* set DBGC to 00 */
+
+	/* clear interrupt state, and disable interrupts */
+	pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
+	pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+	/* disable interrupts & DMA */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Configure Port C pins for
+	 * 5 Volts Enable and 3 Volts enable
+	 */
+	immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
+	immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
+	/* remove all power */
+
+	immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
+
+	/*
+	 * Make sure there is a card in the slot, then configure the interface.
+	 */
+	udelay(10000);
+	debug ("[%d] %s: PIPR(%p)=0x%x\n",
+		__LINE__,__FUNCTION__,
+		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+	if (pcmp->pcmc_pipr & 0x00001800) {
+		printf ("   No Card found\n");
+		return (1);
+	}
+
+	/*
+	 * Power On.
+	 */
+	mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+	reg  = pcmp->pcmc_pipr;
+	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+		reg,
+		(reg&PCMCIA_VS1(slot))?"n":"ff",
+		(reg&PCMCIA_VS2(slot))?"n":"ff");
+	if ((reg & mask) == mask) {
+		immap->im_ioport.iop_pcdat |= 0x0004;
+		puts (" 5.0V card found: ");
+	} else {
+		immap->im_ioport.iop_pcdat |= 0x0002;
+		puts (" 3.3V card found: ");
+	}
+	immap->im_ioport.iop_pcdir |=  (0x0002 | 0x0004);
+#if 0
+	/*  VCC switch error flag, PCMCIA slot INPACK_ pin */
+	cp->cp_pbdir &= ~(0x0020 | 0x0010);
+	cp->cp_pbpar &= ~(0x0020 | 0x0010);
+	udelay(500000);
+#endif
+	udelay(1000);
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(250000);	/* some cards need >150 ms to come up :-( */
+
+	debug ("# hardware_enable done\n");
+
+	return (0);
+}
+
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+	/* remove all power */
+	immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
+
+	/* Configure PCMCIA General Control Register */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(10000);
+
+	return (0);
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	volatile immap_t	*immap;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("voltage_set: "
+		PCMCIA_BOARD_MSG
+		" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+		'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Configure Port C pins for
+	 * 5 Volts Enable and 3 Volts enable,
+	 * Turn off all power
+	 */
+	debug ("PCMCIA power OFF\n");
+	immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
+	immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
+	immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
+
+	reg = 0;
+	switch(vcc) {
+	case  0: 		break;
+	case 33: reg |= 0x0002;	break;
+	case 50: reg |= 0x0004;	break;
+	default: 		goto done;
+	}
+
+	/* Checking supported voltages */
+
+	debug ("PIPR: 0x%x --> %s\n",
+		pcmp->pcmc_pipr,
+		(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+	immap->im_ioport.iop_pcdat |= reg;
+	immap->im_ioport.iop_pcdir |=  (0x0002 | 0x0004);
+	if (reg) {
+		debug ("PCMCIA powered at %sV\n",
+			(reg&0x0004) ? "5.0" : "3.3");
+	} else {
+		debug ("PCMCIA powered down\n");
+	}
+
+done:
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
+		slot+'A');
+	return (0);
+}
+
+#endif	/* TQM8xxL */
+
+
+/* ---------------------------------------------------------------------------- */
+/* LWMON Board									*/
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_LWMON)
+
+#define PCMCIA_BOARD_MSG "LWMON"
+
+/* #define's for MAX1604 Power Switch */
+#define MAX1604_OP_SUS		0x80
+#define MAX1604_VCCBON		0x40
+#define MAX1604_VCC_35		0x20
+#define MAX1604_VCCBHIZ		0x10
+#define MAX1604_VPPBON		0x08
+#define MAX1604_VPPBPBPGM	0x04
+#define MAX1604_VPPBHIZ		0x02
+/* reserved			0x01	*/
+
+static int hardware_enable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	volatile sysconf8xx_t	*sysp;
+	uint reg, mask;
+	uchar val;
+
+
+	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	/* Switch on PCMCIA port in PIC register 0x60 */
+	reg = pic_read  (0x60);
+	debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+	reg &= ~0x10;
+	/* reg |=  0x08; Vpp not needed */
+	pic_write (0x60, reg);
+#ifdef DEBUG
+	reg = pic_read  (0x60);
+	printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+#endif
+	udelay(10000);
+
+	immap = (immap_t *)CFG_IMMR;
+	sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/*
+	 * Configure SIUMCR to enable PCMCIA port B
+	 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+	 */
+	sysp->sc_siumcr &= ~SIUMCR_DBGC11;	/* set DBGC to 00 */
+
+	/* clear interrupt state, and disable interrupts */
+	pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
+	pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+	/* disable interrupts & DMA */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Make sure there is a card in the slot, then configure the interface.
+	 */
+	udelay(10000);
+	debug ("[%d] %s: PIPR(%p)=0x%x\n",
+		__LINE__,__FUNCTION__,
+		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+	if (pcmp->pcmc_pipr & 0x00001800) {
+		printf ("   No Card found\n");
+		return (1);
+	}
+
+	/*
+	 * Power On.
+	 */
+	mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+	reg  = pcmp->pcmc_pipr;
+	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+		reg,
+		(reg&PCMCIA_VS1(slot))?"n":"ff",
+		(reg&PCMCIA_VS2(slot))?"n":"ff");
+	if ((reg & mask) == mask) {
+		val = 0;		/* VCCB3/5 = 0 ==> use Vx = 5.0 V */
+		puts (" 5.0V card found: ");
+	} else {
+		val = MAX1604_VCC_35;	/* VCCB3/5 = 1 ==> use Vy = 3.3 V */
+		puts (" 3.3V card found: ");
+	}
+
+	/*  switch VCC on */
+	val |=  MAX1604_OP_SUS | MAX1604_VCCBON;
+	i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+	i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+
+	udelay(500000);
+
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(250000);	/* some cards need >150 ms to come up :-( */
+
+	debug ("# hardware_enable done\n");
+
+	return (0);
+}
+
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+	uchar val;
+
+	debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+	/* remove all power, put output in high impedance state */
+	val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
+	i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+	i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+
+	/* Configure PCMCIA General Control Register */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	/* Switch off PCMCIA port in PIC register 0x60 */
+	reg = pic_read  (0x60);
+	debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+	reg |=  0x10;
+	reg &= ~0x08;
+	pic_write (0x60, reg);
+#ifdef DEBUG
+	reg = pic_read  (0x60);
+	printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+#endif
+	udelay(10000);
+
+	return (0);
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	volatile immap_t	*immap;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+	uchar val;
+
+	debug ("voltage_set: "
+		PCMCIA_BOARD_MSG
+		" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+		'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Turn off all power (switch to high impedance)
+	 */
+	debug ("PCMCIA power OFF\n");
+	val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
+	i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+	i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+
+	val = 0;
+	switch(vcc) {
+	case  0: 			break;
+	case 33: val = MAX1604_VCC_35;	break;
+	case 50: 			break;
+	default: 			goto done;
+	}
+
+	/* Checking supported voltages */
+
+	debug ("PIPR: 0x%x --> %s\n",
+		pcmp->pcmc_pipr,
+		(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+	i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+	if (val) {
+		debug ("PCMCIA powered at %sV\n",
+			(val & MAX1604_VCC_35) ? "3.3" : "5.0");
+	} else {
+		debug ("PCMCIA powered down\n");
+	}
+
+done:
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
+		slot+'A');
+	return (0);
+}
+
+#endif	/* LWMON */
+
+/* ---------------------------------------------------------------------------- */
+/* GTH board by Corelatus AB                                                    */
+/* ---------------------------------------------------------------------------- */
+#if defined(CONFIG_GTH)
+
+#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{  /* Do nothing */
+  return 0;
+}
+
+static int hardware_enable (int slot)
+{
+  volatile immap_t	*immap;
+  volatile cpm8xx_t	*cp;
+  volatile pcmconf8xx_t	*pcmp;
+  volatile sysconf8xx_t	*sysp;
+  uint reg, mask;
+
+  debug ("hardware_enable: GTH Slot %c\n", 'A'+slot);
+
+  immap = (immap_t *)CFG_IMMR;
+  sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+  pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+  cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+  /* clear interrupt state, and disable interrupts */
+  pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
+  pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+  /* disable interrupts & DMA */
+  PCMCIA_PGCRX(_slot_) = 0;
+
+  /*
+   * Disable PCMCIA buffers (isolate the interface)
+   * and assert RESET signal
+   */
+  debug ("Disable PCMCIA buffers and assert RESET\n");
+  reg  =  PCMCIA_PGCRX(_slot_);
+  reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+  reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+  PCMCIA_PGCRX(_slot_) = reg;
+  udelay(500);
+
+  /*
+   * Make sure there is a card in the slot, then configure the interface.
+   */
+  udelay(10000);
+  debug ("[%d] %s: PIPR(%p)=0x%x\n",
+		__LINE__,__FUNCTION__,
+		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+  if (pcmp->pcmc_pipr & 0x98000000) {
+    printf ("   No Card found\n");
+    return (1);
+  }
+
+  mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+  reg  = pcmp->pcmc_pipr;
+  debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+		reg,
+		(reg&PCMCIA_VS1(slot))?"n":"ff",
+		(reg&PCMCIA_VS2(slot))?"n":"ff");
+
+  debug ("Enable PCMCIA buffers and stop RESET\n");
+  reg  =  PCMCIA_PGCRX(_slot_);
+  reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+  reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+  PCMCIA_PGCRX(_slot_) = reg;
+
+  udelay(250000);	/* some cards need >150 ms to come up :-( */
+
+  debug ("# hardware_enable done\n");
+
+  return 0;
+}
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	return 0;	/* No hardware to disable */
+}
+#endif	/* CFG_CMD_PCMCIA */
+#endif	/* CONFIG_GTH */
+
+/* ---------------------------------------------------------------------------- */
+/* ICU862 Boards by Cambridge Broadband Ltd.					*/
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_ICU862)
+
+#define PCMCIA_BOARD_MSG "ICU862"
+
+static void cfg_port_B (void);
+
+static int hardware_enable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	volatile sysconf8xx_t	*sysp;
+	uint reg, pipr, mask;
+	int i;
+
+	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	udelay(10000);
+
+	immap = (immap_t *)CFG_IMMR;
+	sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
+	cfg_port_B ();
+
+	/*
+	 * Configure SIUMCR to enable PCMCIA port B
+	 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+	 */
+	sysp->sc_siumcr &= ~SIUMCR_DBGC11;	/* set DBGC to 00 */
+
+	/* clear interrupt state, and disable interrupts */
+	pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
+	pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+	/* disable interrupts & DMA */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Make sure there is a card in the slot, then configure the interface.
+	 */
+	udelay(10000);
+	debug ("[%d] %s: PIPR(%p)=0x%x\n",
+		__LINE__,__FUNCTION__,
+		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+	if (pcmp->pcmc_pipr & 0x00001800) {
+		printf ("   No Card found\n");
+		return (1);
+	}
+
+	/*
+	 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
+	 */
+	mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+	pipr = pcmp->pcmc_pipr;
+	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+		pipr,
+		(reg&PCMCIA_VS1(slot))?"n":"ff",
+		(reg&PCMCIA_VS2(slot))?"n":"ff");
+
+	reg  = cp->cp_pbdat;
+	if ((pipr & mask) == mask) {
+		reg |=  (TPS2205_VPP_PGM | TPS2205_VPP_VCC |	/* VAVPP => Hi-Z */
+			 TPS2205_VCC3);				/* 3V off	*/
+		reg &= ~(TPS2205_VCC5);				/* 5V on	*/
+		puts (" 5.0V card found: ");
+	} else {
+		reg |=  (TPS2205_VPP_PGM | TPS2205_VPP_VCC |	/* VAVPP => Hi-Z */
+			 TPS2205_VCC5);				/* 5V off	*/
+		reg &= ~(TPS2205_VCC3);				/* 3V on	*/
+		puts (" 3.3V card found: ");
+	}
+
+	debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
+		reg,
+		(reg & TPS2205_VCC3)    ? "off" : "on",
+		(reg & TPS2205_VCC5)    ? "off" : "on",
+		(reg & TPS2205_VPP_PGM) ? "off" : "on",
+		(reg & TPS2205_VPP_VCC) ? "off" : "on" );
+
+	cp->cp_pbdat = reg;
+
+	/*  Wait 500 ms; use this to check for over-current */
+	for (i=0; i<5000; ++i) {
+		if ((cp->cp_pbdat & TPS2205_OC) == 0) {
+			printf ("   *** Overcurrent - Safety shutdown ***\n");
+			cp->cp_pbdat &= ~(TPS2205_SHDN);
+			return (1);
+		}
+		udelay (100);
+	}
+
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(250000);	/* some cards need >150 ms to come up :-( */
+
+	debug ("# hardware_enable done\n");
+
+	return (0);
+}
+
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	immap = (immap_t *)CFG_IMMR;
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+	/* Shut down */
+	cp->cp_pbdat &= ~(TPS2205_SHDN);
+
+	/* Configure PCMCIA General Control Register */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(10000);
+
+	return (0);
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("voltage_set: "
+		PCMCIA_BOARD_MSG
+		" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+		'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+	immap = (immap_t *)CFG_IMMR;
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Configure Port C pins for
+	 * 5 Volts Enable and 3 Volts enable,
+	 * Turn all power pins to Hi-Z
+	 */
+	debug ("PCMCIA power OFF\n");
+	cfg_port_B ();	/* Enables switch, but all in Hi-Z */
+
+	reg  = cp->cp_pbdat;
+
+	switch(vcc) {
+	case  0: 			break;	/* Switch off		*/
+	case 33: reg &= ~TPS2205_VCC3;	break;	/* Switch on 3.3V	*/
+	case 50: reg &= ~TPS2205_VCC5;	break;	/* Switch on 5.0V	*/
+	default: 			goto done;
+	}
+
+	/* Checking supported voltages */
+
+	debug ("PIPR: 0x%x --> %s\n",
+		pcmp->pcmc_pipr,
+		(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+	cp->cp_pbdat = reg;
+
+#ifdef DEBUG
+    {
+	char *s;
+
+	if ((reg & TPS2205_VCC3) == 0) {
+		s = "at 3.3V";
+	} else if ((reg & TPS2205_VCC5) == 0) {
+		s = "at 5.0V";
+	} else {
+		s = "down";
+	}
+	printf ("PCMCIA powered %s\n", s);
+    }
+#endif
+
+done:
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
+		slot+'A');
+	return (0);
+}
+
+static void cfg_port_B (void)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	uint reg;
+
+	immap = (immap_t *)CFG_IMMR;
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/*
+	 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
+	 *
+	 * Switch off all voltages, assert shutdown
+	 */
+	reg  = cp->cp_pbdat;
+	reg |=  (TPS2205_VPP_PGM | TPS2205_VPP_VCC |	/* VAVPP => Hi-Z */
+		 TPS2205_VCC3    | TPS2205_VCC5    |	/* VAVCC => Hi-Z */
+		 TPS2205_SHDN);				/* enable switch */
+	cp->cp_pbdat = reg;
+
+	cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
+
+	reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
+	cp->cp_pbdir = reg | TPS2205_OUTPUTS;
+
+	debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
+		cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
+}
+
+#endif	/* ICU862 */
+
+
+/* ---------------------------------------------------------------------------- */
+/* C2MON Boards by TTTech Computertechnik AG					*/
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_C2MON)
+
+#define PCMCIA_BOARD_MSG "C2MON"
+
+static void cfg_ports (void);
+
+static int hardware_enable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	volatile sysconf8xx_t	*sysp;
+	uint reg, pipr, mask;
+	ushort sreg;
+	int i;
+
+	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	udelay(10000);
+
+	immap = (immap_t *)CFG_IMMR;
+	sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
+	cfg_ports ();
+
+	/*
+	 * Configure SIUMCR to enable PCMCIA port B
+	 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+	 */
+	sysp->sc_siumcr &= ~SIUMCR_DBGC11;	/* set DBGC to 00 */
+
+	/* clear interrupt state, and disable interrupts */
+	pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
+	pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+	/* disable interrupts & DMA */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Make sure there is a card in the slot, then configure the interface.
+	 */
+	udelay(10000);
+	debug ("[%d] %s: PIPR(%p)=0x%x\n",
+		__LINE__,__FUNCTION__,
+		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+	if (pcmp->pcmc_pipr & 0x00001800) {
+		printf ("   No Card found\n");
+		return (1);
+	}
+
+	/*
+	 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
+	 */
+	mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+	pipr = pcmp->pcmc_pipr;
+	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+		pipr,
+		(reg&PCMCIA_VS1(slot))?"n":"ff",
+		(reg&PCMCIA_VS2(slot))?"n":"ff");
+
+	sreg = immap->im_ioport.iop_pcdat;
+	if ((pipr & mask) == mask) {
+		sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |	/* VAVPP => Hi-Z */
+			  TPS2211_VCCD1);			/* 5V on	*/
+		sreg &= ~(TPS2211_VCCD0);			/* 3V off	*/
+		puts (" 5.0V card found: ");
+	} else {
+		sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |	/* VAVPP => Hi-Z */
+			  TPS2211_VCCD0);			/* 3V on	*/
+		sreg &= ~(TPS2211_VCCD1);			/* 5V off	*/
+		puts (" 3.3V card found: ");
+	}
+
+	debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
+		sreg,
+		( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
+		(!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) ? "on" : "off"
+	);
+
+	immap->im_ioport.iop_pcdat = sreg;
+
+	/*  Wait 500 ms; use this to check for over-current */
+	for (i=0; i<5000; ++i) {
+		if ((cp->cp_pbdat & TPS2211_OC) == 0) {
+		    printf ("   *** Overcurrent - Safety shutdown ***\n");
+		    immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
+		    return (1);
+		}
+		udelay (100);
+	}
+
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(250000);	/* some cards need >150 ms to come up :-( */
+
+	debug ("# hardware_enable done\n");
+
+	return (0);
+}
+
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+	/* Configure PCMCIA General Control Register */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	/* ALl voltages off / Hi-Z */
+	immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
+				       TPS2211_VCCD0 | TPS2211_VCCD1 );
+
+	udelay(10000);
+
+	return (0);
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+	ushort sreg;
+
+	debug ("voltage_set: "
+		PCMCIA_BOARD_MSG
+		" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+		'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+	immap = (immap_t *)CFG_IMMR;
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Configure Port C pins for
+	 * 5 Volts Enable and 3 Volts enable,
+	 * Turn all power pins to Hi-Z
+	 */
+	debug ("PCMCIA power OFF\n");
+	cfg_ports ();	/* Enables switch, but all in Hi-Z */
+
+	sreg  = immap->im_ioport.iop_pcdat;
+	sreg |= TPS2211_VPPD0 | TPS2211_VPPD1;		/* VAVPP always Hi-Z */
+
+	switch(vcc) {
+	case  0: 			break;	/* Switch off		*/
+	case 33: sreg |=  TPS2211_VCCD0;	/* Switch on 3.3V	*/
+		 sreg &= ~TPS2211_VCCD1;
+		 			break;
+	case 50: sreg &= ~TPS2211_VCCD0;	/* Switch on 5.0V	*/
+		 sreg |=  TPS2211_VCCD1;
+		 			break;
+	default: 			goto done;
+	}
+
+	/* Checking supported voltages */
+
+	debug ("PIPR: 0x%x --> %s\n",
+		pcmp->pcmc_pipr,
+		(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+	immap->im_ioport.iop_pcdat = sreg;
+
+#ifdef DEBUG
+    {
+	char *s;
+
+	if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
+		s = "at 3.3V";
+	} else if (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) {
+		s = "at 5.0V";
+	} else {
+		s = "down";
+	}
+	printf ("PCMCIA powered %s\n", s);
+    }
+#endif
+
+done:
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
+		slot+'A');
+	return (0);
+}
+
+static void cfg_ports (void)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	ushort sreg;
+
+	immap = (immap_t *)CFG_IMMR;
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/*
+	 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
+	 *
+	 * Switch off all voltages, assert shutdown
+	 */
+	sreg = immap->im_ioport.iop_pcdat;
+	sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1);	/* VAVPP => Hi-Z */
+	sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1);	/* 3V and 5V off */
+	immap->im_ioport.iop_pcdat = sreg;
+
+	immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
+	immap->im_ioport.iop_pcdir |=   TPS2211_OUTPUTS;
+
+	debug ("Set Port C: PAR:     %04x DIR:     %04x DAT:     %04x\n",
+		immap->im_ioport.iop_pcpar,
+		immap->im_ioport.iop_pcdir,
+		immap->im_ioport.iop_pcdat);
+
+	/*
+	 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
+	 *
+	 * Over-Current Input only
+	 */
+	cp->cp_pbpar &= ~(TPS2211_INPUTS);
+	cp->cp_pbdir &= ~(TPS2211_INPUTS);
+
+	debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
+		cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
+}
+
+#endif	/* C2MON */
+
+/* ----------------------------------------------------------------------------
+   MBX board from Morotola
+   ---------------------------------------------------------------------------- */
+
+#if defined( CONFIG_MBX )
+#include <../board/mbx8xx/csr.h>
+
+/* A lot of this has been taken from the RPX code in this file it works from me.
+   I have added the voltage selection for the MBX board. */
+
+/* MBX voltage bit in control register #2 */
+#define CR2_VPP12       ((uchar)0x10)
+#define CR2_VPPVDD      ((uchar)0x20)
+#define CR2_VDD5        ((uchar)0x40)
+#define CR2_VDD3        ((uchar)0x80)
+
+#define PCMCIA_BOARD_MSG "MBX860"
+
+static int voltage_set (int slot, int vcc, int vpp)
+{
+	uchar reg = 0;
+
+	debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+		 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
+
+	switch (vcc) {
+	case 0:
+		break;
+	case 33:
+		reg |= CR2_VDD3;
+		break;
+	case 50:
+		reg |= CR2_VDD5;
+		break;
+	default:
+		return 1;
+	}
+
+	switch (vpp) {
+	case 0:
+		break;
+	case 33:
+	case 50:
+		if (vcc == vpp) {
+			reg |= CR2_VPPVDD;
+		} else {
+			return 1;
+		}
+		break;
+	case 120:
+		reg |= CR2_VPP12;
+		break;
+	default:
+		return 1;
+	}
+
+	/* first, turn off all power */
+	MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
+
+	/* enable new powersettings */
+	MBX_CSR2 |= reg;
+	debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
+
+	return (0);
+}
+
+static int hardware_enable (int slot)
+{
+	volatile immap_t *immap;
+	volatile cpm8xx_t *cp;
+	volatile pcmconf8xx_t *pcmp;
+	volatile sysconf8xx_t *sysp;
+	uint reg, mask;
+
+	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
+				  'A' + slot);
+
+	udelay (10000);
+
+	immap = (immap_t *) CFG_IMMR;
+	sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
+	pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
+	cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
+
+	/* clear interrupt state, and disable interrupts */
+	pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
+	pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
+
+	/* disable interrupts & DMA */
+	PCMCIA_PGCRX (_slot_) = 0;
+
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg = PCMCIA_PGCRX (_slot_);
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;	/* active low  */
+	PCMCIA_PGCRX (_slot_) = reg;
+	udelay (500);
+
+	/* remove all power */
+	voltage_set (slot, 0, 0);
+	/*
+	 * Make sure there is a card in the slot, then configure the interface.
+	 */
+	udelay (10000);
+	debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__, __FUNCTION__,
+		  &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
+
+	if (pcmp->pcmc_pipr & 0x00001800) {
+		printf ("   No Card found\n");
+		return (1);
+	}
+
+	/*
+	 * Power On.
+	 */
+	mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
+	reg = pcmp->pcmc_pipr;
+	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
+		  (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
+		  (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
+
+	if ((reg & mask) == mask) {
+		voltage_set (_slot_, 50, 0);
+		printf (" 5.0V card found: ");
+	} else {
+		voltage_set (_slot_, 33, 0);
+		printf (" 3.3V card found: ");
+	}
+
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg = PCMCIA_PGCRX (_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;	/* active low  */
+	PCMCIA_PGCRX (_slot_) = reg;
+
+	udelay (250000);	/* some cards need >150 ms to come up :-( */
+
+	debug ("# hardware_enable done\n");
+
+	return (0);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable (int slot)
+{
+	return 0;	/* No hardware to disable */
+}
+#endif /* CFG_CMD_PCMCIA */
+#endif /* CONFIG_MBX */
+/* ---------------------------------------------------------------------------- */
+/* R360MPI Board								*/
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_R360MPI)
+
+#define PCMCIA_BOARD_MSG "R360MPI"
+
+
+static int hardware_enable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	volatile sysconf8xx_t	*sysp;
+	uint reg, mask;
+
+	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	udelay(10000);
+
+	immap = (immap_t *)CFG_IMMR;
+	sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/*
+	 * Configure SIUMCR to enable PCMCIA port B
+	 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+	 */
+	sysp->sc_siumcr &= ~SIUMCR_DBGC11;	/* set DBGC to 00 */
+
+	/* clear interrupt state, and disable interrupts */
+	pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
+	pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+	/* disable interrupts & DMA */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Configure Ports A, B & C pins for
+	 * 5 Volts Enable and 3 Volts enable
+	 */
+	immap->im_ioport.iop_pcpar &= ~(0x0400);
+	immap->im_ioport.iop_pcso  &= ~(0x0400);/*
+	immap->im_ioport.iop_pcdir |= 0x0400;*/
+
+	immap->im_ioport.iop_papar &= ~(0x0200);/*
+	immap->im_ioport.iop_padir |= 0x0200;*/
+#if 0
+	immap->im_ioport.iop_pbpar &= ~(0xC000);
+	immap->im_ioport.iop_pbdir &= ~(0xC000);
+#endif
+	/* remove all power */
+
+	immap->im_ioport.iop_pcdat |= 0x0400;
+	immap->im_ioport.iop_padat |= 0x0200;
+
+	/*
+	 * Make sure there is a card in the slot, then configure the interface.
+	 */
+	udelay(10000);
+	debug ("[%d] %s: PIPR(%p)=0x%x\n",
+		__LINE__,__FUNCTION__,
+		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+	if (pcmp->pcmc_pipr & 0x00001800) {
+		printf ("   No Card found\n");
+		return (1);
+	}
+
+	/*
+	 * Power On.
+	 */
+	mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+	reg  = pcmp->pcmc_pipr;
+	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+		reg,
+		(reg&PCMCIA_VS1(slot))?"n":"ff",
+		(reg&PCMCIA_VS2(slot))?"n":"ff");
+	if ((reg & mask) == mask) {
+		immap->im_ioport.iop_pcdat &= ~(0x4000);
+		puts (" 5.0V card found: ");
+	} else {
+		immap->im_ioport.iop_padat &= ~(0x0002);
+		puts (" 3.3V card found: ");
+	}
+	immap->im_ioport.iop_pcdir |= 0x0400;
+	immap->im_ioport.iop_padir |= 0x0200;
+#if 0
+	/*  VCC switch error flag, PCMCIA slot INPACK_ pin */
+	cp->cp_pbdir &= ~(0x0020 | 0x0010);
+	cp->cp_pbpar &= ~(0x0020 | 0x0010);
+	udelay(500000);
+#endif
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(250000);	/* some cards need >150 ms to come up :-( */
+
+	debug ("# hardware_enable done\n");
+
+	return (0);
+}
+
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+	/* remove all power */
+	immap->im_ioport.iop_pcdat |= 0x0400;
+	immap->im_ioport.iop_padat |= 0x0200;
+
+	/* Configure PCMCIA General Control Register */
+	PCMCIA_PGCRX(_slot_) = 0;
+
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(10000);
+
+	return (0);
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	volatile immap_t	*immap;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("voltage_set: "
+		PCMCIA_BOARD_MSG
+		" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+		'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Configure Ports A & C pins for
+	 * 5 Volts Enable and 3 Volts enable,
+	 * Turn off all power
+	 */
+	debug ("PCMCIA power OFF\n");
+	immap->im_ioport.iop_pcpar &= ~(0x0400);
+	immap->im_ioport.iop_pcso  &= ~(0x0400);/*
+	immap->im_ioport.iop_pcdir |= 0x0400;*/
+
+	immap->im_ioport.iop_papar &= ~(0x0200);/*
+	immap->im_ioport.iop_padir |= 0x0200;*/
+
+	immap->im_ioport.iop_pcdat |= 0x0400;
+	immap->im_ioport.iop_padat |= 0x0200;
+
+	reg = 0;
+	switch(vcc) {
+	case  0: 		break;
+	case 33: reg |= 0x0200;	break;
+	case 50: reg |= 0x0400;	break;
+	default: 		goto done;
+	}
+
+	/* Checking supported voltages */
+
+	debug ("PIPR: 0x%x --> %s\n",
+		pcmp->pcmc_pipr,
+		(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+	if (reg & 0x0200)
+		immap->im_ioport.iop_pcdat &= !reg;
+	if (reg & 0x0400)
+		immap->im_ioport.iop_padat &= !reg;
+	immap->im_ioport.iop_pcdir |=  0x0200;
+	immap->im_ioport.iop_padir |=  0x0400;
+	if (reg) {
+		debug ("PCMCIA powered at %sV\n",
+			(reg&0x0400) ? "5.0" : "3.3");
+	} else {
+		debug ("PCMCIA powered down\n");
+	}
+
+done:
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
+		slot+'A');
+	return (0);
+}
+
+#endif	/* R360MPI */
+
+
+/* ---------------------------------------------------------------------------- */
+/* End of Board Specific Stuff							*/
+/* ---------------------------------------------------------------------------- */
+
+
+/* ---------------------------------------------------------------------------- */
+/* MPC8xx Specific Stuff - should go to MPC8xx directory			*/
+/* ---------------------------------------------------------------------------- */
+
+/*
+ * Search this table to see if the windowsize is
+ * supported...
+ */
+
+#define M8XX_SIZES_NO 32
+
+static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
+{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
+  0x00000080, 0x00000040, 0x00000010, 0x00000020,
+  0x00008000, 0x00004000, 0x00001000, 0x00002000,
+  0x00000100, 0x00000200, 0x00000800, 0x00000400,
+
+  0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x01000000, 0x02000000, 0xffffffff, 0x04000000,
+  0x00010000, 0x00020000, 0x00080000, 0x00040000,
+  0x00800000, 0x00400000, 0x00100000, 0x00200000 };
+
+
+/* ---------------------------------------------------------------------------- */
+
+static u_int m8xx_get_graycode(u_int size)
+{
+	u_int k;
+
+	for (k = 0; k < M8XX_SIZES_NO; k++) {
+		if(m8xx_size_to_gray[k] == size)
+			break;
+	}
+
+	if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+		k = -1;
+
+	return k;
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+static u_int m8xx_get_speed(u_int ns, u_int is_io)
+{
+	u_int reg, clocks, psst, psl, psht;
+
+	if(!ns) {
+
+		/*
+		 * We get called with IO maps setup to 0ns
+		 * if not specified by the user.
+		 * They should be 255ns.
+		 */
+
+		if(is_io)
+			ns = 255;
+		else
+			ns = 100;  /* fast memory if 0 */
+	}
+
+	/*
+	 * In PSST, PSL, PSHT fields we tell the controller
+	 * timing parameters in CLKOUT clock cycles.
+	 * CLKOUT is the same as GCLK2_50.
+	 */
+
+/* how we want to adjust the timing - in percent */
+
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
+
+	clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+	clocks = (clocks * ADJ) / (100*1000);
+
+	if(clocks >= PCMCIA_BMT_LIMIT) {
+		DEBUG(0, "Max access time limit reached\n");
+		clocks = PCMCIA_BMT_LIMIT-1;
+	}
+
+	psst = clocks / 7;          /* setup time */
+	psht = clocks / 7;          /* hold time */
+	psl  = (clocks * 5) / 7;    /* strobe length */
+
+	psst += clocks - (psst + psht + psl);
+
+	reg =  psst << 12;
+	reg |= psl  << 7;
+	reg |= psht << 16;
+
+	return reg;
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+static void print_funcid (int func)
+{
+	puts (indent);
+	switch (func) {
+	case CISTPL_FUNCID_MULTI:
+		puts (" Multi-Function");
+		break;
+	case CISTPL_FUNCID_MEMORY:
+		puts (" Memory");
+		break;
+	case CISTPL_FUNCID_SERIAL:
+		puts (" Serial Port");
+		break;
+	case CISTPL_FUNCID_PARALLEL:
+		puts (" Parallel Port");
+		break;
+	case CISTPL_FUNCID_FIXED:
+		puts (" Fixed Disk");
+		break;
+	case CISTPL_FUNCID_VIDEO:
+		puts (" Video Adapter");
+		break;
+	case CISTPL_FUNCID_NETWORK:
+		puts (" Network Adapter");
+		break;
+	case CISTPL_FUNCID_AIMS:
+		puts (" AIMS Card");
+		break;
+	case CISTPL_FUNCID_SCSI:
+		puts (" SCSI Adapter");
+		break;
+	default:
+		puts (" Unknown");
+		break;
+	}
+	puts (" Card\n");
+}
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+static void print_fixed (volatile uchar *p)
+{
+	if (p == NULL)
+		return;
+
+	puts(indent);
+
+	switch (*p) {
+	case CISTPL_FUNCE_IDE_IFACE:
+	    {   uchar iface = *(p+2);
+
+		puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
+		puts (" interface ");
+		break;
+	    }
+	case CISTPL_FUNCE_IDE_MASTER:
+	case CISTPL_FUNCE_IDE_SLAVE:
+	    {   uchar f1 = *(p+2);
+		uchar f2 = *(p+4);
+
+		puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
+
+		if (f1 & CISTPL_IDE_UNIQUE)
+			puts (" [unique]");
+
+		puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
+
+		if (f2 & CISTPL_IDE_HAS_SLEEP)
+			puts (" [sleep]");
+
+		if (f2 & CISTPL_IDE_HAS_STANDBY)
+			puts (" [standby]");
+
+		if (f2 & CISTPL_IDE_HAS_IDLE)
+			puts (" [idle]");
+
+		if (f2 & CISTPL_IDE_LOW_POWER)
+			puts (" [low power]");
+
+		if (f2 & CISTPL_IDE_REG_INHIBIT)
+			puts (" [reg inhibit]");
+
+		if (f2 & CISTPL_IDE_HAS_INDEX)
+			puts (" [index]");
+
+		if (f2 & CISTPL_IDE_IOIS16)
+			puts (" [IOis16]");
+
+		break;
+	    }
+	}
+	putc ('\n');
+}
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+
+#define MAX_IDENT_CHARS		64
+#define	MAX_IDENT_FIELDS	4
+
+static uchar *known_cards[] = {
+	"ARGOSY PnPIDE D5",
+	NULL
+};
+
+static int identify  (volatile uchar *p)
+{
+	uchar id_str[MAX_IDENT_CHARS];
+	uchar data;
+	uchar *t;
+	uchar **card;
+	int i, done;
+
+	if (p == NULL)
+		return (0);	/* Don't know */
+
+	t = id_str;
+	done =0;
+
+	for (i=0; i<=4 && !done; ++i, p+=2) {
+		while ((data = *p) != '\0') {
+			if (data == 0xFF) {
+				done = 1;
+				break;
+			}
+			*t++ = data;
+			if (t == &id_str[MAX_IDENT_CHARS-1]) {
+				done = 1;
+				break;
+			}
+			p += 2;
+		}
+		if (!done)
+			*t++ = ' ';
+	}
+	*t = '\0';
+	while (--t > id_str) {
+		if (*t == ' ')
+			*t = '\0';
+		else
+			break;
+	}
+	puts (id_str);
+	putc ('\n');
+
+	for (card=known_cards; *card; ++card) {
+		debug ("## Compare against \"%s\"\n", *card);
+		if (strcmp(*card, id_str) == 0) {	/* found! */
+			debug ("## CARD FOUND ##\n");
+			return (1);
+		}
+	}
+
+	return (0);	/* don't know */
+}
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
diff --git a/common/env_flash.c b/common/env_flash.c
new file mode 100644
index 0000000..1593d2c
--- /dev/null
+++ b/common/env_flash.c
@@ -0,0 +1,377 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+
+#if defined(CFG_ENV_IS_IN_FLASH) /* Environment is in Flash */
+
+#include <command.h>
+#include <environment.h>
+#include <cmd_nvedit.h>
+#include <linux/stddef.h>
+
+#if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH))
+#define CMD_SAVEENV
+#elif defined(CFG_ENV_ADDR_REDUND)
+#error Cannot use CFG_ENV_ADDR_REDUND without CFG_CMD_ENV & CFG_CMD_FLASH
+#endif
+
+#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE) && \
+    defined(CFG_ENV_ADDR_REDUND)
+#error CFG_ENV_ADDR_REDUND should not be used when CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
+#endif
+
+#if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND < CFG_ENV_SIZE)
+#error CFG_ENV_SIZE_REDUND should not be less then CFG_ENV_SIZE
+#endif
+
+#ifdef CONFIG_INFERNO
+# ifdef CFG_ENV_ADDR_REDUND
+#error CFG_ENV_ADDR_REDUND is not implemented for CONFIG_INFERNO
+# endif
+#endif
+
+char * env_name_spec = "Flash";
+
+#ifdef ENV_IS_EMBEDDED
+
+extern uchar environment[];
+env_t *env_ptr = (env_t *)(&environment[0]);
+
+#ifdef CMD_SAVEENV
+/* static env_t *flash_addr = (env_t *)(&environment[0]);-broken on ARM-wd-*/
+static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
+#endif
+
+#else /* ! ENV_IS_EMBEDDED */
+
+env_t *env_ptr = (env_t *)CFG_ENV_ADDR;
+#ifdef CMD_SAVEENV
+static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
+#endif
+
+#endif /* ENV_IS_EMBEDDED */
+
+#ifdef CFG_ENV_ADDR_REDUND
+static env_t *flash_addr_new = (env_t *)CFG_ENV_ADDR_REDUND;
+
+static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SIZE - 1;
+static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1;
+
+static uchar active_flag = 1;
+static uchar obsolete_flag = 0;
+#endif
+
+extern uchar default_environment[];
+extern int default_environment_size;
+
+
+uchar env_get_char_spec (int index)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	return ( *((uchar *)(gd->env_addr + index)) );
+}
+
+#ifdef CFG_ENV_ADDR_REDUND
+
+int  env_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int crc1_ok =
+		(crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc);
+	int crc2_ok =
+		(crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc);
+
+	uchar flag1 = flash_addr->flags;
+	uchar flag2 = flash_addr_new->flags;
+
+	ulong addr_default = (ulong)&default_environment[0];
+	ulong addr1 = (ulong)&(flash_addr->data);
+	ulong addr2 = (ulong)&(flash_addr_new->data);
+
+	if (crc1_ok && ! crc2_ok)
+	{
+		gd->env_addr  = addr1;
+		gd->env_valid = 1;
+	}
+	else if (! crc1_ok && crc2_ok)
+	{
+		gd->env_addr  = addr2;
+		gd->env_valid = 1;
+	}
+	else if (! crc1_ok && ! crc2_ok)
+	{
+		gd->env_addr  = addr_default;
+		gd->env_valid = 0;
+	}
+	else if (flag1 == active_flag && flag2 == obsolete_flag)
+	{
+		gd->env_addr  = addr1;
+		gd->env_valid = 1;
+	}
+	else if (flag1 == obsolete_flag && flag2 == active_flag)
+	{
+		gd->env_addr  = addr2;
+		gd->env_valid = 1;
+	}
+	else if (flag1 == flag2)
+	{
+		gd->env_addr  = addr1;
+		gd->env_valid = 2;
+	}
+	else if (flag1 == 0xFF)
+	{
+		gd->env_addr  = addr1;
+		gd->env_valid = 2;
+	}
+	else if (flag2 == 0xFF)
+	{
+		gd->env_addr  = addr2;
+		gd->env_valid = 2;
+	}
+
+	return (0);
+}
+
+#ifdef CMD_SAVEENV
+int saveenv(void)
+{
+	int rc = 1;
+
+	debug ("Protect off %08lX ... %08lX\n",
+		(ulong)flash_addr, end_addr);
+
+	if (flash_sect_protect (0, (ulong)flash_addr, end_addr)) {
+		goto Done;
+	}
+
+	debug ("Protect off %08lX ... %08lX\n",
+		(ulong)flash_addr_new, end_addr_new);
+
+	if (flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new)) {
+		goto Done;
+	}
+
+	puts ("Erasing Flash...");
+	debug (" %08lX ... %08lX ...",
+		(ulong)flash_addr_new, end_addr_new);
+
+	if (flash_sect_erase ((ulong)flash_addr_new, end_addr_new)) {
+		goto Done;
+	}
+
+	puts ("Writing to Flash... ");
+	debug (" %08lX ... %08lX ...",
+		(ulong)&(flash_addr_new->data),
+		sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data));
+	if (flash_write(env_ptr->data,
+	                (ulong)&(flash_addr_new->data),
+			sizeof(env_ptr->data)) ||
+
+	    flash_write((char *)&(env_ptr->crc),
+	                (ulong)&(flash_addr_new->crc),
+			sizeof(env_ptr->crc)) ||
+
+	    flash_write((char *)&obsolete_flag,
+	                (ulong)&(flash_addr->flags),
+			sizeof(flash_addr->flags)) ||
+
+	    flash_write((char *)&active_flag,
+	                (ulong)&(flash_addr_new->flags),
+			sizeof(flash_addr_new->flags)))
+	{
+		flash_perror (rc);
+		goto Done;
+	}
+	puts ("done\n");
+
+	{
+		env_t * etmp = flash_addr;
+		ulong ltmp = end_addr;
+
+		flash_addr = flash_addr_new;
+		flash_addr_new = etmp;
+
+		end_addr = end_addr_new;
+		end_addr_new = ltmp;
+	}
+
+	rc = 0;
+Done:
+
+	/* try to re-protect */
+	(void) flash_sect_protect (1, (ulong)flash_addr, end_addr);
+	(void) flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
+
+	return rc;
+}
+#endif /* CMD_SAVEENV */
+
+#else /* ! CFG_ENV_ADDR_REDUND */
+
+int  env_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
+		gd->env_addr  = (ulong)&(env_ptr->data);
+		gd->env_valid = 1;
+	} else {
+		gd->env_addr  = (ulong)&default_environment[0];
+		gd->env_valid = 0;
+	}
+
+	return (0);
+}
+
+#ifdef CMD_SAVEENV
+
+int saveenv(void)
+{
+	int	len, rc;
+	ulong	end_addr;
+	ulong	flash_sect_addr;
+#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
+	ulong	flash_offset;
+	uchar	env_buffer[CFG_ENV_SECT_SIZE];
+#else
+	uchar *env_buffer = (char *)env_ptr;
+#endif	/* CFG_ENV_SECT_SIZE */
+	int rcode = 0;
+
+#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
+
+	flash_offset    = ((ulong)flash_addr) & (CFG_ENV_SECT_SIZE-1);
+	flash_sect_addr = ((ulong)flash_addr) & ~(CFG_ENV_SECT_SIZE-1);
+
+	debug ( "copy old content: "
+		"sect_addr: %08lX  env_addr: %08lX  offset: %08lX\n",
+		flash_sect_addr, (ulong)flash_addr, flash_offset);
+
+	/* copy old contents to temporary buffer */
+	memcpy (env_buffer, (void *)flash_sect_addr, CFG_ENV_SECT_SIZE);
+
+	/* copy current environment to temporary buffer */
+	memcpy ((uchar *)((unsigned long)env_buffer + flash_offset),
+		env_ptr,
+		CFG_ENV_SIZE);
+
+	len	 = CFG_ENV_SECT_SIZE;
+#else
+	flash_sect_addr = (ulong)flash_addr;
+	len	 = CFG_ENV_SIZE;
+#endif	/* CFG_ENV_SECT_SIZE */
+
+#ifndef CONFIG_INFERNO
+	end_addr = flash_sect_addr + len - 1;
+#else
+	/* this is the last sector, and the size is hardcoded here */
+	/* otherwise we will get stack problems on loading 128 KB environment */
+	end_addr = flash_sect_addr + 0x20000 - 1;
+#endif
+
+	debug ("Protect off %08lX ... %08lX\n",
+		(ulong)flash_sect_addr, end_addr);
+
+	if (flash_sect_protect (0, flash_sect_addr, end_addr))
+		return 1;
+
+	puts ("Erasing Flash...");
+	if (flash_sect_erase (flash_sect_addr, end_addr))
+		return 1;
+
+	puts ("Writing to Flash... ");
+	rc = flash_write(env_buffer, flash_sect_addr, len);
+	if (rc != 0) {
+		flash_perror (rc);
+		rcode = 1;
+	} else {
+		puts ("done\n");
+	}
+
+	/* try to re-protect */
+	(void) flash_sect_protect (1, flash_sect_addr, end_addr);
+	return rcode;
+}
+
+#endif /* CMD_SAVEENV */
+
+#endif /* CFG_ENV_ADDR_REDUND */
+
+void env_relocate_spec (void)
+{
+#if !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND)
+#ifdef CFG_ENV_ADDR_REDUND
+	DECLARE_GLOBAL_DATA_PTR;
+
+	if (gd->env_addr != (ulong)&(flash_addr->data))
+	{
+		env_t * etmp = flash_addr;
+		ulong ltmp = end_addr;
+
+		flash_addr = flash_addr_new;
+		flash_addr_new = etmp;
+
+		end_addr = end_addr_new;
+		end_addr_new = ltmp;
+	}
+
+	if (flash_addr_new->flags != obsolete_flag &&
+	    crc32(0, flash_addr_new->data, ENV_SIZE) ==
+	    flash_addr_new->crc)
+	{
+		gd->env_valid = 2;
+		flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new);
+		flash_write((char *)&obsolete_flag,
+                    	    (ulong)&(flash_addr_new->flags),
+	        	    sizeof(flash_addr_new->flags));
+		flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
+	}
+
+	if (flash_addr->flags != active_flag &&
+	    (flash_addr->flags & active_flag) == active_flag)
+	{
+		gd->env_valid = 2;
+		flash_sect_protect (0, (ulong)flash_addr, end_addr);
+		flash_write((char *)&active_flag,
+                    	    (ulong)&(flash_addr->flags),
+	        	    sizeof(flash_addr->flags));
+		flash_sect_protect (1, (ulong)flash_addr, end_addr);
+	}
+
+	if (gd->env_valid == 2)
+		puts ("*** Warning - some problems detected "
+		      "reading environment; recovered successfully\n\n");
+#endif /* CFG_ENV_ADDR_REDUND */
+	memcpy (env_ptr, (void*)flash_addr, CFG_ENV_SIZE);
+#endif /* ! ENV_IS_EMBEDDED || CFG_ENV_ADDR_REDUND */
+}
+
+#endif /* CFG_ENV_IS_IN_FLASH) */
diff --git a/common/env_nvram.c b/common/env_nvram.c
new file mode 100644
index 0000000..fdfa4fc
--- /dev/null
+++ b/common/env_nvram.c
@@ -0,0 +1,138 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * 09-18-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
+ *
+ * It might not be possible in all cases to use 'memcpy()' to copy
+ * the environment to NVRAM, as the NVRAM might not be mapped into
+ * the memory space. (I.e. this is the case for the BAB750). In those
+ * cases it might be possible to access the NVRAM using a different
+ * method. For example, the RTC on the BAB750 is accessible in IO
+ * space using its address and data registers. To enable usage of
+ * NVRAM in those cases I invented the functions 'nvram_read()' and
+ * 'nvram_write()', which will be activated upon the configuration
+ * #define CFG_NVRAM_ACCESS_ROUTINE. Note, that those functions are
+ * strongly dependent on the used HW, and must be redefined for each
+ * board that wants to use them.
+ */
+
+#include <common.h>
+
+#ifdef CFG_ENV_IS_IN_NVRAM /* Environment is in NVRAM */
+
+#include <command.h>
+#include <environment.h>
+#include <cmd_nvedit.h>
+#include <linux/stddef.h>
+#include <malloc.h>
+
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+extern void *nvram_read(void *dest, const long src, size_t count);
+extern void nvram_write(long dest, const void *src, size_t count);
+env_t *env_ptr = NULL;
+#else
+env_t *env_ptr = (env_t *)CFG_ENV_ADDR;
+#endif
+
+char * env_name_spec = "NVRAM";
+
+extern uchar default_environment[];
+extern int default_environment_size;
+
+extern uchar (*env_get_char)(int);
+extern uchar env_get_char_memory (int index);
+
+
+uchar env_get_char_spec (int index)
+{
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+	uchar c;
+
+	nvram_read(&c, CFG_ENV_ADDR+index, 1);
+
+	return c;
+#else
+	DECLARE_GLOBAL_DATA_PTR;
+
+	return *((uchar *)(gd->env_addr + index));
+#endif
+}
+
+void env_relocate_spec (void)
+{
+#if defined(CFG_NVRAM_ACCESS_ROUTINE)
+	nvram_read(env_ptr, CFG_ENV_ADDR, CFG_ENV_SIZE);
+#else
+	memcpy (env_ptr, (void*)CFG_ENV_ADDR, CFG_ENV_SIZE);
+#endif
+}
+
+int saveenv (void)
+{
+	int rcode = 0;
+
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+	nvram_write(CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE);
+#else
+	if (memcpy ((char *)CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE) == NULL)
+		    rcode = 1 ;
+#endif
+	return rcode;
+}
+
+
+/************************************************************************
+ * Initialize Environment use
+ *
+ * We are still running from ROM, so data use is limited
+ */
+int env_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CFG_NVRAM_ACCESS_ROUTINE)
+	ulong crc;
+	uchar data[ENV_SIZE];
+	nvram_read (&crc, CFG_ENV_ADDR, sizeof(ulong));
+	nvram_read (data, CFG_ENV_ADDR+sizeof(ulong), ENV_SIZE);
+
+	if (crc32(0, data, ENV_SIZE) == crc) {
+		gd->env_addr  = (ulong)CFG_ENV_ADDR + sizeof(long);
+#else
+	if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
+		gd->env_addr  = (ulong)&(env_ptr->data);
+#endif
+		gd->env_valid = 1;
+	} else {
+		gd->env_addr  = (ulong)&default_environment[0];
+		gd->env_valid = 0;
+	}
+
+	return (0);
+}
+
+#endif /* CFG_ENV_IS_IN_NVRAM */
diff --git a/common/environment.c b/common/environment.c
new file mode 100644
index 0000000..74bfd62
--- /dev/null
+++ b/common/environment.c
@@ -0,0 +1,198 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.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
+ */
+
+#include <config.h>
+#include <environment.h>
+
+/*
+ * Handle HOSTS that have prepended
+ * crap on symbol names, not TARGETS.
+ */
+#if defined(__APPLE__)
+/* Leading underscore on symbols */
+#  define SYM_CHAR "_"
+#else /* No leading character on symbols */
+#  define SYM_CHAR
+#endif
+
+/*
+ * Generate embedded environment table
+ * inside U-Boot image, if needed.
+ */
+#if defined(ENV_IS_EMBEDDED)
+/*
+ * Only put the environment in it's own section when we are building
+ * U-Boot proper.  The host based program "tools/envcrc" does not need
+ * a seperate section.  Note that ENV_CRC is only defined when building
+ * U-Boot itself.
+ */
+#if (defined(CONFIG_FADS)	|| \
+     defined(CONFIG_HYMOD)	|| \
+     defined(CONFIG_ICU862)	|| \
+     defined(CONFIG_R360MPI)	|| \
+     defined(CONFIG_TQM8xxL)	|| \
+     defined(CONFIG_RRVISION)	|| \
+     defined(CONFIG_TRAB)   )	&& \
+     defined(ENV_CRC) /* Environment embedded in U-Boot .ppcenv section */
+/* XXX - This only works with GNU C */
+#  define __PPCENV__ __attribute__ ((section(".ppcenv")))
+#  define __PPCTEXT__ __attribute__ ((section(".text")))
+
+#elif defined(USE_HOSTCC) /* Native for 'tools/envcrc' */
+#  define __PPCENV__ /*XXX DO_NOT_DEL_THIS_COMMENT*/
+#  define __PPCTEXT__ /*XXX DO_NOT_DEL_THIS_COMMENT*/
+
+#else /* Environment is embedded in U-Boot's .text section */
+/* XXX - This only works with GNU C */
+#  define __PPCENV__ __attribute__ ((section(".text")))
+#  define __PPCTEXT__ __attribute__ ((section(".text")))
+#endif
+
+/*
+ * Macros to generate global absolutes.
+ */
+#define GEN_SYMNAME(str) SYM_CHAR #str
+#define GEN_VALUE(str) #str
+#define GEN_ABS(name, value) \
+		asm (".globl " GEN_SYMNAME(name)); \
+		asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
+
+/*
+ * Macros to transform values
+ * into environment strings.
+ */
+#define XMK_STR(x)	#x
+#define MK_STR(x)	XMK_STR(x)
+
+/*
+ * Check to see if we are building with a
+ * computed CRC.  Otherwise define it as ~0.
+ */
+#if !defined(ENV_CRC)
+#  define ENV_CRC	~0
+#endif
+
+env_t environment __PPCENV__ = {
+	ENV_CRC,	/* CRC Sum */
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+	1,		/* Flags: valid */
+#endif
+	{
+#if defined(CONFIG_BOOTARGS)
+	"bootargs="	CONFIG_BOOTARGS			"\0"
+#endif
+#if defined(CONFIG_BOOTCOMMAND)
+	"bootcmd="	CONFIG_BOOTCOMMAND		"\0"
+#endif
+#if defined(CONFIG_RAMBOOTCOMMAND)
+	"ramboot="	CONFIG_RAMBOOTCOMMAND		"\0"
+#endif
+#if defined(CONFIG_NFSBOOTCOMMAND)
+	"nfsboot="	CONFIG_NFSBOOTCOMMAND		"\0"
+#endif
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+	"bootdelay="	MK_STR(CONFIG_BOOTDELAY)	"\0"
+#endif
+#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
+	"baudrate="	MK_STR(CONFIG_BAUDRATE)		"\0"
+#endif
+#ifdef	CONFIG_LOADS_ECHO
+	"loads_echo="	MK_STR(CONFIG_LOADS_ECHO)	"\0"
+#endif
+#ifdef	CONFIG_ETHADDR
+	"ethaddr="	MK_STR(CONFIG_ETHADDR)		"\0"
+#endif
+#ifdef	CONFIG_ETH1ADDR
+	"eth1addr="	MK_STR(CONFIG_ETH1ADDR)		"\0"
+#endif
+#ifdef	CONFIG_ETH2ADDR
+	"eth2addr="	MK_STR(CONFIG_ETH2ADDR)		"\0"
+#endif
+#ifdef	CONFIG_ETHPRIME
+	"ethprime="	CONFIG_ETHPRIME			"\0"
+#endif
+#ifdef	CONFIG_IPADDR
+	"ipaddr="	MK_STR(CONFIG_IPADDR)		"\0"
+#endif
+#ifdef	CONFIG_SERVERIP
+	"serverip="	MK_STR(CONFIG_SERVERIP)		"\0"
+#endif
+#ifdef	CFG_AUTOLOAD
+	"autoload="	CFG_AUTOLOAD			"\0"
+#endif
+#ifdef	CONFIG_ROOTPATH
+	"rootpath="	MK_STR(CONFIG_ROOTPATH)		"\0"
+#endif
+#ifdef	CONFIG_GATEWAYIP
+	"gatewayip="	MK_STR(CONFIG_GATEWAYIP)	"\0"
+#endif
+#ifdef	CONFIG_NETMASK
+	"netmask="	MK_STR(CONFIG_NETMASK)		"\0"
+#endif
+#ifdef	CONFIG_HOSTNAME
+	"hostname="	MK_STR(CONFIG_HOSTNAME)		"\0"
+#endif
+#ifdef	CONFIG_BOOTFILE
+	"bootfile="	MK_STR(CONFIG_BOOTFILE)		"\0"
+#endif
+#ifdef	CONFIG_LOADADDR
+	"loadaddr="	MK_STR(CONFIG_LOADADDR)		"\0"
+#endif
+#ifdef	CONFIG_PREBOOT
+	"preboot="	CONFIG_PREBOOT			"\0"
+#endif
+#ifdef	CONFIG_CLOCKS_IN_MHZ
+	"clocks_in_mhz=" "1"				"\0"
+#endif
+#ifdef  CONFIG_EXTRA_ENV_SETTINGS
+	CONFIG_EXTRA_ENV_SETTINGS
+#endif
+	"\0"		/* Term. env_t.data with 2 NULLs */
+	}
+};
+#ifdef CFG_ENV_ADDR_REDUND
+env_t redundand_environment __PPCENV__ = {
+	0,		/* CRC Sum: invalid */
+	0,		/* Flags:   invalid */
+	{
+	"\0"
+	}
+};
+#endif	/* CFG_ENV_ADDR_REDUND */
+
+/*
+ * These will end up in the .text section
+ * if the environment strings are embedded
+ * in the image.  When this is used for
+ * tools/envcrc, they are placed in the
+ * .data/.sdata section.
+ *
+ */
+unsigned long env_size __PPCTEXT__ = sizeof(env_t);
+
+/*
+ * Add in absolutes.
+ */
+GEN_ABS(env_offset, CFG_ENV_OFFSET);
+
+#endif /* ENV_IS_EMBEDDED */
diff --git a/common/main.c b/common/main.c
new file mode 100644
index 0000000..014804b
--- /dev/null
+++ b/common/main.c
@@ -0,0 +1,817 @@
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <cmd_nvedit.h>
+#include <cmd_bootm.h>
+#include <malloc.h>
+#if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY)
+#include <cmd_boot.h>		/* for do_reset() prototype */
+#endif
+
+#ifdef CFG_HUSH_PARSER
+#include <hush.h>
+#endif
+
+#define MAX_DELAY_STOP_STR 32
+
+static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
+static int parse_line (char *, char *[]);
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+static int abortboot(int);
+#endif
+
+#undef DEBUG_PARSER
+
+char        console_buffer[CFG_CBSIZE];		/* console I/O buffer	*/
+
+static char erase_seq[] = "\b \b";		/* erase sequence	*/
+static char   tab_seq[] = "        ";		/* used to expand TABs	*/
+
+#ifdef CONFIG_BOOT_RETRY_TIME
+static uint64_t endtime = 0;  /* must be set, default is instant timeout */
+static int      retry_time = -1; /* -1 so can call readline before main_loop */
+#endif
+
+#define	endtick(seconds) (get_ticks() + (uint64_t)(seconds) * get_tbclk())
+
+#ifndef CONFIG_BOOT_RETRY_MIN
+#define CONFIG_BOOT_RETRY_MIN CONFIG_BOOT_RETRY_TIME
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+int do_mdm_init = 0;
+extern void mdm_init(void); /* defined in board.c */
+#endif
+
+/***************************************************************************
+ * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
+ * returns: 0 -  no key string, allow autoboot
+ *          1 - got key string, abort
+ */
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+# if defined(CONFIG_AUTOBOOT_KEYED)
+static __inline__ int abortboot(int bootdelay)
+{
+	int abort = 0;
+	uint64_t etime = endtick(bootdelay);
+	struct
+	{
+		char* str;
+		u_int len;
+		int retry;
+	}
+	delaykey [] =
+	{
+		{ str: getenv ("bootdelaykey"),  retry: 1 },
+		{ str: getenv ("bootdelaykey2"), retry: 1 },
+		{ str: getenv ("bootstopkey"),   retry: 0 },
+		{ str: getenv ("bootstopkey2"),  retry: 0 },
+	};
+
+	char presskey [MAX_DELAY_STOP_STR];
+	u_int presskey_len = 0;
+	u_int presskey_max = 0;
+	u_int i;
+
+#  ifdef CONFIG_AUTOBOOT_PROMPT
+	printf (CONFIG_AUTOBOOT_PROMPT, bootdelay);
+#  endif
+
+#  ifdef CONFIG_AUTOBOOT_DELAY_STR
+	if (delaykey[0].str == NULL)
+		delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;
+#  endif
+#  ifdef CONFIG_AUTOBOOT_DELAY_STR2
+	if (delaykey[1].str == NULL)
+		delaykey[1].str = CONFIG_AUTOBOOT_DELAY_STR2;
+#  endif
+#  ifdef CONFIG_AUTOBOOT_STOP_STR
+	if (delaykey[2].str == NULL)
+		delaykey[2].str = CONFIG_AUTOBOOT_STOP_STR;
+#  endif
+#  ifdef CONFIG_AUTOBOOT_STOP_STR2
+	if (delaykey[3].str == NULL)
+		delaykey[3].str = CONFIG_AUTOBOOT_STOP_STR2;
+#  endif
+
+	for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
+		delaykey[i].len = delaykey[i].str == NULL ?
+				    0 : strlen (delaykey[i].str);
+		delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ?
+				    MAX_DELAY_STOP_STR : delaykey[i].len;
+
+		presskey_max = presskey_max > delaykey[i].len ?
+				    presskey_max : delaykey[i].len;
+
+#  if DEBUG_BOOTKEYS
+		printf("%s key:<%s>\n",
+		       delaykey[i].retry ? "delay" : "stop",
+		       delaykey[i].str ? delaykey[i].str : "NULL");
+#  endif
+	}
+
+	/* In order to keep up with incoming data, check timeout only
+	 * when catch up.
+	 */
+	while (!abort && get_ticks() <= etime) {
+		for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
+			if (delaykey[i].len > 0 &&
+			    presskey_len >= delaykey[i].len &&
+			    memcmp (presskey + presskey_len - delaykey[i].len,
+		        	    delaykey[i].str,
+				    delaykey[i].len) == 0) {
+#  if DEBUG_BOOTKEYS
+				printf("got %skey\n",
+				       delaykey[i].retry ? "delay" : "stop");
+#  endif
+
+#  ifdef CONFIG_BOOT_RETRY_TIME
+				/* don't retry auto boot */
+				if (! delaykey[i].retry)
+					retry_time = -1;
+#  endif
+				abort = 1;
+			}
+		}
+
+		if (tstc()) {
+			if (presskey_len < presskey_max) {
+				presskey [presskey_len ++] = getc();
+			}
+			else {
+				for (i = 0; i < presskey_max - 1; i ++)
+					presskey [i] = presskey [i + 1];
+
+				presskey [i] = getc();
+			}
+		}
+	}
+#  if DEBUG_BOOTKEYS
+	if (!abort)
+		printf("key timeout\n");
+#  endif
+
+	return abort;
+}
+
+# else	/* !defined(CONFIG_AUTOBOOT_KEYED) */
+
+static __inline__ int abortboot(int bootdelay)
+{
+	int abort = 0;
+
+	printf("Hit any key to stop autoboot: %2d ", bootdelay);
+
+#if defined CONFIG_ZERO_BOOTDELAY_CHECK
+        /*
+         * Check if key already pressed
+         * Don't check if bootdelay < 0
+         */
+	if (bootdelay >= 0) {
+		if (tstc()) {	/* we got a key press	*/
+			(void) getc();  /* consume input	*/
+			printf ("\b\b\b 0\n");
+			return 1; 	/* don't auto boot	*/
+		}
+        }
+#endif
+
+	while (bootdelay > 0) {
+		int i;
+
+		--bootdelay;
+		/* delay 100 * 10ms */
+		for (i=0; !abort && i<100; ++i) {
+			if (tstc()) {	/* we got a key press	*/
+				abort  = 1;	/* don't auto boot	*/
+				bootdelay = 0;	/* no more delay	*/
+				(void) getc();  /* consume input	*/
+				break;
+			}
+			udelay (10000);
+		}
+
+		printf ("\b\b\b%2d ", bootdelay);
+	}
+
+	putc ('\n');
+
+	return abort;
+}
+# endif	/* CONFIG_AUTOBOOT_KEYED */
+#endif	/* CONFIG_BOOTDELAY >= 0  */
+
+/****************************************************************************/
+
+void main_loop (void)
+{
+#ifndef CFG_HUSH_PARSER
+	static char lastcommand[CFG_CBSIZE] = { 0, };
+	int len;
+	int rc = 1;
+	int flag;
+#endif
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+	char *s;
+	int bootdelay;
+#endif
+#ifdef CONFIG_PREBOOT
+	char *p;
+#endif
+
+#if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)
+	ulong bmp = 0;		/* default bitmap */
+	extern int trab_vfd (ulong bitmap);
+
+#ifdef CONFIG_MODEM_SUPPORT
+	if (do_mdm_init)
+		bmp = 1;	/* alternate bitmap */
+#endif
+	trab_vfd (bmp);
+#endif	/* CONFIG_VFD && VFD_TEST_LOGO */
+
+#ifdef CONFIG_MODEM_SUPPORT
+	debug ("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init);
+	if (do_mdm_init) {
+		uchar *str = strdup(getenv("mdm_cmd"));
+		setenv ("preboot", str);  /* set or delete definition */
+		if (str != NULL)
+			free (str);
+		mdm_init(); /* wait for modem connection */
+	}
+#endif  /* CONFIG_MODEM_SUPPORT */
+
+#ifdef CFG_HUSH_PARSER
+	u_boot_hush_start ();
+#endif
+
+#ifdef CONFIG_PREBOOT
+	if ((p = getenv ("preboot")) != NULL) {
+# ifdef CONFIG_AUTOBOOT_KEYED
+		int prev = disable_ctrlc(1);	/* disable Control C checking */
+# endif
+
+# ifndef CFG_HUSH_PARSER
+		run_command (p, 0);
+# else
+		parse_string_outer(p, FLAG_PARSE_SEMICOLON |
+				    FLAG_EXIT_FROM_LOOP);
+# endif
+
+# ifdef CONFIG_AUTOBOOT_KEYED
+		disable_ctrlc(prev);	/* restore Control C checking */
+# endif
+	}
+#endif /* CONFIG_PREBOOT */
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+	s = getenv ("bootdelay");
+	bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
+
+#if 0
+	printf ("### main_loop entered:\n\n");
+#endif
+
+# ifdef CONFIG_BOOT_RETRY_TIME
+	s = getenv ("bootretry");
+	if (s != NULL)
+		retry_time = (int)simple_strtoul(s, NULL, 10);
+	else
+		retry_time =  CONFIG_BOOT_RETRY_TIME;
+	if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
+		retry_time = CONFIG_BOOT_RETRY_MIN;
+# endif	/* CONFIG_BOOT_RETRY_TIME */
+
+	s = getenv ("bootcmd");
+	if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
+# ifdef CONFIG_AUTOBOOT_KEYED
+		int prev = disable_ctrlc(1);	/* disable Control C checking */
+# endif
+
+# ifndef CFG_HUSH_PARSER
+		run_command (s, 0);
+# else
+		parse_string_outer(s, FLAG_PARSE_SEMICOLON |
+				    FLAG_EXIT_FROM_LOOP);
+# endif
+
+# ifdef CONFIG_AUTOBOOT_KEYED
+		disable_ctrlc(prev);	/* restore Control C checking */
+# endif
+	}
+#endif	/* CONFIG_BOOTDELAY */
+
+	/*
+	 * Main Loop for Monitor Command Processing
+	 */
+#ifdef CFG_HUSH_PARSER
+	parse_file_outer();
+	/* This point is never reached */
+	for (;;);
+#else
+	for (;;) {
+#ifdef CONFIG_BOOT_RETRY_TIME
+		if (rc >= 0) {
+			/* Saw enough of a valid command to
+			 * restart the timeout.
+			 */
+			reset_cmd_timeout();
+		}
+#endif
+		len = readline (CFG_PROMPT);
+
+		flag = 0;	/* assume no special flags for now */
+		if (len > 0)
+			strcpy (lastcommand, console_buffer);
+		else if (len == 0)
+			flag |= CMD_FLAG_REPEAT;
+#ifdef CONFIG_BOOT_RETRY_TIME
+		else if (len == -2) {
+			/* -2 means timed out, retry autoboot
+			 */
+			printf("\nTimed out waiting for command\n");
+# ifdef CONFIG_RESET_TO_RETRY
+			/* Reinit board to run initialization code again */
+			do_reset (NULL, 0, 0, NULL);
+# else
+			return;		/* retry autoboot */
+# endif
+		}
+#endif
+
+		if (len == -1)
+			printf ("<INTERRUPT>\n");
+		else
+			rc = run_command (lastcommand, flag);
+
+		if (rc <= 0) {
+			/* invalid command or not repeatable, forget it */
+			lastcommand[0] = 0;
+		}
+	}
+#endif /*CFG_HUSH_PARSER*/
+}
+
+/***************************************************************************
+ * reset command line timeout to retry_time seconds
+ */
+#ifdef CONFIG_BOOT_RETRY_TIME
+void reset_cmd_timeout(void)
+{
+	endtime = endtick(retry_time);
+}
+#endif
+
+/****************************************************************************/
+
+/*
+ * Prompt for input and read a line.
+ * If  CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,
+ * time out when time goes past endtime (timebase time in ticks).
+ * Return:	number of read characters
+ *		-1 if break
+ *		-2 if timed out
+ */
+int readline (const char *const prompt)
+{
+	char   *p = console_buffer;
+	int	n = 0;				/* buffer index		*/
+	int	plen = 0;			/* prompt length	*/
+	int	col;				/* output column cnt	*/
+	char	c;
+
+	/* print prompt */
+	if (prompt) {
+		plen = strlen (prompt);
+		puts (prompt);
+	}
+	col = plen;
+
+	for (;;) {
+#ifdef CONFIG_BOOT_RETRY_TIME
+		while (!tstc()) {	/* while no incoming data */
+			if (retry_time >= 0 && get_ticks() > endtime)
+				return (-2);	/* timed out */
+		}
+#endif
+		WATCHDOG_RESET();		/* Trigger watchdog, if needed */
+
+#ifdef CONFIG_SHOW_ACTIVITY
+		while (!tstc()) {
+			extern void show_activity(int arg);
+			show_activity(0);
+		}
+#endif
+		c = getc();
+
+		/*
+		 * Special character handling
+		 */
+		switch (c) {
+		case '\r':				/* Enter		*/
+		case '\n':
+			*p = '\0';
+			puts ("\r\n");
+			return (p - console_buffer);
+
+		case 0x03:				/* ^C - break		*/
+			console_buffer[0] = '\0';	/* discard input */
+			return (-1);
+
+		case 0x15:				/* ^U - erase line	*/
+			while (col > plen) {
+				puts (erase_seq);
+				--col;
+			}
+			p = console_buffer;
+			n = 0;
+			continue;
+
+		case 0x17:				/* ^W - erase word 	*/
+			p=delete_char(console_buffer, p, &col, &n, plen);
+			while ((n > 0) && (*p != ' ')) {
+				p=delete_char(console_buffer, p, &col, &n, plen);
+			}
+			continue;
+
+		case 0x08:				/* ^H  - backspace	*/
+		case 0x7F:				/* DEL - backspace	*/
+			p=delete_char(console_buffer, p, &col, &n, plen);
+			continue;
+
+		default:
+			/*
+			 * Must be a normal character then
+			 */
+			if (n < CFG_CBSIZE-2) {
+				if (c == '\t') {	/* expand TABs		*/
+					puts (tab_seq+(col&07));
+					col += 8 - (col&07);
+				} else {
+					++col;		/* echo input		*/
+					putc (c);
+				}
+				*p++ = c;
+				++n;
+			} else {			/* Buffer full		*/
+				putc ('\a');
+			}
+		}
+	}
+}
+
+/****************************************************************************/
+
+static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen)
+{
+	char *s;
+
+	if (*np == 0) {
+		return (p);
+	}
+
+	if (*(--p) == '\t') {			/* will retype the whole line	*/
+		while (*colp > plen) {
+			puts (erase_seq);
+			(*colp)--;
+		}
+		for (s=buffer; s<p; ++s) {
+			if (*s == '\t') {
+				puts (tab_seq+((*colp) & 07));
+				*colp += 8 - ((*colp) & 07);
+			} else {
+				++(*colp);
+				putc (*s);
+			}
+		}
+	} else {
+		puts (erase_seq);
+		(*colp)--;
+	}
+	(*np)--;
+	return (p);
+}
+
+/****************************************************************************/
+
+int parse_line (char *line, char *argv[])
+{
+	int nargs = 0;
+
+#ifdef DEBUG_PARSER
+	printf ("parse_line: \"%s\"\n", line);
+#endif
+	while (nargs < CFG_MAXARGS) {
+
+		/* skip any white space */
+		while ((*line == ' ') || (*line == '\t')) {
+			++line;
+		}
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+#ifdef DEBUG_PARSER
+		printf ("parse_line: nargs=%d\n", nargs);
+#endif
+			return (nargs);
+		}
+
+		argv[nargs++] = line;	/* begin of argument string	*/
+
+		/* find end of string */
+		while (*line && (*line != ' ') && (*line != '\t')) {
+			++line;
+		}
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+#ifdef DEBUG_PARSER
+		printf ("parse_line: nargs=%d\n", nargs);
+#endif
+			return (nargs);
+		}
+
+		*line++ = '\0';		/* terminate current arg	 */
+	}
+
+	printf ("** Too many args (max. %d) **\n", CFG_MAXARGS);
+
+#ifdef DEBUG_PARSER
+	printf ("parse_line: nargs=%d\n", nargs);
+#endif
+	return (nargs);
+}
+
+/****************************************************************************/
+
+static void process_macros (const char *input, char *output)
+{
+	char c, prev;
+	const char *varname_start = NULL;
+	int inputcnt  = strlen (input);
+	int outputcnt = CFG_CBSIZE;
+	int state = 0;	/* 0 = waiting for '$'	*/
+			/* 1 = waiting for '('	*/
+			/* 2 = waiting for ')'	*/
+
+#ifdef DEBUG_PARSER
+	char *output_start = output;
+
+	printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input), input);
+#endif
+
+	prev = '\0';			/* previous character	*/
+
+	while (inputcnt && outputcnt) {
+	    c = *input++;
+	    inputcnt--;
+
+	    /* remove one level of escape characters */
+	    if ((c == '\\') && (prev != '\\')) {
+		if (inputcnt-- == 0)
+			break;
+		prev = c;
+	    	c = *input++;
+	    }
+
+	    switch (state) {
+	    case 0:			/* Waiting for (unescaped) $	*/
+		if ((c == '$') && (prev != '\\')) {
+			state++;
+		} else {
+			*(output++) = c;
+			outputcnt--;
+		}
+		break;
+	    case 1:			/* Waiting for (	*/
+		if (c == '(') {
+			state++;
+			varname_start = input;
+		} else {
+			state = 0;
+			*(output++) = '$';
+			outputcnt--;
+
+			if (outputcnt) {
+				*(output++) = c;
+				outputcnt--;
+			}
+		}
+		break;
+	    case 2:			/* Waiting for )	*/
+		if (c == ')') {
+			int i;
+			char envname[CFG_CBSIZE], *envval;
+			int envcnt = input-varname_start-1; /* Varname # of chars */
+
+			/* Get the varname */
+			for (i = 0; i < envcnt; i++) {
+				envname[i] = varname_start[i];
+			}
+			envname[i] = 0;
+
+			/* Get its value */
+			envval = getenv (envname);
+
+			/* Copy into the line if it exists */
+			if (envval != NULL)
+				while ((*envval) && outputcnt) {
+					*(output++) = *(envval++);
+					outputcnt--;
+				}
+			/* Look for another '$' */
+			state = 0;
+		}
+		break;
+	    }
+
+	    prev = c;
+	}
+
+	if (outputcnt)
+		*output = 0;
+
+#ifdef DEBUG_PARSER
+	printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
+		strlen(output_start), output_start);
+#endif
+}
+
+/****************************************************************************
+ * returns:
+ *	1  - command executed, repeatable
+ *	0  - command executed but not repeatable, interrupted commands are
+ *	     always considered not repeatable
+ *	-1 - not executed (unrecognized, bootd recursion or too many args)
+ *           (If cmd is NULL or "" or longer than CFG_CBSIZE-1 it is
+ *           considered unrecognized)
+ *
+ * WARNING:
+ *
+ * We must create a temporary copy of the command since the command we get
+ * may be the result from getenv(), which returns a pointer directly to
+ * the environment data, which may change magicly when the command we run
+ * creates or modifies environment variables (like "bootp" does).
+ */
+
+int run_command (const char *cmd, int flag)
+{
+	cmd_tbl_t *cmdtp;
+	char cmdbuf[CFG_CBSIZE];	/* working copy of cmd		*/
+	char *token;			/* start of token in cmdbuf	*/
+	char *sep;			/* end of token (separator) in cmdbuf */
+	char finaltoken[CFG_CBSIZE];
+	char *str = cmdbuf;
+	char *argv[CFG_MAXARGS + 1];	/* NULL terminated	*/
+	int argc;
+	int repeatable = 1;
+
+#ifdef DEBUG_PARSER
+	printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
+	puts (cmd ? cmd : "NULL");	/* use puts - string may be loooong */
+	puts ("\"\n");
+#endif
+
+	clear_ctrlc();		/* forget any previous Control C */
+
+	if (!cmd || !*cmd) {
+		return -1;	/* empty command */
+	}
+
+	if (strlen(cmd) >= CFG_CBSIZE) {
+		puts ("## Command too long!\n");
+		return -1;
+	}
+
+	strcpy (cmdbuf, cmd);
+
+	/* Process separators and check for invalid
+	 * repeatable commands
+	 */
+
+#ifdef DEBUG_PARSER
+	printf ("[PROCESS_SEPARATORS] %s\n", cmd);
+#endif
+	while (*str) {
+
+		/*
+		 * Find separator, or string end
+		 * Allow simple escape of ';' by writing "\;"
+		 */
+		for (sep = str; *sep; sep++) {
+			if ((*sep == ';') &&	/* separator		*/
+			    ( sep != str) &&	/* past string start	*/
+			    (*(sep-1) != '\\'))	/* and NOT escaped	*/
+				break;
+		}
+
+		/*
+		 * Limit the token to data between separators
+		 */
+		token = str;
+		if (*sep) {
+			str = sep + 1;	/* start of command for next pass */
+			*sep = '\0';
+		}
+		else
+			str = sep;	/* no more commands for next pass */
+#ifdef DEBUG_PARSER
+		printf ("token: \"%s\"\n", token);
+#endif
+
+		/* find macros in this token and replace them */
+		process_macros (token, finaltoken);
+
+		/* Extract arguments */
+		argc = parse_line (finaltoken, argv);
+
+		/* Look up command in command table */
+		if ((cmdtp = find_cmd(argv[0])) == NULL) {
+			printf ("Unknown command '%s' - try 'help'\n", argv[0]);
+			return -1;	/* give up after bad command */
+		}
+
+		/* found - check max args */
+		if (argc > cmdtp->maxargs) {
+			printf ("Usage:\n%s\n", cmdtp->usage);
+			return -1;
+		}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
+		/* avoid "bootd" recursion */
+		if (cmdtp->cmd == do_bootd) {
+#ifdef DEBUG_PARSER
+			printf ("[%s]\n", finaltoken);
+#endif
+			if (flag & CMD_FLAG_BOOTD) {
+				printf ("'bootd' recursion detected\n");
+				return -1;
+			}
+			else
+				flag |= CMD_FLAG_BOOTD;
+		}
+#endif	/* CFG_CMD_BOOTD */
+
+		/* OK - call function to do the command */
+		if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
+			return (-1);
+		}
+
+		repeatable &= cmdtp->repeatable;
+
+		/* Did the user stop this? */
+		if (had_ctrlc ())
+			return 0;	/* if stopped then not repeatable */
+	}
+
+	return repeatable;
+}
+
+/****************************************************************************/
+
+#if (CONFIG_COMMANDS & CFG_CMD_RUN)
+int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	int i;
+	int rcode = 1;
+
+	if (argc < 2) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	for (i=1; i<argc; ++i) {
+#ifndef CFG_HUSH_PARSER
+	    if (run_command (getenv (argv[i]), flag) != -1) ++rcode;
+#else
+   	    if (parse_string_outer(getenv (argv[i]),
+		    FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) == 0) ++rcode;
+#endif
+	}
+	return ((rcode == i) ? 0 : 1);
+}
+#endif
diff --git a/common/miiphyutil.c b/common/miiphyutil.c
new file mode 100644
index 0000000..6b2425f
--- /dev/null
+++ b/common/miiphyutil.c
@@ -0,0 +1,172 @@
+/*
+ * (C) Copyright 2001
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.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
+ */
+
+/*
+ * This provides a bit-banged interface to the ethernet MII management
+ * channel.
+ */
+
+#include <common.h>
+#include <miiphy.h>
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+
+/*****************************************************************************
+ *
+ * Read the OUI, manufacture's model number, and revision number.
+ *
+ * OUI:     22 bits (unsigned int)
+ * Model:    6 bits (unsigned char)
+ * Revision: 4 bits (unsigned char)
+ *
+ * Returns:
+ *   0 on success
+ */
+int miiphy_info (unsigned char addr,
+		 unsigned int *oui,
+		 unsigned char *model, unsigned char *rev)
+{
+	unsigned int reg = 0;
+
+	/*
+	 * Trick: we are reading two 16 registers into a 32 bit variable
+	 * so we do a 16 read into the high order bits of the variable (big
+	 * endian, you know), shift it down 16 bits, and the read the rest.
+	 */
+	if (miiphy_read (addr, PHY_PHYIDR2, (unsigned short *) &reg) != 0) {
+#ifdef DEBUG
+		printf ("PHY ID register 2 read failed\n");
+#endif
+		return (-1);
+	}
+	reg >>= 16;
+
+#ifdef DEBUG
+	printf ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg);
+#endif
+	if (reg == 0xFFFF) {
+		/* No physical device present at this address */
+		return (-1);
+	}
+
+	if (miiphy_read (addr, PHY_PHYIDR1, (unsigned short *) &reg) != 0) {
+#ifdef DEBUG
+		printf ("PHY ID register 1 read failed\n");
+#endif
+		return (-1);
+	}
+#ifdef DEBUG
+	printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
+#endif
+	*oui   =                 ( reg >> 10);
+	*model = (unsigned char) ((reg >>  4) & 0x0000003F);
+	*rev   = (unsigned char) ( reg        & 0x0000000F);
+	return (0);
+}
+
+
+/*****************************************************************************
+ *
+ * Reset the PHY.
+ * Returns:
+ *   0 on success
+ */
+int miiphy_reset (unsigned char addr)
+{
+	unsigned short reg;
+	int loop_cnt;
+
+	if (miiphy_write (addr, PHY_BMCR, 0x8000) != 0) {
+#ifdef DEBUG
+		printf ("PHY reset failed\n");
+#endif
+		return (-1);
+	}
+
+	/*
+	 * Poll the control register for the reset bit to go to 0 (it is
+	 * auto-clearing).  This should happen within 0.5 seconds per the
+	 * IEEE spec.
+	 */
+	loop_cnt = 0;
+	reg = 0x8000;
+	while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) {
+		if (miiphy_read (addr, PHY_BMCR, &reg) != 0) {
+#     ifdef DEBUG
+			printf ("PHY status read failed\n");
+#     endif
+			return (-1);
+		}
+	}
+	if ((reg & 0x8000) == 0) {
+		return (0);
+	} else {
+		printf ("PHY reset timed out\n");
+		return (-1);
+	}
+	return (0);
+}
+
+
+/*****************************************************************************
+ *
+ * Determine the ethernet speed (10/100).
+ */
+int miiphy_speed (unsigned char addr)
+{
+	unsigned short reg;
+
+	if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
+		printf ("PHY speed1 read failed, assuming 10bT\n");
+		return (_10BASET);
+	}
+
+	if ((reg & PHY_ANLPAR_100) != 0) {
+		return (_100BASET);
+	} else {
+		return (_10BASET);
+	}
+}
+
+
+/*****************************************************************************
+ *
+ * Determine full/half duplex.
+ */
+int miiphy_duplex (unsigned char addr)
+{
+	unsigned short reg;
+
+	if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
+		printf ("PHY duplex read failed, assuming half duplex\n");
+		return (HALF);
+	}
+
+	if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) {
+		return (FULL);
+	} else {
+		return (HALF);
+	}
+}
+
+#endif /* CONFIG_MII || (CONFIG_COMMANDS & CFG_CMD_MII) */
diff --git a/common/soft_i2c.c b/common/soft_i2c.c
new file mode 100644
index 0000000..7777480
--- /dev/null
+++ b/common/soft_i2c.c
@@ -0,0 +1,416 @@
+/*
+ * (C) Copyright 2001, 2002
+ * 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
+ *
+ * This has been changed substantially by Gerald Van Baren, Custom IDEAS,
+ * vanbaren@cideas.com.  It was heavily influenced by LiMon, written by
+ * Neil Russell.
+ */
+
+#include <common.h>
+#ifdef	CONFIG_MPC8260			/* only valid for MPC8260 */
+#include <ioports.h>
+#endif
+#include <i2c.h>
+
+#if defined(CONFIG_SOFT_I2C)
+
+/* #define	DEBUG_I2C	*/
+
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#define RETRIES		0
+
+
+#define I2C_ACK		0		/* PD_SDA level to ack a byte */
+#define I2C_NOACK	1		/* PD_SDA level to noack a byte */
+
+
+#ifdef DEBUG_I2C
+#define PRINTD(fmt,args...)	do {	\
+	DECLARE_GLOBAL_DATA_PTR;	\
+	if (gd->have_console)		\
+		printf (fmt ,##args);	\
+	} while (0)
+#else
+#define PRINTD(fmt,args...)
+#endif
+
+/*-----------------------------------------------------------------------
+ * Local functions
+ */
+static void  send_reset	(void);
+static void  send_start	(void);
+static void  send_stop	(void);
+static void  send_ack	(int);
+static int   write_byte	(uchar byte);
+static uchar read_byte	(int);
+
+
+/*-----------------------------------------------------------------------
+ * Send a reset sequence consisting of 9 clocks with the data signal high
+ * to clock any confused device back into an idle state.  Also send a
+ * <stop> at the end of the sequence for belts & suspenders.
+ */
+static void send_reset(void)
+{
+#ifdef	CONFIG_MPC8260
+	volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef	CONFIG_8xx
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+	int j;
+
+	I2C_ACTIVE;
+	I2C_SDA(1);
+	for(j = 0; j < 9; j++) {
+		I2C_SCL(0);
+		I2C_DELAY;
+		I2C_DELAY;
+		I2C_SCL(1);
+		I2C_DELAY;
+		I2C_DELAY;
+	}
+	send_stop();
+	I2C_TRISTATE;
+}
+
+/*-----------------------------------------------------------------------
+ * START: High -> Low on SDA while SCL is High
+ */
+static void send_start(void)
+{
+#ifdef	CONFIG_MPC8260
+	volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef	CONFIG_8xx
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+	I2C_DELAY;
+	I2C_SDA(1);
+	I2C_ACTIVE;
+	I2C_DELAY;
+	I2C_SCL(1);
+	I2C_DELAY;
+	I2C_SDA(0);
+	I2C_DELAY;
+}
+
+/*-----------------------------------------------------------------------
+ * STOP: Low -> High on SDA while SCL is High
+ */
+static void send_stop(void)
+{
+#ifdef	CONFIG_MPC8260
+	volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef	CONFIG_8xx
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+	I2C_SCL(0);
+	I2C_DELAY;
+	I2C_SDA(0);
+	I2C_ACTIVE;
+	I2C_DELAY;
+	I2C_SCL(1);
+	I2C_DELAY;
+	I2C_SDA(1);
+	I2C_DELAY;
+	I2C_TRISTATE;
+}
+
+
+/*-----------------------------------------------------------------------
+ * ack should be I2C_ACK or I2C_NOACK
+ */
+static void send_ack(int ack)
+{
+#ifdef	CONFIG_MPC8260
+	volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef	CONFIG_8xx
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+	I2C_ACTIVE;
+	I2C_SCL(0);
+	I2C_DELAY;
+
+	I2C_SDA(ack);
+
+	I2C_ACTIVE;
+	I2C_DELAY;
+	I2C_SCL(1);
+	I2C_DELAY;
+	I2C_DELAY;
+	I2C_SCL(0);
+	I2C_DELAY;
+}
+
+
+/*-----------------------------------------------------------------------
+ * Send 8 bits and look for an acknowledgement.
+ */
+static int write_byte(uchar data)
+{
+#ifdef	CONFIG_MPC8260
+	volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef	CONFIG_8xx
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+	int j;
+	int nack;
+
+	I2C_ACTIVE;
+	for(j = 0; j < 8; j++) {
+		I2C_SCL(0);
+		I2C_DELAY;
+		I2C_SDA(data & 0x80);
+		I2C_DELAY;
+		I2C_SCL(1);
+		I2C_DELAY;
+		I2C_DELAY;
+
+		data <<= 1;
+	}
+
+	/*
+	 * Look for an <ACK>(negative logic) and return it.
+	 */
+	I2C_SCL(0);
+	I2C_DELAY;
+	I2C_SDA(1);
+	I2C_TRISTATE;
+	I2C_DELAY;
+	I2C_SCL(1);
+	I2C_DELAY;
+	I2C_DELAY;
+	nack = I2C_READ;
+	I2C_SCL(0);
+	I2C_DELAY;
+	I2C_ACTIVE;
+
+	return(nack);	/* not a nack is an ack */
+}
+
+
+/*-----------------------------------------------------------------------
+ * if ack == I2C_ACK, ACK the byte so can continue reading, else
+ * send I2C_NOACK to end the read.
+ */
+static uchar read_byte(int ack)
+{
+#ifdef	CONFIG_MPC8260
+	volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef	CONFIG_8xx
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+	int  data;
+	int  j;
+
+	/*
+	 * Read 8 bits, MSB first.
+	 */
+	I2C_TRISTATE;
+	data = 0;
+	for(j = 0; j < 8; j++) {
+		I2C_SCL(0);
+		I2C_DELAY;
+		I2C_SCL(1);
+		I2C_DELAY;
+		data <<= 1;
+		data |= I2C_READ;
+		I2C_DELAY;
+	}
+	send_ack(ack);
+
+	return(data);
+}
+
+/*=====================================================================*/
+/*                         Public Functions                            */
+/*=====================================================================*/
+
+/*-----------------------------------------------------------------------
+ * Initialization
+ */
+void i2c_init (int speed, int slaveaddr)
+{
+#ifdef	CONFIG_8xx
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+#ifdef	I2C_INIT
+	I2C_INIT;
+#endif
+	/*
+         * WARNING: Do NOT save speed in a static variable: if the
+         * I2C routines are called before RAM is initialized (to read
+         * the DIMM SPD, for instance), RAM won't be usable and your
+         * system will crash.
+	 */
+	send_reset ();
+}
+
+/*-----------------------------------------------------------------------
+ * Probe to see if a chip is present.  Also good for checking for the
+ * completion of EEPROM writes since the chip stops responding until
+ * the write completes (typically 10mSec).
+ */
+int i2c_probe(uchar addr)
+{
+	int rc;
+
+	send_start();
+	rc = write_byte ((addr << 1) | 1);
+	send_stop();
+
+	return (rc ? 1 : 0);
+}
+
+/*-----------------------------------------------------------------------
+ * Read bytes
+ */
+int  i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int shift;
+	PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
+		chip, addr, alen, buffer, len);
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+	/*
+	 * EEPROM chips that implement "address overflow" are ones
+	 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+	 * address and the extra bits end up in the "chip address"
+	 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+	 * four 256 byte chips.
+	 *
+	 * Note that we consider the length of the address field to
+	 * still be one byte because the extra address bits are
+	 * hidden in the chip address.
+	 */
+	chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+
+	PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n",
+		chip, addr);
+#endif
+
+	/*
+	 * Do the addressing portion of a write cycle to set the
+	 * chip's address pointer.  If the address length is zero,
+	 * don't do the normal write cycle to set the address pointer,
+	 * there is no address pointer in this chip.
+	 */
+	send_start();
+	if(alen > 0) {
+		if(write_byte(chip << 1)) {	/* write cycle */
+			send_stop();
+			PRINTD("i2c_read, no chip responded %02X\n", chip);
+			return(1);
+		}
+		shift = (alen-1) * 8;
+		while(alen-- > 0) {
+			if(write_byte(addr >> shift)) {
+				PRINTD("i2c_read, address not <ACK>ed\n");
+				return(1);
+			}
+			shift -= 8;
+		}
+		send_stop();	/* reportedly some chips need a full stop */
+		send_start();
+	}
+	/*
+	 * Send the chip address again, this time for a read cycle.
+	 * Then read the data.  On the last byte, we do a NACK instead
+	 * of an ACK(len == 0) to terminate the read.
+	 */
+	write_byte((chip << 1) | 1);	/* read cycle */
+	while(len-- > 0) {
+		*buffer++ = read_byte(len == 0);
+	}
+	send_stop();
+	return(0);
+}
+
+/*-----------------------------------------------------------------------
+ * Write bytes
+ */
+int  i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int shift, failures = 0;
+
+	PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n",
+		chip, addr, alen, buffer, len);
+
+	send_start();
+	if(write_byte(chip << 1)) {	/* write cycle */
+		send_stop();
+		PRINTD("i2c_write, no chip responded %02X\n", chip);
+		return(1);
+	}
+	shift = (alen-1) * 8;
+	while(alen-- > 0) {
+		if(write_byte(addr >> shift)) {
+			PRINTD("i2c_write, address not <ACK>ed\n");
+			return(1);
+		}
+		shift -= 8;
+	}
+
+	while(len-- > 0) {
+		if(write_byte(*buffer++)) {
+			failures++;
+		}
+	}
+	send_stop();
+	return(failures);
+}
+
+/*-----------------------------------------------------------------------
+ * Read a register
+ */
+uchar i2c_reg_read(uchar i2c_addr, uchar reg)
+{
+	char buf;
+
+	i2c_read(i2c_addr, reg, 1, &buf, 1);
+
+	return(buf);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a register
+ */
+void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
+{
+	i2c_write(i2c_addr, reg, 1, &val, 1);
+}
+
+
+#endif	/* CONFIG_SOFT_I2C */
diff --git a/cpu/arm720t/Makefile b/cpu/arm720t/Makefile
new file mode 100644
index 0000000..8c950da
--- /dev/null
+++ b/cpu/arm720t/Makefile
@@ -0,0 +1,43 @@
+#
+# (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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(CPU).a
+
+START	= start.o
+OBJS	= serial.o interrupts.o cpu.o
+
+all:	.depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c
new file mode 100644
index 0000000..52787fe
--- /dev/null
+++ b/cpu/arm720t/interrupts.c
@@ -0,0 +1,265 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.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 <clps7111.h>
+
+#include <asm/proc-armv/ptrace.h>
+
+extern void reset_cpu(ulong addr);
+
+/* we always count down the max. */
+#define TIMER_LOAD_VAL 0xffff
+
+/* macro to read the 16 bit timer */
+#define READ_TIMER (IO_TC1D & 0xffff)
+
+#ifdef CONFIG_USE_IRQ
+/* enable IRQ/FIQ interrupts */
+void enable_interrupts (void)
+{
+	unsigned long temp;
+	__asm__ __volatile__("mrs %0, cpsr\n"
+			     "bic %0, %0, #0x80\n"
+			     "msr cpsr_c, %0"
+			     : "=r" (temp)
+			     :
+			     : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+	unsigned long old,temp;
+	__asm__ __volatile__("mrs %0, cpsr\n"
+			     "orr %1, %0, #0x80\n"
+			     "msr cpsr_c, %1"
+			     : "=r" (old), "=r" (temp)
+			     :
+			     : "memory");
+	return (old & 0x80) == 0;
+}
+#else
+void enable_interrupts (void)
+{
+	return;
+}
+int disable_interrupts (void)
+{
+	return 0;
+}
+#endif
+
+
+
+void bad_mode (void)
+{
+	panic ("Resetting CPU ...\n");
+	reset_cpu (0);
+}
+
+void show_regs (struct pt_regs *regs)
+{
+	unsigned long flags;
+	const char *processor_modes[] =
+			{ "USER_26", "FIQ_26", "IRQ_26", "SVC_26", "UK4_26", "UK5_26",
+"UK6_26", "UK7_26",
+		"UK8_26", "UK9_26", "UK10_26", "UK11_26", "UK12_26", "UK13_26",
+				"UK14_26", "UK15_26",
+		"USER_32", "FIQ_32", "IRQ_32", "SVC_32", "UK4_32", "UK5_32",
+				"UK6_32", "ABT_32",
+		"UK8_32", "UK9_32", "UK10_32", "UND_32", "UK12_32", "UK13_32",
+				"UK14_32", "SYS_32"
+	};
+
+	flags = condition_codes (regs);
+
+	printf ("pc : [<%08lx>]    lr : [<%08lx>]\n"
+			"sp : %08lx  ip : %08lx  fp : %08lx\n",
+			instruction_pointer (regs),
+			regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+	printf ("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+			regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+	printf ("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+			regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+	printf ("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+			regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+	printf ("Flags: %c%c%c%c",
+			flags & CC_N_BIT ? 'N' : 'n',
+			flags & CC_Z_BIT ? 'Z' : 'z',
+			flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+	printf ("  IRQs %s  FIQs %s  Mode %s%s\n",
+			interrupts_enabled (regs) ? "on" : "off",
+			fast_interrupts_enabled (regs) ? "on" : "off",
+			processor_modes[processor_mode (regs)],
+			thumb_mode (regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction (struct pt_regs *pt_regs)
+{
+	printf ("undefined instruction\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_software_interrupt (struct pt_regs *pt_regs)
+{
+	printf ("software interrupt\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_prefetch_abort (struct pt_regs *pt_regs)
+{
+	printf ("prefetch abort\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_data_abort (struct pt_regs *pt_regs)
+{
+	printf ("data abort\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_not_used (struct pt_regs *pt_regs)
+{
+	printf ("not used\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_fiq (struct pt_regs *pt_regs)
+{
+	printf ("fast interrupt request\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_irq (struct pt_regs *pt_regs)
+{
+	printf ("interrupt request\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+static ulong timestamp;
+static ulong lastdec;
+
+int interrupt_init (void)
+{
+	/* disable all interrupts */
+	IO_INTMR1 = 0;
+
+	/* operate timer 1 in prescale mode */
+	IO_SYSCON1 |= SYSCON1_TC1M;
+
+	/* select 2kHz clock source for timer 1 */
+	IO_SYSCON1 &= ~SYSCON1_TC1S;
+
+	/* set timer 1 counter */
+	lastdec = IO_TC1D = TIMER_LOAD_VAL;
+	timestamp = 0;
+
+	return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+	reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+	return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+	timestamp = t;
+}
+
+void udelay (unsigned long usec)
+{
+	ulong tmo;
+
+	tmo = usec / 1000;
+	tmo *= CFG_HZ;
+	tmo /= 1000;
+
+	tmo += get_timer (0);
+
+	while (get_timer_masked () < tmo)
+		/*NOP*/;
+}
+
+void reset_timer_masked (void)
+{
+	/* reset time */
+	lastdec = READ_TIMER;
+	timestamp = 0;
+}
+
+ulong get_timer_masked (void)
+{
+	ulong now = READ_TIMER;
+
+	if (lastdec >= now) {
+		/* normal mode */
+		timestamp += lastdec - now;
+	} else {
+		/* we have an overflow ... */
+		timestamp += lastdec + TIMER_LOAD_VAL - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+void udelay_masked (unsigned long usec)
+{
+	ulong tmo;
+
+	tmo = usec / 1000;
+	tmo *= CFG_HZ;
+	tmo /= 1000;
+
+	reset_timer_masked ();
+
+	while (get_timer_masked () < tmo)
+		/*NOP*/;
+}
diff --git a/cpu/arm920t/Makefile b/cpu/arm920t/Makefile
new file mode 100644
index 0000000..e5ec81d
--- /dev/null
+++ b/cpu/arm920t/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# 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 $(TOPDIR)/config.mk
+
+LIB	= lib$(CPU).a
+
+START	= start.o
+OBJS	= serial.o interrupts.o cpu.o speed.o
+
+all:	.depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/interrupts.c b/cpu/arm920t/interrupts.c
new file mode 100644
index 0000000..963ccbd
--- /dev/null
+++ b/cpu/arm920t/interrupts.c
@@ -0,0 +1,304 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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 <arm920t.h>
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#include <asm/proc-armv/ptrace.h>
+
+extern void reset_cpu(ulong addr);
+int timer_load_val = 0;
+
+/* macro to read the 16 bit timer */
+#define READ_TIMER (rTCNTO4 & 0xffff)
+
+#ifdef CONFIG_USE_IRQ
+/* enable IRQ interrupts */
+void enable_interrupts (void)
+{
+	unsigned long temp;
+	__asm__ __volatile__("mrs %0, cpsr\n"
+			     "bic %0, %0, #0x80\n"
+			     "msr cpsr_c, %0"
+			     : "=r" (temp)
+			     :
+			     : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+	unsigned long old,temp;
+	__asm__ __volatile__("mrs %0, cpsr\n"
+			     "orr %1, %0, #0xc0\n"
+			     "msr cpsr_c, %1"
+			     : "=r" (old), "=r" (temp)
+			     :
+			     : "memory");
+	return (old & 0x80) == 0;
+}
+#else
+void enable_interrupts (void)
+{
+	return;
+}
+int disable_interrupts (void)
+{
+	return 0;
+}
+#endif
+
+
+
+void bad_mode (void)
+{
+	panic ("Resetting CPU ...\n");
+	reset_cpu (0);
+}
+
+void show_regs (struct pt_regs *regs)
+{
+	unsigned long flags;
+	const char *processor_modes[] = {
+	"USER_26",	"FIQ_26",	"IRQ_26",	"SVC_26",
+	"UK4_26",	"UK5_26",	"UK6_26",	"UK7_26",
+	"UK8_26",	"UK9_26",	"UK10_26",	"UK11_26",
+	"UK12_26",	"UK13_26",	"UK14_26",	"UK15_26",
+	"USER_32",	"FIQ_32",	"IRQ_32",	"SVC_32",
+	"UK4_32",	"UK5_32",	"UK6_32",	"ABT_32",
+	"UK8_32",	"UK9_32",	"UK10_32",	"UND_32",
+	"UK12_32",	"UK13_32",	"UK14_32",	"SYS_32",
+	};
+
+	flags = condition_codes (regs);
+
+	printf ("pc : [<%08lx>]    lr : [<%08lx>]\n"
+		"sp : %08lx  ip : %08lx  fp : %08lx\n",
+		instruction_pointer (regs),
+		regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+	printf ("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+		regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+	printf ("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+		regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+	printf ("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+		regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+	printf ("Flags: %c%c%c%c",
+		flags & CC_N_BIT ? 'N' : 'n',
+		flags & CC_Z_BIT ? 'Z' : 'z',
+		flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+	printf ("  IRQs %s  FIQs %s  Mode %s%s\n",
+		interrupts_enabled (regs) ? "on" : "off",
+		fast_interrupts_enabled (regs) ? "on" : "off",
+		processor_modes[processor_mode (regs)],
+		thumb_mode (regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction (struct pt_regs *pt_regs)
+{
+	printf ("undefined instruction\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_software_interrupt (struct pt_regs *pt_regs)
+{
+	printf ("software interrupt\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_prefetch_abort (struct pt_regs *pt_regs)
+{
+	printf ("prefetch abort\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_data_abort (struct pt_regs *pt_regs)
+{
+	printf ("data abort\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_not_used (struct pt_regs *pt_regs)
+{
+	printf ("not used\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_fiq (struct pt_regs *pt_regs)
+{
+	printf ("fast interrupt request\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_irq (struct pt_regs *pt_regs)
+{
+	printf ("interrupt request\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+static ulong timestamp;
+static ulong lastdec;
+
+int interrupt_init (void)
+{
+	/* use PWM Timer 4 because it has no output */
+	/* prescaler for Timer 4 is 16 */
+	rTCFG0 = 0x0f00;
+	if (timer_load_val == 0)
+	{
+		/*
+		 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
+		 * (default) and prescaler = 16. Should be 10390
+		 * @33.25MHz and 15625 @ 50 MHz
+		 */
+		timer_load_val = get_PCLK()/(2 * 16 * 100);
+	}
+	/* load value for 10 ms timeout */
+	lastdec = rTCNTB4 = timer_load_val;
+	/* auto load, manual update of Timer 4 */
+	rTCON = 0x600000;
+	/* auto load, start Timer 4 */
+	rTCON = 0x500000;
+	timestamp = 0;
+
+	return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+	reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+	return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+	timestamp = t;
+}
+
+void udelay (unsigned long usec)
+{
+	ulong tmo;
+
+	tmo = usec / 1000;
+	tmo *= (timer_load_val * 100);
+	tmo /= 1000;
+
+	tmo += get_timer (0);
+
+	while (get_timer_masked () < tmo)
+		/*NOP*/;
+}
+
+void reset_timer_masked (void)
+{
+	/* reset time */
+	lastdec = READ_TIMER;
+	timestamp = 0;
+}
+
+ulong get_timer_masked (void)
+{
+	ulong now = READ_TIMER;
+
+	if (lastdec >= now) {
+		/* normal mode */
+		timestamp += lastdec - now;
+	} else {
+		/* we have an overflow ... */
+		timestamp += lastdec + timer_load_val - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+void udelay_masked (unsigned long usec)
+{
+	ulong tmo;
+
+	tmo = usec / 1000;
+	tmo *= (timer_load_val * 100);
+	tmo /= 1000;
+
+	reset_timer_masked ();
+
+	while (get_timer_masked () < tmo)
+		/*NOP*/;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+	ulong tbclk;
+
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+	tbclk = timer_load_val * 100;
+#elif defined(CONFIG_SMDK2410)
+	tbclk = CFG_HZ;
+#endif
+
+	return tbclk;
+}
diff --git a/cpu/arm920t/serial.c b/cpu/arm920t/serial.c
new file mode 100644
index 0000000..c32e73b
--- /dev/null
+++ b/cpu/arm920t/serial.c
@@ -0,0 +1,200 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * 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>
+#if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+
+void serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int i;
+	unsigned int reg = 0;
+
+	/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
+	reg = get_PCLK() / (16 * gd->baudrate) - 1;
+
+#ifdef CONFIG_SERIAL1
+	/* FIFO enable, Tx/Rx FIFO clear */
+	rUFCON0 = 0x07;
+	rUMCON0 = 0x0;
+	/* Normal,No parity,1 stop,8 bit */
+	rULCON0 = 0x3;
+	/*
+	 * tx=level,rx=edge,disable timeout int.,enable rx error int.,
+	 * normal,interrupt or polling
+	 */
+	rUCON0 = 0x245;
+	rUBRDIV0 = reg;
+
+#ifdef CONFIG_HWFLOW
+	rUMCON0 = 0x1; /* RTS up */
+#endif
+	for (i = 0; i < 100; i++);
+#elif CONFIG_SERIAL2
+# if defined(CONFIG_TRAB)
+#  #error "TRAB supports only CONFIG_SERIAL1"
+# endif
+	/* FIFO enable, Tx/Rx FIFO clear */
+	rUFCON1 = 0x06;
+	rUMCON1 = 0x0;
+	/* Normal,No parity,1 stop,8 bit */
+	rULCON1 = 0x3;
+	/*
+	 * tx=level,rx=edge,disable timeout int.,enable rx error int.,
+	 * normal,interrupt or polling
+	 */
+	rUCON1 = 0x245;
+	rUBRDIV1 = reg;
+
+#ifdef CONFIG_HWFLOW
+	rUMCON1 = 0x1; /* RTS up */
+#endif
+	for (i = 0; i < 100; i++);
+#else
+#error "Bad: you didn't configure serial ..."
+#endif
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init (void)
+{
+	serial_setbrg ();
+
+	return (0);
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc (void)
+{
+#ifdef CONFIG_SERIAL1
+	while (!(rUTRSTAT0 & 0x1));
+
+	return rURXH0 & 0xff;
+#elif CONFIG_SERIAL2
+	while (!(rUTRSTAT1 & 0x1));
+
+	return rURXH1 & 0xff;
+#endif
+}
+
+#ifdef CONFIG_HWFLOW
+static int hwflow = 0; /* turned off by default */
+int hwflow_onoff(int on)
+{
+	switch(on) {
+	case 0:
+	default:
+		break; /* return current */
+	case 1:
+		hwflow = 1; /* turn on */
+		break;
+	case -1:
+		hwflow = 0; /* turn off */
+		break;
+	}
+	return hwflow;
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int be_quiet = 0;
+void disable_putc(void)
+{
+	be_quiet = 1;
+}
+
+void enable_putc(void)
+{
+	be_quiet = 0;
+}
+#endif
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc (const char c)
+{
+#ifdef CONFIG_MODEM_SUPPORT
+	if (be_quiet)
+		return;
+#endif
+
+#ifdef CONFIG_SERIAL1
+	/* wait for room in the tx FIFO on SERIAL1 */
+	while (!(rUTRSTAT0 & 0x2));
+
+#ifdef CONFIG_HWFLOW
+	/* Wait for CTS up */
+	while(hwflow && !(rUMSTAT0 & 0x1))
+		;
+#endif
+
+	rUTXH0 = c;
+#elif CONFIG_SERIAL2
+	/* wait for room in the tx FIFO on SERIAL2 */
+	while (!(rUTRSTAT1 & 0x2));
+
+#ifdef CONFIG_HWFLOW
+	/* Wait for CTS up */
+	while(hwflow && !(rUMSTAT1 & 0x1))
+		;
+#endif
+	rUTXH1 = c;
+#endif
+
+	/* If \n, also do \r */
+	if (c == '\n')
+		serial_putc ('\r');
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int serial_tstc (void)
+{
+#ifdef CONFIG_SERIAL1
+	return rUTRSTAT0 & 0x1;
+#elif CONFIG_SERIAL2
+	return rUTRSTAT1 & 0x1;
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
diff --git a/cpu/arm920t/speed.c b/cpu/arm920t/speed.c
new file mode 100644
index 0000000..1ee0c1a
--- /dev/null
+++ b/cpu/arm920t/speed.c
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2001-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.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
+ */
+
+/* This code should work for both the S3C2400 and the S3C2410
+ * as they seem to have the same PLL and clock machinery inside.
+ * The different address mapping is handled by the s3c24xx.h files below.
+ */
+
+#include <common.h>
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#define MPLL 0
+#define UPLL 1
+
+/* ------------------------------------------------------------------------- */
+/* NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_PLL_INPUT_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+static ulong get_PLLCLK(int pllreg)
+{
+    ulong r, m, p, s;
+
+    if (pllreg == MPLL)
+	r = rMPLLCON;
+    else if (pllreg == UPLL)
+	r = rUPLLCON;
+    else
+	hang();
+
+    m = ((r & 0xFF000) >> 12) + 8;
+    p = ((r & 0x003F0) >> 4) + 2;
+    s = r & 0x3;
+
+    return((CONFIG_PLL_INPUT_FREQ * m) / (p << s));
+}
+
+/* return FCLK frequency */
+ulong get_FCLK(void)
+{
+    return(get_PLLCLK(MPLL));
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+    ulong clkdiv = rCLKDIVN;
+
+    return((clkdiv & 0x2) ? get_FCLK()/2 : get_FCLK());
+}
+
+/* return PCLK frequency */
+ulong get_PCLK(void)
+{
+    ulong clkdiv = rCLKDIVN;
+
+    return((clkdiv & 0x1) ? get_HCLK()/2 : get_HCLK());
+}
+
+/* return UCLK frequency */
+ulong get_UCLK(void)
+{
+    return(get_PLLCLK(UPLL));
+}
diff --git a/cpu/mpc824x/cpu_init.c b/cpu/mpc824x/cpu_init.c
new file mode 100644
index 0000000..602f65d
--- /dev/null
+++ b/cpu/mpc824x/cpu_init.c
@@ -0,0 +1,383 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor. Flying Pig Systems. robt@flyingpig.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
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <mpc824x.h>
+
+#ifndef CFG_BANK0_ROW
+#define CFG_BANK0_ROW 0
+#endif
+#ifndef CFG_BANK1_ROW
+#define CFG_BANK1_ROW 0
+#endif
+#ifndef CFG_BANK2_ROW
+#define CFG_BANK2_ROW 0
+#endif
+#ifndef CFG_BANK3_ROW
+#define CFG_BANK3_ROW 0
+#endif
+#ifndef CFG_BANK4_ROW
+#define CFG_BANK4_ROW 0
+#endif
+#ifndef CFG_BANK5_ROW
+#define CFG_BANK5_ROW 0
+#endif
+#ifndef CFG_BANK6_ROW
+#define CFG_BANK6_ROW 0
+#endif
+#ifndef CFG_BANK7_ROW
+#define CFG_BANK7_ROW 0
+#endif
+#ifndef CFG_DBUS_SIZE2
+#define CFG_DBUS_SIZE2 0
+#endif
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ */
+void
+cpu_init_f (void)
+{
+/* MOUSSE board is initialized in asm */
+#if !defined(CONFIG_MOUSSE) && !defined(CONFIG_BMW)
+    register unsigned long val;
+    CONFIG_WRITE_HALFWORD(PCICR, 0x06); /* Bus Master, respond to PCI memory space acesses*/
+/*    CONFIG_WRITE_HALFWORD(PCISR, 0xffff); */ /*reset PCISR*/
+
+#if defined(CONFIG_MUSENKI) || defined(CONFIG_PN62)
+/* Why is this here, you ask?  Try, just try setting 0x8000
+ * in PCIACR with CONFIG_WRITE_HALFWORD()
+ * this one was a stumper, and we are annoyed
+ */
+
+#define M_CONFIG_WRITE_HALFWORD( addr, data ) \
+    __asm__ __volatile__(     \
+      "                       \
+      stw  %2,0(%0)\n         \
+      sync\n                  \
+      sth  %3,2(%1)\n         \
+      sync\n                  \
+      "                       \
+      : /* no output */       \
+      : "r" (CONFIG_ADDR), "r" (CONFIG_DATA),                 \
+        "r" (PCISWAP(addr & ~3)), "r" (PCISWAP(data << 16))   \
+      );
+
+    M_CONFIG_WRITE_HALFWORD(PCIACR, 0x8000);
+#endif
+
+    CONFIG_WRITE_BYTE(PCLSR, 0x8);	/* set PCI cache line size */
+
+    /*
+     * Note that although this bit is cleared after a hard reset, it
+     * must be explicitly set and then cleared by software during
+     * initialization in order to guarantee correct operation of the
+     * DLL and the SDRAM_CLK[0:3] signals (if they are used).
+     */
+    CONFIG_READ_BYTE (AMBOR, val);
+    CONFIG_WRITE_BYTE(AMBOR, val & 0xDF);
+    CONFIG_WRITE_BYTE(AMBOR, val | 0x20);
+    CONFIG_WRITE_BYTE(AMBOR, val & 0xDF);
+
+    CONFIG_READ_WORD(PICR1, val);
+#if defined(CONFIG_MPC8240)
+    CONFIG_WRITE_WORD( PICR1,
+       (val & (PICR1_ADDRESS_MAP | PICR1_RCS0)) |
+	       PIRC1_MSK | PICR1_PROC_TYPE_603E |
+	       PICR1_FLASH_WR_EN | PICR1_MCP_EN |
+	       PICR1_CF_DPARK | PICR1_EN_PCS |
+	       PICR1_CF_APARK );
+#elif defined(CONFIG_MPC8245)
+    CONFIG_WRITE_WORD( PICR1,
+       (val & (PICR1_RCS0)) |
+	       PICR1_PROC_TYPE_603E |
+	       PICR1_FLASH_WR_EN | PICR1_MCP_EN |
+	       PICR1_CF_DPARK | PICR1_NO_BUSW_CK |
+	       PICR1_DEC| PICR1_CF_APARK | 0x10);	/* 8245 UM says bit 4 must be set */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+    CONFIG_READ_WORD(PICR2, val);
+    val= val & ~ (PICR2_CF_SNOOP_WS_MASK | PICR2_CF_APHASE_WS_MASK); /*mask off waitstate bits*/
+#ifndef CONFIG_PN62
+    val |= PICR2_CF_SNOOP_WS_1WS | PICR2_CF_APHASE_WS_1WS; /*1 wait state*/
+#endif
+    CONFIG_WRITE_WORD(PICR2, val);
+
+    CONFIG_WRITE_WORD(EUMBBAR, CFG_EUMB_ADDR);
+#ifndef CFG_RAMBOOT
+    CONFIG_WRITE_WORD(MCCR1, (CFG_ROMNAL << MCCR1_ROMNAL_SHIFT) |
+				 (CFG_BANK0_ROW) |
+				 (CFG_BANK1_ROW << MCCR1_BANK1ROW_SHIFT) |
+				 (CFG_BANK2_ROW << MCCR1_BANK2ROW_SHIFT) |
+				 (CFG_BANK3_ROW << MCCR1_BANK3ROW_SHIFT) |
+				 (CFG_BANK4_ROW << MCCR1_BANK4ROW_SHIFT) |
+				 (CFG_BANK5_ROW << MCCR1_BANK5ROW_SHIFT) |
+				 (CFG_BANK6_ROW << MCCR1_BANK6ROW_SHIFT) |
+				 (CFG_BANK7_ROW << MCCR1_BANK7ROW_SHIFT) |
+			     (CFG_ROMFAL << MCCR1_ROMFAL_SHIFT));
+#endif
+
+#if defined(CFG_ASRISE) && defined(CFG_ASFALL)
+    CONFIG_WRITE_WORD(MCCR2, CFG_REFINT << MCCR2_REFINT_SHIFT |
+    			     CFG_ASRISE << MCCR2_ASRISE_SHIFT |
+    			     CFG_ASFALL << MCCR2_ASFALL_SHIFT);
+#else
+    CONFIG_WRITE_WORD(MCCR2, CFG_REFINT << MCCR2_REFINT_SHIFT);
+#endif
+
+#if defined(CONFIG_MPC8240)
+    CONFIG_WRITE_WORD(MCCR3,
+	(((CFG_BSTOPRE & 0x003c) >> 2) << MCCR3_BSTOPRE2TO5_SHIFT) |
+	(CFG_REFREC << MCCR3_REFREC_SHIFT) |
+	(CFG_RDLAT  << MCCR3_RDLAT_SHIFT));
+#elif defined(CONFIG_MPC8245)
+    CONFIG_WRITE_WORD(MCCR3,
+	(((CFG_BSTOPRE & 0x003c) >> 2) << MCCR3_BSTOPRE2TO5_SHIFT) |
+	(CFG_REFREC << MCCR3_REFREC_SHIFT));
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+/* this is gross.  We think these should all be the same, and various boards
+ *  should define CFG_ACTORW to 0 if they don't want to set it, or even, if
+ *  its not set, we define it to zero in this file
+ */
+#if defined(CONFIG_CU824) || defined(CONFIG_PN62)
+	CONFIG_WRITE_WORD(MCCR4,
+	(CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+	(CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+	MCCR4_BIT21 |
+	(CFG_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+	((CFG_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+	(((CFG_SDMODE_CAS_LAT <<4) | (CFG_SDMODE_WRAP <<3) |
+		  CFG_SDMODE_BURSTLEN) << MCCR4_SDMODE_SHIFT) |
+	(CFG_ACTORW << MCCR4_ACTTORW_SHIFT) |
+	(((CFG_BSTOPRE & 0x03c0) >> 6) << MCCR4_BSTOPRE6TO9_SHIFT));
+#elif defined(CONFIG_MPC8240)
+	CONFIG_WRITE_WORD(MCCR4,
+	(CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+	(CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+	MCCR4_BIT21 |
+	(CFG_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+	((CFG_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+	(((CFG_SDMODE_CAS_LAT <<4) | (CFG_SDMODE_WRAP <<3) |
+		  (CFG_SDMODE_BURSTLEN)) <<MCCR4_SDMODE_SHIFT) |
+	(((CFG_BSTOPRE & 0x03c0) >> 6) <<MCCR4_BSTOPRE6TO9_SHIFT ));
+#elif defined(CONFIG_MPC8245)
+    CONFIG_READ_WORD(MCCR1, val);
+    val &= MCCR1_DBUS_SIZE0;    /* test for 64-bit mem bus */
+
+    CONFIG_WRITE_WORD(MCCR4,
+	(CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+	(CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+        (CFG_EXTROM ? MCCR4_EXTROM : 0) |
+        (CFG_REGDIMM ? MCCR4_REGDIMM : 0) |
+	(CFG_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+	((CFG_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+	(CFG_DBUS_SIZE2 << MCCR4_DBUS_SIZE2_SHIFT) |
+	(((CFG_SDMODE_CAS_LAT <<4) | (CFG_SDMODE_WRAP <<3) |
+              (val ? 2 : 3)) << MCCR4_SDMODE_SHIFT)  |
+	(CFG_ACTORW << MCCR4_ACTTORW_SHIFT) |
+	(((CFG_BSTOPRE & 0x03c0) >> 6) <<MCCR4_BSTOPRE6TO9_SHIFT ));
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+    CONFIG_WRITE_WORD(MSAR1,
+	( (CFG_BANK0_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+	(((CFG_BANK1_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+	(((CFG_BANK2_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+	(((CFG_BANK3_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+    CONFIG_WRITE_WORD(EMSAR1,
+	( (CFG_BANK0_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+	(((CFG_BANK1_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+	(((CFG_BANK2_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+	(((CFG_BANK3_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+    CONFIG_WRITE_WORD(MSAR2,
+	( (CFG_BANK4_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+	(((CFG_BANK5_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+	(((CFG_BANK6_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+	(((CFG_BANK7_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+    CONFIG_WRITE_WORD(EMSAR2,
+	( (CFG_BANK4_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+	(((CFG_BANK5_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+	(((CFG_BANK6_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+	(((CFG_BANK7_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+    CONFIG_WRITE_WORD(MEAR1,
+	( (CFG_BANK0_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+	(((CFG_BANK1_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+	(((CFG_BANK2_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+	(((CFG_BANK3_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+    CONFIG_WRITE_WORD(EMEAR1,
+	( (CFG_BANK0_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+	(((CFG_BANK1_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+	(((CFG_BANK2_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+	(((CFG_BANK3_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+    CONFIG_WRITE_WORD(MEAR2,
+	( (CFG_BANK4_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+	(((CFG_BANK5_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+	(((CFG_BANK6_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+	(((CFG_BANK7_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+    CONFIG_WRITE_WORD(EMEAR2,
+	( (CFG_BANK4_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+	(((CFG_BANK5_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+	(((CFG_BANK6_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+	(((CFG_BANK7_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+
+    CONFIG_WRITE_BYTE(ODCR, CFG_ODCR);
+#ifdef CFG_DLL_MAX_DELAY
+	CONFIG_WRITE_BYTE(MIOCR1, CFG_DLL_MAX_DELAY);	/* needed to make DLL lock */
+#endif
+#if defined(CFG_DLL_EXTEND) && defined(CFG_PCI_HOLD_DEL)
+	CONFIG_WRITE_BYTE(PMCR2, CFG_DLL_EXTEND | CFG_PCI_HOLD_DEL);
+#endif
+#if defined(MIOCR2) && defined(CFG_SDRAM_DSCD)
+	CONFIG_WRITE_BYTE(MIOCR2, CFG_SDRAM_DSCD);	/* change memory input */
+#endif /* setup & hold time */
+
+    CONFIG_WRITE_BYTE(MBER,
+	 CFG_BANK0_ENABLE |
+	(CFG_BANK1_ENABLE << 1) |
+	(CFG_BANK2_ENABLE << 2) |
+	(CFG_BANK3_ENABLE << 3) |
+	(CFG_BANK4_ENABLE << 4) |
+	(CFG_BANK5_ENABLE << 5) |
+	(CFG_BANK6_ENABLE << 6) |
+	(CFG_BANK7_ENABLE << 7));
+
+#ifdef CFG_PGMAX
+    CONFIG_WRITE_BYTE(MPMR, CFG_PGMAX);
+#endif
+
+    /* ! Wait 200us before initialize other registers */
+    /*FIXME: write a decent udelay wait */
+    __asm__ __volatile__(
+      " mtctr	%0 \n \
+       0: bdnz	 0b\n"
+      :
+      : "r" (0x10000));
+
+   CONFIG_READ_WORD(MCCR1, val);
+   CONFIG_WRITE_WORD(MCCR1, val | MCCR1_MEMGO); /* set memory access going */
+   __asm__ __volatile__("eieio");
+
+#endif /* !CONFIG_MOUSSE && !CONFIG_BMW */
+}
+
+
+#ifdef CONFIG_MOUSSE
+#ifdef INCLUDE_MPC107_REPORT
+struct MPC107_s{
+    unsigned int iobase;
+    char desc[120];
+} MPC107Regs[] ={
+    {BMC_BASE+0x0,  "MPC107 Vendor/Device ID"},
+    {BMC_BASE+0x4,  "MPC107 PCI Command/Status Register"},
+    {BMC_BASE+0x8,  "MPC107 Revision"},
+    {BMC_BASE+0xC,  "MPC107 Cache Line Size"},
+    {BMC_BASE+0x10, "MPC107 LMBAR"},
+    {BMC_BASE+0x14, "MPC824x PCSR"},
+    {BMC_BASE+0xA8, "MPC824x PICR1"},
+    {BMC_BASE+0xAC, "MPC824x PICR2"},
+    {BMC_BASE+0x46, "MPC824x PACR"},
+    {BMC_BASE+0x310, "MPC824x ITWR"},
+    {BMC_BASE+0x300, "MPC824x OMBAR"},
+    {BMC_BASE+0x308, "MPC824x OTWR"},
+    {BMC_BASE+0x14, "MPC107 Peripheral Control and Status Register"},
+    {BMC_BASE+0x78, "MPC107 EUMBAR"},
+    {BMC_BASE+0xC0, "MPC107 Processor Bus Error Status"},
+    {BMC_BASE+0xC4, "MPC107 PCI Bus Error Status"},
+    {BMC_BASE+0xC8, "MPC107 Processor/PCI Error Address"},
+    {BMC_BASE+0xE0, "MPC107 AMBOR Register"},
+    {BMC_BASE+0xF0, "MPC107 MCCR1 Register"},
+    {BMC_BASE+0xF4, "MPC107 MCCR2 Register"},
+    {BMC_BASE+0xF8, "MPC107 MCCR3 Register"},
+    {BMC_BASE+0xFC, "MPC107 MCCR4 Register"}
+};
+#define N_MPC107_Regs	(sizeof(MPC107Regs)/sizeof(MPC107Regs[0]))
+#endif /* INCLUDE_MPC107_REPORT */
+#endif /* CONFIG_MOUSSE */
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r (void)
+{
+#ifdef CONFIG_MOUSSE
+#ifdef INCLUDE_MPC107_REPORT
+	unsigned int tmp = 0, i;
+#endif
+	/*
+	 * Initialize the EUMBBAR (Embedded Util Mem Block Base Addr Reg).
+	 * This is necessary before the EPIC, DMA ctlr, I2C ctlr, etc. can
+	 * be accessed.
+	 */
+
+#ifdef CONFIG_MPC8240			/* only on MPC8240 */
+	mpc824x_mpc107_setreg (EUMBBAR, EUMBBAR_VAL);
+	/* MOT/SPS: Issue #10002, PCI (FD Alias enable) */
+	mpc824x_mpc107_setreg (AMBOR, 0x000000C0);
+#endif
+
+
+#ifdef INCLUDE_MPC107_REPORT
+	/* Check MPC824x PCI Device and Vendor ID */
+	while ((tmp = mpc824x_mpc107_getreg (BMC_BASE)) != 0x31057) {
+		printf ("	MPC107: offset=0x%x, val = 0x%x\n",
+			BMC_BASE,
+			tmp);
+	}
+
+	for (i = 0; i < N_MPC107_Regs; i++) {
+		printf ("	0x%x/%s = 0x%x\n",
+			MPC107Regs[i].iobase,
+			MPC107Regs[i].desc,
+			mpc824x_mpc107_getreg (MPC107Regs[i].iobase));
+	}
+
+	printf ("IBAT0L = 0x%08X\n", mfspr (IBAT0L));
+	printf ("IBAT0U = 0x%08X\n", mfspr (IBAT0U));
+	printf ("IBAT1L = 0x%08X\n", mfspr (IBAT1L));
+	printf ("IBAT1U = 0x%08X\n", mfspr (IBAT1U));
+	printf ("IBAT2L = 0x%08X\n", mfspr (IBAT2L));
+	printf ("IBAT2U = 0x%08X\n", mfspr (IBAT2U));
+	printf ("IBAT3L = 0x%08X\n", mfspr (IBAT3L));
+	printf ("IBAT3U = 0x%08X\n", mfspr (IBAT3U));
+	printf ("DBAT0L = 0x%08X\n", mfspr (DBAT0L));
+	printf ("DBAT0U = 0x%08X\n", mfspr (DBAT0U));
+	printf ("DBAT1L = 0x%08X\n", mfspr (DBAT1L));
+	printf ("DBAT1U = 0x%08X\n", mfspr (DBAT1U));
+	printf ("DBAT2L = 0x%08X\n", mfspr (DBAT2L));
+	printf ("DBAT2U = 0x%08X\n", mfspr (DBAT2U));
+	printf ("DBAT3L = 0x%08X\n", mfspr (DBAT3L));
+	printf ("DBAT3U = 0x%08X\n", mfspr (DBAT3U));
+#endif /* INCLUDE_MPC107_REPORT */
+#endif /* CONFIG_MOUSSE */
+	return (0);
+}
diff --git a/cpu/mpc824x/drivers/i2c/i2c1.c b/cpu/mpc824x/drivers/i2c/i2c1.c
new file mode 100644
index 0000000..be6ec60
--- /dev/null
+++ b/cpu/mpc824x/drivers/i2c/i2c1.c
@@ -0,0 +1,1228 @@
+/*************************************************************
+ *
+ * Copyright @ Motorola, 1999
+ *
+ ************************************************************/
+#include <common.h>
+
+#ifdef CONFIG_HARD_I2C
+#include <i2c.h>
+#include "i2c_export.h"
+#include "i2c.h"
+
+#undef  I2CDBG0
+#undef  DEBUG
+
+/* Define a macro to use an optional application-layer print function, if
+ * one was passed to the I2C library during initialization.  If there was
+ * no function pointer passed, this protects against calling it.  Also define
+ * the global variable that holds the passed pointer.
+ */
+#define TIMEOUT (CFG_HZ/4)
+#define PRINT if ( app_print ) app_print
+static int (*app_print) (char *, ...);
+
+/******************* Internal to I2C Driver *****************/
+static unsigned int ByteToXmit = 0;
+static unsigned int XmitByte = 0;
+static unsigned char *XmitBuf = 0;
+static unsigned int XmitBufEmptyStop = 0;
+static unsigned int ByteToRcv = 0;
+static unsigned int RcvByte = 0;
+static unsigned char *RcvBuf = 0;
+static unsigned int RcvBufFulStop = 0;
+static unsigned int MasterRcvAddress = 0;
+
+/* Set by call to get_eumbbar during I2C_Initialize.
+ * This could be globally available to the I2C library, but there is
+ * an advantage to passing it as a parameter: it is already in a register
+ * and doesn't have to be loaded from memory.  Also, that is the way the
+ * I2C library was already implemented and I don't want to change it without
+ * a more detailed analysis.
+ * It is being set as a global variable in I2C_Initialize to hide it from
+ * the DINK application layer, because it is Kahlua-specific.  I think that
+ * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
+ * a Kahlua-specific library dealing with the embedded utilities memory block.
+ * Right now, get_eumbbar is defined in dink32/kahlua.s.  The other two are
+ * defined in dink32/drivers/i2c/i2c2.s.
+ */
+static unsigned int Global_eumbbar = 0;
+
+extern unsigned int load_runtime_reg (unsigned int eumbbar,
+				      unsigned int reg);
+
+extern unsigned int store_runtime_reg (unsigned int eumbbar,
+				       unsigned int reg, unsigned int val);
+
+/************************** API *****************/
+
+/* Application Program Interface (API) are the calls provided by the I2C
+ * library to upper layer applications (i.e., DINK) to access the Kahlua
+ * I2C bus interface.  The functions and values that are part of this API
+ * are declared in i2c_export.h.
+ */
+
+/*  Initialize I2C unit with the following:
+ *  driver's slave address
+ *  interrupt enabled
+ *  optional pointer to application layer print function
+ *
+ *  These parameters may be added:
+ *  desired clock rate
+ *  digital filter frequency sampling rate
+ *
+ *  This function must be called before I2C unit can be used.
+ */
+I2C_Status I2C_Initialize (unsigned char addr,
+			   I2C_INTERRUPT_MODE en_int,
+			   int (*p) (char *, ...))
+{
+	I2CStatus status;
+
+	/* establish the pointer, if there is one, to the application's "printf" */
+	app_print = p;
+
+	/* If this is the first call, get the embedded utilities memory block
+	 * base address.  I'm not sure what to do about error handling here:
+	 * if a non-zero value is returned, accept it.
+	 */
+	if (Global_eumbbar == 0)
+		Global_eumbbar = get_eumbbar ();
+	if (Global_eumbbar == 0) {
+		PRINT ("I2C_Initialize: can't find EUMBBAR\n");
+		return I2C_ERROR;
+	}
+
+	/* validate the I2C address */
+	if (addr & 0x80) {
+		PRINT ("I2C_Initialize, I2C address invalid:  %d 0x%x\n",
+			   (unsigned int) addr, (unsigned int) addr);
+		return I2C_ERROR;
+	}
+
+	/* Call the internal I2C library function to perform work.
+	 * Accept the default frequency sampling rate (no way to set it currently,
+	 * via I2C_Init) and set the clock frequency to something reasonable.
+	 */
+	status = I2C_Init (Global_eumbbar, (unsigned char) 0x31, addr, en_int);
+	if (status != I2CSUCCESS) {
+		PRINT ("I2C_Initialize: error in initiation\n");
+		return I2C_ERROR;
+	}
+
+	/* all is well */
+	return I2C_SUCCESS;
+}
+
+
+/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
+ * are implemented.  Both are only in polling mode.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * i2c_addr is the I2C address of the slave device
+ * data_addr is the address of the data on the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ *        I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ *        I2C_RESTART, this is a continuation of existing transaction
+ */
+I2C_Status I2C_do_transaction ( I2C_INTERRUPT_MODE en_int,
+				I2C_TRANSACTION_MODE act,
+				unsigned char i2c_addr,
+				unsigned char data_addr,
+				int len,
+				char *buffer,
+				I2C_STOP_MODE stop,
+				int retry, I2C_RESTART_MODE rsta)
+{
+	I2C_Status status;
+	unsigned char data_addr_buffer[1];
+
+#if 1
+/* This is a temporary work-around.  The I2C library breaks the protocol
+ * if it attempts to handle a data transmission in more than one
+ * transaction, so the data address and the actual data bytes are put
+ * into a single buffer before sending it to the library internal functions.
+ * The problem is related to being able to restart a transaction without
+ * sending the I2C device address or repeating the data address.  It may take
+ * a day or two to sort it all out, so I'll have to get back to it later.
+ * Look at I2C_Start to see about using some status flags (I'm not sure that
+ * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic
+ * in the library is insufficient) to control correct handling of the protocol.
+ */
+	unsigned char dummy_buffer[257];
+
+	if (act == I2C_MASTER_XMIT) {
+		int i;
+
+		if (len > 256)
+			return I2C_ERROR;
+		for (i = 1; i <= len; i++)
+			dummy_buffer[i] = buffer[i - 1];
+		dummy_buffer[0] = data_addr;
+		status = I2C_do_buffer (en_int, act, i2c_addr, 1 + len,
+					dummy_buffer, stop, retry, rsta);
+		if (status != I2C_SUCCESS) {
+			PRINT ("I2C_do_transaction: can't perform data transfer\n");
+			return I2C_ERROR;
+		}
+		return I2C_SUCCESS;
+	}
+#endif	/* end of temp work-around */
+
+	/* validate requested transaction type */
+	if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) {
+		PRINT ("I2C_do_transaction, invalid transaction request:  %d\n",
+			act);
+		return I2C_ERROR;
+	}
+
+	/* range check the I2C address */
+	if (i2c_addr & 0x80) {
+		PRINT ("I2C_do_transaction, I2C address out of range:  %d 0x%x\n",
+			(unsigned int) i2c_addr, (unsigned int) i2c_addr);
+		return I2C_ERROR;
+	} else {
+		data_addr_buffer[0] = data_addr;
+	}
+
+	/*
+         * We first have to contact the slave device and transmit the
+         * data address. Be careful about the STOP and restart stuff.
+         * We don't want to signal STOP after sending the data
+         * address, but this could be a continuation if the
+         * application didn't release the bus after the previous
+         * transaction, by not sending a STOP after it.
+	 */
+	status = I2C_do_buffer (en_int, I2C_MASTER_XMIT, i2c_addr, 1,
+				data_addr_buffer, I2C_NO_STOP, retry, rsta);
+	if (status != I2C_SUCCESS) {
+		PRINT ("I2C_do_transaction: can't send data address for read\n");
+		return I2C_ERROR;
+	}
+
+	/* The data transfer will be a continuation. */
+	rsta = I2C_RESTART;
+
+	/* now handle the user data */
+	status = I2C_do_buffer (en_int, act, i2c_addr, len,
+				buffer, stop, retry, rsta);
+	if (status != I2C_SUCCESS) {
+		PRINT ("I2C_do_transaction: can't perform data transfer\n");
+		return I2C_ERROR;
+	}
+
+	/* all is well */
+	return I2C_SUCCESS;
+}
+
+/* This function performs the work for I2C_do_transaction.  The work is
+ * split into this function to enable I2C_do_transaction to first transmit
+ * the data address to the I2C slave device without putting the data address
+ * into the first byte of the buffer.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * i2c_addr is the I2C address of the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ *        I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ *        I2C_RESTART, this is a continuation of existing transaction
+ */
+static I2C_Status I2C_do_buffer (I2C_INTERRUPT_MODE en_int,
+				 I2C_TRANSACTION_MODE act,
+				 unsigned char i2c_addr,
+				 int len,
+				 unsigned char *buffer,
+				 I2C_STOP_MODE stop,
+				 int retry, I2C_RESTART_MODE rsta)
+{
+	I2CStatus rval;
+	unsigned int dev_stat;
+
+	if (act == I2C_MASTER_RCV) {
+		/* set up for master-receive transaction */
+		rval = I2C_get (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
+	} else {
+		/* set up for master-transmit transaction */
+		rval = I2C_put (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
+	}
+
+	/* validate the setup */
+	if (rval != I2CSUCCESS) {
+		dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
+		PRINT ("Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat);
+		I2C_Stop (Global_eumbbar);
+		return I2C_ERROR;
+	}
+
+	if (en_int == 1) {
+		/* this should not happen, no interrupt handling yet */
+		return I2C_SUCCESS;
+	}
+
+	/* this performs the polling action, when the transfer is completed,
+	 * the status returned from I2C_Timer_Event will be I2CBUFFFULL or
+	 * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the
+	 * transaction is not yet complete, anything else is an error.
+	 */
+	while (rval == I2CSUCCESS || rval == I2CADDRESS) {
+		int timeval = get_timer (0);
+
+		/* poll the device until something happens */
+		do {
+			rval = I2C_Timer_Event (Global_eumbbar, 0);
+		}
+		while (rval == I2CNOEVENT && get_timer (timeval) < TIMEOUT);
+
+		/* check for error condition */
+		if (rval == I2CSUCCESS   ||
+		    rval == I2CBUFFFULL  ||
+		    rval == I2CBUFFEMPTY ||
+		    rval == I2CADDRESS) {
+			;	/* do nothing */
+		} else {
+			/* report the error condition */
+			dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
+			PRINT ("Error(I2C_do_buffer):  code(0x%08x), status(0x%08x)\n",
+				   rval, dev_stat);
+			return I2C_ERROR;
+		}
+	}
+
+	/* all is well */
+	return I2C_SUCCESS;
+}
+
+/**
+ * Note:
+ *
+ * In all following functions,
+ * the caller shall pass the configured embedded utility memory
+ * block base, EUMBBAR.
+ **/
+
+/***********************************************************
+ * function: I2C_put
+ *
+ * description:
+   Send a buffer of data to the intended rcv_addr.
+ * If stop_flag is set, after the whole buffer
+ * is sent, generate a STOP signal provided that the
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the master performing transmitting. If
+ * no STOP signal is generated at the end of current
+ * transaction, the master can generate a START signal
+ * to another slave addr.
+ *
+ * note: this is master xmit API
+ *********************************************************/
+static I2CStatus I2C_put (unsigned int eumbbar, unsigned char rcv_addr,	/* receiver's address */
+	  unsigned char *buffer_ptr,	/* pointer of data to be sent */
+	  unsigned int length,	/* number of byte of in the buffer */
+	  unsigned int stop_flag,	/* 1 - signal STOP when buffer is empty
+					 * 0 - no STOP signal when buffer is empty
+					 */
+	  unsigned int is_cnt)
+{					/* 1 - this is a restart, don't check MBB
+					 * 0 - this is a new start, check MBB
+					 */
+	if (buffer_ptr == 0 || length == 0) {
+		return I2CERROR;
+	}
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__);
+#endif
+
+	XmitByte = 0;
+	ByteToXmit = length;
+	XmitBuf = buffer_ptr;
+	XmitBufEmptyStop = stop_flag;
+
+	RcvByte = 0;
+	ByteToRcv = 0;
+	RcvBuf = 0;
+
+	/* we are the master, start transaction */
+	return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt);
+}
+
+/***********************************************************
+ * function: I2C_get
+ *
+ * description:
+ * Receive a buffer of data from the desired sender_addr
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the master performing receiving. If no STOP signal
+ * is generated, the master can generate a START signal
+ * to another slave addr.
+ *
+ * note: this is master receive API
+ **********************************************************/
+static I2CStatus I2C_get (unsigned int eumbbar, unsigned char rcv_from,	/* sender's address */
+		  unsigned char *buffer_ptr,	/* pointer of receiving buffer */
+		  unsigned int length,	/* length of the receiving buffer */
+		  unsigned int stop_flag,	/* 1 - signal STOP when buffer is full
+						 * 0 - no STOP signal when buffer is full
+						 */
+		  unsigned int is_cnt)
+{						/* 1 - this is a restart, don't check MBB
+						 * 0 - this is a new start, check MBB
+						 */
+	if (buffer_ptr == 0 || length == 0) {
+		return I2CERROR;
+	}
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__);
+#endif
+
+	RcvByte = 0;
+	ByteToRcv = length;
+	RcvBuf = buffer_ptr;
+	RcvBufFulStop = stop_flag;
+
+	XmitByte = 0;
+	ByteToXmit = 0;
+	XmitBuf = 0;
+
+	/* we are the master, start the transaction */
+	return I2C_Start (eumbbar, rcv_from, RCV, is_cnt);
+
+}
+
+#if 0	/* turn off dead code */
+/*********************************************************
+ * function: I2C_write
+ *
+ * description:
+ * Send a buffer of data to the requiring master.
+ * If stop_flag is set, after the whole buffer is sent,
+ * generate a STOP signal provided that the requiring
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the slave performing transmitting.
+ *
+ * Note: this is slave xmit API.
+ *
+ *       due to the current Kahlua design, slave transmitter
+ *       shall not signal STOP since there is no way
+ *       for master to detect it, causing I2C bus hung.
+ *
+ *       For the above reason, the stop_flag is always
+ *       set, i.e., 0.
+ *
+ *       programmer shall use the timer on Kahlua to
+ *       control the interval of data byte at the
+ *       master side.
+ *******************************************************/
+static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of data to be sent */
+		unsigned int length,	/* number of byte of in the buffer */
+		unsigned int stop_flag)
+{					/* 1 - signal STOP when buffer is empty
+					 * 0 - no STOP signal when buffer is empty
+					 */
+	if (buffer_ptr == 0 || length == 0) {
+		return I2CERROR;
+	}
+
+	XmitByte = 0;
+	ByteToXmit = length;
+	XmitBuf = buffer_ptr;
+	XmitBufEmptyStop = 0;	/* in order to avoid bus hung, ignored the user's stop_flag */
+
+	RcvByte = 0;
+	ByteToRcv = 0;
+	RcvBuf = 0;
+
+	/* we are the slave, just wait for being called, or pull */
+	/* I2C_Timer_Event( eumbbar ); */
+}
+
+/******************************************************
+ * function: I2C_read
+ *
+ * description:
+ * Receive a buffer of data from the sending master.
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the slave performing receiving.
+ *
+ * note: this is slave receive API
+ ****************************************************/
+static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of receiving buffer */
+		   unsigned int length,	/* length of the receiving buffer */
+		   unsigned int stop_flag)
+{					/* 1 - signal STOP when buffer is full
+					 * 0 - no STOP signal when buffer is full
+					 */
+	if (buffer_ptr == 0 || length == 0) {
+		return I2CERROR;
+	}
+
+	RcvByte = 0;
+	ByteToRcv = length;
+	RcvBuf = buffer_ptr;
+	RcvBufFulStop = stop_flag;
+
+	XmitByte = 0;
+	ByteToXmit = 0;
+	XmitBuf = 0;
+
+	/* wait for master to call us, or poll */
+	/* I2C_Timer_Event( eumbbar ); */
+}
+#endif	/* turn off dead code */
+
+/*********************************************************
+ * function: I2c_Timer_Event
+ *
+ * description:
+ * if interrupt is not used, this is the timer event handler.
+ * After each fixed time interval, this function can be called
+ * to check the I2C status and call appropriate function to
+ * handle the status event.
+ ********************************************************/
+static I2CStatus I2C_Timer_Event (unsigned int eumbbar,
+				  I2CStatus (*handler) (unsigned int))
+{
+	I2C_STAT stat;
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__);
+#endif
+
+	stat = I2C_Get_Stat (eumbbar);
+
+	if (stat.mif == 1) {
+		if (handler == 0) {
+			return I2C_ISR (eumbbar);
+		} else {
+			return (*handler) (eumbbar);
+		}
+	}
+
+	return I2CNOEVENT;
+}
+
+
+/****************** Device I/O function *****************/
+
+/******************************************************
+ * function: I2C_Start
+ *
+ * description: Generate a START signal in the desired mode.
+ *              I2C is the master.
+ *
+ *              Return I2CSUCCESS if no error.
+ *
+ * note:
+ ****************************************************/
+static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr,	/* address of the receiver */
+			I2C_MODE mode,	/* XMIT(1) - put (write)
+					 * RCV(0)  - get (read)
+					 */
+			unsigned int is_cnt)
+{					/* 1 - this is a restart, don't check MBB
+					 * 0 - this is a new start
+					 */
+	unsigned int tmp = 0;
+	I2C_STAT stat;
+	I2C_CTRL ctrl;
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__,
+		   __LINE__, slave_addr, mode, is_cnt);
+#endif
+
+	ctrl = I2C_Get_Ctrl (eumbbar);
+
+	/* first make sure I2C has been initialized */
+	if (ctrl.men == 0) {
+		return I2CERROR;
+	}
+
+	/* next make sure bus is idle */
+	stat = I2C_Get_Stat (eumbbar);
+
+	if (is_cnt == 0 && stat.mbb == 1) {
+		/* sorry, we lost */
+		return I2CBUSBUSY;
+	} else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) {
+		/* sorry, we lost the bus */
+		return I2CALOSS;
+	}
+
+
+	/* OK, I2C is enabled and we have the bus */
+
+	/* prepare to write the slave address */
+	ctrl.msta = 1;
+	ctrl.mtx = 1;
+	ctrl.txak = 0;
+	ctrl.rsta = is_cnt;		/* set the repeat start bit */
+	I2C_Set_Ctrl (eumbbar, ctrl);
+
+	/* write the slave address and xmit/rcv mode bit */
+	tmp = load_runtime_reg (eumbbar, I2CDR);
+	tmp = (tmp & 0xffffff00) |
+	      ((slave_addr & 0x007f) << 1) |
+	      (mode == XMIT ? 0x0 : 0x1);
+	store_runtime_reg (eumbbar, I2CDR, tmp);
+
+	if (mode == RCV) {
+		MasterRcvAddress = 1;
+	} else {
+		MasterRcvAddress = 0;
+	}
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__);
+#endif
+
+	/* wait for the interrupt or poll  */
+	return I2CSUCCESS;
+}
+
+/***********************************************************
+ * function: I2c_Stop
+ *
+ * description: Generate a STOP signal to terminate the master
+ *              transaction.
+ *              return I2CSUCCESS
+ *
+ **********************************************************/
+static I2CStatus I2C_Stop (unsigned int eumbbar)
+{
+	I2C_CTRL ctrl;
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__);
+#endif
+
+	ctrl = I2C_Get_Ctrl (eumbbar);
+	ctrl.msta = 0;
+	I2C_Set_Ctrl (eumbbar, ctrl);
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__);
+#endif
+
+	return I2CSUCCESS;
+}
+
+/****************************************************
+ * function: I2C_Master_Xmit
+ *
+ * description: Master sends one byte of data to
+ *              slave target
+ *
+ *              return I2CSUCCESS if the byte transmitted.
+ *              Otherwise no-zero
+ *
+ * Note: condition must meet when this function is called:
+ *       I2CSR(MIF) == 1 && I2CSR(MCF)  == 1  && I2CSR(RXAK) == 0
+ *       I2CCR(MSTA) == 1  && I2CCR(MTX) == 1
+ *
+ ***************************************************/
+static I2CStatus I2C_Master_Xmit (unsigned int eumbbar)
+{
+	unsigned int val;
+
+	if (ByteToXmit > 0) {
+
+		if (ByteToXmit == XmitByte) {
+			/* all xmitted */
+			ByteToXmit = 0;
+
+			if (XmitBufEmptyStop == 1) {
+				I2C_Stop (eumbbar);
+			}
+
+			return I2CBUFFEMPTY;
+
+		}
+#ifdef I2CDBG0
+		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
+			   *(XmitBuf + XmitByte));
+#endif
+
+		val = *(XmitBuf + XmitByte);
+		val &= 0x000000ff;
+		store_runtime_reg (eumbbar, I2CDR, val);
+		XmitByte++;
+
+		return I2CSUCCESS;
+
+	}
+
+	return I2CBUFFEMPTY;
+}
+
+/***********************************************
+ * function: I2C_Master_Rcv
+ *
+ * description: master reads one byte data
+ *              from slave source
+ *
+ *              return I2CSUCCESS if no error
+ *
+ * Note: condition must meet when this function is called:
+ *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
+ *       I2CCR(MSTA) == 1 && I2CCR(MTX) == 0
+ *
+ ***********************************************/
+static I2CStatus I2C_Master_Rcv (unsigned int eumbbar)
+{
+	I2C_CTRL ctrl;
+	unsigned int val;
+
+	if (ByteToRcv > 0) {
+
+		if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) {
+			/* master requests more than or equal to 2 bytes
+			 * we are reading 2nd to last byte
+			 */
+
+			/* we need to set I2CCR(TXAK) to generate a STOP */
+			ctrl = I2C_Get_Ctrl (eumbbar);
+			ctrl.txak = 1;
+			I2C_Set_Ctrl (eumbbar, ctrl);
+
+			/* Kahlua will automatically generate a STOP
+			 * next time a transaction happens
+			 */
+
+			/* note: the case of master requesting one byte is
+			 *       handled in I2C_ISR
+			 */
+		}
+
+		/* generat a STOP before reading the last byte */
+		if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) {
+			I2C_Stop (eumbbar);
+		}
+
+		val = load_runtime_reg (eumbbar, I2CDR);
+		*(RcvBuf + RcvByte) = val & 0xFF;
+
+#ifdef I2CDBG0
+		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
+			   *(RcvBuf + RcvByte));
+#endif
+
+		RcvByte++;
+
+		if (ByteToRcv == RcvByte) {
+			ByteToRcv = 0;
+
+			return I2CBUFFFULL;
+		}
+
+		return I2CSUCCESS;
+	}
+
+	return I2CBUFFFULL;
+
+}
+
+/****************************************************
+ * function: I2C_Slave_Xmit
+ *
+ * description: Slave sends one byte of data to
+ *              requesting destination
+ *
+ *        return SUCCESS if the byte transmitted. Otherwise
+ *        No-zero
+ *
+ * Note: condition must meet when this function is called:
+ *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&  I2CSR(RXAK) = 0
+ *       I2CCR(MSTA) == 0  && I2CCR(MTX) == 1
+ *
+ ***************************************************/
+static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar)
+{
+	unsigned int val;
+
+	if (ByteToXmit > 0) {
+
+		if (ByteToXmit == XmitByte) {
+			/* no more data to send */
+			ByteToXmit = 0;
+
+			/*
+                         * do not toggle I2CCR(MTX). Doing so will
+                         * cause bus-hung since current Kahlua design
+                         * does not give master a way to detect slave
+                         * stop. It is always a good idea for master
+                         * to use timer to prevent the long long
+                         * delays
+			 */
+
+			return I2CBUFFEMPTY;
+		}
+#ifdef I2CDBG
+		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
+			   *(XmitBuf + XmitByte));
+#endif
+
+		val = *(XmitBuf + XmitByte);
+		val &= 0x000000ff;
+		store_runtime_reg (eumbbar, I2CDR, val);
+		XmitByte++;
+
+		return I2CSUCCESS;
+	}
+
+	return I2CBUFFEMPTY;
+}
+
+/***********************************************
+ * function: I2C_Slave_Rcv
+ *
+ * description: slave reads one byte data
+ *              from master source
+ *
+ *              return I2CSUCCESS if no error otherwise non-zero
+ *
+ * Note: condition must meet when this function is called:
+ *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
+ *       I2CCR(MSTA) == 0 && I2CCR(MTX)  = 0
+ *
+ ***********************************************/
+static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar)
+{
+	unsigned int val;
+	I2C_CTRL ctrl;
+
+	if (ByteToRcv > 0) {
+		val = load_runtime_reg (eumbbar, I2CDR);
+		*(RcvBuf + RcvByte) = val & 0xff;
+#ifdef I2CDBG
+		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
+			   *(RcvBuf + RcvByte));
+#endif
+		RcvByte++;
+
+		if (ByteToRcv == RcvByte) {
+			if (RcvBufFulStop == 1) {
+				/* all done */
+				ctrl = I2C_Get_Ctrl (eumbbar);
+				ctrl.txak = 1;
+				I2C_Set_Ctrl (eumbbar, ctrl);
+			}
+
+			ByteToRcv = 0;
+			return I2CBUFFFULL;
+		}
+
+		return I2CSUCCESS;
+	}
+
+	return I2CBUFFFULL;
+}
+
+/****************** Device Control Function *************/
+
+/*********************************************************
+ * function: I2C_Init
+ *
+ * description: Initialize I2C unit with desired frequency divider,
+ *              master's listening address, with interrupt enabled
+ *              or disabled.
+ *
+ * note:
+ ********************************************************/
+static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr,	/* frequency divider */
+		   unsigned char slave_addr,	/* driver's address used for receiving */
+		   unsigned int en_int)
+{						/* 1 - enable I2C interrupt
+						 * 0 - disable I2C interrup
+						 */
+	I2C_CTRL ctrl;
+	unsigned int tmp;
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__);
+#endif
+
+	ctrl = I2C_Get_Ctrl (eumbbar);
+	/* disable the I2C module before we change everything */
+	ctrl.men = 0;
+	I2C_Set_Ctrl (eumbbar, ctrl);
+
+	/* set the frequency diver */
+	tmp = load_runtime_reg (eumbbar, I2CFDR);
+	tmp = (tmp & 0xffffffc0) | (fdr & 0x3f);
+	store_runtime_reg (eumbbar, I2CFDR, tmp);
+
+	/* Set our listening (slave) address */
+	tmp = load_runtime_reg (eumbbar, I2CADR);
+	tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1);
+	store_runtime_reg (eumbbar, I2CADR, tmp);
+
+	/* enable I2C with desired interrupt setting */
+	ctrl.men = 1;
+	ctrl.mien = en_int & 0x1;
+	I2C_Set_Ctrl (eumbbar, ctrl);
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__);
+#endif
+
+	return I2CSUCCESS;
+
+}
+
+/*****************************************
+ * function I2c_Get_Stat
+ *
+ * description: Query I2C Status, i.e., read I2CSR
+ *
+ ****************************************/
+static I2C_STAT I2C_Get_Stat (unsigned int eumbbar)
+{
+	unsigned int temp;
+	I2C_STAT stat;
+
+	temp = load_runtime_reg (eumbbar, I2CSR);
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp);
+#endif
+
+	stat.rsrv0 = (temp & 0xffffff00) >> 8;
+	stat.mcf   = (temp & 0x00000080) >> 7;
+	stat.maas  = (temp & 0x00000040) >> 6;
+	stat.mbb   = (temp & 0x00000020) >> 5;
+	stat.mal   = (temp & 0x00000010) >> 4;
+	stat.rsrv1 = (temp & 0x00000008) >> 3;
+	stat.srw   = (temp & 0x00000004) >> 2;
+	stat.mif   = (temp & 0x00000002) >> 1;
+	stat.rxak  = (temp & 0x00000001);
+	return stat;
+}
+
+/*********************************************
+ * function: I2c_Set_Ctrl
+ *
+ * description: Change I2C Control bits,
+ *              i.e., write to I2CCR
+ *
+ ********************************************/
+static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl)
+{						/* new control value */
+	unsigned int temp = load_runtime_reg (eumbbar, I2CCR);
+
+	temp &= 0xffffff03;
+	temp |= ((ctrl.men  & 0x1) << 7);
+	temp |= ((ctrl.mien & 0x1) << 6);
+	temp |= ((ctrl.msta & 0x1) << 5);
+	temp |= ((ctrl.mtx  & 0x1) << 4);
+	temp |= ((ctrl.txak & 0x1) << 3);
+	temp |= ((ctrl.rsta & 0x1) << 2);
+#ifdef I2CDBG0
+	PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp);
+#endif
+	store_runtime_reg (eumbbar, I2CCR, temp);
+
+}
+
+/*****************************************
+ * function: I2C_Get_Ctrl
+ *
+ * description: Query I2C Control bits,
+ *              i.e., read I2CCR
+ *****************************************/
+static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar)
+{
+	union {
+		I2C_CTRL ctrl;
+		unsigned int temp;
+	} s;
+
+	s.temp = load_runtime_reg (eumbbar, I2CCR);
+#ifdef I2CDBG0
+	PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp);
+#endif
+
+	return s.ctrl;
+}
+
+
+/****************************************
+ * function: I2C_Slave_Addr
+ *
+ * description: Process slave address phase.
+ *              return I2CSUCCESS if no error
+ *
+ * note: Precondition for calling this function:
+ *       I2CSR(MIF) == 1 &&
+ *       I2CSR(MAAS) == 1
+ ****************************************/
+static I2CStatus I2C_Slave_Addr (unsigned int eumbbar)
+{
+	I2C_STAT stat = I2C_Get_Stat (eumbbar);
+	I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar);
+
+	if (stat.srw == 1) {
+		/* we are asked to xmit */
+		ctrl.mtx = 1;
+		I2C_Set_Ctrl (eumbbar, ctrl);	/* set MTX */
+		return I2C_Slave_Xmit (eumbbar);
+	}
+
+	/* we are asked to receive data */
+	ctrl.mtx = 0;
+	I2C_Set_Ctrl (eumbbar, ctrl);
+	(void) load_runtime_reg (eumbbar, I2CDR);	/* do a fake read to start */
+
+	return I2CADDRESS;
+}
+
+/***********************************************
+ * function: I2C_ISR
+ *
+ * description: I2C Interrupt service routine
+ *
+ * note: Precondition:
+ *      I2CSR(MIF) == 1
+ **********************************************/
+static I2CStatus I2C_ISR (unsigned int eumbbar)
+{
+	I2C_STAT stat;
+	I2C_CTRL ctrl;
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__);
+#endif
+
+	stat = I2C_Get_Stat (eumbbar);
+	ctrl = I2C_Get_Ctrl (eumbbar);
+
+	/* clear MIF */
+	stat.mif = 0;
+
+	/* Now let see what kind of event this is */
+	if (stat.mcf == 1) {
+		/* transfer compete */
+
+		/* clear the MIF bit */
+		I2C_Set_Stat (eumbbar, stat);
+
+		if (ctrl.msta == 1) {
+			/* master */
+			if (ctrl.mtx == 1) {
+				/* check if this is the address phase for master receive */
+				if (MasterRcvAddress == 1) {
+					/* Yes, it is the address phase of master receive */
+					ctrl.mtx = 0;
+					/* now check how much we want to receive */
+					if (ByteToRcv == 1 && RcvBufFulStop == 1) {
+						ctrl.txak = 1;
+					}
+
+					I2C_Set_Ctrl (eumbbar, ctrl);
+					(void) load_runtime_reg (eumbbar, I2CDR);	/* fake read first */
+
+					MasterRcvAddress = 0;
+					return I2CADDRESS;
+
+				}
+
+				/* master xmit */
+				if (stat.rxak == 0) {
+					/* slave has acknowledged */
+					return I2C_Master_Xmit (eumbbar);
+				}
+
+				/* slave has not acknowledged yet, generate a STOP */
+				if (XmitBufEmptyStop == 1) {
+					ctrl.msta = 0;
+					I2C_Set_Ctrl (eumbbar, ctrl);
+				}
+
+				return I2CSUCCESS;
+			}
+
+			/* master receive */
+			return I2C_Master_Rcv (eumbbar);
+		}
+
+		/* slave */
+		if (ctrl.mtx == 1) {
+			/* slave xmit */
+			if (stat.rxak == 0) {
+				/* master has acknowledged */
+				return I2C_Slave_Xmit (eumbbar);
+			}
+
+			/* master has not acknowledged, wait for STOP */
+			/* do nothing for preventing bus from hung */
+			return I2CSUCCESS;
+		}
+
+		/* slave rcv */
+		return I2C_Slave_Rcv (eumbbar);
+
+	} else if (stat.maas == 1) {
+		/* received a call from master */
+
+		/* clear the MIF bit */
+		I2C_Set_Stat (eumbbar, stat);
+
+		/* master is calling us, process the address phase */
+		return I2C_Slave_Addr (eumbbar);
+	} else {
+		/* has to be arbitration lost */
+		stat.mal = 0;
+		I2C_Set_Stat (eumbbar, stat);
+
+		ctrl.msta = 0;			/* return to receive mode */
+		I2C_Set_Ctrl (eumbbar, ctrl);
+	}
+
+	return I2CSUCCESS;
+
+}
+
+/******************************************************
+ * function: I2C_Set_Stat
+ *
+ * description: modify the I2CSR
+ *
+ *****************************************************/
+static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat)
+{
+	union {
+		unsigned int val;
+		I2C_STAT stat;
+	} s_tmp;
+	union {
+		unsigned int val;
+		I2C_STAT stat;
+	} s;
+
+	s.val = load_runtime_reg (eumbbar, I2CSR);
+	s.val &= 0xffffff08;
+	s_tmp.stat = stat;
+	s.val |= (s_tmp.val & 0xf7);
+
+#ifdef I2CDBG0
+	PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val);
+#endif
+
+	store_runtime_reg (eumbbar, I2CSR, s.val);
+
+}
+
+/******************************************************
+ * The following are routines to glue the rest of
+ * U-Boot to the Sandpoint I2C driver.
+ *****************************************************/
+
+void i2c_init (int speed, int slaveadd)
+{
+#ifdef DEBUG
+	I2C_Initialize (0x7f, 0, (void *) printf);
+#else
+	I2C_Initialize (0x7f, 0, 0);
+#endif
+}
+
+int i2c_probe (uchar chip)
+{
+	int tmp;
+
+	/*
+	 * Try to read the first location of the chip.  The underlying
+	 * driver doesn't appear to support sending just the chip address
+	 * and looking for an <ACK> back.
+	 */
+	udelay(10000);
+	return i2c_read (chip, 0, 1, (char *)&tmp, 1);
+}
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+	I2CStatus status;
+	uchar xaddr[4];
+
+	if (alen > 0) {
+		xaddr[0] = (addr >> 24) & 0xFF;
+		xaddr[1] = (addr >> 16) & 0xFF;
+		xaddr[2] = (addr >> 8) & 0xFF;
+		xaddr[3] = addr & 0xFF;
+
+		status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen,
+					&xaddr[4 - alen], I2C_NO_STOP, 1,
+					I2C_NO_RESTART);
+		if (status != I2C_SUCCESS) {
+			PRINT ("i2c_read: can't send data address for read\n");
+			return 1;
+		}
+	}
+
+	/* The data transfer will be a continuation. */
+	status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len,
+				buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART :
+				I2C_NO_RESTART));
+
+	if (status != I2C_SUCCESS) {
+		PRINT ("i2c_read: can't perform data transfer\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+	I2CStatus status;
+	unsigned char dummy_buffer[I2C_RXTX_LEN + 2];
+	int i;
+
+	dummy_buffer[0] = addr & 0xFF;
+	if (alen == 2)
+		dummy_buffer[1] = (addr >> 8) & 0xFF;
+	for (i = 0; i < len; i++)
+		dummy_buffer[i + alen] = buffer[i];
+
+	status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len,
+				dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART);
+
+#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS
+	udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
+#endif
+	if (status != I2C_SUCCESS) {
+		PRINT ("i2c_write: can't perform data transfer\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
+{
+	char buf[1];
+
+	i2c_init (0, 0);
+
+	i2c_read (i2c_addr, reg, 1, buf, 1);
+
+	return (buf[0]);
+}
+
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
+{
+	i2c_init (0, 0);
+
+	i2c_write (i2c_addr, reg, 1, &val, 1);
+}
+
+#endif	/* CONFIG_HARD_I2C */
diff --git a/cpu/mpc824x/pci.c b/cpu/mpc824x/pci.c
new file mode 100644
index 0000000..7e3c4c3
--- /dev/null
+++ b/cpu/mpc824x/pci.c
@@ -0,0 +1,78 @@
+/*
+ * arch/ppc/kernel/mpc10x_common.c
+ *
+ * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
+ * Mem ctlr, EPIC, etc.
+ *
+ * Author: Mark A. Greer
+ *         mgreer@mvista.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * 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.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <mpc824x.h>
+
+void pci_mpc824x_init (struct pci_controller *hose)
+{
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	/* System memory space */
+	pci_set_region(hose->regions + 0,
+		       CHRP_PCI_MEMORY_BUS,
+		       CHRP_PCI_MEMORY_PHYS,
+		       CHRP_PCI_MEMORY_SIZE,
+		       PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+	/* PCI memory space */
+	pci_set_region(hose->regions + 1,
+		       CHRP_PCI_MEM_BUS,
+		       CHRP_PCI_MEM_PHYS,
+		       CHRP_PCI_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* ISA/PCI memory space */
+	pci_set_region(hose->regions + 2,
+		       CHRP_ISA_MEM_BUS,
+		       CHRP_ISA_MEM_PHYS,
+		       CHRP_ISA_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* PCI I/O space */
+	pci_set_region(hose->regions + 3,
+		       CHRP_PCI_IO_BUS,
+		       CHRP_PCI_IO_PHYS,
+		       CHRP_PCI_IO_SIZE,
+		       PCI_REGION_IO);
+
+	/* ISA/PCI I/O space */
+	pci_set_region(hose->regions + 4,
+		       CHRP_ISA_IO_BUS,
+		       CHRP_ISA_IO_PHYS,
+		       CHRP_ISA_IO_SIZE,
+		       PCI_REGION_IO);
+
+	hose->region_count = 5;
+
+	pci_setup_indirect(hose,
+			   CHRP_REG_ADDR,
+			   CHRP_REG_DATA);
+
+	pci_register_hose(hose);
+
+	hose->last_busno = pci_hose_scan(hose);
+}
+
+#endif
diff --git a/cpu/mpc824x/start.S b/cpu/mpc824x/start.S
new file mode 100644
index 0000000..bd9706d
--- /dev/null
+++ b/cpu/mpc824x/start.S
@@ -0,0 +1,835 @@
+/*
+ *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2000,2001,2002 Wolfgang Denk <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
+ */
+
+/* U-Boot - Startup Code for PowerPC based Embedded Boards
+ *
+ *
+ * The processor starts at 0x00000100 and the code is executed
+ * from flash. The code is organized to be at an other address
+ * in memory, but as long we don't jump around before relocating.
+ * board_init lies at a quite high address and when the cpu has
+ * jumped there, everything is ok.
+ * This works because the cpu gives the FLASH (CS0) the whole
+ * address space at startup, and board_init lies as a echo of
+ * the flash somewhere up there in the memorymap.
+ *
+ * board_init will change CS0 to be positioned at the correct
+ * address and (s)dram will be positioned at address 0
+ */
+#include <config.h>
+#include <mpc824x.h>
+#include <version.h>
+
+#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef CONFIG_IDENT_STRING
+#define CONFIG_IDENT_STRING ""
+#endif
+
+/* We don't want the MMU yet.
+*/
+#undef	MSR_KERNEL
+/* FP, Machine Check and Recoverable Interr. */
+#define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+	START_GOT
+	GOT_ENTRY(_GOT2_TABLE_)
+	GOT_ENTRY(_FIXUP_TABLE_)
+
+	GOT_ENTRY(_start)
+	GOT_ENTRY(_start_of_vectors)
+	GOT_ENTRY(_end_of_vectors)
+	GOT_ENTRY(transfer_to_handler)
+
+	GOT_ENTRY(_end)
+	GOT_ENTRY(.bss)
+#if defined(CONFIG_FADS)
+	GOT_ENTRY(environment)
+#endif
+	END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+	.text
+	.long	0x27051956		/* U-Boot Magic Number			*/
+	.globl	version_string
+version_string:
+	.ascii U_BOOT_VERSION
+	.ascii " (", __DATE__, " - ", __TIME__, ")"
+	.ascii CONFIG_IDENT_STRING, "\0"
+
+	. = EXC_OFF_SYS_RESET
+	.globl	_start
+_start:
+	li	r21, BOOTFLAG_COLD	/* Normal Power-On: Boot from FLASH	*/
+	b	boot_cold
+
+	. = EXC_OFF_SYS_RESET + 0x10
+
+	.globl	_start_warm
+_start_warm:
+	li	r21, BOOTFLAG_WARM	/* Software reboot			*/
+	b	boot_warm
+
+boot_cold:
+boot_warm:
+
+	/* Initialize machine status; enable machine check interrupt		*/
+	/*----------------------------------------------------------------------*/
+	li	r3, MSR_KERNEL		/* Set FP, ME, RI flags */
+	mtmsr	r3
+	mtspr	SRR1, r3		/* Make SRR1 match MSR */
+
+	addis	r0,0,0x0000		/* lets make sure that r0 is really 0 */
+	mtspr   HID0, r0		/* disable I and D caches */
+
+	mfspr	r3, ICR			/* clear Interrupt Cause Register */
+
+	mfmsr	r3			/* turn off address translation */
+	addis	r4,0,0xffff
+	ori	r4,r4,0xffcf
+	and	r3,r3,r4
+	mtmsr	r3
+	isync
+	sync				/* the MMU should be off... */
+
+
+in_flash:
+#if defined(CONFIG_BMW)
+	bl early_init_f /* Must be ASM: no stack yet! */
+#endif
+	/*
+	 * Setup BATs - cannot be done in C since we don't have a stack yet
+	 */
+	bl	setup_bats
+
+	/* Enable MMU.
+	 */
+	mfmsr	r3
+	ori	r3, r3, (MSR_IR | MSR_DR)
+	mtmsr	r3
+#if !defined(CONFIG_BMW)
+	/* Enable and invalidate data cache.
+	 */
+	mfspr	r3, HID0
+	mr	r2, r3
+	ori	r3, r3, HID0_DCE | HID0_DCI
+	ori	r2, r2, HID0_DCE
+	sync
+	mtspr	HID0, r3
+	mtspr	HID0, r2
+	sync
+
+	/* Allocate Initial RAM in data cache.
+	 */
+	lis	r3, CFG_INIT_RAM_ADDR@h
+	ori	r3, r3, CFG_INIT_RAM_ADDR@l
+	li	r2, 128
+	mtctr	r2
+1:
+	dcbz	r0, r3
+	addi	r3, r3, 32
+	bdnz	1b
+
+	/* Lock way0 in data cache.
+	 */
+	mfspr	r3, 1011
+	lis	r2, 0xffff
+	ori	r2, r2, 0xff1f
+	and	r3, r3, r2
+	ori	r3, r3, 0x0080
+	sync
+	mtspr	1011, r3
+#endif /* !CONFIG_BMW */
+	/*
+	 * Thisk the stack pointer *somewhere* sensible. Doesnt
+	 * matter much where as we'll move it when we relocate
+	 */
+	lis	r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
+	ori	r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
+
+	li	r0, 0			/* Make room for stack frame header and	*/
+	stwu	r0, -4(r1)		/* clear final stack frame so that	*/
+	stwu	r0, -4(r1)		/* stack backtraces terminate cleanly	*/
+
+	/* let the C-code set up the rest					*/
+	/*									*/
+	/* Be careful to keep code relocatable !				*/
+	/*----------------------------------------------------------------------*/
+
+	GET_GOT			/* initialize GOT access			*/
+
+	/* r3: IMMR */
+	bl	cpu_init_f	/* run low-level CPU init code     (from Flash)	*/
+
+	mr	r3, r21
+	/* r3: BOOTFLAG */
+	bl	board_init_f	/* run 1st part of board init code (from Flash) */
+
+
+
+	.globl	_start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+	STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
+
+/* Data Storage exception.  "Never" generated on the 860. */
+	STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
+
+/* Instruction Storage exception.  "Never" generated on the 860. */
+	STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+	STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+	. = EXC_OFF_ALIGN
+Alignment:
+	EXCEPTION_PROLOG
+	mfspr	r4,DAR
+	stw	r4,_DAR(r21)
+	mfspr	r5,DSISR
+	stw	r5,_DSISR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_Alignment:
+	.long	AlignmentException - _start + EXC_OFF_SYS_RESET
+	.long	int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+	. = EXC_OFF_PROGRAM
+ProgramCheck:
+	EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_ProgramCheck:
+	.long	ProgramCheckException - _start + EXC_OFF_SYS_RESET
+	.long	int_return - _start + EXC_OFF_SYS_RESET
+
+	/* No FPU on MPC8xx. This exception is not supposed to happen.
+	*/
+	STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
+
+	/* I guess we could implement decrementer, and may have
+	 * to someday for timekeeping.
+	 */
+	STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
+	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+
+	. = 0xc00
+/*
+ * r0 - SYSCALL number
+ * r3-... arguments
+ */
+SystemCall:
+	addis	r11,r0,0		/* get functions table addr */
+	ori	r11,r11,0		/* Note: this code is patched in trap_init */
+	addis	r12,r0,0		/* get number of functions */
+	ori	r12,r12,0
+
+	cmplw	0, r0, r12
+	bge	1f
+
+	rlwinm	r0,r0,2,0,31		/* fn_addr = fn_tbl[r0] */
+	add	r11,r11,r0
+	lwz	r11,0(r11)
+
+	li	r12,0xd00-4*3		/* save LR & SRRx */
+	mflr	r0
+	stw	r0,0(r12)
+	mfspr	r0,SRR0
+	stw	r0,4(r12)
+	mfspr	r0,SRR1
+	stw	r0,8(r12)
+
+	li	r12,0xc00+_back-SystemCall
+	mtlr	r12
+	mtspr	SRR0,r11
+
+1:	SYNC
+	rfi
+
+_back:
+
+	mfmsr	r11			/* Disable interrupts */
+	li	r12,0
+	ori	r12,r12,MSR_EE
+	andc	r11,r11,r12
+	SYNC				/* Some chip revs need this... */
+	mtmsr	r11
+	SYNC
+
+	li	r12,0xd00-4*3		/* restore regs */
+	lwz	r11,0(r12)
+	mtlr	r11
+	lwz	r11,4(r12)
+	mtspr	SRR0,r11
+	lwz	r11,8(r12)
+	mtspr	SRR1,r11
+
+	SYNC
+	rfi
+
+	STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
+
+	STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
+	STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
+
+	STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
+	STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
+	STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
+	STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, UnknownException)
+	STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
+	STD_EXCEPTION(0x1500, Reserved5, UnknownException)
+	STD_EXCEPTION(0x1600, Reserved6, UnknownException)
+	STD_EXCEPTION(0x1700, Reserved7, UnknownException)
+	STD_EXCEPTION(0x1800, Reserved8, UnknownException)
+	STD_EXCEPTION(0x1900, Reserved9, UnknownException)
+	STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
+	STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
+	STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
+	STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
+	STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
+	STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
+
+	STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
+
+	.globl	_end_of_vectors
+_end_of_vectors:
+
+
+	. = 0x3000
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+	.globl	transfer_to_handler
+transfer_to_handler:
+	stw	r22,_NIP(r21)
+	lis	r22,MSR_POW@h
+	andc	r23,r23,r22
+	stw	r23,_MSR(r21)
+	SAVE_GPR(7, r21)
+	SAVE_4GPRS(8, r21)
+	SAVE_8GPRS(12, r21)
+	SAVE_8GPRS(24, r21)
+#if 0
+	andi.	r23,r23,MSR_PR
+	mfspr	r23,SPRG3		/* if from user, fix up tss.regs */
+	beq	2f
+	addi	r24,r1,STACK_FRAME_OVERHEAD
+	stw	r24,PT_REGS(r23)
+2:	addi	r2,r23,-TSS		/* set r2 to current */
+	tovirt(r2,r2,r23)
+#endif
+	mflr	r23
+	andi.	r24,r23,0x3f00		/* get vector offset */
+	stw	r24,TRAP(r21)
+	li	r22,0
+	stw	r22,RESULT(r21)
+	mtspr	SPRG2,r22		/* r1 is now kernel sp */
+#if 0
+	addi	r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
+	cmplw	0,r1,r2
+	cmplw	1,r1,r24
+	crand	1,1,4
+	bgt	stack_ovf		/* if r2 < r1 < r2+TASK_STRUCT_SIZE */
+#endif
+	lwz	r24,0(r23)		/* virtual address of handler */
+	lwz	r23,4(r23)		/* where to go when done */
+	mtspr	SRR0,r24
+	ori	r20,r20,0x30		/* enable IR, DR */
+	mtspr	SRR1,r20
+	mtlr	r23
+	SYNC
+	rfi				/* jump to handler, enable MMU */
+
+int_return:
+	mfmsr	r28		/* Disable interrupts */
+	li	r4,0
+	ori	r4,r4,MSR_EE
+	andc	r28,r28,r4
+	SYNC			/* Some chip revs need this... */
+	mtmsr	r28
+	SYNC
+	lwz	r2,_CTR(r1)
+	lwz	r0,_LINK(r1)
+	mtctr	r2
+	mtlr	r0
+	lwz	r2,_XER(r1)
+	lwz	r0,_CCR(r1)
+	mtspr	XER,r2
+	mtcrf	0xFF,r0
+	REST_10GPRS(3, r1)
+	REST_10GPRS(13, r1)
+	REST_8GPRS(23, r1)
+	REST_GPR(31, r1)
+	lwz	r2,_NIP(r1)	/* Restore environment */
+	lwz	r0,_MSR(r1)
+	mtspr	SRR0,r2
+	mtspr	SRR1,r0
+	lwz	r0,GPR0(r1)
+	lwz	r2,GPR2(r1)
+	lwz	r1,GPR1(r1)
+	SYNC
+	rfi
+
+/* Cache functions.
+*/
+	.globl	icache_enable
+icache_enable:
+	mfspr	r5,HID0		/* turn on the I cache. */
+	ori	r5,r5,0x8800	/* Instruction cache only! */
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0xF7FF
+	and	r6,r5,r6	/* clear the invalidate bit */
+	sync
+	mtspr	HID0,r5
+	mtspr	HID0,r6
+	isync
+	sync
+	blr
+
+	.globl	icache_disable
+icache_disable:
+	mfspr	r5,HID0
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0x7FFF
+	and	r5,r5,r6
+	sync
+	mtspr	HID0,r5
+	isync
+	sync
+	blr
+
+	.globl	icache_status
+icache_status:
+	mfspr	r3, HID0
+	srwi	r3, r3, 15	/* >>15 & 1=> select bit 16 */
+	andi.	r3, r3, 1
+	blr
+
+	.globl	dcache_enable
+dcache_enable:
+	mfspr	r5,HID0		/* turn on the D cache. */
+	ori	r5,r5,0x4400	/* Data cache only! */
+	mfspr	r4, PVR		/* read PVR */
+	srawi	r3, r4, 16	/* shift off the least 16 bits */
+	cmpi	0, 0, r3, 0xC	/* Check for Max pvr */
+	bne	NotMax
+	ori	r5,r5,0x0040	/* setting the DCFA bit, for Max rev 1 errata */
+NotMax:
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0xFBFF
+	and	r6,r5,r6	/* clear the invalidate bit */
+	sync
+	mtspr	HID0,r5
+	mtspr	HID0,r6
+	isync
+	sync
+	blr
+
+	.globl	dcache_disable
+dcache_disable:
+	mfspr	r5,HID0
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0xBFFF
+	and	r5,r5,r6
+	sync
+	mtspr	HID0,r5
+	isync
+	sync
+	blr
+
+	.globl	dcache_status
+dcache_status:
+	mfspr	r3, HID0
+	srwi	r3, r3, 14	/* >>14 & 1=> select bit 17 */
+	andi.	r3, r3, 1
+	blr
+
+	.globl	dc_read
+dc_read:
+/*TODO : who uses this, what should it do?
+*/
+	blr
+
+
+	.globl get_pvr
+get_pvr:
+	mfspr	r3, PVR
+	blr
+
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+	.globl	relocate_code
+relocate_code:
+
+	mr	r1,  r3		/* Set new stack pointer		*/
+	mr	r9,  r4		/* Save copy of Global Data pointer	*/
+	mr	r10, r5		/* Save copy of Destination Address	*/
+
+	mr	r3,  r5				/* Destination Address	*/
+#ifdef DEBUG
+	lis	r4, CFG_SDRAM_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CFG_SDRAM_BASE@l
+#else
+	lis	r4, CFG_MONITOR_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CFG_MONITOR_BASE@l
+#endif
+	lis	r5, CFG_MONITOR_LEN@h		/* Length in Bytes	*/
+	ori	r5, r5, CFG_MONITOR_LEN@l
+	li	r6, CFG_CACHELINE_SIZE		/* Cache Line Size	*/
+
+	/*
+	 * Fix GOT pointer:
+	 *
+	 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+	 *
+	 * Offset:
+	 */
+	sub	r15, r10, r4
+
+	/* First our own GOT */
+	add	r14, r14, r15
+	/* the the one used by the C code */
+	add	r30, r30, r15
+
+	/*
+	 * Now relocate code
+	 */
+
+	cmplw	cr1,r3,r4
+	addi	r0,r5,3
+	srwi.	r0,r0,2
+	beq	cr1,4f		/* In place copy is not necessary	*/
+	beq	7f		/* Protect against 0 count		*/
+	mtctr	r0
+	bge	cr1,2f
+
+	la	r8,-4(r4)
+	la	r7,-4(r3)
+1:	lwzu	r0,4(r8)
+	stwu	r0,4(r7)
+	bdnz	1b
+	b	4f
+
+2:	slwi	r0,r0,2
+	add	r8,r4,r0
+	add	r7,r3,r0
+3:	lwzu	r0,-4(r8)
+	stwu	r0,-4(r7)
+	bdnz	3b
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4:	cmpwi	r6,0
+	add	r5,r3,r5
+	beq	7f		/* Always flush prefetch queue in any case */
+	subi	r0,r6,1
+	andc	r3,r3,r0
+	mr	r4,r3
+5:	dcbst	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	5b
+	sync			/* Wait for all dcbst to complete on bus */
+	mr	r4,r3
+6:	icbi	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	6b
+7:	sync			/* Wait for all icbi to complete on bus	*/
+	isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+
+	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+	mtlr	r0
+	blr
+
+in_ram:
+
+	/*
+	 * Relocation Function, r14 point to got2+0x8000
+	 *
+	 * Adjust got2 pointers, no need to check for 0, this code
+	 * already puts a few entries in the table.
+	 */
+	li	r0,__got2_entries@sectoff@l
+	la	r3,GOT(_GOT2_TABLE_)
+	lwz	r11,GOT(_GOT2_TABLE_)
+	mtctr	r0
+	sub	r11,r3,r11
+	addi	r3,r3,-4
+1:	lwzu	r0,4(r3)
+	add	r0,r0,r11
+	stw	r0,0(r3)
+	bdnz	1b
+
+	/*
+	 * Now adjust the fixups and the pointers to the fixups
+	 * in case we need to move ourselves again.
+	 */
+2:	li	r0,__fixup_entries@sectoff@l
+	lwz	r3,GOT(_FIXUP_TABLE_)
+	cmpwi	r0,0
+	mtctr	r0
+	addi	r3,r3,-4
+	beq	4f
+3:	lwzu	r4,4(r3)
+	lwzux	r0,r4,r11
+	add	r0,r0,r11
+	stw	r10,0(r3)
+	stw	r0,0(r4)
+	bdnz	3b
+4:
+clear_bss:
+	/*
+	 * Now clear BSS segment
+	 */
+	lwz	r3,GOT(.bss)
+	lwz	r4,GOT(_end)
+
+	cmplw	0, r3, r4
+	beq	6f
+
+	li	r0, 0
+5:
+	stw	r0, 0(r3)
+	addi	r3, r3, 4
+	cmplw	0, r3, r4
+	blt	5b
+6:
+
+	mr	r3, r9		/* Global Data pointer		*/
+	mr	r4, r10		/* Destination Address		*/
+	bl	board_init_r
+
+	/* Problems accessing "end" in C, so do it here */
+	.globl	get_endaddr
+get_endaddr:
+	lwz	r3,GOT(_end)
+	blr
+
+	/*
+	 * Copy exception vector code to low memory
+	 *
+	 * r3: dest_addr
+	 * r7: source address, r8: end address, r9: target address
+	 */
+	.globl	trap_init
+trap_init:
+	lwz	r7, GOT(_start)
+	lwz	r8, GOT(_end_of_vectors)
+
+	rlwinm	r9, r7, 0, 18, 31	/* _start & 0x3FFF	*/
+
+	cmplw	0, r7, r8
+	bgelr				/* return if r7>=r8 - just in case */
+
+	mflr	r4			/* save link register		*/
+1:
+	lwz	r0, 0(r7)
+	stw	r0, 0(r9)
+	addi	r7, r7, 4
+	addi	r9, r9, 4
+	cmplw	0, r7, r8
+	bne	1b
+
+	/*
+	 * relocate `hdlr' and `int_return' entries
+	 */
+	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+	li	r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	2b
+
+	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+	bl	trap_reloc
+
+	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+	bl	trap_reloc
+
+	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET
+3:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	3b
+
+	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
+	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+4:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	4b
+
+	mtlr	r4			/* restore link register	*/
+	blr
+
+	/*
+	 * Function: relocate entries for one exception vector
+	 */
+trap_reloc:
+	lwz	r0, 0(r7)		/* hdlr ...			*/
+	add	r0, r0, r3		/*  ... += dest_addr		*/
+	stw	r0, 0(r7)
+
+	lwz	r0, 4(r7)		/* int_return ...		*/
+	add	r0, r0, r3		/*  ... += dest_addr		*/
+	stw	r0, 4(r7)
+
+	blr
+
+	/* Setup the BAT registers.
+	 */
+setup_bats:
+	lis	r4, CFG_IBAT0L@h
+	ori	r4, r4, CFG_IBAT0L@l
+	lis	r3, CFG_IBAT0U@h
+	ori	r3, r3, CFG_IBAT0U@l
+	mtspr	IBAT0L, r4
+	mtspr	IBAT0U, r3
+	isync
+
+	lis	r4, CFG_DBAT0L@h
+	ori	r4, r4, CFG_DBAT0L@l
+	lis	r3, CFG_DBAT0U@h
+	ori	r3, r3, CFG_DBAT0U@l
+	mtspr	DBAT0L, r4
+	mtspr	DBAT0U, r3
+	isync
+
+	lis	r4, CFG_IBAT1L@h
+	ori	r4, r4, CFG_IBAT1L@l
+	lis	r3, CFG_IBAT1U@h
+	ori	r3, r3, CFG_IBAT1U@l
+	mtspr	IBAT1L, r4
+	mtspr	IBAT1U, r3
+	isync
+
+	lis	r4, CFG_DBAT1L@h
+	ori	r4, r4, CFG_DBAT1L@l
+	lis	r3, CFG_DBAT1U@h
+	ori	r3, r3, CFG_DBAT1U@l
+	mtspr	DBAT1L, r4
+	mtspr	DBAT1U, r3
+	isync
+
+	lis	r4, CFG_IBAT2L@h
+	ori	r4, r4, CFG_IBAT2L@l
+	lis	r3, CFG_IBAT2U@h
+	ori	r3, r3, CFG_IBAT2U@l
+	mtspr	IBAT2L, r4
+	mtspr	IBAT2U, r3
+	isync
+
+	lis	r4, CFG_DBAT2L@h
+	ori	r4, r4, CFG_DBAT2L@l
+	lis	r3, CFG_DBAT2U@h
+	ori	r3, r3, CFG_DBAT2U@l
+	mtspr	DBAT2L, r4
+	mtspr	DBAT2U, r3
+	isync
+
+	lis	r4, CFG_IBAT3L@h
+	ori	r4, r4, CFG_IBAT3L@l
+	lis	r3, CFG_IBAT3U@h
+	ori	r3, r3, CFG_IBAT3U@l
+	mtspr	IBAT3L, r4
+	mtspr	IBAT3U, r3
+	isync
+
+	lis	r4, CFG_DBAT3L@h
+	ori	r4, r4, CFG_DBAT3L@l
+	lis	r3, CFG_DBAT3U@h
+	ori	r3, r3, CFG_DBAT3U@l
+	mtspr	DBAT3L, r4
+	mtspr	DBAT3U, r3
+	isync
+
+	/* Invalidate TLBs.
+	 * -> for (val = 0; val < 0x20000; val+=0x1000)
+	 * ->   tlbie(val);
+	 */
+	lis	r3, 0
+	lis	r5, 2
+
+1:
+	tlbie	r3
+	addi	r3, r3, 0x1000
+	cmp	0, 0, r3, r5
+	blt	1b
+
+	blr
+
+
diff --git a/cpu/mpc8260/cpu_init.c b/cpu/mpc8260/cpu_init.c
new file mode 100644
index 0000000..9f9369a
--- /dev/null
+++ b/cpu/mpc8260/cpu_init.c
@@ -0,0 +1,264 @@
+/*
+ * (C) Copyright 2000-2002
+ * 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 <mpc8260.h>
+#include <asm/cpm_8260.h>
+#include <ioports.h>
+
+static void config_8260_ioports (volatile immap_t * immr)
+{
+	int portnum;
+
+	for (portnum = 0; portnum < 4; portnum++) {
+		uint pmsk = 0,
+		     ppar = 0,
+		     psor = 0,
+		     pdir = 0,
+		     podr = 0,
+		     pdat = 0;
+		iop_conf_t *iopc = (iop_conf_t *) & iop_conf_tab[portnum][0];
+		iop_conf_t *eiopc = iopc + 32;
+		uint msk = 1;
+
+		/*
+		 * NOTE:
+		 * index 0 refers to pin 31,
+		 * index 31 refers to pin 0
+		 */
+		while (iopc < eiopc) {
+			if (iopc->conf) {
+				pmsk |= msk;
+				if (iopc->ppar)
+					ppar |= msk;
+				if (iopc->psor)
+					psor |= msk;
+				if (iopc->pdir)
+					pdir |= msk;
+				if (iopc->podr)
+					podr |= msk;
+				if (iopc->pdat)
+					pdat |= msk;
+			}
+
+			msk <<= 1;
+			iopc++;
+		}
+
+		if (pmsk != 0) {
+			volatile ioport_t *iop = ioport_addr (immr, portnum);
+			uint tpmsk = ~pmsk;
+
+			/*
+                         * the (somewhat confused) paragraph at the
+                         * bottom of page 35-5 warns that there might
+                         * be "unknown behaviour" when programming
+                         * PSORx and PDIRx, if PPARx = 1, so I
+                         * decided this meant I had to disable the
+                         * dedicated function first, and enable it
+                         * last.
+			 */
+			iop->ppar &= tpmsk;
+			iop->psor = (iop->psor & tpmsk) | psor;
+			iop->pdat = (iop->pdat & tpmsk) | pdat;
+			iop->pdir = (iop->pdir & tpmsk) | pdir;
+			iop->podr = (iop->podr & tpmsk) | podr;
+			iop->ppar |= ppar;
+		}
+	}
+}
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ * initialize the UPM's
+ */
+void cpu_init_f (volatile immap_t * immr)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile memctl8260_t *memctl = &immr->im_memctl;
+	extern void m8260_cpm_reset (void);
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+	/* Clear initial global data */
+	memset ((void *) gd, 0, sizeof (gd_t));
+
+	/* RSR - Reset Status Register - clear all status (5-4) */
+	gd->reset_status = immr->im_clkrst.car_rsr;
+	immr->im_clkrst.car_rsr = RSR_ALLBITS;
+
+	/* RMR - Reset Mode Register - contains checkstop reset enable (5-5) */
+	immr->im_clkrst.car_rmr = CFG_RMR;
+
+	/* BCR - Bus Configuration Register (4-25) */
+	immr->im_siu_conf.sc_bcr = CFG_BCR;
+
+	/* SIUMCR - contains debug pin configuration (4-31) */
+	immr->im_siu_conf.sc_siumcr = CFG_SIUMCR;
+
+	config_8260_ioports (immr);
+
+	/* initialize time counter status and control register (4-40) */
+	immr->im_sit.sit_tmcntsc = CFG_TMCNTSC;
+
+	/* initialize the PIT (4-42) */
+	immr->im_sit.sit_piscr = CFG_PISCR;
+
+#if !defined(CONFIG_COGENT)		/* done in start.S for the cogent */
+	/* System clock control register (9-8) */
+	immr->im_clkrst.car_sccr = CFG_SCCR;
+#endif /* !CONFIG_COGENT */
+
+	/*
+	 * Memory Controller:
+	 */
+
+	/* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
+	 * addresses - these have to be modified later when FLASH size
+	 * has been determined
+	 */
+
+#if defined(CFG_OR0_REMAP)
+	memctl->memc_or0 = CFG_OR0_REMAP;
+#endif
+#if defined(CFG_OR1_REMAP)
+	memctl->memc_or1 = CFG_OR1_REMAP;
+#endif
+
+	/* now restrict to preliminary range */
+	memctl->memc_br0 = CFG_BR0_PRELIM;
+	memctl->memc_or0 = CFG_OR0_PRELIM;
+
+#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
+	memctl->memc_or1 = CFG_OR1_PRELIM;
+	memctl->memc_br1 = CFG_BR1_PRELIM;
+#endif
+
+#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
+	memctl->memc_or2 = CFG_OR2_PRELIM;
+	memctl->memc_br2 = CFG_BR2_PRELIM;
+#endif
+
+#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
+	memctl->memc_or3 = CFG_OR3_PRELIM;
+	memctl->memc_br3 = CFG_BR3_PRELIM;
+#endif
+
+#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
+	memctl->memc_or4 = CFG_OR4_PRELIM;
+	memctl->memc_br4 = CFG_BR4_PRELIM;
+#endif
+
+#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
+	memctl->memc_or5 = CFG_OR5_PRELIM;
+	memctl->memc_br5 = CFG_BR5_PRELIM;
+#endif
+
+#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
+	memctl->memc_or6 = CFG_OR6_PRELIM;
+	memctl->memc_br6 = CFG_BR6_PRELIM;
+#endif
+
+#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
+	memctl->memc_or7 = CFG_OR7_PRELIM;
+	memctl->memc_br7 = CFG_BR7_PRELIM;
+#endif
+
+#if defined(CFG_BR8_PRELIM) && defined(CFG_OR8_PRELIM)
+	memctl->memc_or8 = CFG_OR8_PRELIM;
+	memctl->memc_br8 = CFG_BR8_PRELIM;
+#endif
+
+#if defined(CFG_BR9_PRELIM) && defined(CFG_OR9_PRELIM)
+	memctl->memc_or9 = CFG_OR9_PRELIM;
+	memctl->memc_br9 = CFG_BR9_PRELIM;
+#endif
+
+#if defined(CFG_BR10_PRELIM) && defined(CFG_OR10_PRELIM)
+	memctl->memc_or10 = CFG_OR10_PRELIM;
+	memctl->memc_br10 = CFG_BR10_PRELIM;
+#endif
+
+#if defined(CFG_BR11_PRELIM) && defined(CFG_OR11_PRELIM)
+	memctl->memc_or11 = CFG_OR11_PRELIM;
+	memctl->memc_br11 = CFG_BR11_PRELIM;
+#endif
+
+	m8260_cpm_reset ();
+}
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile immap_t *immr = (immap_t *) gd->bd->bi_immr_base;
+
+	immr->im_cpm.cp_rccr = CFG_RCCR;
+
+	return (0);
+}
+
+/*
+ * print out the reason for the reset
+ */
+int prt_8260_rsr (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	static struct {
+		ulong mask;
+		char *desc;
+	} bits[] = {
+		{
+		RSR_JTRS, "JTAG"}, {
+		RSR_CSRS, "Check Stop"}, {
+		RSR_SWRS, "Software Watchdog"}, {
+		RSR_BMRS, "Bus Monitor"}, {
+		RSR_ESRS, "External Soft"}, {
+		RSR_EHRS, "External Hard"}
+	};
+	static int n = sizeof bits / sizeof bits[0];
+	ulong rsr = gd->reset_status;
+	int i;
+	char *sep;
+
+	puts ("MPC8260 Reset Status:");
+
+	sep = " ";
+	for (i = 0; i < n; i++)
+		if (rsr & bits[i].mask) {
+			printf ("%s%s", sep, bits[i].desc);
+			sep = ", ";
+		}
+
+	puts ("\n\n");
+	return (0);
+}
diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c
new file mode 100644
index 0000000..8bfa2e8
--- /dev/null
+++ b/cpu/mpc8260/i2c.c
@@ -0,0 +1,733 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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>
+
+#if defined(CONFIG_HARD_I2C)
+
+#include <asm/cpm_8260.h>
+#include <i2c.h>
+
+/* define to enable debug messages */
+#undef  DEBUG_I2C
+
+/* uSec to wait between polls of the i2c */
+#define DELAY_US	100
+/* uSec to wait for the CPM to start processing the buffer */
+#define START_DELAY_US	1000
+
+/*
+ * tx/rx per-byte timeout: we delay DELAY_US uSec between polls so the
+ * timeout will be (tx_length + rx_length) * DELAY_US * TOUT_LOOP
+ */
+#define TOUT_LOOP 5
+
+/*-----------------------------------------------------------------------
+ * Set default values
+ */
+#ifndef	CFG_I2C_SPEED
+#define	CFG_I2C_SPEED	50000
+#endif
+
+#ifndef	CFG_I2C_SLAVE
+#define	CFG_I2C_SLAVE	0xFE
+#endif
+/*-----------------------------------------------------------------------
+ */
+
+typedef void (*i2c_ecb_t)(int, int);    /* error callback function */
+
+/* This structure keeps track of the bd and buffer space usage. */
+typedef struct i2c_state {
+	int		rx_idx;		/* index   to next free Rx BD */
+	int		tx_idx;		/* index   to next free Tx BD */
+	void		*rxbd;		/* pointer to next free Rx BD */
+	void		*txbd;		/* pointer to next free Tx BD */
+	int		tx_space;	/* number  of Tx bytes left   */
+	unsigned char	*tx_buf;	/* pointer to free Tx area    */
+	i2c_ecb_t	err_cb;		/* error callback function    */
+} i2c_state_t;
+
+/* flags for i2c_send() and i2c_receive() */
+#define	I2CF_ENABLE_SECONDARY	0x01	/* secondary_address is valid	*/
+#define	I2CF_START_COND		0x02	/* tx: generate start condition	*/
+#define I2CF_STOP_COND		0x04	/* tx: generate stop  condition	*/
+
+/* return codes */
+#define I2CERR_NO_BUFFERS	0x01	/* no more BDs or buffer space	*/
+#define I2CERR_MSG_TOO_LONG	0x02	/* tried to send/receive to much data   */
+#define I2CERR_TIMEOUT		0x03	/* timeout in i2c_doio()	*/
+#define I2CERR_QUEUE_EMPTY	0x04	/* i2c_doio called without send/receive */
+
+/* error callback flags */
+#define I2CECB_RX_ERR		0x10	/* this is a receive error	*/
+#define     I2CECB_RX_ERR_OV	0x02	/* receive overrun error	*/
+#define     I2CECB_RX_MASK	0x0f	/* mask for error bits		*/
+#define I2CECB_TX_ERR		0x20	/* this is a transmit error	*/
+#define     I2CECB_TX_CL	0x01	/* transmit collision error	*/
+#define     I2CECB_TX_UN	0x02	/* transmit underflow error	*/
+#define     I2CECB_TX_NAK	0x04	/* transmit no ack error	*/
+#define     I2CECB_TX_MASK	0x0f	/* mask for error bits		*/
+#define I2CECB_TIMEOUT		0x40	/* this is a timeout error	*/
+
+#define ERROR_I2C_NONE		0
+#define ERROR_I2C_LENGTH	1
+
+#define I2C_WRITE_BIT		0x00
+#define I2C_READ_BIT		0x01
+
+#define I2C_RXTX_LEN	128	/* maximum tx/rx buffer length */
+
+
+#define NUM_RX_BDS 4
+#define NUM_TX_BDS 4
+#define MAX_TX_SPACE 256
+
+typedef struct I2C_BD
+{
+  unsigned short status;
+  unsigned short length;
+  unsigned char *addr;
+} I2C_BD;
+#define BD_I2C_TX_START 0x0400  /* special status for i2c: Start condition */
+
+#define BD_I2C_TX_CL	0x0001	/* collision error */
+#define BD_I2C_TX_UN	0x0002	/* underflow error */
+#define BD_I2C_TX_NAK	0x0004	/* no acknowledge error */
+#define BD_I2C_TX_ERR	(BD_I2C_TX_NAK|BD_I2C_TX_UN|BD_I2C_TX_CL)
+
+#define BD_I2C_RX_ERR	BD_SC_OV
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/*
+ * Returns the best value of I2BRG to meet desired clock speed of I2C with
+ * input parameters (clock speed, filter, and predivider value).
+ * It returns computer speed value and the difference between it and desired
+ * speed.
+ */
+static inline int
+i2c_roundrate(int hz, int speed, int filter, int modval,
+		int *brgval, int *totspeed)
+{
+    int moddiv = 1 << (5-(modval & 3)), brgdiv, div;
+
+    PRINTD(("\t[I2C] trying hz=%d, speed=%d, filter=%d, modval=%d\n",
+	hz, speed, filter, modval));
+
+    div = moddiv * speed;
+    brgdiv = (hz + div - 1) / div;
+
+    PRINTD(("\t\tmoddiv=%d, brgdiv=%d\n", moddiv, brgdiv));
+
+    *brgval = (brgdiv / 2) - 3 - (2*filter);
+
+    if ((*brgval < 0) || (*brgval > 255)) {
+	  PRINTD(("\t\trejected brgval=%d\n", *brgval));
+	  return -1;
+    }
+
+    brgdiv = 2 * (*brgval + 3 + (2 * filter));
+    div = moddiv * brgdiv ;
+    *totspeed = (hz + div - 1) / div;
+
+    PRINTD(("\t\taccepted brgval=%d, totspeed=%d\n", *brgval, *totspeed));
+
+    return  0;
+}
+
+/*
+ * Sets the I2C clock predivider and divider to meet required clock speed.
+ */
+static int i2c_setrate(int hz, int speed)
+{
+    immap_t	*immap = (immap_t *)CFG_IMMR ;
+    volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c;
+    int brgval,
+	  modval,	/* 0-3 */
+	  bestspeed_diff = speed,
+	  bestspeed_brgval=0,
+	  bestspeed_modval=0,
+	  bestspeed_filter=0,
+	  totspeed,
+	  filter = 0; /* Use this fixed value */
+
+	for (modval = 0; modval < 4; modval++)
+	{
+		if (i2c_roundrate (hz, speed, filter, modval, &brgval, &totspeed) == 0)
+		{
+			int diff = speed - totspeed ;
+
+			if ((diff >= 0) && (diff < bestspeed_diff))
+			{
+				bestspeed_diff 	= diff ;
+				bestspeed_modval 	= modval;
+				bestspeed_brgval 	= brgval;
+				bestspeed_filter 	= filter;
+			}
+		}
+	}
+
+    PRINTD(("[I2C] Best is:\n"));
+    PRINTD(("[I2C] CPU=%dhz RATE=%d F=%d I2MOD=%08x I2BRG=%08x DIFF=%dhz\n",
+		   hz, speed,
+		   bestspeed_filter, bestspeed_modval, bestspeed_brgval,
+		   bestspeed_diff));
+
+    i2c->i2c_i2mod |= ((bestspeed_modval & 3) << 1) | (bestspeed_filter << 3);
+    i2c->i2c_i2brg = bestspeed_brgval & 0xff;
+
+    PRINTD(("[I2C] i2mod=%08x i2brg=%08x\n", i2c->i2c_i2mod, i2c->i2c_i2brg));
+
+    return 1 ;
+}
+
+void i2c_init(int speed, int slaveadd)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile immap_t *immap = (immap_t *)CFG_IMMR ;
+	volatile cpm8260_t *cp = (cpm8260_t *)&immap->im_cpm;
+	volatile i2c8260_t *i2c	= (i2c8260_t *)&immap->im_i2c;
+	volatile iic_t *iip;
+	ulong rbase, tbase;
+	volatile I2C_BD *rxbd, *txbd;
+	uint dpaddr;
+
+	dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
+	if (dpaddr == 0) {
+	    /* need to allocate dual port ram */
+	    dpaddr = m8260_cpm_dpalloc(64 +
+		(NUM_RX_BDS * sizeof(I2C_BD)) + (NUM_TX_BDS * sizeof(I2C_BD)) +
+		MAX_TX_SPACE, 64);
+	    *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])) = dpaddr;
+	}
+
+	/*
+	 * initialise data in dual port ram:
+	 *
+	 * 	  dpaddr -> parameter ram (64 bytes)
+	 *         rbase -> rx BD         (NUM_RX_BDS * sizeof(I2C_BD) bytes)
+	 *         tbase -> tx BD         (NUM_TX_BDS * sizeof(I2C_BD) bytes)
+	 *                  tx buffer     (MAX_TX_SPACE bytes)
+	 */
+
+	iip = (iic_t *)&immap->im_dprambase[dpaddr];
+	memset((void*)iip, 0, sizeof(iic_t));
+
+	rbase = dpaddr + 64;
+	tbase = rbase + NUM_RX_BDS * sizeof(I2C_BD);
+
+	/* Disable interrupts */
+	i2c->i2c_i2mod = 0x00;
+	i2c->i2c_i2cmr = 0x00;
+	i2c->i2c_i2cer = 0xff;
+	i2c->i2c_i2add = slaveadd;
+
+	/*
+	 * Set the I2C BRG Clock division factor from desired i2c rate
+	 * and current CPU rate (we assume sccr dfbgr field is 0;
+	 * divide BRGCLK by 1)
+	 */
+	PRINTD(("[I2C] Setting rate...\n"));
+	i2c_setrate (gd->brg_clk, CFG_I2C_SPEED) ;
+
+	/* Set I2C controller in master mode */
+	i2c->i2c_i2com = 0x01;
+
+	/* Initialize Tx/Rx parameters */
+	iip->iic_rbase = rbase;
+	iip->iic_tbase = tbase;
+	rxbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_rbase]);
+	txbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_tbase]);
+
+	PRINTD(("[I2C] rbase = %04x\n", iip->iic_rbase));
+	PRINTD(("[I2C] tbase = %04x\n", iip->iic_tbase));
+	PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
+	PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
+
+	/* Set big endian byte order */
+	iip->iic_tfcr = 0x10;
+	iip->iic_rfcr = 0x10;
+
+	/* Set maximum receive size. */
+	iip->iic_mrblr = I2C_RXTX_LEN;
+
+    cp->cp_cpcr = mk_cr_cmd(CPM_CR_I2C_PAGE,
+							CPM_CR_I2C_SBLOCK,
+							0x00,
+							CPM_CR_INIT_TRX) | CPM_CR_FLG;
+    do {
+		__asm__ __volatile__ ("eieio");
+    } while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Clear events and interrupts */
+	i2c->i2c_i2cer = 0xff;
+	i2c->i2c_i2cmr = 0x00;
+}
+
+static
+void i2c_newio(i2c_state_t *state)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR ;
+	volatile iic_t *iip;
+	uint dpaddr;
+
+	PRINTD(("[I2C] i2c_newio\n"));
+
+	dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
+	iip = (iic_t *)&immap->im_dprambase[dpaddr];
+	state->rx_idx = 0;
+	state->tx_idx = 0;
+	state->rxbd = (void*)&immap->im_dprambase[iip->iic_rbase];
+	state->txbd = (void*)&immap->im_dprambase[iip->iic_tbase];
+	state->tx_space = MAX_TX_SPACE;
+	state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD);
+	state->err_cb = NULL;
+
+	PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd));
+	PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd));
+	PRINTD(("[I2C] tx_buf = %08x\n", (int)state->tx_buf));
+
+	/* clear the buffer memory */
+	memset((char *)state->tx_buf, 0, MAX_TX_SPACE);
+}
+
+static
+int i2c_send(i2c_state_t *state,
+			 unsigned char address,
+			 unsigned char secondary_address,
+			 unsigned int flags,
+			 unsigned short size,
+			 unsigned char *dataout)
+{
+	volatile I2C_BD *txbd;
+	int i,j;
+
+	PRINTD(("[I2C] i2c_send add=%02d sec=%02d flag=%02d size=%d\n",
+			address, secondary_address, flags, size));
+
+	/* trying to send message larger than BD */
+	if (size > I2C_RXTX_LEN)
+	  return I2CERR_MSG_TOO_LONG;
+
+	/* no more free bds */
+	if (state->tx_idx >= NUM_TX_BDS || state->tx_space < (2 + size))
+	  return I2CERR_NO_BUFFERS;
+
+	txbd = (I2C_BD *)state->txbd;
+	txbd->addr = state->tx_buf;
+
+	PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
+
+    if (flags & I2CF_START_COND)
+    {
+	PRINTD(("[I2C] Formatting addresses...\n"));
+	if (flags & I2CF_ENABLE_SECONDARY)
+	{
+		txbd->length = size + 2;  /* Length of message plus dest addresses */
+		txbd->addr[0] = address << 1;
+		txbd->addr[1] = secondary_address;
+		i = 2;
+	}
+	else
+	{
+		txbd->length = size + 1;  /* Length of message plus dest address */
+		txbd->addr[0] = address << 1;  /* Write destination address to BD */
+		i = 1;
+	}
+    }
+    else
+    {
+	txbd->length = size;  /* Length of message */
+	i = 0;
+    }
+
+	/* set up txbd */
+	txbd->status = BD_SC_READY;
+	if (flags & I2CF_START_COND)
+	  txbd->status |= BD_I2C_TX_START;
+	if (flags & I2CF_STOP_COND)
+	  txbd->status |= BD_SC_LAST | BD_SC_WRAP;
+
+	/* Copy data to send into buffer */
+	PRINTD(("[I2C] copy data...\n"));
+	for(j = 0; j < size; i++, j++)
+	  txbd->addr[i] = dataout[j];
+
+	PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
+		   txbd->length,
+		   txbd->status,
+		   txbd->addr[0],
+		   txbd->addr[1]));
+
+	/* advance state */
+	state->tx_buf += txbd->length;
+	state->tx_space -= txbd->length;
+	state->tx_idx++;
+	state->txbd = (void*)(txbd + 1);
+
+	return 0;
+}
+
+static
+int i2c_receive(i2c_state_t *state,
+				unsigned char address,
+				unsigned char secondary_address,
+				unsigned int flags,
+				unsigned short size_to_expect,
+				unsigned char *datain)
+{
+	volatile I2C_BD *rxbd, *txbd;
+
+	PRINTD(("[I2C] i2c_receive %02d %02d %02d\n", address, secondary_address, flags));
+
+	/* Expected to receive too much */
+	if (size_to_expect > I2C_RXTX_LEN)
+	  return I2CERR_MSG_TOO_LONG;
+
+	/* no more free bds */
+	if (state->tx_idx >= NUM_TX_BDS || state->rx_idx >= NUM_RX_BDS
+		 || state->tx_space < 2)
+	  return I2CERR_NO_BUFFERS;
+
+	rxbd = (I2C_BD *)state->rxbd;
+	txbd = (I2C_BD *)state->txbd;
+
+	PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
+	PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
+
+	txbd->addr = state->tx_buf;
+
+	/* set up TXBD for destination address */
+	if (flags & I2CF_ENABLE_SECONDARY)
+	{
+		txbd->length = 2;
+		txbd->addr[0] = address << 1;   /* Write data */
+		txbd->addr[1] = secondary_address;  /* Internal address */
+		txbd->status = BD_SC_READY;
+	}
+	else
+	{
+		txbd->length = 1 + size_to_expect;
+		txbd->addr[0] = (address << 1) | 0x01;
+		txbd->status = BD_SC_READY;
+		memset(&txbd->addr[1], 0, txbd->length);
+	}
+
+	/* set up rxbd for reception */
+	rxbd->status = BD_SC_EMPTY;
+	rxbd->length = size_to_expect;
+	rxbd->addr = datain;
+
+	txbd->status |= BD_I2C_TX_START;
+	if (flags & I2CF_STOP_COND)
+	{
+		txbd->status |= BD_SC_LAST | BD_SC_WRAP;
+		rxbd->status |= BD_SC_WRAP;
+	}
+
+	PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
+		   txbd->length,
+		   txbd->status,
+		   txbd->addr[0],
+		   txbd->addr[1]));
+	PRINTD(("[I2C] rxbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
+		   rxbd->length,
+		   rxbd->status,
+		   rxbd->addr[0],
+		   rxbd->addr[1]));
+
+	/* advance state */
+	state->tx_buf += txbd->length;
+	state->tx_space -= txbd->length;
+	state->tx_idx++;
+	state->txbd = (void*)(txbd + 1);
+	state->rx_idx++;
+	state->rxbd = (void*)(rxbd + 1);
+
+	return 0;
+}
+
+
+static
+int i2c_doio(i2c_state_t *state)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR ;
+	volatile iic_t *iip;
+	volatile i2c8260_t *i2c	= (i2c8260_t *)&immap->im_i2c;
+	volatile I2C_BD *txbd, *rxbd;
+	int  j;
+        int  timeout;
+	uint dpaddr;
+
+	PRINTD(("[I2C] i2c_doio\n"));
+
+        timeout = TOUT_LOOP * 256;	/* arbitrarily long */
+
+	if (state->tx_idx <= 0 && state->rx_idx <= 0) {
+		PRINTD(("[I2C] No I/O is queued\n"));
+		return I2CERR_QUEUE_EMPTY;
+	}
+
+	dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
+	iip = (iic_t *)&immap->im_dprambase[dpaddr];
+	iip->iic_rbptr = iip->iic_rbase;
+	iip->iic_tbptr = iip->iic_tbase;
+
+	/* Enable I2C */
+	PRINTD(("[I2C] Enabling I2C...\n"));
+	i2c->i2c_i2mod |= 0x01;
+
+	/* Begin transmission */
+	i2c->i2c_i2com |= 0x80;
+
+	/* Loop until transmit & receive completed */
+
+	txbd = ((I2C_BD*)state->txbd) - 1;
+	j = 0;
+	if (state->tx_idx > 0) {
+        	timeout = TOUT_LOOP * txbd->length;
+
+		PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd));
+		udelay(START_DELAY_US);	/* give it time to start */
+		while((txbd->status & BD_SC_READY) && (j++ < timeout)) {
+			udelay(DELAY_US);
+			if (ctrlc())
+				return (-1);
+			__asm__ __volatile__ ("eieio");
+		}
+	}
+
+	rxbd = ((I2C_BD*)state->rxbd) - 1;
+	j = 0;
+	if ((state->rx_idx > 0) && (j < timeout)) {
+        	timeout = TOUT_LOOP * rxbd->length;
+		PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd));
+		udelay(START_DELAY_US);	/* give it time to start */
+		while((rxbd->status & BD_SC_EMPTY) && (j++ < timeout)) {
+			udelay(DELAY_US);
+			if (ctrlc())
+				return (-1);
+			__asm__ __volatile__ ("eieio");
+		}
+	}
+
+	/* Turn off I2C */
+	i2c->i2c_i2mod &= ~0x01;
+
+	if (state->err_cb != NULL) {
+		int n, i, b;
+
+		/*
+		 * if we have an error callback function, look at the
+		 * error bits in the bd status and pass them back
+		 */
+
+		if ((n = state->tx_idx) > 0) {
+			for (i = 0; i < n; i++) {
+				txbd = ((I2C_BD*)state->txbd) - (n - i);
+				if ((b = txbd->status & BD_I2C_TX_ERR) != 0)
+					(*state->err_cb)(I2CECB_TX_ERR|b, i);
+			}
+		}
+
+		if ((n = state->rx_idx) > 0) {
+			for (i = 0; i < n; i++) {
+				rxbd = ((I2C_BD*)state->rxbd) - (n - i);
+				if ((b = rxbd->status & BD_I2C_RX_ERR) != 0)
+					(*state->err_cb)(I2CECB_RX_ERR|b, i);
+			}
+		}
+
+		if (j >= timeout)
+			(*state->err_cb)(I2CECB_TIMEOUT, 0);
+	}
+
+	/* sort out errors and return appropriate good/error status */
+	if(j >= timeout)
+		return(I2CERR_TIMEOUT);
+	if((txbd->status & BD_I2C_TX_ERR) != 0)
+		return(I2CECB_TX_ERR | (txbd->status & I2CECB_TX_MASK));
+	if((rxbd->status & BD_I2C_RX_ERR) != 0)
+		return(I2CECB_RX_ERR | (rxbd->status & I2CECB_RX_MASK));
+
+	return(0);
+}
+
+static int had_tx_nak;
+
+static void
+i2c_test_callback(int flags, int xnum)
+{
+	if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK))
+		had_tx_nak = 1;
+}
+
+int i2c_probe(uchar chip)
+{
+	i2c_state_t state;
+	int rc;
+	uchar buf[1];
+
+	i2c_newio(&state);
+
+	state.err_cb = i2c_test_callback;
+	had_tx_nak = 0;
+
+	rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf);
+
+	if (rc != 0)
+		return (rc);
+
+	rc = i2c_doio(&state);
+
+	if ((rc != 0) && (rc != I2CERR_TIMEOUT))
+		return (rc);
+
+	return (had_tx_nak);
+}
+
+
+int
+i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	i2c_state_t state;
+	uchar xaddr[4];
+	int rc;
+
+	xaddr[0] = (addr >> 24) & 0xFF;
+	xaddr[1] = (addr >> 16) & 0xFF;
+	xaddr[2] = (addr >>  8) & 0xFF;
+	xaddr[3] =  addr        & 0xFF;
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+	 /*
+	  * EEPROM chips that implement "address overflow" are ones
+	  * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address
+	  * and the extra bits end up in the "chip address" bit slots.
+	  * This makes a 24WC08 (1Kbyte) chip look like four 256 byte
+	  * chips.
+  	  *
+	  * Note that we consider the length of the address field to still
+	  * be one byte because the extra address bits are hidden in the
+	  * chip address.
+	  */
+	chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+
+	i2c_newio(&state);
+
+	rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
+	if (rc != 0) {
+		printf("i2c_read: i2c_send failed (%d)\n", rc);
+		return 1;
+	}
+
+	rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer);
+	if (rc != 0) {
+		printf("i2c_read: i2c_receive failed (%d)\n", rc);
+		return 1;
+	}
+
+	rc = i2c_doio(&state);
+	if (rc != 0) {
+		printf("i2c_read: i2c_doio failed (%d)\n", rc);
+		return 1;
+	}
+	return 0;
+}
+
+int
+i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	i2c_state_t state;
+	uchar xaddr[4];
+	int rc;
+
+	xaddr[0] = (addr >> 24) & 0xFF;
+	xaddr[1] = (addr >> 16) & 0xFF;
+	xaddr[2] = (addr >>  8) & 0xFF;
+	xaddr[3] =  addr        & 0xFF;
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+	 /*
+	  * EEPROM chips that implement "address overflow" are ones
+	  * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address
+	  * and the extra bits end up in the "chip address" bit slots.
+	  * This makes a 24WC08 (1Kbyte) chip look like four 256 byte
+	  * chips.
+  	  *
+	  * Note that we consider the length of the address field to still
+	  * be one byte because the extra address bits are hidden in the
+	  * chip address.
+	  */
+	chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+
+	i2c_newio(&state);
+
+	rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
+	if (rc != 0) {
+		printf("i2c_write: first i2c_send failed (%d)\n", rc);
+		return 1;
+	}
+
+	rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer);
+	if (rc != 0) {
+		printf("i2c_write: second i2c_send failed (%d)\n", rc);
+		return 1;
+	}
+
+	rc = i2c_doio(&state);
+	if (rc != 0) {
+		printf("i2c_write: i2c_doio failed (%d)\n", rc);
+		return 1;
+	}
+	return 0;
+}
+
+uchar
+i2c_reg_read(uchar chip, uchar reg)
+{
+	char buf;
+
+	i2c_read(chip, reg, 1, &buf, 1);
+
+	return (buf);
+}
+
+void
+i2c_reg_write(uchar chip, uchar reg, uchar val)
+{
+	i2c_write(chip, reg, 1, &val, 1);
+}
+
+#endif	/* CONFIG_HARD_I2C */
diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c
new file mode 100644
index 0000000..b1b58b0
--- /dev/null
+++ b/cpu/mpc8xx/cpu.c
@@ -0,0 +1,516 @@
+/*
+ * (C) Copyright 2000-2002
+ * 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
+ */
+
+/*
+ * m8xx.c
+ *
+ * CPU specific code
+ *
+ * written or collected and sometimes rewritten by
+ * Magnus Damm <damm@bitsmart.com>
+ *
+ * minor modifications by
+ * Wolfgang Denk <wd@denx.de>
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <mpc8xx.h>
+#include <asm/cache.h>
+
+static char *cpu_warning = "\n         " \
+	"*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***";
+
+#if ((defined(CONFIG_MPC860) || defined(CONFIG_MPC855)) && \
+     !defined(CONFIG_MPC862))
+# ifdef	CONFIG_MPC855
+#  define	ID_STR	"PC855"
+# else
+#  define	ID_STR	"PC860"
+# endif
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+	volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+	uint k, m;
+	char buf[32];
+	char pre = 'X';
+	char *mid = "xx";
+	char *suf;
+
+	/* the highest 16 bits should be 0x0050 for a 860 */
+
+	if ((pvr >> 16) != 0x0050)
+		return -1;
+
+	k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+	m = 0;
+
+	switch (k) {
+	case 0x00020001: pre = 'p'; suf = ""; break;
+	case 0x00030001: suf = ""; break;
+	case 0x00120003: suf = "A"; break;
+	case 0x00130003: suf = "A3"; break;
+
+	case 0x00200004: suf = "B"; break;
+
+	case 0x00300004: suf = "C"; break;
+	case 0x00310004: suf = "C1"; m = 1;
+		break;
+
+	case 0x00200064: mid = "SR"; suf = "B"; break;
+	case 0x00300065: mid = "SR"; suf = "C"; break;
+	case 0x00310065: mid = "SR"; suf = "C1"; m = 1; break;
+	case 0x05010000: suf = "D3"; m = 1; break;
+	case 0x05020000: suf = "D4"; m = 1; break;
+
+		/* this value is not documented anywhere */
+	case 0x40000000: pre = 'P'; suf = "D"; m = 1; break;
+
+	default: suf = NULL; break;
+	}
+
+	if (suf)
+		printf ("%c" ID_STR "%sZPnn%s", pre, mid, suf);
+	else
+		printf ("unknown M" ID_STR " (0x%08x)", k);
+
+	printf (" at %s MHz:", strmhz (buf, clock));
+
+	printf (" %u kB I-Cache", checkicache () >> 10);
+	printf (" %u kB D-Cache", checkdcache () >> 10);
+
+	/* lets check and see if we're running on a 860T (or P?) */
+
+	immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+	if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+		printf (" FEC present");
+	}
+
+	if (!m) {
+		puts (cpu_warning);
+	}
+
+	putc ('\n');
+
+	return 0;
+}
+
+#elif defined(CONFIG_MPC862)
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+	volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+	uint k, m;
+	char buf[32];
+	char pre = 'X';
+	char *mid = "xx";
+	char *suf;
+
+	/* the highest 16 bits should be 0x0050 for a 8xx */
+
+	if ((pvr >> 16) != 0x0050)
+		return -1;
+
+	k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+	m = 0;
+
+	switch (k) {
+
+		/* this value is not documented anywhere */
+	case 0x06000000: mid = "P"; suf = "0"; break;
+	case 0x06010001: mid = "P"; suf = "A"; m = 1; break;
+	case 0x07000003: mid = "P"; suf = "B"; m = 1; break;
+	default: suf = NULL; break;
+	}
+
+	if (suf)
+		printf ("%cPC862%sZPnn%s", pre, mid, suf);
+	else
+		printf ("unknown MPC862 (0x%08x)", k);
+
+	printf (" at %s MHz:", strmhz (buf, clock));
+
+	printf (" %u kB I-Cache", checkicache () >> 10);
+	printf (" %u kB D-Cache", checkdcache () >> 10);
+
+	/* lets check and see if we're running on a 862T (or P?) */
+
+	immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+	if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+		printf (" FEC present");
+	}
+
+	if (!m) {
+		puts (cpu_warning);
+	}
+
+	putc ('\n');
+
+	return 0;
+}
+
+#elif defined(CONFIG_MPC823)
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+	volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+	uint k, m;
+	char buf[32];
+	char *suf;
+
+	/* the highest 16 bits should be 0x0050 for a 8xx */
+
+	if ((pvr >> 16) != 0x0050)
+		return -1;
+
+	k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+	m = 0;
+
+	switch (k) {
+		/* MPC823 */
+	case 0x20000000: suf = "0"; break;
+	case 0x20010000: suf = "0.1"; break;
+	case 0x20020000: suf = "Z2/3"; break;
+	case 0x20020001: suf = "Z3"; break;
+	case 0x21000000: suf = "A"; break;
+	case 0x21010000: suf = "B"; m = 1; break;
+	case 0x21010001: suf = "B2"; m = 1; break;
+		/* MPC823E */
+	case 0x24010000: suf = NULL;
+			puts ("PPC823EZTnnB2");
+			m = 1;
+			break;
+	default:
+			suf = NULL;
+			printf ("unknown MPC823 (0x%08x)", k);
+			break;
+	}
+	if (suf)
+		printf ("PPC823ZTnn%s", suf);
+
+	printf (" at %s MHz:", strmhz (buf, clock));
+
+	printf (" %u kB I-Cache", checkicache () >> 10);
+	printf (" %u kB D-Cache", checkdcache () >> 10);
+
+	/* lets check and see if we're running on a 860T (or P?) */
+
+	immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+	if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+		puts (" FEC present");
+	}
+
+	if (!m) {
+		puts (cpu_warning);
+	}
+
+	putc ('\n');
+
+	return 0;
+}
+
+#elif defined(CONFIG_MPC850)
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+	volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+	uint k, m;
+	char buf[32];
+
+	/* the highest 16 bits should be 0x0050 for a 8xx */
+
+	if ((pvr >> 16) != 0x0050)
+		return -1;
+
+	k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+	m = 0;
+
+	switch (k) {
+	case 0x20020001:
+		printf ("XPC850xxZT");
+		break;
+	case 0x21000065:
+		printf ("XPC850xxZTA");
+		break;
+	case 0x21010067:
+		printf ("XPC850xxZTB");
+		m = 1;
+		break;
+	case 0x21020068:
+		printf ("XPC850xxZTC");
+		m = 1;
+		break;
+	default:
+		printf ("unknown MPC850 (0x%08x)", k);
+	}
+	printf (" at %s MHz:", strmhz (buf, clock));
+
+	printf (" %u kB I-Cache", checkicache () >> 10);
+	printf (" %u kB D-Cache", checkdcache () >> 10);
+
+	/* lets check and see if we're running on a 850T (or P?) */
+
+	immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+	if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+		printf (" FEC present");
+	}
+
+	if (!m) {
+		puts (cpu_warning);
+	}
+
+	putc ('\n');
+
+	return 0;
+}
+#else
+#error CPU undefined
+#endif
+/* ------------------------------------------------------------------------- */
+
+int checkcpu (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	ulong clock = gd->cpu_clk;
+	uint immr = get_immr (0);	/* Return full IMMR contents */
+	uint pvr = get_pvr ();
+
+	puts ("CPU:   ");
+
+	/* 850 has PARTNUM 20 */
+	/* 801 has PARTNUM 10 */
+	return check_CPU (clock, pvr, immr);
+}
+
+/* ------------------------------------------------------------------------- */
+/* L1 i-cache                                                                */
+/* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB)              */
+/* the 860 P (plus) has 256 sets of 16 bytes in 4 ways (= 16 kB)             */
+
+int checkicache (void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	u32 cacheon = rd_ic_cst () & IDC_ENABLED;
+
+#ifdef CONFIG_IP860
+	u32 k = memctl->memc_br1 & ~0x00007fff;	/* probe in flash memoryarea */
+#else
+	u32 k = memctl->memc_br0 & ~0x00007fff;	/* probe in flash memoryarea */
+#endif
+	u32 m;
+	u32 lines = -1;
+
+	wr_ic_cst (IDC_UNALL);
+	wr_ic_cst (IDC_INVALL);
+	wr_ic_cst (IDC_DISABLE);
+	__asm__ volatile ("isync");
+
+	while (!((m = rd_ic_cst ()) & IDC_CERR2)) {
+		wr_ic_adr (k);
+		wr_ic_cst (IDC_LDLCK);
+		__asm__ volatile ("isync");
+
+		lines++;
+		k += 0x10;				/* the number of bytes in a cacheline */
+	}
+
+	wr_ic_cst (IDC_UNALL);
+	wr_ic_cst (IDC_INVALL);
+
+	if (cacheon)
+		wr_ic_cst (IDC_ENABLE);
+	else
+		wr_ic_cst (IDC_DISABLE);
+
+	__asm__ volatile ("isync");
+
+	return lines << 4;
+};
+
+/* ------------------------------------------------------------------------- */
+/* L1 d-cache                                                                */
+/* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB)              */
+/* the 860 P (plus) has 256 sets of 16 bytes in 2 ways (= 8 kB)              */
+/* call with cache disabled                                                  */
+
+int checkdcache (void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	u32 cacheon = rd_dc_cst () & IDC_ENABLED;
+
+#ifdef CONFIG_IP860
+	u32 k = memctl->memc_br1 & ~0x00007fff;	/* probe in flash memoryarea */
+#else
+	u32 k = memctl->memc_br0 & ~0x00007fff;	/* probe in flash memoryarea */
+#endif
+	u32 m;
+	u32 lines = -1;
+
+	wr_dc_cst (IDC_UNALL);
+	wr_dc_cst (IDC_INVALL);
+	wr_dc_cst (IDC_DISABLE);
+
+	while (!((m = rd_dc_cst ()) & IDC_CERR2)) {
+		wr_dc_adr (k);
+		wr_dc_cst (IDC_LDLCK);
+		lines++;
+		k += 0x10;	/* the number of bytes in a cacheline */
+	}
+
+	wr_dc_cst (IDC_UNALL);
+	wr_dc_cst (IDC_INVALL);
+
+	if (cacheon)
+		wr_dc_cst (IDC_ENABLE);
+	else
+		wr_dc_cst (IDC_DISABLE);
+
+	return lines << 4;
+};
+
+/* ------------------------------------------------------------------------- */
+
+void upmconfig (uint upm, uint * table, uint size)
+{
+	uint i;
+	uint addr = 0;
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+	for (i = 0; i < size; i++) {
+		memctl->memc_mdr = table[i];	/* (16-15) */
+		memctl->memc_mcr = addr | upm;	/* (16-16) */
+		addr++;
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+int do_reset (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc,
+			  char *argv[])
+{
+	ulong msr, addr;
+
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+	immap->im_clkrst.car_plprcr |= PLPRCR_CSR;	/* Checkstop Reset enable */
+
+	/* Interrupts and MMU off */
+	__asm__ volatile ("mtspr    81, 0");
+	__asm__ volatile ("mfmsr    %0":"=r" (msr));
+
+	msr &= ~0x1030;
+	__asm__ volatile ("mtmsr    %0"::"r" (msr));
+
+	/*
+	 * Trying to execute the next instruction at a non-existing address
+	 * should cause a machine check, resulting in reset
+	 */
+#ifdef CFG_RESET_ADDRESS
+	addr = CFG_RESET_ADDRESS;
+#else
+	/*
+	 * note: when CFG_MONITOR_BASE points to a RAM address, CFG_MONITOR_BASE
+	 * - sizeof (ulong) is usually a valid address. Better pick an address
+	 * known to be invalid on your system and assign it to CFG_RESET_ADDRESS.
+	 * "(ulong)-1" used to be a good choice for many systems...
+	 */
+	addr = CFG_MONITOR_BASE - sizeof (ulong);
+#endif
+	((void (*)(void)) addr) ();
+	return 1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Get timebase clock frequency (like cpu_clk in Hz)
+ *
+ * See table 15-5 pp. 15-16, and SCCR[RTSEL] pp. 15-27.
+ */
+unsigned long get_tbclk (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile immap_t *immr = (volatile immap_t *) CFG_IMMR;
+	ulong oscclk, factor;
+
+	if (immr->im_clkrst.car_sccr & SCCR_TBS) {
+		return (gd->cpu_clk / 16);
+	}
+
+	factor = (((CFG_PLPRCR) & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT) + 1;
+
+	oscclk = gd->cpu_clk / factor;
+
+	if ((immr->im_clkrst.car_sccr & SCCR_RTSEL) == 0 || factor > 2) {
+		return (oscclk / 4);
+	}
+	return (oscclk / 16);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_WATCHDOG)
+void watchdog_reset (void)
+{
+	int re_enable = disable_interrupts ();
+
+	reset_8xx_watchdog ((immap_t *) CFG_IMMR);
+	if (re_enable)
+		enable_interrupts ();
+}
+
+void reset_8xx_watchdog (volatile immap_t * immr)
+{
+# if defined(CONFIG_LWMON)
+	/*
+	 * The LWMON board uses a MAX6301 Watchdog
+	 * with the trigger pin connected to port PA.7
+	 *
+	 * (The old board version used a MAX706TESA Watchdog, which
+	 * had to be handled exactly the same.)
+	 */
+# define WATCHDOG_BIT	0x0100
+	immr->im_ioport.iop_papar &= ~(WATCHDOG_BIT);	/* GPIO     */
+	immr->im_ioport.iop_padir |= WATCHDOG_BIT;	/* Output   */
+	immr->im_ioport.iop_paodr &= ~(WATCHDOG_BIT);	/* active output */
+
+	immr->im_ioport.iop_padat ^= WATCHDOG_BIT;	/* Toggle WDI   */
+# else
+	/*
+	 * All other boards use the MPC8xx Internal Watchdog
+	 */
+	immr->im_siu_conf.sc_swsr = 0x556c;	/* write magic1 */
+	immr->im_siu_conf.sc_swsr = 0xaa39;	/* write magic2 */
+# endif /* CONFIG_LWMON */
+}
+
+#endif /* CONFIG_WATCHDOG */
+
+/* ------------------------------------------------------------------------- */
diff --git a/cpu/mpc8xx/fec.c b/cpu/mpc8xx/fec.c
new file mode 100644
index 0000000..d43dcaa
--- /dev/null
+++ b/cpu/mpc8xx/fec.c
@@ -0,0 +1,710 @@
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <commproc.h>
+#include <net.h>
+#include <command.h>
+
+#undef	ET_DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
+
+#ifdef CFG_DISCOVER_PHY
+#include <miiphy.h>
+static void mii_discover_phy(void);
+#endif
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH  1520
+
+#define TX_BUF_CNT 2
+
+#define TOUT_LOOP 100
+
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1520
+
+
+static char txbuf[DBUF_LENGTH];
+
+static uint rxIdx;	/* index of the current RX buffer */
+static uint txIdx;	/* index of the current TX buffer */
+
+/*
+  * FEC Ethernet Tx and Rx buffer descriptors allocated at the
+  *  immr->udata_bd address on Dual-Port RAM
+  * Provide for Double Buffering
+  */
+
+typedef volatile struct CommonBufferDescriptor {
+    cbd_t rxbd[PKTBUFSRX];		/* Rx BD */
+    cbd_t txbd[TX_BUF_CNT];		/* Tx BD */
+} RTXBD;
+
+static RTXBD *rtx = NULL;
+
+static int fec_send(struct eth_device* dev, volatile void *packet, int length);
+static int fec_recv(struct eth_device* dev);
+static int fec_init(struct eth_device* dev, bd_t * bd);
+static void fec_halt(struct eth_device* dev);
+
+int fec_initialize(bd_t *bis)
+{
+	struct eth_device* dev;
+
+	dev = (struct eth_device*) malloc(sizeof *dev);
+
+	sprintf(dev->name, "FEC ETHERNET");
+	dev->iobase = 0;
+	dev->priv   = 0;
+	dev->init   = fec_init;
+	dev->halt   = fec_halt;
+	dev->send   = fec_send;
+	dev->recv   = fec_recv;
+
+	eth_register(dev);
+
+	return 1;
+}
+
+static int fec_send(struct eth_device* dev, volatile void *packet, int length)
+{
+	int j, rc;
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+	volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+
+	/* section 16.9.23.3
+	 * Wait for ready
+	 */
+	j = 0;
+	while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
+		udelay(1);
+		j++;
+	}
+	if (j>=TOUT_LOOP) {
+		printf("TX not ready\n");
+	}
+
+	rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
+	rtx->txbd[txIdx].cbd_datlen  = length;
+	rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST;
+	__asm__ ("eieio");
+
+	/* Activate transmit Buffer Descriptor polling */
+	fecp->fec_x_des_active = 0x01000000;	/* Descriptor polling active	*/
+
+	j = 0;
+	while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
+#if defined(CONFIG_ICU862)
+		udelay(10);
+#else
+		udelay(1);
+#endif
+		j++;
+	}
+	if (j>=TOUT_LOOP) {
+		printf("TX timeout\n");
+	}
+#ifdef ET_DEBUG
+	printf("%s[%d] %s: cycles: %d    status: %x  retry cnt: %d\n",
+	__FILE__,__LINE__,__FUNCTION__,j,rtx->txbd[txIdx].cbd_sc,
+	(rtx->txbd[txIdx].cbd_sc & 0x003C)>>2);
+#endif
+	/* return only status bits */;
+	rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS);
+
+	txIdx = (txIdx + 1) % TX_BUF_CNT;
+
+	return rc;
+}
+
+static int fec_recv(struct eth_device* dev)
+{
+	int length;
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+	volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+
+   for (;;) {
+	/* section 16.9.23.2 */
+	if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+		length = -1;
+		break;     /* nothing received - leave for() loop */
+	}
+
+	length = rtx->rxbd[rxIdx].cbd_datlen;
+
+	if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
+#ifdef ET_DEBUG
+		printf("%s[%d] err: %x\n",
+		__FUNCTION__,__LINE__,rtx->rxbd[rxIdx].cbd_sc);
+#endif
+	} else {
+		/* Pass the packet up to the protocol layers. */
+		NetReceive(NetRxPackets[rxIdx], length - 4);
+	}
+
+	/* Give the buffer back to the FEC. */
+	rtx->rxbd[rxIdx].cbd_datlen = 0;
+
+	/* wrap around buffer index when necessary */
+	if ((rxIdx + 1) >= PKTBUFSRX) {
+		rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+		rxIdx = 0;
+	} else {
+		rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+		rxIdx++;
+	}
+
+	__asm__ ("eieio");
+
+	/* Try to fill Buffer Descriptors */
+	fecp->fec_r_des_active = 0x01000000;	/* Descriptor polling active	*/
+   }
+
+   return length;
+}
+
+/**************************************************************
+ *
+ * FEC Ethernet Initialization Routine
+ *
+ *************************************************************/
+
+#define	FEC_ECNTRL_PINMUX	0x00000004
+#define FEC_ECNTRL_ETHER_EN	0x00000002
+#define FEC_ECNTRL_RESET	0x00000001
+
+#define FEC_RCNTRL_BC_REJ	0x00000010
+#define FEC_RCNTRL_PROM		0x00000008
+#define FEC_RCNTRL_MII_MODE	0x00000004
+#define FEC_RCNTRL_DRT		0x00000002
+#define FEC_RCNTRL_LOOP		0x00000001
+
+#define FEC_TCNTRL_FDEN		0x00000004
+#define FEC_TCNTRL_HBC		0x00000002
+#define FEC_TCNTRL_GTS		0x00000001
+
+#define	FEC_RESET_DELAY		50
+
+static int fec_init(struct eth_device* dev, bd_t * bd)
+{
+
+	int i;
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+	volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+
+#if defined(CONFIG_FADS) && defined(CONFIG_MPC860T)
+	/* configure FADS for fast (FEC) ethernet, half-duplex */
+	/* The LXT970 needs about 50ms to recover from reset, so
+	 * wait for it by discovering the PHY before leaving eth_init().
+	 */
+	{
+		volatile uint *bcsr4 = (volatile uint *) BCSR4;
+		*bcsr4 = (*bcsr4 & ~(BCSR4_FETH_EN | BCSR4_FETHCFG1))
+			| (BCSR4_FETHCFG0 | BCSR4_FETHFDE | BCSR4_FETHRST);
+
+		/* reset the LXT970 PHY */
+		*bcsr4 &= ~BCSR4_FETHRST;
+		udelay (10);
+		*bcsr4 |= BCSR4_FETHRST;
+		udelay (10);
+	}
+#endif
+	/* Whack a reset.
+	 * A delay is required between a reset of the FEC block and
+	 * initialization of other FEC registers because the reset takes
+	 * some time to complete. If you don't delay, subsequent writes
+	 * to FEC registers might get killed by the reset routine which is
+	 * still in progress.
+	 */
+	fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
+	for (i = 0;
+	     (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+	     ++i) {
+		udelay (1);
+	}
+	if (i == FEC_RESET_DELAY) {
+		printf ("FEC_RESET_DELAY timeout\n");
+		return 0;
+	}
+
+	/* We use strictly polling mode only
+	 */
+	fecp->fec_imask = 0;
+
+	/* Clear any pending interrupt
+	 */
+	fecp->fec_ievent = 0xffc0;
+
+	/* No need to set the IVEC register */
+
+	/* Set station address
+	 */
+#define ea eth_get_dev()->enetaddr
+	fecp->fec_addr_low   =	(ea[0] << 24) | (ea[1] << 16) |
+				(ea[2] <<  8) | (ea[3]      ) ;
+	fecp->fec_addr_high  =	(ea[4] <<  8) | (ea[5]	    ) ;
+#undef ea
+
+	/* Clear multicast address hash table
+	 */
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low  = 0;
+
+	/* Set maximum receive buffer size.
+	 */
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+
+	/* Set maximum frame length
+	 */
+	fecp->fec_r_hash = PKT_MAXBUF_SIZE;
+
+	/*
+	 * Setup Buffers and Buffer Desriptors
+	 */
+	rxIdx = 0;
+	txIdx = 0;
+
+	if (!rtx) {
+#ifdef CFG_ALLOC_DPRAM
+	    rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + dpram_alloc_align(sizeof(RTXBD),8));
+#else
+	    rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_FEC_BASE);
+#endif
+	}
+	/*
+	 * Setup Receiver Buffer Descriptors (13.14.24.18)
+	 * Settings:
+	 *     Empty, Wrap
+	 */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		rtx->rxbd[i].cbd_sc      = BD_ENET_RX_EMPTY;
+		rtx->rxbd[i].cbd_datlen  = 0;	/* Reset */
+		rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+	}
+	rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+	/*
+	 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+	 * Settings:
+	 *    Last, Tx CRC
+	 */
+	for (i = 0; i < TX_BUF_CNT; i++) {
+		rtx->txbd[i].cbd_sc      = BD_ENET_TX_LAST | BD_ENET_TX_TC;
+		rtx->txbd[i].cbd_datlen  = 0;	/* Reset */
+		rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
+	}
+	rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+	/* Set receive and transmit descriptor base
+	 */
+	fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
+	fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
+
+	/* Enable MII mode
+	 */
+#if 0	/* Full duplex mode */
+	fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE;
+	fecp->fec_x_cntrl = FEC_TCNTRL_FDEN;
+#else	/* Half duplex mode */
+	fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
+	fecp->fec_x_cntrl = 0;
+#endif
+
+	/* Enable big endian and don't care about SDMA FC.
+	 */
+	fecp->fec_fun_code = 0x78000000;
+
+	/* Set MII speed to 2.5 MHz or slightly below.
+	 * According to the MPC860T (Rev. D) Fast ethernet controller user
+	 * manual (6.2.14),
+	 * the MII management interface clock must be less than or equal
+	 * to 2.5 MHz.
+	 * This MDC frequency is equal to system clock / (2 * MII_SPEED).
+	 * Then MII_SPEED = system_clock / 2 * 2,5 Mhz.
+	 */
+	fecp->fec_mii_speed = ((bd->bi_busfreq + 4999999) / 5000000) << 1;
+
+#if !defined(CONFIG_ICU862) && !defined(CONFIG_IAD210)
+	/* Configure all of port D for MII.
+	 */
+	immr->im_ioport.iop_pdpar = 0x1fff;
+
+	/* Bits moved from Rev. D onward */
+	if ((get_immr (0) & 0xffff) < 0x0501) {
+		immr->im_ioport.iop_pddir = 0x1c58;	/* Pre rev. D */
+	} else {
+		immr->im_ioport.iop_pddir = 0x1fff;	/* Rev. D and later */
+	}
+#else
+	/* Configure port A for MII.
+	*/
+
+#if defined(CONFIG_ICU862) && defined(CFG_DISCOVER_PHY)
+
+	/* On the ICU862 board the MII-MDC pin is routed to PD8 pin
+	 * of CPU, so for this board we need to configure Utopia and
+	 * enable PD8 to MII-MDC function */
+	immr->im_ioport.iop_pdpar |= 0x4080;
+#endif
+
+	/* Has Utopia been configured? */
+	if (immr->im_ioport.iop_pdpar & (0x8000 >> 1)) {
+		/*
+		 * YES - Use MUXED mode for UTOPIA bus.
+		 * This frees Port A for use by MII (see 862UM table 41-6).
+		 */
+		immr->im_ioport.utmode &= ~0x80;
+	} else {
+		/*
+		 * NO - set SPLIT mode for UTOPIA bus.
+		 *
+		 * This doesn't really effect UTOPIA (which isn't
+		 * enabled anyway) but just tells the 862
+		 * to use port A for MII (see 862UM table 41-6).
+		 */
+		immr->im_ioport.utmode |= 0x80;
+	}
+#endif	/* !defined(CONFIG_ICU862) */
+
+	rxIdx = 0;
+	txIdx = 0;
+
+	/* Now enable the transmit and receive processing
+	 */
+	fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
+
+#ifdef CFG_DISCOVER_PHY
+	/* wait for the PHY to wake up after reset
+	 */
+	mii_discover_phy();
+#endif
+
+	/* And last, try to fill Rx Buffer Descriptors */
+	fecp->fec_r_des_active = 0x01000000;	/* Descriptor polling active	*/
+
+	return 1;
+}
+
+
+
+static void fec_halt(struct eth_device* dev)
+{
+#if 0
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+    immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+}
+
+#if 0
+void restart(void)
+{
+   volatile immap_t *immr = (immap_t *)CFG_IMMR;
+   immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+}
+#endif
+
+#if defined(CFG_DISCOVER_PHY) || (CONFIG_COMMANDS & CFG_CMD_MII)
+
+static	int	phyaddr = -1;	/* didn't find a PHY yet */
+static	uint	phytype;
+
+/* Make MII read/write commands for the FEC.
+*/
+
+#define mk_mii_read(ADDR, REG)	(0x60020000 | ((ADDR << 23) | \
+						(REG & 0x1f) << 18))
+
+#define mk_mii_write(ADDR, REG, VAL)	(0x50020000 | ((ADDR << 23) | \
+						(REG & 0x1f) << 18) | \
+						(VAL & 0xffff))
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR	((uint)0x80000000)	/* Heartbeat error */
+#define FEC_ENET_BABR	((uint)0x40000000)	/* Babbling receiver */
+#define FEC_ENET_BABT	((uint)0x20000000)	/* Babbling transmitter */
+#define FEC_ENET_GRA	((uint)0x10000000)	/* Graceful stop complete */
+#define FEC_ENET_TXF	((uint)0x08000000)	/* Full frame transmitted */
+#define FEC_ENET_TXB	((uint)0x04000000)	/* A buffer was transmitted */
+#define FEC_ENET_RXF	((uint)0x02000000)	/* Full frame received */
+#define FEC_ENET_RXB	((uint)0x01000000)	/* A buffer was received */
+#define FEC_ENET_MII	((uint)0x00800000)	/* MII interrupt */
+#define FEC_ENET_EBERR	((uint)0x00400000)	/* SDMA bus error */
+
+/* PHY identification
+ */
+#define PHY_ID_LXT970		0x78100000	/* LXT970 */
+#define PHY_ID_LXT971		0x001378e0	/* LXT971 and 972 */
+#define PHY_ID_82555		0x02a80150	/* Intel 82555 */
+#define PHY_ID_QS6612		0x01814400	/* QS6612 */
+#define PHY_ID_AMD79C784	0x00225610	/* AMD 79C784 */
+#define PHY_ID_LSI80225		0x0016f870	/* LSI 80225 */
+#define PHY_ID_LSI80225B	0x0016f880	/* LSI 80225/B */
+
+
+/* send command to phy using mii, wait for result */
+static uint
+mii_send(uint mii_cmd)
+{
+	uint mii_reply;
+	volatile fec_t	*ep;
+
+	ep = &(((immap_t *)CFG_IMMR)->im_cpm.cp_fec);
+
+	ep->fec_mii_data = mii_cmd;	/* command to phy */
+
+	/* wait for mii complete */
+	while (!(ep->fec_ievent & FEC_ENET_MII))
+		;	/* spin until done */
+	mii_reply = ep->fec_mii_data;		/* result from phy */
+	ep->fec_ievent = FEC_ENET_MII;		/* clear MII complete */
+#if 0
+	printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
+		__FILE__,__LINE__,__FUNCTION__,mii_cmd,mii_reply);
+#endif
+	return (mii_reply & 0xffff);		/* data read from phy */
+}
+#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */
+
+#if defined(CFG_DISCOVER_PHY)
+static void
+mii_discover_phy(void)
+{
+#define MAX_PHY_PASSES 11
+	uint phyno;
+	int  pass;
+
+	phyaddr = -1;	/* didn't find a PHY yet */
+	for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
+		if (pass > 1) {
+			/* PHY may need more time to recover from reset.
+			 * The LXT970 needs 50ms typical, no maximum is
+			 * specified, so wait 10ms before try again.
+			 * With 11 passes this gives it 100ms to wake up.
+			 */
+			udelay(10000);	/* wait 10ms */
+		}
+		for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
+			phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1));
+#ifdef ET_DEBUG
+			printf("PHY type 0x%x pass %d type ", phytype, pass);
+#endif
+			if (phytype != 0xffff) {
+				phyaddr = phyno;
+				phytype <<= 16;
+				phytype |= mii_send(mk_mii_read(phyno,
+								PHY_PHYIDR2));
+
+#ifdef ET_DEBUG
+				printf("PHY @ 0x%x pass %d type ",phyno,pass);
+				switch (phytype & 0xfffffff0) {
+				case PHY_ID_LXT970:
+					printf("LXT970\n");
+					break;
+				case PHY_ID_LXT971:
+					printf("LXT971\n");
+					break;
+				case PHY_ID_82555:
+					printf("82555\n");
+					break;
+				case PHY_ID_QS6612:
+					printf("QS6612\n");
+					break;
+				case PHY_ID_AMD79C784:
+					printf("AMD79C784\n");
+					break;
+				case PHY_ID_LSI80225B:
+					printf("LSI L80225/B\n");
+					break;
+				default:
+					printf("0x%08x\n", phytype);
+					break;
+				}
+#endif
+			}
+		}
+	}
+	if (phyaddr < 0) {
+		printf("No PHY device found.\n");
+	}
+}
+#endif	/* CFG_DISCOVER_PHY */
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)
+
+static int mii_init_done = 0;
+
+/****************************************************************************
+ * mii_init -- Initialize the MII for MII command without ethernet
+ * This function is a subset of eth_init
+ ****************************************************************************
+ */
+void mii_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	bd_t *bd = gd->bd;
+
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+	volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+	int i;
+
+	if (mii_init_done != 0) {
+		return;
+	}
+
+	/* Whack a reset.
+	 * A delay is required between a reset of the FEC block and
+	 * initialization of other FEC registers because the reset takes
+	 * some time to complete. If you don't delay, subsequent writes
+	 * to FEC registers might get killed by the reset routine which is
+	 * still in progress.
+	 */
+
+	fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
+	for (i = 0;
+	     (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+	     ++i) {
+		udelay (1);
+	}
+	if (i == FEC_RESET_DELAY) {
+		printf ("FEC_RESET_DELAY timeout\n");
+		return;
+	}
+
+	/* We use strictly polling mode only
+	 */
+	fecp->fec_imask = 0;
+
+	/* Clear any pending interrupt
+	 */
+	fecp->fec_ievent = 0xffc0;
+
+	/* Set MII speed to 2.5 MHz or slightly below.
+	 * According to the MPC860T (Rev. D) Fast ethernet controller user
+	 * manual (6.2.14),
+	 * the MII management interface clock must be less than or equal
+	 * to 2.5 MHz.
+	 * This MDC frequency is equal to system clock / (2 * MII_SPEED).
+	 * Then MII_SPEED = system_clock / 2 * 2,5 Mhz.
+	 */
+	fecp->fec_mii_speed = ((bd->bi_busfreq + 4999999) / 5000000) << 1;
+
+#if !defined(CONFIG_ICU862) && !defined(CONFIG_IAD210)
+	/* Configure all of port D for MII.
+	 */
+	immr->im_ioport.iop_pdpar = 0x1fff;
+
+	/* Bits moved from Rev. D onward */
+	if ((get_immr (0) & 0xffff) < 0x0501) {
+		immr->im_ioport.iop_pddir = 0x1c58;	/* Pre rev. D */
+	} else {
+		immr->im_ioport.iop_pddir = 0x1fff;	/* Rev. D and later */
+	}
+#else
+	/* Configure port A for MII.
+	*/
+
+#if defined(CONFIG_ICU862)
+
+	/* On the ICU862 board the MII-MDC pin is routed to PD8 pin
+	 * of CPU, so for this board we need to configure Utopia and
+	 * enable PD8 to MII-MDC function */
+	immr->im_ioport.iop_pdpar |= 0x4080;
+#endif
+
+	/* Has Utopia been configured? */
+	if (immr->im_ioport.iop_pdpar & (0x8000 >> 1)) {
+		/*
+		 * YES - Use MUXED mode for UTOPIA bus.
+		 * This frees Port A for use by MII (see 862UM table 41-6).
+		 */
+		immr->im_ioport.utmode &= ~0x80;
+	} else {
+		/*
+		 * NO - set SPLIT mode for UTOPIA bus.
+		 *
+		 * This doesn't really effect UTOPIA (which isn't
+		 * enabled anyway) but just tells the 862
+		 * to use port A for MII (see 862UM table 41-6).
+		 */
+		immr->im_ioport.utmode |= 0x80;
+	}
+#endif	/* !defined(CONFIG_ICU862) */
+	/* Now enable the transmit and receive processing
+	 */
+	fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
+
+	mii_init_done = 1;
+}
+/*****************************************************************************
+ * Read and write a MII PHY register, routines used by MII Utilities
+ *
+ * FIXME: These routines are expected to return 0 on success, but mii_send
+ *	  does _not_ return an error code. Maybe 0xFFFF means error, i.e.
+ *	  no PHY connected...
+ *	  For now always return 0.
+ * FIXME: These routines only work after calling eth_init() at least once!
+ *	  Otherwise they hang in mii_send() !!! Sorry!
+ *****************************************************************************/
+
+int miiphy_read(unsigned char addr, unsigned char  reg, unsigned short *value)
+{
+	short rdreg;    /* register working value */
+
+#ifdef MII_DEBUG
+	printf ("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
+#endif
+	rdreg = mii_send(mk_mii_read(addr, reg));
+
+	*value = rdreg;
+
+#ifdef MII_DEBUG
+	printf ("0x%04x\n", *value);
+#endif
+
+	return 0;
+}
+
+int miiphy_write(unsigned char  addr, unsigned char  reg, unsigned short value)
+{
+	short rdreg;    /* register working value */
+
+#ifdef MII_DEBUG
+	printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
+#endif
+
+	rdreg = mii_send(mk_mii_write(addr, reg, value));
+
+#ifdef MII_DEBUG
+	printf ("0x%04x\n", value);
+#endif
+
+	return 0;
+}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)*/
+
+#endif	/* CFG_CMD_NET, FEC_ENET */
diff --git a/cpu/mpc8xx/spi.c b/cpu/mpc8xx/spi.c
new file mode 100644
index 0000000..f04d88e
--- /dev/null
+++ b/cpu/mpc8xx/spi.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2001 Navin Boppuri / Prashant Patel
+ *	<nboppuri@trinetcommunication.com>,
+ *	<pmpatel@trinetcommunication.com>
+ * Copyright (c) 2001 Gerd Mennchen <Gerd.Mennchen@icn.siemens.de>
+ * Copyright (c) 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
+ */
+
+/*
+ * MPC8xx CPM SPI interface.
+ *
+ * Parts of this code are probably not portable and/or specific to
+ * the board which I used for the tests. Please send fixes/complaints
+ * to wd@denx.de
+ *
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <commproc.h>
+#include <linux/ctype.h>
+#include <malloc.h>
+#include <post.h>
+#include <net.h>
+
+#if (defined(CONFIG_SPI)) || (CONFIG_POST & CFG_POST_SPI)
+
+/* Warning:
+ * You cannot enable DEBUG for early system initalization, i. e. when
+ * this driver is used to read environment parameters like "baudrate"
+ * from EEPROM which are used to initialize the serial port which is
+ * needed to print the debug messages...
+ */
+#undef	DEBUG
+
+#define SPI_EEPROM_WREN		0x06
+#define SPI_EEPROM_RDSR		0x05
+#define SPI_EEPROM_READ		0x03
+#define SPI_EEPROM_WRITE	0x02
+
+/* ---------------------------------------------------------------
+ * Offset for initial SPI buffers in DPRAM:
+ * We need a 520 byte scratch DPRAM area to use at an early stage.
+ * It is used between the two initialization calls (spi_init_f()
+ * and spi_init_r()).
+ * The value 0xb00 makes it far enough from the start of the data
+ * area (as well as from the stack pointer).
+ * --------------------------------------------------------------- */
+#ifndef	CFG_SPI_INIT_OFFSET
+#define	CFG_SPI_INIT_OFFSET	0xB00
+#endif
+
+#ifdef	DEBUG
+
+#define	DPRINT(a)	printf a;
+/* -----------------------------------------------
+ * Helper functions to peek into tx and rx buffers
+ * ----------------------------------------------- */
+static const char * const hex_digit = "0123456789ABCDEF";
+
+static char quickhex (int i)
+{
+	return hex_digit[i];
+}
+
+static void memdump (void *pv, int num)
+{
+	int i;
+	unsigned char *pc = (unsigned char *) pv;
+
+	for (i = 0; i < num; i++)
+		printf ("%c%c ", quickhex (pc[i] >> 4), quickhex (pc[i] & 0x0f));
+	printf ("\t");
+	for (i = 0; i < num; i++)
+		printf ("%c", isprint (pc[i]) ? pc[i] : '.');
+	printf ("\n");
+}
+#else	/* !DEBUG */
+
+#define	DPRINT(a)
+
+#endif	/* DEBUG */
+
+/* -------------------
+ * Function prototypes
+ * ------------------- */
+void spi_init (void);
+
+ssize_t spi_read (uchar *, int, uchar *, int);
+ssize_t spi_write (uchar *, int, uchar *, int);
+ssize_t spi_xfer (size_t);
+
+/* -------------------
+ * Variables
+ * ------------------- */
+
+#define MAX_BUFFER	0x104
+
+/* ----------------------------------------------------------------------
+ * Initially we place the RX and TX buffers at a fixed location in DPRAM!
+ * ---------------------------------------------------------------------- */
+static uchar *rxbuf =
+  (uchar *)&((cpm8xx_t *)&((immap_t *)CFG_IMMR)->im_cpm)->cp_dpmem
+			[CFG_SPI_INIT_OFFSET];
+static uchar *txbuf =
+  (uchar *)&((cpm8xx_t *)&((immap_t *)CFG_IMMR)->im_cpm)->cp_dpmem
+			[CFG_SPI_INIT_OFFSET+MAX_BUFFER];
+
+/* **************************************************************************
+ *
+ *  Function:    spi_init_f
+ *
+ *  Description: Init SPI-Controller (ROM part)
+ *
+ *  return:      ---
+ *
+ * *********************************************************************** */
+void spi_init_f (void)
+{
+	unsigned int dpaddr;
+
+	volatile spi_t *spi;
+	volatile immap_t *immr;
+	volatile cpic8xx_t *cpi;
+	volatile cpm8xx_t *cp;
+	volatile iop8xx_t *iop;
+	volatile cbd_t *tbdf, *rbdf;
+
+	immr = (immap_t *)  CFG_IMMR;
+	cpi  = (cpic8xx_t *)&immr->im_cpic;
+	iop  = (iop8xx_t *) &immr->im_ioport;
+	cp   = (cpm8xx_t *) &immr->im_cpm;
+
+#ifdef CFG_SPI_UCODE_PATCH
+	spi  = (spi_t *)&cp->cp_dpmem[spi->spi_rpbase];
+#else
+	spi  = (spi_t *)&cp->cp_dparam[PROFF_SPI];
+	/* Disable relocation */
+	spi->spi_rpbase = 0;
+#endif
+
+/* 1 */
+	/* ------------------------------------------------
+	 * Initialize Port B SPI pins -> page 34-8 MPC860UM
+	 * (we are only in Master Mode !)
+	 * ------------------------------------------------ */
+
+	/* --------------------------------------------
+	 * GPIO or per. Function
+	 * PBPAR[28] = 1 [0x00000008] -> PERI: (SPIMISO)
+	 * PBPAR[29] = 1 [0x00000004] -> PERI: (SPIMOSI)
+	 * PBPAR[30] = 1 [0x00000002] -> PERI: (SPICLK)
+	 * PBPAR[31] = 0 [0x00000001] -> GPIO: (CS for PCUE/CCM-EEPROM)
+	 * -------------------------------------------- */
+	cp->cp_pbpar |=  0x0000000E;	/* set  bits	*/
+	cp->cp_pbpar &= ~0x00000001;	/* reset bit	*/
+
+	/* ----------------------------------------------
+	 * In/Out or per. Function 0/1
+	 * PBDIR[28] = 1 [0x00000008] -> PERI1: SPIMISO
+	 * PBDIR[29] = 1 [0x00000004] -> PERI1: SPIMOSI
+	 * PBDIR[30] = 1 [0x00000002] -> PERI1: SPICLK
+	 * PBDIR[31] = 1 [0x00000001] -> GPIO OUT: CS for PCUE/CCM-EEPROM
+	 * ---------------------------------------------- */
+	cp->cp_pbdir |= 0x0000000F;
+
+	/* ----------------------------------------------
+	 * open drain or active output
+	 * PBODR[28] = 1 [0x00000008] -> open drain: SPIMISO
+	 * PBODR[29] = 0 [0x00000004] -> active output SPIMOSI
+	 * PBODR[30] = 0 [0x00000002] -> active output: SPICLK
+	 * PBODR[31] = 0 [0x00000001] -> active output: GPIO OUT: CS for PCUE/CCM
+	 * ---------------------------------------------- */
+
+	cp->cp_pbodr |=  0x00000008;
+	cp->cp_pbodr &= ~0x00000007;
+
+	/* Initialize the parameter ram.
+	 * We need to make sure many things are initialized to zero
+	 */
+	spi->spi_rstate	= 0;
+	spi->spi_rdp	= 0;
+	spi->spi_rbptr	= 0;
+	spi->spi_rbc	= 0;
+	spi->spi_rxtmp	= 0;
+	spi->spi_tstate	= 0;
+	spi->spi_tdp	= 0;
+	spi->spi_tbptr	= 0;
+	spi->spi_tbc	= 0;
+	spi->spi_txtmp	= 0;
+
+	/* Allocate space for one transmit and one receive buffer
+	 * descriptor in the DP ram
+	 */
+#ifdef CFG_ALLOC_DPRAM
+	dpaddr = dpram_alloc_align (sizeof(cbd_t)*2, 8);
+#else
+	dpaddr = CPM_SPI_BASE;
+#endif
+
+/* 3 */
+	/* Set up the SPI parameters in the parameter ram */
+	spi->spi_rbase = dpaddr;
+	spi->spi_tbase = dpaddr + sizeof (cbd_t);
+
+	/***********IMPORTANT******************/
+
+        /*
+         * Setting transmit and receive buffer descriptor pointers
+         * initially to rbase and tbase. Only the microcode patches
+         * documentation talks about initializing this pointer. This
+         * is missing from the sample I2C driver. If you dont
+         * initialize these pointers, the kernel hangs.
+	 */
+	spi->spi_rbptr = spi->spi_rbase;
+	spi->spi_tbptr = spi->spi_tbase;
+
+/* 4 */
+#ifdef CFG_SPI_UCODE_PATCH
+	/*
+	 *  Initialize required parameters if using microcode patch.
+	 */
+	spi->spi_rstate = 0;
+	spi->spi_tstate = 0;
+#else
+	/* Init SPI Tx + Rx Parameters */
+	while (cp->cp_cpcr & CPM_CR_FLG)
+		;
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SPI, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG)
+		;
+#endif	/* CFG_SPI_UCODE_PATCH */
+
+/* 5 */
+	/* Set SDMA configuration register */
+	immr->im_siu_conf.sc_sdcr = 0x0001;
+
+/* 6 */
+	/* Set to big endian. */
+	spi->spi_tfcr = SMC_EB;
+	spi->spi_rfcr = SMC_EB;
+
+/* 7 */
+	/* Set maximum receive size. */
+	spi->spi_mrblr = MAX_BUFFER;
+
+/* 8 + 9 */
+	/* tx and rx buffer descriptors */
+	tbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_tbase];
+	rbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_rbase];
+
+	tbdf->cbd_sc &= ~BD_SC_READY;
+	rbdf->cbd_sc &= ~BD_SC_EMPTY;
+
+	/* Set the bd's rx and tx buffer address pointers */
+	rbdf->cbd_bufaddr = (ulong) rxbuf;
+	tbdf->cbd_bufaddr = (ulong) txbuf;
+
+/* 10 + 11 */
+	cp->cp_spim = 0;			/* Mask  all SPI events */
+	cp->cp_spie = SPI_EMASK;		/* Clear all SPI events	*/
+
+	return;
+}
+
+/* **************************************************************************
+ *
+ *  Function:    spi_init_r
+ *
+ *  Description: Init SPI-Controller (RAM part) -
+ *		 The malloc engine is ready and we can move our buffers to
+ *		 normal RAM
+ *
+ *  return:      ---
+ *
+ * *********************************************************************** */
+void spi_init_r (void)
+{
+	volatile cpm8xx_t *cp;
+	volatile spi_t *spi;
+	volatile immap_t *immr;
+	volatile cbd_t *tbdf, *rbdf;
+
+	immr = (immap_t *)  CFG_IMMR;
+	cp   = (cpm8xx_t *) &immr->im_cpm;
+
+#ifdef CFG_SPI_UCODE_PATCH
+	spi  = (spi_t *)&cp->cp_dpmem[spi->spi_rpbase];
+#else
+	spi  = (spi_t *)&cp->cp_dparam[PROFF_SPI];
+	/* Disable relocation */
+	spi->spi_rpbase = 0;
+#endif
+
+	/* tx and rx buffer descriptors */
+	tbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_tbase];
+	rbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_rbase];
+
+	/* Allocate memory for RX and TX buffers */
+	rxbuf = (uchar *) malloc (MAX_BUFFER);
+	txbuf = (uchar *) malloc (MAX_BUFFER);
+
+	rbdf->cbd_bufaddr = (ulong) rxbuf;
+	tbdf->cbd_bufaddr = (ulong) txbuf;
+
+	return;
+}
+
+/****************************************************************************
+ *  Function:    spi_write
+ **************************************************************************** */
+ssize_t spi_write (uchar *addr, int alen, uchar *buffer, int len)
+{
+	int i;
+
+	memset(rxbuf, 0, MAX_BUFFER);
+	memset(txbuf, 0, MAX_BUFFER);
+	*txbuf = SPI_EEPROM_WREN;		/* write enable		*/
+	spi_xfer(1);
+	memcpy(txbuf, addr, alen);
+	*txbuf = SPI_EEPROM_WRITE;		/* WRITE memory array	*/
+	memcpy(alen + txbuf, buffer, len);
+	spi_xfer(alen + len);
+						/* ignore received data	*/
+	for (i = 0; i < 1000; i++) {
+		*txbuf = SPI_EEPROM_RDSR;	/* read status		*/
+		txbuf[1] = 0;
+		spi_xfer(2);
+		if (!(rxbuf[1] & 1)) {
+			break;
+		}
+		udelay(1000);
+	}
+	if (i >= 1000) {
+		printf ("*** spi_write: Time out while writing!\n");
+	}
+
+	return len;
+}
+
+/****************************************************************************
+ *  Function:    spi_read
+ **************************************************************************** */
+ssize_t spi_read (uchar *addr, int alen, uchar *buffer, int len)
+{
+	memset(rxbuf, 0, MAX_BUFFER);
+	memset(txbuf, 0, MAX_BUFFER);
+	memcpy(txbuf, addr, alen);
+	*txbuf = SPI_EEPROM_READ;		/* READ memory array	*/
+
+	/*
+	 * There is a bug in 860T (?) that cuts the last byte of input
+	 * if we're reading into DPRAM. The solution we choose here is
+	 * to always read len+1 bytes (we have one extra byte at the
+	 * end of the buffer).
+	 */
+	spi_xfer(alen + len + 1);
+	memcpy(buffer, alen + rxbuf, len);
+
+	return len;
+}
+
+/****************************************************************************
+ *  Function:    spi_xfer
+ **************************************************************************** */
+ssize_t spi_xfer (size_t count)
+{
+	volatile immap_t *immr;
+	volatile cpm8xx_t *cp;
+	volatile spi_t *spi;
+	cbd_t *tbdf, *rbdf;
+	ushort loop;
+	int tm;
+
+	DPRINT (("*** spi_xfer entered ***\n"));
+
+	immr = (immap_t *) CFG_IMMR;
+	cp   = (cpm8xx_t *) &immr->im_cpm;
+
+#ifdef CFG_SPI_UCODE_PATCH
+	spi  = (spi_t *)&cp->cp_dpmem[spi->spi_rpbase];
+#else
+	spi  = (spi_t *)&cp->cp_dparam[PROFF_SPI];
+	/* Disable relocation */
+	spi->spi_rpbase = 0;
+#endif
+
+	tbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_tbase];
+	rbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_rbase];
+
+	/* Set CS for device */
+	cp->cp_pbdat &= ~0x0001;
+
+	/* Setting tx bd status and data length */
+	tbdf->cbd_sc  = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP;
+	tbdf->cbd_datlen = count;
+
+	DPRINT (("*** spi_xfer: Bytes to be xferred: %d ***\n",
+							tbdf->cbd_datlen));
+
+	/* Setting rx bd status and data length */
+	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+	rbdf->cbd_datlen = 0;	 /* rx length has no significance */
+
+	loop = cp->cp_spmode & SPMODE_LOOP;
+	cp->cp_spmode = /*SPMODE_DIV16	|*/	/* BRG/16 mode not used here */
+			loop		|
+			SPMODE_REV	|
+			SPMODE_MSTR	|
+			SPMODE_EN	|
+			SPMODE_LEN(8)	|	/* 8 Bits per char */
+			SPMODE_PM(0x8) ;	/* medium speed */
+	cp->cp_spim = 0;			/* Mask  all SPI events */
+	cp->cp_spie = SPI_EMASK;		/* Clear all SPI events	*/
+
+	/* start spi transfer */
+	DPRINT (("*** spi_xfer: Performing transfer ...\n"));
+	cp->cp_spcom |= SPI_STR;		/* Start transmit */
+
+	/* --------------------------------
+	 * Wait for SPI transmit to get out
+	 * or time out (1 second = 1000 ms)
+	 * -------------------------------- */
+	for (tm=0; tm<1000; ++tm) {
+		if (cp->cp_spie & SPI_TXB) {	/* Tx Buffer Empty */
+			DPRINT (("*** spi_xfer: Tx buffer empty\n"));
+			break;
+		}
+		if ((tbdf->cbd_sc & BD_SC_READY) == 0) {
+			DPRINT (("*** spi_xfer: Tx BD done\n"));
+			break;
+		}
+		udelay (1000);
+	}
+	if (tm >= 1000) {
+		printf ("*** spi_xfer: Time out while xferring to/from SPI!\n");
+	}
+	DPRINT (("*** spi_xfer: ... transfer ended\n"));
+
+#ifdef	DEBUG
+	printf ("\nspi_xfer: txbuf after xfer\n");
+	memdump ((void *) txbuf, 16);	/* dump of txbuf before transmit */
+	printf ("spi_xfer: rxbuf after xfer\n");
+	memdump ((void *) rxbuf, 16);	/* dump of rxbuf after transmit */
+	printf ("\n");
+#endif
+
+	/* Clear CS for device */
+	cp->cp_pbdat |= 0x0001;
+
+	return count;
+}
+#endif	/* CONFIG_SPI || (CONFIG_POST & CFG_POST_SPI) */
+
+/*
+ * SPI test
+ *
+ * The Serial Peripheral Interface (SPI) is tested in the local loopback mode.
+ * The interface is configured accordingly and several packets
+ * are transfered. The configurable test parameters are:
+ *   TEST_MIN_LENGTH - minimum size of packet to transfer
+ *   TEST_MAX_LENGTH - maximum size of packet to transfer
+ *   TEST_NUM - number of tests
+ */
+
+#if CONFIG_POST & CFG_POST_SPI
+
+#define TEST_MIN_LENGTH		1
+#define TEST_MAX_LENGTH		MAX_BUFFER
+#define TEST_NUM		1
+
+static void packet_fill (char * packet, int length)
+{
+	char c = (char) length;
+	int i;
+
+	for (i = 0; i < length; i++)
+	{
+	    packet[i] = c++;
+	}
+}
+
+static int packet_check (char * packet, int length)
+{
+	char c = (char) length;
+	int i;
+
+	for (i = 0; i < length; i++)
+	{
+	    if (packet[i] != c++) return -1;
+	}
+
+	return 0;
+}
+
+int spi_post_test (int flags)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int res = -1;
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+	volatile cpm8xx_t *cp = (cpm8xx_t *) &immr->im_cpm;
+	int i;
+	int l;
+
+	spi_init_f();
+	spi_init_r();
+
+	cp->cp_spmode |= SPMODE_LOOP;
+
+	for (i = 0; i < TEST_NUM; i++)
+	{
+	    for (l = TEST_MIN_LENGTH; l <= TEST_MAX_LENGTH; l += 8)
+	    {
+		packet_fill(txbuf, l);
+
+		spi_xfer(l);
+
+		if (packet_check(rxbuf, l) < 0)
+		{
+		    goto Done;
+		}
+	    }
+	}
+
+	res = 0;
+
+	Done:
+
+	cp->cp_spmode &= ~SPMODE_LOOP;
+
+	/*
+	 * SCC2 Ethernet parameter RAM space overlaps
+	 * the SPI parameter RAM space. So we need to restore
+	 * the SCC2 configuration if it is used by UART or Ethernet.
+	 */
+
+#if defined(CONFIG_8xx_CONS_SCC2)
+	serial_init();
+#endif
+
+#if defined(SCC_ENET) && (SCC_ENET == 1)
+	eth_init(gd->bd);
+#endif
+
+	if (res != 0)
+	{
+		post_log("SPI test failed\n");
+	}
+
+	return res;
+}
+#endif	/* CONFIG_POST & CFG_POST_SPI */
diff --git a/cpu/ppc4xx/405gp_enet.c b/cpu/ppc4xx/405gp_enet.c
new file mode 100644
index 0000000..49e9e42
--- /dev/null
+++ b/cpu/ppc4xx/405gp_enet.c
@@ -0,0 +1,867 @@
+/*-----------------------------------------------------------------------------+
+ *
+ *       This source code has been made available to you by IBM on an AS-IS
+ *       basis.  Anyone receiving this source is licensed under IBM
+ *       copyrights to use it in any way he or she deems fit, including
+ *       copying it, modifying it, compiling it, and redistributing it either
+ *       with or without modifications.  No license under IBM patents or
+ *       patent applications is to be implied by the copyright license.
+ *
+ *       Any user of this software should understand that IBM cannot provide
+ *       technical support for this software and will not be responsible for
+ *       any consequences resulting from the use of this software.
+ *
+ *       Any person who transfers this source code or any derivative work
+ *       must include the IBM copyright notice, this paragraph, and the
+ *       preceding two paragraphs in the transferred software.
+ *
+ *       COPYRIGHT   I B M   CORPORATION 1995
+ *       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+ *-----------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------+
+ *
+ *  File Name:  enetemac.c
+ *
+ *  Function:   Device driver for the ethernet EMAC3 macro on the 405GP.
+ *
+ *  Author:     Mark Wisner
+ *
+ *  Change Activity-
+ *
+ *  Date        Description of Change                                       BY
+ *  ---------   ---------------------                                       ---
+ *  05-May-99   Created                                                     MKW
+ *  27-Jun-99   Clean up                                                    JWB
+ *  16-Jul-99   Added MAL error recovery and better IP packet handling      MKW
+ *  29-Jul-99   Added Full duplex support                                   MKW
+ *  06-Aug-99   Changed names for Mal CR reg                                MKW
+ *  23-Aug-99   Turned off SYE when running at 10Mbs                        MKW
+ *  24-Aug-99   Marked descriptor empty after call_xlc                      MKW
+ *  07-Sep-99   Set MAL RX buffer size reg to ENET_MAX_MTU_ALIGNED / 16     MCG
+ *              to avoid chaining maximum sized packets. Push starting
+ *              RX descriptor address up to the next cache line boundary.
+ *  16-Jan-00   Added support for booting with IP of 0x0                    MKW
+ *  15-Mar-00   Updated enetInit() to enable broadcast addresses in the
+ *	        EMAC_RXM register.                                          JWB
+ *  12-Mar-01   anne-sophie.harnois@nextream.fr
+ *               - Variables are compatible with those already defined in
+ *                include/net.h
+ *              - Receive buffer descriptor ring is used to send buffers
+ *                to the user
+ *              - Info print about send/received/handled packet number if
+ *                INFO_405_ENET is set
+ *  17-Apr-01   stefan.roese@esd-electronics.com
+ *              - MAL reset in "eth_halt" included
+ *              - Enet speed and duplex output now in one line
+ *  08-May-01   stefan.roese@esd-electronics.com
+ *              - MAL error handling added (eth_init called again)
+ *  13-Nov-01   stefan.roese@esd-electronics.com
+ *              - Set IST bit in EMAC_M1 reg upon 100MBit or full duplex
+ *  04-Jan-02   stefan.roese@esd-electronics.com
+ *              - Wait for PHY auto negotiation to complete added
+ *  06-Feb-02   stefan.roese@esd-electronics.com
+ *              - Bug fixed in waiting for auto negotiation to complete
+ *  26-Feb-02   stefan.roese@esd-electronics.com
+ *              - rx and tx buffer descriptors now allocated (no fixed address
+ *                used anymore)
+ *  17-Jun-02   stefan.roese@esd-electronics.com
+ *              - MAL error debug printf 'M' removed (rx de interrupt may
+ *                occur upon many incoming packets with only 4 rx buffers).
+ *-----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <asm/processor.h>
+#include <ppc4xx.h>
+#include <commproc.h>
+#include <405gp_enet.h>
+#include <405_mal.h>
+#include <miiphy.h>
+#include <net.h>
+#include <malloc.h>
+#include "vecnum.h"
+
+#if defined(CONFIG_405GP) || defined(CONFIG_440)
+
+#define EMAC_RESET_TIMEOUT 1000	/* 1000 ms reset timeout */
+#define PHY_AUTONEGOTIATE_TIMEOUT 2000	/* 2000 ms autonegotiate timeout */
+
+#define NUM_TX_BUFF 1
+/* AS.HARNOIS
+ * Use PKTBUFSRX (include/net.h) instead of setting NUM_RX_BUFF again
+ * These both variables are used to define the same thing!
+ * #define NUM_RX_BUFF 4
+ */
+#define NUM_RX_BUFF PKTBUFSRX
+
+/* Ethernet Transmit and Receive Buffers */
+/* AS.HARNOIS
+ * In the same way ENET_MAX_MTU and ENET_MAX_MTU_ALIGNED are set from
+ * PKTSIZE and PKTSIZE_ALIGN (include/net.h)
+ */
+#define ENET_MAX_MTU           PKTSIZE
+#define ENET_MAX_MTU_ALIGNED   PKTSIZE_ALIGN
+
+static char *txbuf_ptr;
+
+/* define the number of channels implemented */
+#define EMAC_RXCHL      1
+#define EMAC_TXCHL      1
+
+/*-----------------------------------------------------------------------------+
+ * Defines for MAL/EMAC interrupt conditions as reported in the UIC (Universal
+ * Interrupt Controller).
+ *-----------------------------------------------------------------------------*/
+#define MAL_UIC_ERR ( UIC_MAL_SERR | UIC_MAL_TXDE  | UIC_MAL_RXDE)
+#define MAL_UIC_DEF  (UIC_MAL_RXEOB | MAL_UIC_ERR)
+#define EMAC_UIC_DEF UIC_ENET
+
+/*-----------------------------------------------------------------------------+
+ * Global variables. TX and RX descriptors and buffers.
+ *-----------------------------------------------------------------------------*/
+static volatile mal_desc_t *tx;
+static volatile mal_desc_t *rx;
+static mal_desc_t *alloc_tx_buf = NULL;
+static mal_desc_t *alloc_rx_buf = NULL;
+
+/* IER globals */
+static unsigned long emac_ier;
+static unsigned long mal_ier;
+
+
+/* Statistic Areas */
+#define MAX_ERR_LOG 10
+struct emac_stats {
+	int data_len_err;
+	int rx_frames;
+	int rx;
+	int rx_prot_err;
+};
+
+static struct stats {			/* Statistic Block */
+	struct emac_stats emac;
+	int int_err;
+	short tx_err_log[MAX_ERR_LOG];
+	short rx_err_log[MAX_ERR_LOG];
+} stats;
+
+static int first_init = 0;
+
+static int tx_err_index = 0;	/* Transmit Error Index for tx_err_log */
+static int rx_err_index = 0;	/* Receive Error Index for rx_err_log */
+
+static int rx_slot = 0;			/* MAL Receive Slot */
+static int rx_i_index = 0;		/* Receive Interrupt Queue Index */
+static int rx_u_index = 0;		/* Receive User Queue Index */
+static int rx_ready[NUM_RX_BUFF];	/* Receive Ready Queue */
+
+static int tx_slot = 0;			/* MAL Transmit Slot */
+static int tx_i_index = 0;		/* Transmit Interrupt Queue Index */
+static int tx_u_index = 0;		/* Transmit User Queue Index */
+static int tx_run[NUM_TX_BUFF];	/* Transmit Running Queue */
+
+#undef INFO_405_ENET 1
+#ifdef INFO_405_ENET
+static int packetSent = 0;
+static int packetReceived = 0;
+static int packetHandled = 0;
+#endif
+
+static char emac_hwd_addr[ENET_ADDR_LENGTH];
+
+static bd_t *bis_save = NULL;	/* for eth_init upon mal error */
+
+static int is_receiving = 0;	/* sync with eth interrupt */
+static int print_speed = 1;	/* print speed message upon start */
+
+static void enet_rcv (unsigned long malisr);
+
+/*-----------------------------------------------------------------------------+
+ * Prototypes and externals.
+ *-----------------------------------------------------------------------------*/
+void mal_err (unsigned long isr, unsigned long uic, unsigned long mal_def,
+	      unsigned long mal_errr);
+void emac_err (unsigned long isr);
+
+
+void eth_halt (void)
+{
+	mtdcr (malier, 0x00000000);	/* disable mal interrupts */
+	out32 (EMAC_IER, 0x00000000);	/* disable emac interrupts */
+
+	/* 1st reset MAL */
+	mtdcr (malmcr, MAL_CR_MMSR);
+
+	/* wait for reset */
+	while (mfdcr (malmcr) & MAL_CR_MMSR) {
+	};
+
+	/* EMAC RESET */
+	out32 (EMAC_M0, EMAC_M0_SRST);
+
+	print_speed = 1;		/* print speed message again next time */
+}
+
+
+int eth_init (bd_t * bis)
+{
+	int i;
+	unsigned long reg;
+	unsigned long msr;
+	unsigned long speed;
+	unsigned long duplex;
+	unsigned mode_reg;
+	unsigned short reg_short;
+
+	msr = mfmsr ();
+	mtmsr (msr & ~(MSR_EE));	/* disable interrupts */
+
+#ifdef INFO_405_ENET
+	/* AS.HARNOIS
+	 * We should have :
+	 * packetHandled <=  packetReceived <= packetHandled+PKTBUFSRX
+         * In the most cases packetHandled = packetReceived, but it
+         * is possible that new packets (without relationship with
+         * current transfer) have got the time to arrived before
+         * netloop calls eth_halt
+	 */
+	printf ("About preceeding transfer:\n"
+		"- Sent packet number %d\n"
+		"- Received packet number %d\n"
+		"- Handled packet number %d\n",
+		packetSent, packetReceived, packetHandled);
+	packetSent = 0;
+	packetReceived = 0;
+	packetHandled = 0;
+#endif
+
+	/* MAL RESET */
+	mtdcr (malmcr, MAL_CR_MMSR);
+	/* wait for reset */
+	while (mfdcr (malmcr) & MAL_CR_MMSR) {
+	};
+
+	tx_err_index = 0;		/* Transmit Error Index for tx_err_log */
+	rx_err_index = 0;		/* Receive Error Index for rx_err_log */
+
+	rx_slot = 0;			/* MAL Receive Slot */
+	rx_i_index = 0;			/* Receive Interrupt Queue Index */
+	rx_u_index = 0;			/* Receive User Queue Index */
+
+	tx_slot = 0;			/* MAL Transmit Slot */
+	tx_i_index = 0;			/* Transmit Interrupt Queue Index */
+	tx_u_index = 0;			/* Transmit User Queue Index */
+
+#if defined(CONFIG_440)
+        /* set RMII mode */
+        out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
+#endif /* CONFIG_440 */
+
+	/* EMAC RESET */
+	out32 (EMAC_M0, EMAC_M0_SRST);
+
+	/* wait for PHY to complete auto negotiation */
+	reg_short = 0;
+#ifndef CONFIG_CS8952_PHY
+	miiphy_read (CONFIG_PHY_ADDR, PHY_BMSR, &reg_short);
+
+	/*
+	 * Wait if PHY is able of autonegotiation and autonegotiation is not complete
+	 */
+	if ((reg_short & PHY_BMSR_AUTN_ABLE)
+	    && !(reg_short & PHY_BMSR_AUTN_COMP)) {
+		puts ("Waiting for PHY auto negotiation to complete");
+		i = 0;
+		while (!(reg_short & PHY_BMSR_AUTN_COMP)) {
+			if ((i++ % 100) == 0)
+				putc ('.');
+			udelay (10000);		/* 10 ms */
+			miiphy_read (CONFIG_PHY_ADDR, PHY_BMSR, &reg_short);
+
+			/*
+			 * Timeout reached ?
+			 */
+			if (i * 10 > PHY_AUTONEGOTIATE_TIMEOUT) {
+				puts (" TIMEOUT !\n");
+				break;
+			}
+		}
+		puts (" done\n");
+		udelay (500000);	/* another 500 ms (results in faster booting) */
+	}
+#endif
+	speed = miiphy_speed (CONFIG_PHY_ADDR);
+	duplex = miiphy_duplex (CONFIG_PHY_ADDR);
+	if (print_speed) {
+		print_speed = 0;
+		printf ("ENET Speed is %d Mbps - %s duplex connection\n",
+			(int) speed, (duplex == HALF) ? "HALF" : "FULL");
+	}
+
+	/* set the Mal configuration reg */
+#if defined(CONFIG_440)
+	/* Errata 1.12: MAL_1 -- Disable MAL bursting */
+	if( get_pvr() == PVR_440GP_RB )
+	    mtdcr (malmcr, MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
+	else
+#else
+	mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
+#endif
+
+	/* Free "old" buffers */
+	if (alloc_tx_buf) free(alloc_tx_buf);
+	if (alloc_rx_buf) free(alloc_rx_buf);
+
+	/*
+	 * Malloc MAL buffer desciptors, make sure they are
+	 * aligned on cache line boundary size
+	 * (401/403/IOP480 = 16, 405 = 32)
+	 * and doesn't cross cache block boundaries.
+	 */
+	alloc_tx_buf = (mal_desc_t *)malloc((sizeof(mal_desc_t) * NUM_TX_BUFF) +
+					    ((2 * CFG_CACHELINE_SIZE) - 2));
+	if (((int)alloc_tx_buf & CACHELINE_MASK) != 0) {
+		tx = (mal_desc_t *)((int)alloc_tx_buf + CFG_CACHELINE_SIZE -
+				    ((int)alloc_tx_buf & CACHELINE_MASK));
+	} else {
+		tx = alloc_tx_buf;
+	}
+
+	alloc_rx_buf = (mal_desc_t *)malloc((sizeof(mal_desc_t) * NUM_RX_BUFF) +
+					    ((2 * CFG_CACHELINE_SIZE) - 2));
+	if (((int)alloc_rx_buf & CACHELINE_MASK) != 0) {
+		rx = (mal_desc_t *)((int)alloc_rx_buf + CFG_CACHELINE_SIZE -
+				    ((int)alloc_rx_buf & CACHELINE_MASK));
+	} else {
+		rx = alloc_rx_buf;
+	}
+
+	for (i = 0; i < NUM_TX_BUFF; i++) {
+		tx[i].ctrl = 0;
+		tx[i].data_len = 0;
+		if (first_init == 0)
+			txbuf_ptr = (char *) malloc (ENET_MAX_MTU_ALIGNED);
+		tx[i].data_ptr = txbuf_ptr;
+		if ((NUM_TX_BUFF - 1) == i)
+			tx[i].ctrl |= MAL_TX_CTRL_WRAP;
+		tx_run[i] = -1;
+#if 0
+		printf ("TX_BUFF %d @ 0x%08lx\n", i, (ulong) tx[i].data_ptr);
+#endif
+	}
+
+	for (i = 0; i < NUM_RX_BUFF; i++) {
+		rx[i].ctrl = 0;
+		rx[i].data_len = 0;
+		/*       rx[i].data_ptr = (char *) &rx_buff[i]; */
+		rx[i].data_ptr = (char *) NetRxPackets[i];
+		if ((NUM_RX_BUFF - 1) == i)
+			rx[i].ctrl |= MAL_RX_CTRL_WRAP;
+		rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
+		rx_ready[i] = -1;
+#if 0
+		printf ("RX_BUFF %d @ 0x%08lx\n", i, (ulong) rx[i].data_ptr);
+#endif
+	}
+
+	memcpy (emac_hwd_addr, bis->bi_enetaddr, ENET_ADDR_LENGTH);
+
+	reg = 0x00000000;
+
+	reg |= emac_hwd_addr[0];	/* set high address */
+	reg = reg << 8;
+	reg |= emac_hwd_addr[1];
+
+	out32 (EMAC_IAH, reg);
+
+	reg = 0x00000000;
+	reg |= emac_hwd_addr[2];	/* set low address  */
+	reg = reg << 8;
+	reg |= emac_hwd_addr[3];
+	reg = reg << 8;
+	reg |= emac_hwd_addr[4];
+	reg = reg << 8;
+	reg |= emac_hwd_addr[5];
+
+	out32 (EMAC_IAL, reg);
+
+	/* setup MAL tx & rx channel pointers */
+	mtdcr (maltxctp0r, tx);
+	mtdcr (malrxctp0r, rx);
+
+	/* Reset transmit and receive channels */
+	mtdcr (malrxcarr, 0x80000000);	/* 2 channels */
+	mtdcr (maltxcarr, 0x80000000);	/* 2 channels */
+
+	/* Enable MAL transmit and receive channels */
+	mtdcr (maltxcasr, 0x80000000);	/* 1 channel */
+	mtdcr (malrxcasr, 0x80000000);	/* 1 channel */
+
+	/* set RX buffer size */
+	mtdcr (malrcbs0, ENET_MAX_MTU_ALIGNED / 16);
+
+	/* set transmit enable & receive enable */
+	out32 (EMAC_M0, EMAC_M0_TXE | EMAC_M0_RXE);
+
+	/* set receive fifo to 4k and tx fifo to 2k */
+	mode_reg = EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K;
+
+	/* set speed */
+	if (speed == _100BASET)
+		mode_reg = mode_reg | EMAC_M1_MF_100MBPS | EMAC_M1_IST;
+	else
+		mode_reg = mode_reg & ~0x00C00000;	/* 10 MBPS */
+	if (duplex == FULL)
+		mode_reg = mode_reg | 0x80000000 | EMAC_M1_IST;
+
+	out32 (EMAC_M1, mode_reg);
+
+	/* Enable broadcast and indvidual address */
+	out32 (EMAC_RXM, EMAC_RMR_BAE | EMAC_RMR_IAE
+	       /*| EMAC_RMR_ARRP| EMAC_RMR_SFCS | EMAC_RMR_SP */ );
+
+	/* we probably need to set the tx mode1 reg? maybe at tx time */
+
+	/* set transmit request threshold register */
+	out32 (EMAC_TRTR, 0x18000000);	/* 256 byte threshold */
+
+	/* set receive  low/high water mark register */
+#if defined(CONFIG_440)
+	/* 440GP has a 64 byte burst length */
+        out32 (EMAC_RX_HI_LO_WMARK, 0x80009000);
+        out32 (EMAC_TXM1,           0xf8640000);
+#else /* CONFIG_440 */
+	/* 405s have a 16 byte burst length */
+	out32 (EMAC_RX_HI_LO_WMARK, 0x0f002000);
+#endif /* CONFIG_440 */
+
+	/* Frame gap set */
+	out32 (EMAC_I_FRAME_GAP_REG, 0x00000008);
+
+	if (first_init == 0) {
+		/*
+		 * Connect interrupt service routines
+		 */
+		irq_install_handler (VECNUM_EWU0, (interrupt_handler_t *) enetInt, NULL);
+		irq_install_handler (VECNUM_MS, (interrupt_handler_t *) enetInt, NULL);
+		irq_install_handler (VECNUM_MTE, (interrupt_handler_t *) enetInt, NULL);
+		irq_install_handler (VECNUM_MRE, (interrupt_handler_t *) enetInt, NULL);
+		irq_install_handler (VECNUM_TXDE, (interrupt_handler_t *) enetInt, NULL);
+		irq_install_handler (VECNUM_RXDE, (interrupt_handler_t *) enetInt, NULL);
+		irq_install_handler (VECNUM_ETH0, (interrupt_handler_t *) enetInt, NULL);
+	}
+
+	/* set up interrupt handler */
+	/* setup interrupt controler to take interrupts from the MAL &
+	   EMAC */
+	mtdcr (uicsr, 0xffffffff);	/* clear pending interrupts */
+	mtdcr (uicer, mfdcr (uicer) | MAL_UIC_DEF | EMAC_UIC_DEF);
+
+	/* set the MAL IER ??? names may change with new spec ??? */
+	mal_ier = MAL_IER_DE | MAL_IER_NE | MAL_IER_TE | MAL_IER_OPBE |
+		MAL_IER_PLBE;
+	mtdcr (malesr, 0xffffffff);	/* clear pending interrupts */
+	mtdcr (maltxdeir, 0xffffffff);	/* clear pending interrupts */
+	mtdcr (malrxdeir, 0xffffffff);	/* clear pending interrupts */
+	mtdcr (malier, mal_ier);
+
+	/* Set EMAC IER */
+	emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS |
+		EMAC_ISR_PTLE | EMAC_ISR_ORE  | EMAC_ISR_IRE;
+	if (speed == _100BASET)
+		emac_ier = emac_ier | EMAC_ISR_SYE;
+
+	out32 (EMAC_ISR, 0xffffffff);	/* clear pending interrupts */
+	out32 (EMAC_IER, emac_ier);
+
+	mtmsr (msr);				/* enable interrupts again */
+
+	bis_save = bis;
+	first_init = 1;
+
+	return (0);
+}
+
+
+int eth_send (volatile void *ptr, int len)
+{
+	struct enet_frame *ef_ptr;
+	ulong time_start, time_now;
+	unsigned long temp_txm0;
+
+	ef_ptr = (struct enet_frame *) ptr;
+
+	/*-----------------------------------------------------------------------+
+	 *  Copy in our address into the frame.
+	 *-----------------------------------------------------------------------*/
+	(void) memcpy (ef_ptr->source_addr, emac_hwd_addr, ENET_ADDR_LENGTH);
+
+	/*-----------------------------------------------------------------------+
+	 * If frame is too long or too short, modify length.
+	 *-----------------------------------------------------------------------*/
+	if (len > ENET_MAX_MTU)
+		len = ENET_MAX_MTU;
+
+	/*   memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */
+	memcpy ((void *) txbuf_ptr, (const void *) ptr, len);
+
+	/*-----------------------------------------------------------------------+
+	 * set TX Buffer busy, and send it
+	 *-----------------------------------------------------------------------*/
+	tx[tx_slot].ctrl = (MAL_TX_CTRL_LAST |
+			    EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP) &
+		~(EMAC_TX_CTRL_ISA | EMAC_TX_CTRL_RSA);
+	if ((NUM_TX_BUFF - 1) == tx_slot)
+		tx[tx_slot].ctrl |= MAL_TX_CTRL_WRAP;
+
+	tx[tx_slot].data_len = (short) len;
+	tx[tx_slot].ctrl |= MAL_TX_CTRL_READY;
+
+    __asm__ volatile ("eieio");
+	out32 (EMAC_TXM0, in32 (EMAC_TXM0) | EMAC_TXM0_GNP0);
+#ifdef INFO_405_ENET
+	packetSent++;
+#endif
+
+	/*-----------------------------------------------------------------------+
+	 * poll unitl the packet is sent and then make sure it is OK
+	 *-----------------------------------------------------------------------*/
+	time_start = get_timer (0);
+	while (1) {
+		temp_txm0 = in32 (EMAC_TXM0);
+		/* loop until either TINT turns on or 3 seconds elapse */
+		if ((temp_txm0 & EMAC_TXM0_GNP0) != 0) {
+			/* transmit is done, so now check for errors
+                         * If there is an error, an interrupt should
+                         * happen when we return
+			 */
+			time_now = get_timer (0);
+			if ((time_now - time_start) > 3000) {
+				return (-1);
+			}
+		} else {
+			return (0);
+		}
+	}
+}
+
+
+#if defined(CONFIG_440)
+/*-----------------------------------------------------------------------------+
+| EnetInt.
+| EnetInt is the interrupt handler.  It will determine the
+| cause of the interrupt and call the apporpriate servive
+| routine.
++-----------------------------------------------------------------------------*/
+int enetInt ()
+{
+	int serviced;
+	int rc = -1;				/* default to not us */
+	unsigned long mal_isr;
+	unsigned long emac_isr = 0;
+	unsigned long mal_rx_eob;
+	unsigned long my_uic0msr, my_uic1msr;
+
+	/* enter loop that stays in interrupt code until nothing to service */
+	do {
+		serviced = 0;
+
+		my_uic0msr = mfdcr (uic0msr);
+		my_uic1msr = mfdcr (uic1msr);
+
+		if (!(my_uic0msr & UIC_MRE)
+                    && !(my_uic1msr & (UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE))) {
+                        /* not for us */
+			return (rc);
+		}
+
+		/* get and clear controller status interrupts */
+		/* look at Mal and EMAC interrupts */
+		if ((my_uic0msr & UIC_MRE)
+                    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
+                        /* we have a MAL interrupt */
+			mal_isr = mfdcr (malesr);
+			/* look for mal error */
+			if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) {
+				mal_err (mal_isr, my_uic0msr, MAL_UIC_DEF, MAL_UIC_ERR);
+				serviced = 1;
+				rc = 0;
+			}
+		}
+		if (UIC_ETH0 & my_uic1msr) {	/* look for EMAC errors */
+			emac_isr = in32 (EMAC_ISR);
+			if ((emac_ier & emac_isr) != 0) {
+				emac_err (emac_isr);
+				serviced = 1;
+				rc = 0;
+			}
+		}
+		if ((emac_ier & emac_isr)
+                    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
+			mtdcr (uic0sr, UIC_MRE); /* Clear */
+			mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+			return (rc);		/* we had errors so get out */
+		}
+
+		/* handle MAL RX EOB  interupt from a receive */
+		/* check for EOB on valid channels            */
+		if (my_uic0msr & UIC_MRE) {
+			mal_rx_eob = mfdcr (malrxeobisr);
+			if ((mal_rx_eob & 0x80000000) != 0) {	/* call emac routine for channel 0 */
+				/* clear EOB
+				   mtdcr(malrxeobisr, mal_rx_eob); */
+				enet_rcv (emac_isr);
+				/* indicate that we serviced an interrupt */
+				serviced = 1;
+				rc = 0;
+			}
+		}
+                mtdcr (uic0sr, UIC_MRE); /* Clear */
+                mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+	} while (serviced);
+
+	return (rc);
+}
+#else /* CONFIG_440 */
+/*-----------------------------------------------------------------------------+
+ * EnetInt.
+ * EnetInt is the interrupt handler.  It will determine the
+ * cause of the interrupt and call the apporpriate servive
+ * routine.
+ *-----------------------------------------------------------------------------*/
+int enetInt ()
+{
+	int serviced;
+	int rc = -1;				/* default to not us */
+	unsigned long mal_isr;
+	unsigned long emac_isr = 0;
+	unsigned long mal_rx_eob;
+	unsigned long my_uicmsr;
+
+	/* enter loop that stays in interrupt code until nothing to service */
+	do {
+		serviced = 0;
+
+		my_uicmsr = mfdcr (uicmsr);
+		if ((my_uicmsr & (MAL_UIC_DEF | EMAC_UIC_DEF)) == 0) {	/* not for us */
+			return (rc);
+		}
+
+
+		/* get and clear controller status interrupts */
+		/* look at Mal and EMAC interrupts */
+		if ((MAL_UIC_DEF & my_uicmsr) != 0) {	/* we have a MAL interrupt */
+			mal_isr = mfdcr (malesr);
+			/* look for mal error */
+			if ((my_uicmsr & MAL_UIC_ERR) != 0) {
+				mal_err (mal_isr, my_uicmsr, MAL_UIC_DEF, MAL_UIC_ERR);
+				serviced = 1;
+				rc = 0;
+			}
+		}
+		if ((EMAC_UIC_DEF & my_uicmsr) != 0) {	/* look for EMAC errors */
+			emac_isr = in32 (EMAC_ISR);
+			if ((emac_ier & emac_isr) != 0) {
+				emac_err (emac_isr);
+				serviced = 1;
+				rc = 0;
+			}
+		}
+		if (((emac_ier & emac_isr) != 0) | ((MAL_UIC_ERR & my_uicmsr) != 0)) {
+			mtdcr (uicsr, MAL_UIC_DEF | EMAC_UIC_DEF); /* Clear */
+			return (rc);		/* we had errors so get out */
+		}
+
+
+		/* handle MAL RX EOB  interupt from a receive */
+		/* check for EOB on valid channels            */
+		if ((my_uicmsr & UIC_MAL_RXEOB) != 0) {
+			mal_rx_eob = mfdcr (malrxeobisr);
+			if ((mal_rx_eob & 0x80000000) != 0) {	/* call emac routine for channel 0 */
+				/* clear EOB
+				   mtdcr(malrxeobisr, mal_rx_eob); */
+				enet_rcv (emac_isr);
+				/* indicate that we serviced an interrupt */
+				serviced = 1;
+				rc = 0;
+			}
+		}
+		mtdcr (uicsr, MAL_UIC_DEF | EMAC_UIC_DEF);	/* Clear */
+	}
+	while (serviced);
+
+	return (rc);
+}
+#endif /* CONFIG_440 */
+
+/*-----------------------------------------------------------------------------+
+ *  MAL Error Routine
+ *-----------------------------------------------------------------------------*/
+void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef,
+	      unsigned long mal_errr)
+{
+	mtdcr (malesr, isr);		/* clear interrupt */
+
+	/* clear DE interrupt */
+	mtdcr (maltxdeir, 0xC0000000);
+	mtdcr (malrxdeir, 0x80000000);
+
+#if 1	/*sr */
+	printf ("\nMAL error occured.... ISR = %lx UIC = = %lx  MAL_DEF = %lx  MAL_ERR= %lx \n",
+		isr, uic, maldef, mal_errr);
+#else
+#if 0
+	/*
+	 * MAL error is RX DE error (out of rx buffers)! This is OK here, upon
+	 * many incoming packets with only 4 rx buffers.
+	 */
+	printf ("M");			/* just to see something upon mal error */
+#endif
+#endif	/*sr */
+
+	eth_init (bis_save);		/* start again... */
+}
+
+/*-----------------------------------------------------------------------------+
+ *  EMAC Error Routine
+ *-----------------------------------------------------------------------------*/
+void emac_err (unsigned long isr)
+{
+	printf ("EMAC error occured.... ISR = %lx\n", isr);
+	out32 (EMAC_ISR, isr);
+}
+
+/*-----------------------------------------------------------------------------+
+ *  enet_rcv() handles the ethernet receive data
+ *-----------------------------------------------------------------------------*/
+static void enet_rcv (unsigned long malisr)
+{
+	struct enet_frame *ef_ptr;
+	unsigned long data_len;
+	unsigned long rx_eob_isr;
+
+	int handled = 0;
+	int i;
+	int loop_count = 0;
+
+	rx_eob_isr = mfdcr (malrxeobisr);
+	if ((0x80000000 >> (EMAC_RXCHL - 1)) & rx_eob_isr) {
+		/* clear EOB */
+		mtdcr (malrxeobisr, rx_eob_isr);
+
+		/* EMAC RX done */
+		while (1) {				/* do all */
+			i = rx_slot;
+
+			if ((MAL_RX_CTRL_EMPTY & rx[i].ctrl)
+			    || (loop_count >= NUM_RX_BUFF))
+				break;
+			loop_count++;
+			rx_slot++;
+			if (NUM_RX_BUFF == rx_slot)
+				rx_slot = 0;
+			handled++;
+			data_len = (unsigned long) rx[i].data_len;	/* Get len */
+			if (data_len) {
+				if (data_len > ENET_MAX_MTU)	/* Check len */
+					data_len = 0;
+				else {
+					if (EMAC_RX_ERRORS & rx[i].ctrl) {	/* Check Errors */
+						data_len = 0;
+						stats.rx_err_log[rx_err_index] = rx[i].ctrl;
+						rx_err_index++;
+						if (rx_err_index == MAX_ERR_LOG)
+							rx_err_index = 0;
+					}	/* emac_erros         */
+				}		/* data_len < max mtu */
+			}			/* if data_len        */
+			if (!data_len) {	/* no data */
+				rx[i].ctrl |= MAL_RX_CTRL_EMPTY;	/* Free Recv Buffer */
+
+				stats.emac.data_len_err++;	/* Error at Rx */
+			}
+
+			/* !data_len */
+			/* AS.HARNOIS */
+			/* Check if user has already eaten buffer */
+			/* if not => ERROR */
+			else if (rx_ready[rx_i_index] != -1) {
+				if (is_receiving)
+					printf ("ERROR : Receive buffers are full!\n");
+				break;
+			} else {
+				stats.emac.rx_frames++;
+				stats.emac.rx += data_len;
+				ef_ptr = (struct enet_frame *) rx[i].data_ptr;
+#ifdef INFO_405_ENET
+				packetReceived++;
+#endif
+				/* AS.HARNOIS
+				 * use ring buffer
+				 */
+				rx_ready[rx_i_index] = i;
+				rx_i_index++;
+				if (NUM_RX_BUFF == rx_i_index)
+					rx_i_index = 0;
+
+				/* printf("X");  /|* test-only *|/ */
+
+				/*  AS.HARNOIS
+				 * free receive buffer only when
+				 * buffer has been handled (eth_rx)
+				 rx[i].ctrl |= MAL_RX_CTRL_EMPTY;
+				*/
+			}			/* if data_len */
+		}				/* while */
+	}					/* if EMACK_RXCHL */
+}
+
+
+int eth_rx (void)
+{
+	int length;
+	int user_index;
+	unsigned long msr;
+
+	is_receiving = 1;			/* tell driver */
+
+	for (;;) {
+		/* AS.HARNOIS
+		 * use ring buffer and
+		 * get index from rx buffer desciptor queue
+		 */
+		user_index = rx_ready[rx_u_index];
+		if (user_index == -1) {
+			length = -1;
+			break;	/* nothing received - leave for() loop */
+		}
+
+		msr = mfmsr ();
+		mtmsr (msr & ~(MSR_EE));
+
+		length = rx[user_index].data_len;
+
+		/* Pass the packet up to the protocol layers. */
+		/*       NetReceive(NetRxPackets[rxIdx], length - 4); */
+		/*       NetReceive(NetRxPackets[i], length); */
+		NetReceive (NetRxPackets[user_index], length - 4);
+		/* Free Recv Buffer */
+		rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;
+		/* Free rx buffer descriptor queue */
+		rx_ready[rx_u_index] = -1;
+		rx_u_index++;
+		if (NUM_RX_BUFF == rx_u_index)
+			rx_u_index = 0;
+
+#ifdef INFO_405_ENET
+		packetHandled++;
+#endif
+
+		mtmsr (msr);			/* Enable IRQ's */
+	}
+
+	is_receiving = 0;			/* tell driver */
+
+	return length;
+}
+
+#endif	/* CONFIG_405GP */
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
new file mode 100644
index 0000000..1c2c59b
--- /dev/null
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -0,0 +1,502 @@
+/*-----------------------------------------------------------------------------+
+ *
+ *       This source code has been made available to you by IBM on an AS-IS
+ *       basis.  Anyone receiving this source is licensed under IBM
+ *       copyrights to use it in any way he or she deems fit, including
+ *       copying it, modifying it, compiling it, and redistributing it either
+ *       with or without modifications.  No license under IBM patents or
+ *       patent applications is to be implied by the copyright license.
+ *
+ *       Any user of this software should understand that IBM cannot provide
+ *       technical support for this software and will not be responsible for
+ *       any consequences resulting from the use of this software.
+ *
+ *       Any person who transfers this source code or any derivative work
+ *       must include the IBM copyright notice, this paragraph, and the
+ *       preceding two paragraphs in the transferred software.
+ *
+ *       COPYRIGHT   I B M   CORPORATION 1995
+ *       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+ *-----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+ *
+ *  File Name:   405gp_pci.c
+ *
+ *  Function:    Initialization code for the 405GP PCI Configuration regs.
+ *
+ *  Author:      Mark Game
+ *
+ *  Change Activity-
+ *
+ *  Date        Description of Change                                       BY
+ *  ---------   ---------------------                                       ---
+ *  09-Sep-98   Created                                                     MCG
+ *  02-Nov-98   Removed External arbiter selected message                   JWB
+ *  27-Nov-98   Zero out PTMBAR2 and disable in PTM2MS                      JWB
+ *  04-Jan-99   Zero out other unused PMM and PTM regs. Change bus scan     MCG
+ *              from (0 to n) to (1 to n).
+ *  17-May-99   Port to Walnut                                              JWB
+ *  17-Jun-99   Updated for VGA support                                     JWB
+ *  21-Jun-99   Updated to allow SRAM region to be a target from PCI bus    JWB
+ *  19-Jul-99   Updated for 405GP pass 1 errata #26 (Low PCI subsequent     MCG
+ *              target latency timer values are not supported).
+ *              Should be fixed in pass 2.
+ *  09-Sep-99   Removed use of PTM2 since the SRAM region no longer needs   JWB
+ *              to be a PCI target. Zero out PTMBAR2 and disable in PTM2MS.
+ *  10-Dec-99   Updated PCI_Write_CFG_Reg for pass2 errata #6               JWB
+ *  11-Jan-00   Ensure PMMxMAs disabled before setting PMMxLAs. This is not
+ *              really required after a reset since PMMxMAs are already
+ * 	        disabled but is a good practice nonetheless.                JWB
+ *  12-Jun-01   stefan.roese@esd-electronics.com
+ *              - PCI host/adapter handling reworked
+ *  09-Jul-01   stefan.roese@esd-electronics.com
+ *              - PCI host now configures from device 0 (not 1) to max_dev,
+ *                (host configures itself)
+ *              - On CPCI-405 pci base address and size is generated from
+ *                SDRAM and FLASH size (CFG regs not used anymore)
+ *              - Some minor changes for CPCI-405-A (adapter version)
+ *  14-Sep-01   stefan.roese@esd-electronics.com
+ *              - CONFIG_PCI_SCAN_SHOW added to print pci devices upon startup
+ *  28-Sep-01   stefan.roese@esd-electronics.com
+ *              - Changed pci master configuration for linux compatibility
+ *                (no need for bios_fixup() anymore)
+ *  26-Feb-02   stefan.roese@esd-electronics.com
+ *              - Bug fixed in pci configuration (Andrew May)
+ *              - Removed pci class code init for CPCI405 board
+ *  15-May-02   stefan.roese@esd-electronics.com
+ *              - New vga device handling
+ *  29-May-02   stefan.roese@esd-electronics.com
+ *              - PCI class code init added (if defined)
+ *----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <command.h>
+#include <cmd_boot.h>
+#if !defined(CONFIG_440)
+#include <405gp_pci.h>
+#endif
+#include <asm/processor.h>
+#include <pci.h>
+
+#if defined(CONFIG_405GP)
+
+#ifdef CONFIG_PCI
+
+/*#define DEBUG*/
+
+/*-----------------------------------------------------------------------------+
+ * pci_init.  Initializes the 405GP PCI Configuration regs.
+ *-----------------------------------------------------------------------------*/
+void pci_405gp_init(struct pci_controller *hose)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int i, reg_num = 0;
+	bd_t *bd = gd->bd;
+
+	unsigned short temp_short;
+	unsigned long ptmpcila[2] = {CFG_PCI_PTM1PCI, CFG_PCI_PTM2PCI};
+#if defined(CONFIG_CPCI405)
+	unsigned long ptmla[2]    = {bd->bi_memstart, bd->bi_flashstart};
+	unsigned long ptmms[2]    = {~(bd->bi_memsize - 1) | 1, ~(bd->bi_flashsize - 1) | 1};
+#else
+	unsigned long ptmla[2]    = {CFG_PCI_PTM1LA, CFG_PCI_PTM2LA};
+	unsigned long ptmms[2]    = {CFG_PCI_PTM1MS, CFG_PCI_PTM2MS};
+#endif
+#if defined(CONFIG_PIP405) || defined (CONFIG_MIP405)
+	unsigned long pmmla[3]    = {0x80000000, 0xA0000000, 0};
+	unsigned long pmmma[3]    = {0xE0000001, 0xE0000001, 0};
+	unsigned long pmmpcila[3] = {0x80000000, 0x00000000, 0};
+	unsigned long pmmpciha[3] = {0x00000000, 0x00000000, 0};
+#else
+	unsigned long pmmla[3]    = {0x80000000, 0,0};
+	unsigned long pmmma[3]    = {0xC0000001, 0,0};
+	unsigned long pmmpcila[3] = {0x80000000, 0,0};
+	unsigned long pmmpciha[3] = {0x00000000, 0,0};
+#endif
+
+	/*
+	 * Register the hose
+	 */
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	/* ISA/PCI I/O space */
+	pci_set_region(hose->regions + reg_num++,
+		       MIN_PCI_PCI_IOADDR,
+		       MIN_PLB_PCI_IOADDR,
+		       0x10000,
+		       PCI_REGION_IO);
+
+	/* PCI I/O space */
+	pci_set_region(hose->regions + reg_num++,
+		       0x00800000,
+		       0xe8800000,
+		       0x03800000,
+		       PCI_REGION_IO);
+
+	reg_num = 2;
+
+	/* Memory spaces */
+	for (i=0; i<2; i++)
+		if (ptmms[i] & 1)
+		{
+			if (!i) hose->pci_fb = hose->regions + reg_num;
+
+			pci_set_region(hose->regions + reg_num++,
+				       ptmpcila[i], ptmla[i],
+				       ~(ptmms[i] & 0xfffff000) + 1,
+				       PCI_REGION_MEM |
+				       PCI_REGION_MEMORY);
+		}
+
+	/* PCI memory spaces */
+	for (i=0; i<3; i++)
+		if (pmmma[i] & 1)
+		{
+			pci_set_region(hose->regions + reg_num++,
+				       pmmpcila[i], pmmla[i],
+				       ~(pmmma[i] & 0xfffff000) + 1,
+				       PCI_REGION_MEM);
+		}
+
+	hose->region_count = reg_num;
+
+	pci_setup_indirect(hose,
+			   PCICFGADR,
+			   PCICFGDATA);
+
+	if (hose->pci_fb)
+		pciauto_region_init(hose->pci_fb);
+
+	pci_register_hose(hose);
+
+	/*--------------------------------------------------------------------------+
+	 * 405GP PCI Master configuration.
+	 * Map one 512 MB range of PLB/processor addresses to PCI memory space.
+	 * PLB address 0x80000000-0xBFFFFFFF ==> PCI address 0x80000000-0xBFFFFFFF
+	 * Use byte reversed out routines to handle endianess.
+	 *--------------------------------------------------------------------------*/
+	out32r(PMM0MA,    pmmma[0]);          /* ensure disabled b4 setting PMM0LA */
+	out32r(PMM0LA,    pmmla[0]);
+	out32r(PMM0PCILA, pmmpcila[0]);
+	out32r(PMM0PCIHA, pmmpciha[0]);
+	out32r(PMM0MA,    pmmma[0]);
+
+	/*--------------------------------------------------------------------------+
+	 * PMM1 is not used.  Initialize them to zero.
+	 *--------------------------------------------------------------------------*/
+	out32r(PMM1MA,    pmmma[1]);          /* ensure disabled b4 setting PMM2LA */
+	out32r(PMM1LA,    pmmla[1]);
+	out32r(PMM1PCILA, pmmpcila[1]);
+	out32r(PMM1PCIHA, pmmpciha[1]);
+	out32r(PMM1MA,    pmmma[1]);
+
+	/*--------------------------------------------------------------------------+
+	 * PMM2 is not used.  Initialize them to zero.
+	 *--------------------------------------------------------------------------*/
+	out32r(PMM2MA,    pmmma[2]);          /* ensure disabled b4 setting PMM2LA */
+	out32r(PMM2LA,    pmmla[2]);
+	out32r(PMM2PCILA, pmmpcila[2]);
+	out32r(PMM2PCIHA, pmmpciha[2]);
+	out32r(PMM2MA,    pmmma[2]);
+
+	/*--------------------------------------------------------------------------+
+	 * 405GP PCI Target configuration.  (PTM1)
+	 * Note: PTM1MS is hardwire enabled but we set the enable bit anyway.
+	 *--------------------------------------------------------------------------*/
+	out32r(PTM1LA,    ptmla[0]);         /* insert address                     */
+	out32r(PTM1MS,    ptmms[0]);         /* insert size, enable bit is 1       */
+
+	/*--------------------------------------------------------------------------+
+	 * 405GP PCI Target configuration.  (PTM2)
+	 *--------------------------------------------------------------------------*/
+	out32r(PTM2LA, ptmla[1]);            /* insert address                     */
+	if (ptmms[1] == 0)
+	{
+		out32r(PTM2MS,    0x00000001);   /* set enable bit                     */
+		pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, 0x00000000);
+		out32r(PTM2MS,    0x00000000);   /* disable                            */
+	}
+	else
+	{
+		out32r(PTM2MS, ptmms[1]);        /* insert size, enable bit is 1       */
+	}
+
+	/*
+	 * Insert Subsystem Vendor and Device ID
+	 */
+	pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_VENDOR_ID, CFG_PCI_SUBSYS_VENDORID);
+#ifdef CONFIG_CPCI405
+	if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+		pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_DEVICEID);
+	else
+		pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_DEVICEID2);
+#else
+	pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_DEVICEID);
+#endif
+
+	/*
+	 * Insert Class-code
+	 */
+#ifdef CFG_PCI_CLASSCODE
+	pci_write_config_word(PCIDEVID_405GP, PCI_CLASS_SUB_CODE, CFG_PCI_CLASSCODE);
+#endif /* CFG_PCI_CLASSCODE */
+
+	/*--------------------------------------------------------------------------+
+	 * If PCI speed = 66Mhz, set 66Mhz capable bit.
+	 *--------------------------------------------------------------------------*/
+	if (bd->bi_pci_busfreq >= 66000000) {
+		pci_read_config_word(PCIDEVID_405GP, PCI_STATUS, &temp_short);
+		pci_write_config_word(PCIDEVID_405GP,PCI_STATUS,(temp_short|PCI_STATUS_66MHZ));
+	}
+
+#if (CONFIG_PCI_HOST != PCI_HOST_ADAPTER)
+#if (CONFIG_PCI_HOSE == PCI_HOST_AUTO)
+	if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+#endif
+	{
+		/*--------------------------------------------------------------------------+
+		 * Write the 405GP PCI Configuration regs.
+		 * Enable 405GP to be a master on the PCI bus (PMM).
+		 * Enable 405GP to act as a PCI memory target (PTM).
+		 *--------------------------------------------------------------------------*/
+		pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &temp_short);
+		pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND, temp_short |
+				      PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+	}
+#endif
+
+	/*
+	 * Set HCE bit (Host Configuration Enabled)
+	 */
+	pci_read_config_word(PCIDEVID_405GP, PCIBRDGOPT2, &temp_short);
+	pci_write_config_word(PCIDEVID_405GP, PCIBRDGOPT2, (temp_short | 0x0001));
+
+#ifdef CONFIG_PCI_PNP
+	/*--------------------------------------------------------------------------+
+	 * Scan the PCI bus and configure devices found.
+	 *--------------------------------------------------------------------------*/
+#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
+	if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+#endif
+	{
+#ifdef CONFIG_PCI_SCAN_SHOW
+		printf("PCI:   Bus Dev VenId DevId Class Int\n");
+#endif
+
+		hose->last_busno = pci_hose_scan(hose);
+	}
+#endif  /* CONFIG_PCI_PNP */
+
+}
+
+/*
+ * drivers/pci.c skips every host bridge but the 405GP since it could
+ * be set as an Adapter.
+ *
+ * I (Andrew May) don't know what we should do here, but I don't want
+ * the auto setup of a PCI device disabling what is done pci_405gp_init
+ * as has happened before.
+ */
+void pci_405gp_setup_bridge(struct pci_controller *hose, pci_dev_t dev,
+			    struct pci_config_table *entry)
+{
+#ifdef DEBUG
+        printf("405gp_setup_bridge\n");
+#endif
+}
+
+/*
+ *
+ */
+
+void pci_405gp_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	unsigned char int_line = 0xff;
+
+	/*
+	 * Write pci interrupt line register (cpci405 specific)
+	 */
+	switch (PCI_DEV(dev) & 0x03)
+	{
+	case 0:
+		int_line = 27 + 2;
+		break;
+	case 1:
+		int_line = 27 + 3;
+		break;
+	case 2:
+		int_line = 27 + 0;
+		break;
+	case 3:
+		int_line = 27 + 1;
+		break;
+	}
+
+	pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
+}
+
+void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
+			 struct pci_config_table *entry)
+{
+	unsigned int cmdstat = 0;
+
+	pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+
+	/* always enable io space on vga boards */
+	pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+	cmdstat |= PCI_COMMAND_IO;
+	pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
+}
+
+#if !(defined(CONFIG_PIP405) || defined (CONFIG_MIP405))
+
+/*
+ *As is these functs get called out of flash Not a horrible
+ *thing, but something to keep in mind. (no statics?)
+ */
+static struct pci_config_table pci_405gp_config_table[] = {
+/*if VendID is 0 it terminates the table search (ie Walnut)*/
+#if CFG_PCI_SUBSYS_VENDORID
+	{CFG_PCI_SUBSYS_VENDORID, PCI_ANY_ID, PCI_CLASS_BRIDGE_HOST,
+	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_bridge},
+#endif
+	{PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_vga},
+
+	{PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_vga},
+
+	{ }
+};
+
+static struct pci_controller hose = {
+	fixup_irq: pci_405gp_fixup_irq,
+	config_table: pci_405gp_config_table,
+};
+
+void pci_init(void)
+{
+	/*we want the ptrs to RAM not flash (ie don't use init list)*/
+	hose.fixup_irq    = pci_405gp_fixup_irq;
+	hose.config_table = pci_405gp_config_table;
+	pci_405gp_init(&hose);
+}
+
+#endif
+
+#endif /* CONFIG_PCI */
+
+#endif /* CONFIG_405GP */
+
+/*-----------------------------------------------------------------------------+
+ * CONFIG_440
+ *-----------------------------------------------------------------------------*/
+#if defined(CONFIG_440) && defined(CONFIG_PCI)
+
+static struct pci_controller ppc440_hose = {0};
+
+
+void pci_440_init (struct pci_controller *hose)
+{
+	int reg_num = 0;
+	unsigned long strap;
+
+	/*--------------------------------------------------------------------------+
+	 * The PCI initialization sequence enable bit must be set ... if not abort
+     * pci setup since updating the bit requires chip reset.
+	 *--------------------------------------------------------------------------*/
+    strap = mfdcr(cpc0_strp1);
+    if( (strap & 0x00040000) == 0 ){
+        printf("PCI: CPC0_STRP1[PISE] not set.\n");
+        printf("PCI: Configuration aborted.\n");
+        return;
+    }
+
+	/*--------------------------------------------------------------------------+
+	 * PCI controller init
+	 *--------------------------------------------------------------------------*/
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	pci_set_region(hose->regions + reg_num++,
+		       0x00000000,
+			   PCIX0_IOBASE,
+			   0x10000,
+			   PCI_REGION_IO);
+
+	pci_set_region(hose->regions + reg_num++,
+		       CFG_PCI_TARGBASE,
+			   CFG_PCI_MEMBASE,
+			   0x10000000,
+			   PCI_REGION_MEM );
+	hose->region_count = reg_num;
+
+	pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA);
+
+#if defined(CFG_PCI_PRE_INIT)
+    /* Let board change/modify hose & do initial checks */
+    if( pci_pre_init (hose) == 0 ){
+        printf("PCI: Board-specific initialization failed.\n");
+        printf("PCI: Configuration aborted.\n");
+        return;
+    }
+#endif
+
+	pci_register_hose( hose );
+
+	/*--------------------------------------------------------------------------+
+	 * PCI target init
+	 *--------------------------------------------------------------------------*/
+#if defined(CFG_PCI_TARGET_INIT)
+	pci_target_init(hose);                /* Let board setup pci target */
+#else
+    out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+    out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_ID );
+    out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */
+#endif
+
+    out32r( PCIX0_BRDGOPT1, 0x10000060 );               /* PLB Rq pri highest   */
+    out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 1 ); /* Enable host config   */
+
+	/*--------------------------------------------------------------------------+
+	 * PCI master init: default is one 256MB region for PCI memory:
+	 * 0x3_00000000 - 0x3_0FFFFFFF  ==> CFG_PCI_MEMBASE
+	 *--------------------------------------------------------------------------*/
+#if defined(CFG_PCI_MASTER_INIT)
+	pci_master_init(hose);          /* Let board setup pci master */
+#else
+	out32r( PCIX0_POM0SA, 0 ); /* disable */
+	out32r( PCIX0_POM1SA, 0 ); /* disable */
+	out32r( PCIX0_POM2SA, 0 ); /* disable */
+	out32r( PCIX0_POM0LAL, 0x00000000 );
+	out32r( PCIX0_POM0LAH, 0x00000003 );
+	out32r( PCIX0_POM0PCIAL, CFG_PCI_MEMBASE );
+	out32r( PCIX0_POM0PCIAH, 0x00000000 );
+	out32r( PCIX0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
+    out32r( PCIX0_STS, in32r( PCIX0_STS ) & ~0x0000fff8 );
+#endif
+
+	/*--------------------------------------------------------------------------+
+	 * PCI host configuration -- we don't make any assumptions here ... the
+     * _board_must_indicate_ what to do -- there's just too many runtime
+     * scenarios in environments like cPCI, PPMC, etc. to make a determination
+     * based on hard-coded values or state of arbiter enable.
+	 *--------------------------------------------------------------------------*/
+    if( is_pci_host(hose) ){
+#ifdef CONFIG_PCI_SCAN_SHOW
+        printf("PCI:   Bus Dev VenId DevId Class Int\n");
+#endif
+        out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
+        hose->last_busno = pci_hose_scan(hose);
+    }
+}
+
+
+void pci_init(void)
+{
+	pci_440_init (&ppc440_hose);
+}
+
+#endif /* CONFIG_440 & CONFIG_PCI */
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
new file mode 100644
index 0000000..8aaffb1
--- /dev/null
+++ b/cpu/ppc4xx/cpu.c
@@ -0,0 +1,253 @@
+/*
+ * (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
+ */
+
+/*
+ * m8xx.c
+ *
+ * CPU specific code
+ *
+ * written or collected and sometimes rewritten by
+ * Magnus Damm <damm@bitsmart.com>
+ *
+ * minor modifications by
+ * Wolfgang Denk <wd@denx.de>
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <ppc4xx.h>
+
+
+#if defined(CONFIG_440)
+static int do_chip_reset( unsigned long sys0, unsigned long sys1 );
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+int checkcpu (void)
+{
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_IOP480) || defined(CONFIG_440)
+	uint pvr = get_pvr();
+#endif
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_IOP480)
+	DECLARE_GLOBAL_DATA_PTR;
+
+	ulong clock = gd->cpu_clk;
+	char buf[32];
+#endif
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR)
+	PPC405_SYS_INFO sys_info;
+
+	puts ("CPU:   ");
+
+	get_sys_info(&sys_info);
+
+#if CONFIG_405GP
+	puts("IBM PowerPC 405GP");
+	if (pvr == PVR_405GPR_RA) {
+		putc('r');
+	}
+	puts(" Rev. ");
+#endif
+#if CONFIG_405CR
+	puts("IBM PowerPC 405CR Rev. ");
+#endif
+	switch (pvr) {
+	case PVR_405GP_RB:
+		putc('B');
+		break;
+	case PVR_405GP_RC:
+#if CONFIG_405CR
+	case PVR_405CR_RC:
+#endif
+		putc('C');
+		break;
+	case PVR_405GP_RD:
+		putc('D');
+		break;
+#if CONFIG_405GP
+	case PVR_405GP_RE:
+		putc('E');
+		break;
+#endif
+	case PVR_405CR_RA:
+	case PVR_405GPR_RA:
+		putc('A');
+		break;
+	case PVR_405CR_RB:
+		putc('B');
+		break;
+	default:
+		printf("? (PVR=%08x)", pvr);
+		break;
+	}
+
+	printf(" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
+	       sys_info.freqPLB / 1000000,
+	       sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
+	       sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
+
+#if CONFIG_405GP
+	if (mfdcr(strap) & PSR_PCI_ASYNC_EN)
+		printf("           PCI async ext clock used, ");
+	else
+		printf("           PCI sync clock at %lu MHz, ",
+		       sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
+	if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+		printf("internal PCI arbiter enabled\n");
+	else
+		printf("external PCI arbiter enabled\n");
+#endif
+
+	if ((pvr | 0x00000001) == PVR_405GPR_RA) {
+		printf("           16 kB I-Cache 16 kB D-Cache");
+	} else {
+		printf("           16 kB I-Cache 8 kB D-Cache");
+	}
+
+
+#endif  /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */
+
+#ifdef CONFIG_IOP480
+	printf("PLX IOP480 (PVR=%08x)", pvr);
+	printf(" at %s MHz:", strmhz(buf, clock));
+	printf(" %u kB I-Cache", 4);
+	printf(" %u kB D-Cache", 2);
+#endif
+
+#if defined(CONFIG_440)
+	puts("IBM PowerPC 440 Rev. ");
+	switch(pvr)
+	{
+        case PVR_440GP_RB:
+		putc('B');
+        /* See errata 1.12: CHIP_4 */
+        if(   ( mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0) )
+            ||( mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1) ) ){
+            puts("\n\t CPC0_SYSx DCRs corrupted. Resetting chip ...\n");
+            udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
+            do_chip_reset( mfdcr(cpc0_strp0), mfdcr(cpc0_strp1) );
+        }
+		break;
+        case PVR_440GP_RC:
+		putc('C');
+		break;
+        default:
+		printf("UNKNOWN (PVR=%08x)", pvr);
+		break;
+	}
+#endif
+
+	printf("\n");
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+        /*
+         * Initiate system reset in debug control register DBCR
+         */
+	__asm__ __volatile__("lis   3, 0x3000" ::: "r3");
+#if defined(CONFIG_440)
+	__asm__ __volatile__("mtspr 0x134, 3");
+#else
+	__asm__ __volatile__("mtspr 0x3f2, 3");
+#endif
+	return 1;
+}
+
+#if defined(CONFIG_440)
+static
+int do_chip_reset( unsigned long sys0, unsigned long sys1 )
+{
+    /* Changes to cpc0_sys0 and cpc0_sys1 require chip
+     * reset.
+     */
+    mtdcr( cntrl0, mfdcr(cntrl0) | 0x80000000 ); /* Set SWE */
+    mtdcr( cpc0_sys0, sys0 );
+    mtdcr( cpc0_sys1, sys1 );
+    mtdcr( cntrl0, mfdcr(cntrl0) & ~0x80000000 ); /* Clr SWE */
+    mtspr( dbcr0, 0x20000000);  /* Reset the chip */
+
+    return 1;
+}
+#endif
+
+
+/*
+ * Get timebase clock frequency
+ */
+unsigned long get_tbclk (void)
+{
+#if defined(CONFIG_440)
+
+	sys_info_t  sys_info;
+
+	get_sys_info(&sys_info);
+	return (sys_info.freqProcessor);
+
+#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405)
+
+	PPC405_SYS_INFO sys_info;
+
+	get_sys_info(&sys_info);
+	return (sys_info.freqProcessor);
+
+#elif defined(CONFIG_IOP480)
+
+	return (66000000);
+
+#else
+
+# error get_tbclk() not implemented
+
+#endif
+
+}
+
+
+#if defined(CONFIG_WATCHDOG)
+void
+watchdog_reset(void)
+{
+	int re_enable = disable_interrupts();
+	reset_4xx_watchdog();
+	if (re_enable) enable_interrupts();
+}
+
+void
+reset_4xx_watchdog(void)
+{
+	/*
+	 * Clear TSR(WIS) bit
+	 */
+	mtspr(tsr, 0x40000000);
+}
+#endif	/* CONFIG_WATCHDOG */
diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c
new file mode 100644
index 0000000..68af057
--- /dev/null
+++ b/cpu/ppc4xx/i2c.c
@@ -0,0 +1,417 @@
+/*****************************************************************************/
+/* I2C Bus interface initialisation and I2C Commands                         */
+/* for PPC405GP		                                                     */
+/* Author : AS HARNOIS                                                       */
+/* Date   : 13.Dec.00                                                        */
+/*****************************************************************************/
+
+#include <common.h>
+#include <ppc4xx.h>
+#if defined(CONFIG_440)
+#   include <440_i2c.h>
+#else
+#   include <405gp_i2c.h>
+#endif
+#include <i2c.h>
+
+#ifdef CONFIG_HARD_I2C
+
+#define IIC_OK		0
+#define IIC_NOK		1
+#define IIC_NOK_LA	2		/* Lost arbitration */
+#define IIC_NOK_ICT	3		/* Incomplete transfer */
+#define IIC_NOK_XFRA	4		/* Transfer aborted */
+#define IIC_NOK_DATA	5		/* No data in buffer */
+#define IIC_NOK_TOUT	6		/* Transfer timeout */
+
+#define IIC_TIMEOUT 1			/* 1 seconde */
+
+
+static void _i2c_bus_reset (void)
+{
+	int i, status;
+
+	/* Reset status register */
+	/* write 1 in SCMP and IRQA to clear these fields */
+	out8 (IIC_STS, 0x0A);
+
+	/* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
+	out8 (IIC_EXTSTS, 0x8F);
+	__asm__ volatile ("eieio");
+
+	/*
+	 * Get current state, reset bus
+	 * only if no transfers are pending.
+	 */
+	i = 10;
+	do {
+		/* Get status */
+		status = in8 (IIC_STS);
+		udelay (500);			/* 500us */
+		i--;
+	} while ((status & IIC_STS_PT) && (i > 0));
+	/* Soft reset controller */
+	status = in8 (IIC_XTCNTLSS);
+	out8 (IIC_XTCNTLSS, (status | IIC_XTCNTLSS_SRST));
+	__asm__ volatile ("eieio");
+
+	/* make sure where in initial state, data hi, clock hi */
+	out8 (IIC_DIRECTCNTL, 0xC);
+	for (i = 0; i < 10; i++) {
+		if ((in8 (IIC_DIRECTCNTL) & 0x3) != 0x3) {
+			/* clock until we get to known state */
+			out8 (IIC_DIRECTCNTL, 0x8);	/* clock lo */
+			udelay (100);		/* 100us */
+			out8 (IIC_DIRECTCNTL, 0xC);	/* clock hi */
+			udelay (100);		/* 100us */
+		} else {
+			break;
+		}
+	}
+	/* send start condition */
+	out8 (IIC_DIRECTCNTL, 0x4);
+	udelay (1000);				/* 1ms */
+	/* send stop condition */
+	out8 (IIC_DIRECTCNTL, 0xC);
+	udelay (1000);				/* 1ms */
+	/* Unreset controller */
+	out8 (IIC_XTCNTLSS, (status & ~IIC_XTCNTLSS_SRST));
+	udelay (1000);				/* 1ms */
+}
+
+void i2c_init (int speed, int slaveadd)
+{
+	sys_info_t sysInfo;
+	unsigned long freqOPB;
+	int val, divisor;
+
+	/* Handle possible failed I2C state */
+	_i2c_bus_reset ();
+
+	/* clear lo master address */
+	out8 (IIC_LMADR, 0);
+
+	/* clear hi master address */
+	out8 (IIC_HMADR, 0);
+
+	/* clear lo slave address */
+	out8 (IIC_LSADR, 0);
+
+	/* clear hi slave address */
+	out8 (IIC_HSADR, 0);
+
+	/* Clock divide Register */
+	/* get OPB frequency */
+	get_sys_info (&sysInfo);
+	freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv;
+	/* set divisor according to freqOPB */
+	divisor = (freqOPB - 1) / 10000000;
+	if (divisor == 0)
+		divisor = 1;
+	out8 (IIC_CLKDIV, divisor);
+
+	/* no interrupts */
+	out8 (IIC_INTRMSK, 0);
+
+	/* clear transfer count */
+	out8 (IIC_XFRCNT, 0);
+
+	/* clear extended control & stat */
+	/* write 1 in SRC SRS SWC SWS to clear these fields */
+	out8 (IIC_XTCNTLSS, 0xF0);
+
+	/* Mode Control Register
+	   Flush Slave/Master data buffer */
+	out8 (IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
+	__asm__ volatile ("eieio");
+
+
+        val = in8(IIC_MDCNTL);
+        __asm__ volatile ("eieio");
+
+        /* Ignore General Call, slave transfers are ignored,
+           disable interrupts, exit unknown bus state, enable hold
+           SCL
+           100kHz normaly or FastMode for 400kHz and above
+        */
+
+        val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL;
+        if( speed >= 400000 ){
+                val |= IIC_MDCNTL_FSM;
+        }
+	out8 (IIC_MDCNTL, val);
+
+	/* clear control reg */
+	out8 (IIC_CNTL, 0x00);
+	__asm__ volatile ("eieio");
+
+}
+
+/*
+  This code tries to use the features of the 405GP i2c
+  controller. It will transfer up to 4 bytes in one pass
+  on the loop. It only does out8(lbz) to the buffer when it
+  is possible to do out16(lhz) transfers.
+
+  cmd_type is 0 for write 1 for read.
+
+  addr_len can take any value from 0-255, it is only limited
+  by the char, we could make it larger if needed. If it is
+  0 we skip the address write cycle.
+
+  Typical case is a Write of an addr followd by a Read. The
+  IBM FAQ does not cover this. On the last byte of the write
+  we don't set the creg CHT bit, and on the first bytes of the
+  read we set the RPST bit.
+
+  It does not support address only transfers, there must be
+  a data part. If you want to write the address yourself, put
+  it in the data pointer.
+
+  It does not support transfer to/from address 0.
+
+  It does not check XFRCNT.
+*/
+static
+int i2c_transfer(unsigned char cmd_type,
+                 unsigned char chip,
+                 unsigned char addr[],
+                 unsigned char addr_len,
+                 unsigned char data[],
+		 unsigned short data_len )
+{
+        unsigned char* ptr;
+        int reading;
+        int tran,cnt;
+        int result;
+        int status;
+        int i;
+        uchar creg;
+
+        if( data == 0 || data_len == 0 ){
+                /*Don't support data transfer of no length or to address 0*/
+                printf( "i2c_transfer: bad call\n" );
+                return IIC_NOK;
+        }
+        if( addr && addr_len ){
+                ptr = addr;
+                cnt = addr_len;
+                reading = 0;
+        }else{
+                ptr = data;
+                cnt = data_len;
+                reading = cmd_type;
+        }
+
+        /*Clear Stop Complete Bit*/
+        out8(IIC_STS,IIC_STS_SCMP);
+        /* Check init */
+        i=10;
+        do {
+                /* Get status */
+                status = in8(IIC_STS);
+                __asm__ volatile("eieio");
+                i--;
+        } while ((status & IIC_STS_PT) && (i>0));
+
+        if (status & IIC_STS_PT) {
+                result = IIC_NOK_TOUT;
+                return(result);
+        }
+        /*flush the Master/Slave Databuffers*/
+        out8(IIC_MDCNTL, ((in8(IIC_MDCNTL))|IIC_MDCNTL_FMDB|IIC_MDCNTL_FSDB));
+        /*need to wait 4 OPB clocks? code below should take that long*/
+
+        /* 7-bit adressing */
+        out8(IIC_HMADR,0);
+        out8(IIC_LMADR, chip);
+        __asm__ volatile("eieio");
+
+        tran = 0;
+        result = IIC_OK;
+        creg = 0;
+
+        while ( tran != cnt && (result == IIC_OK)) {
+                int  bc,j;
+
+                /* Control register =
+                   Normal transfer, 7-bits adressing, Transfer up to bc bytes, Normal start,
+                   Transfer is a sequence of transfers
+                */
+                creg |= IIC_CNTL_PT;
+
+                bc = (cnt - tran) > 4 ? 4 :
+                        cnt - tran;
+                creg |= (bc-1)<<4;
+                /* if the real cmd type is write continue trans*/
+                if ( (!cmd_type && (ptr == addr)) || ((tran+bc) != cnt) )
+                        creg |= IIC_CNTL_CHT;
+
+                if (reading)
+                        creg |= IIC_CNTL_READ;
+                else {
+                        for(j=0; j<bc; j++) {
+                                /* Set buffer */
+                                out8(IIC_MDBUF,ptr[tran+j]);
+                                __asm__ volatile("eieio");
+                        }
+                }
+                out8(IIC_CNTL, creg );
+                __asm__ volatile("eieio");
+
+                /* Transfer is in progress
+                   we have to wait for upto 5 bytes of data
+                   1 byte chip address+r/w bit then bc bytes
+                   of data.
+                   udelay(10) is 1 bit time at 100khz
+                   Doubled for slop. 20 is too small.
+		*/
+                i=2*5*8;
+                do {
+                        /* Get status */
+                        status = in8(IIC_STS);
+                        __asm__ volatile("eieio");
+                        udelay (10);
+                        i--;
+                } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR)
+			 && (i>0));
+
+                if (status & IIC_STS_ERR) {
+                        result = IIC_NOK;
+                        status = in8 (IIC_EXTSTS);
+                        /* Lost arbitration? */
+                        if (status & IIC_EXTSTS_LA)
+                                result = IIC_NOK_LA;
+                        /* Incomplete transfer? */
+                        if (status & IIC_EXTSTS_ICT)
+                                result = IIC_NOK_ICT;
+                        /* Transfer aborted? */
+                        if (status & IIC_EXTSTS_XFRA)
+                                result = IIC_NOK_XFRA;
+                } else if ( status & IIC_STS_PT) {
+                        result = IIC_NOK_TOUT;
+                }
+                /* Command is reading => get buffer */
+                if ((reading) && (result == IIC_OK)) {
+                        /* Are there data in buffer */
+                        if (status & IIC_STS_MDBS) {
+                                /*
+                                  even if we have data we have to wait 4OPB clocks
+                                  for it to hit the front of the FIFO, after that
+                                  we can just read. We should check XFCNT here and
+                                  if the FIFO is full there is no need to wait.
+				*/
+                                udelay (1);
+                                for(j=0;j<bc;j++) {
+                                        ptr[tran+j] = in8(IIC_MDBUF);
+                                        __asm__ volatile("eieio");
+                                }
+                        } else
+                                result = IIC_NOK_DATA;
+                }
+                creg = 0;
+                tran+=bc;
+                if( ptr == addr && tran == cnt ) {
+                        ptr = data;
+                        cnt = data_len;
+                        tran = 0;
+                        reading = cmd_type;
+                        if( reading )
+                                creg = IIC_CNTL_RPST;
+                }
+        }
+        return (result);
+}
+
+int i2c_probe (uchar chip)
+{
+	uchar buf[1];
+
+	buf[0] = 0;
+
+        /*
+         * What is needed is to send the chip address and verify that the
+         * address was <ACK>ed (i.e. there was a chip at that address which
+         * drove the data line low).
+         */
+        return(i2c_transfer (1, chip << 1, 0,0, buf, 1) != 0);
+}
+
+
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+        uchar xaddr[4];
+        int ret;
+
+	if ( alen > 4 ) {
+		printf ("I2C read: addr len %d not supported\n", alen);
+		return 1;
+	}
+
+        if ( alen > 0 ) {
+                xaddr[0] = (addr >> 24) & 0xFF;
+                xaddr[1] = (addr >> 16) & 0xFF;
+                xaddr[2] = (addr >> 8) & 0xFF;
+                xaddr[3] = addr & 0xFF;
+        }
+
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+	/*
+         * EEPROM chips that implement "address overflow" are ones
+         * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+         * address and the extra bits end up in the "chip address"
+         * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+         * four 256 byte chips.
+	 *
+         * Note that we consider the length of the address field to
+         * still be one byte because the extra address bits are
+         * hidden in the chip address.
+	 */
+        if( alen > 0 )
+                chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+        if( (ret = i2c_transfer( 1, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
+                printf( "I2c read: failed %d\n", ret);
+                return 1;
+        }
+        return 0;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+        uchar xaddr[4];
+
+	if ( alen > 4 ) {
+		printf ("I2C write: addr len %d not supported\n", alen);
+		return 1;
+
+	}
+        if ( alen > 0 ) {
+                xaddr[0] = (addr >> 24) & 0xFF;
+                xaddr[1] = (addr >> 16) & 0xFF;
+                xaddr[2] = (addr >> 8) & 0xFF;
+                xaddr[3] = addr & 0xFF;
+        }
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+	/*
+         * EEPROM chips that implement "address overflow" are ones
+         * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+         * address and the extra bits end up in the "chip address"
+         * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+         * four 256 byte chips.
+	 *
+         * Note that we consider the length of the address field to
+         * still be one byte because the extra address bits are
+         * hidden in the chip address.
+	 */
+        if( alen > 0 )
+                chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+
+        return (i2c_transfer( 0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
+}
+
+#endif	/* CONFIG_HARD_I2C */
diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c
new file mode 100644
index 0000000..d64bf96
--- /dev/null
+++ b/cpu/ppc4xx/sdram.c
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2002
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+
+#ifdef CONFIG_SDRAM_BANK0
+
+
+#define MAGIC0 0x00000000
+#define MAGIC1 0x11111111
+#define MAGIC2 0x22222222
+#define MAGIC3 0x33333333
+#define MAGIC4 0x44444444
+
+#define ADDR_ZERO 0x00000000
+#define ADDR_400  0x00000400
+#define ADDR_08MB 0x00800000
+#define ADDR_16MB 0x01000000
+#define ADDR_32MB 0x02000000
+#define ADDR_64MB 0x04000000
+
+#define mtsdram0(reg, data)  mtdcr(memcfga,reg);mtdcr(memcfgd,data)
+
+
+/*-----------------------------------------------------------------------
+ */
+void sdram_init(void)
+{
+	ulong speed;
+	ulong sdtr1;
+	ulong rtr;
+
+	/*
+	 * Determine SDRAM speed
+	 */
+	speed = get_bus_freq(0); /* parameter not used on ppc4xx */
+
+	/*
+	 * Support for 100MHz and 133MHz SDRAM
+	 */
+	if (speed > 100000000) {
+		/*
+		 * 133 MHz SDRAM
+		 */
+		sdtr1 = 0x01074015;
+		rtr = 0x07f00000;
+	} else {
+		/*
+		 * default: 100 MHz SDRAM
+		 */
+		sdtr1 = 0x0086400d;
+		rtr = 0x05f00000;
+	}
+
+	/*
+	 * Set MB0CF for bank 0. (0-64MB) Address Mode 3 since 13x9(4)
+	 */
+	mtsdram0(mem_mb0cf, 0x00084001);
+
+	mtsdram0(mem_sdtr1, sdtr1);
+	mtsdram0(mem_rtr, rtr);
+
+	/*
+	 * Wait for 200us
+	 */
+	udelay(200);
+
+	/*
+	 * Set memory controller options reg, MCOPT1.
+	 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
+	 * read/prefetch.
+	 */
+	mtsdram0(mem_mcopt1, 0x80800000);
+
+	/*
+	 * Wait for 10ms
+	 */
+	udelay(10000);
+
+	/*
+	 * Test if 64 MByte are equipped (mirror test)
+	 */
+	*(volatile ulong *)ADDR_ZERO = MAGIC0;
+	*(volatile ulong *)ADDR_08MB = MAGIC1;
+	*(volatile ulong *)ADDR_16MB = MAGIC2;
+	*(volatile ulong *)ADDR_32MB = MAGIC3;
+
+	if ((*(volatile ulong *)ADDR_ZERO == MAGIC0) &&
+	    (*(volatile ulong *)ADDR_08MB == MAGIC1) &&
+	    (*(volatile ulong *)ADDR_16MB == MAGIC2)) {
+		/*
+		 * OK, 64MB detected -> all done
+		 */
+		return;
+	}
+
+	/*
+	 * Now test for 32 MByte...
+	 */
+
+        /*
+	 * Disable memory controller.
+	 */
+	mtsdram0(mem_mcopt1, 0x00000000);
+
+	/*
+	 * Set MB0CF for bank 0. (0-32MB) Address Mode 2 since 12x9(4)
+	 */
+	mtsdram0(mem_mb0cf, 0x00062001);
+
+	/*
+	 * Set memory controller options reg, MCOPT1.
+	 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
+	 * read/prefetch.
+	 */
+	mtsdram0(mem_mcopt1, 0x80800000);
+
+	/*
+	 * Wait for 10ms
+	 */
+	udelay(10000);
+
+	/*
+	 * Test if 32 MByte are equipped (mirror test)
+	 */
+	*(volatile ulong *)ADDR_ZERO = MAGIC0;
+	*(volatile ulong *)ADDR_400  = MAGIC1;
+	*(volatile ulong *)ADDR_08MB = MAGIC2;
+	*(volatile ulong *)ADDR_16MB = MAGIC3;
+
+	if ((*(volatile ulong *)ADDR_ZERO == MAGIC0) &&
+	    (*(volatile ulong *)ADDR_400  == MAGIC1) &&
+	    (*(volatile ulong *)ADDR_08MB == MAGIC2)) {
+		/*
+		 * OK, 32MB detected -> all done
+		 */
+		return;
+	}
+
+	/*
+	 * Setup for 16 MByte...
+	 */
+
+        /*
+	 * Disable memory controller.
+	 */
+	mtsdram0(mem_mcopt1, 0x00000000);
+
+	/*
+	 * Set MB0CF for bank 0. (0-16MB) Address Mode 4 since 12x8(4)
+	 */
+	mtsdram0(mem_mb0cf, 0x00046001);
+
+	/*
+	 * Set memory controller options reg, MCOPT1.
+	 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
+	 * read/prefetch.
+	 */
+	mtsdram0(mem_mcopt1, 0x80800000);
+
+	/*
+	 * Wait for 10ms
+	 */
+	udelay(10000);
+}
+
+#endif /* CONFIG_SDRAM_BANK0 */
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
new file mode 100644
index 0000000..4541529
--- /dev/null
+++ b/cpu/ppc4xx/speed.c
@@ -0,0 +1,308 @@
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <ppc_asm.tmpl>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/* ------------------------------------------------------------------------- */
+
+#define ONE_BILLION        1000000000
+
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR)
+
+void get_sys_info (PPC405_SYS_INFO * sysInfo)
+{
+	unsigned long pllmr;
+	unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
+	uint pvr = get_pvr();
+	unsigned long psr;
+	unsigned long m;
+
+	/*
+	 * Read PLL Mode register
+	 */
+	pllmr = mfdcr (pllmd);
+
+	/*
+	 * Read Pin Strapping register
+	 */
+	psr = mfdcr (strap);
+
+	/*
+	 * Determine FWD_DIV.
+	 */
+	sysInfo->pllFwdDiv = 8 - ((pllmr & PLLMR_FWD_DIV_MASK) >> 29);
+
+	/*
+	 * Determine FBK_DIV.
+	 */
+	sysInfo->pllFbkDiv = ((pllmr & PLLMR_FB_DIV_MASK) >> 25);
+	if (sysInfo->pllFbkDiv == 0) {
+		sysInfo->pllFbkDiv = 16;
+	}
+
+	/*
+	 * Determine PLB_DIV.
+	 */
+	sysInfo->pllPlbDiv = ((pllmr & PLLMR_CPU_TO_PLB_MASK) >> 17) + 1;
+
+	/*
+	 * Determine PCI_DIV.
+	 */
+	sysInfo->pllPciDiv = ((pllmr & PLLMR_PCI_TO_PLB_MASK) >> 13) + 1;
+
+	/*
+	 * Determine EXTBUS_DIV.
+	 */
+	sysInfo->pllExtBusDiv = ((pllmr & PLLMR_EXB_TO_PLB_MASK) >> 11) + 2;
+
+	/*
+	 * Determine OPB_DIV.
+	 */
+	sysInfo->pllOpbDiv = ((pllmr & PLLMR_OPB_TO_PLB_MASK) >> 15) + 1;
+
+	/*
+	 * Check if PPC405GPr used (mask minor revision field)
+	 */
+	if ((pvr & 0xfffffff0) == (PVR_405GPR_RA & 0xfffffff0)) {
+		/*
+		 * Determine FWD_DIV B (only PPC405GPr with new mode strapping).
+		 */
+		sysInfo->pllFwdDivB = 8 - (pllmr & PLLMR_FWDB_DIV_MASK);
+
+		/*
+		 * Determine factor m depending on PLL feedback clock source
+		 */
+		if (!(psr & PSR_PCI_ASYNC_EN)) {
+			if (psr & PSR_NEW_MODE_EN) {
+				/*
+				 * sync pci clock used as feedback (new mode)
+				 */
+				m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllPciDiv;
+			} else {
+				/*
+				 * sync pci clock used as feedback (legacy mode)
+				 */
+				m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllPciDiv;
+			}
+		} else if (psr & PSR_NEW_MODE_EN) {
+			if (psr & PSR_PERCLK_SYNC_MODE_EN) {
+				/*
+				 * PerClk used as feedback (new mode)
+				 */
+				m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllExtBusDiv;
+			} else {
+				/*
+				 * CPU clock used as feedback (new mode)
+				 */
+				m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;
+			}
+		} else if (sysInfo->pllExtBusDiv == sysInfo->pllFbkDiv) {
+			/*
+			 * PerClk used as feedback (legacy mode)
+			 */
+			m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllExtBusDiv;
+		} else {
+			/*
+			 * PLB clock used as feedback (legacy mode)
+			 */
+			m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv;
+		}
+
+		sysInfo->freqVCOMhz = (1000000 * m) / sysClkPeriodPs;
+		sysInfo->freqProcessor = (sysInfo->freqVCOMhz * 1000000) / sysInfo->pllFwdDiv;
+		sysInfo->freqPLB = (sysInfo->freqVCOMhz * 1000000) /
+			(sysInfo->pllFwdDivB * sysInfo->pllPlbDiv);
+	} else {
+		/*
+		 * Check pllFwdDiv to see if running in bypass mode where the CPU speed
+		 * is equal to the 405GP SYS_CLK_FREQ. If not in bypass mode, check VCO
+		 * to make sure it is within the proper range.
+		 *    spec:    VCO = SYS_CLOCK x FBKDIV x PLBDIV x FWDDIV
+		 * Note freqVCO is calculated in Mhz to avoid errors introduced by rounding.
+		 */
+		if (sysInfo->pllFwdDiv == 1) {
+			sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ;
+			sysInfo->freqPLB = CONFIG_SYS_CLK_FREQ / sysInfo->pllPlbDiv;
+		} else {
+			sysInfo->freqVCOMhz = ( 1000000 *
+						sysInfo->pllFwdDiv *
+						sysInfo->pllFbkDiv *
+						sysInfo->pllPlbDiv
+				) / sysClkPeriodPs;
+			if (sysInfo->freqVCOMhz >= VCO_MIN
+			    && sysInfo->freqVCOMhz <= VCO_MAX) {
+				sysInfo->freqPLB = (ONE_BILLION /
+						    ((sysClkPeriodPs * 10) /
+						     sysInfo->pllFbkDiv)) * 10000;
+				sysInfo->freqProcessor = sysInfo->freqPLB * sysInfo->pllPlbDiv;
+			} else {
+				printf ("\nInvalid VCO frequency calculated :  %ld MHz \a\n",
+					sysInfo->freqVCOMhz);
+				printf ("It must be between %d-%d MHz \a\n",
+					VCO_MIN, VCO_MAX);
+				printf ("PLL Mode reg           :  %8.8lx\a\n",
+					pllmr);
+				hang ();
+			}
+		}
+	}
+}
+
+
+/********************************************
+ * get_OPB_freq
+ * return OPB bus freq in Hz
+ *********************************************/
+ulong get_OPB_freq (void)
+{
+	ulong val = 0;
+
+	PPC405_SYS_INFO sys_info;
+
+	get_sys_info (&sys_info);
+	val = sys_info.freqPLB / sys_info.pllOpbDiv;
+
+	return val;
+}
+
+
+/********************************************
+ * get_PCI_freq
+ * return PCI bus freq in Hz
+ *********************************************/
+ulong get_PCI_freq (void)
+{
+	ulong val;
+	PPC405_SYS_INFO sys_info;
+
+	get_sys_info (&sys_info);
+	val = sys_info.freqPLB / sys_info.pllPciDiv;
+	return val;
+}
+
+
+#elif defined(CONFIG_440)
+void get_sys_info (sys_info_t * sysInfo)
+{
+	unsigned long strp0;
+	unsigned long temp;
+	unsigned long m;
+
+	/* Extract configured divisors */
+	strp0 = mfdcr( cpc0_strp0 );
+	sysInfo->pllFwdDivA = 8 - ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 15);
+	sysInfo->pllFwdDivB = 8 - ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 12);
+	temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 18;
+	sysInfo->pllFbkDiv = temp ? temp : 16;
+	sysInfo->pllOpbDiv = 1 + ((strp0 & PLLSYS0_OPB_DIV_MASK) >> 10);
+	sysInfo->pllExtBusDiv = 1 + ((strp0 & PLLSYS0_EPB_DIV_MASK) >> 8);
+
+	/* Calculate 'M' based on feedback source */
+	if( strp0 & PLLSYS0_EXTSL_MASK )
+		m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
+	else
+		m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
+
+	/* Now calculate the individual clocks */
+	sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
+	sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
+	sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB;
+    if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
+        sysInfo->freqPLB >>= 1;
+	sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
+	sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
+
+}
+
+ulong get_OPB_freq (void)
+{
+
+	sys_info_t sys_info;
+	get_sys_info (&sys_info);
+	return sys_info.freqOPB;
+}
+
+#elif defined(CONFIG_405)
+
+void get_sys_info (sys_info_t * sysInfo) {
+
+	sysInfo->freqVCOMhz=3125000;
+	sysInfo->freqProcessor=12*1000*1000;
+	sysInfo->freqPLB=50*1000*1000;
+	sysInfo->freqPCI=66*1000*1000;
+
+}
+
+#endif
+
+int get_clocks (void)
+{
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405)
+	DECLARE_GLOBAL_DATA_PTR;
+
+	sys_info_t sys_info;
+
+	get_sys_info (&sys_info);
+	gd->cpu_clk = sys_info.freqProcessor;
+	gd->bus_clk = sys_info.freqPLB;
+
+#endif	/* defined(CONFIG_405GP) || defined(CONFIG_405CR) */
+
+#ifdef CONFIG_IOP480
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->cpu_clk = 66000000;
+	gd->bus_clk = 66000000;
+#endif
+	return (0);
+}
+
+
+/********************************************
+ * get_bus_freq
+ * return PLB bus freq in Hz
+ *********************************************/
+ulong get_bus_freq (ulong dummy)
+{
+	ulong val;
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_440)
+	sys_info_t sys_info;
+
+	get_sys_info (&sys_info);
+	val = sys_info.freqPLB;
+
+#elif defined(CONFIG_IOP480)
+
+	val = 66;
+
+#else
+# error get_bus_freq() not implemented
+#endif
+
+	return val;
+}
diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h
new file mode 100644
index 0000000..d493a5d
--- /dev/null
+++ b/cpu/ppc4xx/vecnum.h
@@ -0,0 +1,100 @@
+/*
+*  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.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
+*/
+
+/*
+ * Interrupt vector number definitions to ease the
+ * 405 -- 440 porting pain ;-)
+ *
+ * NOTE: They're not all here yet ... update as needed.
+ *
+ */
+
+#ifndef _VECNUMS_H_
+#define _VECNUMS_H_
+
+#if defined(CONFIG_440)
+
+/* UIC 0 */
+#define VECNUM_U0           0           /* UART0                        */
+#define VECNUM_U1           1           /* UART1                        */
+#define VECNUM_IIC0         2           /* IIC0                         */
+#define VECNUM_IIC1         3           /* IIC1                         */
+#define VECNUM_PIM          4           /* PCI inbound message          */
+#define VECNUM_PCRW         5           /* PCI command reg write        */
+#define VECNUM_PPM          6           /* PCI power management         */
+#define VECNUM_MSI0         7           /* PCI MSI level 0              */
+#define VECNUM_MSI1         8           /* PCI MSI level 0              */
+#define VECNUM_MSI2         9           /* PCI MSI level 0              */
+#define VECNUM_MTE          10          /* MAL TXEOB                    */
+#define VECNUM_MRE          11          /* MAL RXEOB                    */
+#define VECNUM_D0           12          /* DMA channel 0                */
+#define VECNUM_D1           13          /* DMA channel 1                */
+#define VECNUM_D2           14          /* DMA channel 2                */
+#define VECNUM_D3           15          /* DMA channel 3                */
+#define VECNUM_CT0          18          /* GPT compare timer 0          */
+#define VECNUM_CT1          19          /* GPT compare timer 1          */
+#define VECNUM_CT2          20          /* GPT compare timer 2          */
+#define VECNUM_CT3          21          /* GPT compare timer 3          */
+#define VECNUM_CT4          22          /* GPT compare timer 4          */
+#define VECNUM_EIR0         23          /* External interrupt 0         */
+#define VECNUM_EIR1         24          /* External interrupt 1         */
+#define VECNUM_EIR2         25          /* External interrupt 2         */
+#define VECNUM_EIR3         26          /* External interrupt 3         */
+#define VECNUM_EIR4         27          /* External interrupt 4         */
+#define VECNUM_EIR5         28          /* External interrupt 5         */
+#define VECNUM_EIR6         29          /* External interrupt 6         */
+#define VECNUM_UIC1NC       30          /* UIC1 non-critical interrupt  */
+#define VECNUM_UIC1C        31          /* UIC1 critical interrupt      */
+
+/* UIC 1 */
+#define VECNUM_MS           (32 + 0 )   /* MAL SERR                     */
+#define VECNUM_TXDE         (32 + 1 )   /* MAL TXDE                     */
+#define VECNUM_RXDE         (32 + 2 )   /* MAL RXDE                     */
+#define VECNUM_ETH0         (32 + 28)   /* Ethernet 0 interrupt status  */
+#define VECNUM_EWU0         (32 + 29)   /* Ethernet 0 wakeup            */
+
+#else /* !defined(CONFIG_440) */
+
+#define VECNUM_U0           0           /* UART0                        */
+#define VECNUM_U1           1           /* UART1                        */
+#define VECNUM_D0           5           /* DMA channel 0                */
+#define VECNUM_D1           6           /* DMA channel 1                */
+#define VECNUM_D2           7           /* DMA channel 2                */
+#define VECNUM_D3           8           /* DMA channel 3                */
+#define VECNUM_EWU0         9           /* Ethernet wakeup              */
+#define VECNUM_MS           10          /* MAL SERR                     */
+#define VECNUM_MTE          11          /* MAL TXEOB                    */
+#define VECNUM_MRE          12          /* MAL RXEOB                    */
+#define VECNUM_TXDE         13          /* MAL TXDE                     */
+#define VECNUM_RXDE         14          /* MAL RXDE                     */
+#define VECNUM_ETH0         15          /* Ethernet interrupt status    */
+#define VECNUM_EIR0         25          /* External interrupt 0         */
+#define VECNUM_EIR1         26          /* External interrupt 1         */
+#define VECNUM_EIR2         27          /* External interrupt 2         */
+#define VECNUM_EIR3         28          /* External interrupt 3         */
+#define VECNUM_EIR4         29          /* External interrupt 4         */
+#define VECNUM_EIR5         30          /* External interrupt 5         */
+#define VECNUM_EIR6         31          /* External interrupt 6         */
+
+#endif /* defined(CONFIG_440) */
+
+#endif /* _VECNUMS_H_ */
diff --git a/cpu/sa1100/Makefile b/cpu/sa1100/Makefile
new file mode 100644
index 0000000..8c950da
--- /dev/null
+++ b/cpu/sa1100/Makefile
@@ -0,0 +1,43 @@
+#
+# (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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(CPU).a
+
+START	= start.o
+OBJS	= serial.o interrupts.o cpu.o
+
+all:	.depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/xscale/serial.c b/cpu/xscale/serial.c
new file mode 100644
index 0000000..35302a7
--- /dev/null
+++ b/cpu/xscale/serial.c
@@ -0,0 +1,143 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * 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 <asm/arch/pxa-regs.h>
+
+void serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	unsigned int quot = 0;
+
+	if (gd->baudrate == 1200)
+		quot = 192;
+	else if (gd->baudrate == 9600)
+		quot = 96;
+	else if (gd->baudrate == 19200)
+		quot = 48;
+	else if (gd->baudrate == 38400)
+		quot = 24;
+	else if (gd->baudrate == 57600)
+		quot = 16;
+	else if (gd->baudrate == 115200)
+		quot = 8;
+	else
+		hang ();
+
+#ifdef CONFIG_FFUART
+
+	CKEN |= CKEN6_FFUART;
+
+	FFIER = 0;					/* Disable for now */
+	FFFCR = 0;					/* No fifos enabled */
+
+	/* set baud rate */
+	FFLCR = LCR_WLS0 | LCR_WLS1 | LCR_DLAB;
+	FFDLL = quot & 0xff;
+	FFDLH = quot >> 8;
+	FFLCR = LCR_WLS0 | LCR_WLS1;
+
+	FFIER = IER_UUE;			/* Enable FFUART */
+
+#elif CONFIG_STUART
+#error "Bad: not implemented yet!"
+#else
+#error "Bad: you didn't configured serial ..."
+#endif
+}
+
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init (void)
+{
+	serial_setbrg ();
+
+	return (0);
+}
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc (const char c)
+{
+#ifdef CONFIG_FFUART
+	/* wait for room in the tx FIFO on FFUART */
+	while ((FFLSR & LSR_TEMT) == 0);
+
+	FFTHR = c;
+#elif CONFIG_STUART
+#endif
+
+	/* If \n, also do \r */
+	if (c == '\n')
+		serial_putc ('\r');
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_tstc (void)
+{
+#ifdef CONFIG_FFUART
+	return FFLSR & LSR_DR;
+#elif CONFIG_STUART
+#endif
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc (void)
+{
+#ifdef CONFIG_FFUART
+	while (!(FFLSR & LSR_DR));
+
+	return (char) FFRBR & 0xff;
+#elif CONFIG_STUART
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
diff --git a/cpu/xscale/start.S b/cpu/xscale/start.S
new file mode 100644
index 0000000..f1049a8
--- /dev/null
+++ b/cpu/xscale/start.S
@@ -0,0 +1,412 @@
+/*
+ *  armboot - Startup Code for XScale
+ *
+ *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2000	Wolfgang Denk <wd@denx.de>
+ *  Copyright (c) 2001	Alex Züpke <azu@sysgo.de>
+ *  Copyright (c) 2002	Kyle Harris <kharris@nexus-tech.net>
+ *
+ * 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 <config.h>
+#include <version.h>
+
+.globl _start
+_start:	b       reset
+	ldr	pc, _undefined_instruction
+	ldr	pc, _software_interrupt
+	ldr	pc, _prefetch_abort
+	ldr	pc, _data_abort
+	ldr	pc, _not_used
+	ldr	pc, _irq
+	ldr	pc, _fiq
+
+_undefined_instruction:	.word undefined_instruction
+_software_interrupt:	.word software_interrupt
+_prefetch_abort:	.word prefetch_abort
+_data_abort:		.word data_abort
+_not_used:		.word not_used
+_irq:			.word irq
+_fiq:			.word fiq
+
+	.balignl 16,0xdeadbeef
+
+
+/*
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * - relocate armboot to ram
+ * - setup stack
+ * - jump to second stage
+ */
+
+/*
+ * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
+ */
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+.globl _armboot_start
+_armboot_start:
+	.word _start
+
+/*
+ * Note: _armboot_end_data and _armboot_end are defined
+ * by the (board-dependent) linker script.
+ * _armboot_end_data is the first usable FLASH address after armboot
+ */
+.globl _armboot_end_data
+_armboot_end_data:
+	.word armboot_end_data
+.globl _armboot_end
+_armboot_end:
+	.word armboot_end
+
+/*
+ * _armboot_real_end is the first usable RAM address behind armboot
+ * and the various stacks
+ */
+.globl _armboot_real_end
+_armboot_real_end:
+	.word 0x0badc0de
+
+/*
+ * We relocate uboot to this address (end of RAM - 128 KiB)
+ */
+.globl _uboot_reloc
+_uboot_reloc:
+	.word CFG_DRAM_BASE + CFG_DRAM_SIZE - CFG_MONITOR_LEN
+
+#ifdef CONFIG_USE_IRQ
+/* IRQ stack memory (calculated at run-time) */
+.globl IRQ_STACK_START
+IRQ_STACK_START:
+	.word	0x0badc0de
+
+/* IRQ stack memory (calculated at run-time) */
+.globl FIQ_STACK_START
+FIQ_STACK_START:
+	.word 0x0badc0de
+#endif
+
+
+/****************************************************************************/
+/*                                                                          */
+/* the actual reset code                                                    */
+/*                                                                          */
+/****************************************************************************/
+
+reset:
+	mrs	r0,cpsr			/* set the cpu to SVC32 mode        */
+	bic	r0,r0,#0x1f		/* (superviser mode, M=10011)       */
+	orr	r0,r0,#0x13
+	msr	cpsr,r0
+
+	bl	cpu_init_crit		/* we do sys-critical inits         */
+
+relocate:				/* relocate U-Boot to RAM          */
+	adr	r0, _start		/* r0 <- current position of code */
+	ldr	r2, _armboot_start
+	ldr	r3, _armboot_end
+	sub	r2, r3, r2		/* r2 <- size of armboot */
+/*	ldr	r1, _uboot_reloc	/ * r1 <- destination address        */
+	ldr	r1, _TEXT_BASE
+	add	r2, r0, r2		/* r2 <- source end address */
+
+copy_loop:
+	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
+	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
+	cmp	r0, r2			/* until source end addreee [r2]    */
+	ble	copy_loop
+
+	/* Set up the stack                                                 */
+	ldr	r0, _uboot_reloc	/* upper 128 KiB: relocated uboot   */
+	sub	r0, r0, #CFG_MALLOC_LEN	/* malloc area                      */
+					/* FIXME: bdinfo should be here     */
+	sub	sp, r0, #12		/* leave 3 words for abort-stack */
+
+	ldr	pc, _start_armboot
+
+_start_armboot:	.word start_armboot
+
+
+/****************************************************************************/
+/*                                                                          */
+/* CPU_init_critical registers                                              */
+/*                                                                          */
+/* - setup important registers                                              */
+/* - setup memory timing                                                    */
+/*                                                                          */
+/****************************************************************************/
+
+	/* Interrupt-Controller base address                                */
+IC_BASE:	   .word	   0x40d00000
+#define ICMR	0x04
+
+/* Reset-Controller */
+RST_BASE:	.word   0x40f00030
+#define RCSR	0x00
+
+
+	/* Clock Manager Registers                                          */
+CC_BASE:		.word	0x41300000
+#define CCCR    0x00
+cpuspeed:	.word   CFG_CPUSPEED
+
+	/* RS: ???                                                          */
+	.macro CPWAIT
+    mrc  p15,0,r0,c2,c0,0
+	mov  r0,r0
+	sub  pc,pc,#4
+	.endm
+
+
+cpu_init_crit:
+
+	/* mask all IRQs                                                    */
+	ldr	r0, IC_BASE
+	mov	r1, #0x00
+	str	r1, [r0, #ICMR]
+
+	/* set clock speed */
+	ldr	r0, CC_BASE
+	ldr	r1, cpuspeed
+	str	r1, [r0, #CCCR]
+
+	/*
+	 * before relocating, we have to setup RAM timing
+	 * because memory timing is board-dependend, you will
+	 * find a memsetup.S in your board directory.
+	 */
+	mov	ip,	lr
+	bl	memsetup
+	mov	lr,	ip
+
+	/* Memory interfaces are working. Disable MMU and enable I-cache.   */
+
+	ldr	r0, =0x2001		/* enable access to all coproc.     */
+	mcr	p15, 0, r0, c15, c1, 0
+    CPWAIT
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write & fill buffers   */
+    CPWAIT
+
+	mcr	p15, 0, r0, c7, c7, 0	/* flush Icache, Dcache and BTB     */
+    CPWAIT
+
+	mcr	p15, 0, r0, c8, c7, 0	/* flush instuction and data TLBs   */
+    CPWAIT
+
+	/* Enable the Icache                                                */
+/*
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #0x1800
+	mcr	p15, 0, r0, c1, c0, 0
+    CPWAIT
+*/
+	mov	pc, lr
+
+
+/****************************************************************************/
+/*                                                                          */
+/* Interrupt handling                                                       */
+/*                                                                          */
+/****************************************************************************/
+
+/* IRQ stack frame                                                          */
+
+#define S_FRAME_SIZE	72
+
+#define S_OLD_R0	68
+#define S_PSR		64
+#define S_PC		60
+#define S_LR		56
+#define S_SP		52
+
+#define S_IP		48
+#define S_FP		44
+#define S_R10		40
+#define S_R9		36
+#define S_R8		32
+#define S_R7		28
+#define S_R6		24
+#define S_R5		20
+#define S_R4		16
+#define S_R3		12
+#define S_R2		8
+#define S_R1		4
+#define S_R0		0
+
+#define MODE_SVC 0x13
+
+	/* use bad_save_user_regs for abort/prefetch/undef/swi ...          */
+
+	.macro	bad_save_user_regs
+	sub	sp, sp, #S_FRAME_SIZE
+	stmia	sp, {r0 - r12}			/* Calling r0-r12           */
+	add     r8, sp, #S_PC
+
+	ldr	r2, _armboot_end
+	add	r2, r2, #CONFIG_STACKSIZE
+	sub	r2, r2, #8
+	ldmia	r2, {r2 - r4}                   /* get pc, cpsr, old_r0     */
+	add	r0, sp, #S_FRAME_SIZE		/* restore sp_SVC           */
+
+	add	r5, sp, #S_SP
+	mov	r1, lr
+	stmia	r5, {r0 - r4}                   /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
+	mov	r0, sp
+	.endm
+
+
+	/* use irq_save_user_regs / irq_restore_user_regs for                */
+	/* IRQ/FIQ handling                                                  */
+
+	.macro	irq_save_user_regs
+	sub	sp, sp, #S_FRAME_SIZE
+	stmia	sp, {r0 - r12}			/* Calling r0-r12            */
+	add     r8, sp, #S_PC
+	stmdb   r8, {sp, lr}^                   /* Calling SP, LR            */
+	str     lr, [r8, #0]                    /* Save calling PC           */
+	mrs     r6, spsr
+	str     r6, [r8, #4]                    /* Save CPSR                 */
+	str     r0, [r8, #8]                    /* Save OLD_R0               */
+	mov	r0, sp
+	.endm
+
+	.macro	irq_restore_user_regs
+	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
+	mov	r0, r0
+	ldr	lr, [sp, #S_PC]			@ Get PC
+	add	sp, sp, #S_FRAME_SIZE
+	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
+	.endm
+
+	.macro get_bad_stack
+	ldr	r13, _armboot_end		@ setup our mode stack
+	add	r13, r13, #CONFIG_STACKSIZE	@ resides at top of normal stack
+	sub	r13, r13, #8
+
+	str	lr, [r13]			@ save caller lr / spsr
+	mrs	lr, spsr
+	str     lr, [r13, #4]
+
+	mov	r13, #MODE_SVC			@ prepare SVC-Mode
+	msr	spsr_c, r13
+	mov	lr, pc
+	movs	pc, lr
+	.endm
+
+	.macro get_irq_stack			@ setup IRQ stack
+	ldr	sp, IRQ_STACK_START
+	.endm
+
+	.macro get_fiq_stack			@ setup FIQ stack
+	ldr	sp, FIQ_STACK_START
+	.endm
+
+
+/****************************************************************************/
+/*                                                                          */
+/* exception handlers                                                       */
+/*                                                                          */
+/****************************************************************************/
+
+	.align  5
+undefined_instruction:
+	get_bad_stack
+	bad_save_user_regs
+	bl 	do_undefined_instruction
+
+	.align	5
+software_interrupt:
+	get_bad_stack
+	bad_save_user_regs
+	bl 	do_software_interrupt
+
+	.align	5
+prefetch_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl 	do_prefetch_abort
+
+	.align	5
+data_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl 	do_data_abort
+
+	.align	5
+not_used:
+	get_bad_stack
+	bad_save_user_regs
+	bl 	do_not_used
+
+#ifdef CONFIG_USE_IRQ
+
+	.align	5
+irq:
+	get_irq_stack
+	irq_save_user_regs
+	bl 	do_irq
+	irq_restore_user_regs
+
+	.align	5
+fiq:
+	get_fiq_stack
+	irq_save_user_regs		/* someone ought to write a more    */
+	bl 	do_fiq			/* effiction fiq_save_user_regs     */
+	irq_restore_user_regs
+
+#else
+
+	.align	5
+irq:
+	get_bad_stack
+	bad_save_user_regs
+	bl 	do_irq
+
+	.align	5
+fiq:
+	get_bad_stack
+	bad_save_user_regs
+	bl 	do_fiq
+
+#endif
+
+/*
+ * FIXME How do we reset??? Watchdog timeout??
+ */
+	.align	5
+.globl reset_cpu
+reset_cpu:
+	/*
+	ldr	r0, RST_BASE
+	mov	r1, #0x0			@ set bit 3-0 ...
+	str	r1, [r0, #RCSR]			@ ... to clear in RCSR
+	mov	r1, #0x1
+	str	r1, [r0, #RCSR]			@ and perform reset
+	*/
+	b	reset_cpu			@ silly, but repeat endlessly
+
diff --git a/doc/README.JFFS2 b/doc/README.JFFS2
new file mode 100644
index 0000000..0d39c46
--- /dev/null
+++ b/doc/README.JFFS2
@@ -0,0 +1,68 @@
+JFFS2 options and usage.
+-----------------------
+
+JFFS2 in U-Boot is a read only implementation of the file system in
+Linux with the same name. To use JFFS2 define CFG_CMD_JFFS2.
+
+The module adds three new commands.
+fsload  - load binary file from a file system image
+fsinfo  - print information about file systems
+ls      - list files in a directory
+
+
+There is two ways for JFFS2 to find the disk. The default way uses
+the flash_info structure to find the start of a JFFS2 disk (called
+partition in the code) and you can change where the partition is with
+two defines.
+
+CFG_JFFS2_FIRST_BANK
+	defined the first flash bank to use
+
+CFG_JFFS2_FIRST_SECTOR
+	defines the first sector to use
+
+
+The second way is to define CFG_JFFS_CUSTOM_PART and implement the
+jffs2_part_info(int part_num) function in your board specific files.
+In this mode CFG_JFFS2_FIRST_BANK and CFG_JFFS2_FIRST_SECTOR is not
+used.
+
+The input is a partition number starting with 0.
+Return a pointer to struct part_info or NULL for error;
+
+Ex jffs2_part_info() for one partition.
+---
+#if defined CFG_JFFS_CUSTOM_PART
+#include <jffs2/jffs2.h>
+
+static struct part_info part;
+
+struct part_info*
+jffs2_part_info(int part_num)
+{
+	if(part_num==0){
+		if(part.usr_priv==(void*)1)
+			return &part;
+
+		memset(&part, 0, sizeof(part));
+		part.offset=(char*)0xFF800000;
+		part.size=1024*1024*8;
+
+		/* Mark the struct as ready */
+		part.usr_priv=(void*)1;
+
+		return &part;
+	}
+	return 0;
+}
+#endif
+---
+
+TODO.
+
+        Add a new command so it's actually possible to change
+	partition.
+
+        Remove the assumption that JFFS can dereference a pointer
+        into the disk. The current code do not work with memory holes
+        or hardware with a sliding window (PCMCIA).
diff --git a/doc/README.Modem b/doc/README.Modem
new file mode 100644
index 0000000..a3ba7b7
--- /dev/null
+++ b/doc/README.Modem
@@ -0,0 +1,73 @@
+How to configure modem support in U-Boot :
+
+1. Define modem initialization strings:
+---------------------------------------
+
+The modem initialization strings have following format:
+
+	mdm_init1=<AT-command>
+	mdm_init2=<AT-command>
+	...
+
+Turning off modem verbose responses with ATV0 or ATQ1 is not allowed;
+U-Boot analyzes only verbose (not numeric) result codes. Modem local
+command echo can be turned off (ATE0).
+
+2. RTS/CTS hardware flow control:
+---------------------------------
+
+You may wish to enable RTS/CTS hardware flow control, if the board's
+UART driver supports it (see CONFIG_HWFLOW compile-time flag in
+config/<board>.h). This is controlled by the 'mdm_flow_control'
+environment variable:
+
+	'mdm_flow_control=rts/cts'  - to enable RTS/CTS flow control.
+	'mdm_flow_control=none '    - to disable.
+
+
+The following are the examples using a Rockwell OEM modem
+configuration:
+
+SAMSUNG # setenv mdm_init1 ATZ			- reset the modem to
+						  the factory defaults.
+SAMSUNG # setenv mdm_init2 ATS0=1               - set modem into
+						  answer mode.
+SAMSUNG # setenv mdm_flow_control rts/cts       - enable serial port
+						  flow control
+SAMSUNG # saveenv
+
+The example above initializes modem into answer mode to wait for the
+incoming call. RTS/CTS flow control is enabled for the serial port.
+(The RTS/CTS flow control is enabled by default on the modem).
+
+
+SAMSUNG # setenv mdm_init1 ATZ
+SAMSUNG # setenv mdm_init2 ATS39=0+IFC=0,0	- disable modem
+						  RTS/CTS flow control
+SAMSUNG # setenv mdm_init3 ATDT1643973         -  dial out the number
+SAMSUNG # setenv mdm_flow_control none
+SAMSUNG # saveenv
+
+The example above initializes modem to dial-up connection on the
+number 1643973. Flow control is disabled.
+
+Note that flow control must be turned both off or both on for the
+board serial port and for the modem.
+
+
+If the connection was set up successfully, the U-Boot prompt appears
+on the terminal console. If not (U-Boot modem was configured for
+originating the call and connection was not established) - the board
+should be reset for another dial-up try.
+
+
+Note on the SMDK2400 board:
+---------------------------
+
+Since the board serial ports does not have DTR signal wired, modem
+should be told to ignore port DTR setting prior to connection to the
+SMDK board, and this setting should be stored in modem NVRAM. For the
+Rockwell OEM modem this can to be done with the following command:
+
+AT&D0&W
+
diff --git a/doc/README.commands b/doc/README.commands
new file mode 100644
index 0000000..576186e
--- /dev/null
+++ b/doc/README.commands
@@ -0,0 +1,99 @@
+#
+# The commands in this table are sorted alphabetically by the
+# command name and in descending order by the command name string
+# length. This is to prevent conflicts in command name parsing.
+# Please ensure that new commands are added according to that rule.
+# See $(TOPDIR)/common/command.c
+#
+########################
+#
+# command	length
+#
+########################
+askenv		8
+as		2
+autoscr		5
+base		2
+bdinfo		2
+bootelf		7
+bootm		5
+bootp		5
+bootvx		6
+bootd		4
+break		2
+brginfo		3
+carinfo		3
+chpart		6
+cmp		3
+coninfo		5
+continue	4
+cp		2
+crc32		3
+date		3
+dcache		2
+dhcp		4
+dmainfo		3
+ds		2
+dtt		3
+echo		4
+eeprom		3
+erase		3
+fccinfo		3
+fdcboot		4
+flinfo		3
+fpga		4
+fsinfo		5
+fsload		5
+getdcr		6		# IBM 4XX DCR registers
+go		2
+help		1
+i2cinfo		4
+i2c		3
+icache		2
+icinfo		3
+ide		3
+iminfo		3
+iopinfo		3
+irqinfo		3
+kgdb		4
+loadb		5
+loads		5
+loop		4
+ls		2
+mccinfo		3
+md		2
+memcinfo	4
+mii		3
+mm		2
+mtest		5
+muxinfo		3
+mw		2
+next		4
+nm		2
+pciinfo		3
+pinit		4
+printenv	8
+protect		4
+rarpboot	4
+rdump		5
+reginfo		3
+reset		5
+run		3
+saveenv		4
+sccinfo		3
+scsiboot	5
+scsi		4
+siiinfo		3
+sitinfo		3
+siuinfo		3
+setdcr		6		# IBM 4XX DCR registers
+setenv		6
+smcinfo		3
+spiinfo		3
+stack		5
+step		4
+tftpboot	4
+usbboot		5
+usb		4
+version		4
+?		1
diff --git a/doc/README.ebony b/doc/README.ebony
new file mode 100644
index 0000000..12a0d70
--- /dev/null
+++ b/doc/README.ebony
@@ -0,0 +1,138 @@
+                           IBM Ebony Board
+
+                    Last Update: September 12, 2002
+=======================================================================
+
+This file contains some handy info regarding U-Boot and the IBM
+Ebony evalutation board. See the README.ppc440 for additional
+information.
+
+
+SWITCH SETTINGS & JUMPERS
+==========================
+
+Here's what I've been using successfully. If you feel inclined to
+change things ... please read the docs!
+
+DIPSW   U46         U80
+------------------------
+SW 1    off         on
+SW 2    on          on
+SW 3    on          on
+SW 4    off         on
+SW 5    on          off
+SW 6    on          on
+SW 7    on          off
+SW 8    on          off
+
+J41: strapped
+J42: open
+
+All others are factory default.
+
+
+I2C iprobe
+=====================
+
+The i2c utilities have been tested on both Rev B. and Rev C. and
+look good. The CFG_I2C_NOPROBES macro is defined to prevent
+probing the CDCV850 clock controller at address 0x69 (since reading
+it causes the i2c implementation to misbehave. The output of
+iprobe should look like this (assuming you are only using a single
+SO-DIMM:
+
+=> iprobe
+Valid chip addresses: 50 53 54
+Excluded chip addresses: 69
+
+
+GETTING OUT OF I2C TROUBLE
+===========================
+
+If you're like me ... you may have screwed up your bootstrap serial
+eeprom ... or worse, your SPD eeprom when experimenting with the
+i2c commands. If so, here are some ideas on how to get out of
+trouble:
+
+Serial bootstrap eeprom corruption:
+-----------------------------------
+Power down the board and set the following straps:
+
+J41 - open
+J42 - strapped
+
+This will select the default sys0 and sys1 settings (the serial
+eeproms are not used). Then power up the board and fix the serial
+eeprom using the imm command. Here are the values I currently
+use:
+
+=> imd 50 0 10
+0000: bf a2 04 01 ae 94 11 00 00 00 00 00 00 00 00 00    ................
+
+=> imd 54 0 10
+0000: 8f b3 24 01 4d 14 11 00 00 00 00 00 00 00 00 00    ..$.M...........
+
+Once you have the eeproms set correctly change the
+J41/J42 straps as you desire.
+
+SPD eeprom corruption:
+------------------------
+I've corrupted the SPD eeprom several times ... perhaps too much coffee
+and not enough presence of mind ;-). By default, the ebony code uses
+the SPD to initialize the DDR SDRAM control registers. So if the SPD
+eeprom is corrupted, U-Boot will never get into ram. Here's how I got
+out of this situation:
+
+0. First, _before_ playing with the i2c utilities, do an iprobe, then
+use imd to capture the various device contents to a file. Some day
+you may be glad you did this ... trust me :-). Otherwise try the
+following:
+
+1. In the include/configs/EBONY.h file find the line that defines
+the CONFIG_SPD_EEPROM macro and undefine it. E.g:
+
+#undef CONFIG_SPD_EEPROM
+
+This will make the code use default SDRAM control register
+settings without using the SPD eeprom.
+
+2. Rebuild U-Boot
+
+3. Load the new U-Boot image and reboot ebony.
+
+4. Repair the SPD eeprom using the imm command. Here's the eeprom
+contents that work with the default SO-DIMM that comes with the
+ebony board (micron 8VDDT164AG-265A1). Note: these are probably
+_not_ the factory settings ... but they work.
+
+=> imd 53 0 10 80
+0000: 80 08 07 0c 0a 01 40 00 04 75 75 00 80 08 00 01    ......@..uu.....
+0010: 0e 04 0c 01 02 20 00 a0 75 00 00 50 3c 50 2d 20    ..... ..u..P<P-
+0020: 90 90 50 50 00 00 00 00 00 41 4b 34 32 75 00 00    ..PP.....AK42u..
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c    ................
+0040: 2c 00 00 00 00 00 00 00 08 38 56 44 44 54 31 36    ,........8VDDT16
+0050: 36 34 41 47 2d 32 36 35 41 31 20 01 00 01 2c 63    64AG-265A1 ...,c
+0060: 22 25 ab 00 00 00 00 00 00 00 00 00 00 00 00 00    "%..............
+0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
+
+
+PCI DOUBLE-ENUMERATION WOES
+===========================
+
+If you're not using PCI-X cards and are simply using 32-bit and/or
+33 MHz cards via extenders and the like, you may notice that the
+initial pci scan reports various devices twice ... and configuration
+does not succeed (one or more devices are enumerated twice). To correct
+this we replaced the 2K ohm resistor on the IDSEL line(s) with a
+22 ohm resistor and the problem went away. This change hasn't broken
+anything yet -- use at your own risk.
+
+We never tested anything other than 33 MHz/32-bit cards. If you have
+the chance to do this, please let me know how things turn out :-)
+
+
+
+Regards,
+--Scott
+<smcnutt@artesyncp.com>
+
diff --git a/doc/README.ppc440 b/doc/README.ppc440
new file mode 100644
index 0000000..acb0c6f
--- /dev/null
+++ b/doc/README.ppc440
@@ -0,0 +1,204 @@
+                           PowerPC 440
+
+                    Last Update: September 11, 2002
+=======================================================================
+
+
+OVERVIEW
+============
+
+Support for the ppc440 is contained in the cpu/ppc44x directory
+and enabled via the CONFIG_440 flag. It is largely based on the
+405gp code. A sample board support implementation is contained
+in the board/ebony directory.
+
+All testing was performed using the IBM Ebony board using both
+Rev B and Rev C silicon. However, since the Rev B. silicon has
+extensive errata, support for Rev B. is minimal (it boots, and
+features such as i2c, pci, tftpboot, etc. seem to work ok).
+The expectation is that all new board designs will be using
+Rev C or later parts -- if not, you may be in for a rough ride ;-)
+
+The ppc440 port does a fair job of keeping "board-specific" code
+out of the "cpu-specific" source. The goal of course was to
+provide mechanisms for each board to customize without having
+to clutter the cpu-specific source with a lot of ifdefs. Most
+of these mechanisms are described in the following sections.
+
+
+MEMORY MANAGEMENT
+=================
+
+The ppc440 doesn't run in "real mode". The MMU must be active
+at all times. Additionally, the 440 implements a 36-bit physical
+memory space that gets mapped into the PowerPC 32-bit virtual
+address space. So things like memory-mapped peripherals, etc must
+all be mapped in. Once this is done, the 32-bit virtual address
+space is then viewed as though it were physical memory.
+
+However, this means that memory, peripherals, etc can be configured
+to appear (mostly) anywhere in the virtual address space. Each board
+must define its own mappings using the tlbtab (see board/ebony/init.S).
+The actual TLB setup is performed by the cpu-specific code.
+
+Although each board is free to define its own mappings, there are
+several definitions to be aware of. These definitions may be used in
+the cpu-specific code (vs. board-specific code), so you should
+at least review these before deciding to make any changes ... it
+will probably save you some headaches ;-)
+
+CFG_SDRAM_BASE - The virtual address where SDRAM is mapped (always 0)
+
+CFG_FLASH_BASE - The virtual address where FLASH is mapped.
+
+CFG_PCI_MEMBASE - The virtual address where PCI-bus memory is mapped.
+    This mapping provides access to PCI-bus memory.
+
+CFG_PERIPHERAL_BASE - The virtual address where the 440 memory-mapped
+    peripherals are mapped. (e.g. -- UART registers, IIC registers, etc).
+
+CFG_ISRAM_BASE - The virtual address where the 440 internal SRAM is
+    mapped. The internal SRAM is equivalent to 405gp OCM and is used
+    for the initial stack.
+
+CFG_PCI_BASE - The virtual address where the 440 PCI-x bridge config
+    registers are mapped.
+
+CFG_PCI_TARGBASE - The PCI address that is mapped to the virtual address
+    defined by CFG_PCI_MEMBASE.
+
+
+UART / SERIAL
+=================
+
+The UART port works fine when an external serial clock is provided
+(like the one on the Ebony board) and when using internal clocking.
+This is controlled with the CFG_EXT_SERIAL_CLOCK flag. When using
+internal clocking, the "ideal baud rate" settings in the 440GP
+user manual are automatically calculated.
+
+CONFIG_SERIAL_SOFTWARE_FIFO enables interrupt-driven serial operation.
+But the last time I checked, interrupts were initialized after the
+serial port causing the interrupt handler to be removed from the
+handler table. This will probably be fixed soon ... or fix it
+yourself and submit a patch :-)
+
+
+I2C
+=================
+
+The i2c utilities have been tested on both Rev B. and Rev C. and
+look good. The iprobe command implementation has been updated to
+allow for 'skipped' addresses. Some i2c slaves are write only and
+cause problems when a probe (read) is performed (for example the
+CDCV850 clock controller at address 0x69 on the ebony board).
+
+To prevent probing certain addresses you can define the
+CFG_I2C_NOPROBES macro in your board-specific header file. When
+defined, all specified addresses are skipped during a probe.
+The addresses that are skipped will be displayed in the output
+of the iprobe command.
+
+For example, to prevent probing address 0x69, define the macro as
+follows:
+
+#define CFG_I2C_NOPROBES {0x69}
+
+Similarly, to prevent probing addresses 0x69 and 0x70, define the
+macro a:
+
+#define CFG_I2C_NOPROBES {0x69, 0x70}
+
+
+DDR SDRAM CONTROLLER
+====================
+
+SDRAM controller intialization using Serial Presence Detect (SPD) is
+now supported (thanks Jun). It is enabled by defining CONFIG_SPD_EEPROM.
+The i2c eeprom addresses are controlled by the SPD_EEPROM_ADDRESS macro.
+
+NOTE: The SPD_EEPROM_ADDRESS macro is defined differently than for other
+processors. Traditionally, it defined a single address. For the 440 it
+defines an array of addresses to support multiple banks. Address order
+is significant: the addresses are used in order to program the BankN
+registers. For example, two banks with i2c addresses of 0x53 (bank 0)
+and 0x52 (bank 1) would be defined as follows:
+
+#define SPD_EEPROM_ADDRESS {0x53,0x52}
+
+
+PCI-X BRIDGE
+====================
+
+PCI is an area that requires lots of flexibility since every board has
+its own set of constraints and configuration. This section describes the
+440 implementation.
+
+CPC0_STRP1[PISE] -- if the PISE strap bit is not asserted, PCI init
+is aborted and an indication is printed. This is NOT considered an
+error -- only an indication that PCI shouldn't be initialized. This
+gives you a chance to edit the i2c bootstrap eeproms using the i2c
+utilities once you get to the U-Boot command prompt. NOTE: the default
+440 bootstrap options (not using i2c eeprom) negates this bit.
+
+The cpu-specific code sets up a default pci_controller structure
+that maps in a single PCI I/O space and PCI memory space. The I/O
+space begins at PCI I/O address 0 and the PCI memory space is
+256 MB starting at PCI address CFG_PCI_TARGBASE. After the
+pci_controller structure is initialized, the cpu-specific code will
+call the routine pci_pre_init() if the CFG_PCI_PRE_INIT flag is
+defined. This routine is implemented by board-specific code & is where
+the board can over-ride/extend the default pci_controller structure
+settings and do other pre-initialization tasks. If pci_pre_init()
+returns a value of zero, PCI initialization is aborted; otherwise the
+controller structure is registered and initialization continues.
+
+The default 440GP PCI target configuration is minimal -- it assumes that
+the strapping registers are set as necessary. Since the strapping bits
+provide very limited flexibility, you may want to customize the boards
+target configuration. If CFG_PCI_TARGET_INIT is defined, the cpu-specific
+code will call the routine pci_target_init() which you must implement
+in your board-specific code.
+
+Target initialization is completed by the cpu-specific code by
+initializing the subsystem id and subsystem vendor id, and then ensuring
+that the 'enable host configuration' bit in the PCIX0_BRDGOPT2 is set.
+
+The default PCI master initialization maps in 256 MB of pci memory
+starting at PCI address CFG_PCI_MEMBASE. To customize this, define
+PCI_MASTER_INIT. This will call the routine pci_master_init() in your
+board-specific code rather than performing the default master
+initialization.
+
+The decision to perform PCI host configuration must often be determined
+at run time. The ppc440 port differs from most other implementations in
+that it requires the board to determine its host configuration at run
+time rather than by using compile-time flags. This shouldn't create a
+large impact on the board-specific code since the board only needs to
+implement a single routine that returns a zero or non-zero value:
+is_pci_host().
+
+Justification for this becomes clear when considering systems running
+in a cPCI environment:
+
+1. Arbiter strapping: Many cPCI boards provide an external arbiter (often
+part of the PCI-to-PCI bridge). Even though the arbiter is external (the
+arbiter strapping is negated), the CPU may still be required to perform
+local PCI bus configuration.
+
+2. Host only: PPMC boards must sample the MONARCH# signal at run-time.
+Depending on the configuration of the carrier boar, the PPMC board must
+determine if it should configure the PCI bus at run-time. And in most
+cases, access to the MONARCH# signal is board-specific (e.g. via
+board-specific FPGA registers, etc).
+
+In any event, the is_pci_host() routine gives each board the opportunity
+to decide at run-time. If your board is always configured a certain way,
+then just hardcode a return of 1 or 0 as appropriate.
+
+
+
+Regards,
+--Scott
+<smcnutt@artesyncp.com>
+
diff --git a/drivers/3c589.h b/drivers/3c589.h
new file mode 100644
index 0000000..00e7f7c
--- /dev/null
+++ b/drivers/3c589.h
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2. The name
+ * of the author may not be used to endorse or promote products derived from
+ * this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ October 2, 1994
+
+ Modified by: Andres Vega Garcia
+
+ INRIA - Sophia Antipolis, France
+ e-mail: avega@sophia.inria.fr
+ finger: avega@pax.inria.fr
+
+ */
+
+/*
+ * Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the
+ * 3c590 family.
+ */
+
+/*
+ * Modified by Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
+ * for etherboot
+ * Mar. 14, 2000
+*/
+
+/*
+ * Ethernet software status per interface.
+ */
+
+/*
+ * Some global constants
+ */
+
+#define TX_INIT_RATE         16
+#define TX_INIT_MAX_RATE     64
+#define RX_INIT_LATENCY      64
+#define RX_INIT_EARLY_THRESH 64
+#define MIN_RX_EARLY_THRESHF   16 /* not less than ether_header */
+#define MIN_RX_EARLY_THRESHL   4
+
+#define EEPROMSIZE      0x40
+#define MAX_EEPROMBUSY  1000
+#define VX_LAST_TAG     0xd7
+#define VX_MAX_BOARDS   16
+#define VX_ID_PORT      0x100
+
+/*
+ * some macros to acces long named fields
+ */
+#define BASE 	(EL_BASE_ADDR)
+
+/*
+ * Commands to read/write EEPROM trough EEPROM command register (Window 0,
+ * Offset 0xa)
+ */
+#define EEPROM_CMD_RD    0x0080	/* Read:  Address required (5 bits) */
+#define EEPROM_CMD_WR    0x0040	/* Write: Address required (5 bits) */
+#define EEPROM_CMD_ERASE 0x00c0	/* Erase: Address required (5 bits) */
+#define EEPROM_CMD_EWEN  0x0030	/* Erase/Write Enable: No data required */
+
+#define EEPROM_BUSY		(1<<15)
+
+/*
+ * Some short functions, worth to let them be a macro
+ */
+
+/**************************************************************************
+ *									  *
+ * These define the EEPROM data structure.  They are used in the probe
+ * function to verify the existence of the adapter after having sent
+ * the ID_Sequence.
+ *
+ * There are others but only the ones we use are defined here.
+ *
+ **************************************************************************/
+
+#define EEPROM_NODE_ADDR_0	0x0	/* Word */
+#define EEPROM_NODE_ADDR_1	0x1	/* Word */
+#define EEPROM_NODE_ADDR_2	0x2	/* Word */
+#define EEPROM_PROD_ID		0x3	/* 0x9[0-f]50 */
+#define EEPROM_MFG_ID		0x7	/* 0x6d50 */
+#define EEPROM_ADDR_CFG		0x8	/* Base addr */
+#define EEPROM_RESOURCE_CFG	0x9	/* IRQ. Bits 12-15 */
+#define EEPROM_OEM_ADDR_0	0xa	/* Word */
+#define EEPROM_OEM_ADDR_1	0xb	/* Word */
+#define EEPROM_OEM_ADDR_2	0xc	/* Word */
+#define EEPROM_SOFT_INFO_2	0xf     /* Software information 2 */
+
+#define NO_RX_OVN_ANOMALY       (1<<5)
+
+/**************************************************************************
+ *										  *
+ * These are the registers for the 3Com 3c509 and their bit patterns when *
+ * applicable.  They have been taken out the the "EtherLink III Parallel  *
+ * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
+ * from 3com.								  *
+ *										  *
+ **************************************************************************/
+
+#define VX_COMMAND		0x0e	/* Write. BASE+0x0e is always a
+					 * command reg. */
+#define VX_STATUS		0x0e	/* Read. BASE+0x0e is always status
+					 * reg. */
+#define VX_WINDOW		0x0f	/* Read. BASE+0x0f is always window
+					 * reg. */
+/*
+ * Window 0 registers. Setup.
+ */
+/* Write */
+#define VX_W0_EEPROM_DATA	0x0c
+#define VX_W0_EEPROM_COMMAND	0x0a
+#define VX_W0_RESOURCE_CFG	0x08
+#define VX_W0_ADDRESS_CFG	0x06
+#define VX_W0_CONFIG_CTRL	0x04
+        /* Read */
+#define VX_W0_PRODUCT_ID	0x02
+#define VX_W0_MFG_ID		0x00
+
+
+/*
+ * Window 1 registers. Operating Set.
+ */
+/* Write */
+#define VX_W1_TX_PIO_WR_2	0x02
+#define VX_W1_TX_PIO_WR_1	0x00
+/* Read */
+#define VX_W1_FREE_TX		0x0c
+#define VX_W1_TX_STATUS		0x0b	/* byte */
+#define VX_W1_TIMER		0x0a	/* byte */
+#define VX_W1_RX_STATUS		0x08
+#define VX_W1_RX_PIO_RD_2	0x02
+#define VX_W1_RX_PIO_RD_1	0x00
+
+/*
+ * Window 2 registers. Station Address Setup/Read
+ */
+/* Read/Write */
+#define VX_W2_ADDR_5		0x05
+#define VX_W2_ADDR_4		0x04
+#define VX_W2_ADDR_3		0x03
+#define VX_W2_ADDR_2		0x02
+#define VX_W2_ADDR_1		0x01
+#define VX_W2_ADDR_0		0x00
+
+/*
+ * Window 3 registers. FIFO Management.
+ */
+/* Read */
+#define VX_W3_INTERNAL_CFG	0x00
+#define VX_W3_RESET_OPT		0x08
+#define VX_W3_FREE_TX		0x0c
+#define VX_W3_FREE_RX		0x0a
+
+/*
+ * Window 4 registers. Diagnostics.
+ */
+/* Read/Write */
+#define VX_W4_MEDIA_TYPE	0x0a
+#define VX_W4_CTRLR_STATUS	0x08
+#define VX_W4_NET_DIAG		0x06
+#define VX_W4_FIFO_DIAG		0x04
+#define VX_W4_HOST_DIAG		0x02
+#define VX_W4_TX_DIAG		0x00
+
+/*
+ * Window 5 Registers.  Results and Internal status.
+ */
+/* Read */
+#define VX_W5_READ_0_MASK	0x0c
+#define VX_W5_INTR_MASK		0x0a
+#define VX_W5_RX_FILTER		0x08
+#define VX_W5_RX_EARLY_THRESH	0x06
+#define VX_W5_TX_AVAIL_THRESH	0x02
+#define VX_W5_TX_START_THRESH	0x00
+
+/*
+ * Window 6 registers. Statistics.
+ */
+/* Read/Write */
+#define TX_TOTAL_OK		0x0c
+#define RX_TOTAL_OK		0x0a
+#define TX_DEFERRALS		0x08
+#define RX_FRAMES_OK		0x07
+#define TX_FRAMES_OK		0x06
+#define RX_OVERRUNS		0x05
+#define TX_COLLISIONS		0x04
+#define TX_AFTER_1_COLLISION	0x03
+#define TX_AFTER_X_COLLISIONS	0x02
+#define TX_NO_SQE		0x01
+#define TX_CD_LOST		0x00
+
+/****************************************
+ *
+ * Register definitions.
+ *
+ ****************************************/
+
+/*
+ * Command register. All windows.
+ *
+ * 16 bit register.
+ *     15-11:  5-bit code for command to be executed.
+ *     10-0:   11-bit arg if any. For commands with no args;
+ *	      this can be set to anything.
+ */
+#define GLOBAL_RESET		(unsigned short) 0x0000	/* Wait at least 1ms
+							 * after issuing */
+#define WINDOW_SELECT		(unsigned short) (0x1<<11)
+#define START_TRANSCEIVER	(unsigned short) (0x2<<11)	/* Read ADDR_CFG reg to
+							 * determine whether
+							 * this is needed. If
+							 * so; wait 800 uSec
+							 * before using trans-
+							 * ceiver. */
+#define RX_DISABLE		(unsigned short) (0x3<<11)	/* state disabled on
+							 * power-up */
+#define RX_ENABLE		(unsigned short) (0x4<<11)
+#define RX_RESET		(unsigned short) (0x5<<11)
+#define RX_DISCARD_TOP_PACK	(unsigned short) (0x8<<11)
+#define TX_ENABLE		(unsigned short) (0x9<<11)
+#define TX_DISABLE		(unsigned short) (0xa<<11)
+#define TX_RESET		(unsigned short) (0xb<<11)
+#define REQ_INTR		(unsigned short) (0xc<<11)
+/*
+ * The following C_* acknowledge the various interrupts. Some of them don't
+ * do anything.  See the manual.
+ */
+#define ACK_INTR		(unsigned short) (0x6800)
+#	define C_INTR_LATCH	(unsigned short) (ACK_INTR|0x1)
+#	define C_CARD_FAILURE	(unsigned short) (ACK_INTR|0x2)
+#	define C_TX_COMPLETE	(unsigned short) (ACK_INTR|0x4)
+#	define C_TX_AVAIL	(unsigned short) (ACK_INTR|0x8)
+#	define C_RX_COMPLETE	(unsigned short) (ACK_INTR|0x10)
+#	define C_RX_EARLY	(unsigned short) (ACK_INTR|0x20)
+#	define C_INT_RQD		(unsigned short) (ACK_INTR|0x40)
+#	define C_UPD_STATS	(unsigned short) (ACK_INTR|0x80)
+#define SET_INTR_MASK		(unsigned short) (0xe<<11)
+#define SET_RD_0_MASK		(unsigned short) (0xf<<11)
+#define SET_RX_FILTER		(unsigned short) (0x10<<11)
+#	define FIL_INDIVIDUAL	(unsigned short) (0x1)
+#	define FIL_MULTICAST     (unsigned short) (0x02)
+#	define FIL_BRDCST        (unsigned short) (0x04)
+#	define FIL_PROMISC       (unsigned short) (0x08)
+#define SET_RX_EARLY_THRESH	(unsigned short) (0x11<<11)
+#define SET_TX_AVAIL_THRESH	(unsigned short) (0x12<<11)
+#define SET_TX_START_THRESH	(unsigned short) (0x13<<11)
+#define STATS_ENABLE		(unsigned short) (0x15<<11)
+#define STATS_DISABLE		(unsigned short) (0x16<<11)
+#define STOP_TRANSCEIVER	(unsigned short) (0x17<<11)
+
+/*
+ * Status register. All windows.
+ *
+ *     15-13:  Window number(0-7).
+ *     12:     Command_in_progress.
+ *     11:     reserved.
+ *     10:     reserved.
+ *     9:      reserved.
+ *     8:      reserved.
+ *     7:      Update Statistics.
+ *     6:      Interrupt Requested.
+ *     5:      RX Early.
+ *     4:      RX Complete.
+ *     3:      TX Available.
+ *     2:      TX Complete.
+ *     1:      Adapter Failure.
+ *     0:      Interrupt Latch.
+ */
+#define S_INTR_LATCH		(unsigned short) (0x1)
+#define S_CARD_FAILURE		(unsigned short) (0x2)
+#define S_TX_COMPLETE		(unsigned short) (0x4)
+#define S_TX_AVAIL		(unsigned short) (0x8)
+#define S_RX_COMPLETE		(unsigned short) (0x10)
+#define S_RX_EARLY		(unsigned short) (0x20)
+#define S_INT_RQD		(unsigned short) (0x40)
+#define S_UPD_STATS		(unsigned short) (0x80)
+#define S_COMMAND_IN_PROGRESS	(unsigned short) (0x1000)
+
+#define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS)
+
+/* Address Config. Register.
+ * Window 0/Port 06
+ */
+
+#define ACF_CONNECTOR_BITS	14
+#define ACF_CONNECTOR_UTP	0
+#define ACF_CONNECTOR_AUI	1
+#define ACF_CONNECTOR_BNC	3
+
+#define INTERNAL_CONNECTOR_BITS 20
+#define INTERNAL_CONNECTOR_MASK 0x01700000
+
+/*
+ * FIFO Registers. RX Status.
+ *
+ *     15:     Incomplete or FIFO empty.
+ *     14:     1: Error in RX Packet   0: Incomplete or no error.
+ *     13-11:  Type of error.
+ *	      1000 = Overrun.
+ *	      1011 = Run Packet Error.
+ *	      1100 = Alignment Error.
+ *	      1101 = CRC Error.
+ *	      1001 = Oversize Packet Error (>1514 bytes)
+ *	      0010 = Dribble Bits.
+ *	      (all other error codes, no errors.)
+ *
+ *     10-0:   RX Bytes (0-1514)
+ */
+#define ERR_INCOMPLETE  (unsigned short) (0x8000)
+#define ERR_RX          (unsigned short) (0x4000)
+#define ERR_MASK        (unsigned short) (0x7800)
+#define ERR_OVERRUN     (unsigned short) (0x4000)
+#define ERR_RUNT        (unsigned short) (0x5800)
+#define ERR_ALIGNMENT   (unsigned short) (0x6000)
+#define ERR_CRC         (unsigned short) (0x6800)
+#define ERR_OVERSIZE    (unsigned short) (0x4800)
+#define ERR_DRIBBLE     (unsigned short) (0x1000)
+
+/*
+ * TX Status.
+ *
+ *   Reports the transmit status of a completed transmission. Writing this
+ *   register pops the transmit completion stack.
+ *
+ *   Window 1/Port 0x0b.
+ *
+ *     7:      Complete
+ *     6:      Interrupt on successful transmission requested.
+ *     5:      Jabber Error (TP Only, TX Reset required. )
+ *     4:      Underrun (TX Reset required. )
+ *     3:      Maximum Collisions.
+ *     2:      TX Status Overflow.
+ *     1-0:    Undefined.
+ *
+ */
+#define TXS_COMPLETE		0x80
+#define TXS_INTR_REQ		0x40
+#define TXS_JABBER		0x20
+#define TXS_UNDERRUN		0x10
+#define TXS_MAX_COLLISION	0x8
+#define TXS_STATUS_OVERFLOW	0x4
+
+#define RS_AUI			(1<<5)
+#define RS_BNC			(1<<4)
+#define RS_UTP			(1<<3)
+#define	RS_T4			(1<<0)
+#define	RS_TX			(1<<1)
+#define	RS_FX			(1<<2)
+#define	RS_MII			(1<<6)
+
+
+/*
+ * FIFO Status (Window 4)
+ *
+ *   Supports FIFO diagnostics
+ *
+ *   Window 4/Port 0x04.1
+ *
+ *     15:	1=RX receiving (RO). Set when a packet is being received
+ *		into the RX FIFO.
+ *     14:	Reserved
+ *     13:	1=RX underrun (RO). Generates Adapter Failure interrupt.
+ *		Requires RX Reset or Global Reset command to recover.
+ *		It is generated when you read past the end of a packet -
+ *		reading past what has been received so far will give bad
+ *		data.
+ *     12:	1=RX status overrun (RO). Set when there are already 8
+ *		packets in the RX FIFO. While this bit is set, no additional
+ *		packets are received. Requires no action on the part of
+ *		the host. The condition is cleared once a packet has been
+ *		read out of the RX FIFO.
+ *     11:	1=RX overrun (RO). Set when the RX FIFO is full (there
+ *		may not be an overrun packet yet). While this bit is set,
+ *		no additional packets will be received (some additional
+ *		bytes can still be pending between the wire and the RX
+ *		FIFO). Requires no action on the part of the host. The
+ *		condition is cleared once a few bytes have been read out
+ *		from the RX FIFO.
+ *     10:	1=TX overrun (RO). Generates adapter failure interrupt.
+ *		Requires TX Reset or Global Reset command to recover.
+ *		Disables Transmitter.
+ *     9-8:	Unassigned.
+ *     7-0:	Built in self test bits for the RX and TX FIFO's.
+ */
+#define FIFOS_RX_RECEIVING	(unsigned short) 0x8000
+#define FIFOS_RX_UNDERRUN	(unsigned short) 0x2000
+#define FIFOS_RX_STATUS_OVERRUN	(unsigned short) 0x1000
+#define FIFOS_RX_OVERRUN	(unsigned short) 0x0800
+#define FIFOS_TX_OVERRUN	(unsigned short) 0x0400
+
+/*
+ * Misc defines for various things.
+ */
+#define TAG_ADAPTER                     0xd0
+#define ACTIVATE_ADAPTER_TO_CONFIG      0xff
+#define ENABLE_DRQ_IRQ                  0x0001
+#define MFG_ID                          0x506d  /* `TCM' */
+#define PROD_ID                         0x5090
+#define GO_WINDOW(x)		outw(WINDOW_SELECT|(x),BASE+VX_COMMAND)
+#define JABBER_GUARD_ENABLE	0x40
+#define LINKBEAT_ENABLE		0x80
+#define	ENABLE_UTP		(JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
+#define DISABLE_UTP		0x0
+#define RX_BYTES_MASK		(unsigned short) (0x07ff)
+#define RX_ERROR        0x4000
+#define RX_INCOMPLETE   0x8000
+#define TX_INDICATE		1<<15
+#define is_eeprom_busy(b)	(inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY)
+
+#define	VX_IOSIZE	0x20
+
+#define VX_CONNECTORS 8
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/5701rls.c b/drivers/5701rls.c
new file mode 100644
index 0000000..c4409e4
--- /dev/null
+++ b/drivers/5701rls.c
@@ -0,0 +1,46 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*                                                                            */
+/******************************************************************************/
+
+#if INCLUDE_5701_AX_FIX
+
+#include "bcm570x_mm.h"
+#include "5701rls.h"
+
+LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice)
+{
+  T3_FWIMG_INFO FwImgInfo;
+
+  FwImgInfo.StartAddress = t3FwStartAddr;
+  FwImgInfo.Text.Buffer = (PLM_UINT8)t3FwText;
+  FwImgInfo.Text.Offset  = t3FwTextAddr;
+  FwImgInfo.Text.Length  = t3FwTextLen;
+  FwImgInfo.ROnlyData.Buffer = (PLM_UINT8)t3FwRodata;
+  FwImgInfo.ROnlyData.Offset  = t3FwRodataAddr;
+  FwImgInfo.ROnlyData.Length  = t3FwRodataLen;
+  FwImgInfo.Data.Buffer = (PLM_UINT8)t3FwData;
+  FwImgInfo.Data.Offset  = t3FwDataAddr;
+  FwImgInfo.Data.Length  = t3FwDataLen;
+
+  if (LM_LoadFirmware(pDevice,
+                      &FwImgInfo,
+                      T3_RX_CPU_ID | T3_TX_CPU_ID,
+                      T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
+    {
+      return LM_STATUS_FAILURE;
+    }
+
+  return LM_STATUS_SUCCESS;
+}
+
+#endif /* INCLUDE_5701_AX_FIX */
diff --git a/drivers/5701rls.h b/drivers/5701rls.h
new file mode 100644
index 0000000..30b127a
--- /dev/null
+++ b/drivers/5701rls.h
@@ -0,0 +1,198 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+
+typedef unsigned long U32;
+int t3FwReleaseMajor = 0x0;
+int t3FwReleaseMinor = 0x0;
+int t3FwReleaseFix = 0x0;
+U32 t3FwStartAddr = 0x08000000;
+U32 t3FwTextAddr = 0x08000000;
+int t3FwTextLen = 0x9c0;
+U32 t3FwRodataAddr = 0x080009c0;
+int t3FwRodataLen = 0x60;
+U32 t3FwDataAddr = 0x08000a40;
+int t3FwDataLen = 0x20;
+U32 t3FwSbssAddr = 0x08000a60;
+int t3FwSbssLen = 0xc;
+U32 t3FwBssAddr = 0x08000a70;
+int t3FwBssLen = 0x10;
+U32 t3FwText[(0x9c0/4) + 1] = {
+0x0,
+0x10000003, 0x0, 0xd, 0xd,
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
+0x26100000, 0xe000018, 0x0, 0xd,
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
+0x26100034, 0xe00021c, 0x0, 0xd,
+0x0, 0x0, 0x0, 0x27bdffe0,
+0x3c1cc000, 0xafbf0018, 0xaf80680c, 0xe00004c,
+0x241b2105, 0x97850000, 0x97870002, 0x9782002c,
+0x9783002e, 0x3c040800, 0x248409c0, 0xafa00014,
+0x21400, 0x621825, 0x52c00, 0xafa30010,
+0x8f860010, 0xe52825, 0xe000060, 0x24070102,
+0x3c02ac00, 0x34420100, 0x3c03ac01, 0x34630100,
+0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498,
+0xaf82049c, 0x24020001, 0xaf825ce0, 0xe00003f,
+0xaf825d00, 0xe000140, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x2402ffff, 0xaf825404,
+0x8f835400, 0x34630400, 0xaf835400, 0xaf825404,
+0x3c020800, 0x24420034, 0xaf82541c, 0x3e00008,
+0xaf805400, 0x0, 0x0, 0x3c020800,
+0x34423000, 0x3c030800, 0x34633000, 0x3c040800,
+0x348437ff, 0x3c010800, 0xac220a64, 0x24020040,
+0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60,
+0xac600000, 0x24630004, 0x83102b, 0x5040fffd,
+0xac600000, 0x3e00008, 0x0, 0x804821,
+0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800,
+0x8c840a68, 0x8fab0014, 0x24430001, 0x44102b,
+0x3c010800, 0xac230a60, 0x14400003, 0x4021,
+0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60,
+0x3c030800, 0x8c630a64, 0x91240000, 0x21140,
+0x431021, 0x481021, 0x25080001, 0xa0440000,
+0x29020008, 0x1440fff4, 0x25290001, 0x3c020800,
+0x8c420a60, 0x3c030800, 0x8c630a64, 0x8f84680c,
+0x21140, 0x431021, 0xac440008, 0xac45000c,
+0xac460010, 0xac470014, 0xac4a0018, 0x3e00008,
+0xac4b001c, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x2000008,
+0x0, 0xa0001e3, 0x3c0a0001, 0xa0001e3,
+0x3c0a0002, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x3c0a0007, 0xa0001e3, 0x3c0a0008, 0xa0001e3,
+0x3c0a0009, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x3c0a000b, 0xa0001e3,
+0x3c0a000c, 0xa0001e3, 0x3c0a000d, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x3c0a000e, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x3c0a0013, 0xa0001e3,
+0x3c0a0014, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x27bdffe0,
+0x1821, 0x1021, 0xafbf0018, 0xafb10014,
+0xafb00010, 0x3c010800, 0x220821, 0xac200a70,
+0x3c010800, 0x220821, 0xac200a74, 0x3c010800,
+0x220821, 0xac200a78, 0x24630001, 0x1860fff5,
+0x2442000c, 0x24110001, 0x8f906810, 0x32020004,
+0x14400005, 0x24040001, 0x3c020800, 0x8c420a78,
+0x18400003, 0x2021, 0xe000182, 0x0,
+0x32020001, 0x10400003, 0x0, 0xe000169,
+0x0, 0xa000153, 0xaf915028, 0x8fbf0018,
+0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0020,
+0x3c050800, 0x8ca50a70, 0x3c060800, 0x8cc60a80,
+0x3c070800, 0x8ce70a78, 0x27bdffe0, 0x3c040800,
+0x248409d0, 0xafbf0018, 0xafa00010, 0xe000060,
+0xafa00014, 0xe00017b, 0x2021, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x24020001, 0x8f836810,
+0x821004, 0x21027, 0x621824, 0x3e00008,
+0xaf836810, 0x27bdffd8, 0xafbf0024, 0x1080002e,
+0xafb00020, 0x8f825cec, 0xafa20018, 0x8f825cec,
+0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000,
+0xaf825cec, 0x8e020000, 0x18400016, 0x0,
+0x3c020800, 0x94420a74, 0x8fa3001c, 0x221c0,
+0xac830004, 0x8fa2001c, 0x3c010800, 0xe000201,
+0xac220a74, 0x10400005, 0x0, 0x8e020000,
+0x24420001, 0xa0001df, 0xae020000, 0x3c020800,
+0x8c420a70, 0x21c02, 0x321c0, 0xa0001c5,
+0xafa2001c, 0xe000201, 0x0, 0x1040001f,
+0x0, 0x8e020000, 0x8fa3001c, 0x24420001,
+0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74,
+0xa0001df, 0xae020000, 0x3c100800, 0x26100a78,
+0x8e020000, 0x18400028, 0x0, 0xe000201,
+0x0, 0x14400024, 0x0, 0x8e020000,
+0x3c030800, 0x8c630a70, 0x2442ffff, 0xafa3001c,
+0x18400006, 0xae020000, 0x31402, 0x221c0,
+0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e,
+0x2442ff00, 0x2c420300, 0x1440000b, 0x24024000,
+0x3c040800, 0x248409dc, 0xafa00010, 0xafa00014,
+0x8fa6001c, 0x24050008, 0xe000060, 0x3821,
+0xa0001df, 0x0, 0xaf825cf8, 0x3c020800,
+0x8c420a40, 0x8fa3001c, 0x24420001, 0xaf835cf8,
+0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020,
+0x3e00008, 0x27bd0028, 0x27bdffe0, 0x3c040800,
+0x248409e8, 0x2821, 0x3021, 0x3821,
+0xafbf0018, 0xafa00010, 0xe000060, 0xafa00014,
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f82680c,
+0x8f85680c, 0x21827, 0x3182b, 0x31823,
+0x431024, 0x441021, 0xa2282b, 0x10a00006,
+0x0, 0x401821, 0x8f82680c, 0x43102b,
+0x1440fffd, 0x0, 0x3e00008, 0x0,
+0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40,
+0x64102b, 0x54400002, 0x831023, 0x641023,
+0x2c420008, 0x3e00008, 0x38420001, 0x27bdffe0,
+0x802821, 0x3c040800, 0x24840a00, 0x3021,
+0x3821, 0xafbf0018, 0xafa00010, 0xe000060,
+0xafa00014, 0xa000216, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x0, 0x27bdffe0,
+0x3c1cc000, 0xafbf0018, 0xe00004c, 0xaf80680c,
+0x3c040800, 0x24840a10, 0x3802821, 0x3021,
+0x3821, 0xafa00010, 0xe000060, 0xafa00014,
+0x2402ffff, 0xaf825404, 0x3c0200aa, 0xe000234,
+0xaf825434, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0x0, 0x0, 0x0, 0x27bdffe8,
+0xafb00010, 0x24100001, 0xafbf0014, 0x3c01c003,
+0xac200000, 0x8f826810, 0x30422000, 0x10400003,
+0x0, 0xe000246, 0x0, 0xa00023a,
+0xaf905428, 0x8fbf0014, 0x8fb00010, 0x3e00008,
+0x27bd0018, 0x27bdfff8, 0x8f845d0c, 0x3c0200ff,
+0x3c030800, 0x8c630a50, 0x3442fff8, 0x821024,
+0x1043001e, 0x3c0500ff, 0x34a5fff8, 0x3c06c003,
+0x3c074000, 0x851824, 0x8c620010, 0x3c010800,
+0xac230a50, 0x30420008, 0x10400005, 0x871025,
+0x8cc20000, 0x24420001, 0xacc20000, 0x871025,
+0xaf825d0c, 0x8fa20000, 0x24420001, 0xafa20000,
+0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000,
+0x8fa20000, 0x8f845d0c, 0x3c030800, 0x8c630a50,
+0x851024, 0x1443ffe8, 0x851824, 0x27bd0008,
+0x3e00008, 0x0, 0x0, 0x0 };
+U32 t3FwRodata[(0x60/4) + 1] = {
+0x35373031, 0x726c7341, 0x0,
+0x0, 0x53774576, 0x656e7430, 0x0,
+0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e,
+0x45766e74, 0x0, 0x0, 0x0,
+0x0, 0x66617461, 0x6c457272, 0x0,
+0x0, 0x4d61696e, 0x43707542, 0x0,
+0x0, 0x0 };
+U32 t3FwData[(0x20/4) + 1] = {
+0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0 };
diff --git a/drivers/bcm570x_autoneg.h b/drivers/bcm570x_autoneg.h
new file mode 100644
index 0000000..95fcc07
--- /dev/null
+++ b/drivers/bcm570x_autoneg.h
@@ -0,0 +1,415 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+
+
+#ifndef AUTONEG_H
+#define AUTONEG_H
+
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+#define AN_LINK_TIMER_INTERVAL_US           9000       /* 10ms */
+
+/* TRUE, FALSE */
+#define AN_TRUE                             1
+#define AN_FALSE                            0
+
+
+
+/******************************************************************************/
+/* Main data structure for keeping track of 802.3z auto-negotation state */
+/* variables as shown in Figure 37-6 of the IEEE 802.3z specification. */
+/******************************************************************************/
+
+typedef struct
+{
+    /* Current auto-negotiation state. */
+    unsigned long State;
+    #define AN_STATE_UNKNOWN                        0
+    #define AN_STATE_AN_ENABLE                      1
+    #define AN_STATE_AN_RESTART_INIT                2
+    #define AN_STATE_AN_RESTART                     3
+    #define AN_STATE_DISABLE_LINK_OK                4
+    #define AN_STATE_ABILITY_DETECT_INIT            5
+    #define AN_STATE_ABILITY_DETECT                 6
+    #define AN_STATE_ACK_DETECT_INIT                7
+    #define AN_STATE_ACK_DETECT                     8
+    #define AN_STATE_COMPLETE_ACK_INIT              9
+    #define AN_STATE_COMPLETE_ACK                   10
+    #define AN_STATE_IDLE_DETECT_INIT               11
+    #define AN_STATE_IDLE_DETECT                    12
+    #define AN_STATE_LINK_OK                        13
+    #define AN_STATE_NEXT_PAGE_WAIT_INIT            14
+    #define AN_STATE_NEXT_PAGE_WAIT                 16
+
+    /* Link timer. */
+    unsigned long LinkTime_us;
+
+    /* Current time. */
+    unsigned long CurrentTime_us;
+
+    /* Need these values for consistency check. */
+    unsigned short AbilityMatchCfg;
+
+    /* Ability, idle, and ack match functions. */
+    unsigned long AbilityMatchCnt;
+    char AbilityMatch;
+    char IdleMatch;
+    char AckMatch;
+
+    /* Tx config data */
+    union
+    {
+        /* The TxConfig register is arranged as follows:                      */
+        /*                                                                    */
+        /* MSB                                                           LSB  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        struct
+        {
+#ifdef BIG_ENDIAN_HOST
+            unsigned int D7:1;        /* PS1 */
+            unsigned int D6:1;        /* HD */
+            unsigned int D5:1;        /* FD */
+            unsigned int D4:1;
+            unsigned int D3:1;
+            unsigned int D2:1;
+            unsigned int D1:1;
+            unsigned int D0:1;
+            unsigned int D15:1;       /* NP */
+            unsigned int D14:1;       /* ACK */
+            unsigned int D13:1;       /* RF2 */
+            unsigned int D12:1;       /* RF1 */
+            unsigned int D11:1;
+            unsigned int D10:1;
+            unsigned int D9:1;
+            unsigned int D8:1;        /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+            unsigned int D8:1;        /* PS2 */
+            unsigned int D9:1;
+            unsigned int D10:1;
+            unsigned int D11:1;
+            unsigned int D12:1;       /* RF1 */
+            unsigned int D13:1;       /* RF2 */
+            unsigned int D14:1;       /* ACK */
+            unsigned int D15:1;       /* NP */
+            unsigned int D0:1;
+            unsigned int D1:1;
+            unsigned int D2:1;
+            unsigned int D3:1;
+            unsigned int D4:1;
+            unsigned int D5:1;        /* FD */
+            unsigned int D6:1;        /* HD */
+            unsigned int D7:1;        /* PS1 */
+#endif
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define D8_PS2                      bits.D8
+        #define D12_RF1                     bits.D12
+        #define D13_RF2                     bits.D13
+        #define D14_ACK                     bits.D14
+        #define D15_NP                      bits.D15
+        #define D5_FD                       bits.D5
+        #define D6_HD                       bits.D6
+        #define D7_PS1                      bits.D7
+    } TxConfig;
+
+    /* Rx config data */
+    union
+    {
+        /* The RxConfig register is arranged as follows:                      */
+        /*                                                                    */
+        /* MSB                                                           LSB  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        struct
+        {
+#ifdef BIG_ENDIAN_HOST
+	    unsigned int D7:1;        /* PS1 */
+            unsigned int D6:1;        /* HD */
+	    unsigned int D5:1;        /* FD */
+            unsigned int D4:1;
+            unsigned int D3:1;
+            unsigned int D2:1;
+            unsigned int D1:1;
+            unsigned int D0:1;
+  	    unsigned int D15:1;       /* NP */
+            unsigned int D14:1;       /* ACK */
+            unsigned int D13:1;       /* RF2 */
+            unsigned int D12:1;       /* RF1 */
+            unsigned int D11:1;
+            unsigned int D10:1;
+            unsigned int D9:1;
+            unsigned int D8:1;        /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+            unsigned int D8:1;        /* PS2 */
+            unsigned int D9:1;
+            unsigned int D10:1;
+            unsigned int D11:1;
+            unsigned int D12:1;       /* RF1 */
+            unsigned int D13:1;       /* RF2 */
+            unsigned int D14:1;       /* ACK */
+            unsigned int D15:1;       /* NP */
+            unsigned int D0:1;
+            unsigned int D1:1;
+            unsigned int D2:1;
+            unsigned int D3:1;
+            unsigned int D4:1;
+            unsigned int D5:1;        /* FD */
+            unsigned int D6:1;        /* HD */
+            unsigned int D7:1;        /* PS1 */
+#endif
+        } bits;
+
+        unsigned short AsUSHORT;
+    } RxConfig;
+
+    #define AN_CONFIG_NP                            0x0080
+    #define AN_CONFIG_ACK                           0x0040
+    #define AN_CONFIG_RF2                           0x0020
+    #define AN_CONFIG_RF1                           0x0010
+    #define AN_CONFIG_PS2                           0x0001
+    #define AN_CONFIG_PS1                           0x8000
+    #define AN_CONFIG_HD                            0x4000
+    #define AN_CONFIG_FD                            0x2000
+
+
+    /* Management registers. */
+
+    /* Control register. */
+    union
+    {
+        struct
+        {
+            unsigned int an_enable:1;
+            unsigned int loopback:1;
+            unsigned int reset:1;
+            unsigned int restart_an:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_an_enable                Mr0.bits.an_enable
+        #define mr_loopback                 Mr0.bits.loopback
+        #define mr_main_reset               Mr0.bits.reset
+        #define mr_restart_an               Mr0.bits.restart_an
+    } Mr0;
+
+    /* Status register. */
+    union
+    {
+        struct
+        {
+            unsigned int an_complete:1;
+            unsigned int link_ok:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_an_complete              Mr1.bits.an_complete
+        #define mr_link_ok                  Mr1.bits.link_ok
+    } Mr1;
+
+    /* Advertisement register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_4:5;
+            unsigned int full_duplex:1;
+            unsigned int half_duplex:1;
+            unsigned int sym_pause:1;
+            unsigned int asym_pause:1;
+            unsigned int reserved_11:3;
+            unsigned int remote_fault1:1;
+            unsigned int remote_fault2:1;
+            unsigned int reserved_14:1;
+            unsigned int next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_adv_full_duplex          Mr4.bits.full_duplex
+        #define mr_adv_half_duplex          Mr4.bits.half_duplex
+        #define mr_adv_sym_pause            Mr4.bits.sym_pause
+        #define mr_adv_asym_pause           Mr4.bits.asym_pause
+        #define mr_adv_remote_fault1        Mr4.bits.remote_fault1
+        #define mr_adv_remote_fault2        Mr4.bits.remote_fault2
+        #define mr_adv_next_page            Mr4.bits.next_page
+    } Mr4;
+
+    /* Link partner advertisement register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_4:5;
+            unsigned int lp_full_duplex:1;
+            unsigned int lp_half_duplex:1;
+            unsigned int lp_sym_pause:1;
+            unsigned int lp_asym_pause:1;
+            unsigned int reserved_11:3;
+            unsigned int lp_remote_fault1:1;
+            unsigned int lp_remote_fault2:1;
+            unsigned int lp_ack:1;
+            unsigned int lp_next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_lp_adv_full_duplex       Mr5.bits.lp_full_duplex
+        #define mr_lp_adv_half_duplex       Mr5.bits.lp_half_duplex
+        #define mr_lp_adv_sym_pause         Mr5.bits.lp_sym_pause
+        #define mr_lp_adv_asym_pause        Mr5.bits.lp_asym_pause
+        #define mr_lp_adv_remote_fault1     Mr5.bits.lp_remote_fault1
+        #define mr_lp_adv_remote_fault2     Mr5.bits.lp_remote_fault2
+        #define mr_lp_adv_next_page         Mr5.bits.lp_next_page
+    } Mr5;
+
+    /* Auto-negotiation expansion register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_0:1;
+            unsigned int page_received:1;
+            unsigned int next_pageable:1;
+            unsigned int reserved_15:13;
+        } bits;
+
+        unsigned short AsUSHORT;
+    } Mr6;
+
+    /* Auto-negotiation next page transmit register. */
+    union
+    {
+        struct
+        {
+            unsigned int code_field:11;
+            unsigned int toggle:1;
+            unsigned int ack2:1;
+            unsigned int message_page:1;
+            unsigned int reserved_14:1;
+            unsigned int next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_np_tx                    Mr7.AsUSHORT
+    } Mr7;
+
+    /* Auto-negotiation link partner ability register. */
+    union
+    {
+        struct
+        {
+            unsigned int code_field:11;
+            unsigned int toggle:1;
+            unsigned int ack2:1;
+            unsigned int message_page:1;
+            unsigned int ack:1;
+            unsigned int next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_lp_np_rx                 Mr8.AsUSHORT
+    } Mr8;
+
+    /* Extended status register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_11:12;
+            unsigned int base1000_t_hd:1;
+            unsigned int base1000_t_fd:1;
+            unsigned int base1000_x_hd:1;
+            unsigned int base1000_x_fd:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+    } Mr15;
+
+    /* Miscellaneous state variables. */
+    union
+    {
+        struct
+        {
+            unsigned int toggle_tx:1;
+            unsigned int toggle_rx:1;
+            unsigned int np_rx:1;
+            unsigned int page_rx:1;
+            unsigned int np_loaded:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_toggle_tx                MrMisc.bits.toggle_tx
+        #define mr_toggle_rx                MrMisc.bits.toggle_rx
+        #define mr_np_rx                    MrMisc.bits.np_rx
+        #define mr_page_rx                  MrMisc.bits.page_rx
+        #define mr_np_loaded                MrMisc.bits.np_loaded
+    } MrMisc;
+
+
+    /* Implement specifics */
+
+    /* Pointer to the operating system specific data structure. */
+    void *pContext;
+} AN_STATE_INFO, *PAN_STATE_INFO;
+
+
+
+/******************************************************************************/
+/* Return code of Autoneg8023z. */
+/******************************************************************************/
+
+typedef enum
+{
+    AUTONEG_STATUS_OK               = 0,
+    AUTONEG_STATUS_DONE             = 1,
+    AUTONEG_STATUS_TIMER_ENABLED    = 2,
+    AUTONEG_STATUS_FAILED           = 0xfffffff
+} AUTONEG_STATUS, *PAUTONEG_STATUS;
+
+
+
+/******************************************************************************/
+/* Function prototypes. */
+/******************************************************************************/
+
+AUTONEG_STATUS Autoneg8023z(PAN_STATE_INFO pAnInfo);
+void AutonegInit(PAN_STATE_INFO pAnInfo);
+
+
+
+/******************************************************************************/
+/* The following functions are defined in the os-dependent module. */
+/******************************************************************************/
+
+void MM_AnTxConfig(PAN_STATE_INFO pAnInfo);
+void MM_AnTxIdle(PAN_STATE_INFO pAnInfo);
+char MM_AnRxConfig(PAN_STATE_INFO pAnInfo, unsigned short *pRxConfig);
+
+
+
+#endif /* AUTONEG_H */
+
diff --git a/drivers/bcm570x_debug.h b/drivers/bcm570x_debug.h
new file mode 100644
index 0000000..0a688cf
--- /dev/null
+++ b/drivers/bcm570x_debug.h
@@ -0,0 +1,111 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#ifdef VXWORKS
+#include <vxWorks.h>
+#endif
+
+/******************************************************************************/
+/* Debug macros                                                               */
+/******************************************************************************/
+
+/* Code path for controlling output debug messages. */
+/* Define your code path here. */
+#define CP_INIT                     0x010000
+#define CP_SEND                     0x020000
+#define CP_RCV                      0x040000
+#define CP_INT                      0x080000
+#define CP_UINIT                    0x100000
+#define CP_RESET                    0x200000
+
+#define CP_ALL                      (CP_INIT | CP_SEND | CP_RCV | CP_INT | \
+                                    CP_RESET | CP_UINIT)
+
+#define CP_MASK                     0xffff0000
+
+
+/* Debug message levels. */
+#define LV_VERBOSE                  0x03
+#define LV_INFORM                   0x02
+#define LV_WARN                     0x01
+#define LV_FATAL                    0x00
+
+#define LV_MASK                     0xffff
+
+
+/* Code path and messsage level combined.  These are the first argument of */
+/* the DbgMessage macro. */
+#define INIT_V                      (CP_INIT | LV_VERBOSE)
+#define INIT_I                      (CP_INIT | LV_INFORM)
+#define INIT_W                      (CP_INIT | LV_WARN)
+#define SEND_V                      (CP_SEND | LV_VERBOSE)
+#define SEND_I                      (CP_SEND | LV_INFORM)
+#define SEND_W                      (CP_SEND | LV_WARN)
+#define RCV_V                       (CP_RCV | LV_VERBOSE)
+#define RCV_I                       (CP_RCV | LV_INFORM)
+#define RCV_W                       (CP_RCV | LV_WARN)
+#define INT_V                       (CP_INT | LV_VERBOSE)
+#define INT_I                       (CP_INT | LV_INFORM)
+#define INT_W                       (CP_INT | LV_WARN)
+#define UINIT_V                     (CP_UINIT | LV_VERBOSE)
+#define UINIT_I                     (CP_UINIT | LV_INFORM)
+#define UINIT_W                     (CP_UINIT | LV_WARN)
+#define RESET_V                     (CP_RESET | LV_VERBOSE)
+#define RESET_I                     (CP_RESET | LV_INFORM)
+#define RESET_W                     (CP_RESET | LV_WARN)
+#define CPALL_V                     (CP_ALL | LV_VERBOSE)
+#define CPALL_I                     (CP_ALL | LV_INFORM)
+#define CPALL_W                     (CP_ALL | LV_WARN)
+
+
+/* All code path message levels. */
+#define FATAL                       (CP_ALL | LV_FATAL)
+#define WARN                        (CP_ALL | LV_WARN)
+#define INFORM                      (CP_ALL | LV_INFORM)
+#define VERBOSE                     (CP_ALL | LV_VERBOSE)
+
+
+/* These constants control the message output. */
+/* Set your debug message output level and code path here. */
+#ifndef DBG_MSG_CP
+#define DBG_MSG_CP                  CP_ALL      /* Where to output messages. */
+#endif
+
+#ifndef DBG_MSG_LV
+#define DBG_MSG_LV                  LV_VERBOSE  /* Level of message output. */
+#endif
+
+/* DbgMessage macro. */
+#if DBG
+#define DbgMessage(CNTRL, MESSAGE)  \
+    if((CNTRL & DBG_MSG_CP) && ((CNTRL & LV_MASK) <= DBG_MSG_LV)) \
+        printf MESSAGE
+#define DbgBreak()                 DbgBreakPoint()
+#undef STATIC
+#define STATIC
+#else
+#define DbgMessage(CNTRL, MESSAGE)
+#define DbgBreak()
+#undef STATIC
+#define STATIC static
+#endif /* DBG */
+
+
+
+#endif /* DEBUG_H */
+
diff --git a/drivers/bcm570x_lm.h b/drivers/bcm570x_lm.h
new file mode 100644
index 0000000..79073a8
--- /dev/null
+++ b/drivers/bcm570x_lm.h
@@ -0,0 +1,469 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef LM_H
+#define LM_H
+
+#include "bcm570x_queue.h"
+#include "bcm570x_bits.h"
+
+
+
+/******************************************************************************/
+/* Basic types. */
+/******************************************************************************/
+
+typedef char           LM_CHAR,    *PLM_CHAR;
+typedef unsigned int   LM_UINT,    *PLM_UINT;
+typedef unsigned char  LM_UINT8,   *PLM_UINT8;
+typedef unsigned short LM_UINT16,  *PLM_UINT16;
+typedef unsigned int   LM_UINT32,  *PLM_UINT32;
+typedef unsigned int   LM_COUNTER, *PLM_COUNTER;
+typedef void           LM_VOID,    *PLM_VOID;
+typedef char           LM_BOOL,    *PLM_BOOL;
+
+/* 64bit value. */
+typedef struct {
+#ifdef BIG_ENDIAN_HOST
+    LM_UINT32 High;
+    LM_UINT32 Low;
+#else /* BIG_ENDIAN_HOST */
+    LM_UINT32 Low;
+    LM_UINT32 High;
+#endif /* !BIG_ENDIAN_HOST */
+} LM_UINT64, *PLM_UINT64;
+
+typedef LM_UINT64 LM_PHYSICAL_ADDRESS, *PLM_PHYSICAL_ADDRESS;
+
+/* void LM_INC_PHYSICAL_ADDRESS(PLM_PHYSICAL_ADDRESS pAddr,LM_UINT32 IncSize) */
+#define LM_INC_PHYSICAL_ADDRESS(pAddr, IncSize)             \
+    {                                                       \
+        LM_UINT32 OrgLow;                                   \
+                                                            \
+        OrgLow = (pAddr)->Low;                              \
+        (pAddr)->Low += IncSize;                            \
+        if((pAddr)->Low < OrgLow) {                         \
+            (pAddr)->High++; /* Wrap around. */             \
+        }                                                   \
+    }
+
+
+#ifndef NULL
+#define NULL                ((void *) 0)
+#endif /* NULL */
+
+#ifndef OFFSETOF
+#define OFFSETOF(_s, _m)    (MM_UINT_PTR(&(((_s *) 0)->_m)))
+#endif /* OFFSETOF */
+
+
+
+/******************************************************************************/
+/* Simple macros. */
+/******************************************************************************/
+
+#define IS_ETH_BROADCAST(_pEthAddr)                                         \
+    (((unsigned char *) (_pEthAddr))[0] == ((unsigned char) 0xff))
+
+#define IS_ETH_MULTICAST(_pEthAddr)                                         \
+    (((unsigned char *) (_pEthAddr))[0] & ((unsigned char) 0x01))
+
+#define IS_ETH_ADDRESS_EQUAL(_pEtherAddr1, _pEtherAddr2)                    \
+    ((((unsigned char *) (_pEtherAddr1))[0] ==                              \
+    ((unsigned char *) (_pEtherAddr2))[0]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[1] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[1]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[2] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[2]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[3] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[3]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[4] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[4]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[5] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[5]))
+
+#define COPY_ETH_ADDRESS(_Src, _Dst)                                        \
+    ((unsigned char *) (_Dst))[0] = ((unsigned char *) (_Src))[0];          \
+    ((unsigned char *) (_Dst))[1] = ((unsigned char *) (_Src))[1];          \
+    ((unsigned char *) (_Dst))[2] = ((unsigned char *) (_Src))[2];          \
+    ((unsigned char *) (_Dst))[3] = ((unsigned char *) (_Src))[3];          \
+    ((unsigned char *) (_Dst))[4] = ((unsigned char *) (_Src))[4];          \
+    ((unsigned char *) (_Dst))[5] = ((unsigned char *) (_Src))[5];
+
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+#define ETHERNET_ADDRESS_SIZE           6
+#define ETHERNET_PACKET_HEADER_SIZE     14
+#define MIN_ETHERNET_PACKET_SIZE        64      /* with 4 byte crc. */
+#define MAX_ETHERNET_PACKET_SIZE        1518    /* with 4 byte crc. */
+#define MIN_ETHERNET_PACKET_SIZE_NO_CRC 60
+#define MAX_ETHERNET_PACKET_SIZE_NO_CRC 1514
+#define MAX_ETHERNET_PACKET_BUFFER_SIZE 1536    /* A nice even number. */
+
+#ifndef LM_MAX_MC_TABLE_SIZE
+#define LM_MAX_MC_TABLE_SIZE            32
+#endif /* LM_MAX_MC_TABLE_SIZE */
+#define LM_MC_ENTRY_SIZE                (ETHERNET_ADDRESS_SIZE+1)
+#define LM_MC_INSTANCE_COUNT_INDEX      (LM_MC_ENTRY_SIZE-1)
+
+
+/* Receive filter masks. */
+#define LM_ACCEPT_UNICAST               0x0001
+#define LM_ACCEPT_MULTICAST             0x0002
+#define LM_ACCEPT_ALL_MULTICAST         0x0004
+#define LM_ACCEPT_BROADCAST             0x0008
+#define LM_ACCEPT_ERROR_PACKET          0x0010
+
+#define LM_PROMISCUOUS_MODE             0x10000
+
+
+
+/******************************************************************************/
+/* PCI registers. */
+/******************************************************************************/
+
+#define PCI_VENDOR_ID_REG               0x00
+#define PCI_DEVICE_ID_REG               0x02
+
+#define PCI_COMMAND_REG                 0x04
+#define PCI_IO_SPACE_ENABLE             0x0001
+#define PCI_MEM_SPACE_ENABLE            0x0002
+#define PCI_BUSMASTER_ENABLE            0x0004
+#define PCI_MEMORY_WRITE_INVALIDATE     0x0010
+#define PCI_PARITY_ERROR_ENABLE         0x0040
+#define PCI_SYSTEM_ERROR_ENABLE         0x0100
+#define PCI_FAST_BACK_TO_BACK_ENABLE    0x0200
+
+#define PCI_STATUS_REG                  0x06
+#define PCI_REV_ID_REG                  0x08
+
+#define PCI_CACHE_LINE_SIZE_REG         0x0c
+
+#define PCI_IO_BASE_ADDR_REG            0x10
+#define PCI_IO_BASE_ADDR_MASK           0xfffffff0
+
+#define PCI_MEM_BASE_ADDR_LOW           0x10
+#define PCI_MEM_BASE_ADDR_HIGH          0x14
+
+#define PCI_SUBSYSTEM_VENDOR_ID_REG     0x2c
+#define PCI_SUBSYSTEM_ID_REG            0x2e
+#define PCI_INT_LINE_REG                0x3c
+
+#define PCIX_CAP_REG                    0x40
+#define PCIX_ENABLE_RELAXED_ORDERING    BIT_17
+
+/******************************************************************************/
+/* Fragment structure. */
+/******************************************************************************/
+
+typedef struct {
+    LM_UINT32 FragSize;
+    LM_PHYSICAL_ADDRESS FragBuf;
+} LM_FRAG, *PLM_FRAG;
+
+typedef struct {
+    /* FragCount is initialized for the caller to the maximum array size, on */
+    /* return FragCount is the number of the actual fragments in the array. */
+    LM_UINT32 FragCount;
+
+    /* Total buffer size. */
+    LM_UINT32 TotalSize;
+
+    /* Fragment array buffer. */
+    LM_FRAG Fragments[1];
+} LM_FRAG_LIST, *PLM_FRAG_LIST;
+
+#define DECLARE_FRAG_LIST_BUFFER_TYPE(_FRAG_LIST_TYPE_NAME, _MAX_FRAG_COUNT) \
+    typedef struct {                                                         \
+        LM_FRAG_LIST FragList;                                               \
+        LM_FRAG FragListBuffer[_MAX_FRAG_COUNT-1];                           \
+    } _FRAG_LIST_TYPE_NAME, *P##_FRAG_LIST_TYPE_NAME
+
+
+
+/******************************************************************************/
+/* Status codes. */
+/******************************************************************************/
+
+#define LM_STATUS_SUCCESS                                       0
+#define LM_STATUS_FAILURE                                       1
+
+#define LM_STATUS_INTERRUPT_ACTIVE                              2
+#define LM_STATUS_INTERRUPT_NOT_ACTIVE                          3
+
+#define LM_STATUS_LINK_ACTIVE                                   4
+#define LM_STATUS_LINK_DOWN                                     5
+#define LM_STATUS_LINK_SETTING_MISMATCH                         6
+
+#define LM_STATUS_TOO_MANY_FRAGMENTS                            7
+#define LM_STATUS_TRANSMIT_ABORTED                              8
+#define LM_STATUS_TRANSMIT_ERROR                                9
+#define LM_STATUS_RECEIVE_ABORTED                               10
+#define LM_STATUS_RECEIVE_ERROR                                 11
+#define LM_STATUS_INVALID_PACKET_SIZE                           12
+#define LM_STATUS_OUT_OF_MAP_REGISTERS                          13
+#define LM_STATUS_UNKNOWN_ADAPTER                               14
+
+typedef LM_UINT LM_STATUS, *PLM_STATUS;
+
+
+
+/******************************************************************************/
+/* Requested media type. */
+/******************************************************************************/
+
+#define LM_REQUESTED_MEDIA_TYPE_AUTO                            0
+#define LM_REQUESTED_MEDIA_TYPE_BNC                             1
+#define LM_REQUESTED_MEDIA_TYPE_UTP_AUTO                        2
+#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS                      3
+#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX          4
+#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS                     5
+#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX         6
+#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS                    7
+#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX        8
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS                   9
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX       10
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS                  11
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX      12
+#define LM_REQUESTED_MEDIA_TYPE_MAC_LOOPBACK                    0xfffe
+#define LM_REQUESTED_MEDIA_TYPE_PHY_LOOPBACK                    0xffff
+
+typedef LM_UINT32 LM_REQUESTED_MEDIA_TYPE, *PLM_REQUESTED_MEDIA_TYPE;
+
+
+
+/******************************************************************************/
+/* Media type. */
+/******************************************************************************/
+
+#define LM_MEDIA_TYPE_UNKNOWN                                   -1
+#define LM_MEDIA_TYPE_AUTO                                      0
+#define LM_MEDIA_TYPE_UTP                                       1
+#define LM_MEDIA_TYPE_BNC                                       2
+#define LM_MEDIA_TYPE_AUI                                       3
+#define LM_MEDIA_TYPE_FIBER                                     4
+
+typedef LM_UINT32 LM_MEDIA_TYPE, *PLM_MEDIA_TYPE;
+
+
+
+/******************************************************************************/
+/* Line speed. */
+/******************************************************************************/
+
+#define LM_LINE_SPEED_UNKNOWN                                   0
+#define LM_LINE_SPEED_10MBPS                                    1
+#define LM_LINE_SPEED_100MBPS                                   2
+#define LM_LINE_SPEED_1000MBPS                                  3
+
+typedef LM_UINT32 LM_LINE_SPEED, *PLM_LINE_SPEED;
+
+
+
+/******************************************************************************/
+/* Duplex mode. */
+/******************************************************************************/
+
+#define LM_DUPLEX_MODE_UNKNOWN                                  0
+#define LM_DUPLEX_MODE_HALF                                     1
+#define LM_DUPLEX_MODE_FULL                                     2
+
+typedef LM_UINT32 LM_DUPLEX_MODE, *PLM_DUPLEX_MODE;
+
+
+
+/******************************************************************************/
+/* Power state. */
+/******************************************************************************/
+
+#define LM_POWER_STATE_D0       0
+#define LM_POWER_STATE_D1       1
+#define LM_POWER_STATE_D2       2
+#define LM_POWER_STATE_D3       3
+
+typedef LM_UINT32 LM_POWER_STATE, *PLM_POWER_STATE;
+
+
+
+/******************************************************************************/
+/* Task offloading. */
+/******************************************************************************/
+
+#define LM_TASK_OFFLOAD_NONE                    0x0000
+#define LM_TASK_OFFLOAD_TX_IP_CHECKSUM          0x0001
+#define LM_TASK_OFFLOAD_RX_IP_CHECKSUM          0x0002
+#define LM_TASK_OFFLOAD_TX_TCP_CHECKSUM         0x0004
+#define LM_TASK_OFFLOAD_RX_TCP_CHECKSUM         0x0008
+#define LM_TASK_OFFLOAD_TX_UDP_CHECKSUM         0x0010
+#define LM_TASK_OFFLOAD_RX_UDP_CHECKSUM         0x0020
+#define LM_TASK_OFFLOAD_TCP_SEGMENTATION        0x0040
+
+typedef LM_UINT32 LM_TASK_OFFLOAD, *PLM_TASK_OFFLOAD;
+
+
+
+/******************************************************************************/
+/* Flow control. */
+/******************************************************************************/
+
+#define LM_FLOW_CONTROL_NONE                    0x00
+#define LM_FLOW_CONTROL_RECEIVE_PAUSE           0x01
+#define LM_FLOW_CONTROL_TRANSMIT_PAUSE          0x02
+#define LM_FLOW_CONTROL_RX_TX_PAUSE (LM_FLOW_CONTROL_RECEIVE_PAUSE | \
+    LM_FLOW_CONTROL_TRANSMIT_PAUSE)
+
+/* This value can be or-ed with RECEIVE_PAUSE and TRANSMIT_PAUSE.  If the */
+/* auto-negotiation is disabled and the RECEIVE_PAUSE and TRANSMIT_PAUSE */
+/* bits are set, then flow control is enabled regardless of link partner's */
+/* flow control capability. */
+#define LM_FLOW_CONTROL_AUTO_PAUSE              0x80000000
+
+typedef LM_UINT32 LM_FLOW_CONTROL, *PLM_FLOW_CONTROL;
+
+
+
+/******************************************************************************/
+/* Wake up mode. */
+/******************************************************************************/
+
+#define LM_WAKE_UP_MODE_NONE                    0
+#define LM_WAKE_UP_MODE_MAGIC_PACKET            1
+#define LM_WAKE_UP_MODE_NWUF                    2
+#define LM_WAKE_UP_MODE_LINK_CHANGE             4
+
+typedef LM_UINT32 LM_WAKE_UP_MODE, *PLM_WAKE_UP_MODE;
+
+
+
+/******************************************************************************/
+/* Counters. */
+/******************************************************************************/
+
+#define LM_COUNTER_FRAMES_XMITTED_OK                            0
+#define LM_COUNTER_FRAMES_RECEIVED_OK                           1
+#define LM_COUNTER_ERRORED_TRANSMIT_COUNT                       2
+#define LM_COUNTER_ERRORED_RECEIVE_COUNT                        3
+#define LM_COUNTER_RCV_CRC_ERROR                                4
+#define LM_COUNTER_ALIGNMENT_ERROR                              5
+#define LM_COUNTER_SINGLE_COLLISION_FRAMES                      6
+#define LM_COUNTER_MULTIPLE_COLLISION_FRAMES                    7
+#define LM_COUNTER_FRAMES_DEFERRED                              8
+#define LM_COUNTER_MAX_COLLISIONS                               9
+#define LM_COUNTER_RCV_OVERRUN                                  10
+#define LM_COUNTER_XMIT_UNDERRUN                                11
+#define LM_COUNTER_UNICAST_FRAMES_XMIT                          12
+#define LM_COUNTER_MULTICAST_FRAMES_XMIT                        13
+#define LM_COUNTER_BROADCAST_FRAMES_XMIT                        14
+#define LM_COUNTER_UNICAST_FRAMES_RCV                           15
+#define LM_COUNTER_MULTICAST_FRAMES_RCV                         16
+#define LM_COUNTER_BROADCAST_FRAMES_RCV                         17
+
+typedef LM_UINT32 LM_COUNTER_TYPE, *PLM_COUNTER_TYPE;
+
+
+
+/******************************************************************************/
+/* Forward definition. */
+/******************************************************************************/
+
+typedef struct _LM_DEVICE_BLOCK *PLM_DEVICE_BLOCK;
+typedef struct _LM_PACKET *PLM_PACKET;
+
+
+
+/******************************************************************************/
+/* Function prototypes. */
+/******************************************************************************/
+
+LM_STATUS LM_GetAdapterInfo(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_InitializeAdapter(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_ResetAdapter(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_DisableInterrupt(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_EnableInterrupt(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS LM_ServiceInterrupts(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask);
+LM_STATUS LM_Halt(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_MulticastAdd(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
+LM_STATUS LM_MulticastDel(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
+LM_STATUS LM_MulticastClear(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetMacAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress);
+LM_STATUS LM_LoopbackAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pAddress);
+
+LM_UINT32 LM_GetCrcCounter(PLM_DEVICE_BLOCK pDevice);
+
+LM_WAKE_UP_MODE LM_PMCapabilities(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_NwufAdd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
+    LM_UINT8 *pByteMask, LM_UINT8 *pPattern);
+LM_STATUS LM_NwufRemove(PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
+    LM_UINT8 *pByteMask, LM_UINT8 *pPattern);
+LM_STATUS LM_SetPowerState(PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel);
+
+LM_VOID LM_ReadPhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
+    PLM_UINT32 pData32);
+LM_VOID LM_WritePhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
+    LM_UINT32 Data32);
+
+LM_STATUS LM_ControlLoopBack(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Control);
+LM_STATUS LM_SetupPhy(PLM_DEVICE_BLOCK pDevice);
+int LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDuration);
+
+
+
+/******************************************************************************/
+/* These are the OS specific functions called by LMAC. */
+/******************************************************************************/
+
+LM_STATUS MM_ReadConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+    LM_UINT16 *pValue16);
+LM_STATUS MM_WriteConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+    LM_UINT16 Value16);
+LM_STATUS MM_ReadConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+    LM_UINT32 *pValue32);
+LM_STATUS MM_WriteConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+    LM_UINT32 Value32);
+LM_STATUS MM_MapMemBase(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_MapIoBase(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_StartTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_CompleteTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
+    PLM_VOID *pMemoryBlockVirt);
+LM_STATUS MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
+    PLM_VOID *pMemoryBlockVirt, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy,
+    LM_BOOL Cached);
+LM_STATUS MM_GetConfig(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status);
+LM_STATUS MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_CoalesceTxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS LM_MbufWorkAround(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetLinkSpeed(PLM_DEVICE_BLOCK pDevice,
+			  LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+
+#if INCLUDE_5703_A0_FIX
+LM_STATUS LM_Load5703DmaWFirmware(PLM_DEVICE_BLOCK pDevice);
+#endif
+
+
+#endif /* LM_H */
+
diff --git a/drivers/bcm570x_mm.h b/drivers/bcm570x_mm.h
new file mode 100644
index 0000000..badd0d2
--- /dev/null
+++ b/drivers/bcm570x_mm.h
@@ -0,0 +1,160 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef MM_H
+#define MM_H
+
+#define __raw_readl readl
+#define __raw_writel writel
+
+#define BIG_ENDIAN_HOST 1
+#define readl(addr) (*(volatile unsigned int*)(addr))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+/* Define memory barrier function here if needed */
+#define wmb()
+#define membar()
+#include <common.h>
+#include <asm/types.h>
+#include "bcm570x_lm.h"
+#include "bcm570x_queue.h"
+#include "tigon3.h"
+#include <pci.h>
+
+#define FALSE 0
+#define TRUE  1
+#define ERROR -1
+
+#if DBG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+extern int MM_Packet_Desc_Size;
+
+#define MM_PACKET_DESC_SIZE MM_Packet_Desc_Size
+
+DECLARE_QUEUE_TYPE(UM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT+1);
+
+#define MAX_MEM 16
+
+/* Synch */
+typedef int mutex_t;
+typedef int spinlock_t;
+
+/* Embedded device control */
+typedef struct _UM_DEVICE_BLOCK {
+	LM_DEVICE_BLOCK lm_dev;
+        pci_dev_t pdev;
+	char *name;
+	void *mem_list[MAX_MEM];
+	dma_addr_t dma_list[MAX_MEM];
+	int mem_size_list[MAX_MEM];
+	int mem_list_num;
+        int mtu;
+        int index;
+	int opened;
+	int delayed_link_ind; /* Delay link status during initial load */
+	int adapter_just_inited; /* the first few seconds after init. */
+	int spurious_int;            /* new -- unsupported */
+	int timer_interval;
+	int adaptive_expiry;
+	int crc_counter_expiry;         /* new -- unsupported */
+	int poll_tib_expiry;         /* new -- unsupported */
+        int tx_full;
+	int tx_queued;
+	int line_speed;		/* in Mbps, 0 if link is down */
+	UM_RX_PACKET_Q rx_out_of_buf_q;
+	int rx_out_of_buf;
+	int rx_low_buf_thresh; /* changed to rx_buf_repl_thresh */
+	int rx_buf_repl_panic_thresh;
+	int rx_buf_align;            /* new -- unsupported */
+	int do_global_lock;
+        mutex_t global_lock;
+        mutex_t undi_lock;
+	long undi_flags;
+	volatile int interrupt;
+	int tasklet_pending;
+	int tasklet_busy;	     /* new -- unsupported */
+        int rx_pkt;
+        int tx_pkt;
+#ifdef NICE_SUPPORT   /* unsupported, this is a linux ioctl */
+	void (*nice_rx)(void*, void* );
+	void* nice_ctx;
+#endif /* NICE_SUPPORT */
+	int rx_adaptive_coalesce;
+	unsigned int rx_last_cnt;
+	unsigned int tx_last_cnt;
+	unsigned int rx_curr_coalesce_frames;
+	unsigned int rx_curr_coalesce_ticks;
+	unsigned int tx_curr_coalesce_frames;  /* new -- unsupported */
+#if TIGON3_DEBUG          /* new -- unsupported */
+        uint tx_zc_count;
+        uint tx_chksum_count;
+        uint tx_himem_count;
+        uint rx_good_chksum_count;
+#endif
+        unsigned int rx_bad_chksum_count;   /* new -- unsupported */
+        unsigned int rx_misc_errors;        /* new -- unsupported */
+} UM_DEVICE_BLOCK, *PUM_DEVICE_BLOCK;
+
+
+/* Physical/PCI DMA address */
+typedef union {
+        dma_addr_t dma_map;
+} dma_map_t;
+
+/* Packet */
+typedef struct
+_UM_PACKET {
+    LM_PACKET lm_packet;
+    void* skbuff;      /* Address of packet buffer */
+} UM_PACKET, *PUM_PACKET;
+
+#define MM_ACQUIRE_UNDI_LOCK(_pDevice)
+#define MM_RELEASE_UNDI_LOCK(_pDevice)
+#define MM_ACQUIRE_INT_LOCK(_pDevice)
+#define MM_RELEASE_INT_LOCK(_pDevice)
+#define MM_UINT_PTR(_ptr)   ((unsigned long) (_ptr))
+
+/* Macro for setting 64bit address struct */
+#define set_64bit_addr(paddr, low, high) \
+        (paddr)->Low = low;             \
+        (paddr)->High = high;
+
+/* Assume that PCI controller's view of host memory is same as host */
+
+#define MEM_TO_PCI_PHYS(addr) (addr)
+
+extern void MM_SetAddr (LM_PHYSICAL_ADDRESS *paddr, dma_addr_t addr);
+extern void MM_SetT3Addr(T3_64BIT_HOST_ADDR *paddr, dma_addr_t addr);
+extern void MM_MapTxDma (PLM_DEVICE_BLOCK pDevice,
+			 struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR *paddr,
+			 LM_UINT32 *len, int frag);
+extern void MM_MapRxDma ( PLM_DEVICE_BLOCK pDevice,
+			  struct _LM_PACKET *pPacket,
+			  T3_64BIT_HOST_ADDR *paddr);
+
+
+/* BSP needs to provide sysUsecDelay and sysSerialPrintString */
+extern void sysSerialPrintString (char *s);
+#define MM_Wait(usec) udelay(usec)
+
+/* Define memory barrier function here if needed */
+#define wmb()
+
+#if 0
+#define cpu_to_le32(val) LONGSWAP(val)
+#endif
+#endif /* MM_H */
diff --git a/drivers/bcm570x_queue.h b/drivers/bcm570x_queue.h
new file mode 100644
index 0000000..bc32ad7
--- /dev/null
+++ b/drivers/bcm570x_queue.h
@@ -0,0 +1,399 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* Queue functions.                                                           */
+/*    void          QQ_InitQueue(PQQ_CONTAINER pQueue)                        */
+/*    char          QQ_Full(PQQ_CONTAINER pQueue)                             */
+/*    char          QQ_Empty(PQQ_CONTAINER pQueue)                            */
+/*    unsigned int QQ_GetSize(PQQ_CONTAINER pQueue)                          */
+/*    unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue)                      */
+/*    char          QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)       */
+/*    char          QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)       */
+/*    PQQ_ENTRY     QQ_PopHead(PQQ_CONTAINER pQueue)                          */
+/*    PQQ_ENTRY     QQ_PopTail(PQQ_CONTAINER pQueue)                          */
+/*    PQQ_ENTRY     QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx)       */
+/*    PQQ_ENTRY     QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx)       */
+/*                                                                            */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef BCM_QUEUE_H
+#define BCM_QUEUE_H
+#ifndef EMBEDDED
+#define EMBEDDED 1
+#endif
+
+/******************************************************************************/
+/* Queue definitions. */
+/******************************************************************************/
+
+/* Entry for queueing. */
+typedef void *PQQ_ENTRY;
+
+/* Linux Atomic Ops support */
+typedef struct { int counter; } atomic_t;
+
+
+/*
+ * This combination of `inline' and `extern' has almost the effect of a
+ * macro.  The way to use it is to put a function definition in a header
+ * file with these keywords, and put another copy of the definition
+ * (lacking `inline' and `extern') in a library file.  The definition in
+ * the header file will cause most calls to the function to be inlined.
+ * If any uses of the function remain, they will refer to the single copy
+ * in the library.
+ */
+extern __inline void
+atomic_set(atomic_t* entry, int val)
+{
+    entry->counter = val;
+}
+extern __inline int
+atomic_read(atomic_t* entry)
+{
+    return entry->counter;
+}
+extern __inline void
+atomic_inc(atomic_t* entry)
+{
+    if(entry)
+	entry->counter++;
+}
+
+extern __inline void
+atomic_dec(atomic_t* entry)
+{
+    if(entry)
+	entry->counter--;
+}
+
+extern __inline void
+atomic_sub(int a, atomic_t* entry)
+{
+    if(entry)
+	entry->counter -= a;
+}
+extern __inline void
+atomic_add(int a, atomic_t* entry)
+{
+    if(entry)
+	entry->counter += a;
+}
+
+
+/* Queue header -- base type. */
+typedef struct {
+    unsigned int Head;
+    unsigned int Tail;
+    unsigned int Size;
+    atomic_t EntryCnt;
+    PQQ_ENTRY Array[1];
+} QQ_CONTAINER, *PQQ_CONTAINER;
+
+
+/* Declare queue type macro. */
+#define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE)            \
+                                                                \
+    typedef struct {                                            \
+        QQ_CONTAINER Container;                                 \
+        PQQ_ENTRY EntryBuffer[_QUEUE_SIZE];                     \
+    } _QUEUE_TYPE, *P##_QUEUE_TYPE
+
+
+
+/******************************************************************************/
+/* Compilation switches. */
+/******************************************************************************/
+
+#if DBG
+#undef QQ_NO_OVERFLOW_CHECK
+#undef QQ_NO_UNDERFLOW_CHECK
+#endif /* DBG */
+
+#ifdef QQ_USE_MACROS
+/* notdone */
+#else
+
+#ifdef QQ_NO_INLINE
+#define __inline
+#endif /* QQ_NO_INLINE */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline void
+QQ_InitQueue(
+PQQ_CONTAINER pQueue,
+unsigned int QueueSize) {
+    pQueue->Head = 0;
+    pQueue->Tail = 0;
+    pQueue->Size = QueueSize+1;
+    atomic_set(&pQueue->EntryCnt, 0);
+} /* QQ_InitQueue */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_Full(
+PQQ_CONTAINER pQueue) {
+    unsigned int NewHead;
+
+    NewHead = (pQueue->Head + 1) % pQueue->Size;
+
+    return(NewHead == pQueue->Tail);
+} /* QQ_Full */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_Empty(
+PQQ_CONTAINER pQueue) {
+    return(pQueue->Head == pQueue->Tail);
+} /* QQ_Empty */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline unsigned int
+QQ_GetSize(
+PQQ_CONTAINER pQueue) {
+    return pQueue->Size;
+} /* QQ_GetSize */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline unsigned int
+QQ_GetEntryCnt(
+PQQ_CONTAINER pQueue) {
+    return atomic_read(&pQueue->EntryCnt);
+} /* QQ_GetEntryCnt */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    TRUE entry was added successfully.                                      */
+/*    FALSE queue is full.                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_PushHead(
+PQQ_CONTAINER pQueue,
+PQQ_ENTRY pEntry) {
+    unsigned int Head;
+
+    Head = (pQueue->Head + 1) % pQueue->Size;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+    if(Head == pQueue->Tail) {
+        return 0;
+    } /* if */
+#endif /* QQ_NO_OVERFLOW_CHECK */
+
+    pQueue->Array[pQueue->Head] = pEntry;
+    wmb();
+    pQueue->Head = Head;
+    atomic_inc(&pQueue->EntryCnt);
+
+    return -1;
+} /* QQ_PushHead */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    TRUE entry was added successfully.                                      */
+/*    FALSE queue is full.                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_PushTail(
+PQQ_CONTAINER pQueue,
+PQQ_ENTRY pEntry) {
+    unsigned int Tail;
+
+    Tail = pQueue->Tail;
+    if(Tail == 0) {
+        Tail = pQueue->Size;
+    } /* if */
+    Tail--;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+    if(Tail == pQueue->Head) {
+        return 0;
+    } /* if */
+#endif /* QQ_NO_OVERFLOW_CHECK */
+
+    pQueue->Array[Tail] = pEntry;
+    wmb();
+    pQueue->Tail = Tail;
+    atomic_inc(&pQueue->EntryCnt);
+
+    return -1;
+} /* QQ_PushTail */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_PopHead(
+PQQ_CONTAINER pQueue) {
+    unsigned int Head;
+    PQQ_ENTRY Entry;
+
+    Head = pQueue->Head;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+    if(Head == pQueue->Tail) {
+        return (PQQ_ENTRY) 0;
+    } /* if */
+#endif /* QQ_NO_UNDERFLOW_CHECK */
+
+    if(Head == 0) {
+        Head = pQueue->Size;
+    } /* if */
+    Head--;
+
+    Entry = pQueue->Array[Head];
+#ifdef EMBEDDED
+    membar();
+#else
+    mb();
+#endif
+    pQueue->Head = Head;
+    atomic_dec(&pQueue->EntryCnt);
+
+    return Entry;
+} /* QQ_PopHead */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_PopTail(
+PQQ_CONTAINER pQueue) {
+    unsigned int Tail;
+    PQQ_ENTRY Entry;
+
+    Tail = pQueue->Tail;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+    if(Tail == pQueue->Head) {
+        return (PQQ_ENTRY) 0;
+    } /* if */
+#endif /* QQ_NO_UNDERFLOW_CHECK */
+
+    Entry = pQueue->Array[Tail];
+#ifdef EMBEDDED
+    membar();
+#else
+    mb();
+#endif
+    pQueue->Tail = (Tail + 1) % pQueue->Size;
+    atomic_dec(&pQueue->EntryCnt);
+
+    return Entry;
+} /* QQ_PopTail */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_GetHead(
+    PQQ_CONTAINER pQueue,
+    unsigned int Idx)
+{
+    if(Idx >= atomic_read(&pQueue->EntryCnt))
+    {
+        return (PQQ_ENTRY) 0;
+    }
+
+    if(pQueue->Head > Idx)
+    {
+        Idx = pQueue->Head - Idx;
+    }
+    else
+    {
+        Idx = pQueue->Size - (Idx - pQueue->Head);
+    }
+    Idx--;
+
+    return pQueue->Array[Idx];
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_GetTail(
+    PQQ_CONTAINER pQueue,
+    unsigned int Idx)
+{
+    if(Idx >= atomic_read(&pQueue->EntryCnt))
+    {
+        return (PQQ_ENTRY) 0;
+    }
+
+    Idx += pQueue->Tail;
+    if(Idx >= pQueue->Size)
+    {
+        Idx = Idx - pQueue->Size;
+    }
+
+    return pQueue->Array[Idx];
+}
+
+#endif /* QQ_USE_MACROS */
+
+
+
+#endif /* QUEUE_H */
diff --git a/drivers/cfb_console.c b/drivers/cfb_console.c
new file mode 100644
index 0000000..ee2fa9c
--- /dev/null
+++ b/drivers/cfb_console.c
@@ -0,0 +1,912 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * cfb_console.c
+ *
+ * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
+ *
+ * At the moment only the 8x16 font is tested and the font fore- and
+ * background color is limited to black/white/gray colors. The Linux
+ * logo can be placed in the upper left corner and additional board
+ * information strings (that normaly goes to serial port) can be drawed.
+ *
+ * The console driver can use the standard PC keyboard interface (i8042)
+ * for character input. Character output goes to a memory mapped video
+ * framebuffer with little or big-endian organisation.
+ * With environment setting 'console=serial' the console i/o can be
+ * forced to serial port.
+
+ The driver uses graphic specific defines/parameters/functions:
+
+ (for SMI LynxE graphic chip)
+
+ CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
+ VIDEO_FB_LITTLE_ENDIAN  - framebuffer organisation default: big endian
+ VIDEO_HW_RECTFILL       - graphic driver supports hardware rectangle fill
+ VIDEO_HW_BITBLT         - graphic driver supports hardware bit blt
+
+ Console Parameters are set by graphic drivers global struct:
+
+ VIDEO_VISIBLE_COLS          - x resolution
+ VIDEO_VISIBLE_ROWS          - y resolution
+ VIDEO_PIXEL_SIZE            - storage size in byte per pixel
+ VIDEO_DATA_FORMAT           - graphical data format GDF
+ VIDEO_FB_ADRS               - start of video memory
+
+ CONFIG_I8042_KBD            - AT Keyboard driver for i8042
+ VIDEO_KBD_INIT_FCT          - init function for keyboard
+ VIDEO_TSTC_FCT              - keyboard_tstc function
+ VIDEO_GETC_FCT              - keyboard_getc function
+
+ CONFIG_CONSOLE_CURSOR       - on/off drawing cursor is done with delay
+                               loop in VIDEO_TSTC_FCT (i8042)
+ CFG_CONSOLE_BLINK_COUNT     - value for delay loop - blink rate
+ CONFIG_CONSOLE_TIME         - display time/date in upper right corner,
+                               needs CFG_CMD_DATE and CONFIG_CONSOLE_CURSOR
+ CONFIG_VIDEO_LOGO           - display Linux Logo in upper left corner
+ CONFIG_CONSOLE_EXTRA_INFO   - display additional board information strings
+                               that normaly goes to serial port. This define
+                               requires a board specific function:
+                               video_drawstring (VIDEO_INFO_X,
+                                                 VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
+                                                 info);
+                               that fills a info buffer at i=row.
+                               s.a: board/eltec/bab7xx.
+CONFIG_VGA_AS_SINGLE_DEVICE  - If set the framebuffer device will be initialised
+                               as an output only device. The Keyboard driver
+                               will not be set-up. This may be used, if you
+                               have none or more than one Keyboard devices
+                               (USB Keyboard, AT Keyboard).
+
+CONFIG_VIDEO_SW_CURSOR:      - Draws a cursor after the last character. No
+                               blinking is provided. Uses the macros CURSOR_SET
+                               and CURSOR_OFF.
+CONFIG_VIDEO_HW_CURSOR:      - Uses the hardware cursor capability of the
+                               graphic chip. Uses the macro CURSOR_SET.
+                               ATTENTION: If booting an OS, the display driver
+                               must disable the hardware register of the graphic
+                               chip. Otherwise a blinking field is displayed
+*/
+
+#include <common.h>
+
+#ifdef CONFIG_CFB_CONSOLE
+
+/*****************************************************************************/
+/* Console device defines with SMI graphic                                   */
+/* Any other graphic must change this section                                */
+/*****************************************************************************/
+
+#ifdef  CONFIG_VIDEO_SMI_LYNXEM
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the CT69000 driver                                            */
+/*****************************************************************************/
+#ifdef  CONFIG_VIDEO_CT69000
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc             */
+/*****************************************************************************/
+#include <video_fb.h>
+
+/*****************************************************************************/
+/* some Macros                                                               */
+/*****************************************************************************/
+#define VIDEO_VISIBLE_COLS      (pGD->winSizeX)
+#define VIDEO_VISIBLE_ROWS      (pGD->winSizeY)
+#define VIDEO_PIXEL_SIZE        (pGD->gdfBytesPP)
+#define VIDEO_DATA_FORMAT       (pGD->gdfIndex)
+#define VIDEO_FB_ADRS           (pGD->frameAdrs)
+
+/*****************************************************************************/
+/* Console device defines with i8042 keyboard controller                     */
+/* Any other keyboard controller must change this section                    */
+/*****************************************************************************/
+
+#ifdef  CONFIG_I8042_KBD
+#include <i8042.h>
+
+#define VIDEO_KBD_INIT_FCT      i8042_kbd_init()
+#define VIDEO_TSTC_FCT          i8042_tstc
+#define VIDEO_GETC_FCT          i8042_getc
+#endif
+
+/*****************************************************************************/
+/* Console device                                                            */
+/*****************************************************************************/
+
+#include <version.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <video_font.h>
+#ifdef CFG_CMD_DATE
+#include <rtc.h>
+
+#endif
+
+/*****************************************************************************/
+/* Cursor definition:                                                        */
+/* CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/i8042.c) to    */
+/*                         let the cursor blink. Uses the macros CURSOR_OFF  */
+/*                         and CURSOR_ON.                                    */
+/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No       */
+/*                         blinking is provided. Uses the macros CURSOR_SET  */
+/*                         and CURSOR_OFF.                                   */
+/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the        */
+/*                         graphic chip. Uses the macro CURSOR_SET.          */
+/*                         ATTENTION: If booting an OS, the display driver   */
+/*                         must disable the hardware register of the graphic */
+/*                         chip. Otherwise a blinking field is displayed     */
+/*****************************************************************************/
+#if !defined(CONFIG_CONSOLE_CURSOR) && \
+    !defined(CONFIG_VIDEO_SW_CURSOR) && \
+    !defined(CONFIG_VIDEO_HW_CURSOR)
+/* no Cursor defined */
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET
+#endif
+
+#ifdef  CONFIG_CONSOLE_CURSOR
+#ifdef  CURSOR_ON
+#error  only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+void    console_cursor (int state);
+#define CURSOR_ON  console_cursor(1);
+#define CURSOR_OFF console_cursor(0);
+#define CURSOR_SET
+#ifndef CONFIG_I8042_KBD
+#warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c
+#endif
+#else
+#ifdef  CONFIG_CONSOLE_TIME
+#error  CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
+#endif
+#endif /* CONFIG_CONSOLE_CURSOR */
+
+#ifdef  CONFIG_VIDEO_SW_CURSOR
+#ifdef  CURSOR_ON
+#error  only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
+                                 console_row * VIDEO_FONT_HEIGHT, ' ');
+#define CURSOR_SET video_set_cursor();
+#endif /* CONFIG_VIDEO_SW_CURSOR */
+
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+#ifdef  CURSOR_ON
+#error  only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
+                  (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT);
+#endif  /* CONFIG_VIDEO_HW_CURSOR */
+
+#ifdef  CONFIG_VIDEO_LOGO
+#define LINUX_LOGO_WIDTH        80
+#define LINUX_LOGO_HEIGHT       80
+#define LINUX_LOGO_COLORS       214
+#define LINUX_LOGO_LUT_OFFSET   0x20
+#define __initdata
+#include <linux_logo.h>
+#define VIDEO_LOGO_WIDTH        LINUX_LOGO_WIDTH
+#define VIDEO_LOGO_HEIGHT       LINUX_LOGO_HEIGHT
+
+#define VIDEO_INFO_X            (VIDEO_LOGO_WIDTH)
+#define VIDEO_INFO_Y            (VIDEO_FONT_HEIGHT/2)
+#else
+#define VIDEO_LOGO_WIDTH        0
+#define VIDEO_LOGO_HEIGHT       0
+#endif
+
+#define VIDEO_COLS              VIDEO_VISIBLE_COLS
+#define VIDEO_ROWS              VIDEO_VISIBLE_ROWS
+#define VIDEO_SIZE              (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_PIX_BLOCKS        (VIDEO_SIZE >> 2)
+#define VIDEO_LINE_LEN          (VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_BURST_LEN         (VIDEO_COLS/8)
+
+#ifdef  CONFIG_VIDEO_LOGO
+#define CONSOLE_ROWS            ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT)
+#else
+#define CONSOLE_ROWS            (VIDEO_ROWS / VIDEO_FONT_HEIGHT)
+#endif
+
+#define CONSOLE_COLS            (VIDEO_COLS / VIDEO_FONT_WIDTH)
+#define CONSOLE_ROW_SIZE        (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
+#define CONSOLE_ROW_FIRST       (video_console_address)
+#define CONSOLE_ROW_SECOND      (video_console_address + CONSOLE_ROW_SIZE)
+#define CONSOLE_ROW_LAST        (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+#define CONSOLE_SIZE            (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
+#define CONSOLE_SCROLL_SIZE     (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+
+/* Macros */
+#ifdef  VIDEO_FB_LITTLE_ENDIAN
+#define SWAP16(x)        ((((x) & 0x00ff) << 8) | ( (x) >> 8))
+#define SWAP32(x)        ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
+                          (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
+#define SHORTSWAP32(x)   ((((x) & 0x000000ff) <<  8) | (((x) & 0x0000ff00) >> 8)|\
+                          (((x) & 0x00ff0000) <<  8) | (((x) & 0xff000000) >> 8) )
+#else
+#define SWAP16(x)        (x)
+#define SWAP32(x)        (x)
+#define SHORTSWAP32(x)   (x)
+#endif
+
+#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
+#define PRINTD(x)         printf(x)
+#else
+#define PRINTD(x)
+#endif
+
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern void video_get_info_str (    /* setup a board string: type, speed, etc. */
+    int line_number,        /* location to place info string beside logo */
+    char *info              /* buffer for info string */
+    );
+
+#endif
+
+/* Locals */
+static GraphicDevice *pGD;	/* Pointer to Graphic array */
+
+static void *video_fb_address;          /* frame buffer address */
+static void *video_console_address;     /* console buffer start address */
+
+static int console_col = 0; /* cursor col */
+static int console_row = 0; /* cursor row */
+
+static u32 eorx, fgx, bgx;  /* color pats */
+
+static const int video_font_draw_table8[] = {
+            0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+            0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
+            0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
+            0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
+
+static const int video_font_draw_table15[] = {
+            0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
+
+static const int video_font_draw_table16[] = {
+            0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
+
+static const int video_font_draw_table24[16][3] = {
+            { 0x00000000, 0x00000000, 0x00000000 },
+            { 0x00000000, 0x00000000, 0x00ffffff },
+            { 0x00000000, 0x0000ffff, 0xff000000 },
+            { 0x00000000, 0x0000ffff, 0xffffffff },
+            { 0x000000ff, 0xffff0000, 0x00000000 },
+            { 0x000000ff, 0xffff0000, 0x00ffffff },
+            { 0x000000ff, 0xffffffff, 0xff000000 },
+            { 0x000000ff, 0xffffffff, 0xffffffff },
+            { 0xffffff00, 0x00000000, 0x00000000 },
+            { 0xffffff00, 0x00000000, 0x00ffffff },
+            { 0xffffff00, 0x0000ffff, 0xff000000 },
+            { 0xffffff00, 0x0000ffff, 0xffffffff },
+            { 0xffffffff, 0xffff0000, 0x00000000 },
+            { 0xffffffff, 0xffff0000, 0x00ffffff },
+            { 0xffffffff, 0xffffffff, 0xff000000 },
+            { 0xffffffff, 0xffffffff, 0xffffffff } };
+
+static const int video_font_draw_table32[16][4] = {
+            { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+            { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
+            { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
+            { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
+            { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
+            { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
+            { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
+            { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
+            { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
+            { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
+            { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
+            { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
+            { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
+            { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
+            { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
+            { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
+
+
+/******************************************************************************/
+
+
+static void video_drawchars (int xx, int yy, unsigned char *s, int count)
+{
+    u8  *cdat, *dest, *dest0;
+    int rows, offset, c;
+
+    offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
+    dest0 = video_fb_address + offset;
+
+    switch (VIDEO_DATA_FORMAT)
+    {
+    case GDF__8BIT_INDEX:
+    case GDF__8BIT_332RGB:
+        while (count--)
+        {
+        c = *s ;
+        cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+        for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+        {
+            u8 bits = *cdat++;
+            ((u32 *)dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
+            ((u32 *)dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
+        }
+        dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+        s++;
+        }
+        break;
+
+    case GDF_15BIT_555RGB:
+        while (count--)
+        {
+        c = *s ;
+        cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+        for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+        {
+            u8 bits = *cdat++;
+            ((u32 *)dest)[0] = SHORTSWAP32((video_font_draw_table15[bits >> 6] & eorx) ^ bgx);
+            ((u32 *)dest)[1] = SHORTSWAP32((video_font_draw_table15[bits >> 4 & 3] & eorx) ^ bgx);
+            ((u32 *)dest)[2] = SHORTSWAP32((video_font_draw_table15[bits >> 2 & 3] & eorx) ^ bgx);
+            ((u32 *)dest)[3] = SHORTSWAP32((video_font_draw_table15[bits & 3] & eorx) ^ bgx);
+            }
+            dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+            s++ ;
+        }
+        break;
+
+    case GDF_16BIT_565RGB:
+        while (count--)
+        {
+        c = *s ;
+        cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+        for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+        {
+            u8 bits = *cdat++;
+            ((u32 *)dest)[0] = SHORTSWAP32((video_font_draw_table16[bits >> 6] & eorx) ^ bgx);
+            ((u32 *)dest)[1] = SHORTSWAP32((video_font_draw_table16[bits >> 4 & 3] & eorx) ^ bgx);
+            ((u32 *)dest)[2] = SHORTSWAP32((video_font_draw_table16[bits >> 2 & 3] & eorx) ^ bgx);
+            ((u32 *)dest)[3] = SHORTSWAP32((video_font_draw_table16[bits & 3] & eorx) ^ bgx);
+        }
+        dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+        s++ ;
+        }
+        break;
+
+    case GDF_32BIT_X888RGB:
+        while (count--)
+        {
+        c = *s ;
+        cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+        for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+        {
+            u8 bits = *cdat++;
+            ((u32 *)dest)[0] = SWAP32((video_font_draw_table32[bits >> 4][0] & eorx) ^ bgx);
+            ((u32 *)dest)[1] = SWAP32((video_font_draw_table32[bits >> 4][1] & eorx) ^ bgx);
+            ((u32 *)dest)[2] = SWAP32((video_font_draw_table32[bits >> 4][2] & eorx) ^ bgx);
+            ((u32 *)dest)[3] = SWAP32((video_font_draw_table32[bits >> 4][3] & eorx) ^ bgx);
+            ((u32 *)dest)[4] = SWAP32((video_font_draw_table32[bits & 15][0] & eorx) ^ bgx);
+            ((u32 *)dest)[5] = SWAP32((video_font_draw_table32[bits & 15][1] & eorx) ^ bgx);
+            ((u32 *)dest)[6] = SWAP32((video_font_draw_table32[bits & 15][2] & eorx) ^ bgx);
+            ((u32 *)dest)[7] = SWAP32((video_font_draw_table32[bits & 15][3] & eorx) ^ bgx);
+        }
+        dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+        s++ ;
+        }
+        break;
+
+    case GDF_24BIT_888RGB:
+        while (count--)
+        {
+        c = *s ;
+        cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+        for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+        {
+            u8 bits = *cdat++;
+            ((u32 *)dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
+            ((u32 *)dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
+            ((u32 *)dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
+            ((u32 *)dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
+            ((u32 *)dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
+            ((u32 *)dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
+        }
+        dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+        s++ ;
+        }
+        break;
+    }
+}
+
+/*****************************************************************************/
+
+static inline void video_drawstring(int xx, int yy, unsigned char *s)
+{
+    video_drawchars (xx, yy, s, strlen(s));
+}
+
+/*****************************************************************************/
+
+static void video_putchar(int xx, int yy, unsigned char c)
+{
+#ifdef CONFIG_VIDEO_LOGO
+    video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1);
+#else
+    video_drawchars (xx, yy, &c, 1);
+#endif
+}
+
+/*****************************************************************************/
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+static void video_set_cursor(void)
+{
+    /* swap drawing colors */
+    eorx = fgx;
+    fgx  = bgx;
+    bgx  = eorx;
+    eorx = fgx ^ bgx;
+    /* draw cursor */
+    video_putchar (console_col * VIDEO_FONT_WIDTH,
+                   console_row * VIDEO_FONT_HEIGHT, ' ');
+    /* restore drawing colors */
+    eorx = fgx;
+    fgx  = bgx;
+    bgx  = eorx;
+    eorx = fgx ^ bgx;
+}
+#endif
+/*****************************************************************************/
+#ifdef CONFIG_CONSOLE_CURSOR
+void console_cursor (int state)
+{
+    static int last_state = 0;
+#ifdef CONFIG_CONSOLE_TIME
+    struct rtc_time tm;
+    char info[16];
+
+    /* time update only if cursor is on (faster scroll) */
+    if (state)
+    {
+    rtc_get (&tm);
+
+    sprintf(info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min, tm.tm_sec);
+    video_drawstring(VIDEO_VISIBLE_COLS-10*VIDEO_FONT_WIDTH,
+             VIDEO_INFO_Y, info);
+
+    sprintf(info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon, tm.tm_year);
+    video_drawstring(VIDEO_VISIBLE_COLS-10*VIDEO_FONT_WIDTH,
+             VIDEO_INFO_Y+1*VIDEO_FONT_HEIGHT, info);
+    }
+#endif
+
+    if (state && (last_state != state))
+    {
+        video_set_cursor();
+    }
+
+    if (!state && (last_state != state))
+    {
+        /* clear cursor */
+        video_putchar (console_col * VIDEO_FONT_WIDTH,
+                       console_row * VIDEO_FONT_HEIGHT, ' ');
+    }
+
+    last_state = state;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_RECTFILL
+static void memsetl (int *p, int c, int v)
+{
+    while (c--)
+        *(p++) = v;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_BITBLT
+static void memcpyl (int *d, int *s, int c)
+{
+    while (c--)
+        *(d++) = *(s++);
+}
+#endif
+
+/*****************************************************************************/
+
+static void console_scrollup (void)
+{
+    /* copy up rows ignoring the first one */
+
+#ifdef VIDEO_HW_BITBLT
+    video_hw_bitblt (
+    VIDEO_PIXEL_SIZE,     /* bytes per pixel */
+    0,                    /* source pos x */
+    VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */
+    0,                    /* dest pos x */
+    VIDEO_LOGO_HEIGHT,    /* dest pos y */
+    VIDEO_VISIBLE_COLS,   /* frame width */
+    VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT /* frame height */
+    );
+#else
+    memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE >> 2);
+#endif
+
+    /* clear the last one */
+#ifdef VIDEO_HW_RECTFILL
+    video_hw_rectfill (
+    VIDEO_PIXEL_SIZE,     /* bytes per pixel */
+    0,                    /* dest pos x */
+    VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT,  /* dest pos y */
+    VIDEO_VISIBLE_COLS,   /* frame width */
+    VIDEO_FONT_HEIGHT,    /* frame height */
+    CONSOLE_BG_COL          /* fill color */
+    );
+#else
+    memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
+#endif
+}
+
+/*****************************************************************************/
+
+static void console_back (void)
+{
+    CURSOR_OFF
+    console_col--;
+
+    if (console_col < 0)
+    {
+        console_col = CONSOLE_COLS - 1;
+        console_row--;
+        if (console_row < 0)
+        console_row = 0;
+    }
+    video_putchar (console_col * VIDEO_FONT_WIDTH,
+                   console_row * VIDEO_FONT_HEIGHT, ' ');
+}
+
+/*****************************************************************************/
+
+static void console_newline (void)
+{
+    CURSOR_OFF
+    console_row++;
+    console_col = 0;
+
+    /* Check if we need to scroll the terminal */
+    if (console_row >= CONSOLE_ROWS)
+    {
+    /* Scroll everything up */
+    console_scrollup ();
+
+    /* Decrement row number */
+    console_row--;
+    }
+}
+
+/*****************************************************************************/
+
+void video_putc (const char c)
+{
+    switch (c)
+    {
+    case 13: /* ignore */
+        break;
+
+    case '\n': /* next line */
+        console_newline();
+        break;
+
+    case 9:    /* tab 8 */
+        CURSOR_OFF
+        console_col |=  0x0008;
+        console_col &= ~0x0007;
+
+        if (console_col >= CONSOLE_COLS)
+            console_newline();
+        break;
+
+    case 8:    /* backspace */
+        console_back();
+        break;
+
+    default: /* draw the char */
+        video_putchar (console_col * VIDEO_FONT_WIDTH,
+                       console_row * VIDEO_FONT_HEIGHT, c);
+        console_col++ ;
+
+        /* check for newline */
+        if (console_col >= CONSOLE_COLS)
+            console_newline();
+    }
+    CURSOR_SET
+}
+
+
+
+/*****************************************************************************/
+
+void video_puts (const char *s)
+{
+    int count = strlen(s);
+
+    while(count--)
+        video_putc(*s++);
+}
+
+/*****************************************************************************/
+
+#ifdef CONFIG_VIDEO_LOGO
+void logo_plot (void *screen, int width, int x, int y)
+{
+    int skip = (width - LINUX_LOGO_WIDTH) * VIDEO_PIXEL_SIZE,
+        xcount, i,
+        ycount = LINUX_LOGO_HEIGHT;
+    unsigned char
+        *source = linux_logo,
+        *dest   = (unsigned char *) screen + ((y * width * VIDEO_PIXEL_SIZE) + x),
+        r, g, b;
+
+    if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX)
+    {
+        for (i = 0; i < LINUX_LOGO_COLORS; i++)
+        {
+            r = (unsigned char)linux_logo_red  [i];
+            g = (unsigned char)linux_logo_green[i];
+            b = (unsigned char)linux_logo_blue [i];
+            video_set_lut (LINUX_LOGO_LUT_OFFSET + i, r, g, b);
+        }
+    }
+
+    while (ycount--)
+    {
+    xcount = LINUX_LOGO_WIDTH;
+    while (xcount--)
+    {
+        r = (unsigned char)linux_logo_red  [*source - LINUX_LOGO_LUT_OFFSET];
+        g = (unsigned char)linux_logo_green[*source - LINUX_LOGO_LUT_OFFSET];
+        b = (unsigned char)linux_logo_blue [*source - LINUX_LOGO_LUT_OFFSET];
+
+        switch (VIDEO_DATA_FORMAT)
+        {
+        case GDF__8BIT_INDEX:
+            *dest = *source;
+            break;
+        case GDF__8BIT_332RGB:
+            *dest = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);
+            break;
+        case GDF_15BIT_555RGB:
+            *(unsigned short *)dest =
+            SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3)));
+            break;
+        case GDF_16BIT_565RGB:
+            *(unsigned short *)dest =
+            SWAP16((unsigned short)(((r>>3)<<11) | ((g>>2)<<5) | (b>>3)));
+            break;
+        case GDF_32BIT_X888RGB:
+            *(unsigned long  *)dest =
+            SWAP32((unsigned long)((r<<16) | (g<<8) | b));
+            break;
+        case GDF_24BIT_888RGB:
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+            dest[0] = b;
+            dest[1] = g;
+            dest[2] = r;
+#else
+            dest[0] = r;
+            dest[1] = g;
+            dest[2] = b;
+#endif
+            break;
+        }
+        source++;
+        dest += VIDEO_PIXEL_SIZE;
+    }
+    dest += skip;
+    }
+}
+
+
+/*****************************************************************************/
+
+static void *video_logo (void)
+{
+    char info[128];
+
+    logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
+
+    sprintf(info, " %s (%s - %s)", U_BOOT_VERSION, __DATE__, __TIME__);
+    video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, info);
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+    {
+    int i, n = ((VIDEO_LOGO_HEIGHT-VIDEO_FONT_HEIGHT)/VIDEO_FONT_HEIGHT);
+
+    for (i = 1; i < n; i++)
+    {
+        video_get_info_str (i, info);
+        if (*info)
+        video_drawstring (VIDEO_INFO_X,
+                          VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT, info);
+    }
+    }
+#endif
+
+    return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN);
+}
+#endif
+
+
+/*****************************************************************************/
+
+static int video_init(void)
+{
+    unsigned char color8;
+
+    if ((pGD=video_hw_init()) == NULL)
+        return -1;
+
+    video_fb_address = (void*)VIDEO_FB_ADRS;
+#ifdef CONFIG_VIDEO_HW_CURSOR
+    video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
+#endif
+
+    /* Init drawing pats */
+    switch (VIDEO_DATA_FORMAT)
+    {
+    case GDF__8BIT_INDEX:
+        video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+        video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
+        fgx = 0x01010101;
+        bgx = 0x00000000;
+        break;
+    case GDF__8BIT_332RGB:
+        color8 = ((CONSOLE_FG_COL & 0xe0) | ((CONSOLE_FG_COL>>3) & 0x1c) | CONSOLE_FG_COL>>6);
+        fgx = (color8<<24) | (color8<<16) | (color8<<8) | color8;
+        color8 = ((CONSOLE_BG_COL & 0xe0) | ((CONSOLE_BG_COL>>3) & 0x1c) | CONSOLE_BG_COL>>6);
+        bgx = (color8<<24) | (color8<<16) | (color8<<8) | color8;
+        break;
+    case GDF_15BIT_555RGB:
+        fgx = (((CONSOLE_FG_COL>>3)<<26) | ((CONSOLE_FG_COL>>3)<<21) | ((CONSOLE_FG_COL>>3)<<16) |
+           ((CONSOLE_FG_COL>>3)<<10) | ((CONSOLE_FG_COL>>3)<<5)  |  (CONSOLE_FG_COL>>3));
+        bgx = (((CONSOLE_BG_COL>>3)<<26) | ((CONSOLE_BG_COL>>3)<<21) | ((CONSOLE_BG_COL>>3)<<16) |
+           ((CONSOLE_BG_COL>>3)<<10) | ((CONSOLE_BG_COL>>3)<<5)  |  (CONSOLE_BG_COL>>3));
+        break;
+    case GDF_16BIT_565RGB:
+        fgx = (((CONSOLE_FG_COL>>3)<<27) | ((CONSOLE_FG_COL>>2)<<21) | ((CONSOLE_FG_COL>>3)<<16) |
+           ((CONSOLE_FG_COL>>3)<<11) | ((CONSOLE_FG_COL>>2)<<5)  |  (CONSOLE_FG_COL>>3));
+        bgx = (((CONSOLE_BG_COL>>3)<<27) | ((CONSOLE_BG_COL>>2)<<21) | ((CONSOLE_BG_COL>>3)<<16) |
+           ((CONSOLE_BG_COL>>3)<<11) | ((CONSOLE_BG_COL>>2)<<5)  |  (CONSOLE_BG_COL>>3));
+        break;
+    case GDF_32BIT_X888RGB:
+        fgx = (CONSOLE_FG_COL<<16) | (CONSOLE_FG_COL<<8) | CONSOLE_FG_COL;
+        bgx = (CONSOLE_BG_COL<<16) | (CONSOLE_BG_COL<<8) | CONSOLE_BG_COL;
+        break;
+    case GDF_24BIT_888RGB:
+        fgx = (CONSOLE_FG_COL<<24) | (CONSOLE_FG_COL<<16) | (CONSOLE_FG_COL<<8) | CONSOLE_FG_COL;
+        bgx = (CONSOLE_BG_COL<<24) | (CONSOLE_BG_COL<<16) | (CONSOLE_BG_COL<<8) | CONSOLE_BG_COL;
+        break;
+    }
+    eorx = fgx ^ bgx;
+
+#ifdef CONFIG_VIDEO_LOGO
+    /* Plot the logo and get start point of console */
+    PRINTD("Video: Drawing the logo ...\n");
+    video_console_address = video_logo();
+#else
+    video_console_address = video_fb_address;
+#endif
+
+    /* Initialize the console */
+    console_col  = 0;
+    console_row  = 0;
+
+    return 0 ;
+}
+
+
+/*****************************************************************************/
+
+int drv_video_init (void)
+{
+    int skip_dev_init;
+    device_t console_dev;
+    char *penv;
+
+    skip_dev_init = 0;
+
+     /* Force console i/o to serial ? */
+    if ((penv = getenv ("console")) != NULL)
+        if (strcmp (penv, "serial") == 0)
+            return 0;
+
+   /* Init video chip - returns with framebuffer cleared */
+    if (video_init() == -1)
+        skip_dev_init = 1;
+#ifdef CONFIG_VGA_AS_SINGLE_DEVICE
+   /* Devices VGA and Keyboard will be assigned seperately */
+    /* Init vga device */
+    if (!skip_dev_init)
+    {
+        memset (&console_dev, 0, sizeof(console_dev));
+        strcpy(console_dev.name, "vga");
+        console_dev.ext   = DEV_EXT_VIDEO;    /* Video extensions */
+        console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+        console_dev.putc  = video_putc;        /* 'putc' function */
+        console_dev.puts  = video_puts;        /* 'puts' function */
+        console_dev.tstc  = NULL;              /* 'tstc' function */
+        console_dev.getc  = NULL;              /* 'getc' function */
+
+        if (device_register (&console_dev) == 0)
+            return 1;
+    }
+#else
+    PRINTD("KBD: Keyboard init ...\n");
+    if (VIDEO_KBD_INIT_FCT == -1)
+        skip_dev_init = 1;
+
+    /* Init console device */
+    if (!skip_dev_init)
+    {
+        memset (&console_dev, 0, sizeof(console_dev));
+        strcpy(console_dev.name, "console");
+        console_dev.ext   = DEV_EXT_VIDEO;    /* Video extensions */
+        console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+        console_dev.putc  = video_putc;        /* 'putc' function */
+        console_dev.puts  = video_puts;        /* 'puts' function */
+        console_dev.tstc  = VIDEO_TSTC_FCT;    /* 'tstc' function */
+        console_dev.getc  = VIDEO_GETC_FCT;    /* 'getc' function */
+
+        if (device_register (&console_dev) == 0)
+            return 1;
+    }
+#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
+    /* No console dev available */
+    return 0;
+}
+
+#endif /* CONFIG_CFB_CONSOLE */
+
+
+
+
+
+
+
diff --git a/drivers/cs8900.c b/drivers/cs8900.c
new file mode 100644
index 0000000..ecc7c13
--- /dev/null
+++ b/drivers/cs8900.c
@@ -0,0 +1,235 @@
+/*
+ * Cirrus Logic CS8900A Ethernet
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is loaded into SRAM in bootstrap mode, where it waits
+ * for commands on UART1 to read and write memory, jump to code etc.
+ * A design goal for this program is to be entirely independent of the
+ * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
+ * this code in bootstrap mode.  All the board specifics can be handled on
+ * the host.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <command.h>
+#include "cs8900.h"
+#include <net.h>
+
+#ifdef CONFIG_DRIVER_CS8900
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+
+/* packet page register access functions */
+
+#ifdef CS8900_BUS32
+/* we don't need 16 bit initialisation on 32 bit bus */
+#define get_reg_init_bus(x) get_reg((x))
+#else
+static unsigned short get_reg_init_bus(int regno)
+{
+    /* force 16 bit busmode */
+    volatile unsigned char c;
+    c = CS8900_BUS16_0;
+    c = CS8900_BUS16_1;
+    c = CS8900_BUS16_0;
+    c = CS8900_BUS16_1;
+    c = CS8900_BUS16_0;
+
+    CS8900_PPTR = regno;
+    return (unsigned short) CS8900_PDATA;
+}
+#endif
+
+static unsigned short
+get_reg(int regno)
+{
+    CS8900_PPTR = regno;
+    return (unsigned short) CS8900_PDATA;
+}
+
+
+static void put_reg(int regno, unsigned short val)
+{
+    CS8900_PPTR = regno;
+    CS8900_PDATA = val;
+}
+
+static void eth_reset(void)
+{
+    int tmo;
+    unsigned short us;
+
+    /* reset NIC */
+    put_reg(PP_SelfCTL, get_reg(PP_SelfCTL) | PP_SelfCTL_Reset );
+
+    /* wait for 200ms */
+    udelay(200000);
+    /* Wait until the chip is reset */
+
+    tmo = get_timer(0) + 1 * CFG_HZ;
+    while ((((us = get_reg_init_bus(PP_SelfSTAT)) & PP_SelfSTAT_InitD) == 0)
+	   && tmo < get_timer(0))
+      /*NOP*/;
+}
+
+void cs8900_get_enetaddr (uchar *addr)
+{
+    int i;
+    /* verify chip id */
+    if (get_reg_init_bus(PP_ChipID) != 0x630e)
+	return;
+    eth_reset();
+    if ((get_reg(PP_SelfST) & (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
+	      (PP_SelfSTAT_EEPROM|PP_SelfSTAT_EEPROM_OK)) {
+	/* Load the MAC from EEPROM */
+	for (i=0; i<6/2; i++) {
+	    unsigned int Addr;
+	    Addr = get_reg(PP_IA+i*2);
+	    addr[i*2] = Addr & 0xFF;
+	    addr[i*2+1] = Addr >> 8;
+	}
+    }
+}
+
+void eth_halt( void )
+{
+    /* disable transmitter/receiver mode */
+    put_reg(PP_LineCTL, 0);
+
+    /* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
+    get_reg_init_bus(PP_ChipID);
+}
+
+int eth_init( bd_t *bd )
+{
+
+    /* verify chip id */
+    if (get_reg_init_bus(PP_ChipID) != 0x630e)
+    {
+	printf( "CS8900 Ethernet chip not found?!\n" );
+	return 0;
+    }
+
+    eth_reset();
+    /* set the ethernet address */
+    put_reg(PP_IA + 0, bd->bi_enetaddr[0] | (bd->bi_enetaddr[1] << 8));
+    put_reg(PP_IA + 2, bd->bi_enetaddr[2] | (bd->bi_enetaddr[3] << 8));
+    put_reg(PP_IA + 4, bd->bi_enetaddr[4] | (bd->bi_enetaddr[5] << 8));
+
+    /* receive only error free packets addressed to this card */
+    put_reg(PP_RxCTL, PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
+
+    /* do not generate any interrupts on receive operations */
+    put_reg(PP_RxCFG, 0);
+
+    /* do not generate any interrupts on transmit operations */
+    put_reg(PP_TxCFG, 0);
+
+    /* do not generate any interrupts on buffer operations */
+    put_reg(PP_BufCFG, 0);
+
+    /* enable transmitter/receiver mode */
+    put_reg(PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
+
+    return 0;
+}
+
+/* Get a data block via Ethernet */
+extern int eth_rx(void)
+{
+    int i;
+    unsigned short rxlen;
+    unsigned short *addr;
+    unsigned short status;
+
+    status = get_reg(PP_RER);
+
+    if ((status & PP_RER_RxOK) == 0)
+      return 0;
+
+    status = CS8900_RTDATA;       /* stat */
+    rxlen = CS8900_RTDATA;        /* len */
+
+    if(rxlen > PKTSIZE_ALIGN + PKTALIGN)
+      printf("packet too big!\n");
+
+    for(addr = (unsigned short *)NetRxPackets[0], i = rxlen >> 1; i > 0; i-- )
+      *addr++ = CS8900_RTDATA;
+    if(rxlen & 1)
+      *addr++ = CS8900_RTDATA;
+
+    /* Pass the packet up to the protocol layers. */
+    NetReceive(NetRxPackets[0], rxlen);
+
+    return rxlen;
+}
+
+/* Send a data block via Ethernet. */
+extern int eth_send(volatile void *packet, int length)
+{
+    volatile unsigned short *addr;
+    int tmo;
+    unsigned short s;
+
+retry:
+    /* initiate a transmit sequence */
+    CS8900_TxCMD = PP_TxCmd_TxStart_Full;
+    CS8900_TxLEN = length;
+
+    /* Test to see if the chip has allocated memory for the packet */
+    if ((get_reg(PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
+	/* Oops... this should not happen! */
+	printf("cs: unable to send packet; retrying...\n");
+	for (tmo = get_timer(0) + 5 * CFG_HZ; get_timer(0) < tmo; )
+	  /*NOP*/;
+	eth_reset();
+	goto retry;
+    }
+
+    /* Write the contents of the packet */
+    /* assume even number of bytes */
+    for(addr = packet; length > 0; length -= 2 )
+      CS8900_RTDATA = *addr++;
+
+    /* wait for transfer to succeed */
+    tmo = get_timer(0) + 5 * CFG_HZ;
+    while((s = get_reg(PP_TER) & ~0x1F) == 0)
+    {
+	if (get_timer(0) >= tmo)
+	  break;
+    }
+
+      /* nothing */ ;
+    if ((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
+	printf("\ntransmission error %#x\n", s);
+    }
+
+    return 0;
+}
+
+#endif /* COMMANDS & CFG_NET */
+
+#endif /* CONFIG_DRIVER_CS8900 */
diff --git a/drivers/ct69000.c b/drivers/ct69000.c
new file mode 100644
index 0000000..7962f74
--- /dev/null
+++ b/drivers/ct69000.c
@@ -0,0 +1,1484 @@
+/*
+ * (C) Copyright 2002
+ * Denis Peter, MPL AG Switzerland
+ *
+ * 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
+ */
+
+/*
+ * ported from ctfb.c (linux kernel) for the U-Boot
+ *
+ */
+
+/************************************************************************
+  Get Parameters for the video mode:
+  Parameters can be set via the variable "videomode" in the environment.
+  2 diferent ways are possible:
+  "videomode=301"   - 301 is a hexadecimal number describing the VESA
+                      mode. Following modes are implemented:
+
+                      Colors    640x480 800x600 1024x768 1152x864
+                     --------+-----------------------------------
+                      8 bits |  0x301   0x303    0x305    0x161
+                     15 bits |  0x310   0x313    0x316    0x162
+                     16 bits |  0x311   0x314    0x317    0x163
+                     24 bits |  0x312   0x315    0x318      ?
+                     --------+-----------------------------------
+  "videomode=bootargs"
+                   - the parameters are parsed from the bootargs.
+                      The format is "NAME:VALUE,NAME:VALUE" etc.
+                      Ex.:
+                      "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000"
+                      Parameters not included in the list will be taken from
+                      the default mode, which is one of the following:
+                      mode:0  640x480x24
+                      mode:1  800x600x16
+                      mode:2  1024x768x8
+                      mode:3  960x720x24
+                      mode:4  1152x864x16
+                      if "mode" is not provided within the parameter list,
+                      mode:0 is assumed.
+                      Following parameters are supported:
+                      x       xres = visible resolution horizontal
+                      y       yres = visible resolution vertical
+                      pclk    pixelclocks in pico sec
+                      le      left_marging time from sync to picture in pixelclocks
+                      ri      right_marging time from picture to sync in pixelclocks
+                      up      upper_margin time from sync to picture
+                      lo      lower_margin
+                      hs      hsync_len length of horizontal sync
+                      vs      vsync_len length of vertical sync
+                      sync    see FB_SYNC_*
+                      vmode   see FB_VMODE_*
+                      depth   Color depth in bits per pixel
+                      All other parameters in the variable bootargs are ignored.
+                      It is also possible to set the parameters direct in the
+                      variable "videomode", or in another variable i.e.
+                      "myvideo" and setting the variable "videomode=myvideo"..
+****************************************************************************/
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO
+
+#include <pci.h>
+#include <video_fb.h>
+
+#ifdef CONFIG_VIDEO_CT69000
+
+/* debug */
+#undef VGA_DEBUG
+#undef VGA_DUMP_REG
+#ifdef VGA_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/* Macros */
+#ifndef min
+#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
+#endif
+#ifndef max
+#define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b )
+#endif
+#ifdef minmax
+#error "term minmax already used."
+#endif
+#define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) )
+#define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )
+
+/* CT Register Offsets */
+#define CT_AR_O			0x3c0	/* Index and Data write port of the attribute Registers */
+#define CT_GR_O			0x3ce	/* Index port of the Graphic Controller Registers */
+#define CT_SR_O			0x3c4	/* Index port of the Sequencer Controller */
+#define CT_CR_O			0x3d4	/* Index port of the CRT Controller */
+#define CT_XR_O			0x3d6	/* Extended Register index */
+#define CT_MSR_W_O		0x3c2	/* Misc. Output Register (write only) */
+#define CT_LUT_MASK_O		0x3c6	/* Color Palette Mask */
+#define CT_LUT_START_O		0x3c8	/* Color Palette Write Mode Index */
+#define CT_LUT_RGB_O		0x3c9	/* Color Palette Data Port */
+#define CT_STATUS_REG0_O	0x3c2	/* Status Register 0 (read only) */
+#define CT_STATUS_REG1_O	0x3da	/* Input Status Register 1 (read only) */
+
+#define CT_FP_O			0x3d0	/* Index port of the Flat panel Registers */
+#define CT_MR_O			0x3d2	/* Index Port of the Multimedia Extension */
+
+/* defines for the memory mapped registers */
+#define BR00_o		0x400000	/* Source and Destination Span Register */
+#define BR01_o		0x400004	/* Pattern/Source Expansion Background Color & Transparency Key Register */
+#define BR02_o		0x400008	/* Pattern/Source Expansion Foreground Color Register */
+#define BR03_o		0x40000C	/* Monochrome Source Control Register */
+#define BR04_o		0x400010	/* BitBLT Control Register */
+#define BR05_o		0x400014	/* Pattern Address Registe */
+#define BR06_o		0x400018	/* Source Address Register */
+#define BR07_o		0x40001C	/* Destination Address Register */
+#define BR08_o		0x400020	/* Destination Width & Height Register */
+#define BR09_o		0x400024	/* Source Expansion Background Color & Transparency Key Register */
+#define BR0A_o		0x400028	/* Source Expansion Foreground Color Register */
+
+#define CURSOR_SIZE	0x1000	/* in KByte for HW Cursor */
+#define PATTERN_ADR	(pGD->dprBase + CURSOR_SIZE)	/* pattern Memory after Cursor Memory */
+#define PATTERN_SIZE	8*8*4	/* 4 Bytes per Pixel 8 x 8 Pixel */
+#define ACCELMEMORY	(CURSOR_SIZE + PATTERN_SIZE)	/* reserved Memory for BITBlt and hw cursor */
+
+/* Some Mode definitions */
+#define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active  */
+#define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active    */
+#define FB_SYNC_EXT		4	/* external sync                */
+#define FB_SYNC_COMP_HIGH_ACT	8	/* composite sync high active   */
+#define FB_SYNC_BROADCAST	16	/* broadcast video timings      */
+					/* vtotal = 144d/288n/576i => PAL  */
+					/* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN	32	/* sync on green */
+
+#define FB_VMODE_NONINTERLACED  0	/* non interlaced */
+#define FB_VMODE_INTERLACED	1	/* interlaced   */
+#define FB_VMODE_DOUBLE		2	/* double scan */
+#define FB_VMODE_MASK		255
+
+#define FB_VMODE_YWRAP		256	/* ywrap instead of panning     */
+#define FB_VMODE_SMOOTH_XPAN	512	/* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE	512	/* don't update x/yoffset       */
+
+#define text			0
+#define fntwidth		8
+
+/* table for VGA Initialization  */
+typedef struct {
+	const unsigned char reg;
+	const unsigned char val;
+} CT_CFG_TABLE;
+
+/* this table provides some basic initialisations such as Memory Clock etc */
+static CT_CFG_TABLE xreg[] = {
+	{0x09, 0x01},		/* CRT Controller Extensions Enable */
+	{0x0A, 0x02},		/* Frame Buffer Mapping */
+	{0x0B, 0x01},		/* PCI Write Burst support */
+	{0x20, 0x00},		/* BitBLT Configuration */
+	{0x40, 0x03},		/* Memory Access Control */
+	{0x60, 0x00},		/* Video Pin Control */
+	{0x61, 0x00},		/* DPMS Synch control */
+	{0x62, 0x00},		/* GPIO Pin Control */
+	{0x63, 0xBD},		/* GPIO Pin Data */
+	{0x67, 0x00},		/* Pin Tri-State */
+	{0x80, 0x80},		/* Pixel Pipeline Config 0 register */
+	{0xA0, 0x00},		/* Cursor 1 Control Reg */
+	{0xA1, 0x00},		/* Cursor 1 Vertical Extension Reg */
+	{0xA2, 0x00},		/* Cursor 1 Base Address Low */
+	{0xA3, 0x00},		/* Cursor 1 Base Address High */
+	{0xA4, 0x00},		/* Cursor 1 X-Position Low */
+	{0xA5, 0x00},		/* Cursor 1 X-Position High */
+	{0xA6, 0x00},		/* Cursor 1 Y-Position Low */
+	{0xA7, 0x00},		/* Cursor 1 Y-Position High */
+	{0xA8, 0x00},		/* Cursor 2 Control Reg */
+	{0xA9, 0x00},		/* Cursor 2 Vertical Extension Reg */
+	{0xAA, 0x00},		/* Cursor 2 Base Address Low */
+	{0xAB, 0x00},		/* Cursor 2 Base Address High */
+	{0xAC, 0x00},		/* Cursor 2 X-Position Low */
+	{0xAD, 0x00},		/* Cursor 2 X-Position High */
+	{0xAE, 0x00},		/* Cursor 2 Y-Position Low */
+	{0xAF, 0x00},		/* Cursor 2 Y-Position High */
+	{0xC0, 0x7D},		/* Dot Clock 0 VCO M-Divisor */
+	{0xC1, 0x07},		/* Dot Clock 0 VCO N-Divisor */
+	{0xC3, 0x34},		/* Dot Clock 0 Divisor select */
+	{0xC4, 0x55},		/* Dot Clock 1 VCO M-Divisor */
+	{0xC5, 0x09},		/* Dot Clock 1 VCO N-Divisor */
+	{0xC7, 0x24},		/* Dot Clock 1 Divisor select */
+	{0xC8, 0x7D},		/* Dot Clock 2 VCO M-Divisor */
+	{0xC9, 0x07},		/* Dot Clock 2 VCO N-Divisor */
+	{0xCB, 0x34},		/* Dot Clock 2 Divisor select */
+	{0xCC, 0x38},		/* Memory Clock 0 VCO M-Divisor */
+	{0xCD, 0x03},		/* Memory Clock 0 VCO N-Divisor */
+	{0xCE, 0x90},		/* Memory Clock 0 Divisor select */
+	{0xCF, 0x06},		/* Clock Config */
+	{0xD0, 0x0F},		/* Power Down */
+	{0xD1, 0x01},		/* Power Down BitBLT */
+	{0xFF, 0xFF}		/* end of table */
+};
+/* Clock Config:
+ * =============
+ *
+ * PD Registers:
+ * -------------
+ * Bit2 and Bit4..6 are used for the Loop Divisor and Post Divisor.
+ * They are encoded as follows:
+ *
+ * +---+--------------+
+ * | 2 | Loop Divisor |
+ * +---+--------------+
+ * | 1 | 1            |
+ * +---+--------------+
+ * | 0 | 4            |
+ * +---+--------------+
+ * Note: The Memory Clock does not have a Loop Divisor.
+ * +---+---+---+--------------+
+ * | 6 | 5 | 4 | Post Divisor |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 0 | 1            |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 1 | 2            |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 0 | 4            |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 1 | 8            |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 0 | 16           |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 1 | 32           |
+ * +---+---+---+--------------+
+ * | 1 | 1 | X | reserved     |
+ * +---+---+---+--------------+
+ *
+ * All other bits are reserved in these registers.
+ *
+ * Clock VCO M Registers:
+ * ----------------------
+ * These Registers contain the M Value -2.
+ *
+ * Clock VCO N Registers:
+ * ----------------------
+ * These Registers contain the N Value -2.
+ *
+ * Formulas:
+ * ---------
+ * Fvco = (Fref * Loop Divisor * M/N), whereas 100MHz < Fvco < 220MHz
+ * Fout = Fvco / Post Divisor
+ *
+ * Dot Clk0 (default 25MHz):
+ * -------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC0 = (M - 2) = 125 = 0x7D
+ * XRC1 = (N - 2) = 7   = 0x07
+ * XRC3 =                 0x34
+ *
+ * Dot Clk1 (default 28MHz):
+ * -------------------------
+ * Fvco = 14.318 * 87 / 11 = 113.24MHz
+ * Fout = 113.24MHz / 4 = 28.31MHz
+ * Post Divisor = 4
+ * Loop Divisor = 1
+ * XRC4 = (M - 2) = 85 = 0x55
+ * XRC5 = (N - 2) = 9  = 0x09
+ * XRC7 =                0x24
+ *
+ * Dot Clk2 (variable for extended modes set to 25MHz):
+ * ----------------------------------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC8 = (M - 2) = 125 = 0x7D
+ * XRC9 = (N - 2) = 7   = 0x07
+ * XRCB =                 0x34
+ *
+ * Memory Clk for most modes >50MHz:
+ * ----------------------------------
+ * Fvco = 14.318 * 58 / 5 = 166MHz
+ * Fout = 166MHz / 2      = 83MHz
+ * Post Divisor = 2
+ * XRCC = (M - 2) = 57  = 0x38
+ * XRCD = (N - 2) = 3   = 0x03
+ * XRCE =                 0x90
+ *
+ * Note Bit7 enables the clock source from the VCO
+ *
+ */
+
+/******************************************************************
+ * Resolution Struct
+ ******************************************************************/
+struct ctfb_res_modes {
+	int xres;		/* visible resolution           */
+	int yres;
+	/* Timing: All values in pixclocks, except pixclock (of course) */
+	int pixclock;		/* pixel clock in ps (pico seconds) */
+	int left_margin;	/* time from sync to picture    */
+	int right_margin;	/* time from picture to sync    */
+	int upper_margin;	/* time from sync to picture    */
+	int lower_margin;
+	int hsync_len;		/* length of horizontal sync    */
+	int vsync_len;		/* length of vertical sync      */
+	int sync;		/* see FB_SYNC_*                */
+	int vmode;		/* see FB_VMODE_*               */
+};
+
+/******************************************************************
+ * Vesa Mode Struct
+ ******************************************************************/
+struct ctfb_vesa_modes {
+	int vesanr;		/* Vesa number as in LILO (VESA Nr + 0x200} */
+	int resindex;		/* index to resolution struct */
+	int bits_per_pixel;	/* bpp */
+};
+/*******************************************************************
+ * Chips struct
+ *******************************************************************/
+struct ctfb_chips_properties {
+	int device_id;		/* PCI Device ID */
+	unsigned long max_mem;	/* memory for frame buffer */
+	int vld_set;		/* value of VLD if bit2 in clock control is set */
+	int vld_not_set;	/* value of VLD if bit2 in clock control is set */
+	int mn_diff;		/* difference between M/N Value + mn_diff = M/N Register */
+	int mn_min;		/* min value of M/N Value */
+	int mn_max;		/* max value of M/N Value */
+	int vco_min;		/* VCO Min in MHz */
+	int vco_max;		/* VCO Max in MHz */
+};
+
+static const struct ctfb_chips_properties chips[] = {
+	{PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
+	{PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220},	/* NOT TESTED */
+	{0, 0, 0, 0, 0, 0, 0, 0, 0}	/* Terminator */
+};
+
+/*************************************************
+ Video Modes:
+Colours   640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
+--------+--------------------------------------------------------------
+ 4 bits |    ?       ?     0x302      ?        ?        ?         ?
+ 8 bits |  0x300   0x301   0x303    0x305    0x161    0x307     0x31C
+15 bits |    ?     0x310   0x313    0x316    0x162    0x319     0x31D
+16 bits |    ?     0x311   0x314    0x317    0x163    0x31A     0x31E
+24 bits |    ?     0x312   0x315    0x318      ?      0x31B     0x31F
+32 bits |    ?       ?       ?        ?      0x164      ?
+*/
+
+#define RES_MODE_640x480 	0
+#define RES_MODE_800x600 	1
+#define RES_MODE_1024x768 	2
+#define RES_MODE_960_720	3
+#define RES_MODE_1152x864 	4
+#define RES_MODES_COUNT		5
+
+#define VESA_MODES_COUNT 15
+
+static const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
+	{0x301, RES_MODE_640x480, 8},
+	{0x310, RES_MODE_640x480, 15},
+	{0x311, RES_MODE_640x480, 16},
+	{0x312, RES_MODE_640x480, 24},
+	{0x303, RES_MODE_800x600, 8},
+	{0x313, RES_MODE_800x600, 15},
+	{0x314, RES_MODE_800x600, 16},
+	{0x315, RES_MODE_800x600, 24},
+	{0x305, RES_MODE_1024x768, 8},
+	{0x316, RES_MODE_1024x768, 15},
+	{0x317, RES_MODE_1024x768, 16},
+	{0x318, RES_MODE_1024x768, 24},
+	{0x161, RES_MODE_1152x864, 8},
+	{0x162, RES_MODE_1152x864, 15},
+	{0x163, RES_MODE_1152x864, 16}
+};
+
+static const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = {
+	/* x     y pixclk   le  ri  up  lo   hs vs  s  vmode */
+	{640, 480, 39721, 40, 24, 32, 11, 96, 2, 0,
+	 FB_VMODE_NONINTERLACED},
+	{800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED},
+	{1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0,
+	 FB_VMODE_NONINTERLACED},
+	{960, 720, 13100, 160, 40, 32, 8, 80, 4, 0,
+	 FB_VMODE_NONINTERLACED},
+	{1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0,
+	 FB_VMODE_NONINTERLACED}
+};
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+/*******************************************************************************
+*
+* Low Level Routines
+*/
+
+/*******************************************************************************
+*
+* Read CT ISA register
+*/
+#ifdef VGA_DEBUG
+static unsigned char
+ctRead (unsigned short index)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	if (index == CT_AR_O)
+		/* synch the Flip Flop */
+		in8 (pGD->isaBase + CT_STATUS_REG1_O);
+
+	return (in8 (pGD->isaBase + index));
+}
+#endif
+/*******************************************************************************
+*
+* Write CT ISA register
+*/
+static void
+ctWrite (unsigned short index, unsigned char val)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+	out8 ((pGD->isaBase + index), val);
+}
+
+/*******************************************************************************
+*
+* Read CT ISA register indexed
+*/
+static unsigned char
+ctRead_i (unsigned short index, char reg)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	if (index == CT_AR_O)
+		/* synch the Flip Flop */
+		in8 (pGD->isaBase + CT_STATUS_REG1_O);
+	out8 ((pGD->isaBase + index), reg);
+	return (in8 (pGD->isaBase + index + 1));
+}
+
+/*******************************************************************************
+*
+* Write CT ISA register indexed
+*/
+static void
+ctWrite_i (unsigned short index, char reg, char val)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	if (index == CT_AR_O) {
+		/* synch the Flip Flop */
+		in8 (pGD->isaBase + CT_STATUS_REG1_O);
+		out8 ((pGD->isaBase + index), reg);
+		out8 ((pGD->isaBase + index), val);
+	} else {
+		out8 ((pGD->isaBase + index), reg);
+		out8 ((pGD->isaBase + index + 1), val);
+	}
+}
+
+/*******************************************************************************
+*
+* Write a table of CT ISA register
+*/
+static void
+ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab)
+{
+	while (regTab->reg != 0xFF) {
+		ctWrite_i (index, regTab->reg, regTab->val);
+		regTab++;
+	}
+}
+
+/*****************************************************************************/
+static void
+SetArRegs (void)
+{
+	int i, tmp;
+
+	for (i = 0; i < 0x10; i++)
+		ctWrite_i (CT_AR_O, i, i);
+	if (text)
+		tmp = 0x04;
+	else
+		tmp = 0x41;
+
+	ctWrite_i (CT_AR_O, 0x10, tmp);	/* Mode Control Register */
+	ctWrite_i (CT_AR_O, 0x11, 0x00);	/* Overscan Color Register */
+	ctWrite_i (CT_AR_O, 0x12, 0x0f);	/* Memory Plane Enable Register */
+	if (fntwidth == 9)
+		tmp = 0x08;
+	else
+		tmp = 0x00;
+	ctWrite_i (CT_AR_O, 0x13, tmp);	/* Horizontal Pixel Panning */
+	ctWrite_i (CT_AR_O, 0x14, 0x00);	/* Color Select Register    */
+	ctWrite (CT_AR_O, 0x20);	/* enable video             */
+}
+
+/*****************************************************************************/
+static void
+SetGrRegs (void)
+{				/* Set Graphics Mode */
+	int i;
+
+	for (i = 0; i < 0x05; i++)
+		ctWrite_i (CT_GR_O, i, 0);
+	if (text) {
+		ctWrite_i (CT_GR_O, 0x05, 0x10);
+		ctWrite_i (CT_GR_O, 0x06, 0x02);
+	} else {
+		ctWrite_i (CT_GR_O, 0x05, 0x40);
+		ctWrite_i (CT_GR_O, 0x06, 0x05);
+	}
+	ctWrite_i (CT_GR_O, 0x07, 0x0f);
+	ctWrite_i (CT_GR_O, 0x08, 0xff);
+}
+
+/*****************************************************************************/
+static void
+SetSrRegs (void)
+{
+	int tmp = 0;
+
+	ctWrite_i (CT_SR_O, 0x00, 0x00);	/* reset */
+	/*rr( sr, 0x01, tmp );
+	   if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01;
+	   wr( sr, 0x01, tmp );  */
+	if (fntwidth == 8)
+		ctWrite_i (CT_SR_O, 0x01, 0x01);	/* Clocking Mode Register */
+	else
+		ctWrite_i (CT_SR_O, 0x01, 0x00);	/* Clocking Mode Register */
+	ctWrite_i (CT_SR_O, 0x02, 0x0f);	/* Enable CPU wr access to given memory plane */
+	ctWrite_i (CT_SR_O, 0x03, 0x00);	/* Character Map Select Register */
+	if (text)
+		tmp = 0x02;
+	else
+		tmp = 0x0e;
+	ctWrite_i (CT_SR_O, 0x04, tmp);	/* Enable CPU accesses to the rest of the 256KB
+					   total VGA memory beyond the first 64KB and set
+					   fb mapping mode. */
+	ctWrite_i (CT_SR_O, 0x00, 0x03);	/* enable */
+}
+
+/*****************************************************************************/
+static void
+SetBitsPerPixelIntoXrRegs (int bpp)
+{
+	unsigned int n = (bpp >> 3), tmp;	/* only for 15, 8, 16, 24 bpp */
+	static char md[4] = { 0x04, 0x02, 0x05, 0x06 };	/* DisplayColorMode */
+	static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 };	/* mask */
+	static char on[4] = { 0x10, 0x00, 0x10, 0x20 };	/* mask */
+	if (bpp == 15)
+		n = 0;
+	tmp = ctRead_i (CT_XR_O, 0x20);
+	tmp &= off[n];
+	tmp |= on[n];
+	ctWrite_i (CT_XR_O, 0x20, tmp);	/* BitBLT Configuration */
+	ctWrite_i (CT_XR_O, 0x81, md[n]);
+}
+
+/*****************************************************************************/
+static void
+SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel)
+{				/* he -le-   ht|0    hd -ri- hs     -h-      he */
+	unsigned char cr[0x7a];
+	int i, tmp;
+	unsigned int hd, hs, he, ht, hbe;	/* Horizontal.  */
+	unsigned int vd, vs, ve, vt;	/* vertical */
+	unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine;
+	unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay;
+	unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl;
+	unsigned int HorizontalEqualizationPulses;
+	unsigned int HorizontalSerration1Start, HorizontalSerration2Start;
+
+	const int LineCompare = 0x3ff;
+	unsigned int TextScanLines = 1;	/* this is in fact a vertical zoom factor   */
+	unsigned int RAMDAC_BlankPedestalEnable = 0;	/* 1=en-, 0=disable, see XR82 */
+
+	hd = (var->xres) / 8;	/* HDisp.  */
+	hs = (var->xres + var->right_margin) / 8;	/* HsStrt  */
+	he = (var->xres + var->right_margin + var->hsync_len) / 8;	/* HsEnd   */
+	ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;	/* HTotal  */
+	hbe = ht - 1;		/* HBlankEnable todo docu wants ht here, but it does not work */
+	/* ve -up-  vt|0    vd -lo- vs     -v-      ve */
+	vd = var->yres;		/* VDisplay   */
+	vs = var->yres + var->lower_margin;	/* VSyncStart */
+	ve = var->yres + var->lower_margin + var->vsync_len;	/* VSyncEnd */
+	vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;	/* VTotal  */
+	bpp = bits_per_pixel;
+	dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
+	interlaced = var->vmode & FB_VMODE_INTERLACED;
+	bcast = var->sync & FB_SYNC_BROADCAST;
+	CrtHalfLine = bcast ? (hd >> 1) : 0;
+	BlDelayCtrl = bcast ? 1 : 0;
+	CompSyncCharClkDelay = 0;	/* 2 bit */
+	CompSyncPixelClkDelay = 0;	/* 3 bit */
+	if (bcast) {
+		NTSC_PAL_HorizontalPulseWidth = 7;	/*( var->hsync_len >> 1 ) + 1 */
+		HorizontalEqualizationPulses = 0;	/* inverse value */
+		HorizontalSerration1Start = 31;	/* ( ht >> 1 ) */
+		HorizontalSerration2Start = 89;	/* ( ht >> 1 ) */
+	} else {
+		NTSC_PAL_HorizontalPulseWidth = 0;
+		/* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] )
+		 * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */
+		HorizontalEqualizationPulses = 1;	/* inverse value */
+		HorizontalSerration1Start = 0;	/* ( ht >> 1 ) */
+		HorizontalSerration2Start = 0;	/* ( ht >> 1 ) */
+	}
+
+	if (bpp == 15)
+		bpp = 16;
+	wd = var->xres * bpp / 64;	/* double words per line */
+	if (interlaced) {	/* we divide all vertical timings, exept vd */
+		vs >>= 1;
+		ve >>= 1;
+		vt >>= 1;
+	}
+	memset (cr, 0, sizeof (cr));
+	cr[0x00] = 0xff & (ht - 5);
+	cr[0x01] = hd - 1;	/* soll:4f ist 59 */
+	cr[0x02] = hd;
+	cr[0x03] = (hbe & 0x1F) | 0x80;	/* hd + ht - hd  */
+	cr[0x04] = hs;
+	cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
+	cr[0x06] = (vt - 2) & 0xFF;
+	cr[0x30] = (vt - 2) >> 8;
+	cr[0x07] = ((vt & 0x100) >> 8)
+	    | ((vd & 0x100) >> 7)
+	    | ((vs & 0x100) >> 6)
+	    | ((vs & 0x100) >> 5)
+	    | ((LineCompare & 0x100) >> 4)
+	    | ((vt & 0x200) >> 4)
+	    | ((vd & 0x200) >> 3)
+	    | ((vs & 0x200) >> 2);
+	cr[0x08] = 0x00;
+	cr[0x09] = (dblscan << 7)
+	    | ((LineCompare & 0x200) >> 3)
+	    | ((vs & 0x200) >> 4)
+	    | (TextScanLines - 1);
+	cr[0x10] = vs & 0xff;	/* VSyncPulseStart */
+	cr[0x32] = (vs & 0xf00) >> 8;	/* VSyncPulseStart */
+	cr[0x11] = (ve & 0x0f);	/* | 0x20;      */
+	cr[0x12] = (vd - 1) & 0xff;	/* LineCount  */
+	cr[0x31] = ((vd - 1) & 0xf00) >> 8;	/* LineCount */
+	cr[0x13] = wd & 0xff;
+	cr[0x41] = (wd & 0xf00) >> 8;
+	cr[0x15] = vs & 0xff;
+	cr[0x33] = (vs & 0xf00) >> 8;
+	cr[0x38] = (0x100 & (ht - 5)) >> 8;
+	cr[0x3C] = 0xc0 & hbe;
+	cr[0x16] = (vt - 1) & 0xff;	/* vbe - docu wants vt here, */
+	cr[0x17] = 0xe3;	/* but it does not work */
+	cr[0x18] = 0xff & LineCompare;
+	cr[0x22] = 0xff;	/* todo? */
+	cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00;	/* check:0xa6  */
+	cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6)
+	    | (BlDelayCtrl << 5)
+	    | ((0x03 & CompSyncCharClkDelay) << 3)
+	    | (0x07 & CompSyncPixelClkDelay);	/* todo: see XR82 */
+	cr[0x72] = HorizontalSerration1Start;
+	cr[0x73] = HorizontalSerration2Start;
+	cr[0x74] = (HorizontalEqualizationPulses << 5)
+	    | NTSC_PAL_HorizontalPulseWidth;
+	/* todo: ct69000 has also 0x75-79 */
+	/* now set the registers */
+	for (i = 0; i <= 0x0d; i++) {	/*CR00 .. CR0D */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	for (i = 0x10; i <= 0x18; i++) {	/*CR10 .. CR18 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	i = 0x22;		/*CR22 */
+	ctWrite_i (CT_CR_O, i, cr[i]);
+	for (i = 0x30; i <= 0x33; i++) {	/*CR30 .. CR33 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	i = 0x38;		/*CR38 */
+	ctWrite_i (CT_CR_O, i, cr[i]);
+	i = 0x3C;		/*CR3C */
+	ctWrite_i (CT_CR_O, i, cr[i]);
+	for (i = 0x40; i <= 0x41; i++) {	/*CR40 .. CR41 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	for (i = 0x70; i <= 0x74; i++) {	/*CR70 .. CR74 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	tmp = ctRead_i (CT_CR_O, 0x40);
+	tmp &= 0x0f;
+	tmp |= 0x80;
+	ctWrite_i (CT_CR_O, 0x40, tmp);	/* StartAddressEnable */
+}
+
+/* pixelclock control */
+
+/*****************************************************************************
+ We have a rational number p/q and need an m/n which is very close to p/q
+ but has m and n within mnmin and mnmax. We have no floating point in the
+ kernel. We can use long long without divide. And we have time to compute...
+******************************************************************************/
+static unsigned int
+FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin,
+		     unsigned int mnmax, unsigned int *pm, unsigned int *pn)
+{
+	/* this code is not for general purpose usable but good for our number ranges */
+	unsigned int n = mnmin, m = 0;
+	long long int L = 0, P = p, Q = q, H = P >> 1;
+	long long int D = 0x7ffffffffffffffLL;
+	for (n = mnmin; n <= mnmax; n++) {
+		m = mnmin;	/* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */
+		L = P * n - m * Q;	/* n * vco - m * fref should be near 0 */
+		while (L > 0 && m < mnmax) {
+			L -= q;	/* difference is greater as 0 subtract fref */
+			m++;	/* and increment m */
+		}
+		/* difference is less or equal than 0 or m > maximum */
+		if (m > mnmax)
+			break;	/* no solution: if we increase n we get the same situation */
+		/* L is <= 0 now */
+		if (-L > H && m > mnmin) {	/* if difference > the half fref */
+			L += q;	/* we take the situation before */
+			m--;	/* because its closer to 0 */
+		}
+		L = (L < 0) ? -L : +L;	/* absolute value */
+		if (D < L)	/* if last difference was better take next n */
+			continue;
+		D = L;
+		*pm = m;
+		*pn = n;	/*  keep improved data */
+		if (D == 0)
+			break;	/* best result we can get */
+	}
+	return (unsigned int) (0xffffffff & D);
+}
+
+/* that is the hardware < 69000 we have to manage
+ +---------+  +-------------------+  +----------------------+  +--+
+ | REFCLK  |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|÷N|__
+ | 14.3MHz |  |(NTSCDS) (÷1, ÷5)  |  |Select (RDS) (÷1, ÷4) |  |  |  |
+ +---------+  +-------------------+  +----------------------+  +--+  |
+  ___________________________________________________________________|
+ |
+ |                                    fvco                      fout
+ | +--------+  +------------+  +-----+     +-------------------+   +----+
+ +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
+ +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
+ | +--------+  +------------+  +-----+  |  +-------------------+   +----+
+ |                                      |
+ |    +--+   +---------------+          |
+ |____|÷M|___|VCO Loop Divide|__________|
+      |  |   |(VLD)(÷4, ÷16) |
+      +--+   +---------------+
+****************************************************************************
+  that is the hardware >= 69000 we have to manage
+ +---------+  +--+
+ | REFCLK  |__|÷N|__
+ | 14.3MHz |  |  |  |
+ +---------+  +--+  |
+  __________________|
+ |
+ |                                    fvco                      fout
+ | +--------+  +------------+  +-----+     +-------------------+   +----+
+ +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
+ +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
+ | +--------+  +------------+  +-----+  |  +-------------------+   +----+
+ |                                      |
+ |    +--+   +---------------+          |
+ |____|÷M|___|VCO Loop Divide|__________|
+      |  |   |(VLD)(÷1, ÷4)  |
+      +--+   +---------------+
+
+
+*/
+
+#define VIDEO_FREF 14318180;	/* Hz  */
+/*****************************************************************************/
+static int
+ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param)
+{
+	unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock;
+	i = 0;
+	pixclock = -1;
+	fref = VIDEO_FREF;
+	m = ctRead_i (CT_XR_O, 0xc8);
+	n = ctRead_i (CT_XR_O, 0xc9);
+	m -= param->mn_diff;
+	n -= param->mn_diff;
+	xr_cb = ctRead_i (CT_XR_O, 0xcb);
+	PD = (0x70 & xr_cb) >> 4;
+	pd = 1;
+	for (i = 0; i < PD; i++) {
+		pd *= 2;
+	}
+	vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set;
+	if (n * vld * m) {
+		unsigned long long p = 1000000000000LL * pd * n;
+		unsigned long long q = (long long) fref * vld * m;
+		while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) {
+			p >>= 1;	/* can't divide with long long so we scale down */
+			q >>= 1;
+		}
+		pixclock = (unsigned) p / (unsigned) q;
+	} else
+		printf ("Invalid data in xr regs.\n");
+	return pixclock;
+}
+
+/*****************************************************************************/
+static void
+FindAndSetPllParamIntoXrRegs (unsigned int pixelclock,
+			      struct ctfb_chips_properties *param)
+{
+	unsigned int m, n, vld, pd, PD, fref, xr_cb;
+	unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk;
+	unsigned int pfreq, fvco, new_pixclock;
+
+	fref = VIDEO_FREF;
+	pd = 1;
+	PD = 0;
+	fvcomin = param->vco_min;
+	fvcomax = param->vco_max;	/* MHz */
+	pclckmin = 1000000 / fvcomax + 1;	/*   4546 */
+	pclckmax = 32000000 / fvcomin - 1;	/* 666665 */
+	pclk = minmax (pclckmin, pixelclock, pclckmax);	/* ps pp */
+	pfreq = 250 * (4000000000U / pclk);
+	fvco = pfreq;		/* Hz */
+	new_pixclock = 0;
+	while (fvco < fvcomin * 1000000) {
+		/* double VCO starting with the pixelclock frequency
+		 * as long as it is lower than the minimal VCO frequency */
+		fvco *= 2;
+		pd *= 2;
+		PD++;
+	}
+	/* fvco is exactly pd * pixelclock and higher than the ninmal VCO frequency */
+	vld = (param->vld_set > param->vld_not_set) ?
+	    param->vld_not_set : param->vld_set;
+	/* start with lower VLD (higher VLD is NOT yet implemented */
+	FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n);	/* rds = 1 */
+	m += param->mn_diff;
+	n += param->mn_diff;
+	PRINTF ("VCO %d, pd %d, m %d n %d vld %d \n", fvco, pd, m, n, vld);
+	xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0);
+	/* All four of the registers used for dot clock 2 (XRC8 - XRCB) must be
+	 * written, and in order from XRC8 to XRCB, before the hardware will
+	 * update the synthesizer s settings.
+	 */
+	ctWrite_i (CT_XR_O, 0xc8, m);
+	ctWrite_i (CT_XR_O, 0xc9, n);	/* xrca does not exist in CT69000 and CT69030 */
+	ctWrite_i (CT_XR_O, 0xca, 0);	/* because of a hw bug I guess, but we write */
+	ctWrite_i (CT_XR_O, 0xcb, xr_cb);	/* 0 to it for savety */
+	new_pixclock = ReadPixClckFromXrRegsBack (param);
+	PRINTF ("pixelclock.set = %d, pixelclock.real = %d \n",
+		pixelclock, new_pixclock);
+}
+
+/*****************************************************************************/
+static void
+SetMsrRegs (struct ctfb_res_modes *mode)
+{
+	unsigned char h_synch_high, v_synch_high;
+
+	h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;	/* horizontal Synch High active */
+	v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80;	/* vertical Synch High active */
+	ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29));
+	/* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
+	 * Selects the upper 64KB page.Bit5=1
+	 * CLK2 (left reserved in standard VGA) Bit3|2=1|0
+	 * Disables CPU access to frame buffer. Bit1=0
+	 * Sets the I/O address decode for ST01, FCR, and all CR registers
+	 * to the 3Dx I/O address range (CGA emulation). Bit0=1
+	 */
+}
+
+/************************************************************************************/
+#ifdef VGA_DUMP_REG
+
+static void
+ctDispRegs (unsigned short index, int from, int to)
+{
+	unsigned char status;
+	int i;
+
+	for (i = from; i < to; i++) {
+		status = ctRead_i (index, i);
+		printf ("%02X: is %02X\n", i, status);
+	}
+}
+
+void
+video_dump_reg (void)
+{
+	int i;
+
+	printf ("Extended Regs:\n");
+	ctDispRegs (CT_XR_O, 0, 0xC);
+	ctDispRegs (CT_XR_O, 0xe, 0xf);
+	ctDispRegs (CT_XR_O, 0x20, 0x21);
+	ctDispRegs (CT_XR_O, 0x40, 0x50);
+	ctDispRegs (CT_XR_O, 0x60, 0x64);
+	ctDispRegs (CT_XR_O, 0x67, 0x68);
+	ctDispRegs (CT_XR_O, 0x70, 0x72);
+	ctDispRegs (CT_XR_O, 0x80, 0x83);
+	ctDispRegs (CT_XR_O, 0xA0, 0xB0);
+	ctDispRegs (CT_XR_O, 0xC0, 0xD3);
+	printf ("Sequencer Regs:\n");
+	ctDispRegs (CT_SR_O, 0, 0x8);
+	printf ("Graphic Regs:\n");
+	ctDispRegs (CT_GR_O, 0, 0x9);
+	printf ("CRT Regs:\n");
+	ctDispRegs (CT_CR_O, 0, 0x19);
+	ctDispRegs (CT_CR_O, 0x22, 0x23);
+	ctDispRegs (CT_CR_O, 0x30, 0x34);
+	ctDispRegs (CT_CR_O, 0x38, 0x39);
+	ctDispRegs (CT_CR_O, 0x3C, 0x3D);
+	ctDispRegs (CT_CR_O, 0x40, 0x42);
+	ctDispRegs (CT_CR_O, 0x70, 0x80);
+	/* don't display the attributes */
+}
+
+#endif
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+/***************************************************************
+ * Set Hardware Cursor in Pixel
+ */
+void
+video_set_hw_cursor (int x, int y)
+{
+	int sig_x = 0, sig_y = 0;
+	if (x < 0) {
+		x *= -1;
+		sig_x = 1;
+	}
+	if (y < 0) {
+		y *= -1;
+		sig_y = 1;
+	}
+	ctWrite_i (CT_XR_O, 0xa4, x & 0xff);
+	ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7);
+	ctWrite_i (CT_XR_O, 0xa6, y & 0xff);
+	ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7);
+}
+
+/***************************************************************
+ * Init Hardware Cursor. To know the size of the Cursor,
+ * we have to know the Font size.
+ */
+void
+video_init_hw_cursor (int font_width, int font_height)
+{
+	unsigned char xr_80;
+	unsigned long *curs, pattern;
+	int i;
+	int cursor_start;
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+	cursor_start = pGD->dprBase;
+	xr_80 = ctRead_i (CT_XR_O, 0x80);
+	/* set start address */
+	ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0);
+	ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f);
+	/* set cursor shape */
+	curs = (unsigned long *) cursor_start;
+	i = 0;
+	while (i < 0x400) {
+		curs[i++] = 0xffffffff;	/* AND mask */
+		curs[i++] = 0xffffffff;	/* AND mask */
+		curs[i++] = 0;	/* XOR mask */
+		curs[i++] = 0;	/* XOR mask */
+		/* Transparent */
+	}
+	pattern = 0xffffffff >> font_width;
+	i = 0;
+	while (i < (font_height * 2)) {
+		curs[i++] = pattern;	/* AND mask */
+		curs[i++] = pattern;	/* AND mask */
+		curs[i++] = 0;	/* XOR mask */
+		curs[i++] = 0;	/* XOR mask */
+		/* Cursor Color 0 */
+	}
+	/* set blink rate */
+	ctWrite_i (CT_FP_O, 0x19, 0xf);
+
+	/* set cursors colors */
+	xr_80 = ctRead_i (CT_XR_O, 0x80);
+	xr_80 |= 0x1;		/* alternate palette select */
+	ctWrite_i (CT_XR_O, 0x80, xr_80);
+	video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+	/* position 4 is color 0 cursor 0 */
+	xr_80 &= 0xfe;		/* normal palette select */
+	ctWrite_i (CT_XR_O, 0x80, xr_80);
+	/* cursor enable */
+	ctWrite_i (CT_XR_O, 0xa0, 0x91);
+	xr_80 |= 0x10;		/* enable hwcursor */
+	ctWrite_i (CT_XR_O, 0x80, xr_80);
+	video_set_hw_cursor (0, 0);
+}
+#endif				/* CONFIG_VIDEO_HW_CURSOR */
+
+/***************************************************************
+ * Wait for BitBlt ready
+ */
+static int
+video_wait_bitblt (unsigned long addr)
+{
+	unsigned long br04;
+	int i = 0;
+	br04 = in32r (addr);
+	while (br04 & 0x80000000) {
+		udelay (1);
+		br04 = in32r (addr);
+		if (i++ > 1000000) {
+			printf ("ERROR Timeout %lx\n", br04);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/***************************************************************
+ * Set up BitBlt Registrs
+ */
+static void
+SetDrawingEngine (int bits_per_pixel)
+{
+	unsigned long br04, br00;
+	unsigned char tmp;
+
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+	tmp = ctRead_i (CT_XR_O, 0x20);	/* BitBLT Configuration */
+	tmp |= 0x02;		/* reset BitBLT */
+	ctWrite_i (CT_XR_O, 0x20, tmp);	/* BitBLT Configuration */
+	udelay (10);
+	tmp &= 0xfd;		/* release reset BitBLT */
+	ctWrite_i (CT_XR_O, 0x20, tmp);	/* BitBLT Configuration */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+
+	/* set pattern Address */
+	out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8);
+	br04 = 0;
+	if (bits_per_pixel == 1) {
+		br04 |= 0x00040000;	/* monochome Pattern */
+		br04 |= 0x00001000;	/* monochome source */
+	}
+	br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP);	/* bytes per scanline */
+	out32r (pGD->pciBase + BR00_o, br00);	/* */
+	out32r (pGD->pciBase + BR08_o, (10 << 16) + 10);	/* dummy */
+	out32r (pGD->pciBase + BR04_o, br04);	/* write all 0 */
+	out32r (pGD->pciBase + BR07_o, 0);	/* destination */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/************************************************************************
+ * Get Parameters for the video mode:
+ */
+/*********************************************************************
+ * returns the length to the next seperator
+ */
+static int
+video_get_param_len (char *start, char sep)
+{
+	int i = 0;
+	while ((*start != 0) && (*start != sep)) {
+		start++;
+		i++;
+	}
+	return i;
+}
+
+static int
+video_search_param (char *start, char *param)
+{
+	int len, totallen, i;
+	char *p = start;
+	len = strlen (param);
+	totallen = len + strlen (start);
+	for (i = 0; i < totallen; i++) {
+		if (strncmp (p++, param, len) == 0)
+			return (i);
+	}
+	return -1;
+}
+
+/***************************************************************
+* Get parameter via the environment as it is done for the
+* linux kernel i.e:
+* video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000,
+*       le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0
+*
+* penv is a pointer to the environment, containing the string, or the name of
+* another environment variable. It could even be the term "bootargs"
+*/
+
+#define GET_OPTION(name,var) 				\
+		if(strncmp(p,name,strlen(name))==0) { 	\
+			val_s=p+strlen(name); 		\
+			var=simple_strtoul(val_s, NULL, 10); \
+		}
+
+static int
+video_get_params (struct ctfb_res_modes *pPar, char *penv)
+{
+	char *p, *s, *val_s;
+	int i = 0, t;
+	int bpp;
+	int mode;
+	/* first search for the environment containing the real param string */
+	s = penv;
+	if ((p = getenv (s)) != NULL) {
+		s = p;
+	}
+	/* in case of the bootargs line, we have to start
+	 * after "video=ctfb:"
+	 */
+	i = video_search_param (s, "video=ctfb:");
+	if (i >= 0) {
+		s += i;
+		s += strlen ("video=ctfb:");
+	}
+	/* search for mode as a default value */
+	p = s;
+	t = 0;
+	mode = 0;		/* default */
+	while ((i = video_get_param_len (p, ',')) != 0) {
+		GET_OPTION ("mode:", mode)
+		    p += i;
+		if (*p != 0)
+			p++;	/* skip ',' */
+	}
+	if (mode >= RES_MODES_COUNT)
+		mode = 0;
+	*pPar = res_mode_init[mode];	/* copy default values */
+	bpp = 24 - ((mode % 3) * 8);
+	p = s;			/* restart */
+	while ((i = video_get_param_len (p, ',')) != 0) {
+		GET_OPTION ("x:", pPar->xres)
+		    GET_OPTION ("y:", pPar->yres)
+		    GET_OPTION ("le:", pPar->left_margin)
+		    GET_OPTION ("ri:", pPar->right_margin)
+		    GET_OPTION ("up:", pPar->upper_margin)
+		    GET_OPTION ("lo:", pPar->lower_margin)
+		    GET_OPTION ("hs:", pPar->hsync_len)
+		    GET_OPTION ("vs:", pPar->vsync_len)
+		    GET_OPTION ("sync:", pPar->sync)
+		    GET_OPTION ("vmode:", pPar->vmode)
+		    GET_OPTION ("pclk:", pPar->pixclock)
+		    GET_OPTION ("depth:", bpp)
+		    p += i;
+		if (*p != 0)
+			p++;	/* skip ',' */
+	}
+	return bpp;
+}
+
+/****************************************************************************
+* supported Video Chips
+*/
+static struct pci_device_id supported[] = {
+	{PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
+	{}
+};
+
+/*******************************************************************************
+*
+* Init video chip
+*/
+void *
+video_hw_init (void)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	unsigned short device_id;
+	pci_dev_t devbusfn;
+	int videomode;
+	unsigned long t1, hsynch, vsynch;
+	unsigned int pci_mem_base, *vm;
+	int tmp, i, bits_per_pixel;
+	char *penv;
+	struct ctfb_res_modes *res_mode;
+	struct ctfb_res_modes var_mode;
+	struct ctfb_chips_properties *chips_param;
+	/* Search for video chip */
+
+	if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+		printf ("Video: Controller not found !\n");
+#endif
+		return (NULL);
+	}
+
+	/* PCI setup */
+	pci_write_config_dword (devbusfn, PCI_COMMAND,
+				(PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+	pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+	pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+	pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+	/* get chips params */
+	for (chips_param = (struct ctfb_chips_properties *) &chips[0];
+	     chips_param->device_id != 0; chips_param++) {
+		if (chips_param->device_id == device_id)
+			break;
+	}
+	if (chips_param->device_id == 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+		printf ("Video: controller 0x%X not supported\n", device_id);
+#endif
+		return NULL;
+	}
+	/* supported Video controller found */
+	printf ("Video: ");
+
+	tmp = 0;
+	videomode = 0x301;
+	/* get video mode via environment */
+	if ((penv = getenv ("videomode")) != NULL) {
+		/* deceide if it is a string */
+		if (penv[0] <= '9') {
+			videomode = (int) simple_strtoul (penv, NULL, 16);
+			tmp = 1;
+		}
+	} else {
+		tmp = 1;
+	}
+	if (tmp) {
+		/* parameter are vesa modes */
+		/* search params */
+		for (i = 0; i < VESA_MODES_COUNT; i++) {
+			if (vesa_modes[i].vesanr == videomode)
+				break;
+		}
+		if (i == VESA_MODES_COUNT) {
+			printf ("no VESA Mode found, switching to mode 0x301 ");
+			i = 0;
+		}
+		res_mode =
+		    (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
+							     resindex];
+		bits_per_pixel = vesa_modes[i].bits_per_pixel;
+	} else {
+
+		res_mode = (struct ctfb_res_modes *) &var_mode;
+		bits_per_pixel = video_get_params (res_mode, penv);
+	}
+
+	/* calculate available color depth for controller memory */
+	if (bits_per_pixel == 15)
+		tmp = 2;
+	else
+		tmp = bits_per_pixel >> 3;	/* /8 */
+	if (((chips_param->max_mem -
+	      ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) {
+		tmp =
+		    ((chips_param->max_mem -
+		      ACCELMEMORY) / (res_mode->xres * res_mode->yres));
+		if (tmp == 0) {
+			printf
+			    ("No matching videomode found .-> reduce resolution\n");
+			return NULL;
+		} else {
+			printf ("Switching back to %d Bits per Pixel ",
+				tmp << 3);
+			bits_per_pixel = tmp << 3;
+		}
+	}
+
+	/* calculate hsynch and vsynch freq (info only) */
+	t1 = (res_mode->left_margin + res_mode->xres +
+	      res_mode->right_margin + res_mode->hsync_len) / 8;
+	t1 *= 8;
+	t1 *= res_mode->pixclock;
+	t1 /= 1000;
+	hsynch = 1000000000L / t1;
+	t1 *=
+	    (res_mode->upper_margin + res_mode->yres +
+	     res_mode->lower_margin + res_mode->vsync_len);
+	t1 /= 1000;
+	vsynch = 1000000000L / t1;
+
+	/* fill in Graphic device struct */
+	sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
+		 res_mode->yres, bits_per_pixel, (hsynch / 1000),
+		 (vsynch / 1000));
+	printf ("%s\n", pGD->modeIdent);
+	pGD->winSizeX = res_mode->xres;
+	pGD->winSizeY = res_mode->yres;
+	pGD->plnSizeX = res_mode->xres;
+	pGD->plnSizeY = res_mode->yres;
+	switch (bits_per_pixel) {
+	case 8:
+		pGD->gdfBytesPP = 1;
+		pGD->gdfIndex = GDF__8BIT_INDEX;
+		break;
+	case 15:
+		pGD->gdfBytesPP = 2;
+		pGD->gdfIndex = GDF_15BIT_555RGB;
+		break;
+	case 16:
+		pGD->gdfBytesPP = 2;
+		pGD->gdfIndex = GDF_16BIT_565RGB;
+		break;
+	case 24:
+		pGD->gdfBytesPP = 3;
+		pGD->gdfIndex = GDF_24BIT_888RGB;
+		break;
+	}
+	pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
+	pGD->pciBase = pci_mem_base;
+	pGD->frameAdrs = pci_mem_base;
+	pGD->memSize = chips_param->max_mem;
+	/* Cursor Start Address */
+	pGD->dprBase =
+	    (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base;
+	if ((pGD->dprBase & 0x0fff) != 0) {
+		/* allign it */
+		pGD->dprBase &= 0xfffff000;
+		pGD->dprBase += 0x00001000;
+	}
+	PRINTF ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
+		PATTERN_ADR);
+	pGD->vprBase = pci_mem_base;	/* Dummy */
+	pGD->cprBase = pci_mem_base;	/* Dummy */
+	/* set up Hardware */
+
+	ctWrite (CT_MSR_W_O, 0x01);
+
+	/* set the extended Registers */
+	ctLoadRegs (CT_XR_O, xreg);
+	/* set atribute registers */
+	SetArRegs ();
+	/* set Graphics register */
+	SetGrRegs ();
+	/* set sequencer */
+	SetSrRegs ();
+
+	/* set msr */
+	SetMsrRegs (res_mode);
+
+	/* set CRT Registers */
+	SetCrRegs (res_mode, bits_per_pixel);
+	/* set color mode */
+	SetBitsPerPixelIntoXrRegs (bits_per_pixel);
+
+	/* set PLL */
+	FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param);
+
+	ctWrite_i (CT_SR_O, 0, 0x03);	/* clear synchronous reset */
+	/* Clear video memory */
+	i = pGD->memSize / 4;
+	vm = (unsigned int *) pGD->pciBase;
+	while (i--)
+		*vm++ = 0;
+	SetDrawingEngine (bits_per_pixel);
+#ifdef VGA_DUMP_REG
+	video_dump_reg ();
+#endif
+
+	return ((void *) &ctfb);
+}
+
+ /*******************************************************************************
+*
+* Set a RGB color in the LUT (8 bit index)
+*/
+void
+video_set_lut (unsigned int index,	/* color number */
+	       unsigned char r,	/* red */
+	       unsigned char g,	/* green */
+	       unsigned char b	/* blue */
+    )
+{
+
+	ctWrite (CT_LUT_MASK_O, 0xff);
+
+	ctWrite (CT_LUT_START_O, (char) index);
+
+	ctWrite (CT_LUT_RGB_O, r);	/* red */
+	ctWrite (CT_LUT_RGB_O, g);	/* green */
+	ctWrite (CT_LUT_RGB_O, b);	/* blue */
+	udelay (1);
+	ctWrite (CT_LUT_MASK_O, 0xff);
+}
+
+/*******************************************************************************
+*
+* Drawing engine fill on screen region
+*/
+void
+video_hw_rectfill (unsigned int bpp,	/* bytes per pixel */
+		   unsigned int dst_x,	/* dest pos x */
+		   unsigned int dst_y,	/* dest pos y */
+		   unsigned int dim_x,	/* frame width */
+		   unsigned int dim_y,	/* frame height */
+		   unsigned int color	/* fill color */
+    )
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	unsigned long *p, br04;
+
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+
+	p = (unsigned long *) PATTERN_ADR;
+	dim_x *= bpp;
+	if (bpp == 3)
+		bpp++;		/* 24Bit needs a 32bit pattern */
+	memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8));	/* 8 x 8 pattern data */
+	out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);	/* destination */
+	br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00;
+	br04 |= 0xF0;		/* write Pattern P -> D */
+	out32r (pGD->pciBase + BR04_o, br04);	/* */
+	out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);	/* starts the BITBlt */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/*******************************************************************************
+*
+* Drawing engine bitblt with screen region
+*/
+void
+video_hw_bitblt (unsigned int bpp,	/* bytes per pixel */
+		 unsigned int src_x,	/* source pos x */
+		 unsigned int src_y,	/* source pos y */
+		 unsigned int dst_x,	/* dest pos x */
+		 unsigned int dst_y,	/* dest pos y */
+		 unsigned int dim_x,	/* frame width */
+		 unsigned int dim_y	/* frame height */
+    )
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	unsigned long br04;
+
+	br04 = in32r (pGD->pciBase + BR04_o);
+
+	/* to prevent data corruption due to overlap, we have to
+	 * find out if, and how the frames overlaps */
+	if (src_x < dst_x) {
+		/* src is more left than dest
+		 * the frame may overlap -> start from right to left */
+		br04 |= 0x00000100;	/* set bit 8 */
+		src_x += dim_x;
+		dst_x += dim_x;
+	} else {
+		br04 &= 0xfffffeff;	/* clear bit 8 left to right */
+	}
+	if (src_y < dst_y) {
+		/* src is higher than dst
+		 * the frame may overlap => start from bottom */
+		br04 |= 0x00000200;	/* set bit 9 */
+		src_y += dim_y;
+		dst_y += dim_y;
+	} else {
+		br04 &= 0xfffffdff;	/* clear bit 9 top to bottom */
+	}
+	dim_x *= bpp;
+	out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP);	/* source */
+	out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);	/* destination */
+	br04 &= 0xffffff00;
+	br04 |= 0x000000CC;	/* S -> D */
+	out32r (pGD->pciBase + BR04_o, br04);	/* */
+	out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);	/* start the BITBlt */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+#endif				/* CONFIG_CT69000 */
+
+#endif				/* CONFIG_VIDEO */
diff --git a/drivers/dc2114x.c b/drivers/dc2114x.c
new file mode 100644
index 0000000..e1147c0
--- /dev/null
+++ b/drivers/dc2114x.c
@@ -0,0 +1,720 @@
+/*
+ * 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>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+	&& defined(CONFIG_TULIP)
+
+#include <malloc.h>
+#include <net.h>
+#include <pci.h>
+
+#undef DEBUG
+#undef DEBUG_SROM
+#undef DEBUG_SROM2
+
+#undef UPDATE_SROM
+
+/* PCI Registers.
+ */
+#define PCI_CFDA_PSM		0x43
+
+#define CFRV_RN		0x000000f0	/* Revision Number */
+
+#define WAKEUP		0x00		/* Power Saving Wakeup */
+#define SLEEP		0x80		/* Power Saving Sleep Mode */
+
+#define DC2114x_BRK	0x0020		/* CFRV break between DC21142 & DC21143 */
+
+/* Ethernet chip registers.
+ */
+#define DE4X5_BMR	0x000		/* Bus Mode Register */
+#define DE4X5_TPD	0x008		/* Transmit Poll Demand Reg */
+#define DE4X5_RRBA	0x018		/* RX Ring Base Address Reg */
+#define DE4X5_TRBA	0x020		/* TX Ring Base Address Reg */
+#define DE4X5_STS	0x028		/* Status Register */
+#define DE4X5_OMR	0x030		/* Operation Mode Register */
+#define DE4X5_SICR	0x068		/* SIA Connectivity Register */
+#define DE4X5_APROM	0x048		/* Ethernet Address PROM */
+
+/* Register bits.
+ */
+#define BMR_SWR		0x00000001	/* Software Reset */
+#define STS_TS		0x00700000	/* Transmit Process State */
+#define STS_RS		0x000e0000	/* Receive Process State */
+#define OMR_ST		0x00002000	/* Start/Stop Transmission Command */
+#define OMR_SR		0x00000002	/* Start/Stop Receive */
+#define OMR_PS		0x00040000	/* Port Select */
+#define OMR_SDP		0x02000000	/* SD Polarity - MUST BE ASSERTED */
+#define OMR_PM		0x00000080	/* Pass All Multicast */
+
+/* Descriptor bits.
+ */
+#define R_OWN		0x80000000	/* Own Bit */
+#define RD_RER		0x02000000	/* Receive End Of Ring */
+#define RD_LS		0x00000100	/* Last Descriptor */
+#define RD_ES		0x00008000	/* Error Summary */
+#define TD_TER		0x02000000	/* Transmit End Of Ring */
+#define T_OWN		0x80000000	/* Own Bit */
+#define TD_LS		0x40000000	/* Last Segment */
+#define TD_FS		0x20000000	/* First Segment */
+#define TD_ES		0x00008000	/* Error Summary */
+#define TD_SET		0x08000000	/* Setup Packet */
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define SROM_WRITE_CMD	5
+#define SROM_READ_CMD	6
+#define SROM_ERASE_CMD	7
+
+#define SROM_HWADD	    0x0014	/* Hardware Address offset in SROM */
+#define SROM_RD		0x00004000	/* Read from Boot ROM */
+#define EE_DATA_WRITE	0x04	/* EEPROM chip data in. */
+#define EE_WRITE_0		0x4801
+#define EE_WRITE_1		0x4805
+#define EE_DATA_READ	0x08	/* EEPROM chip data out. */
+#define SROM_SR		0x00000800	/* Select Serial ROM when set */
+
+#define DT_IN		0x00000004	/* Serial Data In */
+#define DT_CLK		0x00000002	/* Serial ROM Clock */
+#define DT_CS		0x00000001	/* Serial ROM Chip Select */
+
+#define POLL_DEMAND	1
+
+#define RESET_DE4X5(dev) {\
+    int i;\
+    i=INL(dev, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i, DE4X5_BMR);\
+    udelay(1000);\
+    for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
+    udelay(1000);\
+}
+
+#define START_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr |= OMR_ST | OMR_SR;\
+    OUTL(dev, omr, DE4X5_OMR);		/* Enable the TX and/or RX */\
+}
+
+#define STOP_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr &= ~(OMR_ST|OMR_SR);\
+    OUTL(dev, omr, DE4X5_OMR);		/* Disable the TX and/or RX */ \
+}
+
+#define NUM_RX_DESC PKTBUFSRX
+#define NUM_TX_DESC 1			/* Number of TX descriptors   */
+#define RX_BUFF_SZ  PKTSIZE_ALIGN
+
+#define TOUT_LOOP   1000000
+
+#define SETUP_FRAME_LEN 192
+#define ETH_ALEN	6
+
+
+struct de4x5_desc {
+	volatile s32 status;
+	u32 des1;
+	u32 buf;
+	u32 next;
+};
+
+static struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring         */
+static struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring         */
+static int rx_new;                             /* RX descriptor ring pointer */
+static int tx_new;                             /* TX descriptor ring pointer */
+
+static char rxRingSize;
+static char txRingSize;
+
+static void  sendto_srom(struct eth_device* dev, u_int command, u_long addr);
+static int   getfrom_srom(struct eth_device* dev, u_long addr);
+static int   do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len);
+static int   do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len);
+static int   read_srom(struct eth_device *dev, u_long ioaddr, int index);
+#ifdef UPDATE_SROM
+static int   write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value);
+static void  update_srom(struct eth_device *dev, bd_t *bis);
+#endif
+static void  read_hw_addr(struct eth_device* dev, bd_t * bis);
+static void  send_setup_frame(struct eth_device* dev, bd_t * bis);
+
+static int   dc21x4x_init(struct eth_device* dev, bd_t* bis);
+static int   dc21x4x_send(struct eth_device* dev, volatile void *packet, int length);
+static int   dc21x4x_recv(struct eth_device* dev);
+static void  dc21x4x_halt(struct eth_device* dev);
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+extern void  dc21x4x_select_media(struct eth_device* dev);
+#endif
+
+#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+static int INL(struct eth_device* dev, u_long addr)
+{
+	return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
+}
+
+static void OUTL(struct eth_device* dev, int command, u_long addr)
+{
+	*(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
+}
+
+static struct pci_device_id supported[] = {
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
+	{ }
+};
+
+int dc21x4x_initialize(bd_t *bis)
+{
+	int             	idx=0;
+	int             	card_number = 0;
+	int             	cfrv;
+	unsigned char   	timer;
+	pci_dev_t		devbusfn;
+	unsigned int		iobase;
+	unsigned short		status;
+	struct eth_device* 	dev;
+
+	while(1) {
+		devbusfn =  pci_find_devices(supported, idx++);
+		if (devbusfn == -1) {
+			break;
+		}
+
+		/* Get the chip configuration revision register. */
+		pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
+
+		if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
+			printf("Error: The chip is not DC21143.\n");
+			continue;
+		}
+
+		pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+		status |=
+#ifdef CONFIG_TULIP_USE_IO
+		  PCI_COMMAND_IO |
+#else
+		  PCI_COMMAND_MEMORY |
+#endif
+		  PCI_COMMAND_MASTER;
+		pci_write_config_word(devbusfn, PCI_COMMAND, status);
+
+		pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+		if (!(status & PCI_COMMAND_IO)) {
+			printf("Error: Can not enable I/O access.\n");
+			continue;
+		}
+
+		if (!(status & PCI_COMMAND_IO)) {
+			printf("Error: Can not enable I/O access.\n");
+			continue;
+		}
+
+		if (!(status & PCI_COMMAND_MASTER)) {
+			printf("Error: Can not enable Bus Mastering.\n");
+			continue;
+		}
+
+		/* Check the latency timer for values >= 0x60. */
+		pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer);
+
+		if (timer < 0x60) {
+			pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60);
+		}
+
+#ifdef CONFIG_TULIP_USE_IO
+		/* read BAR for memory space access */
+		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
+		iobase &= PCI_BASE_ADDRESS_IO_MASK;
+#else
+		/* read BAR for memory space access */
+		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase);
+		iobase &= PCI_BASE_ADDRESS_MEM_MASK;
+#endif
+
+#ifdef DEBUG
+		printf("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
+#endif
+
+		dev = (struct eth_device*) malloc(sizeof *dev);
+
+		sprintf(dev->name, "dc21x4x#%d", card_number);
+#ifdef CONFIG_TULIP_USE_IO
+		dev->iobase = pci_io_to_phys(devbusfn, iobase);
+#else
+		dev->iobase = pci_mem_to_phys(devbusfn, iobase);
+#endif
+		dev->priv   = (void*) devbusfn;
+		dev->init   = dc21x4x_init;
+		dev->halt   = dc21x4x_halt;
+		dev->send   = dc21x4x_send;
+		dev->recv   = dc21x4x_recv;
+
+		/* Ensure we're not sleeping. */
+		pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+		udelay(10 * 1000);
+
+		read_hw_addr(dev, bis);
+
+		eth_register(dev);
+
+		card_number++;
+	}
+
+	return card_number;
+}
+
+static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
+{
+	int		i;
+	int		devbusfn = (int) dev->priv;
+
+	/* Ensure we're not sleeping. */
+	pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+	RESET_DE4X5(dev);
+
+	if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
+		printf("Error: Cannot reset ethernet controller.\n");
+		return 0;
+	}
+
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+	dc21x4x_select_media(dev);
+#else
+	OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+#endif
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		rx_ring[i].status = cpu_to_le32(R_OWN);
+		rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
+		rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
+		rx_ring[i].next = 0;
+	}
+
+	for (i=0; i < NUM_TX_DESC; i++) {
+		tx_ring[i].status = 0;
+		tx_ring[i].des1 = 0;
+		tx_ring[i].buf = 0;
+		tx_ring[i].next = 0;
+	}
+
+	rxRingSize = NUM_RX_DESC;
+	txRingSize = NUM_TX_DESC;
+
+	/* Write the end of list marker to the descriptor lists. */
+	rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
+	tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
+
+	/* Tell the adapter where the TX/RX rings are located. */
+	OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA);
+	OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA);
+
+	START_DE4X5(dev);
+
+	tx_new = 0;
+	rx_new = 0;
+
+	send_setup_frame(dev, bis);
+
+	return 1;
+}
+
+static int dc21x4x_send(struct eth_device* dev, volatile void *packet, int length)
+{
+	int		status = -1;
+	int		i;
+
+	if (length <= 0) {
+		printf("%s: bad packet size: %d\n", dev->name, length);
+		goto Done;
+	}
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx error buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	tx_ring[tx_new].buf    = cpu_to_le32(phys_to_bus((u32) packet));
+	tx_ring[tx_new].des1   = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+	tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+	OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf(".%s: tx buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
+#if 0 /* test-only */
+		printf("TX error status = 0x%08X\n",
+		       le32_to_cpu(tx_ring[tx_new].status));
+#endif
+		goto Done;
+	}
+
+	status = length;
+
+ Done:
+	return status;
+}
+
+static int dc21x4x_recv(struct eth_device* dev)
+{
+	s32		status;
+	int		length    = 0;
+
+	for ( ; ; ) {
+		status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+
+		if (status & R_OWN) {
+			break;
+		}
+
+		if (status & RD_LS) {
+			/* Valid frame status.
+			 */
+			if (status & RD_ES) {
+
+				/* There was an error.
+				 */
+				printf("RX error status = 0x%08X\n", status);
+			} else {
+				/* A valid frame received.
+				 */
+				length = (le32_to_cpu(rx_ring[rx_new].status) >> 16);
+
+				/* Pass the packet up to the protocol
+				 * layers.
+				 */
+				NetReceive(NetRxPackets[rx_new], length - 4);
+			}
+
+			/* Change buffer ownership for this frame, back
+			 * to the adapter.
+			 */
+			rx_ring[rx_new].status = cpu_to_le32(R_OWN);
+		}
+
+		/* Update entry information.
+		 */
+		rx_new = (rx_new + 1) % rxRingSize;
+	}
+
+	return length;
+}
+
+static void dc21x4x_halt(struct eth_device* dev)
+{
+	int		devbusfn = (int) dev->priv;
+
+	STOP_DE4X5(dev);
+	OUTL(dev, 0, DE4X5_SICR);
+
+	pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP);
+}
+
+static void send_setup_frame(struct eth_device* dev, bd_t *bis)
+{
+	int		i;
+	char	setup_frame[SETUP_FRAME_LEN];
+	char 	*pa = &setup_frame[0];
+
+	memset(pa, 0xff, SETUP_FRAME_LEN);
+
+	for (i = 0; i < ETH_ALEN; i++) {
+		*(pa + (i & 1)) = dev->enetaddr[i];
+		if (i & 0x01) {
+			pa += 4;
+		}
+	}
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx error buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
+	tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
+	tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+	OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
+		printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
+	}
+Done:
+	return;
+}
+
+/* SROM Read and write routines.
+ */
+
+static void
+sendto_srom(struct eth_device* dev, u_int command, u_long addr)
+{
+	OUTL(dev, command, addr);
+	udelay(1);
+}
+
+static int
+getfrom_srom(struct eth_device* dev, u_long addr)
+{
+	s32 tmp;
+
+	tmp = INL(dev, addr);
+	udelay(1);
+
+	return tmp;
+}
+
+/* Note: this routine returns extra data bits for size detection. */
+static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len)
+{
+	int i;
+	unsigned retval = 0;
+	int read_cmd = location | (SROM_READ_CMD << addr_len);
+
+	sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+	sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM
+	printf(" EEPROM read at %d ", location);
+#endif
+
+	/* Shift the read command bits out. */
+	for (i = 4 + addr_len; i >= 0; i--) {
+		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, ioaddr);
+		udelay(10);
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr);
+		udelay(10);
+#ifdef DEBUG_SROM2
+		printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+		retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+	}
+
+	sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM2
+	printf(" :%X:", getfrom_srom(dev, ioaddr) & 15);
+#endif
+
+	for (i = 16; i > 0; i--) {
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+		udelay(10);
+#ifdef DEBUG_SROM2
+		printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+		retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+		udelay(10);
+	}
+
+	/* Terminate the EEPROM access. */
+	sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM2
+	printf(" EEPROM value at %d is %5.5x.\n", location, retval);
+#endif
+
+	return retval;
+}
+
+/* This executes a generic EEPROM command, typically a write or write enable.
+   It returns the data output from the EEPROM, and thus may also be used for
+   reads. */
+static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len)
+{
+	unsigned retval = 0;
+
+#ifdef DEBUG_SROM
+	printf(" EEPROM op 0x%x: ", cmd);
+#endif
+
+	sendto_srom(dev,SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+
+	/* Shift the command bits out. */
+	do {
+		short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
+		sendto_srom(dev,dataval, ioaddr);
+		udelay(10);
+
+#ifdef DEBUG_SROM2
+		printf("%X", getfrom_srom(dev,ioaddr) & 15);
+#endif
+
+		sendto_srom(dev,dataval | DT_CLK, ioaddr);
+		udelay(10);
+		retval = (retval << 1) | ((getfrom_srom(dev,ioaddr) & EE_DATA_READ) ? 1 : 0);
+	} while (--cmd_len >= 0);
+	sendto_srom(dev,SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+	/* Terminate the EEPROM access. */
+	sendto_srom(dev,SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM
+	printf(" EEPROM result is 0x%5.5x.\n", retval);
+#endif
+
+	return retval;
+}
+
+static int read_srom(struct eth_device *dev, u_long ioaddr, int index)
+{
+	int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+
+	return do_eeprom_cmd(dev, ioaddr,
+			     (((SROM_READ_CMD << ee_addr_size) | index) << 16)
+			     | 0xffff, 3 + ee_addr_size + 16);
+}
+
+#ifdef UPDATE_SROM
+static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value)
+{
+	int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+	int i;
+	unsigned short newval;
+
+	udelay(10*1000); /* test-only */
+
+#ifdef DEBUG_SROM
+	printf("ee_addr_size=%d.\n", ee_addr_size);
+	printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index);
+#endif
+
+	/* Enable programming modes. */
+	do_eeprom_cmd(dev, ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size);
+
+	/* Do the actual write. */
+	do_eeprom_cmd(dev, ioaddr,
+		      (((SROM_WRITE_CMD<<ee_addr_size)|index) << 16) | new_value,
+		      3 + ee_addr_size + 16);
+
+	/* Poll for write finished. */
+	sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+	for (i = 0; i < 10000; i++)			/* Typical 2000 ticks */
+		if (getfrom_srom(dev, ioaddr) & EE_DATA_READ)
+			break;
+
+#ifdef DEBUG_SROM
+	printf(" Write finished after %d ticks.\n", i);
+#endif
+
+	/* Disable programming. */
+	do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size-4)), 3 + ee_addr_size);
+
+	/* And read the result. */
+	newval = do_eeprom_cmd(dev, ioaddr,
+			       (((SROM_READ_CMD<<ee_addr_size)|index) << 16)
+			       | 0xffff, 3 + ee_addr_size + 16);
+#ifdef DEBUG_SROM
+	printf("  New value at offset %d is %4.4x.\n", index, newval);
+#endif
+	return 1;
+}
+#endif
+
+static void read_hw_addr(struct eth_device *dev, bd_t *bis)
+{
+	u_short tmp, *p = (short *)(&dev->enetaddr[0]);
+	int i, j = 0;
+
+	for (i = 0; i < (ETH_ALEN >> 1); i++) {
+		tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i));
+		*p = le16_to_cpu(tmp);
+		j += *p++;
+	}
+
+	if ((j == 0) || (j == 0x2fffd)) {
+		memset (dev->enetaddr, 0, ETH_ALEN);
+#ifdef DEBUG
+		printf("Warning: can't read HW address from SROM.\n");
+#endif
+		goto Done;
+	}
+
+	return;
+
+Done:
+#ifdef UPDATE_SROM
+	update_srom(dev, bis);
+#endif
+	return;
+}
+
+#ifdef UPDATE_SROM
+static void update_srom(struct eth_device *dev, bd_t *bis)
+{
+	int i;
+	static unsigned short eeprom[0x40] = {
+		0x140b, 0x6610, 0x0000, 0x0000, 	/* 00 */
+		0x0000, 0x0000, 0x0000, 0x0000, 	/* 04 */
+		0x00a3, 0x0103, 0x0000, 0x0000,  	/* 08 */
+		0x0000, 0x1f00, 0x0000, 0x0000, 	/* 0c */
+		0x0108, 0x038d, 0x0000, 0x0000,  	/* 10 */
+		0xe078, 0x0001, 0x0040, 0x0018, 	/* 14 */
+		0x0000, 0x0000, 0x0000, 0x0000,  	/* 18 */
+		0x0000, 0x0000, 0x0000, 0x0000, 	/* 1c */
+		0x0000, 0x0000, 0x0000, 0x0000,  	/* 20 */
+		0x0000, 0x0000, 0x0000, 0x0000, 	/* 24 */
+		0x0000, 0x0000, 0x0000, 0x0000,  	/* 28 */
+		0x0000, 0x0000, 0x0000, 0x0000, 	/* 2c */
+		0x0000, 0x0000, 0x0000, 0x0000,  	/* 30 */
+		0x0000, 0x0000, 0x0000, 0x0000, 	/* 34 */
+		0x0000, 0x0000, 0x0000, 0x0000,  	/* 38 */
+		0x0000, 0x0000, 0x0000, 0x4e07,		/* 3c */
+	};
+
+	/* Ethernet Addr... */
+	eeprom[0x0a] = ((bis->bi_enetaddr[1] & 0xff) << 8) | (bis->bi_enetaddr[0] & 0xff);
+	eeprom[0x0b] = ((bis->bi_enetaddr[3] & 0xff) << 8) | (bis->bi_enetaddr[2] & 0xff);
+	eeprom[0x0c] = ((bis->bi_enetaddr[5] & 0xff) << 8) | (bis->bi_enetaddr[4] & 0xff);
+
+	for (i=0; i<0x40; i++)
+	{
+		write_srom(dev, DE4X5_APROM, i, eeprom[i]);
+	}
+}
+#endif
+
+#endif
diff --git a/drivers/i8042.c b/drivers/i8042.c
new file mode 100644
index 0000000..ce24fc9
--- /dev/null
+++ b/drivers/i8042.c
@@ -0,0 +1,655 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/* i8042.c - Intel 8042 keyboard driver routines */
+
+/* includes */
+
+#include <common.h>
+
+#ifdef CONFIG_I8042_KBD
+
+#include <i8042.h>
+
+/* defines */
+
+#ifdef CONFIG_CONSOLE_CURSOR
+extern void console_cursor (int state);
+static int blinkCount = CFG_CONSOLE_BLINK_COUNT;
+static int cursor_state = 0;
+#endif
+
+/* locals */
+
+static int  kbd_input    = -1;          /* no input yet */
+static int  kbd_mapping  = KBD_US;      /* default US keyboard */
+static int  kbd_flags    = NORMAL;      /* after reset */
+static int  kbd_state    = 0;           /* unshift code */
+
+static void kbd_conv_char (unsigned char scan_code);
+static void kbd_led_set (void);
+static void kbd_normal (unsigned char scan_code);
+static void kbd_shift (unsigned char scan_code);
+static void kbd_ctrl (unsigned char scan_code);
+static void kbd_num (unsigned char scan_code);
+static void kbd_caps (unsigned char scan_code);
+static void kbd_scroll (unsigned char scan_code);
+static void kbd_alt (unsigned char scan_code);
+static int  kbd_input_empty (void);
+static int  kbd_reset (void);
+
+static unsigned char kbd_fct_map [144] =
+    { /* kbd_fct_map table for scan code */
+    0,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  0- 7 */
+   AS,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  8- F */
+   AS,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 10-17 */
+   AS,   AS,   AS,   AS,   AS,   CN,   AS,   AS, /* scan 18-1F */
+   AS,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 20-27 */
+   AS,   AS,   SH,   AS,   AS,   AS,   AS,   AS, /* scan 28-2F */
+   AS,   AS,   AS,   AS,   AS,   AS,   SH,   AS, /* scan 30-37 */
+   AS,   AS,   CP,   0,    0,    0,    0,     0, /* scan 38-3F */
+    0,   0,    0,    0,    0,    NM,   ST,   ES, /* scan 40-47 */
+   ES,   ES,   ES,   ES,   ES,   ES,   ES,   ES, /* scan 48-4F */
+   ES,   ES,   ES,   ES,   0,    0,    AS,    0, /* scan 50-57 */
+    0,   0,    0,    0,    0,    0,    0,     0, /* scan 58-5F */
+    0,   0,    0,    0,    0,    0,    0,     0, /* scan 60-67 */
+    0,   0,    0,    0,    0,    0,    0,     0, /* scan 68-6F */
+   AS,   0,    0,    AS,   0,    0,    AS,    0, /* scan 70-77 */
+    0,   AS,   0,    0,    0,    AS,   0,     0, /* scan 78-7F */
+   AS,   CN,   AS,   AS,   AK,   ST,   EX,   EX, /* enhanced   */
+   AS,   EX,   EX,   AS,   EX,   AS,   EX,   EX  /* enhanced   */
+    };
+
+static unsigned char kbd_key_map [2][5][144] =
+    {
+    { /* US keyboard */
+    { /* unshift code */
+    0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6',    /* scan  0- 7 */
+  '7',   '8',   '9',   '0',   '-',   '=',  0x08,  '\t',    /* scan  8- F */
+  'q',   'w',   'e',   'r',   't',   'y',   'u',   'i',    /* scan 10-17 */
+  'o',   'p',   '[',   ']',  '\r',   CN,    'a',   's',    /* scan 18-1F */
+  'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';',    /* scan 20-27 */
+ '\'',   '`',   SH,   '\\',   'z',   'x',   'c',   'v',    /* scan 28-2F */
+  'b',   'n',   'm',   ',',   '.',   '/',   SH,    '*',    /* scan 30-37 */
+  ' ',   ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
+    0,     0,     0,     0,     0,   NM,    ST,    '7',    /* scan 40-47 */
+  '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',    /* scan 48-4F */
+  '2',   '3',   '0',   '.',     0,     0,     0,     0,    /* scan 50-57 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
+    0,   'D',   'C',     0,   'B',     0,    '@',  'P'     /* extended */
+    },
+    { /* shift code */
+    0,  0x1b,   '!',   '@',   '#',   '$',   '%',   '^',    /* scan  0- 7 */
+  '&',   '*',   '(',   ')',   '_',   '+',  0x08,  '\t',    /* scan  8- F */
+  'Q',   'W',   'E',   'R',   'T',   'Y',   'U',   'I',    /* scan 10-17 */
+  'O',   'P',   '{',   '}',  '\r',   CN,    'A',   'S',    /* scan 18-1F */
+  'D',   'F',   'G',   'H',   'J',   'K',   'L',   ':',    /* scan 20-27 */
+  '"',   '~',   SH,    '|',   'Z',   'X',   'C',   'V',    /* scan 28-2F */
+  'B',   'N',   'M',   '<',   '>',   '?',   SH,    '*',    /* scan 30-37 */
+  ' ',   ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
+    0,     0,     0,     0,     0,   NM,    ST,    '7',    /* scan 40-47 */
+  '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',    /* scan 48-4F */
+  '2',   '3',   '0',   '.',     0,     0,     0,     0,    /* scan 50-57 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
+    0,   'D',   'C',     0,   'B',     0,   '@',   'P'     /* extended */
+    },
+    { /* control code */
+ 0xff,  0x1b,  0xff,  0x00,  0xff,  0xff,  0xff,  0xff,    /* scan  0- 7 */
+ 0x1e,  0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  '\t',    /* scan  8- F */
+ 0x11,  0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09,    /* scan 10-17 */
+ 0x0f,  0x10,  0x1b,  0x1d,  '\r',   CN,   0x01,  0x13,    /* scan 18-1F */
+ 0x04,  0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff,    /* scan 20-27 */
+ 0xff,  0x1c,   SH,   0xff,  0x1a,  0x18,  0x03,  0x16,    /* scan 28-2F */
+ 0x02,  0x0e,  0x0d,  0xff,  0xff,  0xff,   SH,   0xff,    /* scan 30-37 */
+ 0xff,  0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 38-3F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,   NM,    ST,   0xff,    /* scan 40-47 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 48-4F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 50-57 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 58-5F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 60-67 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 68-6F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 70-77 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,  0xff,  0xff,    /* extended */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff     /* extended */
+    },
+    { /* non numeric code */
+    0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6',    /* scan  0- 7 */
+  '7',   '8',   '9',   '0',   '-',   '=',  0x08,  '\t',    /* scan  8- F */
+  'q',   'w',   'e',   'r',   't',   'y',   'u',   'i',    /* scan 10-17 */
+  'o',   'p',   '[',   ']',  '\r',   CN,    'a',   's',    /* scan 18-1F */
+  'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';',    /* scan 20-27 */
+ '\'',   '`',   SH,   '\\',   'z',   'x',   'c',   'v',    /* scan 28-2F */
+  'b',   'n',   'm',   ',',   '.',   '/',   SH,    '*',    /* scan 30-37 */
+  ' ',   ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
+    0,     0,     0,     0,     0,   NM,    ST,    'w',    /* scan 40-47 */
+  'x',   'y',   'l',   't',   'u',   'v',   'm',   'q',    /* scan 48-4F */
+  'r',   's',   'p',   'n',     0,     0,     0,     0,    /* scan 50-57 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
+    0,     0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
+    0,   'D',   'C',     0,   'B',     0,    '@',  'P'     /* extended */
+    },
+    { /* right alt mode - not used in US keyboard */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  0 - 7 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  8 - F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 10 -17 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 18 -1F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 20 -27 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 28 -2F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 30 -37 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38 -3F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 40 -47 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48 -4F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50 -57 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58 -5F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60 -67 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68 -6F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70 -77 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78 -7F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* extended    */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended    */
+    }
+    },
+    { /* german keyboard */
+    { /* unshift code */
+    0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
+  '7',   '8',   '9',   '0',  0xe1,  '\'',  0x08,  '\t', /* scan  8- F */
+  'q',   'w',   'e',   'r',   't',   'z',   'u',   'i', /* scan 10-17 */
+  'o',   'p',  0x81,   '+',  '\r',   CN,    'a',   's', /* scan 18-1F */
+  'd',   'f',   'g',   'h',   'j',   'k',   'l',  0x94, /* scan 20-27 */
+ 0x84,   '^',   SH,    '#',   'y',   'x',   'c',   'v', /* scan 28-2F */
+  'b',   'n',   'm',   ',',   '.',   '-',   SH,    '*', /* scan 30-37 */
+  ' ',   ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
+    0,     0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
+  '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
+  '2',   '3',   '0',   ',',     0,     0,   '<',     0, /* scan 50-57 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
+    0,   'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
+    },
+    { /* shift code */
+    0,  0x1b,   '!',   '"',  0x15,   '$',   '%',   '&', /* scan  0- 7 */
+  '/',   '(',   ')',   '=',   '?',   '`',  0x08,  '\t', /* scan  8- F */
+  'Q',   'W',   'E',   'R',   'T',   'Z',   'U',   'I', /* scan 10-17 */
+  'O',   'P',  0x9a,   '*',  '\r',   CN,    'A',   'S', /* scan 18-1F */
+  'D',   'F',   'G',   'H',   'J',   'K',   'L',  0x99, /* scan 20-27 */
+ 0x8e,  0xf8,   SH,   '\'',   'Y',   'X',   'C',   'V', /* scan 28-2F */
+  'B',   'N',   'M',   ';',   ':',   '_',   SH,    '*', /* scan 30-37 */
+  ' ',   ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
+    0,     0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
+  '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
+  '2',   '3',   '0',   ',',     0,     0,   '>',     0, /* scan 50-57 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
+    0,   'D',   'C',     0,   'B',     0,   '@',   'P'  /* extended */
+    },
+    { /* control code */
+ 0xff,  0x1b,  0xff,  0x00,  0xff,  0xff,  0xff,  0xff, /* scan  0- 7 */
+ 0x1e,  0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  '\t', /* scan  8- F */
+ 0x11,  0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09, /* scan 10-17 */
+ 0x0f,  0x10,  0x1b,  0x1d,  '\r',   CN,   0x01,  0x13, /* scan 18-1F */
+ 0x04,  0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff, /* scan 20-27 */
+ 0xff,  0x1c,   SH,   0xff,  0x1a,  0x18,  0x03,  0x16, /* scan 28-2F */
+ 0x02,  0x0e,  0x0d,  0xff,  0xff,  0xff,   SH,   0xff, /* scan 30-37 */
+ 0xff,  0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38-3F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,   NM,    ST,   0xff, /* scan 40-47 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48-4F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50-57 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58-5F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60-67 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68-6F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70-77 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,  0xff,  0xff, /* extended */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended */
+    },
+    { /* non numeric code */
+    0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
+  '7',   '8',   '9',   '0',  0xe1,  '\'',  0x08,  '\t', /* scan  8- F */
+  'q',   'w',   'e',   'r',   't',   'z',   'u',   'i', /* scan 10-17 */
+  'o',   'p',  0x81,   '+',  '\r',   CN,    'a',   's', /* scan 18-1F */
+  'd',   'f',   'g',   'h',   'j',   'k',   'l',  0x94, /* scan 20-27 */
+ 0x84,   '^',   SH,      0,   'y',   'x',   'c',   'v', /* scan 28-2F */
+  'b',   'n',   'm',   ',',   '.',   '-',   SH,    '*', /* scan 30-37 */
+  ' ',   ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
+    0,     0,     0,     0,     0,   NM,    ST,    'w', /* scan 40-47 */
+  'x',   'y',   'l',   't',   'u',   'v',   'm',   'q', /* scan 48-4F */
+  'r',   's',   'p',   'n',     0,     0,   '<',     0, /* scan 50-57 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
+    0,     0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
+  '\r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
+    0,   'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
+    },
+    { /* Right alt mode - is used in German keyboard */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  0 - 7 */
+  '{',   '[',   ']',   '}',  '\\',  0xff,  0xff,  0xff, /* scan  8 - F */
+  '@',  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 10 -17 */
+ 0xff,  0xff,  0xff,   '~',  0xff,  0xff,  0xff,  0xff, /* scan 18 -1F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 20 -27 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 28 -2F */
+ 0xff,  0xff,  0xe6,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 30 -37 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38 -3F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 40 -47 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48 -4F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,   '|',  0xff, /* scan 50 -57 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58 -5F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60 -67 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68 -6F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70 -77 */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78 -7F */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* extended    */
+ 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended    */
+    }
+    }
+    };
+
+static unsigned char ext_key_map [] =
+    {
+    0x1c,   /* keypad enter */
+    0x1d,   /* right control */
+    0x35,   /* keypad slash */
+    0x37,   /* print screen */
+    0x38,   /* right alt */
+    0x46,   /* break */
+    0x47,   /* editpad home */
+    0x48,   /* editpad up */
+    0x49,   /* editpad pgup */
+    0x4b,   /* editpad left */
+    0x4d,   /* editpad right */
+    0x4f,   /* editpad end */
+    0x50,   /* editpad dn */
+    0x51,   /* editpad pgdn */
+    0x52,   /* editpad ins */
+    0x53,   /* editpad del */
+    0x00    /* map end */
+    };
+
+/*******************************************************************************
+ *
+ * i8042_kbd_init - reset keyboard and init state flags
+ */
+int i8042_kbd_init (void)
+{
+    int keymap, try;
+    char *penv;
+
+    /* Init keyboard device (default US layout) */
+    keymap = KBD_US;
+    if ((penv = getenv ("keymap")) != NULL)
+    {
+        if (strncmp (penv, "de", 3) == 0)
+        keymap = KBD_GER;
+    }
+
+    for (try = 0; try < KBD_RESET_TRIES; try++)
+    {
+        if (kbd_reset() == 0)
+        {
+            kbd_mapping   = keymap;
+            kbd_flags     = NORMAL;
+            kbd_state     = 0;
+            kbd_led_set();
+            return 0;
+            }
+    }
+    return -1;
+}
+
+
+/*******************************************************************************
+ *
+ * i8042_tstc - test if keyboard input is available
+ *              option: cursor blinking if called in a loop
+ */
+int i8042_tstc (void)
+{
+    unsigned char scan_code = 0;
+
+#ifdef CONFIG_CONSOLE_CURSOR
+    if (--blinkCount == 0)
+    {
+        cursor_state ^= 1;
+        console_cursor (cursor_state);
+        blinkCount = CFG_CONSOLE_BLINK_COUNT;
+        udelay (10);
+    }
+#endif
+
+    if ((in8 (I8042_STATUS_REG) & 0x01) == 0)
+        return 0;
+    else
+    {
+        scan_code = in8 (I8042_DATA_REG);
+        if (scan_code == 0xfa)
+            return 0;
+
+        kbd_conv_char(scan_code);
+
+        if (kbd_input != -1)
+            return 1;
+    }
+    return 0;
+}
+
+
+/*******************************************************************************
+ *
+ * i8042_getc - wait till keyboard input is available
+ *              option: turn on/off cursor while waiting
+ */
+int i8042_getc (void)
+{
+    int ret_chr;
+    unsigned char scan_code;
+
+    while (kbd_input == -1)
+    {
+        while ((in8 (I8042_STATUS_REG) & 0x01) == 0)
+        {
+#ifdef CONFIG_CONSOLE_CURSOR
+            if (--blinkCount==0)
+            {
+                cursor_state ^= 1;
+                console_cursor (cursor_state);
+                blinkCount = CFG_CONSOLE_BLINK_COUNT;
+            }
+            udelay (10);
+#endif
+        }
+
+        scan_code = in8 (I8042_DATA_REG);
+
+        if (scan_code != 0xfa)
+        kbd_conv_char (scan_code);
+    }
+    ret_chr = kbd_input;
+    kbd_input = -1;
+    return ret_chr;
+}
+
+
+/******************************************************************************/
+
+static void kbd_conv_char (unsigned char scan_code)
+{
+    if (scan_code == 0xe0)
+    {
+        kbd_flags |= EXT;
+        return;
+    }
+
+    /* if high bit of scan_code, set break flag */
+    if (scan_code & 0x80)
+        kbd_flags |=  BRK;
+    else
+        kbd_flags &= ~BRK;
+
+    if ((scan_code == 0xe1) || (kbd_flags & E1))
+    {
+        if (scan_code == 0xe1)
+        {
+            kbd_flags ^= BRK;     /* reset the break flag */
+            kbd_flags ^= E1;      /* bitwise EXOR with E1 flag */
+        }
+        return;
+    }
+
+    scan_code &= 0x7f;
+
+    if (kbd_flags & EXT)
+    {
+        int i;
+
+        kbd_flags ^= EXT;
+        for (i=0; ext_key_map[i]; i++)
+        {
+            if (ext_key_map[i] == scan_code)
+            {
+                scan_code = 0x80 + i;
+                break;
+            }
+        }
+        /* not found ? */
+        if (!ext_key_map[i])
+            return;
+    }
+
+    switch (kbd_fct_map [scan_code])
+    {
+    case AS:  kbd_normal (scan_code);
+        break;
+    case SH:  kbd_shift (scan_code);
+        break;
+    case CN:  kbd_ctrl (scan_code);
+        break;
+    case NM:  kbd_num (scan_code);
+        break;
+    case CP:  kbd_caps (scan_code);
+        break;
+    case ST:  kbd_scroll (scan_code);
+        break;
+    case AK:  kbd_alt (scan_code);
+        break;
+    }
+    return;
+}
+
+
+/******************************************************************************/
+
+static void kbd_normal (unsigned char scan_code)
+{
+    unsigned char chr;
+
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+       chr = kbd_key_map [kbd_mapping][kbd_state][scan_code];
+       if ((chr == 0xff) || (chr == 0x00))
+        {
+            return;
+        }
+
+        /* if caps lock convert upper to lower */
+        if (((kbd_flags & CAPS) == CAPS) && (chr >= 'a' && chr <= 'z'))
+       {
+           chr -= 'a' - 'A';
+       }
+       kbd_input = chr;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_shift (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == BRK)
+    {
+        kbd_state = AS;
+        kbd_flags &= (~SHIFT);
+    }
+    else
+    {
+       kbd_state = SH;
+       kbd_flags |= SHIFT;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_ctrl (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == BRK)
+    {
+       kbd_state = AS;
+       kbd_flags &= (~CTRL);
+    }
+    else
+    {
+       kbd_state = CN;
+       kbd_flags |= CTRL;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_caps (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+       kbd_flags ^= CAPS;
+       kbd_led_set ();            /* update keyboard LED */
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_num (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+       kbd_flags ^= NUM;
+       kbd_state = (kbd_flags & NUM) ? AS : NM;
+       kbd_led_set ();            /* update keyboard LED */
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_scroll (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+        kbd_flags ^= STP;
+        kbd_led_set ();            /* update keyboard LED */
+        if (kbd_flags & STP)
+            kbd_input = 0x13;
+        else
+            kbd_input = 0x11;
+    }
+}
+
+/******************************************************************************/
+
+static void kbd_alt (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == BRK)
+    {
+        kbd_state = AS;
+        kbd_flags &= (~ALT);
+    }
+    else
+    {
+        kbd_state = AK;
+        kbd_flags &= ALT;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_led_set (void)
+{
+    kbd_input_empty();
+    out8 (I8042_DATA_REG, 0xed);        /* SET LED command */
+    kbd_input_empty();
+    out8 (I8042_DATA_REG, (kbd_flags & 0x7));    /* LED bits only */
+}
+
+
+/******************************************************************************/
+
+static int kbd_input_empty (void)
+{
+    int kbdTimeout = KBD_TIMEOUT;
+
+    /* wait for input buf empty */
+    while ((in8 (I8042_STATUS_REG) & 0x02) && kbdTimeout--)
+        udelay(1000);
+
+    return kbdTimeout;
+}
+
+/******************************************************************************/
+
+static int kbd_reset (void)
+{
+    if (kbd_input_empty() == 0)
+        return -1;
+
+    out8 (I8042_DATA_REG, 0xff);
+
+    udelay(250000);
+
+    if (kbd_input_empty() == 0)
+        return -1;
+
+    out8 (I8042_DATA_REG, 0x60);
+
+    if (kbd_input_empty() == 0)
+        return -1;
+
+    out8 (I8042_DATA_REG, 0x45);
+
+
+    if (kbd_input_empty() == 0)
+        return -1;
+
+    out8 (I8042_COMMAND_REG, 0xae);
+
+    if (kbd_input_empty() == 0)
+        return -1;
+
+    return 0;
+}
+
+#endif /* CONFIG_I8042_KBD */
diff --git a/drivers/ns87308.c b/drivers/ns87308.c
new file mode 100644
index 0000000..cf4d359
--- /dev/null
+++ b/drivers/ns87308.c
@@ -0,0 +1,121 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.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
+ */
+
+#include <config.h>
+
+#ifdef CFG_NS87308
+
+#include <ns87308.h>
+
+void initialise_ns87308 (void)
+{
+#ifdef CFG_NS87308_PS2MOD
+	unsigned char data;
+
+	/*
+	 * Switch floppy drive to PS/2 mode.
+	 */
+	read_pnp_config(SUPOERIO_CONF1, &data);
+	data &= 0xFB;
+	write_pnp_config(SUPOERIO_CONF1, data);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_KBC1)
+	PNP_SET_DEVICE_BASE(LDEV_KBC1, CFG_NS87308_KBC1_BASE);
+	write_pnp_config(LUN_CONFIG_REG, 0);
+	write_pnp_config(CBASE_HIGH, 0x00);
+	write_pnp_config(CBASE_LOW, 0x64);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_MOUSE)
+	PNP_ACTIVATE_DEVICE(LDEV_MOUSE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_RTC_APC)
+	PNP_SET_DEVICE_BASE(LDEV_RTC_APC, CFG_NS87308_RTC_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_FDC)
+	PNP_SET_DEVICE_BASE(LDEV_FDC, CFG_NS87308_FDC_BASE);
+	write_pnp_config(LUN_CONFIG_REG, 0x40);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_RARP)
+	PNP_SET_DEVICE_BASE(LDEV_PARP, CFG_NS87308_LPT_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_UART1)
+	PNP_SET_DEVICE_BASE(LDEV_UART1, CFG_NS87308_UART1_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_UART2)
+	PNP_SET_DEVICE_BASE(LDEV_UART2, CFG_NS87308_UART2_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_GPIO)
+	PNP_SET_DEVICE_BASE(LDEV_GPIO, CFG_NS87308_GPIO_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_POWRMAN)
+#ifndef CFG_NS87308_PWMAN_BASE
+	PNP_ACTIVATE_DEVICE(LDEV_POWRMAN);
+#else
+	PNP_SET_DEVICE_BASE(LDEV_POWRMAN, CFG_NS87308_PWMAN_BASE);
+
+	/*
+	 * Enable all units
+	 */
+	write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER1, 0x7d);
+	write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER2, 0x87);
+
+#ifdef CFG_NS87308_PMC1
+	write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC1, CFG_NS87308_PMC1);
+#endif
+
+#ifdef CFG_NS87308_PMC2
+	write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC2, CFG_NS87308_PMC2);
+#endif
+
+#ifdef CFG_NS87308_PMC3
+	write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC3, CFG_NS87308_PMC3);
+#endif
+#endif
+#endif
+
+#ifdef CFG_NS87308_CS0_BASE
+	PNP_PGCS_CSLINE_BASE(0, CFG_NS87308_CS0_BASE);
+	PNP_PGCS_CSLINE_CONF(0, CFG_NS87308_CS0_CONF);
+#endif
+
+#ifdef CFG_NS87308_CS1_BASE
+	PNP_PGCS_CSLINE_BASE(1, CFG_NS87308_CS1_BASE);
+	PNP_PGCS_CSLINE_CONF(1, CFG_NS87308_CS1_CONF);
+#endif
+
+#ifdef CFG_NS87308_CS2_BASE
+	PNP_PGCS_CSLINE_BASE(2, CFG_NS87308_CS2_BASE);
+	PNP_PGCS_CSLINE_CONF(2, CFG_NS87308_CS2_CONF);
+#endif
+}
+
+#endif
diff --git a/drivers/pci.c b/drivers/pci.c
new file mode 100644
index 0000000..52584ce
--- /dev/null
+++ b/drivers/pci.c
@@ -0,0 +1,503 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * 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
+ */
+
+/*
+ * PCI routines
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <command.h>
+#include <cmd_boot.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+/*
+ *
+ */
+
+#define PCI_HOSE_OP(rw, size, type)						\
+int pci_hose_##rw##_config_##size(struct pci_controller *hose, 			\
+				  pci_dev_t dev, 				\
+				  int offset, type value)			\
+{										\
+	return hose->rw##_##size(hose, dev, offset, value);			\
+}
+
+PCI_HOSE_OP(read, byte, u8 *)
+PCI_HOSE_OP(read, word, u16 *)
+PCI_HOSE_OP(read, dword, u32 *)
+PCI_HOSE_OP(write, byte, u8)
+PCI_HOSE_OP(write, word, u16)
+PCI_HOSE_OP(write, dword, u32)
+
+#define PCI_OP(rw, size, type, error_code)					\
+int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)		\
+{										\
+	struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));		\
+										\
+	if (!hose)								\
+	{									\
+		error_code;							\
+		return -1;							\
+	}									\
+										\
+	return pci_hose_##rw##_config_##size(hose, dev, offset, value);		\
+}
+
+PCI_OP(read, byte, u8 *, *value = 0xff)
+PCI_OP(read, word, u16 *, *value = 0xffff)
+PCI_OP(read, dword, u32 *, *value = 0xffffffff)
+PCI_OP(write, byte, u8, )
+PCI_OP(write, word, u16, )
+PCI_OP(write, dword, u32, )
+
+#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)				\
+int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,	\
+					pci_dev_t dev, 				\
+					int offset, type val)			\
+{										\
+	u32 val32;								\
+										\
+	if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)	\
+		return -1;							\
+										\
+	*val = (val32 >> ((offset & (int)off_mask) * 8));			\
+										\
+	return 0;								\
+}
+
+#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)			\
+int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,	\
+					     pci_dev_t dev, 			\
+					     int offset, type val)		\
+{										\
+	u32 val32, mask, ldata;							\
+										\
+	if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)	\
+		return -1;							\
+										\
+	mask = val_mask;							\
+	ldata = (((unsigned long)val) & mask) << ((offset & (int)off_mask) * 8);\
+	mask <<= ((mask & (int)off_mask) * 8);					\
+	val32 = (val32 & ~mask) | ldata;					\
+										\
+	if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)	\
+		return -1;							\
+										\
+	return 0;								\
+}
+
+PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
+PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
+PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
+PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
+
+/*
+ *
+ */
+
+static struct pci_controller* hose_head = NULL;
+
+void pci_register_hose(struct pci_controller* hose)
+{
+	struct pci_controller **phose = &hose_head;
+
+	while(*phose)
+		phose = &(*phose)->next;
+
+	hose->next = NULL;
+
+	*phose = hose;
+}
+
+struct pci_controller* pci_bus_to_hose(int bus)
+{
+	struct pci_controller *hose;
+
+	for (hose = hose_head; hose; hose = hose->next)
+		if (bus >= hose->first_busno &&
+		    bus <= hose->last_busno)
+			return hose;
+
+	return NULL;
+}
+
+pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
+{
+	struct pci_controller * hose;
+	u16 vendor, device;
+	u8 header_type;
+	pci_dev_t bdf;
+	int i, bus, found_multi = 0;
+
+	for (hose = hose_head; hose; hose = hose->next)
+	{
+#if CFG_SCSI_SCAN_BUS_REVERSE
+		for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
+#else
+		for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
+#endif
+			for (bdf = PCI_BDF(bus,0,0);
+#ifdef CONFIG_ELPPC
+			     bdf < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+#else
+			     bdf < PCI_BDF(bus+1,0,0);
+#endif
+			     bdf += PCI_BDF(0,0,1))
+			{
+				if (!PCI_FUNC(bdf))
+				{
+					pci_read_config_byte(bdf,
+							     PCI_HEADER_TYPE,
+							     &header_type);
+
+					found_multi = header_type & 0x80;
+				}
+				else
+				{
+					if (!found_multi)
+						continue;
+				}
+
+				pci_read_config_word(bdf,
+						     PCI_VENDOR_ID,
+						     &vendor);
+				pci_read_config_word(bdf,
+						     PCI_DEVICE_ID,
+						     &device);
+
+				for (i=0; ids[i].vendor != 0; i++)
+					if (vendor == ids[i].vendor &&
+					    device == ids[i].device)
+					{
+						if (index <= 0)
+							return bdf;
+
+						index--;
+					}
+			}
+	}
+
+	return (-1);
+}
+
+pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
+{
+	static struct pci_device_id ids[2] = {{}, {0, 0}};
+
+	ids[0].vendor = vendor;
+	ids[0].device = device;
+
+	return pci_find_devices(ids, index);
+}
+
+/*
+ *
+ */
+
+unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
+				   unsigned long phys_addr,
+				   unsigned long flags)
+{
+	struct pci_region *res;
+	unsigned long bus_addr;
+	int i;
+
+	if (!hose)
+	{
+		printf("pci_hose_phys_to_bus: %s\n", "invalid hose");
+		goto Done;
+	}
+
+	for (i=0; i<hose->region_count; i++)
+	{
+		res = &hose->regions[i];
+
+		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+			continue;
+
+		bus_addr = phys_addr - res->phys_start + res->bus_start;
+
+		if (bus_addr >= res->bus_start &&
+		    bus_addr <  res->bus_start + res->size)
+		{
+			return bus_addr;
+		}
+	}
+
+	printf("pci_hose_phys_to_bus: %s\n", "invalid physical address");
+
+ Done:
+	return 0;
+}
+
+unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
+				   unsigned long bus_addr,
+				   unsigned long flags)
+{
+	struct pci_region *res;
+	int i;
+
+	if (!hose)
+	{
+		printf("pci_hose_bus_to_phys: %s\n", "invalid hose");
+		goto Done;
+	}
+
+	for (i=0; i<hose->region_count; i++)
+	{
+		res = &hose->regions[i];
+
+		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+			continue;
+
+		if (bus_addr >= res->bus_start &&
+		    bus_addr <  res->bus_start + res->size)
+		{
+			return bus_addr - res->bus_start + res->phys_start;
+		}
+	}
+
+	printf("pci_hose_bus_to_phys: %s\n", "invalid physical address");
+
+ Done:
+	return 0;
+}
+
+/*
+ *
+ */
+
+int pci_hose_config_device(struct pci_controller *hose,
+			   pci_dev_t dev,
+			   unsigned long io,
+			   unsigned long mem,
+			   unsigned long command)
+{
+	unsigned int bar_response, bar_size, bar_value, old_command;
+	unsigned char pin;
+	int bar, found_mem64;
+
+	DEBUGF("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n", io, mem, command);
+
+	pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0);
+
+	for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4)
+	{
+		pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
+		pci_hose_read_config_dword(hose, dev, bar, &bar_response);
+
+		if (!bar_response)
+			continue;
+
+		found_mem64 = 0;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
+			bar_value = io;
+
+			io = ((io - 1) | (bar_size - 1)) + 1;
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			     PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+			bar_value = mem;
+
+			mem = ((mem - 1) | (bar_size - 1)) + 1;
+		}
+
+		/* Write it out and update our limit */
+		pci_hose_write_config_dword(hose, dev, bar, bar_value);
+
+		if (found_mem64)
+		{
+			bar += 4;
+			pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
+		}
+	}
+
+	/* Configure Cache Line Size Register */
+	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+	/* Configure Latency Timer */
+	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+
+	/* Disable interrupt line, if device says it wants to use interrupts */
+	pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
+	if (pin != 0)
+	{
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff);
+	}
+
+	pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command);
+	pci_hose_write_config_dword(hose, dev, PCI_COMMAND,
+				    (old_command & 0xffff0000) | command );
+
+	return 0;
+}
+
+/*
+ *
+ */
+
+struct pci_config_table *pci_find_config(struct pci_controller *hose,
+					 unsigned short class,
+					 unsigned int vendor,
+					 unsigned int device,
+					 unsigned int bus,
+					 unsigned int dev,
+					 unsigned int func)
+{
+	struct pci_config_table *table;
+
+	for (table = hose->config_table; table && table->vendor; table++)
+	{
+		if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
+		    (table->device == PCI_ANY_ID || table->device == device) &&
+		    (table->class  == PCI_ANY_ID || table->class  == class)  &&
+		    (table->bus    == PCI_ANY_ID || table->bus    == bus)    &&
+		    (table->dev    == PCI_ANY_ID || table->dev    == dev)    &&
+		    (table->func   == PCI_ANY_ID || table->func   == func))
+		{
+			return table;
+		}
+	}
+
+	return NULL;
+}
+
+void pci_cfgfunc_config_device(struct pci_controller *hose,
+			       pci_dev_t dev,
+			       struct pci_config_table *entry)
+{
+	pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], entry->priv[2]);
+}
+
+void pci_cfgfunc_do_nothing(struct pci_controller *hose,
+			    pci_dev_t dev, struct pci_config_table *entry)
+{
+}
+
+/*
+ *
+ */
+
+extern void pciauto_config_init(struct pci_controller *hose);
+extern void pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
+
+int pci_hose_scan_bus(struct pci_controller *hose, int bus)
+{
+	unsigned int sub_bus, found_multi=0;
+	unsigned short vendor, device, class;
+	unsigned char header_type;
+	struct pci_config_table *cfg;
+	pci_dev_t dev;
+
+	sub_bus = bus;
+
+	for (dev =  PCI_BDF(bus,0,0);
+	     dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+	     dev += PCI_BDF(0,0,1))
+	{
+#ifndef CONFIG_405GP /* don't skip host bridge on ppc405gp */
+		/* Skip our host bridge */
+		if ( dev == PCI_BDF(hose->first_busno,0,0) )
+			continue;
+#endif
+
+		if (PCI_FUNC(dev) && !found_multi)
+			continue;
+
+		pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
+
+		pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
+
+		if (vendor != 0xffff && vendor != 0x0000)
+		{
+
+			if (!PCI_FUNC(dev))
+				found_multi = header_type & 0x80;
+
+			DEBUGF("PCI Scan: Found Bus %d, Device %d, Function %d\n",
+			    PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) );
+
+			pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
+			pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+
+			cfg = pci_find_config(hose, class, vendor, device,
+					      PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
+			if (cfg)
+				cfg->config_device(hose, dev, cfg);
+#ifdef CONFIG_PCI_PNP
+			else
+				pciauto_config_device(hose, dev);
+#endif
+			if (hose->fixup_irq)
+				hose->fixup_irq(hose, dev);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+			/* Skip our host bridge */
+			if ( dev != PCI_BDF(hose->first_busno,0,0) ) {
+			    unsigned char int_line;
+
+			    pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_LINE,
+						      &int_line);
+			    printf("        %02x  %02x  %04x  %04x  %04x  %02x\n",
+				   PCI_BUS(dev), PCI_DEV(dev), vendor, device, class,
+				   int_line);
+			}
+#endif
+		}
+	}
+
+	return sub_bus;
+}
+
+int pci_hose_scan(struct pci_controller *hose)
+{
+#ifdef CONFIG_PCI_PNP
+	pciauto_config_init(hose);
+#endif
+	return pci_hose_scan_bus(hose, hose->first_busno);
+}
+
+#endif /* CONFIG_PCI */
diff --git a/drivers/pci_auto.c b/drivers/pci_auto.c
new file mode 100644
index 0000000..f665ee6
--- /dev/null
+++ b/drivers/pci_auto.c
@@ -0,0 +1,319 @@
+/*
+ * arch/ppc/kernel/pci_auto.c
+ *
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ *
+ * 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.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <pci.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+#define	PCIAUTO_IDE_MODE_MASK		0x05
+
+/*
+ *
+ */
+
+void pciauto_region_init(struct pci_region* res)
+{
+	res->bus_lower = res->bus_start;
+}
+
+void pciauto_region_align(struct pci_region *res, unsigned long size)
+{
+	res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1;
+}
+
+int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar)
+{
+	unsigned long addr;
+
+	if (!res)
+	{
+		DEBUGF("No resource");
+		goto error;
+	}
+
+	addr = ((res->bus_lower - 1) | (size - 1)) + 1;
+
+	if (addr - res->bus_start + size > res->size)
+	{
+		DEBUGF("No room in resource");
+		goto error;
+	}
+
+	res->bus_lower = addr + size;
+
+	DEBUGF("address=0x%lx", addr);
+
+	*bar = addr;
+	return 0;
+
+ error:
+	*bar = 0xffffffff;
+	return -1;
+}
+
+/*
+ *
+ */
+
+void pciauto_setup_device(struct pci_controller *hose,
+			  pci_dev_t dev, int bars_num,
+			  struct pci_region *mem,
+			  struct pci_region *io)
+{
+	unsigned int bar_value, bar_response, bar_size;
+	unsigned int cmdstat = 0;
+	struct pci_region *bar_res;
+	int bar, bar_nr = 0;
+	int found_mem64 = 0;
+
+	pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+	cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER;
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4)
+	{
+		/* Tickle the BAR and get the response */
+		pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
+		pci_hose_read_config_dword(hose, dev, bar, &bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		found_mem64 = 0;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
+			bar_res = io;
+
+			DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr, bar_size);
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			     PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+			bar_res = mem;
+
+			DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
+		}
+
+		if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0)
+		{
+			/* Write it out and update our limit */
+			pci_hose_write_config_dword(hose, dev, bar, bar_value);
+
+			/*
+			 * If we are a 64-bit decoder then increment to the
+			 * upper 32 bits of the bar and force it to locate
+			 * in the lower 4GB of memory.
+			 */
+			if (found_mem64)
+			{
+				bar += 4;
+				pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
+			}
+
+			cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
+				PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
+		}
+
+		DEBUGF("\n");
+
+		bar_nr++;
+	}
+
+	pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
+	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+}
+
+static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+					 pci_dev_t dev, int sub_bus)
+{
+	struct pci_region *pci_mem = hose->pci_mem;
+	struct pci_region *pci_io = hose->pci_io;
+	unsigned int cmdstat;
+
+	pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+
+	/* Configure bus number registers */
+	pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev));
+	pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus + 1);
+	pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
+
+	if (pci_mem)
+	{
+		/* Round memory allocator to 1MB boundary */
+		pciauto_region_align(pci_mem, 0x100000);
+
+		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+		pci_hose_write_config_word(hose, dev, PCI_MEMORY_BASE,
+					(pci_mem->bus_lower & 0xfff00000) >> 16);
+
+		cmdstat |= PCI_COMMAND_MEMORY;
+	}
+
+	if (pci_io)
+	{
+		/* Round I/O allocator to 4KB boundary */
+		pciauto_region_align(pci_io, 0x1000);
+
+		pci_hose_write_config_byte(hose, dev, PCI_IO_BASE,
+					(pci_io->bus_lower & 0x0000f000) >> 8);
+		pci_hose_write_config_word(hose, dev, PCI_IO_BASE_UPPER16,
+					(pci_io->bus_lower & 0xffff0000) >> 16);
+
+		cmdstat |= PCI_COMMAND_IO;
+	}
+
+	/* We don't support prefetchable memory for now, so disable */
+	pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
+	pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
+}
+
+static void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+					  pci_dev_t dev, int sub_bus)
+{
+	struct pci_region *pci_mem = hose->pci_mem;
+	struct pci_region *pci_io = hose->pci_io;
+
+	/* Configure bus number registers */
+	pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, sub_bus);
+
+	if (pci_mem)
+	{
+		/* Round memory allocator to 1MB boundary */
+		pciauto_region_align(pci_mem, 0x100000);
+
+		pci_hose_write_config_word(hose, dev, PCI_MEMORY_LIMIT,
+					(pci_mem->bus_lower-1) >> 16);
+	}
+
+	if (pci_io)
+	{
+		/* Round I/O allocator to 4KB boundary */
+		pciauto_region_align(pci_io, 0x1000);
+
+		pci_hose_write_config_byte(hose, dev, PCI_IO_LIMIT,
+					((pci_io->bus_lower-1) & 0x0000f000) >> 8);
+		pci_hose_write_config_word(hose, dev, PCI_IO_LIMIT_UPPER16,
+					((pci_io->bus_lower-1) & 0xffff0000) >> 16);
+	}
+}
+
+/*
+ *
+ */
+
+void pciauto_config_init(struct pci_controller *hose)
+{
+	int i;
+
+	hose->pci_io = hose->pci_mem = NULL;
+
+	for (i=0; i<hose->region_count; i++)
+	{
+		switch(hose->regions[i].flags)
+		{
+		case PCI_REGION_IO:
+			if (!hose->pci_io ||
+			    hose->pci_io->size < hose->regions[i].size)
+				hose->pci_io = hose->regions + i;
+			break;
+		case PCI_REGION_MEM:
+			if (!hose->pci_mem ||
+			    hose->pci_mem->size < hose->regions[i].size)
+				hose->pci_mem = hose->regions + i;
+			break;
+		}
+	}
+
+
+
+	if (hose->pci_mem)
+	{
+		pciauto_region_init(hose->pci_mem);
+
+		DEBUGF("PCI Autoconfig: Memory region: [%lx-%lx]\n",
+		    hose->pci_mem->bus_start,
+		    hose->pci_mem->bus_start + hose->pci_mem->size - 1);
+	}
+
+	if (hose->pci_io)
+	{
+		pciauto_region_init(hose->pci_io);
+
+		DEBUGF("PCI Autoconfig: I/O region: [%lx-%lx]\n",
+		    hose->pci_io->bus_start,
+		    hose->pci_io->bus_start + hose->pci_io->size - 1);
+	}
+}
+
+void pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
+{
+	unsigned int sub_bus;
+	unsigned short class;
+	unsigned char prg_iface;
+
+	pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+
+	switch(class)
+	{
+	case PCI_CLASS_BRIDGE_PCI:
+		pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io);
+
+		DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
+
+		pciauto_prescan_setup_bridge(hose, dev, PCI_BUS(dev));
+
+		sub_bus = pci_hose_scan_bus(hose, PCI_BUS(dev)+1);
+
+		pciauto_postscan_setup_bridge(hose, dev, sub_bus);
+		break;
+
+	case PCI_CLASS_STORAGE_IDE:
+		pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prg_iface);
+		if (!(prg_iface & PCIAUTO_IDE_MODE_MASK))
+			{
+				DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+				return;
+			}
+
+		pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+		break;
+
+	default:
+		pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+		break;
+	}
+}
+
+#endif /* CONFIG_PCI */
diff --git a/drivers/pcnet.c b/drivers/pcnet.c
new file mode 100644
index 0000000..f69cd2c
--- /dev/null
+++ b/drivers/pcnet.c
@@ -0,0 +1,526 @@
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de.
+ *
+ * This driver for AMD PCnet network controllers is derived from the
+ * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer.
+ *
+ * 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 <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if 0
+#define	PCNET_DEBUG_LEVEL	0 /* 0=off, 1=init, 2=rx/tx */
+#endif
+
+#if PCNET_DEBUG_LEVEL > 0
+#define	DEBUG1(fmt,args...)	printf (fmt ,##args)
+#if PCNET_DEBUG_LEVEL > 1
+#define	DEBUG2(fmt,args...)	printf (fmt ,##args)
+#else
+#define DEBUG2(fmt,args...)
+#endif
+#else
+#define DEBUG1(fmt,args...)
+#define DEBUG2(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+    && defined(CONFIG_PCNET)
+
+#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975)
+#error "Macro for PCnet chip version is not defined!"
+#endif
+
+/*
+ * Set the number of Tx and Rx buffers, using Log_2(# buffers).
+ * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
+ * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
+ */
+#define PCNET_LOG_TX_BUFFERS	0
+#define PCNET_LOG_RX_BUFFERS	2
+
+#define TX_RING_SIZE		(1 << (PCNET_LOG_TX_BUFFERS))
+#define TX_RING_LEN_BITS	((PCNET_LOG_TX_BUFFERS) << 12)
+
+#define RX_RING_SIZE		(1 << (PCNET_LOG_RX_BUFFERS))
+#define RX_RING_LEN_BITS	((PCNET_LOG_RX_BUFFERS) << 4)
+
+#define PKT_BUF_SZ		1544
+
+/* The PCNET Rx and Tx ring descriptors. */
+struct pcnet_rx_head {
+    u32 base;
+    s16 buf_length;
+    s16 status;
+    u32 msg_length;
+    u32 reserved;
+};
+
+struct pcnet_tx_head {
+    u32 base;
+    s16 length;
+    s16 status;
+    u32 misc;
+    u32 reserved;
+};
+
+/* The PCNET 32-Bit initialization block, described in databook. */
+struct pcnet_init_block {
+    u16 mode;
+    u16 tlen_rlen;
+    u8	phys_addr[6];
+    u16 reserved;
+    u32 filter[2];
+    /* Receive and transmit ring base, along with extra bits. */
+    u32 rx_ring;
+    u32 tx_ring;
+    u32 reserved2;
+};
+
+typedef struct pcnet_priv {
+    struct pcnet_rx_head    rx_ring[RX_RING_SIZE];
+    struct pcnet_tx_head    tx_ring[TX_RING_SIZE];
+    struct pcnet_init_block init_block;
+    /* Receive Buffer space */
+    unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4];
+    int cur_rx;
+    int cur_tx;
+} pcnet_priv_t;
+
+static pcnet_priv_t *lp;
+
+/* Offsets from base I/O address for WIO mode */
+#define PCNET_RDP		0x10
+#define PCNET_RAP		0x12
+#define PCNET_RESET		0x14
+#define PCNET_BDP		0x16
+
+static u16 pcnet_read_csr (struct eth_device *dev, int index)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    return inw (dev->iobase+PCNET_RDP);
+}
+
+static void pcnet_write_csr (struct eth_device *dev, int index, u16 val)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    outw (val, dev->iobase+PCNET_RDP);
+}
+
+static u16 pcnet_read_bcr (struct eth_device *dev, int index)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    return inw (dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    outw (val, dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_reset (struct eth_device *dev)
+{
+    inw (dev->iobase+PCNET_RESET);
+}
+
+static int pcnet_check (struct eth_device *dev)
+{
+    outw (88, dev->iobase+PCNET_RAP);
+    return (inw (dev->iobase+PCNET_RAP) == 88);
+}
+
+static int  pcnet_init( struct eth_device* dev, bd_t *bis);
+static int  pcnet_send (struct eth_device* dev, volatile void *packet,
+			int length);
+static int  pcnet_recv (struct eth_device* dev);
+static void pcnet_halt (struct eth_device* dev);
+static int  pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_num);
+
+#define PCI_TO_MEM(d,a) pci_phys_to_mem((pci_dev_t)d->priv, (u_long)(a))
+#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))
+
+static struct pci_device_id supported[] = {
+	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+	{ }
+};
+
+
+int pcnet_initialize(bd_t *bis)
+{
+    pci_dev_t devbusfn;
+    struct eth_device* dev;
+    u16 command, status;
+    int dev_nr = 0;
+
+    DEBUG1("\npcnet_initialize...\n");
+
+    for (dev_nr = 0; ; dev_nr++) {
+
+	/*
+	 * Find the PCnet PCI device(s).
+	 */
+	if ((devbusfn = pci_find_devices(supported, dev_nr)) < 0) {
+	    break;
+	}
+
+	/*
+	 * Allocate and pre-fill the device structure.
+	 */
+	dev = (struct eth_device*) malloc(sizeof *dev);
+	dev->priv = (void *)devbusfn;
+	sprintf(dev->name, "pcnet#%d", dev_nr);
+
+	/*
+	 * Setup the PCI device.
+	 */
+	pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &dev->iobase);
+	dev->iobase &= ~0xf;
+
+	DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ",
+	       dev->name, devbusfn, dev->iobase);
+
+	command = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
+	pci_write_config_word(devbusfn, PCI_COMMAND, command);
+	pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+	if ((status & command) != command) {
+	    printf("%s: Couldn't enable IO access or Bus Mastering\n",
+		   dev->name);
+	    free(dev);
+	    continue;
+	}
+
+	pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);
+
+	/*
+	 * Probe the PCnet chip.
+	 */
+	if (pcnet_probe(dev, bis, dev_nr) < 0) {
+	    free(dev);
+	    continue;
+	}
+
+	/*
+	 * Setup device structure and register the driver.
+	 */
+	dev->init   = pcnet_init;
+	dev->halt   = pcnet_halt;
+	dev->send   = pcnet_send;
+	dev->recv   = pcnet_recv;
+
+	eth_register(dev);
+    }
+
+    udelay(10 * 1000);
+
+    return dev_nr;
+}
+
+static int pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_nr)
+{
+    int chip_version;
+    char *chipname;
+#ifdef PCNET_HAS_PROM
+    int i;
+#endif
+
+    /* Reset the PCnet controller */
+    pcnet_reset(dev);
+
+    /* Check if register access is working */
+    if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) {
+	printf("%s: CSR register access check failed\n", dev->name);
+	return -1;
+    }
+
+    /* Identify the chip */
+    chip_version = pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev,89) << 16);
+    if ((chip_version & 0xfff) != 0x003)
+       return -1;
+    chip_version = (chip_version >> 12) & 0xffff;
+    switch (chip_version) {
+#ifdef CONFIG_PCNET_79C973
+    case 0x2625:
+	chipname = "PCnet/FAST III 79C973"; /* PCI */
+	break;
+#endif
+#ifdef CONFIG_PCNET_79C975
+    case 0x2627:
+	chipname = "PCnet/FAST III 79C975"; /* PCI */
+	break;
+#endif
+    default:
+	printf("%s: PCnet version %#x not supported\n",
+	       dev->name, chip_version);
+	return -1;
+    }
+
+    DEBUG1("AMD %s\n", chipname);
+
+#ifdef PCNET_HAS_PROM
+    /*
+     * In most chips, after a chip reset, the ethernet address is read from
+     * the station address PROM at the base address and programmed into the
+     * "Physical Address Registers" CSR12-14.
+     */
+    for (i = 0; i < 3; i++) {
+	unsigned int val;
+	val = pcnet_read_csr(dev, i+12) & 0x0ffff;
+	/* There may be endianness issues here. */
+	dev->dev_addr[2*i] = val & 0x0ff;
+	dev->dev_addr[2*i+1] = (val >> 8) & 0x0ff;
+    }
+#endif /* PCNET_HAS_PROM */
+
+    return 0;
+}
+
+static int pcnet_init(struct eth_device* dev, bd_t *bis)
+{
+    int i, val;
+    u32 addr;
+
+    DEBUG1("%s: pcnet_init...\n", dev->name);
+
+    /* Switch pcnet to 32bit mode */
+    pcnet_write_bcr (dev, 20, 2);
+
+#ifdef CONFIG_PN62
+    /* Setup LED registers */
+    val = pcnet_read_bcr (dev, 2) | 0x1000;
+    pcnet_write_bcr (dev, 2, val);    /* enable LEDPE */
+    pcnet_write_bcr (dev, 4, 0x5080); /* 100MBit */
+    pcnet_write_bcr (dev, 5, 0x40c0); /* LNKSE */
+    pcnet_write_bcr (dev, 6, 0x4090); /* TX Activity */
+    pcnet_write_bcr (dev, 7, 0x4084); /* RX Activity */
+#endif
+
+    /* Set/reset autoselect bit */
+    val = pcnet_read_bcr (dev, 2) & ~2;
+    val |= 2;
+    pcnet_write_bcr (dev, 2, val);
+
+    /* Enable auto negotiate, setup, disable fd */
+    val = pcnet_read_bcr(dev, 32) & ~0x98;
+    val |= 0x20;
+    pcnet_write_bcr(dev, 32, val);
+
+    /*
+     * We only maintain one structure because the drivers will never
+     * be used concurrently. In 32bit mode the RX and TX ring entries
+     * must be aligned on 16-byte boundaries.
+     */
+    if (lp == NULL) {
+	addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);
+	addr = (addr + 0xf) & ~0xf;
+	lp = (pcnet_priv_t *)addr;
+    }
+
+    lp->init_block.mode = cpu_to_le16(0x0000);
+    lp->init_block.filter[0] = 0x00000000;
+    lp->init_block.filter[1] = 0x00000000;
+
+    /*
+     * Initialize the Rx ring.
+     */
+    lp->cur_rx = 0;
+    for (i = 0; i < RX_RING_SIZE; i++) {
+	lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]);
+	lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ);
+	lp->rx_ring[i].status = cpu_to_le16(0x8000);
+	DEBUG1("Rx%d: base=0x%x buf_length=0x%x status=0x%x\n",
+	       i, lp->rx_ring[i].base, lp->rx_ring[i].buf_length,
+	       lp->rx_ring[i].status);
+    }
+
+    /*
+     * Initialize the Tx ring. The Tx buffer address is filled in as
+     * needed, but we do need to clear the upper ownership bit.
+     */
+    lp->cur_tx = 0;
+    for (i = 0; i < TX_RING_SIZE; i++) {
+	lp->tx_ring[i].base = 0;
+	lp->tx_ring[i].status = 0;
+    }
+
+    /*
+     * Setup Init Block.
+     */
+    DEBUG1("Init block at 0x%p: MAC", &lp->init_block);
+
+    for (i = 0; i < 6; i++) {
+	lp->init_block.phys_addr[i] = dev->enetaddr[i];
+	DEBUG1(" %02x", lp->init_block.phys_addr[i]);
+    }
+
+    lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
+					   RX_RING_LEN_BITS);
+    lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring);
+    lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring);
+
+    DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
+	   lp->init_block.tlen_rlen,
+	   lp->init_block.rx_ring, lp->init_block.tx_ring);
+
+    /*
+     * Tell the controller where the Init Block is located.
+     */
+    addr = PCI_TO_MEM(dev, &lp->init_block);
+    pcnet_write_csr(dev, 1, addr & 0xffff);
+    pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
+
+    pcnet_write_csr (dev, 4, 0x0915);
+    pcnet_write_csr (dev, 0, 0x0001); /* start */
+
+    /* Wait for Init Done bit */
+    for (i = 10000; i > 0; i--) {
+	if (pcnet_read_csr (dev, 0) & 0x0100)
+	    break;
+	udelay(10);
+    }
+    if (i <= 0) {
+	printf("%s: TIMEOUT: controller init failed\n", dev->name);
+	pcnet_reset (dev);
+	return 0;
+    }
+
+    /*
+     * Finally start network controller operation.
+     */
+    pcnet_write_csr (dev, 0, 0x0002);
+
+    return 1;
+}
+
+static int pcnet_send(struct eth_device* dev, volatile void *packet, int pkt_len)
+{
+    int i, status;
+    struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx];
+
+    DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, packet);
+
+    /* Wait for completion by testing the OWN bit */
+    for (i = 1000; i > 0; i--) {
+	status = le16_to_cpu(entry->status);
+	if ((status & 0x8000) == 0)
+	    break;
+	udelay(100);
+	DEBUG2(".");
+    }
+    if (i <= 0) {
+	printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n",
+	       dev->name, lp->cur_tx, status);
+	pkt_len = 0;
+	goto failure;
+    }
+
+    /*
+     * Setup Tx ring. Caution: the write order is important here,
+     * set the status with the "ownership" bits last.
+     */
+    status = 0x8300;
+    entry->length = le16_to_cpu(-pkt_len);
+    entry->misc   = 0x00000000;
+    entry->base   = PCI_TO_MEM_LE(dev, packet);
+    entry->status = le16_to_cpu(status);
+
+    /* Trigger an immediate send poll. */
+    pcnet_write_csr (dev, 0, 0x0008);
+
+ failure:
+    if (++lp->cur_tx >= TX_RING_SIZE)
+	lp->cur_tx = 0;
+
+    DEBUG2("done\n");
+    return pkt_len;
+}
+
+static int pcnet_recv(struct eth_device* dev)
+{
+    struct pcnet_rx_head *entry;
+    int pkt_len = 0;
+    u16 status;
+
+    while (1) {
+	entry = &lp->rx_ring[lp->cur_rx];
+	/*
+	 * If we own the next entry, it's a new packet. Send it up.
+	 */
+	if (((status = le16_to_cpu(entry->status)) & 0x8000) != 0) {
+	    break;
+	}
+	status >>= 8;
+
+	if (status != 0x03) {	/* There was an error. */
+
+	    printf("%s: Rx%d", dev->name, lp->cur_rx);
+	    DEBUG1(" (status=0x%x)", status);
+	    if (status & 0x20) printf(" Frame");
+	    if (status & 0x10) printf(" Overflow");
+	    if (status & 0x08) printf(" CRC");
+	    if (status & 0x04) printf(" Fifo");
+	    printf(" Error\n");
+	    entry->status &= le16_to_cpu(0x03ff);
+
+	} else {
+
+	    pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;
+	    if (pkt_len < 60) {
+		printf("%s: Rx%d: invalid packet length %d\n",
+		       dev->name, lp->cur_rx, pkt_len);
+	    } else {
+		NetReceive(lp->rx_buf[lp->cur_rx], pkt_len);
+		DEBUG2("Rx%d: %d bytes from 0x%p\n",
+		       lp->cur_rx, pkt_len, lp->rx_buf[lp->cur_rx]);
+	    }
+	}
+	entry->status |= cpu_to_le16(0x8000);
+
+	if (++lp->cur_rx >= RX_RING_SIZE)
+	    lp->cur_rx = 0;
+    }
+    return pkt_len;
+}
+
+static void pcnet_halt(struct eth_device* dev)
+{
+    int i;
+
+    DEBUG1("%s: pcnet_halt...\n", dev->name);
+
+    /* Reset the PCnet controller */
+    pcnet_reset (dev);
+
+    /* Wait for Stop bit */
+    for (i = 1000; i > 0; i--) {
+	if (pcnet_read_csr (dev, 0) & 0x4)
+	    break;
+	udelay(10);
+    }
+    if (i <= 0) {
+	printf("%s: TIMEOUT: controller reset failed\n", dev->name);
+    }
+}
+
+#endif
diff --git a/drivers/smiLynxEM.c b/drivers/smiLynxEM.c
new file mode 100644
index 0000000..75d5a31
--- /dev/null
+++ b/drivers/smiLynxEM.c
@@ -0,0 +1,1059 @@
+/*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * smiLynxEM.c
+ *
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ * modification history
+ * --------------------
+ * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ *
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_VIDEO_SMI_LYNXEM)
+
+#include <pci.h>
+#include <video_fb.h>
+
+/*
+ * Export Graphic Device
+ */
+GraphicDevice smi;
+
+/*
+ * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
+ */
+#define VIDEO_MEM_SIZE  0x400000
+
+/*
+ * Supported video modes for SMI Lynx E/EM/EM+
+ */
+#define VIDEO_MODES             7
+#define DUAL_800_600            0   /* SMI710:VGA1:75Hz     (pitch=1600) */
+                                    /*        VGA2:60/120Hz (pitch=1600) */
+                                    /* SMI810:VGA1:75Hz     (pitch=1600) */
+                                    /*        VGA2:75Hz     (pitch=1600) */
+#define DUAL_1024_768           1   /* VGA1:75Hz VGA2:73Hz (pitch=2048)  */
+#define SINGLE_800_600          2   /* VGA1:75Hz (pitch=800)             */
+#define SINGLE_1024_768         3   /* VGA1:75Hz (pitch=1024)            */
+#define SINGLE_1280_1024        4   /* VGA1:75Hz (pitch=1280)            */
+#define TV_MODE_CCIR            5   /* VGA1:50Hz (h=720;v=576;pitch=720) */
+#define TV_MODE_EIA             6   /* VGA1:60Hz (h=720;v=484;pitch=720) */
+
+
+/*
+ * ISA mapped regs
+ */
+#define SMI_INDX_C4             (pGD->isaBase + 0x03c4)    /* index reg */
+#define SMI_DATA_C5             (pGD->isaBase + 0x03c5)    /* data reg */
+#define SMI_INDX_D4             (pGD->isaBase + 0x03d4)    /* index reg */
+#define SMI_DATA_D5             (pGD->isaBase + 0x03d5)    /* data reg */
+#define SMI_INDX_CE             (pGD->isaBase + 0x03ce)    /* index reg */
+#define SMI_DATA_CF             (pGD->isaBase + 0x03cf)    /* data reg */
+#define SMI_LOCK_REG            (pGD->isaBase + 0x03c3)    /* unlock/lock ext crt reg */
+#define SMI_MISC_REG            (pGD->isaBase + 0x03c2)    /* misc reg */
+#define SMI_LUT_MASK            (pGD->isaBase + 0x03c6)    /* lut mask reg */
+#define SMI_LUT_START           (pGD->isaBase + 0x03c8)    /* lut start index */
+#define SMI_LUT_RGB             (pGD->isaBase + 0x03c9)    /* lut colors auto incr.*/
+
+
+/*
+ * Video processor control
+*/
+typedef struct {
+    unsigned int   control;
+    unsigned int   colorKey;
+    unsigned int   colorKeyMask;
+    unsigned int   start;
+    unsigned short offset;
+    unsigned short width;
+    unsigned int   fifoPrio;
+    unsigned int   fifoERL;
+    unsigned int   YUVtoRGB;
+} SmiVideoProc;
+
+/*
+ * Video window control
+ */
+typedef struct {
+    unsigned short top;
+    unsigned short left;
+    unsigned short bottom;
+    unsigned short right;
+    unsigned int   srcStart;
+    unsigned short width;
+    unsigned short offset;
+    unsigned char  hStretch;
+    unsigned char  vStretch;
+} SmiVideoWin;
+
+/*
+ * Capture port control
+ */
+typedef struct {
+    unsigned int   control;
+    unsigned short topClip;
+    unsigned short leftClip;
+    unsigned short srcHeight;
+    unsigned short srcWidth;
+    unsigned int   srcBufStart1;
+    unsigned int   srcBufStart2;
+    unsigned short srcOffset;
+    unsigned short fifoControl;
+} SmiCapturePort;
+
+
+
+/*
+ * Register values for common video modes
+ */
+static char SMI_SCR[22] = {
+    /* all modes */
+    0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0x00, 0x15, 0x90,
+    0x16, 0x10, 0x17, 0x2c, 0x18, 0xb1, 0x19, 0x20, 0x1a, 0x01
+};
+
+static char SMI_EXT_CRT[VIDEO_MODES][24] = {
+    { /* DUAL_800_600_8 */
+    0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+    0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+    },
+    { /* DUAL_1024_768_8 */
+    0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+    0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+    },
+    { /* SINGLE_800_600_8 */
+    0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+    0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+    },
+    { /* SINGLE_1024_768_8 */
+    0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+    0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x30, 0x09, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+    0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+    },
+    { /* TV_MODE_CCIR */
+    0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x01, 0x34, 0x26, 0x35, 0x88,
+    0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
+    },
+    { /* TV_MODE_EIA */
+    0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x00, 0x34, 0xf8, 0x35, 0x88,
+    0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
+    },
+};
+
+static char SMI_CRTCR[VIDEO_MODES][50] = {
+    { /* DUAL_800_600_8 */
+    0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
+    0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+    0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
+    0x12, 0x57, 0x13, 0x64, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+    0x18, 0xff
+    },
+    { /* DUAL_1024_768_8 */
+    0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
+    0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+    0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
+    0x12, 0xff, 0x13, 0x80, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
+    0x18, 0xff
+    },
+    { /* SINGLE_800_600_8 */
+    0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
+    0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+    0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
+    0x12, 0x57, 0x13, 0x32, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+    0x18, 0xff
+    },
+    { /* SINGLE_1024_768_8 */
+    0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
+    0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+    0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
+    0x12, 0xff, 0x13, 0x40, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
+    0x18, 0xff
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x00, 0xce, 0x01, 0x9f, 0x02, 0x9f, 0x03, 0x00, 0x04, 0xa2, 0x05, 0x12,
+    0x06, 0x2a, 0x07, 0x5a, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+    0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x23,
+    0x12, 0xff, 0x13, 0x50, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
+    0x18, 0xff
+    },
+    { /* TV_MODE_CCIR */
+    0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
+    0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+    0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
+    0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+    0x18, 0xff
+    },
+    { /* TV_MODE_EIA */
+    0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
+    0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+    0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
+    0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+    0x18, 0xff
+    },
+};
+
+static char SMI_SEQR[10] = {
+    0x00, 0x03, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e
+};
+
+static char SMI_PCR[VIDEO_MODES][8] = {
+    { /* DUAL_800_600_8 */
+    0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
+    },
+    { /* DUAL_1024_768_8 */
+    0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
+    },
+    { /* SINGLE_800_600_8 */
+    0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+    },
+    { /* SINGLE_1024_768_8 */
+    0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+    },
+    { /* TV_MODE_CCIR */
+    0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+    },
+    { /* TV_MODE_EIA */
+    0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+    },
+};
+
+static char SMI_MCR[VIDEO_MODES][6] = {
+    { /* DUAL_800_600_8 */
+    0x60, 0x01, 0x61, 0x00, 0x62, 0x7a
+    },
+    { /* DUAL_1024_768_8 */
+    0x60, 0x01, 0x61, 0x00, 0x62, 0x7a
+    },
+    { /* SINGLE_800_600_8 */
+    0x60, 0x00, 0x61, 0x00, 0x62, 0x34
+    },
+    { /* SINGLE_1024_768_8 */
+    0x60, 0x00, 0x61, 0x00, 0x62, 0xfe
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x60, 0x00, 0x61, 0x00, 0x62, 0xfe
+    },
+    { /* TV_MODE_CCIR */
+    0x60, 0x00, 0x61, 0x00, 0x62, 0x34
+    },
+    { /* TV_MODE_EIA */
+    0x60, 0x00, 0x61, 0x00, 0x62, 0x34
+    },
+};
+
+static char SMI_CCR[VIDEO_MODES][18] = {
+    { /* DUAL_800_600_8 */
+    0x65, 0x34, 0x68, 0x50, 0x69, 0x05, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+    0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+    },
+    { /* DUAL_1024_768_8 */
+    0x65, 0x00, 0x68, 0x50, 0x69, 0x06, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x0b,
+    0x6d, 0x02, 0x6e, 0x0b, 0x6f, 0x02
+    },
+    { /* SINGLE_800_600_8 */
+    0x65, 0x34, 0x68, 0x40, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+    0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+    },
+    { /* SINGLE_1024_768_8 */
+    0x65, 0x00, 0x68, 0x50, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x0b,
+    0x6d, 0x02, 0x6e, 0x0b, 0x6f, 0x02
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x65, 0x00, 0x68, 0x50, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0xd9,
+    0x6d, 0x17, 0x6e, 0xd9, 0x6f, 0x17
+    },
+    { /* TV_MODE_CCIR */
+    0x65, 0x07, 0x68, 0xc0, 0x69, 0x81, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+    0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+    },
+    { /* TV_MODE_EIA */
+    0x65, 0x07, 0x68, 0xc0, 0x69, 0x81, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+    0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+    },
+};
+
+static char SMI_SHVGA[VIDEO_MODES][24] = {
+    { /* DUAL_800_600_8 */
+    0x40, 0x7f, 0x41, 0x63, 0x42, 0x00, 0x43, 0x68, 0x44, 0x12, 0x45, 0x6f,
+    0x46, 0x57, 0x47, 0x00, 0x48, 0x59, 0x49, 0x0c, 0x4a, 0xa0, 0x4b, 0x20,
+    },
+    { /* DUAL_1024_768_8 */
+    0x40, 0x9f, 0x41, 0x7f, 0x42, 0x00, 0x43, 0x82, 0x44, 0x0e, 0x45, 0x1e,
+    0x46, 0xff, 0x47, 0x00, 0x48, 0x00, 0x49, 0x03, 0x4a, 0xe5, 0x4b, 0x20,
+    },
+    { /* SINGLE_800_600_8 */
+    0x40, 0x7f, 0x41, 0x63, 0x42, 0x00, 0x43, 0x68, 0x44, 0x12, 0x45, 0x6f,
+    0x46, 0x57, 0x47, 0x00, 0x48, 0x59, 0x49, 0x0c, 0x4a, 0xa0, 0x4b, 0x20,
+    },
+    { /* SINGLE_1024_768_8 */
+    0x40, 0x9f, 0x41, 0x7f, 0x42, 0x00, 0x43, 0x82, 0x44, 0x0e, 0x45, 0x1e,
+    0x46, 0xff, 0x47, 0x00, 0x48, 0x01, 0x49, 0x04, 0x4a, 0xa5, 0x4b, 0x20,
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x40, 0xce, 0x41, 0x9f, 0x42, 0x00, 0x43, 0xa2, 0x44, 0x12, 0x45, 0x2a,
+    0x46, 0xff, 0x47, 0x00, 0x48, 0x01, 0x49, 0x03, 0x4a, 0x4a, 0x4b, 0x20,
+    },
+    { /* TV_MODE_CCIR */
+    0x40, 0x6d, 0x41, 0x59, 0x42, 0x00, 0x43, 0x60, 0x44, 0x09, 0x45, 0x38,
+    0x46, 0x25, 0x47, 0x05, 0x48, 0x2a, 0x49, 0x00, 0x4a, 0x4d, 0x4b, 0x00,
+    },
+    { /* TV_MODE_EIA */
+    0x40, 0x6d, 0x41, 0x59, 0x42, 0x00, 0x43, 0x60, 0x44, 0x09, 0x45, 0x06,
+    0x46, 0xf7, 0x47, 0x05, 0x48, 0xfa, 0x49, 0x00, 0x4a, 0x41, 0x4b, 0x00,
+    },
+};
+
+
+static char SMI_GPR[VIDEO_MODES][12] = {
+    { /* DUAL_800_600_8 */
+    0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+    },
+    { /* DUAL_1024_768_8 */
+    0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+    },
+    { /* SINGLE_800_600_8 */
+    0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+    },
+    { /* SINGLE_1024_768_8 */
+    0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+    },
+    { /* TV_MODE_CCIR */
+    0x70, 0x82, 0x71, 0x8d, 0x72, 0x0c, 0x73, 0x32, 0x74, 0x09, 0x75, 0x28
+    },
+    { /* TV_MODE_EIA */
+    0x70, 0x82, 0x71, 0x8d, 0x72, 0x0c, 0x73, 0x32, 0x74, 0x09, 0x75, 0x28
+    },
+};
+
+static char SMI_HCR[VIDEO_MODES][22] = {
+    { /* DUAL_800_600_8 */
+    0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+    0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+    },
+    { /* DUAL_1024_768_8 */
+    0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+    0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+    },
+    { /* SINGLE_800_600_8 */
+    0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+    0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+    },
+    { /* SINGLE_1024_768_8 */
+    0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+    0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+    0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+    },
+    { /* TV_MODE_CCIR */
+    0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+    0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+    },
+    { /* TV_MODE_EIA */
+    0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+    0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+    },
+};
+
+static char SMI_FPR[VIDEO_MODES][88] = {
+    { /* DUAL_800_600_8 */
+    0x30, 0x36, 0x31, 0x83, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x03,
+    0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+    0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x41,
+    0x4b, 0xa0, 0x4c, 0x00,
+    0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x67, 0x55, 0x71,
+    0x56, 0x57, 0x57, 0x59, 0x58, 0x03, 0x59, 0x00, 0x5a, 0x4a,
+    0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+    0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+    0xa0, 0x44
+    },
+    { /* DUAL_1024_768_8 */
+    0x30, 0x3a, 0x31, 0x83, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
+    0x3f, 0x00, 0x40, 0x80, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
+    0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x41,
+    0x4b, 0xa0, 0x4c, 0x00,
+    0x50, 0x06, 0x51, 0x68, 0x52, 0xa7, 0x53, 0x7f, 0x54, 0x83, 0x55, 0x25,
+    0x56, 0xff, 0x57, 0x03, 0x58, 0x04, 0x59, 0x00, 0x5a, 0xc2,
+    0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+    0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+    0xa0, 0x44
+    },
+    { /* SINGLE_800_600_8 */
+    0x30, 0x36, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x03,
+    0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+    0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
+    0x4b, 0xa0, 0x4c, 0x00,
+    0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x67, 0x55, 0x71,
+    0x56, 0x57, 0x57, 0x59, 0x58, 0x03, 0x59, 0x00, 0x5a, 0x4a,
+    0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+    0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+    0xa0, 0x44
+    },
+    { /* SINGLE_1024_768_8 */
+    0x30, 0x3a, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
+    0x3f, 0x00, 0x40, 0x80, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
+    0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x11,
+    0x4b, 0xa0, 0x4c, 0x00,
+    0x50, 0x06, 0x51, 0x68, 0x52, 0xa7, 0x53, 0x7f, 0x54, 0x83, 0x55, 0x24,
+    0x56, 0xff, 0x57, 0x03, 0x58, 0x04, 0x59, 0x00, 0x5a, 0xc2,
+    0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+    0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+    0xa0, 0x44
+    },
+    { /* SINGLE_1280_1024_8 */
+    0x30, 0x3e, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
+    0x3f, 0x00, 0x40, 0xa0, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
+    0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x11,
+    0x4b, 0xa0, 0x4c, 0x00,
+    0x50, 0x08, 0x51, 0x88, 0x52, 0xd3, 0x53, 0x9f, 0x54, 0xa3, 0x55, 0x2a,
+    0x56, 0xff, 0x57, 0x04, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x63,
+    0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+    0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+    0xa0, 0x44
+    },
+    { /* TV_MODE_CCIR */
+    0x30, 0x24, 0x31, 0x84, 0x32, 0x20, 0x33, 0x09, 0x34, 0xf0, 0x3e, 0x03,
+    0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+    0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
+    0x4b, 0xa0, 0x4c, 0x00,
+    0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x68, 0x55, 0x73,
+    0x56, 0x57, 0x57, 0x58, 0x58, 0x04, 0x59, 0x57, 0x5a, 0x7b,
+    0xa1, 0x10, 0xa2, 0xab, 0xa3, 0x98, 0xa4, 0xc1, 0xa8, 0x8c, 0xa9, 0x05,
+    0xaa, 0x17, 0xab, 0x35, 0xac, 0x41, 0xad, 0x68, 0xae, 0x00, 0xaf, 0x00,
+    0xa0, 0x00
+    },
+    { /* TV_MODE_EIA */
+    0x30, 0x24, 0x31, 0x84, 0x32, 0x20, 0x33, 0x09, 0x34, 0xf0, 0x3e, 0x03,
+    0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+    0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
+    0x4b, 0xa0, 0x4c, 0x00,
+    0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x68, 0x55, 0x73,
+    0x56, 0x57, 0x57, 0x58, 0x58, 0x04, 0x59, 0x57, 0x5a, 0x7b,
+    0xa1, 0x10, 0xa2, 0xab, 0xa3, 0x98, 0xa4, 0xc1, 0xa8, 0x8c, 0xa9, 0x05,
+    0xaa, 0x17, 0xab, 0x35, 0xac, 0x41, 0xad, 0x68, 0xae, 0x00, 0xaf, 0x00,
+    0xa0, 0x00
+    },
+};
+
+static char SMI_GCR[18] = {
+    0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
+    0x06, 0x05, 0x07, 0x0f, 0x08, 0xff
+};
+
+/*******************************************************************************
+*
+* Read SMI ISA register
+*/
+static char smiRead (unsigned short index, char reg)
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+    out8 ((pGD->isaBase + index), reg);
+    return (in8 (pGD->isaBase + index + 1));
+}
+
+/*******************************************************************************
+*
+* Write SMI ISA register
+*/
+static void smiWrite (unsigned short index, char reg, char val)
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+    out8 ((pGD->isaBase + index), reg);
+    out8 ((pGD->isaBase + index + 1), val);
+}
+
+/*******************************************************************************
+*
+* Write a table of SMI ISA register
+*/
+static void smiLoadRegs (
+    unsigned int iReg,
+    unsigned int dReg,
+    char         *regTab,
+    unsigned int tabSize
+    )
+{
+    register int i;
+
+    for (i=0; i<tabSize; i+=2)
+    {
+        out8 (iReg, regTab[i]);
+        out8 (dReg, regTab[i+1]);
+    }
+}
+
+/*******************************************************************************
+*
+* Init capture port registers
+*/
+static void smiInitCapturePort (void)
+{
+    SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
+    register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+    register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
+
+    out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16)   | pCP->leftClip));
+    out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
+    out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
+    out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
+    out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
+    out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
+    out32r ((pGD->cprBase + 0x0000), pCP->control);
+}
+
+
+/*******************************************************************************
+*
+* Init video processor registers
+*/
+static void smiInitVideoProcessor (void)
+{
+    SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
+    SmiVideoWin  smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
+    register GraphicDevice *pGD = (GraphicDevice *)&smi;
+    register SmiVideoProc  *pVP = (SmiVideoProc *)&smiVP;
+    register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
+
+    pVP->width    = pGD->plnSizeX * pGD->gdfBytesPP;
+    pVP->control |= pGD->gdfIndex << 16;
+    pVWin->bottom = pGD->winSizeY - 1;
+    pVWin->right  = pGD->winSizeX - 1;
+    pVWin->width  = pVP->width;
+
+    /* color key */
+    out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
+
+     /* color key mask */
+    out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
+
+    /* data src start adrs */
+    out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
+
+    /* data width and offset */
+    out32r ((pGD->vprBase + 0x0010),
+        ((pVP->offset   / 8 * pGD->gdfBytesPP) << 16) |
+         (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
+
+    /* video window 1 */
+    out32r ((pGD->vprBase + 0x0014),
+        ((pVWin->top << 16) | pVWin->left));
+
+    out32r ((pGD->vprBase + 0x0018),
+        ((pVWin->bottom << 16) | pVWin->right));
+
+    out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
+
+    out32r ((pGD->vprBase + 0x0020),
+        (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+    out32r ((pGD->vprBase + 0x0024),
+        (((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+    /* video window 2 */
+    out32r ((pGD->vprBase + 0x0028),
+        ((pVWin->top << 16) | pVWin->left));
+
+    out32r ((pGD->vprBase + 0x002c),
+        ((pVWin->bottom << 16) | pVWin->right));
+
+    out32r ((pGD->vprBase + 0x0030),
+        pVWin->srcStart / 8);
+
+    out32r ((pGD->vprBase + 0x0034),
+        (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+    out32r ((pGD->vprBase + 0x0038),
+        (((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+    /* fifo prio control */
+    out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
+
+    /* fifo empty request levell */
+    out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
+
+    /* conversion constant */
+    out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
+
+    /* vpr control word */
+    out32r ((pGD->vprBase + 0x0000), pVP->control);
+}
+
+/******************************************************************************
+ *
+ * Init drawing engine registers
+ */
+static void smiInitDrawingEngine (void)
+{
+    GraphicDevice *pGD = (GraphicDevice *)&smi;
+    unsigned int val;
+
+    /* don't start now */
+    out32r ((pGD->dprBase + 0x000c), 0x000f0000);
+
+    /* set rop2 to copypen */
+    val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
+    out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
+
+    /* set clip rect */
+    out32r ((pGD->dprBase + 0x002c), 0);
+    out32r ((pGD->dprBase + 0x0030),
+        ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
+
+    /* src row pitch */
+    val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
+    out32r ((pGD->dprBase + 0x0010),
+        (val | pGD->plnSizeX * pGD->gdfBytesPP));
+
+    /* dst row pitch */
+    val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
+    out32r ((pGD->dprBase + 0x0010),
+        (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
+
+    /* window width src/dst */
+    out32r ((pGD->dprBase + 0x003c),
+        (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
+          (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
+    out16r ((pGD->dprBase + 0x001e), 0x0000);
+
+    /* src base adrs */
+    out32r ((pGD->dprBase + 0x0040),
+        (((pGD->frameAdrs/8) & 0x000fffff)));
+
+    /* dst base adrs */
+    out32r ((pGD->dprBase + 0x0044),
+        (((pGD->frameAdrs/8) & 0x000fffff)));
+
+    /* foreground color */
+    out32r ((pGD->dprBase + 0x0014), pGD->fg);
+
+    /* background color */
+    out32r ((pGD->dprBase + 0x0018), pGD->bg);
+
+    /* xcolor */
+    out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
+
+    /* xcolor mask */
+    out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
+
+    /* bit mask */
+    out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
+
+    /* load mono pattern */
+    out32r ((pGD->dprBase + 0x0034), 0);
+    out32r ((pGD->dprBase + 0x0038), 0);
+}
+
+static struct pci_device_id supported[] = {
+    { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
+    { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
+    { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
+    { }
+};
+
+
+/*******************************************************************************
+*
+* Init video chip with common Linux graphic modes (lilo)
+*/
+void *video_hw_init (void)
+{
+    GraphicDevice *pGD = (GraphicDevice *)&smi;
+    unsigned short device_id;
+    pci_dev_t devbusfn;
+    int videomode;
+    unsigned int pci_mem_base, *vm, i;
+    unsigned int gdfTab[] = { 1, 2, 2, 4, 3, 1 };
+    char *penv;
+    char *gdfModes[] =
+            {
+            "8 Bit Index Color",
+            "15 Bit 5-5-5 RGB",
+            "16 Bit 5-6-5 RGB",
+            "32 Bit X-8-8-8 RGB",
+            "24 Bit 8-8-8 RGB",
+            "8 Bit 3-3-2 RGB"
+            };
+    int vgaModes[16][2] =
+            {
+            {769, -1}, {771, 0x00002}, {773, 0x00003}, {775, 0x00004},
+            {784, -1}, {787, 0x10002}, {790, 0x10003}, {793, 0x10004},
+            {785, -1}, {788, 0x20002}, {791, 0x20003}, {794, 0x20004},
+            {786, -1}, {789, 0x40002}, {792, 0x40003}, {795, 0x40004}
+            };
+
+    /* Search for video chip */
+    printf("Video: ");
+
+    if ((devbusfn = pci_find_devices(supported, 0)) < 0)
+    {
+        printf ("Controller not found !\n");
+        return (NULL);
+    }
+
+    /* PCI setup */
+    pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+    pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+    pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+    pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+    /* Initialize the video controller */
+    if ((penv = getenv ("videomode")) != NULL)
+        videomode = (int)simple_strtoul (penv, NULL, 16);
+    else
+        videomode = 0x303;                    /* Default 800x600 8 bit index color */
+
+    /* Compare with common vga mode numbers */
+    for (i=0; i<16; i++)
+    {
+        if (vgaModes[i][0] == videomode)
+        {
+            if (vgaModes[i][1] == -1)
+            {
+                printf("Videomode not supported !\n");
+                return (NULL);                /* mode not supported */
+            }
+            pGD->mode = vgaModes[i][1];        /* use driver int. mode number */
+            break;
+        }
+    }
+
+    /* Extract graphic data format */
+    pGD->gdfIndex = (pGD->mode & 0x00070000) >> 16;
+    if (pGD->gdfIndex > 5)
+        pGD->gdfIndex = 0;
+    pGD->gdfBytesPP = gdfTab[pGD->gdfIndex];
+
+    /* Extract graphic resolution */
+    pGD->mode &= 0xf;
+
+    /* Exit for not supported resolutions */
+    if (((pGD->mode==DUAL_800_600) || (pGD->mode==DUAL_1024_768)) && (pGD->gdfBytesPP > 1))
+    {
+        printf ("Dual screen for 1BPP only !\n");
+        return (NULL);
+    }
+
+    if ((pGD->mode==SINGLE_1280_1024) && (pGD->gdfBytesPP==4))
+    {
+        printf ("Out of memory !\n");
+        return (NULL);
+    }
+
+    /* Set graphic parameters */
+    switch (pGD->mode)
+    {
+    case DUAL_800_600:
+            pGD->winSizeX = 800;
+            pGD->winSizeY = 600;
+            pGD->plnSizeX = 1600;
+            pGD->plnSizeY = 600;
+            sprintf (pGD->modeIdent, "Dual Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
+            break;
+    case DUAL_1024_768:
+            pGD->winSizeX = 1024;
+            pGD->winSizeY = 768;
+            pGD->plnSizeX = 2048;
+            pGD->plnSizeY = 768;
+            sprintf (pGD->modeIdent, "Dual Screen 1024x768 with %s", gdfModes[pGD->gdfIndex]);
+            break;
+    case SINGLE_800_600:
+            pGD->winSizeX = 800;
+            pGD->winSizeY = 600;
+            pGD->plnSizeX = 800;
+            pGD->plnSizeY = 600;
+            sprintf (pGD->modeIdent, "Single Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
+            break;
+    case SINGLE_1024_768:
+            pGD->winSizeX = 1024;
+            pGD->winSizeY = 768;
+            pGD->plnSizeX = 1024;
+            pGD->plnSizeY = 768;
+            sprintf (pGD->modeIdent,"Single Screen 1024x768 with %s", gdfModes[pGD->gdfIndex]);
+            break;
+    case TV_MODE_CCIR:
+            pGD->winSizeX = 720;
+            pGD->winSizeY = 576;
+            pGD->plnSizeX = 720;
+            pGD->plnSizeY = 576;
+            sprintf (pGD->modeIdent, "TV Mode CCIR with %s", gdfModes[pGD->gdfIndex]);
+            break;
+    case TV_MODE_EIA:
+            pGD->winSizeX = 720;
+            pGD->winSizeY = 484;
+            pGD->plnSizeX = 720;
+            pGD->plnSizeY = 484;
+            sprintf (pGD->modeIdent, "TV Mode EIA with %s", gdfModes[pGD->gdfIndex]);
+            break;
+    case SINGLE_1280_1024:
+            pGD->winSizeX = 1280;
+            pGD->winSizeY = 1024;
+            pGD->plnSizeX = 1280;
+            pGD->plnSizeY = 1024;
+            sprintf (pGD->modeIdent, "Single Screen 1280x1024 with %s", gdfModes[pGD->gdfIndex]);
+            break;
+    default:
+            printf("Videomode not supported !\n");
+            return (NULL);
+    }
+
+
+    pGD->isaBase = CFG_ISA_IO;
+    pGD->pciBase = pci_mem_base;
+    pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
+    pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
+    pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
+    pGD->frameAdrs = pci_mem_base;
+    pGD->memSize = VIDEO_MEM_SIZE;
+
+    /* Turn off display */
+    smiWrite (0x3c4, 0x01, 0x20);
+
+    /* Unlock ext. crt regs */
+    out8 (SMI_LOCK_REG, 0x40);
+
+    /* Set Register base to isa 3dx for 3?x regs (color mode) */
+    out8 (SMI_MISC_REG, 0x2b);
+
+    /* Unlock crt regs 0-7 */
+    smiWrite (0x3d4, 0x11, 0x0e);
+
+    /* Sytem Control Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_SCR, sizeof(SMI_SCR));
+
+    /* extented CRT Register */
+    smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
+         SMI_EXT_CRT[pGD->mode], sizeof(SMI_EXT_CRT)/VIDEO_MODES);
+
+    /* Sequencer Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_SEQR, sizeof(SMI_SEQR));
+
+    /* Power Control Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_PCR[pGD->mode], sizeof(SMI_PCR)/VIDEO_MODES);
+
+    /* Memory Control Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_MCR[pGD->mode], sizeof(SMI_MCR)/VIDEO_MODES);
+
+    /* Clock Control Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_CCR[pGD->mode], sizeof(SMI_CCR)/VIDEO_MODES);
+
+    /* Shadow VGA Register */
+    smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
+         SMI_SHVGA[pGD->mode], sizeof(SMI_SHVGA)/VIDEO_MODES);
+
+    /* General Purpose Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_GPR[pGD->mode], sizeof(SMI_GPR)/VIDEO_MODES);
+
+    /* Hardware Cusor Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_HCR[pGD->mode], sizeof(SMI_HCR)/VIDEO_MODES);
+
+    /* Flat Panel Register */
+    smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+         SMI_FPR[pGD->mode], sizeof(SMI_FPR)/VIDEO_MODES);
+
+    /* CRTC Register */
+    smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
+         SMI_CRTCR[pGD->mode], sizeof(SMI_CRTCR)/VIDEO_MODES);
+
+    /* Graphics Controller Register */
+    smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF,
+         SMI_GCR, sizeof(SMI_GCR));
+
+    /* Patch memory and refresh settings for SMI710 */
+    if (device_id == PCI_DEVICE_ID_SMI_710)
+    {
+    unsigned char reg = smiRead (0x3c4, 0x62);
+
+    /* external memory disabled */
+    smiWrite (0x3c4, 0x62, (reg & 0xfb));
+    /* memory clock */
+    smiWrite (0x3c4, 0x6a, 0x75);
+    }
+
+    /* Patch memory and refresh settings for SMI712 */
+    if (device_id == PCI_DEVICE_ID_SMI_712)
+    {
+    unsigned char reg = smiRead (0x3c4, 0x62);
+
+    /* IL runs at MCLK; 64bit bus; external memory disabled */
+    smiWrite (0x3c4, 0x62, (reg | 0xc4));
+    /* memory clock */
+    smiWrite (0x3c4, 0x6a, 0x80);
+    }
+
+    /* Patch clock settings for SMI810 */
+    if (device_id == PCI_DEVICE_ID_SMI_810)
+    {
+    /* clock control */
+    smiWrite (0x3c4, 0x69, 0x03);
+    }
+
+    /* Video processor default setup */
+    smiInitVideoProcessor ();
+
+    /* Capture port default setup */
+    smiInitCapturePort ();
+
+    /* Drawing engine default setup */
+    smiInitDrawingEngine ();
+
+    /* Turn on display */
+    smiWrite (0x3c4, 0x01, 0x01);
+
+    /* Clear video memory */
+    i = pGD->memSize/4;
+    vm = (unsigned int *)pGD->pciBase;
+    while(i--)
+    *vm++ = 0;
+
+    printf("mode=%x - %s\n", videomode, pGD->modeIdent);
+    return ((void*)&smi);
+}
+
+/*******************************************************************************
+*
+* Drawing engine fill on screen region
+*/
+void video_hw_rectfill (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y,           /* frame height */
+    unsigned int color            /* fill color */
+     )
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&smi;
+    register unsigned int control;
+
+    dim_x *= bpp;
+
+    out32r ((pGD->dprBase + 0x0014), color);
+    out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+    out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+
+    control = 0x0000ffff &  in32r ((pGD->dprBase + 0x000c));
+
+    control |= 0x80010000;
+
+    out32r ((pGD->dprBase + 0x000c),  control);
+
+    /* Wait for drawing processor */
+    do
+    {
+    out8 ((pGD->isaBase + 0x3c4), 0x16);
+    } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+*
+* Drawing engine bitblt with screen region
+*/
+void video_hw_bitblt (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int src_x,           /* source pos x */
+    unsigned int src_y,           /* source pos y */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y            /* frame height */
+    )
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&smi;
+    register unsigned int control;
+
+    dim_x *= bpp;
+
+    if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
+    {
+    out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
+    out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
+    control = 0x88000000;
+    }
+    else
+    {
+    out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
+    out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+    control = 0x80000000;
+    }
+
+    out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+    control |= (0x0000ffff &  in32r ((pGD->dprBase + 0x000c)));
+    out32r ((pGD->dprBase + 0x000c), control);
+
+    /* Wait for drawing processor */
+    do
+    {
+    out8 ((pGD->isaBase + 0x3c4), 0x16);
+    } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+*
+* Set a RGB color in the LUT (8 bit index)
+*/
+void video_set_lut (
+    unsigned int index,           /* color number */
+    unsigned char r,              /* red */
+    unsigned char g,              /* green */
+    unsigned char b               /* blue */
+    )
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+    out8 (SMI_LUT_MASK,  0xff);
+
+    out8 (SMI_LUT_START, (char)index);
+
+    out8 (SMI_LUT_RGB, r>>2);    /* red */
+    udelay (10);
+    out8 (SMI_LUT_RGB, g>>2);    /* green */
+    udelay (10);
+    out8 (SMI_LUT_RGB, b>>2);    /* blue */
+    udelay (10);
+}
+
+#endif /* CONFIG_VIDEO_SMI_LYNXEM */
diff --git a/drivers/tigon3.c b/drivers/tigon3.c
new file mode 100644
index 0000000..5883744
--- /dev/null
+++ b/drivers/tigon3.c
@@ -0,0 +1,6222 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+#include <common.h>
+#include "bcm570x_mm.h"
+#include <asm/types.h>
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \
+	defined(CONFIG_TIGON3)
+#ifdef CONFIG_BMW
+#include <mpc824x.h>
+#endif
+#include <malloc.h>
+#include <linux/byteorder/big_endian.h>
+
+#define EMBEDDED 1
+/******************************************************************************/
+/* Local functions. */
+/******************************************************************************/
+
+LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
+
+static LM_STATUS LM_TranslateRequestedMediaType(
+    LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
+    PLM_MEDIA_TYPE pMediaType, PLM_LINE_SPEED pLineSpeed,
+    PLM_DUPLEX_MODE pDuplexMode);
+
+static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);
+
+__inline static LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);
+__inline static LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);
+
+static LM_STATUS LM_ForceAutoNegBcm540xPhy(PLM_DEVICE_BLOCK pDevice,
+    LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice,
+    LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
+    LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
+#if INCLUDE_TBI_SUPPORT
+STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
+#endif
+STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
+STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
+STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
+           LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
+STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number);
+STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
+    PT3_SND_BD pSendBd);
+
+/******************************************************************************/
+/* External functions. */
+/******************************************************************************/
+
+LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_UINT32
+LM_RegRdInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 Register) {
+    LM_UINT32 Value32;
+
+#if PCIX_TARGET_WORKAROUND
+    MM_ACQUIRE_UNDI_LOCK(pDevice);
+#endif
+    MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
+    MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);
+#if PCIX_TARGET_WORKAROUND
+    MM_RELEASE_UNDI_LOCK(pDevice);
+#endif
+
+    return Value32;
+} /* LM_RegRdInd */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_RegWrInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 Register,
+LM_UINT32 Value32) {
+
+#if PCIX_TARGET_WORKAROUND
+    MM_ACQUIRE_UNDI_LOCK(pDevice);
+#endif
+    MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
+    MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, Value32);
+#if PCIX_TARGET_WORKAROUND
+    MM_RELEASE_UNDI_LOCK(pDevice);
+#endif
+} /* LM_RegWrInd */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_UINT32
+LM_MemRdInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 MemAddr) {
+    LM_UINT32 Value32;
+
+    MM_ACQUIRE_UNDI_LOCK(pDevice);
+#ifdef BIG_ENDIAN_HOST
+    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+    Value32 = REG_RD(pDevice, PciCfg.MemWindowData);
+    /*    Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
+#else
+    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+    MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
+#endif
+    MM_RELEASE_UNDI_LOCK(pDevice);
+
+    return Value32;
+} /* LM_MemRdInd */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_MemWrInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 MemAddr,
+LM_UINT32 Value32) {
+    MM_ACQUIRE_UNDI_LOCK(pDevice);
+#ifdef BIG_ENDIAN_HOST
+    REG_WR(pDevice,PciCfg.MemWindowBaseAddr,MemAddr);
+    REG_WR(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4],Value32);
+#else
+    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
+#endif
+    MM_RELEASE_UNDI_LOCK(pDevice);
+} /* LM_MemWrInd */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_QueueRxPackets(
+PLM_DEVICE_BLOCK pDevice) {
+    LM_STATUS Lmstatus;
+    PLM_PACKET pPacket;
+    PT3_RCV_BD pRcvBd;
+    LM_UINT32 StdBdAdded = 0;
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    LM_UINT32 JumboBdAdded = 0;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    Lmstatus = LM_STATUS_SUCCESS;
+
+    pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
+    while(pPacket) {
+        switch(pPacket->u.Rx.RcvProdRing) {
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+            case T3_JUMBO_RCV_PROD_RING:        /* Jumbo Receive Ring. */
+                /* Initialize the buffer descriptor. */
+                pRcvBd =
+                    &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
+                pRcvBd->Flags = RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
+                pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
+
+                /* Initialize the receive buffer pointer */
+#if 0 /* Jimmy, deleted in new */
+                pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
+                pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
+#endif
+                MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
+
+                /* The opaque field may point to an offset from a fix addr. */
+                pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
+                    MM_UINT_PTR(pDevice->pPacketDescBase));
+
+                /* Update the producer index. */
+                pDevice->RxJumboProdIdx = (pDevice->RxJumboProdIdx + 1) &
+                    T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
+
+                JumboBdAdded++;
+                break;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+            case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
+                /* Initialize the buffer descriptor. */
+                pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
+                pRcvBd->Flags = RCV_BD_FLAG_END;
+                pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
+
+                /* Initialize the receive buffer pointer */
+#if 0  /* Jimmy, deleted in new replaced with MM_MapRxDma */
+                pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
+                pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
+#endif
+                MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
+
+                /* The opaque field may point to an offset from a fix addr. */
+                pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
+                    MM_UINT_PTR(pDevice->pPacketDescBase));
+
+                /* Update the producer index. */
+                pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
+                    T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
+
+                StdBdAdded++;
+                break;
+
+            case T3_UNKNOWN_RCV_PROD_RING:
+            default:
+                Lmstatus = LM_STATUS_FAILURE;
+                break;
+        } /* switch */
+
+        /* Bail out if there is any error. */
+        if(Lmstatus != LM_STATUS_SUCCESS)
+        {
+            break;
+        }
+
+        pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
+    } /* while */
+
+    wmb();
+    /* Update the procedure index. */
+    if(StdBdAdded)
+    {
+        MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, pDevice->RxStdProdIdx);
+    }
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    if(JumboBdAdded)
+    {
+        MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low,
+            pDevice->RxJumboProdIdx);
+    }
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    return Lmstatus;
+} /* LM_QueueRxPackets */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_VOID
+LM_NvramInit(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Value32;
+    LM_UINT32 j;
+
+    /* Intialize clock period and state machine. */
+    Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) |
+        SEEPROM_ADDR_FSM_RESET;
+    REG_WR(pDevice, Grc.EepromAddr, Value32);
+
+    for(j = 0; j < 100; j++)
+    {
+        MM_Wait(10);
+    }
+
+    /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
+    Value32 = REG_RD(pDevice, Grc.LocalCtrl);
+    REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
+
+    /* Set the 5701 compatibility mode if we are using EEPROM. */
+    if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+        T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
+    {
+        Value32 = REG_RD(pDevice, Nvram.Config1);
+        if((Value32 & FLASH_INTERFACE_ENABLE) == 0)
+        {
+            /* Use the new interface to read EEPROM. */
+            Value32 &= ~FLASH_COMPAT_BYPASS;
+
+            REG_WR(pDevice, Nvram.Config1, Value32);
+        }
+    }
+} /* LM_NvRamInit */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_EepromRead(
+    PLM_DEVICE_BLOCK pDevice,
+    LM_UINT32 Offset,
+    LM_UINT32 *pData)
+{
+    LM_UINT32 Value32;
+    LM_UINT32 Addr;
+    LM_UINT32 Dev;
+    LM_UINT32 j;
+
+    if(Offset > SEEPROM_CHIP_SIZE)
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    Dev = Offset / SEEPROM_CHIP_SIZE;
+    Addr = Offset % SEEPROM_CHIP_SIZE;
+
+    Value32 = REG_RD(pDevice, Grc.EepromAddr);
+    Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
+        SEEPROM_ADDR_RW_MASK);
+    REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
+        SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_READ);
+
+    for(j = 0; j < 1000; j++)
+    {
+        Value32 = REG_RD(pDevice, Grc.EepromAddr);
+        if(Value32 & SEEPROM_ADDR_COMPLETE)
+        {
+            break;
+        }
+        MM_Wait(10);
+    }
+
+    if(Value32 & SEEPROM_ADDR_COMPLETE)
+    {
+        Value32 = REG_RD(pDevice, Grc.EepromData);
+        *pData = Value32;
+
+        return LM_STATUS_SUCCESS;
+    }
+
+    return LM_STATUS_FAILURE;
+} /* LM_EepromRead */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_NvramRead(
+    PLM_DEVICE_BLOCK pDevice,
+    LM_UINT32 Offset,
+    LM_UINT32 *pData)
+{
+    LM_UINT32 Value32;
+    LM_STATUS Status;
+    LM_UINT32 j;
+
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+        T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+    {
+        Status = LM_EepromRead(pDevice, Offset, pData);
+    }
+    else
+    {
+        /* Determine if we have flash or EEPROM. */
+        Value32 = REG_RD(pDevice, Nvram.Config1);
+        if(Value32 & FLASH_INTERFACE_ENABLE)
+        {
+            if(Value32 & FLASH_SSRAM_BUFFERRED_MODE)
+            {
+                Offset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
+                    BUFFERED_FLASH_PAGE_POS) +
+                    (Offset % BUFFERED_FLASH_PAGE_SIZE);
+            }
+        }
+
+        REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
+        for (j = 0; j < 1000; j++)
+        {
+            if (REG_RD(pDevice, Nvram.SwArb) & SW_ARB_GNT1)
+            {
+                break;
+            }
+            MM_Wait(20);
+        }
+        if (j == 1000)
+        {
+            return LM_STATUS_FAILURE;
+        }
+
+        /* Read from flash or EEPROM with the new 5703/02 interface. */
+        REG_WR(pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
+
+        REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
+            NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+        /* Wait for the done bit to clear. */
+        for(j = 0; j < 500; j++)
+        {
+            MM_Wait(10);
+
+            Value32 = REG_RD(pDevice, Nvram.Cmd);
+            if(!(Value32 & NVRAM_CMD_DONE))
+            {
+                break;
+            }
+        }
+
+        /* Wait for the done bit. */
+        if(!(Value32 & NVRAM_CMD_DONE))
+        {
+            for(j = 0; j < 500; j++)
+            {
+                MM_Wait(10);
+
+                Value32 = REG_RD(pDevice, Nvram.Cmd);
+                if(Value32 & NVRAM_CMD_DONE)
+                {
+                    MM_Wait(10);
+
+                    *pData = REG_RD(pDevice, Nvram.ReadData);
+
+                    /* Change the endianess. */
+                    *pData = ((*pData & 0xff) << 24)| ((*pData & 0xff00) << 8)|
+                        ((*pData & 0xff0000) >> 8) | ((*pData >> 24) & 0xff);
+
+                    break;
+                }
+            }
+        }
+
+        REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
+        if(Value32 & NVRAM_CMD_DONE)
+        {
+            Status = LM_STATUS_SUCCESS;
+        }
+        else
+        {
+            Status = LM_STATUS_FAILURE;
+        }
+    }
+
+    return Status;
+} /* LM_NvramRead */
+
+
+STATIC void
+LM_ReadVPD(PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Vpd_arr[256/4];
+    LM_UINT8 *Vpd = (LM_UINT8 *) &Vpd_arr[0];
+    LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
+    LM_UINT32 Value32;
+    unsigned int j;
+
+    /* Read PN from VPD */
+    for (j = 0; j < 256; j += 4, Vpd_dptr++ )
+    {
+        if (LM_NvramRead(pDevice, 0x100 + j, &Value32) != LM_STATUS_SUCCESS) {
+            printf("BCM570x: LM_ReadVPD: VPD read failed"
+		   " (no EEPROM onboard)\n");
+            return;
+        }
+        *Vpd_dptr = cpu_to_le32(Value32);
+    }
+    for (j = 0; j < 256; )
+    {
+        unsigned int Vpd_r_len;
+        unsigned int Vpd_r_end;
+
+        if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91))
+        {
+            j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
+        }
+        else if (Vpd[j] == 0x90)
+        {
+            Vpd_r_len =  Vpd[j + 1] + (Vpd[j + 2] << 8);
+            j += 3;
+            Vpd_r_end = Vpd_r_len + j;
+            while (j < Vpd_r_end)
+            {
+                if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N'))
+                {
+                    unsigned int len = Vpd[j + 2];
+
+                    if (len <= 24)
+                    {
+                        memcpy(pDevice->PartNo, &Vpd[j + 3], len);
+                    }
+                    break;
+                }
+                else
+                {
+                    if (Vpd[j + 2] == 0)
+                    {
+                        break;
+                    }
+                    j = j + Vpd[j + 2];
+                }
+            }
+            break;
+        }
+        else {
+            break;
+        }
+    }
+}
+
+STATIC void
+LM_ReadBootCodeVersion(PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Value32, offset, ver_offset;
+    int i;
+
+    if (LM_NvramRead(pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
+        return;
+    if (Value32 != 0xaa559966)
+        return;
+    if (LM_NvramRead(pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
+        return;
+
+    offset = ((offset & 0xff) << 24)| ((offset & 0xff00) << 8)|
+        ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
+    if (LM_NvramRead(pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
+        return;
+    if ((Value32 == 0x0300000e) &&
+        (LM_NvramRead(pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS) &&
+        (Value32 == 0)) {
+
+        if (LM_NvramRead(pDevice, offset + 8, &ver_offset) != LM_STATUS_SUCCESS)
+            return;
+        ver_offset = ((ver_offset & 0xff0000) >> 8) |
+            ((ver_offset >> 24) & 0xff);
+        for (i = 0; i < 16; i += 4) {
+            if (LM_NvramRead(pDevice, offset + ver_offset + i, &Value32) !=
+                LM_STATUS_SUCCESS)
+            {
+                return;
+            }
+            *((LM_UINT32 *) &pDevice->BootCodeVer[i]) = cpu_to_le32(Value32);
+        }
+    }
+    else {
+        char c;
+
+        if (LM_NvramRead(pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
+            return;
+
+        i = 0;
+        c = ((Value32 & 0xff0000) >> 16);
+
+        if (c < 10) {
+            pDevice->BootCodeVer[i++] = c + '0';
+        }
+        else {
+            pDevice->BootCodeVer[i++] = (c / 10) + '0';
+            pDevice->BootCodeVer[i++] = (c % 10) + '0';
+        }
+        pDevice->BootCodeVer[i++] = '.';
+        c = (Value32 & 0xff000000) >> 24;
+        if (c < 10) {
+            pDevice->BootCodeVer[i++] = c + '0';
+        }
+        else {
+            pDevice->BootCodeVer[i++] = (c / 10) + '0';
+            pDevice->BootCodeVer[i++] = (c % 10) + '0';
+        }
+        pDevice->BootCodeVer[i] = 0;
+    }
+}
+
+STATIC void
+LM_GetBusSpeed(PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 PciState = pDevice->PciState;
+    LM_UINT32 ClockCtrl;
+    char *SpeedStr = "";
+
+    if (PciState & T3_PCI_STATE_32BIT_PCI_BUS)
+    {
+        strcpy(pDevice->BusSpeedStr, "32-bit ");
+    }
+    else
+    {
+        strcpy(pDevice->BusSpeedStr, "64-bit ");
+    }
+    if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)
+    {
+        strcat(pDevice->BusSpeedStr, "PCI ");
+        if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED)
+        {
+            SpeedStr = "66MHz";
+        }
+        else
+        {
+            SpeedStr = "33MHz";
+        }
+    }
+    else
+    {
+        strcat(pDevice->BusSpeedStr, "PCIX ");
+        if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)
+        {
+            SpeedStr = "133MHz";
+        }
+        else
+        {
+            ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl) & 0x1f;
+            switch (ClockCtrl)
+            {
+            case 0:
+                SpeedStr = "33MHz";
+                break;
+
+            case 2:
+                SpeedStr = "50MHz";
+                break;
+
+            case 4:
+                SpeedStr = "66MHz";
+                break;
+
+            case 6:
+                SpeedStr = "100MHz";
+                break;
+
+            case 7:
+                SpeedStr = "133MHz";
+                break;
+            }
+        }
+    }
+    strcat(pDevice->BusSpeedStr, SpeedStr);
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine initializes default parameters and reads the PCI           */
+/*    configurations.                                                         */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_GetAdapterInfo(
+PLM_DEVICE_BLOCK pDevice)
+{
+    PLM_ADAPTER_INFO pAdapterInfo;
+    LM_UINT32 Value32;
+    LM_STATUS Status;
+    LM_UINT32 j;
+    LM_UINT32 EeSigFound;
+    LM_UINT32 EePhyTypeSerdes = 0;
+    LM_UINT32 EePhyLedMode = 0;
+    LM_UINT32 EePhyId = 0;
+
+    /* Get Device Id and Vendor Id */
+    Status = MM_ReadConfig32(pDevice, PCI_VENDOR_ID_REG, &Value32);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+    pDevice->PciVendorId = (LM_UINT16) Value32;
+    pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
+
+    /* If we are not getting the write adapter, exit. */
+    if((Value32 != T3_PCI_ID_BCM5700) &&
+       (Value32 != T3_PCI_ID_BCM5701) &&
+       (Value32 != T3_PCI_ID_BCM5702) &&
+       (Value32 != T3_PCI_ID_BCM5702x) &&
+       (Value32 != T3_PCI_ID_BCM5702FE) &&
+       (Value32 != T3_PCI_ID_BCM5703) &&
+       (Value32 != T3_PCI_ID_BCM5703x) &&
+       (Value32 != T3_PCI_ID_BCM5704))
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    Status = MM_ReadConfig32(pDevice, PCI_REV_ID_REG, &Value32);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+    pDevice->PciRevId = (LM_UINT8) Value32;
+
+    /* Get IRQ. */
+    Status = MM_ReadConfig32(pDevice, PCI_INT_LINE_REG, &Value32);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+    pDevice->Irq = (LM_UINT8) Value32;
+
+    /* Get interrupt pin. */
+    pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
+
+    /* Get chip revision id. */
+    Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
+    pDevice->ChipRevId = Value32 >> 16;
+
+    /* Get subsystem vendor. */
+    Status = MM_ReadConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+    pDevice->SubsystemVendorId = (LM_UINT16) Value32;
+
+    /* Get PCI subsystem id. */
+    pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
+
+    /* Get the cache line size. */
+    MM_ReadConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
+    pDevice->CacheLineSize = (LM_UINT8) Value32;
+    pDevice->SavedCacheLineReg = Value32;
+
+    if(pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
+        pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
+        pDevice->ChipRevId != T3_CHIP_ID_5704_A0)
+    {
+        pDevice->UndiFix = FALSE;
+    }
+#if !PCIX_TARGET_WORKAROUND
+    pDevice->UndiFix = FALSE;
+#endif
+    /* Map the memory base to system address space. */
+    if (!pDevice->UndiFix)
+    {
+        Status = MM_MapMemBase(pDevice);
+        if(Status != LM_STATUS_SUCCESS)
+        {
+            return Status;
+        }
+        /* Initialize the memory view pointer. */
+        pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
+    }
+
+#if PCIX_TARGET_WORKAROUND
+    /* store whether we are in PCI are PCI-X mode */
+    pDevice->EnablePciXFix = FALSE;
+
+    MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
+    if((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)
+    {
+        /* Enable PCI-X workaround only if we are running on 5700 BX. */
+        if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
+        {
+            pDevice->EnablePciXFix = TRUE;
+        }
+    }
+    if (pDevice->UndiFix)
+    {
+        pDevice->EnablePciXFix = TRUE;
+    }
+#endif
+    /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
+    /* management register may be clobbered which may cause the */
+    /* BCM5700 to go into D3 state.  While in this state, we will */
+    /* not have memory mapped register access.  As a workaround, we */
+    /* need to restore the device to D0 state. */
+    MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
+    Value32 |= T3_PM_PME_ASSERTED;
+    Value32 &= ~T3_PM_POWER_STATE_MASK;
+    Value32 |= T3_PM_POWER_STATE_D0;
+    MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
+
+    /* read the current PCI command word */
+    MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
+
+    /* Make sure bus-mastering is enabled. */
+    Value32 |= PCI_BUSMASTER_ENABLE;
+
+#if PCIX_TARGET_WORKAROUND
+    /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
+        are enabled */
+    if (pDevice->EnablePciXFix == TRUE) {
+        Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
+                    PCI_PARITY_ERROR_ENABLE);
+    }
+    if (pDevice->UndiFix)
+    {
+        Value32 &= ~PCI_MEM_SPACE_ENABLE;
+    }
+
+#endif
+
+    if(pDevice->EnableMWI)
+    {
+        Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
+    }
+    else {
+        Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
+    }
+
+    /* Error out if mem-mapping is NOT enabled for PCI systems */
+    if (!(Value32 | PCI_MEM_SPACE_ENABLE))
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    /* save the value we are going to write into the PCI command word */
+    pDevice->PciCommandStatusWords = Value32;
+
+    Status = MM_WriteConfig32(pDevice, PCI_COMMAND_REG, Value32);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+
+    /* Set power state to D0. */
+    LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
+
+#ifdef BIG_ENDIAN_PCI
+    pDevice->MiscHostCtrl =
+        MISC_HOST_CTRL_MASK_PCI_INT |
+        MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
+        MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
+        MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
+#else /* No CPU Swap modes for PCI IO */
+
+    /* Setup the mode registers. */
+    pDevice->MiscHostCtrl =
+        MISC_HOST_CTRL_MASK_PCI_INT |
+        MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
+#ifdef BIG_ENDIAN_HOST
+        MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
+#endif /* BIG_ENDIAN_HOST */
+        MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
+        MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
+#endif /* !BIG_ENDIAN_PCI */
+
+    /* write to PCI misc host ctr first in order to enable indirect accesses */
+    MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
+
+    REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
+
+#ifdef BIG_ENDIAN_PCI
+    Value32 = GRC_MODE_WORD_SWAP_DATA|
+	      GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+/* No CPU Swap modes for PCI IO */
+#ifdef BIG_ENDIAN_HOST
+    Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+              GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+    Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
+#endif
+#endif /* !BIG_ENDIAN_PCI */
+
+    REG_WR(pDevice, Grc.Mode, Value32);
+
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+    {
+        REG_WR(pDevice, Grc.LocalCtrl, GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+            GRC_MISC_LOCAL_CTRL_GPIO_OE1);
+    }
+    MM_Wait(40);
+
+    /* Enable indirect memory access */
+    REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
+
+    if (REG_RD(pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK)
+    {
+        REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
+                T3_PCI_SELECT_ALTERNATE_CLOCK);
+        REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_SELECT_ALTERNATE_CLOCK);
+        MM_Wait(40);  /* required delay is 27usec */
+    }
+    REG_WR(pDevice, PciCfg.ClockCtrl, 0);
+    REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
+
+#if PCIX_TARGET_WORKAROUND
+    MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
+    if ((pDevice->EnablePciXFix == FALSE) &&
+        ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0))
+    {
+        if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+            pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
+            pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
+            pDevice->ChipRevId == T3_CHIP_ID_5701_B5)
+        {
+            __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x300]));
+            __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
+            __raw_writel(0xffffffff, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
+            if (__raw_readl(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
+            {
+                pDevice->EnablePciXFix = TRUE;
+            }
+        }
+    }
+#endif
+#if 1
+    /*
+    *  This code was at the beginning of else block below, but that's
+    *  a bug if node address in shared memory.
+    */
+    MM_Wait(50);
+    LM_NvramInit(pDevice);
+#endif
+    /* Get the node address.  First try to get in from the shared memory. */
+    /* If the signature is not present, then get it from the NVRAM. */
+    Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
+    if((Value32 >> 16) == 0x484b)
+    {
+
+        pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
+        pDevice->NodeAddress[1] = (LM_UINT8) Value32;
+
+        Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_LOW_MAILBOX);
+
+        pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
+        pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
+        pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
+        pDevice->NodeAddress[5] = (LM_UINT8) Value32;
+
+        Status = LM_STATUS_SUCCESS;
+    }
+    else
+    {
+        Status = LM_NvramRead(pDevice, 0x7c, &Value32);
+        if(Status == LM_STATUS_SUCCESS)
+        {
+            pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
+            pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
+
+            Status = LM_NvramRead(pDevice, 0x80, &Value32);
+
+            pDevice->NodeAddress[2] = (LM_UINT8) Value32;
+            pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
+            pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
+            pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
+        }
+    }
+
+    /* Assign a default address. */
+    if(Status != LM_STATUS_SUCCESS)
+    {
+#ifndef EMBEDDED
+        printk(KERN_ERR "Cannot get MAC addr from NVRAM. Using default.\n");
+#endif
+        pDevice->NodeAddress[0] = 0x00; pDevice->NodeAddress[1] = 0x10;
+        pDevice->NodeAddress[2] = 0x18; pDevice->NodeAddress[3] = 0x68;
+        pDevice->NodeAddress[4] = 0x61; pDevice->NodeAddress[5] = 0x76;
+    }
+
+    pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
+    pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
+    pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
+    pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
+    pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
+    pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
+
+    /* Initialize the default values. */
+    pDevice->NoTxPseudoHdrChksum = FALSE;
+    pDevice->NoRxPseudoHdrChksum = FALSE;
+    pDevice->NicSendBd = FALSE;
+    pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
+    pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
+    pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
+    pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
+    pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
+    pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
+    pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
+    pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
+    pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
+    pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
+    pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
+    pDevice->EnableMWI = FALSE;
+    pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+    pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+    pDevice->DisableAutoNeg = FALSE;
+    pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
+    pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
+    pDevice->LedMode = LED_MODE_AUTO;
+    pDevice->ResetPhyOnInit = TRUE;
+    pDevice->DelayPciGrant = TRUE;
+    pDevice->UseTaggedStatus = FALSE;
+    pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
+
+    pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
+    pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
+    pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
+
+    pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
+    pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
+    pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
+    pDevice->EnableTbi = FALSE;
+#if INCLUDE_TBI_SUPPORT
+    pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
+#endif
+
+    switch (T3_ASIC_REV(pDevice->ChipRevId))
+    {
+    case T3_ASIC_REV_5704:
+        pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
+        pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
+        break;
+    default:
+        pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
+        pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
+        break;
+    }
+
+    pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
+    pDevice->QueueRxPackets = TRUE;
+
+    pDevice->EnableWireSpeed = TRUE;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    /* Make this is a known adapter. */
+    pAdapterInfo = LM_GetAdapterInfoBySsid(pDevice->SubsystemVendorId,
+        pDevice->SubsystemId);
+
+    pDevice->BondId = REG_RD(pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
+    if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
+        pDevice->BondId != GRC_MISC_BD_ID_5701 &&
+        pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
+        pDevice->BondId != GRC_MISC_BD_ID_5703 &&
+        pDevice->BondId != GRC_MISC_BD_ID_5703S &&
+        pDevice->BondId != GRC_MISC_BD_ID_5704 &&
+        pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE)
+    {
+        return LM_STATUS_UNKNOWN_ADAPTER;
+    }
+
+    pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
+    if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
+        (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE))
+    {
+        pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
+        pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
+    }
+
+    /* Get Eeprom info. */
+    Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
+    if (Value32 == T3_NIC_DATA_SIG)
+    {
+        EeSigFound = TRUE;
+        Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
+
+        /* Determine PHY type. */
+        switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK)
+        {
+            case T3_NIC_CFG_PHY_TYPE_COPPER:
+                EePhyTypeSerdes = FALSE;
+                break;
+
+            case T3_NIC_CFG_PHY_TYPE_FIBER:
+                EePhyTypeSerdes = TRUE;
+                break;
+
+            default:
+                EePhyTypeSerdes = FALSE;
+                break;
+        }
+
+        /* Determine PHY led mode. */
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
+            {
+                case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
+                    EePhyLedMode = LED_MODE_THREE_LINK;
+                    break;
+
+                case T3_NIC_CFG_LED_MODE_LINK_SPEED:
+                    EePhyLedMode = LED_MODE_LINK10;
+                    break;
+
+                default:
+                    EePhyLedMode = LED_MODE_AUTO;
+                    break;
+            }
+        }
+        else
+        {
+            switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
+            {
+                case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
+                    EePhyLedMode = LED_MODE_OPEN_DRAIN;
+                    break;
+
+                case T3_NIC_CFG_LED_MODE_OUTPUT:
+                    EePhyLedMode = LED_MODE_OUTPUT;
+                    break;
+
+                default:
+                    EePhyLedMode = LED_MODE_AUTO;
+                    break;
+            }
+        }
+        if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
+            pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
+        {
+            /* Enable EEPROM write protection. */
+            if(Value32 & T3_NIC_EEPROM_WP)
+            {
+                pDevice->EepromWp = TRUE;
+            }
+        }
+
+        /* Get the PHY Id. */
+        Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_PHY_ID_ADDR);
+        if (Value32)
+        {
+            EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
+                PHY_ID1_OUI_MASK) << 10;
+
+            Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
+
+            EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
+              (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
+        }
+        else
+        {
+            EePhyId = 0;
+        }
+    }
+    else
+    {
+        EeSigFound = FALSE;
+    }
+
+    /* Set the PHY address. */
+    pDevice->PhyAddr = PHY_DEVICE_ID;
+
+    /* Disable auto polling. */
+    pDevice->MiMode = 0xc0000;
+    REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+    MM_Wait(40);
+
+    /* Get the PHY id. */
+    LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
+    pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
+
+    LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
+    pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
+      (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
+
+    /* Set the EnableTbi flag to false if we have a copper PHY. */
+    switch(pDevice->PhyId & PHY_ID_MASK)
+    {
+        case PHY_BCM5400_PHY_ID:
+            pDevice->EnableTbi = FALSE;
+            break;
+
+        case PHY_BCM5401_PHY_ID:
+            pDevice->EnableTbi = FALSE;
+            break;
+
+        case PHY_BCM5411_PHY_ID:
+            pDevice->EnableTbi = FALSE;
+            break;
+
+        case PHY_BCM5701_PHY_ID:
+            pDevice->EnableTbi = FALSE;
+            break;
+
+        case PHY_BCM5703_PHY_ID:
+            pDevice->EnableTbi = FALSE;
+            break;
+
+        case PHY_BCM5704_PHY_ID:
+            pDevice->EnableTbi = FALSE;
+            break;
+
+        case PHY_BCM8002_PHY_ID:
+            pDevice->EnableTbi = TRUE;
+            break;
+
+        default:
+
+            if (pAdapterInfo)
+            {
+                pDevice->PhyId = pAdapterInfo->PhyId;
+                pDevice->EnableTbi = pAdapterInfo->Serdes;
+            }
+            else if (EeSigFound)
+            {
+                pDevice->PhyId = EePhyId;
+                pDevice->EnableTbi = EePhyTypeSerdes;
+            }
+            break;
+    }
+
+    /* Bail out if we don't know the copper PHY id. */
+    if(UNKNOWN_PHY_ID(pDevice->PhyId) && !pDevice->EnableTbi)
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
+    {
+        if((pDevice->SavedCacheLineReg & 0xff00) < 0x4000)
+        {
+            pDevice->SavedCacheLineReg &= 0xffff00ff;
+            pDevice->SavedCacheLineReg |= 0x4000;
+        }
+    }
+    /* Change driver parameters. */
+    Status = MM_GetConfig(pDevice);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+
+#if INCLUDE_5701_AX_FIX
+    if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+        pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+    {
+        pDevice->ResetPhyOnInit = TRUE;
+    }
+#endif
+
+    /* Save the current phy link status. */
+    if(!pDevice->EnableTbi)
+    {
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+        /* If we don't have link reset the PHY. */
+        if(!(Value32 & PHY_STATUS_LINK_PASS) || pDevice->ResetPhyOnInit)
+        {
+
+            LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
+
+            for(j = 0; j < 100; j++)
+            {
+                MM_Wait(10);
+
+                LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+                if(Value32 && !(Value32 & PHY_CTRL_PHY_RESET))
+                {
+                    MM_Wait(40);
+                    break;
+                }
+            }
+
+
+#if INCLUDE_5701_AX_FIX
+            /* 5701_AX_BX bug:  only advertises 10mb speed. */
+            if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+                pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+            {
+
+                Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
+                    PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
+                    PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+                Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+                LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+                pDevice->advertising = Value32;
+
+                Value32 = BCM540X_AN_AD_1000BASET_HALF |
+                    BCM540X_AN_AD_1000BASET_FULL | BCM540X_CONFIG_AS_MASTER |
+                    BCM540X_ENABLE_CONFIG_AS_MASTER;
+                LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
+                pDevice->advertising1000 = Value32;
+
+                LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
+                    PHY_CTRL_RESTART_AUTO_NEG);
+            }
+#endif
+            if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
+            {
+                LM_WritePhy(pDevice, 0x18, 0x0c00);
+                LM_WritePhy(pDevice, 0x17, 0x201f);
+                LM_WritePhy(pDevice, 0x15, 0x2aaa);
+            }
+            if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+            {
+                LM_WritePhy(pDevice, 0x1c, 0x8d68);
+                LM_WritePhy(pDevice, 0x1c, 0x8d68);
+            }
+            /* Enable Ethernet@WireSpeed. */
+            if(pDevice->EnableWireSpeed)
+            {
+                LM_WritePhy(pDevice, 0x18, 0x7007);
+                LM_ReadPhy(pDevice, 0x18, &Value32);
+                LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
+            }
+        }
+    }
+
+    /* Turn off tap power management. */
+    if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
+    {
+        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
+        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+
+        MM_Wait(40);
+    }
+
+#if INCLUDE_TBI_SUPPORT
+    pDevice->IgnoreTbiLinkChange = FALSE;
+
+    if(pDevice->EnableTbi)
+    {
+        pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
+        pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
+        if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
+            pDevice->DisableAutoNeg)
+        {
+            pDevice->PollTbiLink = FALSE;
+        }
+    }
+    else
+    {
+        pDevice->PollTbiLink = FALSE;
+    }
+#endif /* INCLUDE_TBI_SUPPORT */
+
+    /* UseTaggedStatus is only valid for 5701 and later. */
+    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+    {
+        pDevice->UseTaggedStatus = FALSE;
+
+        pDevice->CoalesceMode = 0;
+    }
+    else
+    {
+        pDevice->CoalesceMode = HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
+            HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
+    }
+
+    /* Set the status block size. */
+    if(T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
+        T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_BX)
+    {
+        pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
+    }
+
+    /* Check the DURING_INT coalescing ticks parameters. */
+    if(pDevice->UseTaggedStatus)
+    {
+        if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->RxCoalescingTicksDuringInt =
+                DEFAULT_RX_COALESCING_TICKS_DURING_INT;
+        }
+
+        if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->TxCoalescingTicksDuringInt =
+                DEFAULT_TX_COALESCING_TICKS_DURING_INT;
+        }
+
+        if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->RxMaxCoalescedFramesDuringInt =
+                DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
+        }
+
+        if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->TxMaxCoalescedFramesDuringInt =
+                DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
+        }
+    }
+    else
+    {
+        if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->RxCoalescingTicksDuringInt = 0;
+        }
+
+        if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->TxCoalescingTicksDuringInt = 0;
+        }
+
+        if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->RxMaxCoalescedFramesDuringInt = 0;
+        }
+
+        if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+        {
+            pDevice->TxMaxCoalescedFramesDuringInt = 0;
+        }
+    }
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    if(pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */))
+    {
+        pDevice->RxJumboDescCnt = 0;
+        if(pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC)
+        {
+            pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+        }
+    }
+    else
+    {
+        pDevice->RxJumboBufferSize = (pDevice->RxMtu + 8 /* CRC + VLAN */ +
+            COMMON_CACHE_LINE_SIZE-1) & ~COMMON_CACHE_LINE_MASK;
+
+        if(pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE)
+        {
+            pDevice->RxJumboBufferSize = DEFAULT_JUMBO_RCV_BUFFER_SIZE;
+            pDevice->RxMtu = pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */;
+        }
+        pDevice->TxMtu = pDevice->RxMtu;
+
+    }
+#else
+    pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    pDevice->RxPacketDescCnt =
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+        pDevice->RxJumboDescCnt +
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+        pDevice->RxStdDescCnt;
+
+    if(pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC)
+    {
+        pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+    }
+
+    if(pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE)
+    {
+        pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
+    }
+
+    /* Configure the proper ways to get link change interrupt. */
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO)
+    {
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+        {
+            pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+        }
+        else
+        {
+            pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
+        }
+    }
+    else if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+    {
+        /* Auto-polling does not work on 5700_AX and 5700_BX. */
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+        {
+            pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+        }
+    }
+
+    /* Determine the method to get link change status. */
+    if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO)
+    {
+        /* The link status bit in the status block does not work on 5700_AX */
+        /* and 5700_BX chips. */
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+        {
+            pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
+        }
+        else
+        {
+            pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
+        }
+    }
+
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
+        T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+    {
+        pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
+    }
+
+    /* Configure PHY led mode. */
+    if(pDevice->LedMode == LED_MODE_AUTO)
+    {
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            if(pDevice->SubsystemVendorId == T3_SVID_DELL)
+            {
+                pDevice->LedMode = LED_MODE_LINK10;
+            }
+            else
+            {
+                pDevice->LedMode = LED_MODE_THREE_LINK;
+
+                if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
+                {
+                    pDevice->LedMode = EePhyLedMode;
+                }
+            }
+
+            /* bug? 5701 in LINK10 mode does not seem to work when */
+            /* PhyIntMode is LINK_READY. */
+            if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+#if INCLUDE_TBI_SUPPORT
+                pDevice->EnableTbi == FALSE &&
+#endif
+                pDevice->LedMode == LED_MODE_LINK10)
+            {
+                pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+                pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
+            }
+
+            if(pDevice->EnableTbi)
+            {
+                pDevice->LedMode = LED_MODE_THREE_LINK;
+            }
+        }
+        else
+        {
+            if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
+            {
+                pDevice->LedMode = EePhyLedMode;
+            }
+            else
+            {
+                pDevice->LedMode = LED_MODE_OPEN_DRAIN;
+            }
+        }
+    }
+
+    /* Enable OneDmaAtOnce. */
+    if(pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE)
+    {
+        pDevice->OneDmaAtOnce = FALSE;
+    }
+
+    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+        pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+        pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
+        pDevice->ChipRevId == T3_CHIP_ID_5701_B2)
+    {
+        pDevice->WolSpeed = WOL_SPEED_10MB;
+    }
+    else
+    {
+        pDevice->WolSpeed = WOL_SPEED_100MB;
+    }
+
+    /* Offloadings. */
+    pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
+
+    /* Turn off task offloading on Ax. */
+    if(pDevice->ChipRevId == T3_CHIP_ID_5700_B0)
+    {
+        pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
+            LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
+    }
+    pDevice->PciState = REG_RD(pDevice, PciCfg.PciState);
+    LM_ReadVPD(pDevice);
+    LM_ReadBootCodeVersion(pDevice);
+    LM_GetBusSpeed(pDevice);
+
+    return LM_STATUS_SUCCESS;
+} /* LM_GetAdapterInfo */
+
+STATIC PLM_ADAPTER_INFO
+LM_GetAdapterInfoBySsid(
+    LM_UINT16 Svid,
+    LM_UINT16 Ssid)
+{
+    static LM_ADAPTER_INFO AdapterArr[] =
+    {
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6, PHY_BCM5401_PHY_ID, 0},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5, PHY_BCM5701_PHY_ID, 0},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6, PHY_BCM8002_PHY_ID, 1},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1 },
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1, PHY_BCM5701_PHY_ID, 0},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8, PHY_BCM5701_PHY_ID, 0},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10, PHY_BCM5701_PHY_ID, 0},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12, PHY_BCM5701_PHY_ID, 0},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1, PHY_BCM5701_PHY_ID, 0},
+        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2, PHY_BCM5701_PHY_ID, 0},
+
+        { T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0 },
+        { T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0 },
+        { T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1 },
+        { T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0 },
+        { T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0 },
+
+        { T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0 },
+        { T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0 },
+        { T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0 },
+        { T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0 },
+
+        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0 },
+        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID, 0 },
+        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1 },
+        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0 },
+        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID, 0 },
+
+    };
+    LM_UINT32 j;
+
+    for(j = 0; j < sizeof(AdapterArr)/sizeof(LM_ADAPTER_INFO); j++)
+    {
+        if(AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid)
+        {
+            return &AdapterArr[j];
+        }
+    }
+
+    return NULL;
+}
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine sets up receive/transmit buffer descriptions queues.       */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_InitializeAdapter(
+PLM_DEVICE_BLOCK pDevice)
+{
+    LM_PHYSICAL_ADDRESS MemPhy;
+    PLM_UINT8 pMemVirt;
+    PLM_PACKET pPacket;
+    LM_STATUS Status;
+    LM_UINT32 Size;
+    LM_UINT32 j;
+
+    /* Set power state to D0. */
+    LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
+
+    /* Intialize the queues. */
+    QQ_InitQueue(&pDevice->RxPacketReceivedQ.Container,
+        MAX_RX_PACKET_DESC_COUNT);
+    QQ_InitQueue(&pDevice->RxPacketFreeQ.Container,
+        MAX_RX_PACKET_DESC_COUNT);
+
+    QQ_InitQueue(&pDevice->TxPacketFreeQ.Container,MAX_TX_PACKET_DESC_COUNT);
+    QQ_InitQueue(&pDevice->TxPacketActiveQ.Container,MAX_TX_PACKET_DESC_COUNT);
+    QQ_InitQueue(&pDevice->TxPacketXmittedQ.Container,MAX_TX_PACKET_DESC_COUNT);
+
+    /* Allocate shared memory for: status block, the buffers for receive */
+    /* rings -- standard, mini, jumbo, and return rings. */
+    Size = T3_STATUS_BLOCK_SIZE + sizeof(T3_STATS_BLOCK) +
+        T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+        T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+        T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+
+    /* Memory for host based Send BD. */
+    if(pDevice->NicSendBd == FALSE)
+    {
+        Size += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
+    }
+
+    /* Allocate the memory block. */
+    Status = MM_AllocateSharedMemory(pDevice, Size, (PLM_VOID) &pMemVirt, &MemPhy, FALSE);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+
+    /* Program DMA Read/Write */
+    if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS)
+    {
+        pDevice->DmaReadWriteCtrl = 0x763f000f;
+    }
+    else
+    {
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
+        {
+            pDevice->DmaReadWriteCtrl = 0x761f0000;
+        }
+        else
+        {
+            pDevice->DmaReadWriteCtrl = 0x761b000f;
+        }
+        if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
+            pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
+        {
+            pDevice->OneDmaAtOnce = TRUE;
+        }
+    }
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
+    {
+        pDevice->DmaReadWriteCtrl &= 0xfffffff0;
+    }
+
+    if(pDevice->OneDmaAtOnce)
+    {
+        pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
+    }
+    REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
+
+    if (LM_DmaTest(pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS)
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    /* Status block. */
+    pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
+    pDevice->StatusBlkPhy = MemPhy;
+    pMemVirt += T3_STATUS_BLOCK_SIZE;
+    LM_INC_PHYSICAL_ADDRESS(&MemPhy, T3_STATUS_BLOCK_SIZE);
+
+    /* Statistics block. */
+    pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
+    pDevice->StatsBlkPhy = MemPhy;
+    pMemVirt += sizeof(T3_STATS_BLOCK);
+    LM_INC_PHYSICAL_ADDRESS(&MemPhy, sizeof(T3_STATS_BLOCK));
+
+    /* Receive standard BD buffer. */
+    pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
+    pDevice->RxStdBdPhy = MemPhy;
+
+    pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+    LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+        T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    /* Receive jumbo BD buffer. */
+    pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
+    pDevice->RxJumboBdPhy = MemPhy;
+
+    pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+    LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+        T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    /* Receive return BD buffer. */
+    pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
+    pDevice->RcvRetBdPhy = MemPhy;
+
+    pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+    LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+        T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
+
+    /* Set up Send BD. */
+    if(pDevice->NicSendBd == FALSE)
+    {
+        pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
+        pDevice->SendBdPhy = MemPhy;
+
+        pMemVirt += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
+        LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+            sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT);
+    }
+    else
+    {
+        pDevice->pSendBdVirt = (PT3_SND_BD)
+            pDevice->pMemView->uIntMem.First32k.BufferDesc;
+        pDevice->SendBdPhy.High = 0;
+        pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
+    }
+
+    /* Allocate memory for packet descriptors. */
+    Size = (pDevice->RxPacketDescCnt +
+        pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
+    Status = MM_AllocateMemory(pDevice, Size, (PLM_VOID *) &pPacket);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+    pDevice->pPacketDescBase = (PLM_VOID) pPacket;
+
+    /* Create transmit packet descriptors from the memory block and add them */
+    /* to the TxPacketFreeQ for each send ring. */
+    for(j = 0; j < pDevice->TxPacketDescCnt; j++)
+    {
+        /* Ring index. */
+        pPacket->Flags = 0;
+
+        /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
+        QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
+
+        /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
+        /* is the total size of the packet descriptor including the */
+        /* os-specific extensions in the UM_PACKET structure. */
+        pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+    } /* for(j.. */
+
+    /* Create receive packet descriptors from the memory block and add them */
+    /* to the RxPacketFreeQ.  Create the Standard packet descriptors. */
+    for(j = 0; j < pDevice->RxStdDescCnt; j++)
+    {
+        /* Receive producer ring. */
+        pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
+
+        /* Receive buffer size. */
+        pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
+
+        /* Add the descriptor to RxPacketFreeQ. */
+        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+        /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
+        /* is the total size of the packet descriptor including the */
+        /* os-specific extensions in the UM_PACKET structure. */
+        pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+    } /* for */
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    /* Create the Jumbo packet descriptors. */
+    for(j = 0; j < pDevice->RxJumboDescCnt; j++)
+    {
+        /* Receive producer ring. */
+        pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
+
+        /* Receive buffer size. */
+        pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
+
+        /* Add the descriptor to RxPacketFreeQ. */
+        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+        /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
+        /* is the total size of the packet descriptor including the */
+        /* os-specific extensions in the UM_PACKET structure. */
+        pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+    } /* for */
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    /* Initialize the rest of the packet descriptors. */
+    Status = MM_InitializeUmPackets(pDevice);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    } /* if */
+
+    /* Default receive mask. */
+    pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
+        LM_ACCEPT_UNICAST;
+
+    /* Make sure we are in the first 32k memory window or NicSendBd. */
+    REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
+
+    /* Initialize the hardware. */
+    Status = LM_ResetAdapter(pDevice);
+    if(Status != LM_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+
+    /* We are done with initialization. */
+    pDevice->InitDone = TRUE;
+
+    return LM_STATUS_SUCCESS;
+} /* LM_InitializeAdapter */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This function Enables/Disables a given block.                          */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_CntrlBlock(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 mask,LM_UINT32 cntrl)
+{
+    LM_UINT32 j,i,data;
+    LM_UINT32 MaxWaitCnt;
+
+    MaxWaitCnt = 2;
+    j = 0;
+
+    for(i = 0 ; i < 32; i++)
+    {
+        if(!(mask & (1 << i)))
+            continue;
+
+        switch (1 << i)
+        {
+            case T3_BLOCK_DMA_RD:
+                data = REG_RD(pDevice, DmaRead.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~DMA_READ_MODE_ENABLE;
+                    REG_WR(pDevice, DmaRead.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, DmaRead.Mode) & DMA_READ_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, DmaRead.Mode, data | DMA_READ_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_DMA_COMP:
+                data = REG_RD(pDevice,DmaComp.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~DMA_COMP_MODE_ENABLE;
+                    REG_WR(pDevice, DmaComp.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, DmaComp.Mode) & DMA_COMP_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, DmaComp.Mode, data | DMA_COMP_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_RX_BD_INITIATOR:
+                data = REG_RD(pDevice, RcvBdIn.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~RCV_BD_IN_MODE_ENABLE;
+                    REG_WR(pDevice, RcvBdIn.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, RcvBdIn.Mode) & RCV_BD_IN_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, RcvBdIn.Mode,data | RCV_BD_IN_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_RX_BD_COMP:
+                data = REG_RD(pDevice, RcvBdComp.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~RCV_BD_COMP_MODE_ENABLE;
+                    REG_WR(pDevice, RcvBdComp.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, RcvBdComp.Mode) & RCV_BD_COMP_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, RcvBdComp.Mode,data | RCV_BD_COMP_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_DMA_WR:
+                data = REG_RD(pDevice, DmaWrite.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~DMA_WRITE_MODE_ENABLE;
+                    REG_WR(pDevice, DmaWrite.Mode,data);
+
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, DmaWrite.Mode,data | DMA_WRITE_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_MSI_HANDLER:
+                data = REG_RD(pDevice, Msi.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~MSI_MODE_ENABLE;
+                    REG_WR(pDevice, Msi.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, Msi.Mode) & MSI_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, Msi.Mode, data |MSI_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_RX_LIST_PLMT:
+                data = REG_RD(pDevice, RcvListPlmt.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~RCV_LIST_PLMT_MODE_ENABLE;
+                    REG_WR(pDevice, RcvListPlmt.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, RcvListPlmt.Mode) & RCV_LIST_PLMT_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, RcvListPlmt.Mode,data | RCV_LIST_PLMT_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_RX_LIST_SELECTOR:
+                data = REG_RD(pDevice, RcvListSel.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~RCV_LIST_SEL_MODE_ENABLE;
+                    REG_WR(pDevice, RcvListSel.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, RcvListSel.Mode) & RCV_LIST_SEL_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, RcvListSel.Mode,data |RCV_LIST_SEL_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_RX_DATA_INITIATOR:
+                data = REG_RD(pDevice, RcvDataBdIn.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
+                    REG_WR(pDevice, RcvDataBdIn.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_BD_IN_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, RcvDataBdIn.Mode, data | RCV_DATA_BD_IN_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_RX_DATA_COMP:
+                data = REG_RD(pDevice, RcvDataComp.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~RCV_DATA_COMP_MODE_ENABLE;
+                    REG_WR(pDevice, RcvDataComp.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_COMP_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, RcvDataComp.Mode,data | RCV_DATA_COMP_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_HOST_COALESING:
+                data = REG_RD(pDevice, HostCoalesce.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~HOST_COALESCE_ENABLE;
+                    REG_WR(pDevice, HostCoalesce.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, SndBdIn.Mode) & HOST_COALESCE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, HostCoalesce.Mode, data | HOST_COALESCE_ENABLE);
+                break;
+
+            case T3_BLOCK_MAC_RX_ENGINE:
+                if(cntrl == LM_DISABLE)
+                {
+                    pDevice->RxMode &= ~RX_MODE_ENABLE;
+                    REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, MacCtrl.RxMode) & RX_MODE_ENABLE))
+                        {
+                            break;
+                        }
+                        MM_Wait(10);
+                    }
+                }
+                else
+                {
+                    pDevice->RxMode |= RX_MODE_ENABLE;
+                    REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+                }
+                break;
+
+            case T3_BLOCK_MBUF_CLUSTER_FREE:
+                data = REG_RD(pDevice, MbufClusterFree.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
+                    REG_WR(pDevice, MbufClusterFree.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, MbufClusterFree.Mode) & MBUF_CLUSTER_FREE_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, MbufClusterFree.Mode, data | MBUF_CLUSTER_FREE_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_SEND_BD_INITIATOR:
+                data = REG_RD(pDevice, SndBdIn.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~SND_BD_IN_MODE_ENABLE;
+                    REG_WR(pDevice, SndBdIn.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, SndBdIn.Mode) & SND_BD_IN_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, SndBdIn.Mode, data  | SND_BD_IN_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_SEND_BD_COMP:
+                data = REG_RD(pDevice, SndBdComp.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~SND_BD_COMP_MODE_ENABLE;
+                    REG_WR(pDevice, SndBdComp.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, SndBdComp.Mode) & SND_BD_COMP_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, SndBdComp.Mode, data | SND_BD_COMP_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_SEND_BD_SELECTOR:
+                data = REG_RD(pDevice, SndBdSel.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~SND_BD_SEL_MODE_ENABLE;
+                    REG_WR(pDevice, SndBdSel.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, SndBdSel.Mode) & SND_BD_SEL_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, SndBdSel.Mode, data | SND_BD_SEL_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_SEND_DATA_INITIATOR:
+                data = REG_RD(pDevice, SndDataIn.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~T3_SND_DATA_IN_MODE_ENABLE;
+                    REG_WR(pDevice, SndDataIn.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, SndDataIn.Mode) & T3_SND_DATA_IN_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, SndDataIn.Mode,data | T3_SND_DATA_IN_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_SEND_DATA_COMP:
+                data = REG_RD(pDevice, SndDataComp.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~SND_DATA_COMP_MODE_ENABLE;
+                    REG_WR(pDevice, SndDataComp.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, SndDataComp.Mode) & SND_DATA_COMP_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, SndDataComp.Mode,data | SND_DATA_COMP_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_MAC_TX_ENGINE:
+                if(cntrl == LM_DISABLE)
+                {
+                    pDevice->TxMode &= ~TX_MODE_ENABLE;
+                    REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, MacCtrl.TxMode) & TX_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                {
+                    pDevice->TxMode |= TX_MODE_ENABLE;
+                    REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+                }
+                break;
+
+            case T3_BLOCK_MEM_ARBITOR:
+                data = REG_RD(pDevice, MemArbiter.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~T3_MEM_ARBITER_MODE_ENABLE;
+                    REG_WR(pDevice, MemArbiter.Mode, data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, MemArbiter.Mode) & T3_MEM_ARBITER_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, MemArbiter.Mode,data|T3_MEM_ARBITER_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_MBUF_MANAGER:
+                data = REG_RD(pDevice, BufMgr.Mode);
+                if (cntrl == LM_DISABLE)
+                {
+                    data &= ~BUFMGR_MODE_ENABLE;
+                    REG_WR(pDevice, BufMgr.Mode,data);
+                    for(j = 0; j < MaxWaitCnt; j++)
+                    {
+                        if(!(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE))
+                            break;
+                        MM_Wait(10);
+                    }
+                }
+                else
+                    REG_WR(pDevice, BufMgr.Mode,data |  BUFMGR_MODE_ENABLE);
+                break;
+
+            case T3_BLOCK_MAC_GLOBAL:
+                if(cntrl == LM_DISABLE)
+                {
+                    pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
+                        MAC_MODE_ENABLE_RDE |
+                        MAC_MODE_ENABLE_FHDE);
+                }
+                else
+                {
+                    pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
+                        MAC_MODE_ENABLE_RDE |
+                        MAC_MODE_ENABLE_FHDE);
+                }
+                REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+                break;
+
+            default:
+                return LM_STATUS_FAILURE;
+        } /* switch */
+
+        if(j >= MaxWaitCnt)
+        {
+            return LM_STATUS_FAILURE;
+        }
+    }
+
+    return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This function reinitializes the adapter.                                */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_ResetAdapter(
+PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Value32;
+    LM_UINT16 Value16;
+    LM_UINT32 j, k;
+
+    /* Disable interrupt. */
+    LM_DisableInterrupt(pDevice);
+
+    /* May get a spurious interrupt */
+    pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
+
+    /* Disable transmit and receive DMA engines.  Abort all pending requests. */
+    if(pDevice->InitDone)
+    {
+        LM_Abort(pDevice);
+    }
+
+    pDevice->ShuttingDown = FALSE;
+
+    LM_ResetChip(pDevice);
+
+    /* Bug: Athlon fix for B3 silicon only.  This bit does not do anything */
+    /* in other chip revisions. */
+    if(pDevice->DelayPciGrant)
+    {
+        Value32 = REG_RD(pDevice, PciCfg.ClockCtrl);
+        REG_WR(pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
+    }
+
+    if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+    {
+        if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+        {
+            Value32 = REG_RD(pDevice, PciCfg.PciState);
+            Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
+            REG_WR(pDevice, PciCfg.PciState, Value32);
+        }
+    }
+
+    /* Enable TaggedStatus mode. */
+    if(pDevice->UseTaggedStatus)
+    {
+        pDevice->MiscHostCtrl |= MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
+    }
+
+    /* Restore PCI configuration registers. */
+    MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
+        pDevice->SavedCacheLineReg);
+    MM_WriteConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
+        (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
+
+    /* Clear the statistics block. */
+    for(j = 0x0300; j < 0x0b00; j++)
+    {
+        MEM_WR_OFFSET(pDevice, j, 0);
+    }
+
+    /* Initialize the statistis Block */
+    pDevice->pStatusBlkVirt->Status = 0;
+    pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
+    pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
+    pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
+
+    for(j = 0; j < 16; j++)
+    {
+       pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
+       pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
+    }
+
+    for(k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT ;k++)
+    {
+       pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
+       pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
+    }
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    /* Receive jumbo BD buffer. */
+    for(k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++)
+    {
+        pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
+        pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
+    }
+#endif
+
+    REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
+
+    /* GRC mode control register. */
+#ifdef BIG_ENDIAN_PCI    /* Jimmy, this ifdef block deleted in new code! */
+    Value32 =
+        GRC_MODE_WORD_SWAP_DATA |
+        GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+        GRC_MODE_INT_ON_MAC_ATTN |
+        GRC_MODE_HOST_STACK_UP;
+#else
+    /* No CPU Swap modes for PCI IO */
+    Value32 =
+#ifdef BIG_ENDIAN_HOST
+        GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+        GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+        GRC_MODE_BYTE_SWAP_DATA |
+        GRC_MODE_WORD_SWAP_DATA |
+#else
+        GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+        GRC_MODE_BYTE_SWAP_DATA |
+        GRC_MODE_WORD_SWAP_DATA |
+#endif
+        GRC_MODE_INT_ON_MAC_ATTN |
+        GRC_MODE_HOST_STACK_UP;
+#endif /* !BIG_ENDIAN_PCI */
+
+    /* Configure send BD mode. */
+    if(pDevice->NicSendBd == FALSE)
+    {
+        Value32 |= GRC_MODE_HOST_SEND_BDS;
+    }
+    else
+    {
+        Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
+    }
+
+    /* Configure pseudo checksum mode. */
+    if(pDevice->NoTxPseudoHdrChksum)
+    {
+        Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
+    }
+
+    if(pDevice->NoRxPseudoHdrChksum)
+    {
+        Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
+    }
+
+    REG_WR(pDevice, Grc.Mode, Value32);
+
+    /* Setup the timer prescalar register. */
+    REG_WR(pDevice, Grc.MiscCfg, 65 << 1);      /* Clock is alwasy 66Mhz. */
+
+    /* Set up the MBUF pool base address and size. */
+    REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
+    REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
+
+    /* Set up the DMA descriptor pool base address and size. */
+    REG_WR(pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
+    REG_WR(pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
+
+    /* Configure MBUF and Threshold watermarks */
+    /* Configure the DMA read MBUF low water mark. */
+    if(pDevice->DmaMbufLowMark)
+    {
+        REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
+            pDevice->DmaMbufLowMark);
+    }
+    else
+    {
+        if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
+        {
+            REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
+                T3_DEF_DMA_MBUF_LOW_WMARK);
+        }
+        else
+        {
+            REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
+                T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
+        }
+    }
+
+    /* Configure the MAC Rx MBUF low water mark. */
+    if(pDevice->RxMacMbufLowMark)
+    {
+        REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
+            pDevice->RxMacMbufLowMark);
+    }
+    else
+    {
+        if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
+        {
+            REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
+                T3_DEF_RX_MAC_MBUF_LOW_WMARK);
+        }
+        else
+        {
+            REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
+                T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
+        }
+    }
+
+    /* Configure the MBUF high water mark. */
+    if(pDevice->MbufHighMark)
+    {
+        REG_WR(pDevice, BufMgr.MbufHighWaterMark, pDevice->MbufHighMark);
+    }
+    else
+    {
+        if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
+        {
+            REG_WR(pDevice, BufMgr.MbufHighWaterMark,
+                T3_DEF_MBUF_HIGH_WMARK);
+        }
+        else
+        {
+            REG_WR(pDevice, BufMgr.MbufHighWaterMark,
+                T3_DEF_MBUF_HIGH_WMARK_JUMBO);
+        }
+    }
+
+    REG_WR(pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
+    REG_WR(pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
+
+    /* Enable buffer manager. */
+    REG_WR(pDevice, BufMgr.Mode, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
+
+    for(j = 0 ;j < 2000; j++)
+    {
+        if(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
+            break;
+        MM_Wait(10);
+    }
+
+    if(j >= 2000)
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    /* Enable the FTQs. */
+    REG_WR(pDevice, Ftq.Reset, 0xffffffff);
+    REG_WR(pDevice, Ftq.Reset, 0);
+
+    /* Wait until FTQ is ready */
+    for(j = 0; j < 2000; j++)
+    {
+        if(REG_RD(pDevice, Ftq.Reset) == 0)
+            break;
+        MM_Wait(10);
+    }
+
+    if(j >= 2000)
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    /* Initialize the Standard Receive RCB. */
+    REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
+        pDevice->RxStdBdPhy.High);
+    REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
+        pDevice->RxStdBdPhy.Low);
+    REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
+        MAX_STD_RCV_BUFFER_SIZE << 16);
+
+    /* Initialize the Jumbo Receive RCB. */
+    REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
+        T3_RCB_FLAG_RING_DISABLED);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
+        pDevice->RxJumboBdPhy.High);
+    REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
+        pDevice->RxJumboBdPhy.Low);
+
+    REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
+
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    /* Initialize the Mini Receive RCB. */
+    REG_WR(pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
+        T3_RCB_FLAG_RING_DISABLED);
+
+    {
+        REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
+            (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
+        REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
+            (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
+    }
+
+    /* Receive BD Ring replenish threshold. */
+    REG_WR(pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt/8);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    REG_WR(pDevice, RcvBdIn.JumboRcvThreshold, pDevice->RxJumboDescCnt/8);
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    /* Disable all the unused rings. */
+    for(j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
+        MEM_WR(pDevice, SendRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
+    } /* for */
+
+    /* Initialize the indices. */
+    pDevice->SendProdIdx = 0;
+    pDevice->SendConIdx = 0;
+
+    MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
+    MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
+
+    /* Set up host or NIC based send RCB. */
+    if(pDevice->NicSendBd == FALSE)
+    {
+        MEM_WR(pDevice, SendRcb[0].HostRingAddr.High,
+            pDevice->SendBdPhy.High);
+        MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low,
+            pDevice->SendBdPhy.Low);
+
+        /* Set up the NIC ring address in the RCB. */
+        MEM_WR(pDevice, SendRcb[0].NicRingAddr,T3_NIC_SND_BUFFER_DESC_ADDR);
+
+        /* Setup the RCB. */
+        MEM_WR(pDevice, SendRcb[0].u.MaxLen_Flags,
+            T3_SEND_RCB_ENTRY_COUNT << 16);
+
+        for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
+        {
+            pDevice->pSendBdVirt[k].HostAddr.High = 0;
+            pDevice->pSendBdVirt[k].HostAddr.Low = 0;
+        }
+    }
+    else
+    {
+        MEM_WR(pDevice, SendRcb[0].HostRingAddr.High, 0);
+        MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low, 0);
+        MEM_WR(pDevice, SendRcb[0].NicRingAddr,
+            pDevice->SendBdPhy.Low);
+
+        for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
+        {
+            __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.High));
+            __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.Low));
+            __raw_writel(0, &(pDevice->pSendBdVirt[k].u1.Len_Flags));
+            pDevice->ShadowSendBd[k].HostAddr.High = 0;
+            pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
+        }
+    }
+    atomic_set(&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT-1);
+
+    /* Configure the receive return rings. */
+    for(j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++)
+    {
+        MEM_WR(pDevice, RcvRetRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
+    }
+
+    pDevice->RcvRetConIdx = 0;
+
+    MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.High,
+        pDevice->RcvRetBdPhy.High);
+    MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.Low,
+        pDevice->RcvRetBdPhy.Low);
+
+    /* Set up the NIC ring address in the RCB. */
+    /* Not very clear from the spec.  I am guessing that for Receive */
+    /* Return Ring, NicRingAddr is not used. */
+    MEM_WR(pDevice, RcvRetRcb[0].NicRingAddr, 0);
+
+    /* Setup the RCB. */
+    MEM_WR(pDevice, RcvRetRcb[0].u.MaxLen_Flags,
+        T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
+
+    /* Reinitialize RX ring producer index */
+    MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, 0);
+    MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
+    MB_REG_WR(pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    pDevice->RxJumboProdIdx = 0;
+    pDevice->RxJumboQueuedCnt = 0;
+#endif
+
+    /* Reinitialize our copy of the indices. */
+    pDevice->RxStdProdIdx = 0;
+    pDevice->RxStdQueuedCnt = 0;
+
+#if T3_JUMBO_RCV_ENTRY_COUNT
+    pDevice->RxJumboProdIdx = 0;
+#endif /* T3_JUMBO_RCV_ENTRY_COUNT */
+
+    /* Configure the MAC address. */
+    LM_SetMacAddress(pDevice, pDevice->NodeAddress);
+
+    /* Initialize the transmit random backoff seed. */
+    Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
+        pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
+        pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
+        MAC_TX_BACKOFF_SEED_MASK;
+    REG_WR(pDevice, MacCtrl.TxBackoffSeed, Value32);
+
+    /* Receive MTU.  Frames larger than the MTU is marked as oversized. */
+    REG_WR(pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8);   /* CRC + VLAN. */
+
+    /* Configure Time slot/IPG per 802.3 */
+    REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
+
+    /*
+     * Configure Receive Rules so that packets don't match
+     * Programmble rule will be queued to Return Ring 1
+     */
+    REG_WR(pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
+
+    /*
+     * Configure to have 16 Classes of Services (COS) and one
+     * queue per class.  Bad frames are queued to RRR#1.
+     * And frames don't match rules are also queued to COS#1.
+     */
+    REG_WR(pDevice, RcvListPlmt.Config, 0x181);
+
+    /* Enable Receive Placement Statistics */
+    REG_WR(pDevice, RcvListPlmt.StatsEnableMask,0xffffff);
+    REG_WR(pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
+
+    /* Enable Send Data Initator Statistics */
+    REG_WR(pDevice, SndDataIn.StatsEnableMask,0xffffff);
+    REG_WR(pDevice, SndDataIn.StatsCtrl,
+        T3_SND_DATA_IN_STATS_CTRL_ENABLE | \
+        T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
+
+    /* Disable the host coalescing state machine before configuring it's */
+    /* parameters. */
+    REG_WR(pDevice, HostCoalesce.Mode, 0);
+    for(j = 0; j < 2000; j++)
+    {
+        Value32 = REG_RD(pDevice, HostCoalesce.Mode);
+        if(!(Value32 & HOST_COALESCE_ENABLE))
+        {
+            break;
+        }
+        MM_Wait(10);
+    }
+
+    /* Host coalescing configurations. */
+    REG_WR(pDevice, HostCoalesce.RxCoalescingTicks, pDevice->RxCoalescingTicks);
+    REG_WR(pDevice, HostCoalesce.TxCoalescingTicks, pDevice->TxCoalescingTicks);
+    REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFrames,
+        pDevice->RxMaxCoalescedFrames);
+    REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFrames,
+        pDevice->TxMaxCoalescedFrames);
+    REG_WR(pDevice, HostCoalesce.RxCoalescedTickDuringInt,
+        pDevice->RxCoalescingTicksDuringInt);
+    REG_WR(pDevice, HostCoalesce.TxCoalescedTickDuringInt,
+        pDevice->TxCoalescingTicksDuringInt);
+    REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
+        pDevice->RxMaxCoalescedFramesDuringInt);
+    REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
+        pDevice->TxMaxCoalescedFramesDuringInt);
+
+    /* Initialize the address of the status block.  The NIC will DMA */
+    /* the status block to this memory which resides on the host. */
+    REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.High,
+        pDevice->StatusBlkPhy.High);
+    REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.Low,
+        pDevice->StatusBlkPhy.Low);
+
+    /* Initialize the address of the statistics block.  The NIC will DMA */
+    /* the statistics to this block of memory. */
+    REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.High,
+        pDevice->StatsBlkPhy.High);
+    REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.Low,
+        pDevice->StatsBlkPhy.Low);
+
+    REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
+        pDevice->StatsCoalescingTicks);
+
+    REG_WR(pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
+    REG_WR(pDevice, HostCoalesce.StatusBlkNicAddr,0xb00);
+
+    /* Enable Host Coalesing state machine */
+    REG_WR(pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
+        pDevice->CoalesceMode);
+
+    /* Enable the Receive BD Completion state machine. */
+    REG_WR(pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
+        RCV_BD_COMP_MODE_ATTN_ENABLE);
+
+    /* Enable the Receive List Placement state machine. */
+    REG_WR(pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
+
+    /* Enable the Receive List Selector state machine. */
+    REG_WR(pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
+        RCV_LIST_SEL_MODE_ATTN_ENABLE);
+
+    /* Enable transmit DMA, clear statistics. */
+    pDevice->MacMode =  MAC_MODE_ENABLE_TX_STATISTICS |
+        MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
+        MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+        MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
+
+    /* GRC miscellaneous local control register. */
+    pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
+        GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
+
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+    {
+        pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+            GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
+    }
+
+    REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
+    MM_Wait(40);
+
+    /* Reset RX counters. */
+    for(j = 0; j < sizeof(LM_RX_COUNTERS); j++)
+    {
+        ((PLM_UINT8) &pDevice->RxCounters)[j] = 0;
+    }
+
+    /* Reset TX counters. */
+    for(j = 0; j < sizeof(LM_TX_COUNTERS); j++)
+    {
+        ((PLM_UINT8) &pDevice->TxCounters)[j] = 0;
+    }
+
+    MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
+
+    /* Enable the DMA Completion state machine. */
+    REG_WR(pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
+
+    /* Enable the DMA Write state machine. */
+    Value32 = DMA_WRITE_MODE_ENABLE |
+        DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
+        DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
+        DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
+        DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
+        DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
+        DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
+        DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
+        DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
+    REG_WR(pDevice, DmaWrite.Mode, Value32);
+
+    if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+    {
+        if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+        {
+            Value16 = REG_RD(pDevice, PciCfg.PciXCommand);
+            Value16 &= ~(PCIX_CMD_MAX_SPLIT_MASK | PCIX_CMD_MAX_BURST_MASK);
+            Value16 |= ((PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL) &
+                PCIX_CMD_MAX_BURST_MASK);
+            if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
+            {
+                Value16 |= (pDevice->SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
+                   & PCIX_CMD_MAX_SPLIT_MASK;
+            }
+            REG_WR(pDevice, PciCfg.PciXCommand, Value16);
+        }
+    }
+
+    /* Enable the Read DMA state machine. */
+    Value32 = DMA_READ_MODE_ENABLE |
+        DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
+        DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
+        DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
+        DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
+        DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
+        DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
+        DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
+        DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
+
+    if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
+    {
+        Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
+    }
+    REG_WR(pDevice, DmaRead.Mode, Value32);
+
+    /* Enable the Receive Data Completion state machine. */
+    REG_WR(pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
+        RCV_DATA_COMP_MODE_ATTN_ENABLE);
+
+    /* Enable the Mbuf Cluster Free state machine. */
+    REG_WR(pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
+
+    /* Enable the Send Data Completion state machine. */
+    REG_WR(pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
+
+    /* Enable the Send BD Completion state machine. */
+    REG_WR(pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
+        SND_BD_COMP_MODE_ATTN_ENABLE);
+
+    /* Enable the Receive BD Initiator state machine. */
+    REG_WR(pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
+        RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
+
+    /* Enable the Receive Data and Receive BD Initiator state machine. */
+    REG_WR(pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
+        RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
+
+    /* Enable the Send Data Initiator state machine. */
+    REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
+
+    /* Enable the Send BD Initiator state machine. */
+    REG_WR(pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
+        SND_BD_IN_MODE_ATTN_ENABLE);
+
+    /* Enable the Send BD Selector state machine. */
+    REG_WR(pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
+        SND_BD_SEL_MODE_ATTN_ENABLE);
+
+#if INCLUDE_5701_AX_FIX
+    /* Load the firmware for the 5701_A0 workaround. */
+    if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0)
+    {
+        LM_LoadRlsFirmware(pDevice);
+    }
+#endif
+
+    /* Enable the transmitter. */
+    pDevice->TxMode = TX_MODE_ENABLE;
+    REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+
+    /* Enable the receiver. */
+    pDevice->RxMode = RX_MODE_ENABLE;
+    REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+
+    if (pDevice->RestoreOnWakeUp)
+    {
+        pDevice->RestoreOnWakeUp = FALSE;
+        pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
+        pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
+    }
+
+    /* Disable auto polling. */
+    pDevice->MiMode = 0xc0000;
+    REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+        T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+    {
+        Value32 = LED_CTRL_PHY_MODE_1;
+    }
+    else
+    {
+        if(pDevice->LedMode == LED_MODE_OUTPUT)
+        {
+            Value32 = LED_CTRL_PHY_MODE_2;
+        }
+        else
+        {
+            Value32 = LED_CTRL_PHY_MODE_1;
+        }
+    }
+    REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
+
+    /* Activate Link to enable MAC state machine */
+    REG_WR(pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
+
+    if (pDevice->EnableTbi)
+    {
+        REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_RESET);
+        MM_Wait(10);
+        REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+        if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1)
+        {
+            REG_WR(pDevice, MacCtrl.SerdesCfg, 0x616000);
+        }
+    }
+    /* Setup the phy chip. */
+    LM_SetupPhy(pDevice);
+
+    if (!pDevice->EnableTbi) {
+        /* Clear CRC stats */
+        LM_ReadPhy(pDevice, 0x1e, &Value32);
+        LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
+        LM_ReadPhy(pDevice, 0x14, &Value32);
+    }
+
+    /* Set up the receive mask. */
+    LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
+
+    /* Queue Rx packet buffers. */
+    if(pDevice->QueueRxPackets)
+    {
+        LM_QueueRxPackets(pDevice);
+    }
+
+    /* Enable interrupt to the host. */
+    if(pDevice->InitDone)
+    {
+        LM_EnableInterrupt(pDevice);
+    }
+
+    return LM_STATUS_SUCCESS;
+} /* LM_ResetAdapter */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine disables the adapter from generating interrupts.           */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_DisableInterrupt(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
+        MISC_HOST_CTRL_MASK_PCI_INT);
+    MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
+
+    return LM_STATUS_SUCCESS;
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine enables the adapter to generate interrupts.                */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_EnableInterrupt(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
+        ~MISC_HOST_CTRL_MASK_PCI_INT);
+    MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
+
+    if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED)
+    {
+        REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+            GRC_MISC_LOCAL_CTRL_SET_INT);
+    }
+
+    return LM_STATUS_SUCCESS;
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine puts a packet on the wire if there is a transmit DMA       */
+/*    descriptor available; otherwise the packet is queued for later          */
+/*    transmission.  If the second argue is NULL, this routine will put       */
+/*    the queued packet on the wire if possible.                              */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+#if 0
+LM_STATUS
+LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+    LM_UINT32 FragCount;
+    PT3_SND_BD pSendBd;
+    PT3_SND_BD pShadowSendBd;
+    LM_UINT32 Value32, Len;
+    LM_UINT32 Idx;
+
+    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+        return LM_5700SendPacket(pDevice, pPacket);
+    }
+
+    /* Update the SendBdLeft count. */
+    atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+    /* Initalize the send buffer descriptors. */
+    Idx = pDevice->SendProdIdx;
+
+    pSendBd = &pDevice->pSendBdVirt[Idx];
+
+    /* Next producer index. */
+    if (pDevice->NicSendBd == TRUE)
+    {
+        T3_64BIT_HOST_ADDR paddr;
+
+        pShadowSendBd = &pDevice->ShadowSendBd[Idx];
+        for(FragCount = 0; ; )
+        {
+            MM_MapTxDma(pDevice, pPacket, &paddr, &Len, FragCount);
+            /* Initialize the pointer to the send buffer fragment. */
+            if (paddr.High != pShadowSendBd->HostAddr.High)
+            {
+                __raw_writel(paddr.High, &(pSendBd->HostAddr.High));
+                pShadowSendBd->HostAddr.High = paddr.High;
+            }
+            __raw_writel(paddr.Low, &(pSendBd->HostAddr.Low));
+
+            /* Setup the control flags and send buffer size. */
+            Value32 = (Len << 16) | pPacket->Flags;
+
+            Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+            FragCount++;
+            if (FragCount >= pPacket->u.Tx.FragCount)
+            {
+                Value32 |= SND_BD_FLAG_END;
+                if (Value32 != pShadowSendBd->u1.Len_Flags)
+                {
+                    __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
+                    pShadowSendBd->u1.Len_Flags = Value32;
+                }
+                if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
+                    __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
+                }
+                break;
+            }
+            else
+            {
+                if (Value32 != pShadowSendBd->u1.Len_Flags)
+                {
+                    __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
+                    pShadowSendBd->u1.Len_Flags = Value32;
+                }
+                if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
+                    __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
+                }
+            }
+
+            pSendBd++;
+            pShadowSendBd++;
+            if (Idx == 0)
+            {
+                pSendBd = &pDevice->pSendBdVirt[0];
+                pShadowSendBd = &pDevice->ShadowSendBd[0];
+            }
+        } /* for */
+
+        /* Put the packet descriptor in the ActiveQ. */
+        QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
+
+        wmb();
+        MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+
+    }
+    else
+    {
+        for(FragCount = 0; ; )
+        {
+            /* Initialize the pointer to the send buffer fragment. */
+            MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
+
+            pSendBd->u2.VlanTag = pPacket->VlanTag;
+
+            /* Setup the control flags and send buffer size. */
+            Value32 = (Len << 16) | pPacket->Flags;
+
+            Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+            FragCount++;
+            if (FragCount >= pPacket->u.Tx.FragCount)
+            {
+                pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
+                break;
+            }
+            else
+            {
+                pSendBd->u1.Len_Flags = Value32;
+            }
+            pSendBd++;
+            if (Idx == 0)
+            {
+                pSendBd = &pDevice->pSendBdVirt[0];
+            }
+        } /* for */
+
+        /* Put the packet descriptor in the ActiveQ. */
+        QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
+
+        wmb();
+        MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+
+    }
+
+    /* Update the producer index. */
+    pDevice->SendProdIdx = Idx;
+
+    return LM_STATUS_SUCCESS;
+}
+#endif
+
+LM_STATUS
+LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+    LM_UINT32 FragCount;
+    PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
+    T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
+    LM_UINT32 StartIdx, Idx;
+
+    while (1)
+    {
+        /* Initalize the send buffer descriptors. */
+        StartIdx = Idx = pDevice->SendProdIdx;
+
+        if (pDevice->NicSendBd)
+        {
+            pTmpSendBd = pSendBd = &NicSendBdArr[0];
+        }
+        else
+        {
+            pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
+        }
+
+        /* Next producer index. */
+        for(FragCount = 0; ; )
+        {
+            LM_UINT32 Value32, Len;
+
+            /* Initialize the pointer to the send buffer fragment. */
+            MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
+
+            pSendBd->u2.VlanTag = pPacket->VlanTag;
+
+            /* Setup the control flags and send buffer size. */
+            Value32 = (Len << 16) | pPacket->Flags;
+
+            Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+            FragCount++;
+            if (FragCount >= pPacket->u.Tx.FragCount)
+            {
+                pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
+                break;
+            }
+            else
+            {
+                pSendBd->u1.Len_Flags = Value32;
+            }
+            pSendBd++;
+            if ((Idx == 0) && !pDevice->NicSendBd)
+            {
+                pSendBd = &pDevice->pSendBdVirt[0];
+            }
+        } /* for */
+        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+        {
+            if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
+                LM_STATUS_SUCCESS)
+            {
+                if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
+                {
+                    QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
+                    return LM_STATUS_FAILURE;
+                }
+                continue;
+            }
+        }
+        break;
+    }
+    /* Put the packet descriptor in the ActiveQ. */
+    QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
+
+    if (pDevice->NicSendBd)
+    {
+        pSendBd = &pDevice->pSendBdVirt[StartIdx];
+        pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
+
+        while (StartIdx != Idx)
+        {
+            LM_UINT32 Value32;
+
+            if ((Value32 = pTmpSendBd->HostAddr.High) !=
+                pShadowSendBd->HostAddr.High)
+            {
+                __raw_writel(Value32, &(pSendBd->HostAddr.High));
+                pShadowSendBd->HostAddr.High = Value32;
+            }
+
+            __raw_writel(pTmpSendBd->HostAddr.Low, &(pSendBd->HostAddr.Low));
+
+            if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
+                pShadowSendBd->u1.Len_Flags)
+            {
+                __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
+                pShadowSendBd->u1.Len_Flags = Value32;
+            }
+
+            if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
+            {
+                __raw_writel(pTmpSendBd->u2.VlanTag, &(pSendBd->u2.VlanTag));
+            }
+
+            StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+            if (StartIdx == 0)
+                pSendBd = &pDevice->pSendBdVirt[0];
+            else
+                pSendBd++;
+            pTmpSendBd++;
+        }
+        wmb();
+        MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+
+        if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
+        {
+            MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+        }
+    }
+    else
+    {
+        wmb();
+        MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+
+        if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
+        {
+            MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+        }
+    }
+
+    /* Update the SendBdLeft count. */
+    atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+    /* Update the producer index. */
+    pDevice->SendProdIdx = Idx;
+
+    return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS
+LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
+    PT3_SND_BD pSendBd)
+{
+    int FragCount;
+    LM_UINT32 Idx, Base, Len;
+
+    Idx = pDevice->SendProdIdx;
+    for(FragCount = 0; ; )
+    {
+        Len = pSendBd->u1.Len_Flags >> 16;
+        if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
+            (pSendBd->HostAddr.High == 0) &&
+            ((Base + 8 + Len) < Base))
+        {
+            return LM_STATUS_SUCCESS;
+        }
+        FragCount++;
+        if (FragCount >= pPacket->u.Tx.FragCount)
+        {
+            break;
+        }
+        pSendBd++;
+        if (!pDevice->NicSendBd)
+        {
+            Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+            if (Idx == 0)
+            {
+                pSendBd = &pDevice->pSendBdVirt[0];
+            }
+        }
+    }
+    return LM_STATUS_FAILURE;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+__inline static unsigned long
+ComputeCrc32(
+unsigned char *pBuffer,
+unsigned long BufferSize) {
+    unsigned long Reg;
+    unsigned long Tmp;
+    unsigned long j, k;
+
+    Reg = 0xffffffff;
+
+    for(j = 0; j < BufferSize; j++)
+    {
+        Reg ^= pBuffer[j];
+
+        for(k = 0; k < 8; k++)
+        {
+            Tmp = Reg & 0x01;
+
+            Reg >>= 1;
+
+            if(Tmp)
+            {
+                Reg ^= 0xedb88320;
+            }
+        }
+    }
+
+    return ~Reg;
+} /* ComputeCrc32 */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine sets the receive control register according to ReceiveMask */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_SetReceiveMask(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 Mask) {
+    LM_UINT32 ReceiveMask;
+    LM_UINT32 RxMode;
+    LM_UINT32 j, k;
+
+    ReceiveMask = Mask;
+
+    RxMode = pDevice->RxMode;
+
+    if(Mask & LM_ACCEPT_UNICAST)
+    {
+        Mask &= ~LM_ACCEPT_UNICAST;
+    }
+
+    if(Mask & LM_ACCEPT_MULTICAST)
+    {
+        Mask &= ~LM_ACCEPT_MULTICAST;
+    }
+
+    if(Mask & LM_ACCEPT_ALL_MULTICAST)
+    {
+        Mask &= ~LM_ACCEPT_ALL_MULTICAST;
+    }
+
+    if(Mask & LM_ACCEPT_BROADCAST)
+    {
+        Mask &= ~LM_ACCEPT_BROADCAST;
+    }
+
+    RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
+    if(Mask & LM_PROMISCUOUS_MODE)
+    {
+        RxMode |= RX_MODE_PROMISCUOUS_MODE;
+        Mask &= ~LM_PROMISCUOUS_MODE;
+    }
+
+    RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
+    if(Mask & LM_ACCEPT_ERROR_PACKET)
+    {
+        RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
+        Mask &= ~LM_ACCEPT_ERROR_PACKET;
+    }
+
+    /* Make sure all the bits are valid before committing changes. */
+    if(Mask)
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    /* Commit the new filter. */
+    pDevice->RxMode = RxMode;
+    REG_WR(pDevice, MacCtrl.RxMode, RxMode);
+
+    pDevice->ReceiveMask = ReceiveMask;
+
+    /* Set up the MC hash table. */
+    if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
+    {
+        for(k = 0; k < 4; k++)
+        {
+            REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
+        }
+    }
+    else if(ReceiveMask & LM_ACCEPT_MULTICAST)
+    {
+        LM_UINT32 HashReg[4];
+
+        HashReg[0] = 0; HashReg[1] = 0; HashReg[2] = 0; HashReg[3] = 0;
+        for(j = 0; j < pDevice->McEntryCount; j++)
+        {
+            LM_UINT32 RegIndex;
+            LM_UINT32 Bitpos;
+            LM_UINT32 Crc32;
+
+            Crc32 = ComputeCrc32(pDevice->McTable[j], ETHERNET_ADDRESS_SIZE);
+
+            /* The most significant 7 bits of the CRC32 (no inversion), */
+            /* are used to index into one of the possible 128 bit positions. */
+            Bitpos = ~Crc32 & 0x7f;
+
+            /* Hash register index. */
+            RegIndex = (Bitpos & 0x60) >> 5;
+
+            /* Bit to turn on within a hash register. */
+            Bitpos &= 0x1f;
+
+            /* Enable the multicast bit. */
+            HashReg[RegIndex] |= (1 << Bitpos);
+        }
+
+        /* REV_AX has problem with multicast filtering where it uses both */
+        /* DA and SA to perform hashing. */
+        for(k = 0; k < 4; k++)
+        {
+            REG_WR(pDevice, MacCtrl.HashReg[k], HashReg[k]);
+        }
+    }
+    else
+    {
+        /* Reject all multicast frames. */
+        for(j = 0; j < 4; j++)
+        {
+            REG_WR(pDevice, MacCtrl.HashReg[j], 0);
+        }
+    }
+
+    /* By default, Tigon3 will accept broadcast frames.  We need to setup */
+    if(ReceiveMask & LM_ACCEPT_BROADCAST)
+    {
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
+            REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
+            REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
+            REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
+            REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
+    }
+    else
+    {
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
+            REJECT_BROADCAST_RULE1_RULE);
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
+            REJECT_BROADCAST_RULE1_VALUE);
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
+            REJECT_BROADCAST_RULE2_RULE);
+        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
+            REJECT_BROADCAST_RULE2_VALUE);
+    }
+
+    /* disable the rest of the rules. */
+    for(j = RCV_LAST_RULE_IDX; j < 16; j++)
+    {
+        REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
+        REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
+    }
+
+    return LM_STATUS_SUCCESS;
+} /* LM_SetReceiveMask */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    Disable the interrupt and put the transmitter and receiver engines in   */
+/*    an idle state.  Also aborts all pending send requests and receive       */
+/*    buffers.                                                                */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_Abort(
+PLM_DEVICE_BLOCK pDevice)
+{
+    PLM_PACKET pPacket;
+    LM_UINT Idx;
+
+    LM_DisableInterrupt(pDevice);
+
+    /* Disable all the state machines. */
+    LM_CntrlBlock(pDevice,T3_BLOCK_MAC_RX_ENGINE,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_INITIATOR,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_PLMT,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_SELECTOR,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_INITIATOR,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_COMP,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_COMP,LM_DISABLE);
+
+    LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_SELECTOR,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_INITIATOR,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_INITIATOR,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_DMA_RD,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_COMP,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_DMA_COMP,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_COMP,LM_DISABLE);
+
+    /* Clear TDE bit */
+    pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+    LM_CntrlBlock(pDevice,T3_BLOCK_MAC_TX_ENGINE,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_HOST_COALESING,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_DMA_WR,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_CLUSTER_FREE,LM_DISABLE);
+
+    /* Reset all FTQs */
+    REG_WR(pDevice, Ftq.Reset, 0xffffffff);
+    REG_WR(pDevice, Ftq.Reset, 0x0);
+
+    LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_MANAGER,LM_DISABLE);
+    LM_CntrlBlock(pDevice,T3_BLOCK_MEM_ARBITOR,LM_DISABLE);
+
+    MM_ACQUIRE_INT_LOCK(pDevice);
+
+    /* Abort packets that have already queued to go out. */
+    pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
+    while(pPacket)
+    {
+
+        pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
+        pDevice->TxCounters.TxPacketAbortedCnt++;
+
+        atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+        QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
+
+        pPacket = (PLM_PACKET)
+            QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
+    }
+
+    /* Cleanup the receive return rings. */
+    LM_ServiceRxInterrupt(pDevice);
+
+    /* Don't want to indicate rx packets in Ndis miniport shutdown context. */
+    /* Doing so may cause system crash. */
+    if(!pDevice->ShuttingDown)
+    {
+        /* Indicate packets to the protocol. */
+        MM_IndicateTxPackets(pDevice);
+
+        /* Indicate received packets to the protocols. */
+        MM_IndicateRxPackets(pDevice);
+    }
+    else
+    {
+        /* Move the receive packet descriptors in the ReceivedQ to the */
+        /* free queue. */
+        for(; ;)
+        {
+            pPacket = (PLM_PACKET) QQ_PopHead(
+                &pDevice->RxPacketReceivedQ.Container);
+            if(pPacket == NULL)
+            {
+                break;
+            }
+            QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+        }
+    }
+
+    /* Clean up the Std Receive Producer ring. */
+    Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
+
+    while(Idx != pDevice->RxStdProdIdx) {
+        pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
+            MM_UINT_PTR(pDevice->pRxStdBdVirt[Idx].Opaque));
+
+        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+        Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
+    } /* while */
+
+    /* Reinitialize our copy of the indices. */
+    pDevice->RxStdProdIdx = 0;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    /* Clean up the Jumbo Receive Producer ring. */
+    Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
+
+    while(Idx != pDevice->RxJumboProdIdx) {
+        pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
+            MM_UINT_PTR(pDevice->pRxJumboBdVirt[Idx].Opaque));
+
+        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+        Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
+    } /* while */
+
+    /* Reinitialize our copy of the indices. */
+    pDevice->RxJumboProdIdx = 0;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    MM_RELEASE_INT_LOCK(pDevice);
+
+    /* Initialize the statistis Block */
+    pDevice->pStatusBlkVirt->Status = 0;
+    pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
+    pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
+    pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
+
+    return LM_STATUS_SUCCESS;
+} /* LM_Abort */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    Disable the interrupt and put the transmitter and receiver engines in   */
+/*    an idle state.  Aborts all pending send requests and receive buffers.   */
+/*    Also free all the receive buffers.                                      */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_Halt(
+PLM_DEVICE_BLOCK pDevice) {
+    PLM_PACKET pPacket;
+    LM_UINT32 EntryCnt;
+
+    LM_Abort(pDevice);
+
+    /* Get the number of entries in the queue. */
+    EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
+
+    /* Make sure all the packets have been accounted for. */
+    for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
+    {
+        pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
+        if (pPacket == 0)
+            break;
+
+        MM_FreeRxBuffer(pDevice, pPacket);
+
+        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+    }
+
+    LM_ResetChip(pDevice);
+
+    /* Restore PCI configuration registers. */
+    MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
+        pDevice->SavedCacheLineReg);
+    LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
+        (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
+
+    /* Reprogram the MAC address. */
+    LM_SetMacAddress(pDevice, pDevice->NodeAddress);
+
+    return LM_STATUS_SUCCESS;
+} /* LM_Halt */
+
+
+STATIC LM_STATUS
+LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Value32;
+    LM_UINT32 j;
+
+    /* Wait for access to the nvram interface before resetting.  This is */
+    /* a workaround to prevent EEPROM corruption. */
+    if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+        T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
+    {
+        /* Request access to the flash interface. */
+        REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
+
+        for(j = 0; j < 100000; j++)
+        {
+            Value32 = REG_RD(pDevice, Nvram.SwArb);
+            if(Value32 & SW_ARB_GNT1)
+            {
+                break;
+            }
+            MM_Wait(10);
+        }
+    }
+
+    /* Global reset. */
+    REG_WR(pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
+    MM_Wait(40); MM_Wait(40); MM_Wait(40);
+
+    /* make sure we re-enable indirect accesses */
+    MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
+        pDevice->MiscHostCtrl);
+
+    /* Set MAX PCI retry to zero. */
+    Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
+    if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+    {
+        if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+        {
+            Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
+        }
+    }
+    MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
+
+    /* Restore PCI command register. */
+    MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
+        pDevice->PciCommandStatusWords);
+
+    /* Disable PCI-X relaxed ordering bit. */
+    MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
+    Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
+    MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
+
+    /* Enable memory arbiter. */
+    REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
+
+#ifdef BIG_ENDIAN_PCI      /* This from jfd */
+        Value32 = GRC_MODE_WORD_SWAP_DATA|
+                  GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+#ifdef BIG_ENDIAN_HOST
+    /* Reconfigure the mode register. */
+    Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+              GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+              GRC_MODE_BYTE_SWAP_DATA |
+              GRC_MODE_WORD_SWAP_DATA;
+#else
+    /* Reconfigure the mode register. */
+    Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
+#endif
+#endif
+    REG_WR(pDevice, Grc.Mode, Value32);
+
+    /* Prevent PXE from restarting. */
+    MEM_WR_OFFSET(pDevice, 0x0b50, T3_MAGIC_NUM);
+
+    if(pDevice->EnableTbi) {
+        pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
+        REG_WR(pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
+    }
+    else {
+        REG_WR(pDevice, MacCtrl.Mode, 0);
+    }
+
+    /* Wait for the firmware to finish initialization. */
+    for(j = 0; j < 100000; j++)
+    {
+        MM_Wait(10);
+
+        Value32 = MEM_RD_OFFSET(pDevice, 0x0b50);
+        if(Value32 == ~T3_MAGIC_NUM)
+        {
+            break;
+        }
+    }
+    return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+__inline static void
+LM_ServiceTxInterrupt(
+PLM_DEVICE_BLOCK pDevice) {
+    PLM_PACKET pPacket;
+    LM_UINT32 HwConIdx;
+    LM_UINT32 SwConIdx;
+
+    HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
+
+    /* Get our copy of the consumer index.  The buffer descriptors */
+    /* that are in between the consumer indices are freed. */
+    SwConIdx = pDevice->SendConIdx;
+
+    /* Move the packets from the TxPacketActiveQ that are sent out to */
+    /* the TxPacketXmittedQ.  Packets that are sent use the */
+    /* descriptors that are between SwConIdx and HwConIdx. */
+    while(SwConIdx != HwConIdx)
+    {
+        /* Get the packet that was sent from the TxPacketActiveQ. */
+        pPacket = (PLM_PACKET) QQ_PopHead(
+            &pDevice->TxPacketActiveQ.Container);
+
+        /* Set the return status. */
+        pPacket->PacketStatus = LM_STATUS_SUCCESS;
+
+        /* Put the packet in the TxPacketXmittedQ for indication later. */
+        QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
+
+        /* Move to the next packet's BD. */
+        SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
+            T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+        /* Update the number of unused BDs. */
+        atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+        /* Get the new updated HwConIdx. */
+        HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
+    } /* while */
+
+    /* Save the new SwConIdx. */
+    pDevice->SendConIdx = SwConIdx;
+
+} /* LM_ServiceTxInterrupt */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+__inline static void
+LM_ServiceRxInterrupt(
+PLM_DEVICE_BLOCK pDevice) {
+    PLM_PACKET pPacket;
+    PT3_RCV_BD pRcvBd;
+    LM_UINT32 HwRcvRetProdIdx;
+    LM_UINT32 SwRcvRetConIdx;
+
+    /* Loop thru the receive return rings for received packets. */
+    HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+
+    SwRcvRetConIdx = pDevice->RcvRetConIdx;
+    while(SwRcvRetConIdx != HwRcvRetProdIdx)
+    {
+        pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
+
+        /* Get the received packet descriptor. */
+        pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
+            MM_UINT_PTR(pRcvBd->Opaque));
+
+        /* Check the error flag. */
+        if(pRcvBd->ErrorFlag &&
+            pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
+        {
+            pPacket->PacketStatus = LM_STATUS_FAILURE;
+
+            pDevice->RxCounters.RxPacketErrCnt++;
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
+            {
+                pDevice->RxCounters.RxErrCrcCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
+            {
+                pDevice->RxCounters.RxErrCollCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
+            {
+                pDevice->RxCounters.RxErrLinkLostCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
+            {
+                pDevice->RxCounters.RxErrPhyDecodeCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
+            {
+                pDevice->RxCounters.RxErrOddNibbleCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
+            {
+                pDevice->RxCounters.RxErrMacAbortCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
+            {
+                pDevice->RxCounters.RxErrShortPacketCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
+            {
+                pDevice->RxCounters.RxErrNoResourceCnt++;
+            }
+
+            if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
+            {
+                pDevice->RxCounters.RxErrLargePacketCnt++;
+            }
+        }
+        else
+        {
+            pPacket->PacketStatus = LM_STATUS_SUCCESS;
+            pPacket->PacketSize = pRcvBd->Len - 4;
+
+            pPacket->Flags = pRcvBd->Flags;
+            if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
+            {
+                pPacket->VlanTag = pRcvBd->VlanTag;
+            }
+
+            pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
+        }
+
+        /* Put the packet descriptor containing the received packet */
+        /* buffer in the RxPacketReceivedQ for indication later. */
+        QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
+
+        /* Go to the next buffer descriptor. */
+        SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
+            T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
+
+        /* Get the updated HwRcvRetProdIdx. */
+        HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+    } /* while */
+
+    pDevice->RcvRetConIdx = SwRcvRetConIdx;
+
+    /* Update the receive return ring consumer index. */
+    MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
+} /* LM_ServiceRxInterrupt */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This is the interrupt event handler routine. It acknowledges all        */
+/*    pending interrupts and process all pending events.                      */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_ServiceInterrupts(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Value32;
+    int ServicePhyInt = FALSE;
+
+    /* Setup the phy chip whenever the link status changes. */
+    if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
+    {
+        Value32 = REG_RD(pDevice, MacCtrl.Status);
+        if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
+        {
+            if (Value32 & MAC_STATUS_MI_INTERRUPT)
+            {
+                ServicePhyInt = TRUE;
+            }
+        }
+        else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
+        {
+            ServicePhyInt = TRUE;
+        }
+    }
+    else
+    {
+        if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
+        {
+            pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
+                (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
+            ServicePhyInt = TRUE;
+        }
+    }
+#if INCLUDE_TBI_SUPPORT
+    if (pDevice->IgnoreTbiLinkChange == TRUE)
+    {
+        ServicePhyInt = FALSE;
+    }
+#endif
+    if (ServicePhyInt == TRUE)
+    {
+        LM_SetupPhy(pDevice);
+    }
+
+    /* Service receive and transmit interrupts. */
+    LM_ServiceRxInterrupt(pDevice);
+    LM_ServiceTxInterrupt(pDevice);
+
+    /* No spinlock for this queue since this routine is serialized. */
+    if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
+    {
+        /* Indicate receive packets. */
+        MM_IndicateRxPackets(pDevice);
+	/*       LM_QueueRxPackets(pDevice); */
+    }
+
+    /* No spinlock for this queue since this routine is serialized. */
+    if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
+    {
+        MM_IndicateTxPackets(pDevice);
+    }
+
+    return LM_STATUS_SUCCESS;
+} /* LM_ServiceInterrupts */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_MulticastAdd(
+PLM_DEVICE_BLOCK pDevice,
+PLM_UINT8 pMcAddress) {
+    PLM_UINT8 pEntry;
+    LM_UINT32 j;
+
+    pEntry = pDevice->McTable[0];
+    for(j = 0; j < pDevice->McEntryCount; j++)
+    {
+        if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
+        {
+            /* Found a match, increment the instance count. */
+            pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
+
+            return LM_STATUS_SUCCESS;
+        }
+
+        pEntry += LM_MC_ENTRY_SIZE;
+    }
+
+    if(pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE)
+    {
+        return LM_STATUS_FAILURE;
+    }
+
+    pEntry = pDevice->McTable[pDevice->McEntryCount];
+
+    COPY_ETH_ADDRESS(pMcAddress, pEntry);
+    pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
+
+    pDevice->McEntryCount++;
+
+    LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
+
+    return LM_STATUS_SUCCESS;
+} /* LM_MulticastAdd */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_MulticastDel(
+PLM_DEVICE_BLOCK pDevice,
+PLM_UINT8 pMcAddress) {
+    PLM_UINT8 pEntry;
+    LM_UINT32 j;
+
+    pEntry = pDevice->McTable[0];
+    for(j = 0; j < pDevice->McEntryCount; j++)
+    {
+        if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
+        {
+            /* Found a match, decrement the instance count. */
+            pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
+
+            /* No more instance left, remove the address from the table. */
+            /* Move the last entry in the table to the delete slot. */
+            if(pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
+                pDevice->McEntryCount > 1)
+            {
+
+                COPY_ETH_ADDRESS(
+                    pDevice->McTable[pDevice->McEntryCount-1], pEntry);
+                pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
+                    pDevice->McTable[pDevice->McEntryCount-1]
+                    [LM_MC_INSTANCE_COUNT_INDEX];
+            }
+            pDevice->McEntryCount--;
+
+            /* Update the receive mask if the table is empty. */
+            if(pDevice->McEntryCount == 0)
+            {
+                LM_SetReceiveMask(pDevice,
+                    pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
+            }
+
+            return LM_STATUS_SUCCESS;
+        }
+
+        pEntry += LM_MC_ENTRY_SIZE;
+    }
+
+    return LM_STATUS_FAILURE;
+} /* LM_MulticastDel */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_MulticastClear(
+PLM_DEVICE_BLOCK pDevice) {
+    pDevice->McEntryCount = 0;
+
+    LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
+
+    return LM_STATUS_SUCCESS;
+} /* LM_MulticastClear */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_SetMacAddress(
+    PLM_DEVICE_BLOCK pDevice,
+    PLM_UINT8 pMacAddress)
+{
+    LM_UINT32 j;
+
+    for(j = 0; j < 4; j++)
+    {
+        REG_WR(pDevice, MacCtrl.MacAddr[j].High,
+            (pMacAddress[0] << 8) | pMacAddress[1]);
+        REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
+            (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
+            (pMacAddress[4] << 8) | pMacAddress[5]);
+    }
+
+    return LM_STATUS_SUCCESS;
+}
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    Sets up the default line speed, and duplex modes based on the requested */
+/*    media type.                                                             */
+/*                                                                            */
+/* Return:                                                                    */
+/*    None.                                                                   */
+/******************************************************************************/
+static LM_STATUS
+LM_TranslateRequestedMediaType(
+LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
+PLM_MEDIA_TYPE pMediaType,
+PLM_LINE_SPEED pLineSpeed,
+PLM_DUPLEX_MODE pDuplexMode) {
+    *pMediaType = LM_MEDIA_TYPE_AUTO;
+    *pLineSpeed = LM_LINE_SPEED_UNKNOWN;
+    *pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+
+    /* determine media type */
+    switch(RequestedMediaType) {
+        case LM_REQUESTED_MEDIA_TYPE_BNC:
+            *pMediaType = LM_MEDIA_TYPE_BNC;
+            *pLineSpeed = LM_LINE_SPEED_10MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_HALF;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
+            *pMediaType = LM_MEDIA_TYPE_UTP;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
+            *pMediaType = LM_MEDIA_TYPE_UTP;
+            *pLineSpeed = LM_LINE_SPEED_10MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_HALF;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
+            *pMediaType = LM_MEDIA_TYPE_UTP;
+            *pLineSpeed = LM_LINE_SPEED_10MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_FULL;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
+            *pMediaType = LM_MEDIA_TYPE_UTP;
+            *pLineSpeed = LM_LINE_SPEED_100MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_HALF;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
+            *pMediaType = LM_MEDIA_TYPE_UTP;
+            *pLineSpeed = LM_LINE_SPEED_100MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_FULL;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
+            *pMediaType = LM_MEDIA_TYPE_UTP;
+            *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_HALF;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
+            *pMediaType = LM_MEDIA_TYPE_UTP;
+            *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_FULL;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
+            *pMediaType = LM_MEDIA_TYPE_FIBER;
+            *pLineSpeed = LM_LINE_SPEED_100MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_HALF;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
+            *pMediaType = LM_MEDIA_TYPE_FIBER;
+            *pLineSpeed = LM_LINE_SPEED_100MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_FULL;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
+            *pMediaType = LM_MEDIA_TYPE_FIBER;
+            *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_HALF;
+            break;
+
+        case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
+            *pMediaType = LM_MEDIA_TYPE_FIBER;
+            *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+            *pDuplexMode = LM_DUPLEX_MODE_FULL;
+            break;
+
+        default:
+            break;
+    } /* switch */
+
+    return LM_STATUS_SUCCESS;
+} /* LM_TranslateRequestedMediaType */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_LINK_ACTIVE                                                   */
+/*    LM_STATUS_LINK_DOWN                                                     */
+/******************************************************************************/
+static LM_STATUS
+LM_InitBcm540xPhy(
+PLM_DEVICE_BLOCK pDevice)
+{
+    LM_LINE_SPEED CurrentLineSpeed;
+    LM_DUPLEX_MODE CurrentDuplexMode;
+    LM_STATUS CurrentLinkStatus;
+    LM_UINT32 Value32;
+    LM_UINT32 j;
+
+#if 1  /* jmb: bugfix -- moved here, out of code that sets initial pwr state */
+    LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x2);
+#endif
+    if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
+    {
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+        if(!pDevice->InitDone)
+        {
+            Value32 = 0;
+        }
+
+        if(!(Value32 & PHY_STATUS_LINK_PASS))
+        {
+            LM_WritePhy(pDevice, BCM5401_AUX_CTRL,  0x0c20);
+
+            LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+            LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+
+            LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+            LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+
+            LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+            LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+
+            LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+            LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+
+            LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+            LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+
+            LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+            for(j = 0; j < 1000; j++)
+            {
+                MM_Wait(10);
+
+                LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+                if(Value32 & PHY_STATUS_LINK_PASS)
+                {
+                    MM_Wait(40);
+                    break;
+                }
+            }
+
+            if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
+            {
+                if(!(Value32 & PHY_STATUS_LINK_PASS) &&
+                    (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
+                {
+                    LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
+                    for(j = 0; j < 100; j++)
+                    {
+                        MM_Wait(10);
+
+                        LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+                        if(!(Value32 & PHY_CTRL_PHY_RESET))
+                        {
+                            MM_Wait(40);
+                            break;
+                        }
+                    }
+
+                    LM_WritePhy(pDevice, BCM5401_AUX_CTRL,  0x0c20);
+
+                    LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+                    LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+
+                    LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+                    LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+
+                    LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+                    LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+
+                    LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+                    LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+
+                    LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+                    LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+                }
+            }
+        }
+    }
+    else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+        pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+    {
+        /* Bug: 5701 A0, B0 TX CRC workaround. */
+        LM_WritePhy(pDevice, 0x15, 0x0a75);
+        LM_WritePhy(pDevice, 0x1c, 0x8c68);
+        LM_WritePhy(pDevice, 0x1c, 0x8d68);
+        LM_WritePhy(pDevice, 0x1c, 0x8c68);
+    }
+
+    /* Acknowledge interrupts. */
+    LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
+    LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
+
+    /* Configure the interrupt mask. */
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
+    {
+        LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
+    }
+
+    /* Configure PHY led mode. */
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
+        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
+    {
+        if(pDevice->LedMode == LED_MODE_THREE_LINK)
+        {
+            LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
+                BCM540X_EXT_CTRL_LINK3_LED_MODE);
+        }
+        else
+        {
+            LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
+        }
+    }
+
+    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+    /* Get current link and duplex mode. */
+    for(j = 0; j < 100; j++)
+    {
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+        if(Value32 & PHY_STATUS_LINK_PASS)
+        {
+            break;
+        }
+        MM_Wait(40);
+    }
+
+    if(Value32 & PHY_STATUS_LINK_PASS)
+    {
+
+        /* Determine the current line and duplex settings. */
+        LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
+        for(j = 0; j < 2000; j++)
+        {
+            MM_Wait(10);
+
+            LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
+            if(Value32)
+            {
+                break;
+            }
+        }
+
+        switch(Value32 & BCM540X_AUX_SPEED_MASK)
+        {
+            case BCM540X_AUX_10BASET_HD:
+                CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
+                CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+                break;
+
+            case BCM540X_AUX_10BASET_FD:
+                CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
+                CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+                break;
+
+            case BCM540X_AUX_100BASETX_HD:
+                CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
+                CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+                break;
+
+            case BCM540X_AUX_100BASETX_FD:
+                CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
+                CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+                break;
+
+            case BCM540X_AUX_100BASET_HD:
+                CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
+                CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+                break;
+
+            case BCM540X_AUX_100BASET_FD:
+                CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
+                CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+                break;
+
+            default:
+
+                CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
+                CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+                break;
+        }
+
+        /* Make sure we are in auto-neg mode. */
+        for (j = 0; j < 200; j++)
+        {
+            LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+            if(Value32 && Value32 != 0x7fff)
+            {
+                break;
+            }
+
+            if(Value32 == 0 && pDevice->RequestedMediaType ==
+                LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS)
+            {
+                break;
+            }
+
+            MM_Wait(10);
+        }
+
+        /* Use the current line settings for "auto" mode. */
+        if(pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
+            pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
+        {
+            if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
+            {
+                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+
+                /* We may be exiting low power mode and the link is in */
+                /* 10mb.  In this case, we need to restart autoneg. */
+                LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &Value32);
+                pDevice->advertising1000 = Value32;
+                /* 5702FE supports 10/100Mb only. */
+                if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5703 ||
+                    pDevice->BondId != GRC_MISC_BD_ID_5702FE)
+                {
+                    if(!(Value32 & (BCM540X_AN_AD_1000BASET_HALF |
+                        BCM540X_AN_AD_1000BASET_FULL)))
+                    {
+                        CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+                    }
+                }
+            }
+            else
+            {
+                CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+            }
+        }
+        else
+        {
+            /* Force line settings. */
+            /* Use the current setting if it matches the user's requested */
+            /* setting. */
+            LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+            if((pDevice->LineSpeed == CurrentLineSpeed) &&
+                (pDevice->DuplexMode == CurrentDuplexMode))
+            {
+                if ((pDevice->DisableAutoNeg &&
+                    !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
+                    (!pDevice->DisableAutoNeg &&
+                    (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
+                {
+                    CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+                }
+                else
+                {
+                    CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+                }
+            }
+            else
+            {
+                CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+            }
+        }
+
+        /* Save line settings. */
+        pDevice->LineSpeed = CurrentLineSpeed;
+        pDevice->DuplexMode = CurrentDuplexMode;
+        pDevice->MediaType = LM_MEDIA_TYPE_UTP;
+    }
+
+    return CurrentLinkStatus;
+} /* LM_InitBcm540xPhy */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_SetFlowControl(
+    PLM_DEVICE_BLOCK pDevice,
+    LM_UINT32 LocalPhyAd,
+    LM_UINT32 RemotePhyAd)
+{
+    LM_FLOW_CONTROL FlowCap;
+
+    /* Resolve flow control. */
+    FlowCap = LM_FLOW_CONTROL_NONE;
+
+    /* See Table 28B-3 of 802.3ab-1999 spec. */
+    if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
+    {
+        if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
+        {
+            if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
+            {
+                if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
+                {
+                    FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
+                        LM_FLOW_CONTROL_RECEIVE_PAUSE;
+                }
+                else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
+                {
+                    FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
+                }
+            }
+            else
+            {
+                if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
+                {
+                    FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
+                        LM_FLOW_CONTROL_RECEIVE_PAUSE;
+                }
+            }
+        }
+        else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
+        {
+            if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
+                (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
+            {
+                FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
+            }
+        }
+    }
+    else
+    {
+        FlowCap = pDevice->FlowControlCap;
+    }
+
+    /* Enable/disable rx PAUSE. */
+    pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
+    if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
+        (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
+        pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
+    {
+        pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
+        pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
+
+    }
+    REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+
+    /* Enable/disable tx PAUSE. */
+    pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
+    if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
+        (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
+        pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
+    {
+        pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
+        pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
+
+    }
+    REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+
+    return LM_STATUS_SUCCESS;
+}
+
+
+#if INCLUDE_TBI_SUPPORT
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_InitBcm800xPhy(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Value32;
+    LM_UINT32 j;
+
+    Value32 = REG_RD(pDevice, MacCtrl.Status);
+
+    /* Reset the SERDES during init and when we have link. */
+    if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
+    {
+        /* Set PLL lock range. */
+        LM_WritePhy(pDevice, 0x16, 0x8007);
+
+        /* Software reset. */
+        LM_WritePhy(pDevice, 0x00, 0x8000);
+
+        /* Wait for reset to complete. */
+        for(j = 0; j < 500; j++)
+        {
+            MM_Wait(10);
+        }
+
+        /* Config mode; seletct PMA/Ch 1 regs. */
+        LM_WritePhy(pDevice, 0x10, 0x8411);
+
+        /* Enable auto-lock and comdet, select txclk for tx. */
+        LM_WritePhy(pDevice, 0x11, 0x0a10);
+
+        LM_WritePhy(pDevice, 0x18, 0x00a0);
+        LM_WritePhy(pDevice, 0x16, 0x41ff);
+
+        /* Assert and deassert POR. */
+        LM_WritePhy(pDevice, 0x13, 0x0400);
+        MM_Wait(40);
+        LM_WritePhy(pDevice, 0x13, 0x0000);
+
+        LM_WritePhy(pDevice, 0x11, 0x0a50);
+        MM_Wait(40);
+        LM_WritePhy(pDevice, 0x11, 0x0a10);
+
+        /* Delay for signal to stabilize. */
+        for(j = 0; j < 15000; j++)
+        {
+            MM_Wait(10);
+        }
+
+        /* Deselect the channel register so we can read the PHY id later. */
+        LM_WritePhy(pDevice, 0x10, 0x8011);
+    }
+
+    return LM_STATUS_SUCCESS;
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_SetupFiberPhy(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    LM_STATUS CurrentLinkStatus;
+    AUTONEG_STATUS AnStatus = 0;
+    LM_UINT32 Value32;
+    LM_UINT32 Cnt;
+    LM_UINT32 j, k;
+
+    pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
+
+    /* Initialize the send_config register. */
+    REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
+
+    /* Enable TBI and full duplex mode. */
+    pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+    /* Initialize the BCM8002 SERDES PHY. */
+    switch(pDevice->PhyId & PHY_ID_MASK)
+    {
+        case PHY_BCM8002_PHY_ID:
+            LM_InitBcm800xPhy(pDevice);
+            break;
+
+        default:
+            break;
+    }
+
+    /* Enable link change interrupt. */
+    REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
+
+    /* Default to link down. */
+    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+    /* Get the link status. */
+    Value32 = REG_RD(pDevice, MacCtrl.Status);
+    if(Value32 & MAC_STATUS_PCS_SYNCED)
+    {
+        if((pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO) ||
+            (pDevice->DisableAutoNeg == FALSE))
+        {
+            /* auto-negotiation mode. */
+            /* Initialize the autoneg default capaiblities. */
+            AutonegInit(&pDevice->AnInfo);
+
+            /* Set the context pointer to point to the main device structure. */
+            pDevice->AnInfo.pContext = pDevice;
+
+            /* Setup flow control advertisement register. */
+            Value32 = GetPhyAdFlowCntrlSettings(pDevice);
+            if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
+            {
+                pDevice->AnInfo.mr_adv_sym_pause = 1;
+            }
+            else
+            {
+                pDevice->AnInfo.mr_adv_sym_pause = 0;
+            }
+
+            if(Value32 & PHY_AN_AD_ASYM_PAUSE)
+            {
+                pDevice->AnInfo.mr_adv_asym_pause = 1;
+            }
+            else
+            {
+                pDevice->AnInfo.mr_adv_asym_pause = 0;
+            }
+
+            /* Try to autoneg up to six times. */
+            if (pDevice->IgnoreTbiLinkChange)
+            {
+                Cnt = 1;
+            }
+            else
+            {
+                Cnt = 6;
+            }
+            for (j = 0; j < Cnt; j++)
+            {
+                REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
+
+                Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
+                REG_WR(pDevice, MacCtrl.Mode, Value32);
+                MM_Wait(20);
+
+                REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+                    MAC_MODE_SEND_CONFIGS);
+
+                MM_Wait(20);
+
+                pDevice->AnInfo.State = AN_STATE_UNKNOWN;
+                pDevice->AnInfo.CurrentTime_us = 0;
+
+                REG_WR(pDevice, Grc.Timer, 0);
+                for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
+                    (k < 75000); k++)
+                {
+                    AnStatus = Autoneg8023z(&pDevice->AnInfo);
+
+                    if((AnStatus == AUTONEG_STATUS_DONE) ||
+                        (AnStatus == AUTONEG_STATUS_FAILED))
+                    {
+                        break;
+                    }
+
+                    pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
+
+                }
+                if((AnStatus == AUTONEG_STATUS_DONE) ||
+                    (AnStatus == AUTONEG_STATUS_FAILED))
+                {
+                    break;
+                }
+                if (j >= 1)
+                {
+                    if (!(REG_RD(pDevice, MacCtrl.Status) &
+                        MAC_STATUS_PCS_SYNCED)) {
+                        break;
+                    }
+                }
+            }
+
+            /* Stop sending configs. */
+            MM_AnTxIdle(&pDevice->AnInfo);
+
+            /* Resolve flow control settings. */
+            if((AnStatus == AUTONEG_STATUS_DONE) &&
+                pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
+                pDevice->AnInfo.mr_lp_adv_full_duplex)
+                {
+                LM_UINT32 RemotePhyAd;
+                LM_UINT32 LocalPhyAd;
+
+                LocalPhyAd = 0;
+                if(pDevice->AnInfo.mr_adv_sym_pause)
+                {
+                    LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
+                }
+
+                if(pDevice->AnInfo.mr_adv_asym_pause)
+                {
+                    LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
+                }
+
+                RemotePhyAd = 0;
+                if(pDevice->AnInfo.mr_lp_adv_sym_pause)
+                {
+                    RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
+                }
+
+                if(pDevice->AnInfo.mr_lp_adv_asym_pause)
+                {
+                    RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
+                }
+
+                LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
+
+                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+            }
+            for (j = 0; j < 30; j++)
+            {
+                MM_Wait(20);
+                REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+                    MAC_STATUS_CFG_CHANGED);
+                MM_Wait(20);
+                if ((REG_RD(pDevice, MacCtrl.Status) &
+                    (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
+                    break;
+            }
+            if (pDevice->PollTbiLink)
+            {
+                Value32 = REG_RD(pDevice, MacCtrl.Status);
+                if (Value32 & MAC_STATUS_RECEIVING_CFG)
+                {
+                    pDevice->IgnoreTbiLinkChange = TRUE;
+                }
+                else
+                {
+                    pDevice->IgnoreTbiLinkChange = FALSE;
+                }
+            }
+            Value32 = REG_RD(pDevice, MacCtrl.Status);
+            if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
+                 (Value32 & MAC_STATUS_PCS_SYNCED) &&
+                 ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
+            {
+                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+            }
+        }
+        else
+        {
+            /* We are forcing line speed. */
+            pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
+            LM_SetFlowControl(pDevice, 0, 0);
+
+            CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+            REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+                MAC_MODE_SEND_CONFIGS);
+        }
+    }
+    /* Set the link polarity bit. */
+    pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+    pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
+        (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
+
+    for (j = 0; j < 100; j++)
+    {
+        REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+            MAC_STATUS_CFG_CHANGED);
+        MM_Wait(5);
+        if ((REG_RD(pDevice, MacCtrl.Status) &
+            (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
+            break;
+    }
+
+    Value32 = REG_RD(pDevice, MacCtrl.Status);
+    if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
+    {
+        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+        if (pDevice->DisableAutoNeg == FALSE)
+        {
+            REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+                MAC_MODE_SEND_CONFIGS);
+            MM_Wait(1);
+            REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+        }
+    }
+
+    /* Initialize the current link status. */
+    if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+    {
+        pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
+        pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
+        REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
+            LED_CTRL_1000MBPS_LED_ON);
+    }
+    else
+    {
+        pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
+        pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+        REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
+            LED_CTRL_OVERRIDE_TRAFFIC_LED);
+    }
+
+    /* Indicate link status. */
+    if (pDevice->LinkStatus != CurrentLinkStatus) {
+        pDevice->LinkStatus = CurrentLinkStatus;
+        MM_IndicateStatus(pDevice, CurrentLinkStatus);
+    }
+
+    return LM_STATUS_SUCCESS;
+}
+#endif /* INCLUDE_TBI_SUPPORT */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_SetupCopperPhy(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    LM_STATUS CurrentLinkStatus;
+    LM_UINT32 Value32;
+
+    /* Assume there is not link first. */
+    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+    /* Disable phy link change attention. */
+    REG_WR(pDevice, MacCtrl.MacEvent, 0);
+
+    /* Clear link change attention. */
+    REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+        MAC_STATUS_CFG_CHANGED);
+
+    /* Disable auto-polling for the moment. */
+    pDevice->MiMode = 0xc0000;
+    REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+    MM_Wait(40);
+
+    /* Determine the requested line speed and duplex. */
+    pDevice->OldLineSpeed = pDevice->LineSpeed;
+    LM_TranslateRequestedMediaType(pDevice->RequestedMediaType,
+        &pDevice->MediaType, &pDevice->LineSpeed, &pDevice->DuplexMode);
+
+    /* Initialize the phy chip. */
+    switch(pDevice->PhyId & PHY_ID_MASK)
+    {
+        case PHY_BCM5400_PHY_ID:
+        case PHY_BCM5401_PHY_ID:
+        case PHY_BCM5411_PHY_ID:
+        case PHY_BCM5701_PHY_ID:
+        case PHY_BCM5703_PHY_ID:
+        case PHY_BCM5704_PHY_ID:
+            CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
+            break;
+
+        default:
+            break;
+    }
+
+    if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
+    {
+        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+    }
+
+    /* Setup flow control. */
+    pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
+    if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+    {
+        LM_FLOW_CONTROL FlowCap;     /* Flow control capability. */
+
+        FlowCap = LM_FLOW_CONTROL_NONE;
+
+        if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
+        {
+            if(pDevice->DisableAutoNeg == FALSE ||
+                pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
+                pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
+            {
+                LM_UINT32 ExpectedPhyAd;
+                LM_UINT32 LocalPhyAd;
+                LM_UINT32 RemotePhyAd;
+
+                LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
+		pDevice->advertising = LocalPhyAd;
+                LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
+
+                ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
+
+                if(LocalPhyAd != ExpectedPhyAd)
+                {
+                    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+                }
+                else
+                {
+                    LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
+                        &RemotePhyAd);
+
+                    LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
+                }
+            }
+            else
+            {
+                pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
+                LM_SetFlowControl(pDevice, 0, 0);
+            }
+        }
+    }
+
+    if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
+    {
+        LM_ForceAutoNeg(pDevice, pDevice->RequestedMediaType);
+
+        /* If we force line speed, we make get link right away. */
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+        if(Value32 & PHY_STATUS_LINK_PASS)
+        {
+            CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+        }
+    }
+
+    /* GMII interface. */
+    pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
+    if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+    {
+        if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
+            pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
+        {
+            pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
+        }
+        else
+        {
+            pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
+        }
+    }
+    else {
+        pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
+    }
+
+    /* Set the MAC to operate in the appropriate duplex mode. */
+    pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
+    if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
+    {
+        pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
+    }
+
+    /* Set the link polarity bit. */
+    pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
+    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+    {
+        if((pDevice->LedMode == LED_MODE_LINK10) ||
+             (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
+             pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
+        {
+            pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
+        }
+    }
+    else
+    {
+        if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+        {
+            pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
+        }
+
+        /* Set LED mode. */
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            Value32 = LED_CTRL_PHY_MODE_1;
+        }
+        else
+        {
+            if(pDevice->LedMode == LED_MODE_OUTPUT)
+            {
+                Value32 = LED_CTRL_PHY_MODE_2;
+            }
+            else
+            {
+                Value32 = LED_CTRL_PHY_MODE_1;
+            }
+        }
+        REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
+    }
+
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+    /* Enable auto polling. */
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+    {
+        pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
+        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+    }
+
+    /* Enable phy link change attention. */
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
+    {
+        REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
+    }
+    else
+    {
+        REG_WR(pDevice, MacCtrl.MacEvent,
+            MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
+    }
+    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
+        (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
+        (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
+        (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
+          (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
+         !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
+    {
+        MM_Wait(120);
+        REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+            MAC_STATUS_CFG_CHANGED);
+        MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
+            T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
+    }
+
+    /* Indicate link status. */
+    if (pDevice->LinkStatus != CurrentLinkStatus) {
+        pDevice->LinkStatus = CurrentLinkStatus;
+        MM_IndicateStatus(pDevice, CurrentLinkStatus);
+    }
+
+    return LM_STATUS_SUCCESS;
+} /* LM_SetupCopperPhy */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_SetupPhy(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    LM_STATUS LmStatus;
+    LM_UINT32 Value32;
+
+#if INCLUDE_TBI_SUPPORT
+    if(pDevice->EnableTbi)
+    {
+        LmStatus = LM_SetupFiberPhy(pDevice);
+    }
+    else
+#endif /* INCLUDE_TBI_SUPPORT */
+    {
+        LmStatus = LM_SetupCopperPhy(pDevice);
+    }
+    if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+    {
+        if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+        {
+            Value32 = REG_RD(pDevice, PciCfg.PciState);
+            REG_WR(pDevice, PciCfg.PciState,
+                Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
+        }
+    }
+    if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
+        (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
+    {
+        REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
+    }
+    else
+    {
+        REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
+    }
+
+    return LmStatus;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_ReadPhy(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 PhyReg,
+PLM_UINT32 pData32) {
+    LM_UINT32 Value32;
+    LM_UINT32 j;
+
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+    {
+        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
+            ~MI_MODE_AUTO_POLLING_ENABLE);
+        MM_Wait(40);
+    }
+
+    Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
+        ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
+        MI_COM_CMD_READ | MI_COM_START;
+
+    REG_WR(pDevice, MacCtrl.MiCom, Value32);
+
+    for(j = 0; j < 20; j++)
+    {
+        MM_Wait(25);
+
+        Value32 = REG_RD(pDevice, MacCtrl.MiCom);
+
+        if(!(Value32 & MI_COM_BUSY))
+        {
+            MM_Wait(5);
+            Value32 = REG_RD(pDevice, MacCtrl.MiCom);
+            Value32 &= MI_COM_PHY_DATA_MASK;
+            break;
+        }
+    }
+
+    if(Value32 & MI_COM_BUSY)
+    {
+        Value32 = 0;
+    }
+
+    *pData32 = Value32;
+
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+    {
+        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+        MM_Wait(40);
+    }
+} /* LM_ReadPhy */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_WritePhy(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 PhyReg,
+LM_UINT32 Data32) {
+    LM_UINT32 Value32;
+    LM_UINT32 j;
+
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+    {
+        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
+            ~MI_MODE_AUTO_POLLING_ENABLE);
+        MM_Wait(40);
+    }
+
+    Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
+        ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
+        (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
+
+    REG_WR(pDevice, MacCtrl.MiCom, Value32);
+
+    for(j = 0; j < 20; j++)
+    {
+        MM_Wait(25);
+
+        Value32 = REG_RD(pDevice, MacCtrl.MiCom);
+
+        if(!(Value32 & MI_COM_BUSY))
+        {
+            MM_Wait(5);
+            break;
+        }
+    }
+
+    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+    {
+        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+        MM_Wait(40);
+    }
+} /* LM_WritePhy */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_SetPowerState(
+PLM_DEVICE_BLOCK pDevice,
+LM_POWER_STATE PowerLevel) {
+    LM_UINT32 PmeSupport;
+    LM_UINT32 Value32;
+    LM_UINT32 PmCtrl;
+
+    /* make sureindirect accesses are enabled*/
+    MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
+
+    /* Clear the PME_ASSERT bit and the power state bits.  Also enable */
+    /* the PME bit. */
+    MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
+
+    PmCtrl |= T3_PM_PME_ASSERTED;
+    PmCtrl &= ~T3_PM_POWER_STATE_MASK;
+
+    /* Set the appropriate power state. */
+    if(PowerLevel == LM_POWER_STATE_D0)
+    {
+
+        /* Bring the card out of low power mode. */
+        PmCtrl |= T3_PM_POWER_STATE_D0;
+        MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
+
+        REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
+        MM_Wait (40);
+#if 0   /* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
+        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
+#endif
+
+        return LM_STATUS_SUCCESS;
+    }
+    else if(PowerLevel == LM_POWER_STATE_D1)
+    {
+        PmCtrl |= T3_PM_POWER_STATE_D1;
+    }
+    else if(PowerLevel == LM_POWER_STATE_D2)
+    {
+        PmCtrl |= T3_PM_POWER_STATE_D2;
+    }
+    else if(PowerLevel == LM_POWER_STATE_D3)
+    {
+        PmCtrl |= T3_PM_POWER_STATE_D3;
+    }
+    else
+    {
+        return LM_STATUS_FAILURE;
+    }
+    PmCtrl |= T3_PM_PME_ENABLE;
+
+    /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
+    /* setting new line speed. */
+    Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
+    REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
+
+    if(!pDevice->RestoreOnWakeUp)
+    {
+        pDevice->RestoreOnWakeUp = TRUE;
+        pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
+        pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
+    }
+
+    /* Force auto-negotiation to 10 line speed. */
+    pDevice->DisableAutoNeg = FALSE;
+    pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
+    LM_SetupPhy(pDevice);
+
+    /* Put the driver in the initial state, and go through the power down */
+    /* sequence. */
+    LM_Halt(pDevice);
+
+    MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
+
+    if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
+    {
+
+        /* Enable WOL. */
+        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
+        MM_Wait(40);
+
+        /* Set LED mode. */
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            Value32 = LED_CTRL_PHY_MODE_1;
+        }
+        else
+        {
+            if(pDevice->LedMode == LED_MODE_OUTPUT)
+            {
+                Value32 = LED_CTRL_PHY_MODE_2;
+            }
+            else
+            {
+                Value32 = LED_CTRL_PHY_MODE_1;
+            }
+        }
+
+        Value32 = MAC_MODE_PORT_MODE_MII;
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+        {
+            if(pDevice->LedMode == LED_MODE_LINK10 ||
+                pDevice->WolSpeed == WOL_SPEED_10MB)
+            {
+                Value32 |= MAC_MODE_LINK_POLARITY;
+            }
+        }
+        else
+        {
+            Value32 |= MAC_MODE_LINK_POLARITY;
+        }
+        REG_WR(pDevice, MacCtrl.Mode, Value32);
+        MM_Wait(40); MM_Wait(40); MM_Wait(40);
+
+        /* Always enable magic packet wake-up if we have vaux. */
+        if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
+            (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
+        {
+            Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
+        }
+
+        REG_WR(pDevice, MacCtrl.Mode, Value32);
+
+        /* Enable the receiver. */
+        REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
+    }
+
+    /* Disable tx/rx clocks, and seletect an alternate clock. */
+    if(pDevice->WolSpeed == WOL_SPEED_100MB)
+    {
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                T3_PCI_SELECT_ALTERNATE_CLOCK;
+        }
+        else
+        {
+            Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
+        }
+        REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+
+        MM_Wait(40);
+
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
+        }
+        else
+        {
+            Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
+                T3_PCI_44MHZ_CORE_CLOCK;
+        }
+
+        REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+
+        MM_Wait(40);
+
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                T3_PCI_44MHZ_CORE_CLOCK;
+        }
+        else
+        {
+            Value32 = T3_PCI_44MHZ_CORE_CLOCK;
+        }
+
+        REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+    }
+    else
+    {
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                T3_PCI_SELECT_ALTERNATE_CLOCK |
+                T3_PCI_POWER_DOWN_PCI_PLL133;
+        }
+        else
+        {
+            Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
+                T3_PCI_POWER_DOWN_PCI_PLL133;
+        }
+
+        REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+    }
+
+    MM_Wait(40);
+
+    if(!pDevice->EepromWp && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE))
+    {
+        /* Switch adapter to auxilliary power. */
+        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+        {
+            /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
+            REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
+                MM_Wait(40);
+        }
+        else
+        {
+            /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
+            REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
+                MM_Wait(40);
+
+            /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
+            REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
+                MM_Wait(40);
+
+            /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
+            REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
+                MM_Wait(40);
+        }
+    }
+
+    /* Set the phy to low power mode. */
+    /* Put the the hardware in low power mode. */
+    MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
+
+    return LM_STATUS_SUCCESS;
+} /* LM_SetPowerState */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+static LM_UINT32
+GetPhyAdFlowCntrlSettings(
+    PLM_DEVICE_BLOCK pDevice)
+{
+    LM_UINT32 Value32;
+
+    Value32 = 0;
+
+    /* Auto negotiation flow control only when autonegotiation is enabled. */
+    if(pDevice->DisableAutoNeg == FALSE ||
+        pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
+        pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
+    {
+        /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
+        if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
+            ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
+            (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
+        {
+            Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
+        }
+        else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
+        {
+            Value32 |= PHY_AN_AD_ASYM_PAUSE;
+        }
+        else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
+        {
+            Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
+        }
+    }
+
+    return Value32;
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_FAILURE                                                       */
+/*    LM_STATUS_SUCCESS                                                       */
+/*                                                                            */
+/******************************************************************************/
+static LM_STATUS
+LM_ForceAutoNegBcm540xPhy(
+PLM_DEVICE_BLOCK pDevice,
+LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
+{
+    LM_MEDIA_TYPE MediaType;
+    LM_LINE_SPEED LineSpeed;
+    LM_DUPLEX_MODE DuplexMode;
+    LM_UINT32 NewPhyCtrl;
+    LM_UINT32 Value32;
+    LM_UINT32 Cnt;
+
+    /* Get the interface type, line speed, and duplex mode. */
+    LM_TranslateRequestedMediaType(RequestedMediaType, &MediaType, &LineSpeed,
+        &DuplexMode);
+
+    if (pDevice->RestoreOnWakeUp)
+    {
+        LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+        pDevice->advertising1000 = 0;
+        Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
+        if (pDevice->WolSpeed == WOL_SPEED_100MB)
+        {
+            Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+        }
+        Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+        Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+        LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+        pDevice->advertising = Value32;
+    }
+    /* Setup the auto-negotiation advertisement register. */
+    else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
+    {
+        /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
+        Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
+            PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
+            PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+        Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+        LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+        pDevice->advertising = Value32;
+
+        /* Advertise 1000Mbps */
+        Value32 = BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
+
+#if INCLUDE_5701_AX_FIX
+        /* Bug: workaround for CRC error in gigabit mode when we are in */
+        /* slave mode.  This will force the PHY to operate in */
+        /* master mode. */
+        if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+            pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+        {
+            Value32 |= BCM540X_CONFIG_AS_MASTER |
+                BCM540X_ENABLE_CONFIG_AS_MASTER;
+        }
+#endif
+
+        LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
+        pDevice->advertising1000 = Value32;
+    }
+    else
+    {
+        if(LineSpeed == LM_LINE_SPEED_1000MBPS)
+        {
+            Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+            Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+            LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+            pDevice->advertising = Value32;
+
+            if(DuplexMode != LM_DUPLEX_MODE_FULL)
+            {
+                Value32 = BCM540X_AN_AD_1000BASET_HALF;
+            }
+            else
+            {
+                Value32 = BCM540X_AN_AD_1000BASET_FULL;
+            }
+
+            LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
+            pDevice->advertising1000 = Value32;
+        }
+        else if(LineSpeed == LM_LINE_SPEED_100MBPS)
+        {
+            LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+            pDevice->advertising1000 = 0;
+
+            if(DuplexMode != LM_DUPLEX_MODE_FULL)
+            {
+                Value32 = PHY_AN_AD_100BASETX_HALF;
+            }
+            else
+            {
+                Value32 = PHY_AN_AD_100BASETX_FULL;
+            }
+
+            Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+            Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+            LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+            pDevice->advertising = Value32;
+        }
+        else if(LineSpeed == LM_LINE_SPEED_10MBPS)
+        {
+            LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+            pDevice->advertising1000 = 0;
+
+            if(DuplexMode != LM_DUPLEX_MODE_FULL)
+            {
+                Value32 = PHY_AN_AD_10BASET_HALF;
+            }
+            else
+            {
+                Value32 = PHY_AN_AD_10BASET_FULL;
+            }
+
+            Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+            Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+            LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+            pDevice->advertising = Value32;
+        }
+    }
+
+    /* Force line speed if auto-negotiation is disabled. */
+    if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
+    {
+        /* This code path is executed only when there is link. */
+        pDevice->MediaType = MediaType;
+        pDevice->LineSpeed = LineSpeed;
+        pDevice->DuplexMode = DuplexMode;
+
+        /* Force line seepd. */
+        NewPhyCtrl = 0;
+        switch(LineSpeed)
+        {
+            case LM_LINE_SPEED_10MBPS:
+                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
+                break;
+            case LM_LINE_SPEED_100MBPS:
+                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
+                break;
+            case LM_LINE_SPEED_1000MBPS:
+                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
+                break;
+            default:
+                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
+                break;
+        }
+
+        if(DuplexMode == LM_DUPLEX_MODE_FULL)
+        {
+            NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
+        }
+
+        /* Don't do anything if the PHY_CTRL is already what we wanted. */
+        LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+        if(Value32 != NewPhyCtrl)
+        {
+            /* Temporary bring the link down before forcing line speed. */
+            LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
+
+            /* Wait for link to go down. */
+            for(Cnt = 0; Cnt < 15000; Cnt++)
+            {
+                MM_Wait(10);
+
+                LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+                LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+                if(!(Value32 & PHY_STATUS_LINK_PASS))
+                {
+                    MM_Wait(40);
+                    break;
+                }
+            }
+
+            LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
+            MM_Wait(40);
+        }
+    }
+    else
+    {
+        LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
+            PHY_CTRL_RESTART_AUTO_NEG);
+    }
+
+    return LM_STATUS_SUCCESS;
+} /* LM_ForceAutoNegBcm540xPhy */
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+static LM_STATUS
+LM_ForceAutoNeg(
+PLM_DEVICE_BLOCK pDevice,
+LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
+{
+    LM_STATUS LmStatus;
+
+    /* Initialize the phy chip. */
+    switch(pDevice->PhyId & PHY_ID_MASK)
+    {
+        case PHY_BCM5400_PHY_ID:
+        case PHY_BCM5401_PHY_ID:
+        case PHY_BCM5411_PHY_ID:
+        case PHY_BCM5701_PHY_ID:
+        case PHY_BCM5703_PHY_ID:
+        case PHY_BCM5704_PHY_ID:
+            LmStatus = LM_ForceAutoNegBcm540xPhy(pDevice, RequestedMediaType);
+            break;
+
+        default:
+            LmStatus = LM_STATUS_FAILURE;
+            break;
+    }
+
+    return LmStatus;
+} /* LM_ForceAutoNeg */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
+                          PT3_FWIMG_INFO pFwImg,
+                          LM_UINT32 LoadCpu,
+                          LM_UINT32 StartCpu)
+{
+    LM_UINT32 i;
+    LM_UINT32 address;
+
+    if (LoadCpu & T3_RX_CPU_ID)
+    {
+        if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
+        {
+            return LM_STATUS_FAILURE;
+        }
+
+        /* First of all clear scrach pad memory */
+        for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i+=4)
+        {
+            LM_RegWrInd(pDevice,T3_RX_CPU_SPAD_ADDR+i,0);
+        }
+
+        /* Copy code first */
+        address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
+        for (i = 0; i <= pFwImg->Text.Length; i+=4)
+        {
+            LM_RegWrInd(pDevice,address+i,
+                        ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
+        }
+
+        address = T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
+        for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
+        {
+            LM_RegWrInd(pDevice,address+i,
+                        ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
+        }
+
+        address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
+        for (i= 0; i <= pFwImg->Data.Length; i+=4)
+        {
+            LM_RegWrInd(pDevice,address+i,
+                        ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
+        }
+    }
+
+    if (LoadCpu & T3_TX_CPU_ID)
+    {
+        if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
+        {
+            return LM_STATUS_FAILURE;
+        }
+
+        /* First of all clear scrach pad memory */
+        for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
+        {
+            LM_RegWrInd(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
+        }
+
+        /* Copy code first */
+        address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
+        for (i= 0; i <= pFwImg->Text.Length; i+=4)
+        {
+            LM_RegWrInd(pDevice,address+i,
+                        ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
+        }
+
+        address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
+        for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
+        {
+            LM_RegWrInd(pDevice,address+i,
+                        ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
+        }
+
+        address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
+        for (i= 0; i <= pFwImg->Data.Length; i+=4)
+        {
+            LM_RegWrInd(pDevice,address+i,
+                        ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
+        }
+    }
+
+    if (StartCpu & T3_RX_CPU_ID)
+    {
+        /* Start Rx CPU */
+        REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+        REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
+        for (i = 0 ; i < 5; i++)
+        {
+          if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
+             break;
+
+          REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+          REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
+          REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
+          MM_Wait(1000);
+        }
+
+        REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+        REG_WR(pDevice,rxCpu.reg.mode, 0);
+    }
+
+    if (StartCpu & T3_TX_CPU_ID)
+    {
+        /* Start Tx CPU */
+        REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+        REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
+        for (i = 0 ; i < 5; i++)
+        {
+          if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
+             break;
+
+          REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+          REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
+          REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
+          MM_Wait(1000);
+        }
+
+        REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+        REG_WR(pDevice,txCpu.reg.mode, 0);
+    }
+
+    return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
+{
+    LM_UINT32 i;
+
+    if (cpu_number == T3_RX_CPU_ID)
+    {
+        for (i = 0 ; i < 10000; i++)
+        {
+            REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+            REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
+
+            if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
+              break;
+        }
+
+        REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+        REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
+        MM_Wait(10);
+    }
+    else
+    {
+        for (i = 0 ; i < 10000; i++)
+        {
+            REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+            REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
+
+            if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
+               break;
+        }
+    }
+
+  return (( i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
+}
+
+
+int
+LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
+{
+	LM_UINT32 Oldcfg;
+	int j;
+	int ret = 0;
+
+	if(BlinkDurationSec == 0)
+	{
+		return 0;
+        }
+	if(BlinkDurationSec > 120)
+        {
+	        BlinkDurationSec = 120;
+	}
+
+	Oldcfg = REG_RD(pDevice, MacCtrl.LedCtrl);
+	for(j = 0; j < BlinkDurationSec * 2; j++)
+	{
+		if(j % 2)
+		{
+		        /* Turn on the LEDs. */
+			REG_WR(pDevice, MacCtrl.LedCtrl,
+				LED_CTRL_OVERRIDE_LINK_LED |
+				LED_CTRL_1000MBPS_LED_ON |
+				LED_CTRL_100MBPS_LED_ON |
+				LED_CTRL_10MBPS_LED_ON |
+				LED_CTRL_OVERRIDE_TRAFFIC_LED |
+				LED_CTRL_BLINK_TRAFFIC_LED |
+				LED_CTRL_TRAFFIC_LED);
+		}
+		else
+		{
+		        /* Turn off the LEDs. */
+			REG_WR(pDevice, MacCtrl.LedCtrl,
+				LED_CTRL_OVERRIDE_LINK_LED |
+				LED_CTRL_OVERRIDE_TRAFFIC_LED);
+		}
+
+#ifndef EMBEDDED
+                current->state = TASK_INTERRUPTIBLE;
+                if (schedule_timeout(HZ/2) != 0) {
+                        ret = -EINTR;
+                        break;
+                }
+#else
+                udelay(100000);  /* 1s sleep */
+#endif
+	}
+	REG_WR(pDevice, MacCtrl.LedCtrl, Oldcfg);
+	return ret;
+}
+
+int t3_do_dma(PLM_DEVICE_BLOCK pDevice,
+                   LM_PHYSICAL_ADDRESS host_addr_phy, int length,
+                   int dma_read)
+{
+    T3_DMA_DESC dma_desc;
+    int i;
+    LM_UINT32 dma_desc_addr;
+    LM_UINT32 value32;
+
+    REG_WR(pDevice, BufMgr.Mode, 0);
+    REG_WR(pDevice, Ftq.Reset, 0);
+
+    dma_desc.host_addr.High = host_addr_phy.High;
+    dma_desc.host_addr.Low = host_addr_phy.Low;
+    dma_desc.nic_mbuf = 0x2100;
+    dma_desc.len = length;
+    dma_desc.flags = 0x00000004; /* Generate Rx-CPU event */
+
+    if (dma_read)
+    {
+        dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
+            T3_QID_DMA_HIGH_PRI_READ;
+        REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
+    }
+    else
+    {
+        dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
+            T3_QID_DMA_HIGH_PRI_WRITE;
+        REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
+    }
+
+    dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
+
+    /* Writing this DMA descriptor to DMA memory */
+    for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
+    {
+        value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
+        MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
+        MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, cpu_to_le32(value32));
+    }
+    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
+
+    if (dma_read)
+        REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
+    else
+        REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
+
+    for (i = 0; i < 40; i++)
+    {
+        if (dma_read)
+            value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
+        else
+            value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
+
+        if ((value32 & 0xffff) == dma_desc_addr)
+            break;
+
+        MM_Wait(10);
+    }
+
+    return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS
+LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
+           LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
+{
+    int j;
+    LM_UINT32 *ptr;
+    int dma_success = 0;
+
+    if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+        T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
+    {
+        return LM_STATUS_SUCCESS;
+    }
+    while (!dma_success)
+    {
+        /* Fill data with incremental patterns */
+        ptr = (LM_UINT32 *)pBufferVirt;
+        for (j = 0; j < BufferSize/4; j++)
+            *ptr++ = j;
+
+        if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
+        {
+            return LM_STATUS_FAILURE;
+        }
+
+        MM_Wait(40);
+        ptr = (LM_UINT32 *)pBufferVirt;
+        /* Fill data with zero */
+        for (j = 0; j < BufferSize/4; j++)
+            *ptr++ = 0;
+
+        if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
+        {
+            return LM_STATUS_FAILURE;
+        }
+
+        MM_Wait(40);
+        /* Check for data */
+        ptr = (LM_UINT32 *)pBufferVirt;
+        for (j = 0; j < BufferSize/4; j++)
+        {
+            if (*ptr++ != j)
+            {
+                if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
+                    == DMA_CTRL_WRITE_BOUNDARY_DISABLE)
+                {
+                    pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
+                         ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
+                          DMA_CTRL_WRITE_BOUNDARY_16;
+                    REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
+                           pDevice->DmaReadWriteCtrl);
+                    break;
+                 }
+                 else
+                 {
+                     return LM_STATUS_FAILURE;
+                 }
+            }
+        }
+        if (j == (BufferSize/4))
+            dma_success = 1;
+    }
+    return LM_STATUS_SUCCESS;
+}
+#endif /* CFG_CMD_NET, !CONFIG_NET_MULTI, CONFIG_TIGON3 */
diff --git a/drivers/tigon3.h b/drivers/tigon3.h
new file mode 100644
index 0000000..8d30ac9
--- /dev/null
+++ b/drivers/tigon3.h
@@ -0,0 +1,3469 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef TIGON3_H
+#define TIGON3_H
+
+#include "bcm570x_lm.h"
+#if INCLUDE_TBI_SUPPORT
+#include "bcm570x_autoneg.h"
+#endif
+
+
+/* io defines */
+#if !defined(BIG_ENDIAN_HOST)
+#define readl(addr) \
+              (LONGSWAP((*(volatile unsigned int *)(addr))))
+#define writel(b,addr) \
+              ((*(volatile unsigned int *)(addr)) = (LONGSWAP(b)))
+#else
+#if 0 /* !defined(PPC603) */
+#define readl(addr) (*(volatile unsigned int*)(0xa0000000 + (unsigned long)(addr)))
+#define writel(b,addr) ((*(volatile unsigned int *) ((unsigned long)(addr) + 0xa0000000)) = (b))
+#else
+#if 1
+#define readl(addr) (*(volatile unsigned int*)(addr))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+#else
+extern int sprintf(char* buf, const char* f, ...);
+static __inline unsigned int readl(void* addr){
+    char buf[128];
+    unsigned int tmp = (*(volatile unsigned int*)(addr));
+    sprintf(buf,"%s:%s: read 0x%x from 0x%x\n",__FILE__,__LINE__,tmp,addr,0,0);
+    sysSerialPrintString(buf);
+    return tmp;
+}
+static __inline void writel(unsigned int b, unsigned int addr){
+    char buf[128];
+    ((*(volatile unsigned int *) (addr)) = (b));
+    sprintf(buf,"%s:%s: write 0x%x to 0x%x\n",__FILE__,__LINE__,b,addr,0,0);
+    sysSerialPrintString(buf);
+}
+#endif
+#endif /* PPC603 */
+#endif
+
+
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+/* Maxim number of packet descriptors used for sending packets. */
+#define MAX_TX_PACKET_DESC_COUNT            600
+#define DEFAULT_TX_PACKET_DESC_COUNT        2
+
+/* Maximum number of packet descriptors used for receiving packets. */
+#if T3_JUMBO_RCB_ENTRY_COUNT
+#define MAX_RX_PACKET_DESC_COUNT                                            \
+    (T3_STD_RCV_RCB_ENTRY_COUNT + T3_JUMBO_RCV_RCB_ENTRY_COUNT)
+#else
+#define MAX_RX_PACKET_DESC_COUNT            800
+#endif
+#define DEFAULT_RX_PACKET_DESC_COUNT        2
+
+/* Threshhold for double copying small tx packets.  0 will disable double */
+/* copying of small Tx packets. */
+#define DEFAULT_TX_COPY_BUFFER_SIZE         0
+#define MIN_TX_COPY_BUFFER_SIZE             64
+#define MAX_TX_COPY_BUFFER_SIZE             512
+
+/* Cache line. */
+#define COMMON_CACHE_LINE_SIZE              0x20
+#define COMMON_CACHE_LINE_MASK              (COMMON_CACHE_LINE_SIZE-1)
+
+/* Maximum number of fragment we can handle. */
+#ifndef MAX_FRAGMENT_COUNT
+#define MAX_FRAGMENT_COUNT                  32
+#endif
+
+/* B0 bug. */
+#define BCM5700_BX_MIN_FRAG_SIZE            10
+#define BCM5700_BX_MIN_FRAG_BUF_SIZE        16  /* nice aligned size. */
+#define BCM5700_BX_MIN_FRAG_BUF_SIZE_MASK   (BCM5700_BX_MIN_FRAG_BUF_SIZE-1)
+#define BCM5700_BX_TX_COPY_BUF_SIZE         (BCM5700_BX_MIN_FRAG_BUF_SIZE * \
+                                            MAX_FRAGMENT_COUNT)
+
+/* MAGIC number. */
+/* #define T3_MAGIC_NUM                        'KevT' */
+#define T3_FIRMWARE_MAILBOX                0x0b50
+#define T3_MAGIC_NUM                       0x4B657654
+#define T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE 0x4861764b
+
+#define T3_NIC_DATA_SIG_ADDR               0x0b54
+#define T3_NIC_DATA_SIG                    0x4b657654
+
+#define T3_NIC_DATA_NIC_CFG_ADDR           0x0b58
+#define T3_NIC_CFG_LED_MODE_UNKNOWN        BIT_NONE
+#define T3_NIC_CFG_LED_MODE_TRIPLE_SPEED   BIT_2
+#define T3_NIC_CFG_LED_MODE_LINK_SPEED     BIT_3
+#define T3_NIC_CFG_LED_MODE_OPEN_DRAIN     BIT_2
+#define T3_NIC_CFG_LED_MODE_OUTPUT         BIT_3
+#define T3_NIC_CFG_LED_MODE_MASK           (BIT_2 | BIT_3)
+#define T3_NIC_CFG_PHY_TYPE_UNKNOWN         BIT_NONE
+#define T3_NIC_CFG_PHY_TYPE_COPPER          BIT_4
+#define T3_NIC_CFG_PHY_TYPE_FIBER           BIT_5
+#define T3_NIC_CFG_PHY_TYPE_MASK            (BIT_4 | BIT_5)
+#define T3_NIC_CFG_ENABLE_WOL               BIT_6
+#define T3_NIC_CFG_ENABLE_ASF               BIT_7
+#define T3_NIC_EEPROM_WP                    BIT_8
+
+#define T3_NIC_DATA_PHY_ID_ADDR            0x0b74
+#define T3_NIC_PHY_ID1_MASK                0xffff0000
+#define T3_NIC_PHY_ID2_MASK                0x0000ffff
+
+#define T3_CMD_MAILBOX                      0x0b78
+#define T3_CMD_NICDRV_ALIVE                 0x01
+#define T3_CMD_NICDRV_PAUSE_FW              0x02
+#define T3_CMD_NICDRV_IPV4ADDR_CHANGE       0x03
+#define T3_CMD_NICDRV_IPV6ADDR_CHANGE       0x04
+#define T3_CMD_5703A0_FIX_DMAFW_DMAR        0x05
+#define T3_CMD_5703A0_FIX_DMAFW_DMAW        0x06
+
+#define T3_CMD_LENGTH_MAILBOX               0x0b7c
+#define T3_CMD_DATA_MAILBOX                 0x0b80
+
+#define T3_ASF_FW_STATUS_MAILBOX            0x0c00
+
+#define T3_DRV_STATE_MAILBOX                0x0c04
+#define T3_DRV_STATE_START                  0x01
+#define T3_DRV_STATE_UNLOAD                 0x02
+#define T3_DRV_STATE_WOL                    0x03
+#define T3_DRV_STATE_SUSPEND                0x04
+
+#define T3_FW_RESET_TYPE_MAILBOX            0x0c08
+
+#define T3_MAC_ADDR_HIGH_MAILBOX            0x0c14
+#define T3_MAC_ADDR_LOW_MAILBOX             0x0c18
+
+/******************************************************************************/
+/* Hardware constants. */
+/******************************************************************************/
+
+/* Number of entries in the send ring:  must be 512. */
+#define T3_SEND_RCB_ENTRY_COUNT             512
+#define T3_SEND_RCB_ENTRY_COUNT_MASK        (T3_SEND_RCB_ENTRY_COUNT-1)
+
+/* Number of send RCBs.  May be 1-16 but for now, only support one. */
+#define T3_MAX_SEND_RCB_COUNT               16
+
+/* Number of entries in the Standard Receive RCB.  Must be 512 entries. */
+#define T3_STD_RCV_RCB_ENTRY_COUNT          512
+#define T3_STD_RCV_RCB_ENTRY_COUNT_MASK     (T3_STD_RCV_RCB_ENTRY_COUNT-1)
+#define DEFAULT_STD_RCV_DESC_COUNT          200    /* Must be < 512. */
+#define MAX_STD_RCV_BUFFER_SIZE             0x600
+
+/* Number of entries in the Mini Receive RCB.  This value can either be */
+/* 0, 1024.  Currently Mini Receive RCB is disabled. */
+#ifndef T3_MINI_RCV_RCB_ENTRY_COUNT
+#define T3_MINI_RCV_RCB_ENTRY_COUNT         0
+#endif /* T3_MINI_RCV_RCB_ENTRY_COUNT */
+#define T3_MINI_RCV_RCB_ENTRY_COUNT_MASK    (T3_MINI_RCV_RCB_ENTRY_COUNT-1)
+#define MAX_MINI_RCV_BUFFER_SIZE            512
+#define DEFAULT_MINI_RCV_BUFFER_SIZE        64
+#define DEFAULT_MINI_RCV_DESC_COUNT         100    /* Must be < 1024. */
+
+/* Number of entries in the Jumbo Receive RCB.  This value must 256 or 0. */
+/* Currently, Jumbo Receive RCB is disabled. */
+#ifndef T3_JUMBO_RCV_RCB_ENTRY_COUNT
+#define T3_JUMBO_RCV_RCB_ENTRY_COUNT        0
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+#define T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK   (T3_JUMBO_RCV_RCB_ENTRY_COUNT-1)
+
+#define MAX_JUMBO_RCV_BUFFER_SIZE           (10 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_RCV_BUFFER_SIZE       (4 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_RCV_DESC_COUNT        128     /* Must be < 256. */
+
+#define MAX_JUMBO_TX_BUFFER_SIZE            (8 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_TX_BUFFER_SIZE        (4 * 1024) /* > 1514 */
+
+/* Number of receive return RCBs.  Maybe 1-16 but for now, only support one. */
+#define T3_MAX_RCV_RETURN_RCB_COUNT         16
+
+/* Number of entries in a Receive Return ring.  This value is either 1024 */
+/* or 2048. */
+#ifndef T3_RCV_RETURN_RCB_ENTRY_COUNT
+#define T3_RCV_RETURN_RCB_ENTRY_COUNT       1024
+#endif /* T3_RCV_RETURN_RCB_ENTRY_COUNT */
+#define T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK  (T3_RCV_RETURN_RCB_ENTRY_COUNT-1)
+
+
+/* Default coalescing parameters. */
+#define DEFAULT_RX_COALESCING_TICKS         100
+#define MAX_RX_COALESCING_TICKS             500
+#define DEFAULT_TX_COALESCING_TICKS         400
+#define MAX_TX_COALESCING_TICKS             500
+#define DEFAULT_RX_MAX_COALESCED_FRAMES     10
+#define MAX_RX_MAX_COALESCED_FRAMES         100
+#define ADAPTIVE_LO_RX_MAX_COALESCED_FRAMES    5
+#define ADAPTIVE_HI_RX_MAX_COALESCED_FRAMES    42
+#define ADAPTIVE_LO_RX_COALESCING_TICKS         50
+#define ADAPTIVE_HI_RX_COALESCING_TICKS         300
+#define ADAPTIVE_LO_PKT_THRESH              30000
+#define ADAPTIVE_HI_PKT_THRESH              74000
+#define DEFAULT_TX_MAX_COALESCED_FRAMES     40
+#define ADAPTIVE_LO_TX_MAX_COALESCED_FRAMES    25
+#define ADAPTIVE_HI_TX_MAX_COALESCED_FRAMES    75
+#define MAX_TX_MAX_COALESCED_FRAMES         100
+
+#define DEFAULT_RX_COALESCING_TICKS_DURING_INT          25
+#define DEFAULT_TX_COALESCING_TICKS_DURING_INT          25
+#define DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT      5
+#define DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT      5
+
+#define BAD_DEFAULT_VALUE                               0xffffffff
+
+#define DEFAULT_STATS_COALESCING_TICKS      1000000
+#define MAX_STATS_COALESCING_TICKS          3600000000U
+
+
+/* Receive BD Replenish thresholds. */
+#define DEFAULT_RCV_STD_BD_REPLENISH_THRESHOLD      4
+#define DEFAULT_RCV_JUMBO_BD_REPLENISH_THRESHOLD    4
+
+#define SPLIT_MODE_DISABLE                          0
+#define SPLIT_MODE_ENABLE                           1
+
+#define SPLIT_MODE_5704_MAX_REQ                     3
+
+/* Maximum physical fragment size. */
+#define MAX_FRAGMENT_SIZE                   (64 * 1024)
+
+
+/* Standard view. */
+#define T3_STD_VIEW_SIZE                    (64 * 1024)
+#define T3_FLAT_VIEW_SIZE                   (32 * 1024 * 1024)
+
+
+/* Buffer descriptor base address on the NIC's memory. */
+
+#define T3_NIC_SND_BUFFER_DESC_ADDR         0x4000
+#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR     0x6000
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR   0x7000
+
+#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR_EXT_MEM     0xc000
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR_EXT_MEM   0xd000
+#define T3_NIC_MINI_RCV_BUFFER_DESC_ADDR_EXT_MEM    0xe000
+
+#define T3_NIC_SND_BUFFER_DESC_SIZE         (T3_SEND_RCB_ENTRY_COUNT * \
+                                            sizeof(T3_SND_BD) / 4)
+
+#define T3_NIC_STD_RCV_BUFFER_DESC_SIZE     (T3_STD_RCV_RCB_ENTRY_COUNT * \
+                                            sizeof(T3_RCV_BD) / 4)
+
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_SIZE   (T3_JUMBO_RCV_RCB_ENTRY_COUNT * \
+                                            sizeof(T3_EXT_RCV_BD) / 4)
+
+
+/* MBUF pool. */
+#define T3_NIC_MBUF_POOL_ADDR               0x8000
+/* #define T3_NIC_MBUF_POOL_SIZE               0x18000 */
+#define T3_NIC_MBUF_POOL_SIZE96             0x18000
+#define T3_NIC_MBUF_POOL_SIZE64             0x10000
+
+
+#define T3_NIC_MBUF_POOL_ADDR_EXT_MEM       0x20000
+
+/* DMA descriptor pool */
+#define T3_NIC_DMA_DESC_POOL_ADDR           0x2000
+#define T3_NIC_DMA_DESC_POOL_SIZE           0x2000      /* 8KB. */
+
+#define T3_DEF_DMA_MBUF_LOW_WMARK           0x40
+#define T3_DEF_RX_MAC_MBUF_LOW_WMARK        0x20
+#define T3_DEF_MBUF_HIGH_WMARK              0x60
+
+#define T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO     304
+#define T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO  152
+#define T3_DEF_MBUF_HIGH_WMARK_JUMBO        380
+
+#define T3_DEF_DMA_DESC_LOW_WMARK           5
+#define T3_DEF_DMA_DESC_HIGH_WMARK          10
+
+/* Maximum size of giant TCP packet can be sent */
+#define T3_TCP_SEG_MAX_OFFLOAD_SIZE         64*1000
+#define T3_TCP_SEG_MIN_NUM_SEG              20
+
+#define T3_RX_CPU_ID    0x1
+#define T3_TX_CPU_ID    0x2
+#define T3_RX_CPU_SPAD_ADDR  0x30000
+#define T3_RX_CPU_SPAD_SIZE  0x4000
+#define T3_TX_CPU_SPAD_ADDR  0x34000
+#define T3_TX_CPU_SPAD_SIZE  0x4000
+
+typedef struct T3_DIR_ENTRY
+{
+  PLM_UINT8 Buffer;
+  LM_UINT32 Offset;
+  LM_UINT32 Length;
+} T3_DIR_ENTRY,*PT3_DIR_ENTRY;
+
+typedef struct T3_FWIMG_INFO
+{
+  LM_UINT32 StartAddress;
+  T3_DIR_ENTRY Text;
+  T3_DIR_ENTRY ROnlyData;
+  T3_DIR_ENTRY Data;
+  T3_DIR_ENTRY Sbss;
+  T3_DIR_ENTRY Bss;
+} T3_FWIMG_INFO, *PT3_FWIMG_INFO;
+
+
+
+/******************************************************************************/
+/* Tigon3 PCI Registers. */
+/******************************************************************************/
+#define T3_PCI_ID_BCM5700                   0x164414e4
+#define T3_PCI_ID_BCM5701                   0x164514e4
+#define T3_PCI_ID_BCM5702                   0x164614e4
+#define T3_PCI_ID_BCM5702x                  0x16A614e4
+#define T3_PCI_ID_BCM5703                   0x164714e4
+#define T3_PCI_ID_BCM5703x                  0x16A714e4
+#define T3_PCI_ID_BCM5702FE                 0x164D14e4
+#define T3_PCI_ID_BCM5704                   0x164814e4
+
+#define T3_PCI_VENDOR_ID                    (T3_PCI_ID & 0xffff)
+#define T3_PCI_DEVICE_ID                    (T3_PCI_ID >> 16)
+
+#define T3_PCI_MISC_HOST_CTRL_REG           0x68
+
+/* The most significant 16bit of register 0x68. */
+/* ChipId:4, ChipRev:4, MetalRev:8 */
+#define T3_CHIP_ID_5700_A0                  0x7000
+#define T3_CHIP_ID_5700_A1                  0x7001
+#define T3_CHIP_ID_5700_B0                  0x7100
+#define T3_CHIP_ID_5700_B1                  0x7101
+#define T3_CHIP_ID_5700_C0                  0x7200
+
+#define T3_CHIP_ID_5701_A0                  0x0000
+#define T3_CHIP_ID_5701_B0                  0x0100
+#define T3_CHIP_ID_5701_B2                  0x0102
+#define T3_CHIP_ID_5701_B5                  0x0105
+
+#define T3_CHIP_ID_5703_A0                  0x1000
+#define T3_CHIP_ID_5703_A1                  0x1001
+#define T3_CHIP_ID_5703_A2                  0x1002
+
+#define T3_CHIP_ID_5704_A0                  0x2000
+
+/* Chip Id. */
+#define T3_ASIC_REV(_ChipRevId)             ((_ChipRevId) >> 12)
+#define T3_ASIC_REV_5700                    0x07
+#define T3_ASIC_REV_5701                    0x00
+#define T3_ASIC_REV_5703                    0x01
+#define T3_ASIC_REV_5704                    0x02
+
+
+/* Chip id and revision. */
+#define T3_CHIP_REV(_ChipRevId)             ((_ChipRevId) >> 8)
+#define T3_CHIP_REV_5700_AX                 0x70
+#define T3_CHIP_REV_5700_BX                 0x71
+#define T3_CHIP_REV_5700_CX                 0x72
+#define T3_CHIP_REV_5701_AX                 0x00
+
+/* Metal revision. */
+#define T3_METAL_REV(_ChipRevId)            ((_ChipRevId) & 0xff)
+#define T3_METAL_REV_A0                     0x00
+#define T3_METAL_REV_A1                     0x01
+#define T3_METAL_REV_B0                     0x00
+#define T3_METAL_REV_B1                     0x01
+#define T3_METAL_REV_B2                     0x02
+
+#define T3_PCI_REG_CLOCK_CTRL               0x74
+
+#define T3_PCI_DISABLE_RX_CLOCK             BIT_10
+#define T3_PCI_DISABLE_TX_CLOCK             BIT_11
+#define T3_PCI_SELECT_ALTERNATE_CLOCK       BIT_12
+#define T3_PCI_POWER_DOWN_PCI_PLL133        BIT_15
+#define T3_PCI_44MHZ_CORE_CLOCK             BIT_18
+
+
+#define T3_PCI_REG_ADDR_REG                 0x78
+#define T3_PCI_REG_DATA_REG                 0x80
+
+#define T3_PCI_MEM_WIN_ADDR_REG             0x7c
+#define T3_PCI_MEM_WIN_DATA_REG             0x84
+
+#define T3_PCI_PM_CAP_REG                   0x48
+
+#define T3_PCI_PM_CAP_PME_D3COLD            BIT_31
+#define T3_PCI_PM_CAP_PME_D3HOT             BIT_30
+
+#define T3_PCI_PM_STATUS_CTRL_REG           0x4c
+
+#define T3_PM_POWER_STATE_MASK              (BIT_0 | BIT_1)
+#define T3_PM_POWER_STATE_D0                BIT_NONE
+#define T3_PM_POWER_STATE_D1                BIT_0
+#define T3_PM_POWER_STATE_D2                BIT_1
+#define T3_PM_POWER_STATE_D3                (BIT_0 | BIT_1)
+
+#define T3_PM_PME_ENABLE                    BIT_8
+#define T3_PM_PME_ASSERTED                  BIT_15
+
+
+/* PCI state register. */
+#define T3_PCI_STATE_REG                    0x70
+
+#define T3_PCI_STATE_FORCE_RESET            BIT_0
+#define T3_PCI_STATE_INT_NOT_ACTIVE         BIT_1
+#define T3_PCI_STATE_CONVENTIONAL_PCI_MODE  BIT_2
+#define T3_PCI_STATE_BUS_SPEED_HIGH         BIT_3
+#define T3_PCI_STATE_32BIT_PCI_BUS          BIT_4
+
+
+/* Broadcom subsystem/subvendor IDs. */
+#define T3_SVID_BROADCOM                            0x14e4
+
+#define T3_SSID_BROADCOM_BCM95700A6                 0x1644
+#define T3_SSID_BROADCOM_BCM95701A5                 0x0001
+#define T3_SSID_BROADCOM_BCM95700T6                 0x0002  /* BCM8002 */
+#define T3_SSID_BROADCOM_BCM95700A9                 0x0003  /* Agilent */
+#define T3_SSID_BROADCOM_BCM95701T1                 0x0005
+#define T3_SSID_BROADCOM_BCM95701T8                 0x0006
+#define T3_SSID_BROADCOM_BCM95701A7                 0x0007  /* Agilent */
+#define T3_SSID_BROADCOM_BCM95701A10                0x0008
+#define T3_SSID_BROADCOM_BCM95701A12                0x8008
+#define T3_SSID_BROADCOM_BCM95703Ax1                0x0009
+#define T3_SSID_BROADCOM_BCM95703Ax2                0x8009
+
+/* 3COM subsystem/subvendor IDs. */
+#define T3_SVID_3COM                                0x10b7
+
+#define T3_SSID_3COM_3C996T                         0x1000
+#define T3_SSID_3COM_3C996BT                        0x1006
+#define T3_SSID_3COM_3C996CT                        0x1002
+#define T3_SSID_3COM_3C997T                         0x1003
+#define T3_SSID_3COM_3C1000T                        0x1007
+#define T3_SSID_3COM_3C940BR01                      0x1008
+
+/* Fiber boards. */
+#define T3_SSID_3COM_3C996SX                        0x1004
+#define T3_SSID_3COM_3C997SX                        0x1005
+
+
+/* Dell subsystem/subvendor IDs. */
+
+#define T3_SVID_DELL                                0x1028
+
+#define T3_SSID_DELL_VIPER                          0x00d1
+#define T3_SSID_DELL_JAGUAR                         0x0106
+#define T3_SSID_DELL_MERLOT                         0x0109
+#define T3_SSID_DELL_SLIM_MERLOT                    0x010a
+
+/* Compaq subsystem/subvendor IDs */
+
+#define T3_SVID_COMPAQ                              0x0e11
+
+#define T3_SSID_COMPAQ_BANSHEE                      0x007c
+#define T3_SSID_COMPAQ_BANSHEE_2                    0x009a
+#define T3_SSID_COMPAQ_CHANGELING                   0x007d
+#define T3_SSID_COMPAQ_NC7780                       0x0085
+#define T3_SSID_COMPAQ_NC7780_2                     0x0099
+
+
+/******************************************************************************/
+/* MII registers. */
+/******************************************************************************/
+
+/* Control register. */
+#define PHY_CTRL_REG                                0x00
+
+#define PHY_CTRL_SPEED_MASK                         (BIT_6 | BIT_13)
+#define PHY_CTRL_SPEED_SELECT_10MBPS                BIT_NONE
+#define PHY_CTRL_SPEED_SELECT_100MBPS               BIT_13
+#define PHY_CTRL_SPEED_SELECT_1000MBPS              BIT_6
+#define PHY_CTRL_COLLISION_TEST_ENABLE              BIT_7
+#define PHY_CTRL_FULL_DUPLEX_MODE                   BIT_8
+#define PHY_CTRL_RESTART_AUTO_NEG                   BIT_9
+#define PHY_CTRL_ISOLATE_PHY                        BIT_10
+#define PHY_CTRL_LOWER_POWER_MODE                   BIT_11
+#define PHY_CTRL_AUTO_NEG_ENABLE                    BIT_12
+#define PHY_CTRL_LOOPBACK_MODE                      BIT_14
+#define PHY_CTRL_PHY_RESET                          BIT_15
+
+
+/* Status register. */
+#define PHY_STATUS_REG                              0x01
+
+#define PHY_STATUS_LINK_PASS                        BIT_2
+#define PHY_STATUS_AUTO_NEG_COMPLETE                BIT_5
+
+
+/* Phy Id registers. */
+#define PHY_ID1_REG                                 0x02
+#define PHY_ID1_OUI_MASK                            0xffff
+
+#define PHY_ID2_REG                                 0x03
+#define PHY_ID2_REV_MASK                            0x000f
+#define PHY_ID2_MODEL_MASK                          0x03f0
+#define PHY_ID2_OUI_MASK                            0xfc00
+
+
+/* Auto-negotiation advertisement register. */
+#define PHY_AN_AD_REG                               0x04
+
+#define PHY_AN_AD_ASYM_PAUSE                        BIT_11
+#define PHY_AN_AD_PAUSE_CAPABLE                     BIT_10
+#define PHY_AN_AD_10BASET_HALF                      BIT_5
+#define PHY_AN_AD_10BASET_FULL                      BIT_6
+#define PHY_AN_AD_100BASETX_HALF                    BIT_7
+#define PHY_AN_AD_100BASETX_FULL                    BIT_8
+#define PHY_AN_AD_PROTOCOL_802_3_CSMA_CD            0x01
+
+
+/* Auto-negotiation Link Partner Ability register. */
+#define PHY_LINK_PARTNER_ABILITY_REG                0x05
+
+#define PHY_LINK_PARTNER_ASYM_PAUSE                 BIT_11
+#define PHY_LINK_PARTNER_PAUSE_CAPABLE              BIT_10
+
+
+/* Auto-negotiation expansion register. */
+#define PHY_AN_EXPANSION_REG                        0x06
+
+
+
+/******************************************************************************/
+/* BCM5400 and BCM5401 phy info. */
+/******************************************************************************/
+
+#define PHY_DEVICE_ID           1
+
+/* OUI: bit 31-10;   Model#: bit 9-4;   Rev# bit 3-0. */
+#define PHY_UNKNOWN_PHY                             0x00000000
+#define PHY_BCM5400_PHY_ID                          0x60008040
+#define PHY_BCM5401_PHY_ID                          0x60008050
+#define PHY_BCM5411_PHY_ID                          0x60008070
+#define PHY_BCM5701_PHY_ID                          0x60008110
+#define PHY_BCM5703_PHY_ID                          0x60008160
+#define PHY_BCM5704_PHY_ID                          0x60008190
+#define PHY_BCM8002_PHY_ID                          0x60010140
+
+#define PHY_BCM5401_B0_REV                          0x1
+#define PHY_BCM5401_B2_REV                          0x3
+#define PHY_BCM5401_C0_REV                          0x6
+
+#define PHY_ID_OUI_MASK                             0xfffffc00
+#define PHY_ID_MODEL_MASK                           0x000003f0
+#define PHY_ID_REV_MASK                             0x0000000f
+#define PHY_ID_MASK                                 (PHY_ID_OUI_MASK |      \
+                                                    PHY_ID_MODEL_MASK)
+
+
+#define UNKNOWN_PHY_ID(x)   ((((x) & PHY_ID_MASK) != PHY_BCM5400_PHY_ID) && \
+                            (((x) & PHY_ID_MASK) != PHY_BCM5401_PHY_ID) && \
+                            (((x) & PHY_ID_MASK) != PHY_BCM5411_PHY_ID) && \
+                            (((x) & PHY_ID_MASK) != PHY_BCM5701_PHY_ID) && \
+                            (((x) & PHY_ID_MASK) != PHY_BCM5703_PHY_ID) && \
+                            (((x) & PHY_ID_MASK) != PHY_BCM5704_PHY_ID) && \
+                            (((x) & PHY_ID_MASK) != PHY_BCM8002_PHY_ID))
+
+
+
+/* 1000Base-T control register. */
+#define BCM540X_1000BASET_CTRL_REG                  0x09
+
+#define BCM540X_AN_AD_1000BASET_HALF                BIT_8
+#define BCM540X_AN_AD_1000BASET_FULL                BIT_9
+#define BCM540X_CONFIG_AS_MASTER                    BIT_11
+#define BCM540X_ENABLE_CONFIG_AS_MASTER             BIT_12
+
+
+/* Extended control register. */
+#define BCM540X_EXT_CTRL_REG                        0x10
+
+#define BCM540X_EXT_CTRL_LINK3_LED_MODE             BIT_1
+#define BCM540X_EXT_CTRL_TBI                        BIT_15
+
+/* PHY extended status register. */
+#define BCM540X_EXT_STATUS_REG                      0x11
+
+#define BCM540X_EXT_STATUS_LINK_PASS                BIT_8
+
+
+/* DSP Coefficient Read/Write Port. */
+#define BCM540X_DSP_RW_PORT                         0x15
+
+
+/* DSP Coeficient Address Register. */
+#define BCM540X_DSP_ADDRESS_REG                     0x17
+
+#define BCM540X_DSP_TAP_NUMBER_MASK                 0x00
+#define BCM540X_DSP_AGC_A                           0x00
+#define BCM540X_DSP_AGC_B                           0x01
+#define BCM540X_DSP_MSE_PAIR_STATUS                 0x02
+#define BCM540X_DSP_SOFT_DECISION                   0x03
+#define BCM540X_DSP_PHASE_REG                       0x04
+#define BCM540X_DSP_SKEW                            0x05
+#define BCM540X_DSP_POWER_SAVER_UPPER_BOUND         0x06
+#define BCM540X_DSP_POWER_SAVER_LOWER_BOUND         0x07
+#define BCM540X_DSP_LAST_ECHO                       0x08
+#define BCM540X_DSP_FREQUENCY                       0x09
+#define BCM540X_DSP_PLL_BANDWIDTH                   0x0a
+#define BCM540X_DSP_PLL_PHASE_OFFSET                0x0b
+
+#define BCM540X_DSP_FILTER_DCOFFSET                 (BIT_10 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT3                    (BIT_8 | BIT_9 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT2                    (BIT_9 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT1                    (BIT_8 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT0                    BIT_11
+#define BCM540X_DSP_FILTER_NEXT3                    (BIT_8 | BIT_9 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT2                    (BIT_9 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT1                    (BIT_8 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT0                    BIT_10
+#define BCM540X_DSP_FILTER_ECHO                     (BIT_8 | BIT_9)
+#define BCM540X_DSP_FILTER_DFE                      BIT_9
+#define BCM540X_DSP_FILTER_FFE                      BIT_8
+
+#define BCM540X_DSP_CONTROL_ALL_FILTERS             BIT_12
+
+#define BCM540X_DSP_SEL_CH_0                        BIT_NONE
+#define BCM540X_DSP_SEL_CH_1                        BIT_13
+#define BCM540X_DSP_SEL_CH_2                        BIT_14
+#define BCM540X_DSP_SEL_CH_3                        (BIT_13 | BIT_14)
+
+#define BCM540X_CONTROL_ALL_CHANNELS                BIT_15
+
+
+/* Auxilliary Control Register (Shadow Register) */
+#define BCM5401_AUX_CTRL                            0x18
+
+#define BCM5401_SHADOW_SEL_MASK                     0x7
+#define BCM5401_SHADOW_SEL_NORMAL                   0x00
+#define BCM5401_SHADOW_SEL_10BASET                  0x01
+#define BCM5401_SHADOW_SEL_POWER_CONTROL            0x02
+#define BCM5401_SHADOW_SEL_IP_PHONE                 0x03
+#define BCM5401_SHADOW_SEL_MISC_TEST1               0x04
+#define BCM5401_SHADOW_SEL_MISC_TEST2               0x05
+#define BCM5401_SHADOW_SEL_IP_PHONE_SEED            0x06
+
+
+/* Shadow register selector == '000' */
+#define BCM5401_SHDW_NORMAL_DIAG_MODE               BIT_3
+#define BCM5401_SHDW_NORMAL_DISABLE_MBP             BIT_4
+#define BCM5401_SHDW_NORMAL_DISABLE_LOW_PWR         BIT_5
+#define BCM5401_SHDW_NORMAL_DISABLE_INV_PRF         BIT_6
+#define BCM5401_SHDW_NORMAL_DISABLE_PRF             BIT_7
+#define BCM5401_SHDW_NORMAL_RX_SLICING_NORMAL       BIT_NONE
+#define BCM5401_SHDW_NORMAL_RX_SLICING_4D           BIT_8
+#define BCM5401_SHDW_NORMAL_RX_SLICING_3LVL_1D      BIT_9
+#define BCM5401_SHDW_NORMAL_RX_SLICING_5LVL_1D      (BIT_8 | BIT_9)
+#define BCM5401_SHDW_NORMAL_TX_6DB_CODING           BIT_10
+#define BCM5401_SHDW_NORMAL_ENABLE_SM_DSP_CLOCK     BIT_11
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_4NS       BIT_NONE
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_5NS       BIT_12
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_3NS       BIT_13
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_0NS       (BIT_12 | BIT_13)
+#define BCM5401_SHDW_NORMAL_EXT_PACKET_LENGTH       BIT_14
+#define BCM5401_SHDW_NORMAL_EXTERNAL_LOOPBACK       BIT_15
+
+
+/* Auxilliary status summary. */
+#define BCM540X_AUX_STATUS_REG                      0x19
+
+#define BCM540X_AUX_LINK_PASS                       BIT_2
+#define BCM540X_AUX_SPEED_MASK                      (BIT_8 | BIT_9 | BIT_10)
+#define BCM540X_AUX_10BASET_HD                      BIT_8
+#define BCM540X_AUX_10BASET_FD                      BIT_9
+#define BCM540X_AUX_100BASETX_HD                    (BIT_8 | BIT_9)
+#define BCM540X_AUX_100BASET4                       BIT_10
+#define BCM540X_AUX_100BASETX_FD                    (BIT_8 | BIT_10)
+#define BCM540X_AUX_100BASET_HD                     (BIT_9 | BIT_10)
+#define BCM540X_AUX_100BASET_FD                     (BIT_8 | BIT_9 | BIT_10)
+
+
+/* Interrupt status. */
+#define BCM540X_INT_STATUS_REG                      0x1a
+
+#define BCM540X_INT_LINK_CHANGE                     BIT_1
+#define BCM540X_INT_SPEED_CHANGE                    BIT_2
+#define BCM540X_INT_DUPLEX_CHANGE                   BIT_3
+#define BCM540X_INT_AUTO_NEG_PAGE_RX                BIT_10
+
+
+/* Interrupt mask register. */
+#define BCM540X_INT_MASK_REG                        0x1b
+
+
+
+/******************************************************************************/
+/* Register definitions. */
+/******************************************************************************/
+
+typedef volatile LM_UINT8 T3_8BIT_REGISTER, *PT3_8BIT_REGISTER;
+typedef volatile LM_UINT16 T3_16BIT_REGISTER, *PT3_16BIT_REGISTER;
+typedef volatile LM_UINT32 T3_32BIT_REGISTER, *PT3_32BIT_REGISTER;
+
+typedef struct {
+    /* Big endian format. */
+    T3_32BIT_REGISTER High;
+    T3_32BIT_REGISTER Low;
+} T3_64BIT_REGISTER, *PT3_64BIT_REGISTER;
+
+typedef T3_64BIT_REGISTER T3_64BIT_HOST_ADDR, *PT3_64BIT_HOST_ADDR;
+
+#define T3_NUM_OF_DMA_DESC    256
+#define T3_NUM_OF_MBUF        768
+
+typedef struct
+{
+  T3_64BIT_REGISTER host_addr;
+  T3_32BIT_REGISTER nic_mbuf;
+  T3_16BIT_REGISTER len;
+  T3_16BIT_REGISTER cqid_sqid;
+  T3_32BIT_REGISTER flags;
+  T3_32BIT_REGISTER opaque1;
+  T3_32BIT_REGISTER opaque2;
+  T3_32BIT_REGISTER opaque3;
+}T3_DMA_DESC, *PT3_DMA_DESC;
+
+
+
+/******************************************************************************/
+/* Ring control block. */
+/******************************************************************************/
+
+typedef struct {
+    T3_64BIT_REGISTER HostRingAddr;
+
+    union {
+        struct {
+#ifdef BIG_ENDIAN_HOST
+            T3_16BIT_REGISTER MaxLen;
+            T3_16BIT_REGISTER Flags;
+#else /* BIG_ENDIAN_HOST */
+            T3_16BIT_REGISTER Flags;
+            T3_16BIT_REGISTER MaxLen;
+#endif
+        } s;
+
+        T3_32BIT_REGISTER MaxLen_Flags;
+    } u;
+
+    T3_32BIT_REGISTER NicRingAddr;
+} T3_RCB, *PT3_RCB;
+
+#define T3_RCB_FLAG_USE_EXT_RECV_BD                     BIT_0
+#define T3_RCB_FLAG_RING_DISABLED                       BIT_1
+
+
+
+/******************************************************************************/
+/* Status block. */
+/******************************************************************************/
+
+/*
+ * Size of status block is actually 0x50 bytes.  Use 0x80 bytes for
+ * cache line alignment.
+ */
+#define T3_STATUS_BLOCK_SIZE                                    0x80
+
+typedef struct {
+    volatile LM_UINT32 Status;
+    #define STATUS_BLOCK_UPDATED                                BIT_0
+    #define STATUS_BLOCK_LINK_CHANGED_STATUS                    BIT_1
+    #define STATUS_BLOCK_ERROR                                  BIT_2
+
+    volatile LM_UINT32 StatusTag;
+
+#ifdef BIG_ENDIAN_HOST
+    volatile LM_UINT16 RcvStdConIdx;
+    volatile LM_UINT16 RcvJumboConIdx;
+
+    volatile LM_UINT16 Reserved2;
+    volatile LM_UINT16 RcvMiniConIdx;
+
+    struct {
+        volatile LM_UINT16 SendConIdx;   /* Send consumer index. */
+        volatile LM_UINT16 RcvProdIdx;   /* Receive producer index. */
+    } Idx[16];
+#else /* BIG_ENDIAN_HOST */
+    volatile LM_UINT16 RcvJumboConIdx;
+    volatile LM_UINT16 RcvStdConIdx;
+
+    volatile LM_UINT16 RcvMiniConIdx;
+    volatile LM_UINT16 Reserved2;
+
+    struct {
+        volatile LM_UINT16 RcvProdIdx;   /* Receive producer index. */
+        volatile LM_UINT16 SendConIdx;   /* Send consumer index. */
+    } Idx[16];
+#endif
+} T3_STATUS_BLOCK, *PT3_STATUS_BLOCK;
+
+
+
+/******************************************************************************/
+/* Receive buffer descriptors. */
+/******************************************************************************/
+
+typedef struct {
+    T3_64BIT_HOST_ADDR HostAddr;
+
+#ifdef BIG_ENDIAN_HOST
+    volatile LM_UINT16 Index;
+    volatile LM_UINT16 Len;
+
+    volatile LM_UINT16 Type;
+    volatile LM_UINT16 Flags;
+
+    volatile LM_UINT16 IpCksum;
+    volatile LM_UINT16 TcpUdpCksum;
+
+    volatile LM_UINT16 ErrorFlag;
+    volatile LM_UINT16 VlanTag;
+#else /* BIG_ENDIAN_HOST */
+    volatile LM_UINT16 Len;
+    volatile LM_UINT16 Index;
+
+    volatile LM_UINT16 Flags;
+    volatile LM_UINT16 Type;
+
+    volatile LM_UINT16 TcpUdpCksum;
+    volatile LM_UINT16 IpCksum;
+
+    volatile LM_UINT16 VlanTag;
+    volatile LM_UINT16 ErrorFlag;
+#endif
+
+    volatile LM_UINT32 Reserved;
+    volatile LM_UINT32 Opaque;
+} T3_RCV_BD, *PT3_RCV_BD;
+
+
+typedef struct {
+    T3_64BIT_HOST_ADDR HostAddr[3];
+
+#ifdef BIG_ENDIAN_HOST
+    LM_UINT16 Len1;
+    LM_UINT16 Len2;
+
+    LM_UINT16 Len3;
+    LM_UINT16 Reserved1;
+#else /* BIG_ENDIAN_HOST */
+    LM_UINT16 Len2;
+    LM_UINT16 Len1;
+
+    LM_UINT16 Reserved1;
+    LM_UINT16 Len3;
+#endif
+
+    T3_RCV_BD StdRcvBd;
+} T3_EXT_RCV_BD, *PT3_EXT_RCV_BD;
+
+
+/* Error flags. */
+#define RCV_BD_ERR_BAD_CRC                          0x0001
+#define RCV_BD_ERR_COLL_DETECT                      0x0002
+#define RCV_BD_ERR_LINK_LOST_DURING_PKT             0x0004
+#define RCV_BD_ERR_PHY_DECODE_ERR                   0x0008
+#define RCV_BD_ERR_ODD_NIBBLED_RCVD_MII             0x0010
+#define RCV_BD_ERR_MAC_ABORT                        0x0020
+#define RCV_BD_ERR_LEN_LT_64                        0x0040
+#define RCV_BD_ERR_TRUNC_NO_RESOURCES               0x0080
+#define RCV_BD_ERR_GIANT_FRAME_RCVD                 0x0100
+
+
+/* Buffer descriptor flags. */
+#define RCV_BD_FLAG_END                             0x0004
+#define RCV_BD_FLAG_JUMBO_RING                      0x0020
+#define RCV_BD_FLAG_VLAN_TAG                        0x0040
+#define RCV_BD_FLAG_FRAME_HAS_ERROR                 0x0400
+#define RCV_BD_FLAG_MINI_RING                       0x0800
+#define RCV_BD_FLAG_IP_CHKSUM_FIELD                 0x1000
+#define RCV_BD_FLAG_TCP_UDP_CHKSUM_FIELD            0x2000
+#define RCV_BD_FLAG_TCP_PACKET                      0x4000
+
+
+
+/******************************************************************************/
+/* Send buffer descriptor. */
+/******************************************************************************/
+
+typedef struct {
+    T3_64BIT_HOST_ADDR HostAddr;
+
+    union {
+        struct {
+#ifdef BIG_ENDIAN_HOST
+            LM_UINT16 Len;
+            LM_UINT16 Flags;
+#else /* BIG_ENDIAN_HOST */
+            LM_UINT16 Flags;
+            LM_UINT16 Len;
+#endif
+        } s1;
+
+        LM_UINT32 Len_Flags;
+    } u1;
+
+    union {
+        struct {
+#ifdef BIG_ENDIAN_HOST
+            LM_UINT16 Reserved;
+            LM_UINT16 VlanTag;
+#else /* BIG_ENDIAN_HOST */
+            LM_UINT16 VlanTag;
+            LM_UINT16 Reserved;
+#endif
+        } s2;
+
+        LM_UINT32 VlanTag;
+    } u2;
+} T3_SND_BD, *PT3_SND_BD;
+
+
+/* Send buffer descriptor flags. */
+#define SND_BD_FLAG_TCP_UDP_CKSUM                   0x0001
+#define SND_BD_FLAG_IP_CKSUM                        0x0002
+#define SND_BD_FLAG_END                             0x0004
+#define SND_BD_FLAG_IP_FRAG                         0x0008
+#define SND_BD_FLAG_IP_FRAG_END                     0x0010
+#define SND_BD_FLAG_VLAN_TAG                        0x0040
+#define SND_BD_FLAG_COAL_NOW                        0x0080
+#define SND_BD_FLAG_CPU_PRE_DMA                     0x0100
+#define SND_BD_FLAG_CPU_POST_DMA                    0x0200
+#define SND_BD_FLAG_INSERT_SRC_ADDR                 0x1000
+#define SND_BD_FLAG_CHOOSE_SRC_ADDR                 0x6000
+#define SND_BD_FLAG_DONT_GEN_CRC                    0x8000
+
+/* MBUFs */
+typedef struct T3_MBUF_FRAME_DESC {
+#ifdef BIG_ENDIAN_HOST
+  LM_UINT32 status_control;
+  union {
+    struct {
+      LM_UINT8 cqid;
+      LM_UINT8 reserved1;
+      LM_UINT16 length;
+    }s1;
+    LM_UINT32 word;
+  }u1;
+  union {
+    struct
+    {
+      LM_UINT16 ip_hdr_start;
+      LM_UINT16 tcp_udp_hdr_start;
+    }s2;
+
+    LM_UINT32 word;
+  }u2;
+
+  union {
+    struct {
+      LM_UINT16 data_start;
+      LM_UINT16 vlan_id;
+    }s3;
+
+    LM_UINT32 word;
+  }u3;
+
+  union {
+    struct {
+      LM_UINT16 ip_checksum;
+      LM_UINT16 tcp_udp_checksum;
+    }s4;
+
+    LM_UINT32 word;
+  }u4;
+
+  union {
+    struct {
+      LM_UINT16 pseudo_checksum;
+      LM_UINT16 checksum_status;
+    }s5;
+
+    LM_UINT32 word;
+  }u5;
+
+  union {
+    struct {
+      LM_UINT16 rule_match;
+      LM_UINT8 class;
+      LM_UINT8 rupt;
+    }s6;
+
+    LM_UINT32 word;
+  }u6;
+
+  union {
+    struct {
+      LM_UINT16 reserved2;
+      LM_UINT16 mbuf_num;
+    }s7;
+
+    LM_UINT32 word;
+  }u7;
+
+  LM_UINT32 reserved3;
+  LM_UINT32 reserved4;
+#else
+  LM_UINT32 status_control;
+  union {
+    struct {
+      LM_UINT16 length;
+      LM_UINT8  reserved1;
+      LM_UINT8  cqid;
+    }s1;
+    LM_UINT32 word;
+  }u1;
+  union {
+    struct
+    {
+      LM_UINT16 tcp_udp_hdr_start;
+      LM_UINT16 ip_hdr_start;
+    }s2;
+
+    LM_UINT32 word;
+  }u2;
+
+  union {
+    struct {
+      LM_UINT16 vlan_id;
+      LM_UINT16 data_start;
+    }s3;
+
+    LM_UINT32 word;
+  }u3;
+
+  union {
+    struct {
+      LM_UINT16 tcp_udp_checksum;
+      LM_UINT16 ip_checksum;
+    }s4;
+
+    LM_UINT32 word;
+  }u4;
+
+  union {
+    struct {
+      LM_UINT16 checksum_status;
+      LM_UINT16 pseudo_checksum;
+    }s5;
+
+    LM_UINT32 word;
+  }u5;
+
+  union {
+    struct {
+      LM_UINT8 rupt;
+      LM_UINT8 class;
+      LM_UINT16 rule_match;
+    }s6;
+
+    LM_UINT32 word;
+  }u6;
+
+  union {
+    struct {
+      LM_UINT16 mbuf_num;
+      LM_UINT16 reserved2;
+    }s7;
+
+    LM_UINT32 word;
+  }u7;
+
+  LM_UINT32 reserved3;
+  LM_UINT32 reserved4;
+#endif
+}T3_MBUF_FRAME_DESC,*PT3_MBUF_FRAME_DESC;
+
+typedef struct T3_MBUF_HDR {
+  union {
+    struct {
+      unsigned int C:1;
+      unsigned int F:1;
+      unsigned int reserved1:7;
+      unsigned int next_mbuf:16;
+      unsigned int length:7;
+    }s1;
+
+    LM_UINT32 word;
+  }u1;
+
+  LM_UINT32 next_frame_ptr;
+}T3_MBUF_HDR, *PT3_MBUF_HDR;
+
+typedef struct T3_MBUF
+{
+  T3_MBUF_HDR hdr;
+  union
+  {
+    struct {
+      T3_MBUF_FRAME_DESC frame_hdr;
+      LM_UINT32 data[20];
+    }s1;
+
+    struct {
+      LM_UINT32 data[30];
+    }s2;
+  }body;
+}T3_MBUF, *PT3_MBUF;
+
+#define T3_MBUF_BASE   (T3_NIC_MBUF_POOL_ADDR >> 7)
+#define T3_MBUF_END    ((T3_NIC_MBUF_POOL_ADDR + T3_NIC_MBUF_POOL_SIZE) >> 7)
+
+
+
+/******************************************************************************/
+/* Statistics block. */
+/******************************************************************************/
+
+typedef struct {
+    LM_UINT8 Reserved0[0x400-0x300];
+
+    /* Statistics maintained by Receive MAC. */
+    T3_64BIT_REGISTER ifHCInOctets;
+    T3_64BIT_REGISTER Reserved1;
+    T3_64BIT_REGISTER etherStatsFragments;
+    T3_64BIT_REGISTER ifHCInUcastPkts;
+    T3_64BIT_REGISTER ifHCInMulticastPkts;
+    T3_64BIT_REGISTER ifHCInBroadcastPkts;
+    T3_64BIT_REGISTER dot3StatsFCSErrors;
+    T3_64BIT_REGISTER dot3StatsAlignmentErrors;
+    T3_64BIT_REGISTER xonPauseFramesReceived;
+    T3_64BIT_REGISTER xoffPauseFramesReceived;
+    T3_64BIT_REGISTER macControlFramesReceived;
+    T3_64BIT_REGISTER xoffStateEntered;
+    T3_64BIT_REGISTER dot3StatsFramesTooLong;
+    T3_64BIT_REGISTER etherStatsJabbers;
+    T3_64BIT_REGISTER etherStatsUndersizePkts;
+    T3_64BIT_REGISTER inRangeLengthError;
+    T3_64BIT_REGISTER outRangeLengthError;
+    T3_64BIT_REGISTER etherStatsPkts64Octets;
+    T3_64BIT_REGISTER etherStatsPkts65Octetsto127Octets;
+    T3_64BIT_REGISTER etherStatsPkts128Octetsto255Octets;
+    T3_64BIT_REGISTER etherStatsPkts256Octetsto511Octets;
+    T3_64BIT_REGISTER etherStatsPkts512Octetsto1023Octets;
+    T3_64BIT_REGISTER etherStatsPkts1024Octetsto1522Octets;
+    T3_64BIT_REGISTER etherStatsPkts1523Octetsto2047Octets;
+    T3_64BIT_REGISTER etherStatsPkts2048Octetsto4095Octets;
+    T3_64BIT_REGISTER etherStatsPkts4096Octetsto8191Octets;
+    T3_64BIT_REGISTER etherStatsPkts8192Octetsto9022Octets;
+
+    T3_64BIT_REGISTER Unused1[37];
+
+    /* Statistics maintained by Transmit MAC. */
+    T3_64BIT_REGISTER ifHCOutOctets;
+    T3_64BIT_REGISTER Reserved2;
+    T3_64BIT_REGISTER etherStatsCollisions;
+    T3_64BIT_REGISTER outXonSent;
+    T3_64BIT_REGISTER outXoffSent;
+    T3_64BIT_REGISTER flowControlDone;
+    T3_64BIT_REGISTER dot3StatsInternalMacTransmitErrors;
+    T3_64BIT_REGISTER dot3StatsSingleCollisionFrames;
+    T3_64BIT_REGISTER dot3StatsMultipleCollisionFrames;
+    T3_64BIT_REGISTER dot3StatsDeferredTransmissions;
+    T3_64BIT_REGISTER Reserved3;
+    T3_64BIT_REGISTER dot3StatsExcessiveCollisions;
+    T3_64BIT_REGISTER dot3StatsLateCollisions;
+    T3_64BIT_REGISTER dot3Collided2Times;
+    T3_64BIT_REGISTER dot3Collided3Times;
+    T3_64BIT_REGISTER dot3Collided4Times;
+    T3_64BIT_REGISTER dot3Collided5Times;
+    T3_64BIT_REGISTER dot3Collided6Times;
+    T3_64BIT_REGISTER dot3Collided7Times;
+    T3_64BIT_REGISTER dot3Collided8Times;
+    T3_64BIT_REGISTER dot3Collided9Times;
+    T3_64BIT_REGISTER dot3Collided10Times;
+    T3_64BIT_REGISTER dot3Collided11Times;
+    T3_64BIT_REGISTER dot3Collided12Times;
+    T3_64BIT_REGISTER dot3Collided13Times;
+    T3_64BIT_REGISTER dot3Collided14Times;
+    T3_64BIT_REGISTER dot3Collided15Times;
+    T3_64BIT_REGISTER ifHCOutUcastPkts;
+    T3_64BIT_REGISTER ifHCOutMulticastPkts;
+    T3_64BIT_REGISTER ifHCOutBroadcastPkts;
+    T3_64BIT_REGISTER dot3StatsCarrierSenseErrors;
+    T3_64BIT_REGISTER ifOutDiscards;
+    T3_64BIT_REGISTER ifOutErrors;
+
+    T3_64BIT_REGISTER Unused2[31];
+
+    /* Statistics maintained by Receive List Placement. */
+    T3_64BIT_REGISTER COSIfHCInPkts[16];
+    T3_64BIT_REGISTER COSFramesDroppedDueToFilters;
+    T3_64BIT_REGISTER nicDmaWriteQueueFull;
+    T3_64BIT_REGISTER nicDmaWriteHighPriQueueFull;
+    T3_64BIT_REGISTER nicNoMoreRxBDs;
+    T3_64BIT_REGISTER ifInDiscards;
+    T3_64BIT_REGISTER ifInErrors;
+    T3_64BIT_REGISTER nicRecvThresholdHit;
+
+    T3_64BIT_REGISTER Unused3[9];
+
+    /* Statistics maintained by Send Data Initiator. */
+    T3_64BIT_REGISTER COSIfHCOutPkts[16];
+    T3_64BIT_REGISTER nicDmaReadQueueFull;
+    T3_64BIT_REGISTER nicDmaReadHighPriQueueFull;
+    T3_64BIT_REGISTER nicSendDataCompQueueFull;
+
+    /* Statistics maintained by Host Coalescing. */
+    T3_64BIT_REGISTER nicRingSetSendProdIndex;
+    T3_64BIT_REGISTER nicRingStatusUpdate;
+    T3_64BIT_REGISTER nicInterrupts;
+    T3_64BIT_REGISTER nicAvoidedInterrupts;
+    T3_64BIT_REGISTER nicSendThresholdHit;
+
+    LM_UINT8 Reserved4[0xb00-0x9c0];
+} T3_STATS_BLOCK, *PT3_STATS_BLOCK;
+
+
+
+/******************************************************************************/
+/* PCI configuration registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_16BIT_REGISTER VendorId;
+    T3_16BIT_REGISTER DeviceId;
+
+    T3_16BIT_REGISTER Command;
+    T3_16BIT_REGISTER Status;
+
+    T3_32BIT_REGISTER ClassCodeRevId;
+
+    T3_8BIT_REGISTER CacheLineSize;
+    T3_8BIT_REGISTER LatencyTimer;
+    T3_8BIT_REGISTER HeaderType;
+    T3_8BIT_REGISTER Bist;
+
+    T3_32BIT_REGISTER MemBaseAddrLow;
+    T3_32BIT_REGISTER MemBaseAddrHigh;
+
+    LM_UINT8 Unused1[20];
+
+    T3_16BIT_REGISTER SubsystemVendorId;
+    T3_16BIT_REGISTER SubsystemId;
+
+    T3_32BIT_REGISTER RomBaseAddr;
+
+    T3_8BIT_REGISTER PciXCapiblityPtr;
+    LM_UINT8 Unused2[7];
+
+    T3_8BIT_REGISTER IntLine;
+    T3_8BIT_REGISTER IntPin;
+    T3_8BIT_REGISTER MinGnt;
+    T3_8BIT_REGISTER MaxLat;
+
+    T3_8BIT_REGISTER PciXCapabilities;
+    T3_8BIT_REGISTER PmCapabilityPtr;
+    T3_16BIT_REGISTER PciXCommand;
+
+    T3_32BIT_REGISTER PciXStatus;
+
+    T3_8BIT_REGISTER PmCapabilityId;
+    T3_8BIT_REGISTER VpdCapabilityPtr;
+    T3_16BIT_REGISTER PmCapabilities;
+
+    T3_16BIT_REGISTER PmCtrlStatus;
+    #define PM_CTRL_PME_STATUS            BIT_15
+    #define PM_CTRL_PME_ENABLE            BIT_8
+    #define PM_CTRL_PME_POWER_STATE_D0    0
+    #define PM_CTRL_PME_POWER_STATE_D1    1
+    #define PM_CTRL_PME_POWER_STATE_D2    2
+    #define PM_CTRL_PME_POWER_STATE_D3H   3
+
+    T3_8BIT_REGISTER BridgeSupportExt;
+    T3_8BIT_REGISTER PmData;
+
+    T3_8BIT_REGISTER VpdCapabilityId;
+    T3_8BIT_REGISTER MsiCapabilityPtr;
+    T3_16BIT_REGISTER VpdAddrFlag;
+    #define VPD_FLAG_WRITE      (1 << 15)
+    #define VPD_FLAG_RW_MASK    (1 << 15)
+    #define VPD_FLAG_READ       0
+
+
+    T3_32BIT_REGISTER VpdData;
+
+    T3_8BIT_REGISTER MsiCapabilityId;
+    T3_8BIT_REGISTER NextCapabilityPtr;
+    T3_16BIT_REGISTER MsiCtrl;
+    #define MSI_CTRL_64BIT_CAP     (1 << 7)
+    #define MSI_CTRL_MSG_ENABLE(x) (x << 4)
+    #define MSI_CTRL_MSG_CAP(x)    (x << 1)
+    #define MSI_CTRL_ENABLE        (1 << 0)
+
+
+    T3_32BIT_REGISTER MsiAddrLow;
+    T3_32BIT_REGISTER MsiAddrHigh;
+
+    T3_16BIT_REGISTER MsiData;
+    T3_16BIT_REGISTER Unused3;
+
+    T3_32BIT_REGISTER MiscHostCtrl;
+    #define MISC_HOST_CTRL_CLEAR_INT                        BIT_0
+    #define MISC_HOST_CTRL_MASK_PCI_INT                     BIT_1
+    #define MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP          BIT_2
+    #define MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP          BIT_3
+    #define MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW          BIT_4
+    #define MISC_HOST_CTRL_ENABLE_CLK_REG_RW                BIT_5
+    #define MISC_HOST_CTRL_ENABLE_REG_WORD_SWAP             BIT_6
+    #define MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS           BIT_7
+    #define MISC_HOST_CTRL_ENABLE_INT_MASK_MODE             BIT_8
+    #define MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE        BIT_9
+
+    T3_32BIT_REGISTER DmaReadWriteCtrl;
+    #define DMA_CTRL_WRITE_BOUNDARY_MASK            (BIT_11 | BIT_12 | BIT_13)
+    #define DMA_CTRL_WRITE_BOUNDARY_DISABLE         0
+    #define DMA_CTRL_WRITE_BOUNDARY_16              BIT_11
+    #define DMA_CTRL_WRITE_BOUNDARY_32              BIT_12
+    #define DMA_CTRL_WRITE_BOUNDARY_64              (BIT_12 | BIT_11)
+    #define DMA_CTRL_WRITE_BOUNDARY_128             BIT_13
+    #define DMA_CTRL_WRITE_BOUNDARY_256             (BIT_13 | BIT_11)
+    #define DMA_CTRL_WRITE_BOUNDARY_512             (BIT_13 | BIT_12)
+    #define DMA_CTRL_WRITE_BOUNDARY_1024            (BIT_13 | BIT_12 | BIT_11)
+    #define DMA_CTRL_WRITE_ONE_DMA_AT_ONCE          BIT_14
+
+
+    T3_32BIT_REGISTER PciState;
+    #define T3_PCI_STATE_FORCE_PCI_RESET                    BIT_0
+    #define T3_PCI_STATE_INTERRUPT_NOT_ACTIVE               BIT_1
+    #define T3_PCI_STATE_NOT_PCI_X_BUS                      BIT_2
+    #define T3_PCI_STATE_HIGH_BUS_SPEED                     BIT_3
+    #define T3_PCI_STATE_32BIT_PCI_BUS                      BIT_4
+    #define T3_PCI_STATE_PCI_ROM_ENABLE                     BIT_5
+    #define T3_PCI_STATE_PCI_ROM_RETRY_ENABLE               BIT_6
+    #define T3_PCI_STATE_FLAT_VIEW                          BIT_8
+    #define T3_PCI_STATE_RETRY_SAME_DMA                     BIT_13
+
+    T3_32BIT_REGISTER ClockCtrl;
+    #define T3_PCI_CLKCTRL_TXCPU_CLK_DISABLE                BIT_11
+    #define T3_PCI_CLKCTRL_RXCPU_CLK_DISABLE                BIT_10
+    #define T3_PCI_CLKCTRL_CORE_CLK_DISABLE                 BIT_9
+
+    T3_32BIT_REGISTER RegBaseAddr;
+
+    T3_32BIT_REGISTER MemWindowBaseAddr;
+
+#ifdef NIC_CPU_VIEW
+  /* These registers are ONLY visible to NIC CPU */
+    T3_32BIT_REGISTER PowerConsumed;
+    T3_32BIT_REGISTER PowerDissipated;
+#else /* NIC_CPU_VIEW */
+    T3_32BIT_REGISTER RegData;
+    T3_32BIT_REGISTER MemWindowData;
+#endif /* !NIC_CPU_VIEW */
+
+    T3_32BIT_REGISTER ModeCtrl;
+
+    T3_32BIT_REGISTER MiscCfg;
+
+    T3_32BIT_REGISTER MiscLocalCtrl;
+
+    T3_32BIT_REGISTER Unused4;
+
+    /* NOTE: Big/Little-endian clarification needed.  Are these register */
+    /* in big or little endian formate. */
+    T3_64BIT_REGISTER StdRingProdIdx;
+    T3_64BIT_REGISTER RcvRetRingConIdx;
+    T3_64BIT_REGISTER SndProdIdx;
+
+    LM_UINT8 Unused5[80];
+} T3_PCI_CONFIGURATION, *PT3_PCI_CONFIGURATION;
+
+#define PCIX_CMD_MAX_SPLIT_MASK                         0x0070
+#define PCIX_CMD_MAX_SPLIT_SHL                          4
+#define PCIX_CMD_MAX_BURST_MASK                         0x000c
+#define PCIX_CMD_MAX_BURST_SHL                          2
+#define PCIX_CMD_MAX_BURST_CPIOB                        2
+
+/******************************************************************************/
+/* Mac control registers. */
+/******************************************************************************/
+
+typedef struct {
+    /* MAC mode control. */
+    T3_32BIT_REGISTER Mode;
+    #define MAC_MODE_GLOBAL_RESET                       BIT_0
+    #define MAC_MODE_HALF_DUPLEX                        BIT_1
+    #define MAC_MODE_PORT_MODE_MASK                     (BIT_2 | BIT_3)
+    #define MAC_MODE_PORT_MODE_TBI                      (BIT_2 | BIT_3)
+    #define MAC_MODE_PORT_MODE_GMII                     BIT_3
+    #define MAC_MODE_PORT_MODE_MII                      BIT_2
+    #define MAC_MODE_PORT_MODE_NONE                     BIT_NONE
+    #define MAC_MODE_PORT_INTERNAL_LOOPBACK             BIT_4
+    #define MAC_MODE_TAGGED_MAC_CONTROL                 BIT_7
+    #define MAC_MODE_TX_BURSTING                        BIT_8
+    #define MAC_MODE_MAX_DEFER                          BIT_9
+    #define MAC_MODE_LINK_POLARITY                      BIT_10
+    #define MAC_MODE_ENABLE_RX_STATISTICS               BIT_11
+    #define MAC_MODE_CLEAR_RX_STATISTICS                BIT_12
+    #define MAC_MODE_FLUSH_RX_STATISTICS                BIT_13
+    #define MAC_MODE_ENABLE_TX_STATISTICS               BIT_14
+    #define MAC_MODE_CLEAR_TX_STATISTICS                BIT_15
+    #define MAC_MODE_FLUSH_TX_STATISTICS                BIT_16
+    #define MAC_MODE_SEND_CONFIGS                       BIT_17
+    #define MAC_MODE_DETECT_MAGIC_PACKET_ENABLE         BIT_18
+    #define MAC_MODE_ACPI_POWER_ON_ENABLE               BIT_19
+    #define MAC_MODE_ENABLE_MIP                         BIT_20
+    #define MAC_MODE_ENABLE_TDE                         BIT_21
+    #define MAC_MODE_ENABLE_RDE                         BIT_22
+    #define MAC_MODE_ENABLE_FHDE                        BIT_23
+
+    /* MAC status */
+    T3_32BIT_REGISTER Status;
+    #define MAC_STATUS_PCS_SYNCED                       BIT_0
+    #define MAC_STATUS_SIGNAL_DETECTED                  BIT_1
+    #define MAC_STATUS_RECEIVING_CFG                    BIT_2
+    #define MAC_STATUS_CFG_CHANGED                      BIT_3
+    #define MAC_STATUS_SYNC_CHANGED                     BIT_4
+    #define MAC_STATUS_PORT_DECODE_ERROR                BIT_10
+    #define MAC_STATUS_LINK_STATE_CHANGED               BIT_12
+    #define MAC_STATUS_MI_COMPLETION                    BIT_22
+    #define MAC_STATUS_MI_INTERRUPT                     BIT_23
+    #define MAC_STATUS_AP_ERROR                         BIT_24
+    #define MAC_STATUS_ODI_ERROR                        BIT_25
+    #define MAC_STATUS_RX_STATS_OVERRUN                 BIT_26
+    #define MAC_STATUS_TX_STATS_OVERRUN                 BIT_27
+
+    /* Event Enable */
+    T3_32BIT_REGISTER MacEvent;
+    #define MAC_EVENT_ENABLE_PORT_DECODE_ERR            BIT_10
+    #define MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN    BIT_12
+    #define MAC_EVENT_ENABLE_MI_COMPLETION              BIT_22
+    #define MAC_EVENT_ENABLE_MI_INTERRUPT               BIT_23
+    #define MAC_EVENT_ENABLE_AP_ERROR                   BIT_24
+    #define MAC_EVENT_ENABLE_ODI_ERROR                  BIT_25
+    #define MAC_EVENT_ENABLE_RX_STATS_OVERRUN           BIT_26
+    #define MAC_EVENT_ENABLE_TX_STATS_OVERRUN           BIT_27
+
+    /* Led control. */
+    T3_32BIT_REGISTER LedCtrl;
+    #define LED_CTRL_OVERRIDE_LINK_LED                  BIT_0
+    #define LED_CTRL_1000MBPS_LED_ON                    BIT_1
+    #define LED_CTRL_100MBPS_LED_ON                     BIT_2
+    #define LED_CTRL_10MBPS_LED_ON                      BIT_3
+    #define LED_CTRL_OVERRIDE_TRAFFIC_LED               BIT_4
+    #define LED_CTRL_BLINK_TRAFFIC_LED                  BIT_5
+    #define LED_CTRL_TRAFFIC_LED                        BIT_6
+    #define LED_CTRL_1000MBPS_LED_STATUS                BIT_7
+    #define LED_CTRL_100MBPS_LED_STATUS                 BIT_8
+    #define LED_CTRL_10MBPS_LED_STATUS                  BIT_9
+    #define LED_CTRL_TRAFFIC_LED_STATUS                 BIT_10
+    #define LED_CTRL_MAC_MODE                           BIT_NONE
+    #define LED_CTRL_PHY_MODE_1                         BIT_11
+    #define LED_CTRL_PHY_MODE_2                         BIT_12
+    #define LED_CTRL_BLINK_RATE_MASK                    0x7ff80000
+    #define LED_CTRL_OVERRIDE_BLINK_PERIOD              BIT_19
+    #define LED_CTRL_OVERRIDE_BLINK_RATE                BIT_31
+
+    /* MAC addresses. */
+    struct {
+        T3_32BIT_REGISTER High;             /* Upper 2 bytes. */
+        T3_32BIT_REGISTER Low;              /* Lower 4 bytes. */
+    } MacAddr[4];
+
+    /* ACPI Mbuf pointer. */
+    T3_32BIT_REGISTER AcpiMbufPtr;
+
+    /* ACPI Length and Offset. */
+    T3_32BIT_REGISTER AcpiLengthOffset;
+    #define ACPI_LENGTH_MASK                            0xffff
+    #define ACPI_OFFSET_MASK                            0x0fff0000
+    #define ACPI_LENGTH(x)                              x
+    #define ACPI_OFFSET(x)                              ((x) << 16)
+
+    /* Transmit random backoff. */
+    T3_32BIT_REGISTER TxBackoffSeed;
+    #define MAC_TX_BACKOFF_SEED_MASK                    0x3ff
+
+    /* Receive MTU */
+    T3_32BIT_REGISTER MtuSize;
+    #define MAC_RX_MTU_MASK                             0xffff
+
+    /* Gigabit PCS Test. */
+    T3_32BIT_REGISTER PcsTest;
+    #define MAC_PCS_TEST_DATA_PATTERN_MASK              0x0fffff
+    #define MAC_PCS_TEST_ENABLE                         BIT_20
+
+    /* Transmit Gigabit Auto-Negotiation. */
+    T3_32BIT_REGISTER TxAutoNeg;
+    #define MAC_AN_TX_AN_DATA_MASK                      0xffff
+
+    /* Receive Gigabit Auto-Negotiation. */
+    T3_32BIT_REGISTER RxAutoNeg;
+    #define MAC_AN_RX_AN_DATA_MASK                      0xffff
+
+    /* MI Communication. */
+    T3_32BIT_REGISTER MiCom;
+    #define MI_COM_CMD_MASK                             (BIT_26 | BIT_27)
+    #define MI_COM_CMD_WRITE                            BIT_26
+    #define MI_COM_CMD_READ                             BIT_27
+    #define MI_COM_READ_FAILED                          BIT_28
+    #define MI_COM_START                                BIT_29
+    #define MI_COM_BUSY                                 BIT_29
+
+    #define MI_COM_PHY_ADDR_MASK                        0x1f
+    #define MI_COM_FIRST_PHY_ADDR_BIT                   21
+
+    #define MI_COM_PHY_REG_ADDR_MASK                    0x1f
+    #define MI_COM_FIRST_PHY_REG_ADDR_BIT               16
+
+    #define MI_COM_PHY_DATA_MASK                        0xffff
+
+    /* MI Status. */
+    T3_32BIT_REGISTER MiStatus;
+    #define MI_STATUS_ENABLE_LINK_STATUS_ATTN           BIT_0
+
+    /* MI Mode. */
+    T3_32BIT_REGISTER MiMode;
+    #define MI_MODE_CLOCK_SPEED_10MHZ                   BIT_0
+    #define MI_MODE_USE_SHORT_PREAMBLE                  BIT_1
+    #define MI_MODE_AUTO_POLLING_ENABLE                 BIT_4
+    #define MI_MODE_CORE_CLOCK_SPEED_62MHZ              BIT_15
+
+    /* Auto-polling status. */
+    T3_32BIT_REGISTER AutoPollStatus;
+    #define AUTO_POLL_ERROR                             BIT_0
+
+    /* Transmit MAC mode. */
+    T3_32BIT_REGISTER TxMode;
+    #define TX_MODE_RESET                               BIT_0
+    #define TX_MODE_ENABLE                              BIT_1
+    #define TX_MODE_ENABLE_FLOW_CONTROL                 BIT_4
+    #define TX_MODE_ENABLE_BIG_BACKOFF                  BIT_5
+    #define TX_MODE_ENABLE_LONG_PAUSE                   BIT_6
+
+    /* Transmit MAC status. */
+    T3_32BIT_REGISTER TxStatus;
+    #define TX_STATUS_RX_CURRENTLY_XOFFED               BIT_0
+    #define TX_STATUS_SENT_XOFF                         BIT_1
+    #define TX_STATUS_SENT_XON                          BIT_2
+    #define TX_STATUS_LINK_UP                           BIT_3
+    #define TX_STATUS_ODI_UNDERRUN                      BIT_4
+    #define TX_STATUS_ODI_OVERRUN                       BIT_5
+
+    /* Transmit MAC length. */
+    T3_32BIT_REGISTER TxLengths;
+    #define TX_LEN_SLOT_TIME_MASK                       0xff
+    #define TX_LEN_IPG_MASK                             0x0f00
+    #define TX_LEN_IPG_CRS_MASK                         (BIT_12 | BIT_13)
+
+    /* Receive MAC mode. */
+    T3_32BIT_REGISTER RxMode;
+    #define RX_MODE_RESET                               BIT_0
+    #define RX_MODE_ENABLE                              BIT_1
+    #define RX_MODE_ENABLE_FLOW_CONTROL                 BIT_2
+    #define RX_MODE_KEEP_MAC_CONTROL                    BIT_3
+    #define RX_MODE_KEEP_PAUSE                          BIT_4
+    #define RX_MODE_ACCEPT_OVERSIZED                    BIT_5
+    #define RX_MODE_ACCEPT_RUNTS                        BIT_6
+    #define RX_MODE_LENGTH_CHECK                        BIT_7
+    #define RX_MODE_PROMISCUOUS_MODE                    BIT_8
+    #define RX_MODE_NO_CRC_CHECK                        BIT_9
+    #define RX_MODE_KEEP_VLAN_TAG                       BIT_10
+
+    /* Receive MAC status. */
+    T3_32BIT_REGISTER RxStatus;
+    #define RX_STATUS_REMOTE_TRANSMITTER_XOFFED         BIT_0
+    #define RX_STATUS_XOFF_RECEIVED                     BIT_1
+    #define RX_STATUS_XON_RECEIVED                      BIT_2
+
+    /* Hash registers. */
+    T3_32BIT_REGISTER HashReg[4];
+
+    /* Receive placement rules registers. */
+    struct {
+        T3_32BIT_REGISTER Rule;
+        T3_32BIT_REGISTER Value;
+    } RcvRules[16];
+
+    #define RCV_DISABLE_RULE_MASK                       0x7fffffff
+
+    #define RCV_RULE1_REJECT_BROADCAST_IDX              0x00
+    #define REJECT_BROADCAST_RULE1_RULE                 0xc2000000
+    #define REJECT_BROADCAST_RULE1_VALUE                0xffffffff
+
+    #define RCV_RULE2_REJECT_BROADCAST_IDX              0x01
+    #define REJECT_BROADCAST_RULE2_RULE                 0x86000004
+    #define REJECT_BROADCAST_RULE2_VALUE                0xffffffff
+
+#if INCLUDE_5701_AX_FIX
+    #define RCV_LAST_RULE_IDX                           0x04
+#else
+    #define RCV_LAST_RULE_IDX                           0x02
+#endif
+
+    T3_32BIT_REGISTER RcvRuleCfg;
+    #define RX_RULE_DEFAULT_CLASS                       (1 << 3)
+
+    LM_UINT8 Reserved1[140];
+
+    T3_32BIT_REGISTER SerdesCfg;
+    T3_32BIT_REGISTER SerdesStatus;
+
+    LM_UINT8 Reserved2[104];
+
+    volatile LM_UINT8 TxMacState[16];
+    volatile LM_UINT8 RxMacState[20];
+
+    LM_UINT8 Reserved3[476];
+
+    T3_32BIT_REGISTER RxStats[26];
+
+    LM_UINT8 Reserved4[24];
+
+    T3_32BIT_REGISTER TxStats[28];
+
+    LM_UINT8 Reserved5[784];
+} T3_MAC_CONTROL, *PT3_MAC_CONTROL;
+
+
+
+/******************************************************************************/
+/* Send data initiator control registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define T3_SND_DATA_IN_MODE_RESET                       BIT_0
+    #define T3_SND_DATA_IN_MODE_ENABLE                      BIT_1
+    #define T3_SND_DATA_IN_MODE_STATS_OFLW_ATTN_ENABLE      BIT_2
+
+    T3_32BIT_REGISTER Status;
+    #define T3_SND_DATA_IN_STATUS_STATS_OFLW_ATTN           BIT_2
+
+    T3_32BIT_REGISTER StatsCtrl;
+    #define T3_SND_DATA_IN_STATS_CTRL_ENABLE                BIT_0
+    #define T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE         BIT_1
+    #define T3_SND_DATA_IN_STATS_CTRL_CLEAR                 BIT_2
+    #define T3_SND_DATA_IN_STATS_CTRL_FLUSH                 BIT_3
+    #define T3_SND_DATA_IN_STATS_CTRL_FORCE_ZERO            BIT_4
+
+    T3_32BIT_REGISTER StatsEnableMask;
+    T3_32BIT_REGISTER StatsIncMask;
+
+    LM_UINT8 Reserved[108];
+
+    T3_32BIT_REGISTER ClassOfServCnt[16];
+    T3_32BIT_REGISTER DmaReadQFullCnt;
+    T3_32BIT_REGISTER DmaPriorityReadQFullCnt;
+    T3_32BIT_REGISTER SdcQFullCnt;
+
+    T3_32BIT_REGISTER NicRingSetSendProdIdxCnt;
+    T3_32BIT_REGISTER StatusUpdatedCnt;
+    T3_32BIT_REGISTER InterruptsCnt;
+    T3_32BIT_REGISTER AvoidInterruptsCnt;
+    T3_32BIT_REGISTER SendThresholdHitCnt;
+
+    /* Unused space. */
+    LM_UINT8 Unused[800];
+} T3_SEND_DATA_INITIATOR, *PT3_SEND_DATA_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Send data completion control registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define SND_DATA_COMP_MODE_RESET                        BIT_0
+    #define SND_DATA_COMP_MODE_ENABLE                       BIT_1
+
+    /* Unused space. */
+    LM_UINT8 Unused[1020];
+} T3_SEND_DATA_COMPLETION, *PT3_SEND_DATA_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Send BD Ring Selector Control Registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define SND_BD_SEL_MODE_RESET                           BIT_0
+    #define SND_BD_SEL_MODE_ENABLE                          BIT_1
+    #define SND_BD_SEL_MODE_ATTN_ENABLE                     BIT_2
+
+    T3_32BIT_REGISTER Status;
+    #define SND_BD_SEL_STATUS_ERROR_ATTN                    BIT_2
+
+    T3_32BIT_REGISTER HwDiag;
+
+    /* Unused space. */
+    LM_UINT8 Unused1[52];
+
+    /* Send BD Ring Selector Local NIC Send BD Consumer Index. */
+    T3_32BIT_REGISTER NicSendBdSelConIdx[16];
+
+    /* Unused space. */
+    LM_UINT8 Unused2[896];
+} T3_SEND_BD_SELECTOR, *PT3_SEND_BD_SELECTOR;
+
+
+
+/******************************************************************************/
+/* Send BD initiator control registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define SND_BD_IN_MODE_RESET                            BIT_0
+    #define SND_BD_IN_MODE_ENABLE                           BIT_1
+    #define SND_BD_IN_MODE_ATTN_ENABLE                      BIT_2
+
+    T3_32BIT_REGISTER Status;
+    #define SND_BD_IN_STATUS_ERROR_ATTN                     BIT_2
+
+    /* Send BD initiator local NIC send BD producer index. */
+    T3_32BIT_REGISTER NicSendBdInProdIdx[16];
+
+    /* Unused space. */
+    LM_UINT8 Unused2[952];
+} T3_SEND_BD_INITIATOR, *PT3_SEND_BD_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Send BD Completion Control. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define SND_BD_COMP_MODE_RESET                          BIT_0
+    #define SND_BD_COMP_MODE_ENABLE                         BIT_1
+    #define SND_BD_COMP_MODE_ATTN_ENABLE                    BIT_2
+
+    /* Unused space. */
+    LM_UINT8 Unused2[1020];
+} T3_SEND_BD_COMPLETION, *PT3_SEND_BD_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Receive list placement control registers. */
+/******************************************************************************/
+
+typedef struct {
+    /* Mode. */
+    T3_32BIT_REGISTER Mode;
+    #define RCV_LIST_PLMT_MODE_RESET                        BIT_0
+    #define RCV_LIST_PLMT_MODE_ENABLE                       BIT_1
+    #define RCV_LIST_PLMT_MODE_CLASS0_ATTN_ENABLE           BIT_2
+    #define RCV_LIST_PLMT_MODE_MAPPING_OOR_ATTN_ENABLE      BIT_3
+    #define RCV_LIST_PLMT_MODE_STATS_OFLOW_ATTN_ENABLE      BIT_4
+
+    /* Status. */
+    T3_32BIT_REGISTER Status;
+    #define RCV_LIST_PLMT_STATUS_CLASS0_ATTN                BIT_2
+    #define RCV_LIST_PLMT_STATUS_MAPPING_ATTN               BIT_3
+    #define RCV_LIST_PLMT_STATUS_STATS_OFLOW_ATTN           BIT_4
+
+    /* Receive selector list lock register. */
+    T3_32BIT_REGISTER Lock;
+    #define RCV_LIST_SEL_LOCK_REQUEST_MASK                  0xffff
+    #define RCV_LIST_SEL_LOCK_GRANT_MASK                    0xffff0000
+
+    /* Selector non-empty bits. */
+    T3_32BIT_REGISTER NonEmptyBits;
+    #define RCV_LIST_SEL_NON_EMPTY_MASK                     0xffff
+
+    /* Receive list placement configuration register. */
+    T3_32BIT_REGISTER Config;
+
+    /* Receive List Placement statistics Control. */
+    T3_32BIT_REGISTER StatsCtrl;
+#define RCV_LIST_STATS_ENABLE                               BIT_0
+#define RCV_LIST_STATS_FAST_UPDATE                          BIT_1
+
+    /* Receive List Placement statistics Enable Mask. */
+    T3_32BIT_REGISTER StatsEnableMask;
+
+    /* Receive List Placement statistics Increment Mask. */
+    T3_32BIT_REGISTER StatsIncMask;
+
+    /* Unused space. */
+    LM_UINT8 Unused1[224];
+
+    struct {
+        T3_32BIT_REGISTER Head;
+        T3_32BIT_REGISTER Tail;
+        T3_32BIT_REGISTER Count;
+
+        /* Unused space. */
+        LM_UINT8 Unused[4];
+    } RcvSelectorList[16];
+
+    /* Local statistics counter. */
+    T3_32BIT_REGISTER ClassOfServCnt[16];
+
+    T3_32BIT_REGISTER DropDueToFilterCnt;
+    T3_32BIT_REGISTER DmaWriteQFullCnt;
+    T3_32BIT_REGISTER DmaHighPriorityWriteQFullCnt;
+    T3_32BIT_REGISTER NoMoreReceiveBdCnt;
+    T3_32BIT_REGISTER IfInDiscardsCnt;
+    T3_32BIT_REGISTER IfInErrorsCnt;
+    T3_32BIT_REGISTER RcvThresholdHitCnt;
+
+    /* Another unused space. */
+    LM_UINT8 Unused2[420];
+} T3_RCV_LIST_PLACEMENT, *PT3_RCV_LIST_PLACEMENT;
+
+
+
+/******************************************************************************/
+/* Receive Data and Receive BD Initiator Control. */
+/******************************************************************************/
+
+typedef struct {
+    /* Mode. */
+    T3_32BIT_REGISTER Mode;
+    #define RCV_DATA_BD_IN_MODE_RESET                   BIT_0
+    #define RCV_DATA_BD_IN_MODE_ENABLE                  BIT_1
+    #define RCV_DATA_BD_IN_MODE_JUMBO_BD_NEEDED         BIT_2
+    #define RCV_DATA_BD_IN_MODE_FRAME_TOO_BIG           BIT_3
+    #define RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE       BIT_4
+
+    /* Status. */
+    T3_32BIT_REGISTER Status;
+    #define RCV_DATA_BD_IN_STATUS_JUMBO_BD_NEEDED       BIT_2
+    #define RCV_DATA_BD_IN_STATUS_FRAME_TOO_BIG         BIT_3
+    #define RCV_DATA_BD_IN_STATUS_INVALID_RING_SIZE     BIT_4
+
+    /* Split frame minium size. */
+    T3_32BIT_REGISTER SplitFrameMinSize;
+
+    /* Unused space. */
+    LM_UINT8 Unused1[0x2440-0x240c];
+
+    /* Receive RCBs. */
+    T3_RCB JumboRcvRcb;
+    T3_RCB StdRcvRcb;
+    T3_RCB MiniRcvRcb;
+
+    /* Receive Data and Receive BD Ring Initiator Local NIC Receive */
+    /* BD Consumber Index. */
+    T3_32BIT_REGISTER NicJumboConIdx;
+    T3_32BIT_REGISTER NicStdConIdx;
+    T3_32BIT_REGISTER NicMiniConIdx;
+
+    /* Unused space. */
+    LM_UINT8 Unused2[4];
+
+    /* Receive Data and Receive BD Initiator Local Receive Return ProdIdx. */
+    T3_32BIT_REGISTER RcvDataBdProdIdx[16];
+
+    /* Receive Data and Receive BD Initiator Hardware Diagnostic. */
+    T3_32BIT_REGISTER HwDiag;
+
+    /* Unused space. */
+    LM_UINT8 Unused3[828];
+} T3_RCV_DATA_BD_INITIATOR, *PT3_RCV_DATA_BD_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Receive Data Completion Control Registes. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define RCV_DATA_COMP_MODE_RESET                        BIT_0
+    #define RCV_DATA_COMP_MODE_ENABLE                       BIT_1
+    #define RCV_DATA_COMP_MODE_ATTN_ENABLE                  BIT_2
+
+    /* Unused spaced. */
+    LM_UINT8 Unused[1020];
+} T3_RCV_DATA_COMPLETION, *PT3_RCV_DATA_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Receive BD Initiator Control. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define RCV_BD_IN_MODE_RESET                            BIT_0
+    #define RCV_BD_IN_MODE_ENABLE                           BIT_1
+    #define RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE    BIT_2
+
+    T3_32BIT_REGISTER Status;
+    #define RCV_BD_IN_STATUS_BD_IN_DIABLED_RCB_ATTN         BIT_2
+
+    T3_32BIT_REGISTER NicJumboRcvProdIdx;
+    T3_32BIT_REGISTER NicStdRcvProdIdx;
+    T3_32BIT_REGISTER NicMiniRcvProdIdx;
+
+    T3_32BIT_REGISTER MiniRcvThreshold;
+    T3_32BIT_REGISTER StdRcvThreshold;
+    T3_32BIT_REGISTER JumboRcvThreshold;
+
+    /* Unused space. */
+    LM_UINT8 Unused[992];
+} T3_RCV_BD_INITIATOR, *PT3_RCV_BD_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Receive BD Completion Control Registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define RCV_BD_COMP_MODE_RESET                          BIT_0
+    #define RCV_BD_COMP_MODE_ENABLE                         BIT_1
+    #define RCV_BD_COMP_MODE_ATTN_ENABLE                    BIT_2
+
+    T3_32BIT_REGISTER Status;
+    #define RCV_BD_COMP_STATUS_ERROR_ATTN                   BIT_2
+
+    T3_32BIT_REGISTER  NicJumboRcvBdProdIdx;
+    T3_32BIT_REGISTER  NicStdRcvBdProdIdx;
+    T3_32BIT_REGISTER  NicMiniRcvBdProdIdx;
+
+    /* Unused space. */
+    LM_UINT8 Unused[1004];
+} T3_RCV_BD_COMPLETION, *PT3_RCV_BD_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Receive list selector control register. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define RCV_LIST_SEL_MODE_RESET                         BIT_0
+    #define RCV_LIST_SEL_MODE_ENABLE                        BIT_1
+    #define RCV_LIST_SEL_MODE_ATTN_ENABLE                   BIT_2
+
+    T3_32BIT_REGISTER Status;
+    #define RCV_LIST_SEL_STATUS_ERROR_ATTN                  BIT_2
+
+    /* Unused space. */
+    LM_UINT8 Unused[1016];
+} T3_RCV_LIST_SELECTOR, *PT3_RCV_LIST_SELECTOR;
+
+
+
+/******************************************************************************/
+/* Mbuf cluster free registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+#define MBUF_CLUSTER_FREE_MODE_RESET    BIT_0
+#define MBUF_CLUSTER_FREE_MODE_ENABLE   BIT_1
+
+    T3_32BIT_REGISTER Status;
+
+    /* Unused space. */
+    LM_UINT8 Unused[1016];
+} T3_MBUF_CLUSTER_FREE, *PT3_MBUF_CLUSTER_FREE;
+
+
+
+/******************************************************************************/
+/* Host coalescing control registers. */
+/******************************************************************************/
+
+typedef struct {
+    /* Mode. */
+    T3_32BIT_REGISTER Mode;
+    #define HOST_COALESCE_RESET                         BIT_0
+    #define HOST_COALESCE_ENABLE                        BIT_1
+    #define HOST_COALESCE_ATTN                          BIT_2
+    #define HOST_COALESCE_NOW                           BIT_3
+    #define HOST_COALESCE_FULL_STATUS_MODE              BIT_NONE
+    #define HOST_COALESCE_64_BYTE_STATUS_MODE           BIT_7
+    #define HOST_COALESCE_32_BYTE_STATUS_MODE           BIT_8
+    #define HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT    BIT_9
+    #define HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT    BIT_10
+    #define HOST_COALESCE_NO_INT_ON_COALESCE_NOW_MODE   BIT_11
+    #define HOST_COALESCE_NO_INT_ON_FORCE_DMAD_MODE     BIT_12
+
+    /* Status. */
+    T3_32BIT_REGISTER Status;
+    #define HOST_COALESCE_ERROR_ATTN                    BIT_2
+
+    /* Receive coalescing ticks. */
+    T3_32BIT_REGISTER RxCoalescingTicks;
+
+    /* Send coalescing ticks. */
+    T3_32BIT_REGISTER TxCoalescingTicks;
+
+    /* Receive max coalesced frames. */
+    T3_32BIT_REGISTER RxMaxCoalescedFrames;
+
+    /* Send max coalesced frames. */
+    T3_32BIT_REGISTER TxMaxCoalescedFrames;
+
+    /* Receive coalescing ticks during interrupt. */
+    T3_32BIT_REGISTER RxCoalescedTickDuringInt;
+
+    /* Send coalescing ticks during interrupt. */
+    T3_32BIT_REGISTER TxCoalescedTickDuringInt;
+
+    /* Receive max coalesced frames during interrupt. */
+    T3_32BIT_REGISTER RxMaxCoalescedFramesDuringInt;
+
+    /* Send max coalesced frames during interrupt. */
+    T3_32BIT_REGISTER TxMaxCoalescedFramesDuringInt;
+
+    /* Statistics tick. */
+    T3_32BIT_REGISTER StatsCoalescingTicks;
+
+    /* Unused space. */
+    LM_UINT8 Unused2[4];
+
+    /* Statistics host address. */
+    T3_64BIT_REGISTER StatsBlkHostAddr;
+
+    /* Status block host address.*/
+    T3_64BIT_REGISTER StatusBlkHostAddr;
+
+    /* Statistics NIC address. */
+    T3_32BIT_REGISTER StatsBlkNicAddr;
+
+    /* Statust block NIC address. */
+    T3_32BIT_REGISTER StatusBlkNicAddr;
+
+    /* Flow attention registers. */
+    T3_32BIT_REGISTER FlowAttn;
+
+    /* Unused space. */
+    LM_UINT8 Unused3[4];
+
+    T3_32BIT_REGISTER NicJumboRcvBdConIdx;
+    T3_32BIT_REGISTER NicStdRcvBdConIdx;
+    T3_32BIT_REGISTER NicMiniRcvBdConIdx;
+
+    /* Unused space. */
+    LM_UINT8 Unused4[36];
+
+    T3_32BIT_REGISTER NicRetProdIdx[16];
+    T3_32BIT_REGISTER NicSndBdConIdx[16];
+
+    /* Unused space. */
+    LM_UINT8 Unused5[768];
+} T3_HOST_COALESCING, *PT3_HOST_COALESCING;
+
+
+
+/******************************************************************************/
+/* Memory arbiter registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+#define T3_MEM_ARBITER_MODE_RESET       BIT_0
+#define T3_MEM_ARBITER_MODE_ENABLE      BIT_1
+
+    T3_32BIT_REGISTER Status;
+
+    T3_32BIT_REGISTER ArbTrapAddrLow;
+    T3_32BIT_REGISTER ArbTrapAddrHigh;
+
+    /* Unused space. */
+    LM_UINT8 Unused[1008];
+} T3_MEM_ARBITER, *PT3_MEM_ARBITER;
+
+
+
+/******************************************************************************/
+/* Buffer manager control register. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define BUFMGR_MODE_RESET                           BIT_0
+    #define BUFMGR_MODE_ENABLE                          BIT_1
+    #define BUFMGR_MODE_ATTN_ENABLE                     BIT_2
+    #define BUFMGR_MODE_BM_TEST                         BIT_3
+    #define BUFMGR_MODE_MBUF_LOW_ATTN_ENABLE            BIT_4
+
+    T3_32BIT_REGISTER Status;
+    #define BUFMGR_STATUS_ERROR                         BIT_2
+    #define BUFMGR_STATUS_MBUF_LOW                      BIT_4
+
+    T3_32BIT_REGISTER MbufPoolAddr;
+    T3_32BIT_REGISTER MbufPoolSize;
+    T3_32BIT_REGISTER MbufReadDmaLowWaterMark;
+    T3_32BIT_REGISTER MbufMacRxLowWaterMark;
+    T3_32BIT_REGISTER MbufHighWaterMark;
+
+    T3_32BIT_REGISTER RxCpuMbufAllocReq;
+    #define BUFMGR_MBUF_ALLOC_BIT                     BIT_31
+    T3_32BIT_REGISTER RxCpuMbufAllocResp;
+    T3_32BIT_REGISTER TxCpuMbufAllocReq;
+    T3_32BIT_REGISTER TxCpuMbufAllocResp;
+
+    T3_32BIT_REGISTER DmaDescPoolAddr;
+    T3_32BIT_REGISTER DmaDescPoolSize;
+    T3_32BIT_REGISTER DmaLowWaterMark;
+    T3_32BIT_REGISTER DmaHighWaterMark;
+
+    T3_32BIT_REGISTER RxCpuDmaAllocReq;
+    T3_32BIT_REGISTER RxCpuDmaAllocResp;
+    T3_32BIT_REGISTER TxCpuDmaAllocReq;
+    T3_32BIT_REGISTER TxCpuDmaAllocResp;
+
+    T3_32BIT_REGISTER Hwdiag[3];
+
+    /* Unused space. */
+    LM_UINT8 Unused[936];
+} T3_BUFFER_MANAGER, *PT3_BUFFER_MANAGER;
+
+
+
+/******************************************************************************/
+/* Read DMA control registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define DMA_READ_MODE_RESET                         BIT_0
+    #define DMA_READ_MODE_ENABLE                        BIT_1
+    #define DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE      BIT_2
+    #define DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE      BIT_3
+    #define DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE      BIT_4
+    #define DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE     BIT_5
+    #define DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE      BIT_6
+    #define DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE     BIT_7
+    #define DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE     BIT_8
+    #define DMA_READ_MODE_LONG_READ_ATTN_ENABLE         BIT_9
+    #define DMA_READ_MODE_SPLIT_ENABLE                  BIT_11
+    #define DMA_READ_MODE_SPLIT_RESET                   BIT_12
+
+    T3_32BIT_REGISTER Status;
+    #define DMA_READ_STATUS_TARGET_ABORT_ATTN           BIT_2
+    #define DMA_READ_STATUS_MASTER_ABORT_ATTN           BIT_3
+    #define DMA_READ_STATUS_PARITY_ERROR_ATTN           BIT_4
+    #define DMA_READ_STATUS_ADDR_OVERFLOW_ATTN          BIT_5
+    #define DMA_READ_STATUS_FIFO_OVERRUN_ATTN           BIT_6
+    #define DMA_READ_STATUS_FIFO_UNDERRUN_ATTN          BIT_7
+    #define DMA_READ_STATUS_FIFO_OVERREAD_ATTN          BIT_8
+    #define DMA_READ_STATUS_LONG_READ_ATTN              BIT_9
+
+    /* Unused space. */
+    LM_UINT8 Unused[1016];
+} T3_DMA_READ, *PT3_DMA_READ;
+
+typedef union T3_CPU
+{
+  struct
+  {
+    T3_32BIT_REGISTER mode;
+    #define CPU_MODE_HALT   BIT_10
+    #define CPU_MODE_RESET  BIT_0
+    T3_32BIT_REGISTER state;
+    T3_32BIT_REGISTER EventMask;
+    T3_32BIT_REGISTER reserved1[4];
+    T3_32BIT_REGISTER PC;
+    T3_32BIT_REGISTER Instruction;
+    T3_32BIT_REGISTER SpadUnderflow;
+    T3_32BIT_REGISTER WatchdogClear;
+    T3_32BIT_REGISTER WatchdogVector;
+    T3_32BIT_REGISTER WatchdogSavedPC;
+    T3_32BIT_REGISTER HardwareBp;
+    T3_32BIT_REGISTER reserved2[3];
+    T3_32BIT_REGISTER WatchdogSavedState;
+    T3_32BIT_REGISTER LastBrchAddr;
+    T3_32BIT_REGISTER SpadUnderflowSet;
+    T3_32BIT_REGISTER reserved3[(0x200-0x50)/4];
+    T3_32BIT_REGISTER Regs[32];
+    T3_32BIT_REGISTER reserved4[(0x400-0x280)/4];
+  }reg;
+}T3_CPU, *PT3_CPU;
+
+/******************************************************************************/
+/* Write DMA control registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define DMA_WRITE_MODE_RESET                        BIT_0
+    #define DMA_WRITE_MODE_ENABLE                       BIT_1
+    #define DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE     BIT_2
+    #define DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE     BIT_3
+    #define DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE     BIT_4
+    #define DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE    BIT_5
+    #define DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE     BIT_6
+    #define DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE    BIT_7
+    #define DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE    BIT_8
+    #define DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE        BIT_9
+
+    T3_32BIT_REGISTER Status;
+    #define DMA_WRITE_STATUS_TARGET_ABORT_ATTN          BIT_2
+    #define DMA_WRITE_STATUS_MASTER_ABORT_ATTN          BIT_3
+    #define DMA_WRITE_STATUS_PARITY_ERROR_ATTN          BIT_4
+    #define DMA_WRITE_STATUS_ADDR_OVERFLOW_ATTN         BIT_5
+    #define DMA_WRITE_STATUS_FIFO_OVERRUN_ATTN          BIT_6
+    #define DMA_WRITE_STATUS_FIFO_UNDERRUN_ATTN         BIT_7
+    #define DMA_WRITE_STATUS_FIFO_OVERREAD_ATTN         BIT_8
+    #define DMA_WRITE_STATUS_LONG_READ_ATTN             BIT_9
+
+    /* Unused space. */
+    LM_UINT8 Unused[1016];
+} T3_DMA_WRITE, *PT3_DMA_WRITE;
+
+
+
+/******************************************************************************/
+/* Mailbox registers. */
+/******************************************************************************/
+
+typedef struct {
+    /* Interrupt mailbox registers. */
+    T3_64BIT_REGISTER Interrupt[4];
+
+    /* General mailbox registers. */
+    T3_64BIT_REGISTER General[8];
+
+    /* Reload statistics mailbox. */
+    T3_64BIT_REGISTER ReloadStat;
+
+    /* Receive BD ring producer index registers. */
+    T3_64BIT_REGISTER RcvStdProdIdx;
+    T3_64BIT_REGISTER RcvJumboProdIdx;
+    T3_64BIT_REGISTER RcvMiniProdIdx;
+
+    /* Receive return ring consumer index registers. */
+    T3_64BIT_REGISTER RcvRetConIdx[16];
+
+    /* Send BD ring host producer index registers. */
+    T3_64BIT_REGISTER SendHostProdIdx[16];
+
+    /* Send BD ring nic producer index registers. */
+    T3_64BIT_REGISTER SendNicProdIdx[16];
+}T3_MAILBOX, *PT3_MAILBOX;
+
+typedef struct {
+    T3_MAILBOX Mailbox;
+
+    /* Priority mailbox registers. */
+    T3_32BIT_REGISTER HighPriorityEventVector;
+    T3_32BIT_REGISTER HighPriorityEventMask;
+    T3_32BIT_REGISTER LowPriorityEventVector;
+    T3_32BIT_REGISTER LowPriorityEventMask;
+
+    /* Unused space. */
+    LM_UINT8 Unused[496];
+} T3_GRC_MAILBOX, *PT3_GRC_MAILBOX;
+
+
+/******************************************************************************/
+/* Flow through queues. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Reset;
+
+    LM_UINT8 Unused[12];
+
+    T3_32BIT_REGISTER DmaNormalReadFtqCtrl;
+    T3_32BIT_REGISTER DmaNormalReadFtqFullCnt;
+    T3_32BIT_REGISTER DmaNormalReadFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER DmaNormalReadFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER DmaHighReadFtqCtrl;
+    T3_32BIT_REGISTER DmaHighReadFtqFullCnt;
+    T3_32BIT_REGISTER DmaHighReadFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER DmaHighReadFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER DmaCompDiscardFtqCtrl;
+    T3_32BIT_REGISTER DmaCompDiscardFtqFullCnt;
+    T3_32BIT_REGISTER DmaCompDiscardFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER DmaCompDiscardFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER SendBdCompFtqCtrl;
+    T3_32BIT_REGISTER SendBdCompFtqFullCnt;
+    T3_32BIT_REGISTER SendBdCompFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER SendBdCompFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER SendDataInitiatorFtqCtrl;
+    T3_32BIT_REGISTER SendDataInitiatorFtqFullCnt;
+    T3_32BIT_REGISTER SendDataInitiatorFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER SendDataInitiatorFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER DmaNormalWriteFtqCtrl;
+    T3_32BIT_REGISTER DmaNormalWriteFtqFullCnt;
+    T3_32BIT_REGISTER DmaNormalWriteFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER DmaNormalWriteFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER DmaHighWriteFtqCtrl;
+    T3_32BIT_REGISTER DmaHighWriteFtqFullCnt;
+    T3_32BIT_REGISTER DmaHighWriteFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER DmaHighWriteFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER SwType1FtqCtrl;
+    T3_32BIT_REGISTER SwType1FtqFullCnt;
+    T3_32BIT_REGISTER SwType1FtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER SwType1FtqFifoWritePeek;
+
+    T3_32BIT_REGISTER SendDataCompFtqCtrl;
+    T3_32BIT_REGISTER SendDataCompFtqFullCnt;
+    T3_32BIT_REGISTER SendDataCompFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER SendDataCompFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER HostCoalesceFtqCtrl;
+    T3_32BIT_REGISTER HostCoalesceFtqFullCnt;
+    T3_32BIT_REGISTER HostCoalesceFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER HostCoalesceFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER MacTxFtqCtrl;
+    T3_32BIT_REGISTER MacTxFtqFullCnt;
+    T3_32BIT_REGISTER MacTxFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER MacTxFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER MbufClustFreeFtqCtrl;
+    T3_32BIT_REGISTER MbufClustFreeFtqFullCnt;
+    T3_32BIT_REGISTER MbufClustFreeFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER MbufClustFreeFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER RcvBdCompFtqCtrl;
+    T3_32BIT_REGISTER RcvBdCompFtqFullCnt;
+    T3_32BIT_REGISTER RcvBdCompFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER RcvBdCompFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER RcvListPlmtFtqCtrl;
+    T3_32BIT_REGISTER RcvListPlmtFtqFullCnt;
+    T3_32BIT_REGISTER RcvListPlmtFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER RcvListPlmtFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER RcvDataBdInitiatorFtqCtrl;
+    T3_32BIT_REGISTER RcvDataBdInitiatorFtqFullCnt;
+    T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER RcvDataCompFtqCtrl;
+    T3_32BIT_REGISTER RcvDataCompFtqFullCnt;
+    T3_32BIT_REGISTER RcvDataCompFtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER RcvDataCompFtqFifoWritePeek;
+
+    T3_32BIT_REGISTER SwType2FtqCtrl;
+    T3_32BIT_REGISTER SwType2FtqFullCnt;
+    T3_32BIT_REGISTER SwType2FtqFifoEnqueueDequeue;
+    T3_32BIT_REGISTER SwType2FtqFifoWritePeek;
+
+    /* Unused space. */
+    LM_UINT8 Unused2[736];
+} T3_FTQ, *PT3_FTQ;
+
+
+
+/******************************************************************************/
+/* Message signaled interrupt registers. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+#define MSI_MODE_RESET       BIT_0
+#define MSI_MODE_ENABLE      BIT_1
+    T3_32BIT_REGISTER Status;
+
+    T3_32BIT_REGISTER MsiFifoAccess;
+
+    /* Unused space. */
+    LM_UINT8 Unused[1012];
+} T3_MSG_SIGNALED_INT, *PT3_MSG_SIGNALED_INT;
+
+
+
+/******************************************************************************/
+/* DMA Completion registes. */
+/******************************************************************************/
+
+typedef struct {
+    T3_32BIT_REGISTER Mode;
+    #define DMA_COMP_MODE_RESET                         BIT_0
+    #define DMA_COMP_MODE_ENABLE                        BIT_1
+
+    /* Unused space. */
+    LM_UINT8 Unused[1020];
+} T3_DMA_COMPLETION, *PT3_DMA_COMPLETION;
+
+
+
+/******************************************************************************/
+/* GRC registers. */
+/******************************************************************************/
+
+typedef struct {
+    /* Mode control register. */
+    T3_32BIT_REGISTER Mode;
+    #define GRC_MODE_UPDATE_ON_COALESCING               BIT_0
+    #define GRC_MODE_BYTE_SWAP_NON_FRAME_DATA           BIT_1
+    #define GRC_MODE_WORD_SWAP_NON_FRAME_DATA           BIT_2
+    #define GRC_MODE_BYTE_SWAP_DATA                     BIT_4
+    #define GRC_MODE_WORD_SWAP_DATA                     BIT_5
+    #define GRC_MODE_SPLIT_HEADER_MODE                  BIT_8
+    #define GRC_MODE_NO_FRAME_CRACKING                  BIT_9
+    #define GRC_MODE_INCLUDE_CRC                        BIT_10
+    #define GRC_MODE_ALLOW_BAD_FRAMES                   BIT_11
+    #define GRC_MODE_NO_INTERRUPT_ON_SENDS              BIT_13
+    #define GRC_MODE_NO_INTERRUPT_ON_RECEIVE            BIT_14
+    #define GRC_MODE_FORCE_32BIT_PCI_BUS_MODE           BIT_15
+    #define GRC_MODE_HOST_STACK_UP                      BIT_16
+    #define GRC_MODE_HOST_SEND_BDS                      BIT_17
+    #define GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM         BIT_20
+    #define GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM         BIT_23
+    #define GRC_MODE_INT_ON_TX_CPU_ATTN                 BIT_24
+    #define GRC_MODE_INT_ON_RX_CPU_ATTN                 BIT_25
+    #define GRC_MODE_INT_ON_MAC_ATTN                    BIT_26
+    #define GRC_MODE_INT_ON_DMA_ATTN                    BIT_27
+    #define GRC_MODE_INT_ON_FLOW_ATTN                   BIT_28
+    #define GRC_MODE_4X_NIC_BASED_SEND_RINGS            BIT_29
+    #define GRC_MODE_MULTICAST_FRAME_ENABLE             BIT_30
+
+    /* Misc configuration register. */
+    T3_32BIT_REGISTER MiscCfg;
+    #define GRC_MISC_CFG_CORE_CLOCK_RESET               BIT_0
+    #define GRC_MISC_PRESCALAR_TIMER_MASK               0xfe
+    #define GRC_MISC_BD_ID_MASK                         0x0001e000
+    #define GRC_MISC_BD_ID_5700                         0x0001e000
+    #define GRC_MISC_BD_ID_5701                         0x00000000
+    #define GRC_MISC_BD_ID_5703                         0x00000000
+    #define GRC_MISC_BD_ID_5703S                        0x00002000
+    #define GRC_MISC_BD_ID_5702FE                       0x00004000
+    #define GRC_MISC_BD_ID_5704                         0x00000000
+    #define GRC_MISC_BD_ID_5704CIOBE                    0x00004000
+
+    /* Miscellaneous local control register. */
+    T3_32BIT_REGISTER LocalCtrl;
+    #define GRC_MISC_LOCAL_CTRL_INT_ACTIVE              BIT_0
+    #define GRC_MISC_LOCAL_CTRL_CLEAR_INT               BIT_1
+    #define GRC_MISC_LOCAL_CTRL_SET_INT                 BIT_2
+    #define GRC_MISC_LOCAL_CTRL_INT_ON_ATTN             BIT_3
+    #define GRC_MISC_LOCAL_CTRL_GPIO_INPUT0             BIT_8
+    #define GRC_MISC_LOCAL_CTRL_GPIO_INPUT1             BIT_9
+    #define GRC_MISC_LOCAL_CTRL_GPIO_INPUT2             BIT_10
+    #define GRC_MISC_LOCAL_CTRL_GPIO_OE0                BIT_11
+    #define GRC_MISC_LOCAL_CTRL_GPIO_OE1                BIT_12
+    #define GRC_MISC_LOCAL_CTRL_GPIO_OE2                BIT_13
+    #define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0            BIT_14
+    #define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1            BIT_15
+    #define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2            BIT_16
+    #define GRC_MISC_LOCAL_CTRL_ENABLE_EXT_MEMORY       BIT_17
+    #define GRC_MISC_LOCAL_CTRL_BANK_SELECT             BIT_21
+    #define GRC_MISC_LOCAL_CTRL_SSRAM_TYPE              BIT_22
+
+    #define GRC_MISC_MEMSIZE_256K     0
+    #define GRC_MISC_MEMSIZE_512K     (1 << 18)
+    #define GRC_MISC_MEMSIZE_1024K    (2 << 18)
+    #define GRC_MISC_MEMSIZE_2048K    (3 << 18)
+    #define GRC_MISC_MEMSIZE_4096K    (4 << 18)
+    #define GRC_MISC_MEMSIZE_8192K    (5 << 18)
+    #define GRC_MISC_MEMSIZE_16M      (6 << 18)
+    #define GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM            BIT_24
+
+
+    T3_32BIT_REGISTER Timer;
+
+    T3_32BIT_REGISTER RxCpuEvent;
+    T3_32BIT_REGISTER RxTimerRef;
+    T3_32BIT_REGISTER RxCpuSemaphore;
+    T3_32BIT_REGISTER RemoteRxCpuAttn;
+
+    T3_32BIT_REGISTER TxCpuEvent;
+    T3_32BIT_REGISTER TxTimerRef;
+    T3_32BIT_REGISTER TxCpuSemaphore;
+    T3_32BIT_REGISTER RemoteTxCpuAttn;
+
+    T3_64BIT_REGISTER MemoryPowerUp;
+
+    T3_32BIT_REGISTER EepromAddr;
+    #define SEEPROM_ADDR_WRITE       0
+    #define SEEPROM_ADDR_READ        (1 << 31)
+    #define SEEPROM_ADDR_RW_MASK     0x80000000
+    #define SEEPROM_ADDR_COMPLETE    (1 << 30)
+    #define SEEPROM_ADDR_FSM_RESET   (1 << 29)
+    #define SEEPROM_ADDR_DEV_ID(x)   (x << 26)
+    #define SEEPROM_ADDR_DEV_ID_MASK 0x1c000000
+    #define SEEPROM_ADDR_START       (1 << 25)
+    #define SEEPROM_ADDR_CLK_PERD(x) (x << 16)
+    #define SEEPROM_ADDR_ADDRESS(x)  (x & 0xfffc)
+    #define SEEPROM_ADDR_ADDRESS_MASK 0x0000ffff
+
+    #define SEEPROM_CLOCK_PERIOD        60
+    #define SEEPROM_CHIP_SIZE           (64 * 1024)
+
+    T3_32BIT_REGISTER EepromData;
+    T3_32BIT_REGISTER EepromCtrl;
+
+    T3_32BIT_REGISTER MdiCtrl;
+    T3_32BIT_REGISTER SepromDelay;
+
+    /* Unused space. */
+    LM_UINT8 Unused[948];
+} T3_GRC, *PT3_GRC;
+
+
+/******************************************************************************/
+/* NVRAM control registers. */
+/******************************************************************************/
+
+typedef struct
+{
+    T3_32BIT_REGISTER Cmd;
+    #define NVRAM_CMD_RESET                             BIT_0
+    #define NVRAM_CMD_DONE                              BIT_3
+    #define NVRAM_CMD_DO_IT                             BIT_4
+    #define NVRAM_CMD_WR                                BIT_5
+    #define NVRAM_CMD_RD                                BIT_NONE
+    #define NVRAM_CMD_ERASE                             BIT_6
+    #define NVRAM_CMD_FIRST                             BIT_7
+    #define NVRAM_CMD_LAST                              BIT_8
+
+    T3_32BIT_REGISTER Status;
+    T3_32BIT_REGISTER WriteData;
+
+    T3_32BIT_REGISTER Addr;
+    #define NVRAM_ADDRESS_MASK                          0xffffff
+
+    T3_32BIT_REGISTER ReadData;
+
+    /* Flash config 1 register. */
+    T3_32BIT_REGISTER Config1;
+    #define FLASH_INTERFACE_ENABLE                      BIT_0
+    #define FLASH_SSRAM_BUFFERRED_MODE                  BIT_1
+    #define FLASH_PASS_THRU_MODE                        BIT_2
+    #define FLASH_BIT_BANG_MODE                         BIT_3
+    #define FLASH_COMPAT_BYPASS                         BIT_31
+
+    /* Buffered flash (Atmel: AT45DB011B) specific information */
+    #define BUFFERED_FLASH_PAGE_POS         9
+    #define BUFFERED_FLASH_BYTE_ADDR_MASK   ((1<<BUFFERED_FLASH_PAGE_POS) - 1)
+    #define BUFFERED_FLASH_PAGE_SIZE        264
+    #define BUFFERED_FLASH_PHY_PAGE_SIZE    512
+
+    T3_32BIT_REGISTER Config2;
+    T3_32BIT_REGISTER Config3;
+    T3_32BIT_REGISTER SwArb;
+    #define SW_ARB_REQ_SET0                             BIT_0
+    #define SW_ARB_REQ_SET1                             BIT_1
+    #define SW_ARB_REQ_SET2                             BIT_2
+    #define SW_ARB_REQ_SET3                             BIT_3
+    #define SW_ARB_REQ_CLR0                             BIT_4
+    #define SW_ARB_REQ_CLR1                             BIT_5
+    #define SW_ARB_REQ_CLR2                             BIT_6
+    #define SW_ARB_REQ_CLR3                             BIT_7
+    #define SW_ARB_GNT0                                 BIT_8
+    #define SW_ARB_GNT1                                 BIT_9
+    #define SW_ARB_GNT2                                 BIT_10
+    #define SW_ARB_GNT3                                 BIT_11
+    #define SW_ARB_REQ0                                 BIT_12
+    #define SW_ARB_REQ1                                 BIT_13
+    #define SW_ARB_REQ2                                 BIT_14
+    #define SW_ARB_REQ3                                 BIT_15
+
+    /* Unused space. */
+    LM_UINT8 Unused[988];
+} T3_NVRAM, *PT3_NVRAM;
+
+
+/******************************************************************************/
+/* NIC's internal memory. */
+/******************************************************************************/
+
+typedef struct {
+    /* Page zero for the internal CPUs. */
+    LM_UINT8 PageZero[0x100];               /* 0x0000 */
+
+    /* Send RCBs. */
+    T3_RCB SendRcb[16];                     /* 0x0100 */
+
+    /* Receive Return RCBs. */
+    T3_RCB RcvRetRcb[16];                   /* 0x0200 */
+
+    /* Statistics block. */
+    T3_STATS_BLOCK StatsBlk;                /* 0x0300 */
+
+    /* Status block. */
+    T3_STATUS_BLOCK StatusBlk;              /* 0x0b00 */
+
+    /* Reserved for software. */
+    LM_UINT8 Reserved[1200];                /* 0x0b50 */
+
+    /* Unmapped region. */
+    LM_UINT8 Unmapped[4096];                /* 0x1000 */
+
+    /* DMA descriptors. */
+    LM_UINT8 DmaDesc[8192];                 /* 0x2000 */
+
+    /* Buffer descriptors. */
+    LM_UINT8 BufferDesc[16384];             /* 0x4000 */
+} T3_FIRST_32K_SRAM, *PT3_FIRST_32K_SRAM;
+
+
+
+/******************************************************************************/
+/* Memory layout. */
+/******************************************************************************/
+
+typedef struct {
+    /* PCI configuration registers. */
+    T3_PCI_CONFIGURATION PciCfg;
+
+    /* Unused. */
+    LM_UINT8 Unused1[0x100];                            /* 0x0100 */
+
+    /* Mailbox . */
+    T3_MAILBOX Mailbox;                                 /* 0x0200 */
+
+    /* MAC control registers. */
+    T3_MAC_CONTROL MacCtrl;                             /* 0x0400 */
+
+    /* Send data initiator control registers. */
+    T3_SEND_DATA_INITIATOR SndDataIn;                   /* 0x0c00 */
+
+    /* Send data completion Control registers. */
+    T3_SEND_DATA_COMPLETION SndDataComp;                /* 0x1000 */
+
+    /* Send BD ring selector. */
+    T3_SEND_BD_SELECTOR SndBdSel;                       /* 0x1400 */
+
+    /* Send BD initiator control registers. */
+    T3_SEND_BD_INITIATOR SndBdIn;                       /* 0x1800 */
+
+    /* Send BD completion control registers. */
+    T3_SEND_BD_COMPLETION SndBdComp;                    /* 0x1c00 */
+
+    /* Receive list placement control registers. */
+    T3_RCV_LIST_PLACEMENT RcvListPlmt;                  /* 0x2000 */
+
+    /* Receive Data and Receive BD Initiator Control. */
+    T3_RCV_DATA_BD_INITIATOR RcvDataBdIn;               /* 0x2400 */
+
+    /* Receive Data Completion Control */
+    T3_RCV_DATA_COMPLETION RcvDataComp;                 /* 0x2800 */
+
+    /* Receive BD Initiator Control Registers. */
+    T3_RCV_BD_INITIATOR RcvBdIn;                        /* 0x2c00 */
+
+    /* Receive BD Completion Control Registers. */
+    T3_RCV_BD_COMPLETION RcvBdComp;                     /* 0x3000 */
+
+    /* Receive list selector control registers. */
+    T3_RCV_LIST_SELECTOR RcvListSel;                    /* 0x3400 */
+
+    /* Mbuf cluster free registers. */
+    T3_MBUF_CLUSTER_FREE MbufClusterFree;               /* 0x3800 */
+
+    /* Host coalescing control registers. */
+    T3_HOST_COALESCING HostCoalesce;                    /* 0x3c00 */
+
+    /* Memory arbiter control registers. */
+    T3_MEM_ARBITER MemArbiter;                          /* 0x4000 */
+
+    /* Buffer manger control registers. */
+    T3_BUFFER_MANAGER BufMgr;                           /* 0x4400 */
+
+    /* Read DMA control registers. */
+    T3_DMA_READ DmaRead;                                /* 0x4800 */
+
+    /* Write DMA control registers. */
+    T3_DMA_WRITE DmaWrite;                              /* 0x4c00 */
+
+    T3_CPU rxCpu;                                       /* 0x5000 */
+    T3_CPU txCpu;                                       /* 0x5400 */
+
+    /* Mailboxes. */
+    T3_GRC_MAILBOX GrcMailbox;                          /* 0x5800 */
+
+    /* Flow Through queues. */
+    T3_FTQ Ftq;                                         /* 0x5c00 */
+
+    /* Message signaled interrupt registes. */
+    T3_MSG_SIGNALED_INT Msi;                            /* 0x6000 */
+
+    /* DMA completion registers. */
+    T3_DMA_COMPLETION DmaComp;                          /* 0x6400 */
+
+    /* GRC registers. */
+    T3_GRC Grc;                                         /* 0x6800 */
+
+    /* Unused space. */
+    LM_UINT8 Unused2[1024];                             /* 0x6c00 */
+
+    /* NVRAM registers. */
+    T3_NVRAM Nvram;                                     /* 0x7000 */
+
+    /* Unused space. */
+    LM_UINT8 Unused3[3072];                             /* 0x7400 */
+
+    /* The 32k memory window into the NIC's */
+    /* internal memory.  The memory window is */
+    /* controlled by the Memory Window Base */
+    /* Address register.  This register is located */
+    /* in the PCI configuration space. */
+    union {                                             /* 0x8000 */
+        T3_FIRST_32K_SRAM First32k;
+
+        /* Use the memory window base address register to determine the */
+        /* MBUF segment. */
+        LM_UINT32 Mbuf[32768/4];
+        LM_UINT32 MemBlock32K[32768/4];
+    } uIntMem;
+} T3_STD_MEM_MAP, *PT3_STD_MEM_MAP;
+
+
+/******************************************************************************/
+/* Adapter info. */
+/******************************************************************************/
+
+typedef struct
+{
+    LM_UINT16 Svid;
+    LM_UINT16 Ssid;
+    LM_UINT32 PhyId;
+    LM_UINT32 Serdes;   /* 0 = copper PHY, 1 = Serdes */
+} LM_ADAPTER_INFO, *PLM_ADAPTER_INFO;
+
+
+/******************************************************************************/
+/* Packet queues. */
+/******************************************************************************/
+
+DECLARE_QUEUE_TYPE(LM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT);
+DECLARE_QUEUE_TYPE(LM_TX_PACKET_Q, MAX_TX_PACKET_DESC_COUNT);
+
+
+
+/******************************************************************************/
+/* Tx counters. */
+/******************************************************************************/
+
+typedef struct {
+    LM_COUNTER TxPacketGoodCnt;
+    LM_COUNTER TxBytesGoodCnt;
+    LM_COUNTER TxPacketAbortedCnt;
+    LM_COUNTER NoSendBdLeftCnt;
+    LM_COUNTER NoMapRegisterLeftCnt;
+    LM_COUNTER TooManyFragmentsCnt;
+    LM_COUNTER NoTxPacketDescCnt;
+} LM_TX_COUNTERS, *PLM_TX_COUNTERS;
+
+
+
+/******************************************************************************/
+/* Rx counters. */
+/******************************************************************************/
+
+typedef struct {
+    LM_COUNTER RxPacketGoodCnt;
+    LM_COUNTER RxBytesGoodCnt;
+    LM_COUNTER RxPacketErrCnt;
+    LM_COUNTER RxErrCrcCnt;
+    LM_COUNTER RxErrCollCnt;
+    LM_COUNTER RxErrLinkLostCnt;
+    LM_COUNTER RxErrPhyDecodeCnt;
+    LM_COUNTER RxErrOddNibbleCnt;
+    LM_COUNTER RxErrMacAbortCnt;
+    LM_COUNTER RxErrShortPacketCnt;
+    LM_COUNTER RxErrNoResourceCnt;
+    LM_COUNTER RxErrLargePacketCnt;
+} LM_RX_COUNTERS, *PLM_RX_COUNTERS;
+
+
+
+/******************************************************************************/
+/* Receive producer rings. */
+/******************************************************************************/
+
+typedef enum {
+    T3_UNKNOWN_RCV_PROD_RING    = 0,
+    T3_STD_RCV_PROD_RING        = 1,
+    T3_MINI_RCV_PROD_RING       = 2,
+    T3_JUMBO_RCV_PROD_RING      = 3
+} T3_RCV_PROD_RING, *PT3_RCV_PROD_RING;
+
+
+
+/******************************************************************************/
+/* Packet descriptor. */
+/******************************************************************************/
+
+#define LM_PACKET_SIGNATURE_TX              0x6861766b
+#define LM_PACKET_SIGNATURE_RX              0x6b766168
+
+typedef struct _LM_PACKET {
+    /* Set in LM. */
+    LM_STATUS PacketStatus;
+
+    /* Set in LM for Rx, in UM for Tx. */
+    LM_UINT32 PacketSize;
+
+    LM_UINT16 Flags;
+
+    LM_UINT16 VlanTag;
+
+    union {
+        /* Send info. */
+        struct {
+            /* Set up by UM. */
+            LM_UINT32 FragCount;
+
+        } Tx;
+
+        /* Receive info. */
+        struct {
+            /* This descriptor belongs to either Std, Mini, or Jumbo ring. */
+            T3_RCV_PROD_RING RcvProdRing;
+
+            /* Receive buffer size */
+            LM_UINT32 RxBufferSize;
+
+            /* Checksum information. */
+            LM_UINT16 IpChecksum;
+            LM_UINT16 TcpUdpChecksum;
+
+        } Rx;
+    } u;
+} LM_PACKET;
+
+
+
+/******************************************************************************/
+/* Tigon3 device block. */
+/******************************************************************************/
+
+typedef struct _LM_DEVICE_BLOCK {
+    int index; /* Device ID */
+    /* Memory view. */
+    PT3_STD_MEM_MAP pMemView;
+
+    /* Base address of the block of memory in which the LM_PACKET descriptors */
+    /* are allocated from. */
+    PLM_VOID pPacketDescBase;
+
+    LM_UINT32 MiscHostCtrl;
+    LM_UINT32 GrcLocalCtrl;
+    LM_UINT32 DmaReadWriteCtrl;
+    LM_UINT32 PciState;
+
+    /* Rx info */
+    LM_UINT32 RxStdDescCnt;
+    LM_UINT32 RxStdQueuedCnt;
+    LM_UINT32 RxStdProdIdx;
+
+    PT3_RCV_BD pRxStdBdVirt;
+    LM_PHYSICAL_ADDRESS RxStdBdPhy;
+
+    LM_UINT32 RxPacketDescCnt;
+    LM_RX_PACKET_Q RxPacketFreeQ;
+    LM_RX_PACKET_Q RxPacketReceivedQ;
+
+    /* Receive info. */
+    PT3_RCV_BD pRcvRetBdVirt;
+    LM_PHYSICAL_ADDRESS RcvRetBdPhy;
+    LM_UINT32 RcvRetConIdx;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+    LM_UINT32 RxJumboDescCnt;
+    LM_UINT32 RxJumboBufferSize;
+    LM_UINT32 RxJumboQueuedCnt;
+
+    LM_UINT32 RxJumboProdIdx;
+
+    PT3_RCV_BD pRxJumboBdVirt;
+    LM_PHYSICAL_ADDRESS RxJumboBdPhy;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+    /* These values are used by the upper module to inform the protocol */
+    /* of the maximum transmit/receive packet size. */
+    LM_UINT32 TxMtu;    /* Does not include CRC. */
+    LM_UINT32 RxMtu;    /* Does not include CRC. */
+
+    /* We need to shadow the EMAC, Rx, Tx mode registers.  With B0 silicon, */
+    /* we may have problems reading any MAC registers in 10mb mode. */
+    LM_UINT32 MacMode;
+    LM_UINT32 RxMode;
+    LM_UINT32 TxMode;
+
+    /* MiMode register. */
+    LM_UINT32 MiMode;
+
+    /* Host coalesce mode register. */
+    LM_UINT32 CoalesceMode;
+
+    /* Send info. */
+    LM_UINT32 TxPacketDescCnt;
+
+    /* Tx info. */
+    LM_TX_PACKET_Q TxPacketFreeQ;
+    LM_TX_PACKET_Q TxPacketActiveQ;
+    LM_TX_PACKET_Q TxPacketXmittedQ;
+
+    /* Pointers to SendBd. */
+    PT3_SND_BD pSendBdVirt;
+    LM_PHYSICAL_ADDRESS SendBdPhy;  /* Only valid for Host based Send BD. */
+
+    /* Send producer and consumer indices. */
+    LM_UINT32 SendProdIdx;
+    LM_UINT32 SendConIdx;
+
+    /* Number of BD left. */
+    atomic_t SendBdLeft;
+
+    T3_SND_BD ShadowSendBd[T3_SEND_RCB_ENTRY_COUNT];
+
+    /* Counters. */
+    LM_RX_COUNTERS RxCounters;
+    LM_TX_COUNTERS TxCounters;
+
+    /* Host coalescing parameters. */
+    LM_UINT32 RxCoalescingTicks;
+    LM_UINT32 TxCoalescingTicks;
+    LM_UINT32 RxMaxCoalescedFrames;
+    LM_UINT32 TxMaxCoalescedFrames;
+    LM_UINT32 StatsCoalescingTicks;
+    LM_UINT32 RxCoalescingTicksDuringInt;
+    LM_UINT32 TxCoalescingTicksDuringInt;
+    LM_UINT32 RxMaxCoalescedFramesDuringInt;
+    LM_UINT32 TxMaxCoalescedFramesDuringInt;
+
+    /* DMA water marks. */
+    LM_UINT32 DmaMbufLowMark;
+    LM_UINT32 RxMacMbufLowMark;
+    LM_UINT32 MbufHighMark;
+
+    /* Status block. */
+    PT3_STATUS_BLOCK pStatusBlkVirt;
+    LM_PHYSICAL_ADDRESS StatusBlkPhy;
+
+    /* Statistics block. */
+    PT3_STATS_BLOCK pStatsBlkVirt;
+    LM_PHYSICAL_ADDRESS StatsBlkPhy;
+
+    /* Current receive mask. */
+    LM_UINT32 ReceiveMask;
+
+    /* Task offload capabilities. */
+    LM_TASK_OFFLOAD TaskOffloadCap;
+
+    /* Task offload selected. */
+    LM_TASK_OFFLOAD TaskToOffload;
+
+    /* Wake up capability. */
+    LM_WAKE_UP_MODE WakeUpModeCap;
+
+    /* Wake up capability. */
+    LM_WAKE_UP_MODE WakeUpMode;
+
+    /* Flow control. */
+    LM_FLOW_CONTROL FlowControlCap;
+    LM_FLOW_CONTROL FlowControl;
+
+    /* Enable or disable PCI MWI. */
+    LM_UINT32 EnableMWI;
+
+    /* Enable 5701 tagged status mode. */
+    LM_UINT32 UseTaggedStatus;
+
+    /* NIC will not compute the pseudo header checksum.  The driver or OS */
+    /* must seed the checksum field with the pseudo checksum. */
+    LM_UINT32 NoTxPseudoHdrChksum;
+
+    /* The receive checksum in the BD does not include the pseudo checksum. */
+    /* The OS or the driver must calculate the pseudo checksum and add it to */
+    /* the checksum in the BD. */
+    LM_UINT32 NoRxPseudoHdrChksum;
+
+    /* Current node address. */
+    LM_UINT8 NodeAddress[8];
+
+    /* The adapter's node address. */
+    LM_UINT8 PermanentNodeAddress[8];
+
+    /* Adapter info. */
+    LM_UINT16 BusNum;
+    LM_UINT8 DevNum;
+    LM_UINT8 FunctNum;
+    LM_UINT16 PciVendorId;
+    LM_UINT16 PciDeviceId;
+    LM_UINT32 BondId;
+    LM_UINT8 Irq;
+    LM_UINT8 IntPin;
+    LM_UINT8 CacheLineSize;
+    LM_UINT8 PciRevId;
+#if PCIX_TARGET_WORKAROUND
+	LM_UINT32 EnablePciXFix;
+#endif
+    LM_UINT32 UndiFix;   /* new, jimmy */
+    LM_UINT32 PciCommandStatusWords;
+    LM_UINT32 ChipRevId;
+    LM_UINT16 SubsystemVendorId;
+    LM_UINT16 SubsystemId;
+#if 0  /* Jimmy, deleted in new driver */
+    LM_UINT32 MemBaseLow;
+    LM_UINT32 MemBaseHigh;
+    LM_UINT32 MemBaseSize;
+#endif
+    PLM_UINT8 pMappedMemBase;
+
+    /* Saved PCI configuration registers for restoring after a reset. */
+    LM_UINT32 SavedCacheLineReg;
+
+    /* Phy info. */
+    LM_UINT32 PhyAddr;
+    LM_UINT32 PhyId;
+
+    /* Requested phy settings. */
+    LM_REQUESTED_MEDIA_TYPE RequestedMediaType;
+
+    /* Disable auto-negotiation. */
+    LM_UINT32 DisableAutoNeg;
+
+    /* Ways for the MAC to get link change interrupt. */
+    LM_UINT32 PhyIntMode;
+    #define T3_PHY_INT_MODE_AUTO                        0
+    #define T3_PHY_INT_MODE_MI_INTERRUPT                1
+    #define T3_PHY_INT_MODE_LINK_READY                  2
+    #define T3_PHY_INT_MODE_AUTO_POLLING                3
+
+    /* Ways to determine link change status. */
+    LM_UINT32 LinkChngMode;
+    #define T3_LINK_CHNG_MODE_AUTO                      0
+    #define T3_LINK_CHNG_MODE_USE_STATUS_REG            1
+    #define T3_LINK_CHNG_MODE_USE_STATUS_BLOCK          2
+
+
+    /* LED mode. */
+    LM_UINT32 LedMode;
+
+    #define LED_MODE_AUTO                               0
+
+    /* 5700/01 LED mode. */
+    #define LED_MODE_THREE_LINK                         1
+    #define LED_MODE_LINK10                             2
+
+    /* 5703/02/04 LED mode. */
+    #define LED_MODE_OPEN_DRAIN                         1
+    #define LED_MODE_OUTPUT                             2
+
+    /* WOL Speed */
+    LM_UINT32 WolSpeed;
+    #define WOL_SPEED_10MB                              1
+    #define WOL_SPEED_100MB                             2
+
+    /* Reset the PHY on initialization. */
+    LM_UINT32 ResetPhyOnInit;
+
+    LM_UINT32 RestoreOnWakeUp;
+    LM_REQUESTED_MEDIA_TYPE WakeUpRequestedMediaType;
+    LM_UINT32 WakeUpDisableAutoNeg;
+
+    /* Current phy settings. */
+    LM_MEDIA_TYPE MediaType;
+    LM_LINE_SPEED LineSpeed;
+    LM_LINE_SPEED OldLineSpeed;
+    LM_DUPLEX_MODE DuplexMode;
+    LM_STATUS LinkStatus;
+    LM_UINT32 advertising;     /* Jimmy, new! */
+    LM_UINT32 advertising1000; /* Jimmy, new! */
+
+    /* Multicast address list. */
+    LM_UINT32 McEntryCount;
+    LM_UINT8 McTable[LM_MAX_MC_TABLE_SIZE][LM_MC_ENTRY_SIZE];
+
+    /* Use NIC or Host based send BD. */
+    LM_UINT32 NicSendBd;
+
+    /* Athlon fix. */
+    LM_UINT32 DelayPciGrant;
+
+    /* Enable OneDmaAtOnce */
+    LM_UINT32 OneDmaAtOnce;
+
+    /* Split Mode flags, Jimmy new */
+    LM_UINT32 SplitModeEnable;
+    LM_UINT32 SplitModeMaxReq;
+
+    /* Init flag. */
+    LM_BOOL InitDone;
+
+    /* Shutdown flag.  Set by the upper module. */
+    LM_BOOL ShuttingDown;
+
+    /* Flag to determine whether to call LM_QueueRxPackets or not in */
+    /* LM_ResetAdapter routine. */
+    LM_BOOL QueueRxPackets;
+
+    LM_UINT32 MbufBase;
+    LM_UINT32 MbufSize;
+
+    /* TRUE if we have a SERDES PHY. */
+    LM_UINT32 EnableTbi;
+
+    /* Ethernet@WireSpeed. */
+    LM_UINT32 EnableWireSpeed;
+
+    LM_UINT32 EepromWp;
+
+#if INCLUDE_TBI_SUPPORT
+    /* Autoneg state info. */
+    AN_STATE_INFO AnInfo;
+    LM_UINT32 PollTbiLink;
+    LM_UINT32 IgnoreTbiLinkChange;
+#endif
+    char PartNo[24];
+    char BootCodeVer[16];
+    char BusSpeedStr[24]; /* Jimmy, new! */
+    LM_UINT32 PhyCrcCount;
+} LM_DEVICE_BLOCK;
+
+
+#define T3_REG_CPU_VIEW               0xc0000000
+
+#define T3_BLOCK_DMA_RD               (1 << 0)
+#define T3_BLOCK_DMA_COMP             (1 << 1)
+#define T3_BLOCK_RX_BD_INITIATOR      (1 << 2)
+#define T3_BLOCK_RX_BD_COMP           (1 << 3)
+#define T3_BLOCK_DMA_WR               (1 << 4)
+#define T3_BLOCK_MSI_HANDLER          (1 << 5)
+#define T3_BLOCK_RX_LIST_PLMT         (1 << 6)
+#define T3_BLOCK_RX_LIST_SELECTOR     (1 << 7)
+#define T3_BLOCK_RX_DATA_INITIATOR    (1 << 8)
+#define T3_BLOCK_RX_DATA_COMP         (1 << 9)
+#define T3_BLOCK_HOST_COALESING       (1 << 10)
+#define T3_BLOCK_MAC_RX_ENGINE        (1 << 11)
+#define T3_BLOCK_MBUF_CLUSTER_FREE    (1 << 12)
+#define T3_BLOCK_SEND_BD_INITIATOR    (1 << 13)
+#define T3_BLOCK_SEND_BD_COMP         (1 << 14)
+#define T3_BLOCK_SEND_BD_SELECTOR     (1 << 15)
+#define T3_BLOCK_SEND_DATA_INITIATOR  (1 << 16)
+#define T3_BLOCK_SEND_DATA_COMP       (1 << 17)
+#define T3_BLOCK_MAC_TX_ENGINE        (1 << 18)
+#define T3_BLOCK_MEM_ARBITOR          (1 << 19)
+#define T3_BLOCK_MBUF_MANAGER         (1 << 20)
+#define T3_BLOCK_MAC_GLOBAL           (1 << 21)
+
+#define LM_ENABLE               1
+#define LM_DISABLE              2
+
+#define RX_CPU_EVT_SW0              0
+#define RX_CPU_EVT_SW1              1
+#define RX_CPU_EVT_RLP              2
+#define RX_CPU_EVT_SW3              3
+#define RX_CPU_EVT_RLS              4
+#define RX_CPU_EVT_SW4              5
+#define RX_CPU_EVT_RX_BD_COMP       6
+#define RX_CPU_EVT_SW5              7
+#define RX_CPU_EVT_RDI              8
+#define RX_CPU_EVT_DMA_WR           9
+#define RX_CPU_EVT_DMA_RD           10
+#define RX_CPU_EVT_SWQ              11
+#define RX_CPU_EVT_SW6              12
+#define RX_CPU_EVT_RDC              13
+#define RX_CPU_EVT_SW7              14
+#define RX_CPU_EVT_HOST_COALES      15
+#define RX_CPU_EVT_SW8              16
+#define RX_CPU_EVT_HIGH_DMA_WR      17
+#define RX_CPU_EVT_HIGH_DMA_RD      18
+#define RX_CPU_EVT_SW9              19
+#define RX_CPU_EVT_DMA_ATTN         20
+#define RX_CPU_EVT_LOW_P_MBOX       21
+#define RX_CPU_EVT_HIGH_P_MBOX      22
+#define RX_CPU_EVT_SW10             23
+#define RX_CPU_EVT_TX_CPU_ATTN      24
+#define RX_CPU_EVT_MAC_ATTN         25
+#define RX_CPU_EVT_RX_CPU_ATTN      26
+#define RX_CPU_EVT_FLOW_ATTN        27
+#define RX_CPU_EVT_SW11             28
+#define RX_CPU_EVT_TIMER            29
+#define RX_CPU_EVT_SW12             30
+#define RX_CPU_EVT_SW13             31
+
+/* RX-CPU event */
+#define RX_CPU_EVENT_SW_EVENT0      (1 << RX_CPU_EVT_SW0)
+#define RX_CPU_EVENT_SW_EVENT1      (1 << RX_CPU_EVT_SW1)
+#define RX_CPU_EVENT_RLP            (1 << RX_CPU_EVT_RLP)
+#define RX_CPU_EVENT_SW_EVENT3      (1 << RX_CPU_EVT_SW3)
+#define RX_CPU_EVENT_RLS            (1 << RX_CPU_EVT_RLS)
+#define RX_CPU_EVENT_SW_EVENT4      (1 << RX_CPU_EVT_SW4)
+#define RX_CPU_EVENT_RX_BD_COMP     (1 << RX_CPU_EVT_RX_BD_COMP)
+#define RX_CPU_EVENT_SW_EVENT5      (1 << RX_CPU_EVT_SW5)
+#define RX_CPU_EVENT_RDI            (1 << RX_CPU_EVT_RDI)
+#define RX_CPU_EVENT_DMA_WR         (1 << RX_CPU_EVT_DMA_WR)
+#define RX_CPU_EVENT_DMA_RD         (1 << RX_CPU_EVT_DMA_RD)
+#define RX_CPU_EVENT_SWQ            (1 << RX_CPU_EVT_SWQ)
+#define RX_CPU_EVENT_SW_EVENT6      (1 << RX_CPU_EVT_SW6)
+#define RX_CPU_EVENT_RDC            (1 << RX_CPU_EVT_RDC)
+#define RX_CPU_EVENT_SW_EVENT7      (1 << RX_CPU_EVT_SW7)
+#define RX_CPU_EVENT_HOST_COALES    (1 << RX_CPU_EVT_HOST_COALES)
+#define RX_CPU_EVENT_SW_EVENT8      (1 << RX_CPU_EVT_SW8)
+#define RX_CPU_EVENT_HIGH_DMA_WR    (1 << RX_CPU_EVT_HIGH_DMA_WR)
+#define RX_CPU_EVENT_HIGH_DMA_RD    (1 << RX_CPU_EVT_HIGH_DMA_RD)
+#define RX_CPU_EVENT_SW_EVENT9      (1 << RX_CPU_EVT_SW9)
+#define RX_CPU_EVENT_DMA_ATTN       (1 << RX_CPU_EVT_DMA_ATTN)
+#define RX_CPU_EVENT_LOW_P_MBOX     (1 << RX_CPU_EVT_LOW_P_MBOX)
+#define RX_CPU_EVENT_HIGH_P_MBOX    (1 << RX_CPU_EVT_HIGH_P_MBOX)
+#define RX_CPU_EVENT_SW_EVENT10     (1 << RX_CPU_EVT_SW10)
+#define RX_CPU_EVENT_TX_CPU_ATTN    (1 << RX_CPU_EVT_TX_CPU_ATTN)
+#define RX_CPU_EVENT_MAC_ATTN       (1 << RX_CPU_EVT_MAC_ATTN)
+#define RX_CPU_EVENT_RX_CPU_ATTN    (1 << RX_CPU_EVT_RX_CPU_ATTN)
+#define RX_CPU_EVENT_FLOW_ATTN      (1 << RX_CPU_EVT_FLOW_ATTN)
+#define RX_CPU_EVENT_SW_EVENT11     (1 << RX_CPU_EVT_SW11)
+#define RX_CPU_EVENT_TIMER          (1 << RX_CPU_EVT_TIMER)
+#define RX_CPU_EVENT_SW_EVENT12     (1 << RX_CPU_EVT_SW12)
+#define RX_CPU_EVENT_SW_EVENT13     (1 << RX_CPU_EVT_SW13)
+
+#define RX_CPU_MASK (RX_CPU_EVENT_SW_EVENT0 | \
+		     RX_CPU_EVENT_RLP | \
+		     RX_CPU_EVENT_RDI | \
+		     RX_CPU_EVENT_RDC)
+
+#define TX_CPU_EVT_SW0              0
+#define TX_CPU_EVT_SW1              1
+#define TX_CPU_EVT_SW2              2
+#define TX_CPU_EVT_SW3              3
+#define TX_CPU_EVT_TX_MAC           4
+#define TX_CPU_EVT_SW4              5
+#define TX_CPU_EVT_SBDC             6
+#define TX_CPU_EVT_SW5              7
+#define TX_CPU_EVT_SDI              8
+#define TX_CPU_EVT_DMA_WR           9
+#define TX_CPU_EVT_DMA_RD           10
+#define TX_CPU_EVT_SWQ              11
+#define TX_CPU_EVT_SW6              12
+#define TX_CPU_EVT_SDC              13
+#define TX_CPU_EVT_SW7              14
+#define TX_CPU_EVT_HOST_COALES      15
+#define TX_CPU_EVT_SW8              16
+#define TX_CPU_EVT_HIGH_DMA_WR      17
+#define TX_CPU_EVT_HIGH_DMA_RD      18
+#define TX_CPU_EVT_SW9              19
+#define TX_CPU_EVT_DMA_ATTN         20
+#define TX_CPU_EVT_LOW_P_MBOX       21
+#define TX_CPU_EVT_HIGH_P_MBOX      22
+#define TX_CPU_EVT_SW10             23
+#define TX_CPU_EVT_RX_CPU_ATTN      24
+#define TX_CPU_EVT_MAC_ATTN         25
+#define TX_CPU_EVT_TX_CPU_ATTN      26
+#define TX_CPU_EVT_FLOW_ATTN        27
+#define TX_CPU_EVT_SW11             28
+#define TX_CPU_EVT_TIMER            29
+#define TX_CPU_EVT_SW12             30
+#define TX_CPU_EVT_SW13             31
+
+
+/* TX-CPU event */
+#define TX_CPU_EVENT_SW_EVENT0      (1 << TX_CPU_EVT_SW0)
+#define TX_CPU_EVENT_SW_EVENT1      (1 << TX_CPU_EVT_SW1)
+#define TX_CPU_EVENT_SW_EVENT2      (1 << TX_CPU_EVT_SW2)
+#define TX_CPU_EVENT_SW_EVENT3      (1 << TX_CPU_EVT_SW3)
+#define TX_CPU_EVENT_TX_MAC         (1 << TX_CPU_EVT_TX_MAC)
+#define TX_CPU_EVENT_SW_EVENT4      (1 << TX_CPU_EVT_SW4)
+#define TX_CPU_EVENT_SBDC           (1 << TX_CPU_EVT_SBDC)
+#define TX_CPU_EVENT_SW_EVENT5      (1 << TX_CPU_EVT_SW5)
+#define TX_CPU_EVENT_SDI            (1 << TX_CPU_EVT_SDI)
+#define TX_CPU_EVENT_DMA_WR         (1 << TX_CPU_EVT_DMA_WR)
+#define TX_CPU_EVENT_DMA_RD         (1 << TX_CPU_EVT_DMA_RD)
+#define TX_CPU_EVENT_SWQ            (1 << TX_CPU_EVT_SWQ)
+#define TX_CPU_EVENT_SW_EVENT6      (1 << TX_CPU_EVT_SW6)
+#define TX_CPU_EVENT_SDC            (1 << TX_CPU_EVT_SDC)
+#define TX_CPU_EVENT_SW_EVENT7      (1 << TX_CPU_EVT_SW7)
+#define TX_CPU_EVENT_HOST_COALES    (1 << TX_CPU_EVT_HOST_COALES)
+#define TX_CPU_EVENT_SW_EVENT8      (1 << TX_CPU_EVT_SW8)
+#define TX_CPU_EVENT_HIGH_DMA_WR    (1 << TX_CPU_EVT_HIGH_DMA_WR)
+#define TX_CPU_EVENT_HIGH_DMA_RD    (1 << TX_CPU_EVT_HIGH_DMA_RD)
+#define TX_CPU_EVENT_SW_EVENT9      (1 << TX_CPU_EVT_SW9)
+#define TX_CPU_EVENT_DMA_ATTN       (1 << TX_CPU_EVT_DMA_ATTN)
+#define TX_CPU_EVENT_LOW_P_MBOX     (1 << TX_CPU_EVT_LOW_P_MBOX)
+#define TX_CPU_EVENT_HIGH_P_MBOX    (1 << TX_CPU_EVT_HIGH_P_MBOX)
+#define TX_CPU_EVENT_SW_EVENT10     (1 << TX_CPU_EVT_SW10)
+#define TX_CPU_EVENT_RX_CPU_ATTN    (1 << TX_CPU_EVT_RX_CPU_ATTN)
+#define TX_CPU_EVENT_MAC_ATTN       (1 << TX_CPU_EVT_MAC_ATTN)
+#define TX_CPU_EVENT_TX_CPU_ATTN    (1 << TX_CPU_EVT_TX_CPU_ATTN)
+#define TX_CPU_EVENT_FLOW_ATTN      (1 << TX_CPU_EVT_FLOW_ATTN)
+#define TX_CPU_EVENT_SW_EVENT11     (1 << TX_CPU_EVT_SW11)
+#define TX_CPU_EVENT_TIMER          (1 << TX_CPU_EVT_TIMER)
+#define TX_CPU_EVENT_SW_EVENT12     (1 << TX_CPU_EVT_SW12)
+#define TX_CPU_EVENT_SW_EVENT13     (1 << TX_CPU_EVT_SW13)
+
+
+#define TX_CPU_MASK (TX_CPU_EVENT_SW_EVENT0 | \
+		     TX_CPU_EVENT_SDI  | \
+		     TX_CPU_EVENT_SDC)
+
+
+#define T3_FTQ_TYPE1_UNDERFLOW_BIT   (1 << 29)
+#define T3_FTQ_TYPE1_PASS_BIT        (1 << 30)
+#define T3_FTQ_TYPE1_SKIP_BIT        (1 << 31)
+
+#define T3_FTQ_TYPE2_UNDERFLOW_BIT   (1 << 13)
+#define T3_FTQ_TYPE2_PASS_BIT        (1 << 14)
+#define T3_FTQ_TYPE2_SKIP_BIT        (1 << 15)
+
+#define T3_QID_DMA_READ               1
+#define T3_QID_DMA_HIGH_PRI_READ      2
+#define T3_QID_DMA_COMP_DX            3
+#define T3_QID_SEND_BD_COMP           4
+#define T3_QID_SEND_DATA_INITIATOR    5
+#define T3_QID_DMA_WRITE              6
+#define T3_QID_DMA_HIGH_PRI_WRITE     7
+#define T3_QID_SW_TYPE_1              8
+#define T3_QID_SEND_DATA_COMP         9
+#define T3_QID_HOST_COALESCING        10
+#define T3_QID_MAC_TX                 11
+#define T3_QID_MBUF_CLUSTER_FREE      12
+#define T3_QID_RX_BD_COMP             13
+#define T3_QID_RX_LIST_PLM            14
+#define T3_QID_RX_DATA_BD_INITIATOR   15
+#define T3_QID_RX_DATA_COMP           16
+#define T3_QID_SW_TYPE2               17
+
+LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
+                          PT3_FWIMG_INFO pFwImg,
+                          LM_UINT32 LoadCpu,
+                          LM_UINT32 StartCpu);
+
+/******************************************************************************/
+/* NIC register read/write macros. */
+/******************************************************************************/
+
+#if 0  /* Jimmy */
+/* MAC register access. */
+LM_UINT32 LM_RegRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
+LM_VOID LM_RegWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
+    LM_UINT32 Value32);
+
+/* MAC memory access. */
+LM_UINT32 LM_MemRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
+LM_VOID LM_MemWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
+    LM_UINT32 Value32);
+
+#if PCIX_TARGET_WORKAROUND
+
+/* use memory-mapped accesses for mailboxes and reads, UNDI accesses
+   for writes to all other registers */
+#define REG_RD(pDevice, OffsetName)                              \
+    readl(&((pDevice)->pMemView->OffsetName))
+
+#define REG_WR(pDevice, OffsetName, Value32)                     \
+    (((OFFSETOF(T3_STD_MEM_MAP, OffsetName) >=0x200 ) &&         \
+      (OFFSETOF(T3_STD_MEM_MAP, OffsetName) <0x400)) ||	         \
+	 ((pDevice)->EnablePciXFix == FALSE)) ?                  \
+    (void) writel(Value32, &((pDevice)->pMemView->OffsetName)) : \
+    LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
+
+#define MB_REG_RD(pDevice, OffsetName)                           \
+    readl(&((pDevice)->pMemView->OffsetName))
+
+#define MB_REG_WR(pDevice, OffsetName, Value32)                  \
+    writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define REG_RD_OFFSET(pDevice, Offset)                           \
+    readl(&((LM_UINT8 *) (pDevice)->pMemView + Offset))
+
+#define REG_WR_OFFSET(pDevice, Offset, Value32)                  \
+	(((Offset >=0x200 ) && (Offset < 0x400)) ||		 \
+	 ((pDevice)->EnablePciXFix == FALSE)) ?	   		 \
+    (void) writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset)) : \
+    LM_RegWrInd(pDevice, Offset, Value32)
+
+#define MEM_RD(pDevice, AddrName)                                \
+    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32)                       \
+    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset)                           \
+    LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32)                  \
+    LM_MemWrInd(pDevice, Offset, Value32)
+
+#else /* normal target access path below */
+
+/* Register access. */
+#define REG_RD(pDevice, OffsetName)                                         \
+    readl(&((pDevice)->pMemView->OffsetName))
+#define REG_WR(pDevice, OffsetName, Value32)                                \
+    writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define REG_RD_OFFSET(pDevice, Offset)                                      \
+    readl(((LM_UINT8 *) (pDevice)->pMemView + Offset))
+#define REG_WR_OFFSET(pDevice, Offset, Value32)                             \
+    writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset))
+
+
+/* There could be problem access the memory window directly.  For now, */
+/* we have to go through the PCI configuration register. */
+#define MEM_RD(pDevice, AddrName)                                           \
+    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32)                                  \
+    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset)                                      \
+    LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32)                             \
+    LM_MemWrInd(pDevice, Offset, Value32)
+
+#endif  /* PCIX_TARGET_WORKAROUND */
+
+#endif  /* Jimmy, merging */
+
+  /* Jimmy...rest of file is new stuff! */
+/******************************************************************************/
+/* NIC register read/write macros. */
+/******************************************************************************/
+
+/* MAC register access. */
+LM_UINT32 LM_RegRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
+LM_VOID LM_RegWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
+    LM_UINT32 Value32);
+
+/* MAC memory access. */
+LM_UINT32 LM_MemRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
+LM_VOID LM_MemWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
+    LM_UINT32 Value32);
+
+#define MB_REG_WR(pDevice, OffsetName, Value32)                               \
+    ((pDevice)->UndiFix) ?                                                    \
+        LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600,     \
+            Value32) :                                                        \
+        (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define MB_REG_RD(pDevice, OffsetName)                                        \
+    (((pDevice)->UndiFix) ?                                                   \
+        LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600) :   \
+        __raw_readl(&((pDevice)->pMemView->OffsetName)))
+
+#define REG_RD(pDevice, OffsetName)                                           \
+    (((pDevice)->UndiFix) ?                                                   \
+        LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)) :          \
+        __raw_readl(&((pDevice)->pMemView->OffsetName)))
+
+#if PCIX_TARGET_WORKAROUND
+
+#define REG_WR(pDevice, OffsetName, Value32)                                \
+	 ((pDevice)->EnablePciXFix == FALSE) ?                              \
+    (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName)) :      \
+    LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
+
+#else
+
+#define REG_WR(pDevice, OffsetName, Value32)                                \
+    __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#endif
+
+#define MEM_RD(pDevice, AddrName)                                           \
+    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32)                                  \
+    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset)                                      \
+    LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32)                             \
+    LM_MemWrInd(pDevice, Offset, Value32)
+
+#endif /* TIGON3_H */
+
diff --git a/dtt/ds1621.c b/dtt/ds1621.c
new file mode 100644
index 0000000..5c25f64
--- /dev/null
+++ b/dtt/ds1621.c
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.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
+ */
+
+/*
+ * Dallas Semiconductor's DS1621 Digital Thermometer and Thermostat.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1621
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+        (CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than 1 to use CONFIG_DTT_DS1621"
+#endif
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48			/* Dallas Semi's DS1621 */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and command.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW))
+	dlen = 2;
+    else
+	dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+	return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and register.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & sensor);
+
+    /*
+     * Handle various data sizes.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW)) {
+	dlen = 2;
+	data[0] = (char)((val >> 8) & 0xff);	/* MSB first */
+	data[1] = (char)(val & 0xff);
+    }
+    else if ((reg == DTT_WRITE_START_CONV) || (reg == DTT_WRITE_STOP_CONV)) {
+	dlen = 0;
+	data[0] = (char)0;
+	data[1] = (char)0;
+    }
+    else {
+	dlen = 1;
+	data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to device.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup High Temp.
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    /*
+     * Setup Low Temp - hysteresis.
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    /*
+     * Setup configuraton register
+     *
+     * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
+     *
+     * We run in polled mode, since there isn't any way to know if this
+     * lousy device is ready to provide temperature readings on power up.
+     */
+    val = 0x9;
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("DTT%d:  FAILED\n", i+1);
+	else
+	    printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+
+int dtt_get_temp(int sensor)
+{
+    int i;
+
+    /*
+     * Start a conversion, may take up to 1 second.
+     */
+    dtt_write(sensor, DTT_WRITE_START_CONV, 0);
+    for (i = 0; i <= 10; i++) {
+	udelay(100000);
+	if (dtt_read(sensor, DTT_CONFIG) & 0x80)
+	    break;
+    }
+
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+
+#endif /* CONFIG_DTT_DS1621 */
+
diff --git a/dtt/lm75.c b/dtt/lm75.c
new file mode 100644
index 0000000..9930a8b
--- /dev/null
+++ b/dtt/lm75.c
@@ -0,0 +1,181 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * 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
+ */
+
+/*
+ * On Semiconductor's LM75 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM75
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+	(CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM75"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48			/* ON Semi's LM75 device */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if((reg < 0) || (reg > 3))
+	return -1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HYST) ||
+	(reg == DTT_TEMP_SET))
+	dlen = 2;
+    else
+	dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return -1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+	return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if ((reg < 0) || (reg > 3))
+	return 1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Handle 2 byte values.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HYST) ||
+	(reg == DTT_TEMP_SET)) {
+	dlen = 2;
+	data[0] = (char)((val >> 8) & 0xff);	/* MSB first */
+	data[1] = (char)(val & 0xff);
+    } else {
+	dlen = 1;
+	data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to register.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup TSET ( trip point ) register
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80; /* trip */
+    if (dtt_write(sensor, DTT_TEMP_SET, val) != 0)
+	return 1;
+
+    /*
+     * Setup THYST ( untrip point ) register - Hysteresis
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+	return 1;
+
+    /*
+     * Setup configuraton register
+     */
+    /* config = 6 sample integration, int mode, active low, and enable */
+    val = 0x18;
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+	return 1;
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+    const char *const header = "DTT:   ";
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("%s%d FAILED INIT\n", header, i+1);
+	else
+	    printf("%s%d is %i C\n", header, i+1,
+		   dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+int dtt_get_temp(int sensor)
+{
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM75 */
+
diff --git a/include/altera.h b/include/altera.h
new file mode 100644
index 0000000..88f72db
--- /dev/null
+++ b/include/altera.h
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.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
+ *
+ */
+
+#include <fpga.h>
+
+#ifndef _ALTERA_H_
+#define _ALTERA_H_
+
+/*
+ * Note that this is just  Altera FPGA interface boilerplate.
+ * There is no support for Altera devices yet.
+ *
+ * See include/xilinx.h for a working example.
+ */
+
+/* In your board's config.h file you should define CONFIG_FPGA as such:
+ *	#define CONFIG_FPGA 	(CFG_ALTERA_xxx | CFG_ALTERA_IF_xxx )
+ */
+
+/* Altera Model definitions */
+#define CFG_ALTERA_xxxx		( CFG_FPGA_ALTERA | CFG_FPGA_DEV( 0x1 ))
+/* Add new models here */
+
+/* Altera Interface definitions */
+#define CFG_ALTERA_IF_xxx		CFG_FPGA_IF( 0x1 )
+/* Add new interfaces here */
+
+typedef enum {                     /* typedef Altera_iface */
+    min_altera_iface_type,        /* insert all new types after this */
+/* Add new interfaces here */
+    max_altera_iface_type         /* insert all new types before this */
+} Altera_iface;                   /* end, typedef Altera_iface */
+
+typedef enum {                     /* typedef Altera_Family */
+    min_altera_type,              /* insert all new types after this */
+/* Add new models here */
+    max_altera_type               /* insert all new types before this */
+} Altera_Family;                  /* end, typedef Altera_Family */
+
+typedef struct {                   /* typedef Altera_desc */
+    Altera_Family    family;      /* part type */
+    Altera_iface     iface;       /* interface type */
+    size_t            size;        /* bytes of data part can accept */
+    void *            base;        /* base interface address */
+} Altera_desc;                    /* end, typedef Altera_desc */
+
+extern int altera_load( Altera_desc *desc, void *image, size_t size );
+extern int altera_dump( Altera_desc *desc, void *buf, size_t bsize );
+extern int altera_info( Altera_desc *desc );
+extern int altera_reloc( Altera_desc *desc, ulong reloc_off );
+
+#endif  /* _ALTERA_H_ */
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
new file mode 100644
index 0000000..4733858
--- /dev/null
+++ b/include/asm-arm/bitops.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 1995, Russell King.
+ * Various bits and pieces copyrights include:
+ *  Linus Torvalds (test_bit).
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ *
+ * Please note that the code in this file should never be included
+ * from user space.  Many of these are not implemented in assembler
+ * since they would be too costly.  Also, they require priviledged
+ * instructions (which are not available from user mode) to ensure
+ * that they are atomic.
+ */
+
+#ifndef __ASM_ARM_BITOPS_H
+#define __ASM_ARM_BITOPS_H
+
+#ifdef __KERNEL__
+
+#define smp_mb__before_clear_bit()	do { } while (0)
+#define smp_mb__after_clear_bit()	do { } while (0)
+
+/*
+ * Function prototypes to keep gcc -Wall happy.
+ */
+extern void set_bit(int nr, volatile void * addr);
+
+static inline void __set_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
+}
+
+extern void clear_bit(int nr, volatile void * addr);
+
+static inline void __clear_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
+}
+
+extern void change_bit(int nr, volatile void * addr);
+
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
+}
+
+extern int test_and_set_bit(int nr, volatile void * addr);
+
+static inline int __test_and_set_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval | mask;
+	return oldval & mask;
+}
+
+extern int test_and_clear_bit(int nr, volatile void * addr);
+
+static inline int __test_and_clear_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval & ~mask;
+	return oldval & mask;
+}
+
+extern int test_and_change_bit(int nr, volatile void * addr);
+
+static inline int __test_and_change_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval ^ mask;
+	return oldval & mask;
+}
+
+extern int find_first_zero_bit(void * addr, unsigned size);
+extern int find_next_zero_bit(void * addr, int size, int offset);
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static inline int test_bit(int nr, const void * addr)
+{
+    return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
+}
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+	int k;
+
+	word = ~word;
+	k = 31;
+	if (word & 0x0000ffff) { k -= 16; word <<= 16; }
+	if (word & 0x00ff0000) { k -= 8;  word <<= 8;  }
+	if (word & 0x0f000000) { k -= 4;  word <<= 4;  }
+	if (word & 0x30000000) { k -= 2;  word <<= 2;  }
+	if (word & 0x40000000) { k -= 1; }
+        return k;
+}
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#define ext2_set_bit			test_and_set_bit
+#define ext2_clear_bit			test_and_clear_bit
+#define ext2_test_bit			test_bit
+#define ext2_find_first_zero_bit	find_first_zero_bit
+#define ext2_find_next_zero_bit		find_next_zero_bit
+
+/* Bitmap functions for the minix filesystem. */
+#define minix_test_and_set_bit(nr,addr)	test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr)		set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr)	test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr)		test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size)	find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ARM_BITOPS_H */
diff --git a/include/asm-arm/proc-armv/ptrace.h b/include/asm-arm/proc-armv/ptrace.h
new file mode 100644
index 0000000..51708b9
--- /dev/null
+++ b/include/asm-arm/proc-armv/ptrace.h
@@ -0,0 +1,110 @@
+/*
+ *  linux/include/asm-arm/proc-armv/ptrace.h
+ *
+ *  Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_PTRACE_H
+#define __ASM_PROC_PTRACE_H
+
+#include <linux/config.h>
+
+#define USR26_MODE	0x00
+#define FIQ26_MODE	0x01
+#define IRQ26_MODE	0x02
+#define SVC26_MODE	0x03
+#define USR_MODE	0x10
+#define FIQ_MODE	0x11
+#define IRQ_MODE	0x12
+#define SVC_MODE	0x13
+#define ABT_MODE	0x17
+#define UND_MODE	0x1b
+#define SYSTEM_MODE	0x1f
+#define MODE_MASK	0x1f
+#define T_BIT		0x20
+#define F_BIT		0x40
+#define I_BIT		0x80
+#define CC_V_BIT	(1 << 28)
+#define CC_C_BIT	(1 << 29)
+#define CC_Z_BIT	(1 << 30)
+#define CC_N_BIT	(1 << 31)
+#define PCMASK		0
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+	long uregs[18];
+};
+
+#define ARM_cpsr	uregs[16]
+#define ARM_pc		uregs[15]
+#define ARM_lr		uregs[14]
+#define ARM_sp		uregs[13]
+#define ARM_ip		uregs[12]
+#define ARM_fp		uregs[11]
+#define ARM_r10		uregs[10]
+#define ARM_r9		uregs[9]
+#define ARM_r8		uregs[8]
+#define ARM_r7		uregs[7]
+#define ARM_r6		uregs[6]
+#define ARM_r5		uregs[5]
+#define ARM_r4		uregs[4]
+#define ARM_r3		uregs[3]
+#define ARM_r2		uregs[2]
+#define ARM_r1		uregs[1]
+#define ARM_r0		uregs[0]
+#define ARM_ORIG_r0	uregs[17]
+
+#ifdef __KERNEL__
+
+#define user_mode(regs)	\
+	(((regs)->ARM_cpsr & 0xf) == 0)
+
+#ifdef CONFIG_ARM_THUMB
+#define thumb_mode(regs) \
+	(((regs)->ARM_cpsr & T_BIT))
+#else
+#define thumb_mode(regs) (0)
+#endif
+
+#define processor_mode(regs) \
+	((regs)->ARM_cpsr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+	(!((regs)->ARM_cpsr & I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+	(!((regs)->ARM_cpsr & F_BIT))
+
+#define condition_codes(regs) \
+	((regs)->ARM_cpsr & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT))
+
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+	if ((regs->ARM_cpsr & 0xf) == 0 &&
+	    (regs->ARM_cpsr & (F_BIT|I_BIT)) == 0)
+		return 1;
+
+	/*
+	 * Force CPSR to something logical...
+	 */
+	regs->ARM_cpsr &= (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT|0x10);
+
+	return 0;
+}
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __ASSEMBLY__ */
+
+#endif
+
diff --git a/include/asm-arm/u-boot-arm.h b/include/asm-arm/u-boot-arm.h
new file mode 100644
index 0000000..355b1e4
--- /dev/null
+++ b/include/asm-arm/u-boot-arm.h
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.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
+ */
+
+#ifndef _U_BOOT_ARM_H_
+#define _U_BOOT_ARM_H_	1
+
+/* for the following variables, see start.S */
+extern ulong _armboot_start;	/* code start */
+extern ulong _armboot_end_data;	/* code + data end */
+extern ulong _armboot_end;	/* BSS end */
+extern ulong IRQ_STACK_START;	/* top of IRQ stack */
+extern ulong FIQ_STACK_START;	/* top of FIQ stack */
+extern ulong _armboot_real_end;	/* first usable RAM address */
+
+/* cpu/.../cpu.c */
+int	cpu_init(void);
+int	cleanup_before_linux(void);
+
+/* board/.../... */
+int	board_init(void);
+int	dram_init (void);
+
+/* ------------------------------------------------------------ */
+/* Here is a list of some prototypes which are incompatible to	*/
+/* the U-Boot implementation					*/
+/* To be fixed!							*/
+/* ------------------------------------------------------------ */
+/* common/cmd_nvedit.c */
+void	setenv		(char *, char *);
+
+/* cpu/.../interrupt.c */
+void	reset_timer_masked	(void);
+ulong	get_timer_masked	(void);
+void	udelay_masked		(unsigned long usec);
+
+#endif	/* _U_BOOT_ARM_H_ */
diff --git a/include/asm-arm/u-boot.h b/include/asm-arm/u-boot.h
new file mode 100644
index 0000000..c3b0e4a
--- /dev/null
+++ b/include/asm-arm/u-boot.h
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.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
+ */
+
+#ifndef _U_BOOT_H_
+#define _U_BOOT_H_	1
+
+typedef struct bd_info {
+    int			bi_baudrate;	/* serial console baudrate */
+    unsigned long	bi_ip_addr;	/* IP Address */
+    unsigned char	bi_enetaddr[6]; /* Ethernet adress */
+    struct environment_s	       *bi_env;
+    ulong	        bi_arch_number;	/* unique id for this board */
+    ulong	        bi_boot_params;	/* where this board expects params */
+    struct				/* RAM configuration */
+    {
+	ulong start;
+	ulong size;
+    } 			bi_dram[CONFIG_NR_DRAM_BANKS];
+} bd_t;
+
+#define bi_env_data bi_env->data
+#define bi_env_crc  bi_env->crc
+
+#endif	/* _U_BOOT_H_ */
diff --git a/include/cmd_bsp.h b/include/cmd_bsp.h
new file mode 100644
index 0000000..b39d50b
--- /dev/null
+++ b/include/cmd_bsp.h
@@ -0,0 +1,313 @@
+/*
+ * (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
+ */
+
+#ifndef _CMD_BSP_H_
+#define _CMD_BSP_H_
+
+#include <common.h>
+#include <command.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+/* ----- LWMON -----------------------------------------------------------------
+ */
+#if defined(CONFIG_LWMON)
+
+#define	CMD_TBL_BSP	MK_CMD_TBL_ENTRY(					\
+	"pic",	3,	4,	1,	do_pic,					\
+	"pic     - read and write PIC registers\n",				\
+	"read  reg      - read PIC register `reg'\n"				\
+	"pic write reg val  - write value `val' to PIC register `reg'\n"	\
+),  MK_CMD_TBL_ENTRY(								\
+	"kbd",	3,	1,	1,	do_kbd,					\
+	"kbd     - read keyboard status\n",					\
+	NULL									\
+),  MK_CMD_TBL_ENTRY(								\
+	"lsb",	3,	2,	1,	do_lsb,					\
+	"lsb     - check and set LSB switch\n",					\
+	"on  - switch LSB on\n"							\
+	"lsb off - switch LSB off\n"						\
+	"lsb     - print current setting\n"					\
+),
+int do_pic (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_lsb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif	/* CONFIG_LWMON */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- PCU E -----------------------------------------------------------------
+ */
+#if defined(CONFIG_PCU_E)
+
+#define CMD_TBL_BSP	MK_CMD_TBL_ENTRY(					\
+	"puma",	4,	4,	1,	do_puma,				\
+	"puma    - access PUMA FPGA\n",						\
+	"status - print PUMA status\n"						\
+	"puma load addr len - load PUMA configuration data\n"			\
+),
+int do_puma (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif	/* CONFIG_PCU_E */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- CCM/SCM ---------------------------------------------------------------
+ */
+#if defined(CONFIG_CCM) || defined(CONFIG_SCM)
+
+#define CMD_TBL_BSP	MK_CMD_TBL_ENTRY(					\
+	"fpga",	4,	4,	1,	do_fpga,				\
+	"fpga    - access FPGA(s)\n",						\
+	"fpga status [name] - print FPGA status\n"				\
+	"fpga reset  [name] - reset FPGA\n"					\
+	"fpga load [name] addr - load FPGA configuration data\n"		\
+),
+int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif	/* CONFIG_CCM, CONFIG_SCM */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- PIP405 -----------------------------------------------------------------
+ */
+#if defined(CONFIG_PIP405)
+
+#define	CMD_TBL_BSP MK_CMD_TBL_ENTRY(				\
+	"pip405",	4,	6,	1,	do_pip405,			\
+	"pip405  - PIP405 specific Cmds\n",					\
+	"flash mem [SrcAddr] - updates U-Boot with image in memory\n"					\
+	"pip405 flash floppy [SrcAddr] - updates U-Boot with image from floppy\n"					\
+	"pip405 flash mps - updates U-Boot with image from MPS\n"					\
+),
+int do_pip405 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_PIP405 */
+/* ----------------------------------------------------------------------------*/
+/* ----- MIP405 -----------------------------------------------------------------
+ */
+#if defined(CONFIG_MIP405)
+
+#define	CMD_TBL_BSP MK_CMD_TBL_ENTRY(				\
+	"mip405",	4,	6,	1,	do_mip405,			\
+	"mip405  - MIP405 specific Cmds\n",					\
+	"flash mem [SrcAddr] - updates U-Boot with image in memory\n"					\
+	"mip405 flash mps - updates U-Boot with image from MPS\n"					\
+),
+int do_mip405 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_MIP405 */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- DASA_SIM ---------------------------------------------------------------
+ */
+#if defined(CONFIG_DASA_SIM)
+
+#define	CMD_TBL_BSP MK_CMD_TBL_ENTRY(				                \
+	"pci9054",	7,	3,	1,	do_pci9054,			\
+	"pci9054 - PLX PCI9054 EEPROM access\n",				\
+	"pci9054 info - print EEPROM values\n"		                        \
+	"pci9054 update - updates EEPROM with default values\n"			\
+),
+int do_pci9054 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_DASA_SIM */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- HYMOD -----------------------------------------------------------------
+ */
+#if defined(CONFIG_HYMOD)
+
+#define	CMD_TBL_BSP	MK_CMD_TBL_ENTRY(				\
+	"fpga",	4,	6,	1,	do_fpga,			\
+	"fpga    - FPGA sub-system\n",					\
+	"load [type] addr size\n"					\
+	"  - write the configuration data at memory address `addr',\n"	\
+	"    size `size' bytes, into the FPGA of type `type' (either\n"	\
+	"    `main' or `mezz', default `main'). e.g.\n"			\
+	"        `fpga load 100000 7d8f'\n"				\
+	"    loads the main FPGA with config data at address 100000\n"	\
+	"    HEX, size 7d8f HEX (32143 DEC) bytes\n"			\
+	"fpga tftp file addr\n"						\
+	"  - transfers `file' from the tftp server into memory at\n"	\
+	"    address `addr', then writes the entire file contents\n"	\
+	"    into the main FPGA\n"					\
+	"fpga store addr\n"						\
+	"  - read configuration data from the main FPGA (the mezz\n"	\
+	"    FPGA is write-only), into address `addr'. There must be\n"	\
+	"    enough memory available at `addr' to hold all the config\n"\
+	"    data - the size of which is determined by VC:???\n"	\
+	"fpga info\n"							\
+	"  - print information about the Hymod FPGA, namely the\n"	\
+	"    memory addresses at which the four FPGA local bus\n"	\
+	"    address spaces appear in the physical address space\n"	\
+), MK_CMD_TBL_ENTRY(							\
+	"eeclear", 4,	1,	0,	do_eecl,			\
+	"eeclear - Clear the eeprom on a Hymod board \n",		\
+	"[type]\n"							\
+	"  - write zeroes into the EEPROM on the board of type `type'\n"\
+	"    (`type' is either `main' or `mezz' - default `main')\n"	\
+	"    Note: the EEPROM write enable jumper must be installed\n"	\
+),
+int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_eecl (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif	/* CONFIG_HYMOD */
+/* ----------------------------------------------------------------------------*/
+/* CRAY405 (L1) */
+#if defined (CONFIG_CRAYL1)
+#define	CMD_TBL_BSP MK_CMD_TBL_ENTRY(						\
+	"L1cmd",	5,	4,	1,	do_crayL1,			\
+	"L1cmd  - L1 update, setup, commands \n",				\
+	"L1cmd update - update flash images from host\n"			\
+	"L1cmd boot - nfs or ramboot L1\n"					\
+),
+int do_crayL1 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif /* CONFIG_CRAY405 */
+/* ----------------------------------------------------------------------------*/
+
+#if defined (CONFIG_EVB64260)
+/* ----- EVB64260 -------------------------------------------------------------*/
+#ifdef CONFIG_ZUMA_V2
+#define CMD_TBL_BSP  ZUMA_TBL_ENTRY
+
+#define ZUMA_TBL_ENTRY	MK_CMD_TBL_ENTRY(				\
+	"zinit",	 5,	 1,	 0,	 do_zuma_init_pbb,	\
+	"zinit   - init zuma pbb\n",					\
+	"\n"								\
+	"    - init zuma pbb\n"						\
+), MK_CMD_TBL_ENTRY(							\
+	"zdtest",	  6,	  3,	  1,	  do_zuma_test_dma,	\
+	"zdtest  - run dma test\n",					\
+	"[cmd [count]]\n"						\
+	"    - run dma cmd (w=0,v=1,cp=2,cmp=3,wi=4,vi=5), count bytes\n" \
+), MK_CMD_TBL_ENTRY(							\
+	"zminit",	  5,	  1,	  0,	  do_zuma_init_mbox,	\
+	"zminit  - init zuma mbox\n",				\
+	"\n"								\
+	"    - init zuma mbox\n"					\
+),
+
+int do_zuma_init_pbb  (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_zuma_test_dma  (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_zuma_init_mbox (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+void zuma_init_pbb(void);
+int zuma_mbox_init(void);
+int zuma_test_dma(int cmd, int size);
+#else
+#define CMD_TBL_BSP
+#endif /* ZUMA_NTL */
+
+#endif /* CONFIG_EVB64260 */
+/* ----------------------------------------------------------------------------*/
+
+/* -----W7O--------------------------------------------------------------------*/
+#if defined(CONFIG_W7O)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY(			\
+	  "vpd",	3,	2,	1,	do_vpd, \
+	  "vpd     - Read Vital Product Data\n",	\
+	  "[dev_addr]\n"				\
+	  "        - Read VPD Data from default address, or device address 'dev_addr'.\n" \
+),
+
+extern int do_vpd (cmd_tbl_t *, int, int, char *[]);
+
+#endif	/* CONFIG_W7O */
+/* ----------------------------------------------------------------------------*/
+
+/* ---- PCIPPC2 / PCIPPC6 -----------------------------------------------------*/
+#if defined(CONFIG_PCIPPC2) || defined(CONFIG_PCIPPC6)
+#if defined(CONFIG_WATCHDOG)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY(			\
+	"wd",	3,	2,	1,	do_wd,					\
+	"wd      - check and set watchdog\n",					\
+	"on   - switch watchDog on\n"							\
+	"wd off  - switch watchdog off\n"						\
+	"wd      - print current status\n"					\
+),
+
+extern int do_wd (cmd_tbl_t *, int, int, char *[]);
+
+#else
+#define CMD_TBL_BSP
+#endif  /* CONFIG_WATCHDOG */
+
+#endif	/* CONFIG_PCIPPC2 , CONFIG_PCIPPC6 */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- PN62 -----------------------------------------------------------------*/
+#if defined(CONFIG_PN62)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY(				\
+	"loadpci",	5,	2,	1,	do_loadpci, 	\
+	"loadpci - load binary file over PCI\n",		\
+	"[addr]\n"						\
+	"    - load binary file over PCI to address 'addr'\n"	\
+), MK_CMD_TBL_ENTRY( 	 	 	 	 	 	\
+	"led"    ,	3,	3,	1,	do_led, 	\
+	"led     - set LED 0..11 on the PN62 board\n",		\
+	"i fun\n"						\
+	"    - set 'i'th LED to function 'fun'\n"		\
+),
+
+extern int do_loadpci (cmd_tbl_t *, int, int, char *[]);
+extern int do_led (cmd_tbl_t *, int, int, char *[]);
+#endif /* CONFIG_PN62 */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- TRAB ------------------------------------------------------------------
+ */
+#if defined(CONFIG_TRAB)
+
+#define	CMD_TBL_BSP	MK_CMD_TBL_ENTRY(					\
+	"kbd",	3,	1,	1,	do_kbd,					\
+	"kbd     - read keyboard status\n",					\
+	NULL									\
+),
+
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif	/* CONFIG_TRAB */
+/* ----------------------------------------------------------------------------*/
+
+#else
+#define CMD_TBL_BSP
+#endif	/* CFG_CMD_BSP */
+
+/* ----- R360MPI ---------------------------------------------------------------
+ */
+#if defined(CONFIG_R360MPI)
+
+#define	CMD_TBL_BSP	MK_CMD_TBL_ENTRY(					\
+	"kbd",	3,	1,	1,	do_kbd,					\
+	"kbd     - read keyboard status\n",					\
+	NULL									\
+),
+
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif	/* CONFIG_R360MPI */
+/* ----------------------------------------------------------------------------*/
+
+#endif	/* _CMD_BSP_H_ */
diff --git a/include/configs/BMW.h b/include/configs/BMW.h
new file mode 100644
index 0000000..edfd68f
--- /dev/null
+++ b/include/configs/BMW.h
@@ -0,0 +1,303 @@
+/*
+ * (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
+ */
+
+/*
+ *
+ * Configuration settings for the CU824 board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X		1
+#define CONFIG_MPC8245		1
+#define CONFIG_BMW		1
+
+#define CONFIG_BCM570x		1 /* Use Broadcom BCM570x Ethernet Driver */
+#define	CONFIG_TIGON3		1
+
+#define CONFIG_CONS_INDEX	1
+#define CONFIG_BAUDRATE		9600
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_CLOCKS_IN_MHZ	1	/* clocks passsed to Linux in MHz	*/
+
+#define CONFIG_BOOTCOMMAND	"bootm FF820000"	/* autoboot command	*/
+#define CONFIG_BOOTDELAY	5
+
+#define CFG_MAX_DOC_DEVICE      1 /* Only use Onboard TSOP-16MB device */
+#define DOC_PASSIVE_PROBE       1
+#define CFG_DOC_SUPPORT_2000    1
+#define CFG_DOC_SUPPORT_MILLENNIUM 1
+#define CFG_DOC_SHORT_TIMEOUT    1
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL	| \
+				CFG_CMD_DATE	| \
+				CFG_CMD_DOC	| \
+				CFG_CMD_ELF	| \
+				0 )
+#if 0
+#define CONFIG_COMMANDS	        (CONFIG_CMD_DFL	| CFG_CMD_DHCP | \
+				 CFG_CMD_PCI | CFG_CMD_DOC | CFG_CMD_DATE)
+
+#define CONFIG_PCI		1
+#define CONFIG_PCI_PNP		1	/* PCI plug-and-play */
+#endif
+
+/* 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	*/
+#define CFG_CBSIZE	256		/* Console I/O Buffer Size	*/
+
+/* Print Buffer Size
+ */
+#define CFG_PBSIZE	(CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+
+#define CFG_MAXARGS	8		/* Max number of command args	*/
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+#define CFG_LOAD_ADDR	0x00100000	/* Default load address		*/
+
+/*-----------------------------------------------------------------------
+ * 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_BASE0_PRELIM      0xFFF00000      /* FLASH bank on RCS#0 */
+#define CFG_FLASH_BASE1_PRELIM      0xFF800000      /* FLASH bank on RCS#1 */
+#define CFG_FLASH_BASE  CFG_MONITOR_BASE
+#define CFG_FLASH_BANKS		{ CFG_FLASH_BASE0_PRELIM , CFG_FLASH_BASE1_PRELIM }
+
+/* even though FLASHP_BASE is FF800000, with 4MB is RCS0, the
+ * reset vector is actually located at FFB00100, but the 8245
+ * takes care of us.
+ */
+#define CFG_RESET_ADDRESS   0xFFF00100
+
+#define CFG_EUMB_ADDR	    0xFC000000
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+
+#define CFG_MONITOR_LEN	    (256 << 10) /* Reserve 256 kB for Monitor	*/
+#define CFG_MALLOC_LEN	    (2048 << 10) /* Reserve 2MB for malloc()	*/
+
+#define CFG_MEMTEST_START   0x00004000	/* memtest works on		*/
+#define CFG_MEMTEST_END	    0x04000000	/* 0 ... 32 MB in DRAM		*/
+
+	/* Maximum amount of RAM.
+	 */
+#define CFG_MAX_RAM_SIZE    0x04000000	/* 0 .. 64 MB of (S)DRAM */
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_RAM_ADDR CFG_SDRAM_BASE + CFG_MONITOR_LEN
+#define CFG_INIT_RAM_END   0x2F00  /* End of used area in DPRAM  */
+#define CFG_GBL_DATA_SIZE  128  /* 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
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ */
+
+#define CONFIG_SYS_CLK_FREQ  33000000	/* external frequency to pll */
+#define CFG_HZ		     1000
+
+#define CFG_ETH_DEV_FN	     0x7800
+#define CFG_ETH_IOBASE	     0x00104000
+
+	/* Bit-field values for MCCR1.
+	 */
+#define CFG_ROMNAL	    0xf
+#define CFG_ROMFAL	    0x1f
+#define CFG_DBUS_SIZE       0x3
+
+	/* Bit-field values for MCCR2.
+	 */
+#define CFG_TSWAIT	    0x5		    /* Transaction Start Wait States timer */
+#define CFG_REFINT	    0x400	    /* Refresh interval	FIXME: was 0t430		*/
+
+	/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.
+	 */
+#define CFG_BSTOPRE	    0		/* FIXME: was 192 */
+
+	/* Bit-field values for MCCR3.
+	 */
+#define CFG_REFREC	    2	    /* Refresh to activate interval */
+
+	/* Bit-field values for MCCR4.
+	 */
+#define CFG_PRETOACT	    2	    /* Precharge to activate interval FIXME: was 2	*/
+#define CFG_ACTTOPRE	    5	    /* Activate to Precharge interval FIXME: was 5	*/
+#define CFG_SDMODE_CAS_LAT  3	    /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP	    0	    /* SDMODE wrap type	*/
+#define CFG_SDMODE_BURSTLEN 3	    /* SDMODE Burst length */
+#define CFG_ACTORW	    0xa		/* FIXME was 2 */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+#define CFG_PGMAX           0x0 /* how long the 8240 reatins the currently accessed page in memory FIXME: was 0x32*/
+
+#define CFG_SDRAM_DSCD	0x20	/* SDRAM data in sample clock delay - note bottom 3 bits MUST be 0 */
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these vales to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8240 book.
+ */
+
+#define CFG_BANK0_START	    0x00000000
+#define CFG_BANK0_END	    (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE    1
+#define CFG_BANK1_START	    0x3ff00000
+#define CFG_BANK1_END	    0x3fffffff
+#define CFG_BANK1_ENABLE    0
+#define CFG_BANK2_START	    0x3ff00000
+#define CFG_BANK2_END	    0x3fffffff
+#define CFG_BANK2_ENABLE    0
+#define CFG_BANK3_START	    0x3ff00000
+#define CFG_BANK3_END	    0x3fffffff
+#define CFG_BANK3_ENABLE    0
+#define CFG_BANK4_START	    0x3ff00000
+#define CFG_BANK4_END	    0x3fffffff
+#define CFG_BANK4_ENABLE    0
+#define CFG_BANK5_START	    0x3ff00000
+#define CFG_BANK5_END	    0x3fffffff
+#define CFG_BANK5_ENABLE    0
+#define CFG_BANK6_START	    0x3ff00000
+#define CFG_BANK6_END	    0x3fffffff
+#define CFG_BANK6_ENABLE    0
+#define CFG_BANK7_START	    0x3ff00000
+#define CFG_BANK7_END	    0x3fffffff
+#define CFG_BANK7_ENABLE    0
+
+#define CFG_ODCR	    0xff
+
+#define CONFIG_PCI              1 /* Include PCI support */
+#undef CONFIG_PCI_PNP
+
+/* PCI Memory space(s) */
+#define PCI_MEM_SPACE1_START	0x80000000
+#define PCI_MEM_SPACE2_START	0xfd000000
+
+/* ROM Spaces */
+#include "../board/bmw/bmw.h"
+
+/* BAT configuration */
+#define CFG_IBAT0L  (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U  (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L  (0x70000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT1U  (0x70000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT2L  (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U  (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT3L  (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U  (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L  CFG_IBAT0L
+#define CFG_DBAT0U  CFG_IBAT0U
+#define CFG_DBAT1L  CFG_IBAT1L
+#define CFG_DBAT1U  CFG_IBAT1U
+#define CFG_DBAT2L  CFG_IBAT2L
+#define CFG_DBAT2U  CFG_IBAT2U
+#define CFG_DBAT3L  CFG_IBAT3L
+#define CFG_DBAT3U  CFG_IBAT3U
+
+/*
+ * 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	0	/* Max number of flash banks	    */
+#define CFG_MAX_FLASH_SECT	64	/* Max number of sectors per  flash */
+
+#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms) */
+
+/*
+ * Warining: environment is not EMBEDDED in the U-Boot code.
+ * It's stored in flash separately.
+ */
+#define CFG_ENV_IS_IN_NVRAM      1
+#define CONFIG_ENV_OVERWRITE     1
+#define CFG_NVRAM_ACCESS_ROUTINE 1
+#define CFG_ENV_ADDR		0x7c004000 /* right at the start of NVRAM  */
+#define CFG_ENV_SIZE		0x1ff0	/* Size of the Environment - 8K	   */
+#define CFG_ENV_OFFSET		0	/* starting right at the beginning */
+
+/*
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value   */
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM		0x02	/* Software reboot		    */
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/CCM.h b/include/configs/CCM.h
new file mode 100644
index 0000000..0e0248d
--- /dev/null
+++ b/include/configs/CCM.h
@@ -0,0 +1,472 @@
+/*
+ * (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
+ */
+
+/*
+ * configuration options, board specific, for Siemens Card Controller Module
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#undef	CCM_80MHz			/* define for 80 MHz CPU only */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC860           1   /* This is a MPC860 CPU ... */
+#define CONFIG_CCM              1   /* on a Card Controller Module  */
+
+#define CONFIG_8xx_CONS_SMC1    1   /* Console is on SMC1       */
+#undef  CONFIG_8xx_CONS_SMC2
+#undef  CONFIG_8xx_CONS_NONE
+
+/*  ENVIRONMENT */
+
+#define CONFIG_BAUDRATE         19200         /* console baudrate in bps    */
+#define CONFIG_BOOTDELAY        2             /* autoboot after 2 seconds   */
+#define CONFIG_CLOCKS_IN_MHZ    1             /* clocks passsed to Linux in MHz */
+
+#define CONFIG_IPADDR           192.168.0.42
+#define CONFIG_NETMASK          255.255.255.0
+#define CONFIG_GATEWAYIP        0.0.0.0
+#define CONFIG_SERVERIP         192.168.0.254
+
+#define CONFIG_HOSTNAME         CCM
+
+#define CONFIG_LOADADDR         40180000
+
+#undef	CONFIG_BOOTARGS
+
+#define CONFIG_BOOTCOMMAND      "setenv bootargs " \
+                                "mem=$(mem) " \
+                                "root=/dev/ram rw ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off " \
+                                "wt_8xx=timeout:3600; " \
+                                "bootm"
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#undef	CFG_LOADS_BAUD_CHANGE	/* don't allow baudrate change	*/
+
+#define	CONFIG_WATCHDOG		1	/* watchdog enabled		*/
+
+#undef	CONFIG_STATUS_LED		/* Status LED disabled		*/
+
+#define	CONFIG_PRAM		512	/* reserve 512kB "protected RAM"*/
+
+#define	CONFIG_RTC_MPC8xx		/* use internal RTC of MPC8xx	*/
+
+#define	CONFIG_SPI			/* enable SPI driver		*/
+#define	CONFIG_SPI_X			/* 16 bit EEPROM addressing	*/
+
+/* ----------------------------------------------------------------
+ * Offset to initial SPI buffers in DPRAM (used if the environment
+ * is in the SPI EEPROM): We need a 520 byte scratch DPRAM area to
+ * use at an early stage. It is used between the two initialization
+ * calls (spi_init_f() and spi_init_r()). The value 0xB00 makes it
+ * far enough from the start of the data area (as well as from the
+ * stack pointer).
+ * ---------------------------------------------------------------- */
+#define CFG_SPI_INIT_OFFSET		0xB00
+
+#define CFG_EEPROM_PAGE_WRITE_BITS	5	/* 32-byte page size	*/
+
+
+#define CONFIG_MAC_PARTITION		/* nod used yet			*/
+#define CONFIG_DOS_PARTITION
+
+#define CONFIG_BOOTP_MASK	(CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_DHCP	| \
+				CFG_CMD_DATE	| \
+				CFG_CMD_EEPROM	| \
+				CFG_CMD_BSP	)
+
+/* 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	0x00100000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x00F00000	/* 1 ... 15MB in DRAM	*/
+
+#define	CFG_LOAD_ADDR		0x00100000	/* default load address	*/
+
+/* Ethernet hardware configuration done using port pins */
+#define CFG_PA_ETH_RESET 	0x0200		/* PA  6	*/
+#define CFG_PA_ETH_MDDIS	0x4000		/* PA  1	*/
+#define CFG_PB_ETH_POWERDOWN	0x00000800	/* PB 20	*/
+#define CFG_PB_ETH_CFG1		0x00000400	/* PB 21	*/
+#define CFG_PB_ETH_CFG2		0x00000200	/* PB 22	*/
+#define CFG_PB_ETH_CFG3		0x00000100	/* PB 23	*/
+
+/* Ethernet settings:
+ * MDIO not disabled, autonegotiation, 10/100Mbps, half/full duplex
+ */
+#define CFG_ETH_MDDIS_VALUE	0
+#define CFG_ETH_CFG1_VALUE	1
+#define CFG_ETH_CFG2_VALUE	1
+#define CFG_ETH_CFG3_VALUE	1
+
+/* PUMA configuration */
+#define CFG_PC_PUMA_PROG	0x0200		/* PC  6        */
+#define CFG_PC_PUMA_DONE	0x0008		/* PC 12	*/
+#define CFG_PC_PUMA_INIT	0x0004		/* PC 13	*/
+
+#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		0xF0000000
+
+/*-----------------------------------------------------------------------
+ * 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
+
+/*-----------------------------------------------------------------------
+ * Address accessed to reset the board - must not be mapped/assigned
+ */
+#define	CFG_RESET_ADDRESS	0xFEFFFFFF
+
+/*-----------------------------------------------------------------------
+ * 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()	*/
+
+/*
+ * 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	67	/* 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)	*/
+
+#if 1
+/* Start port with environment in flash; switch to SPI EEPROM later */
+#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	*/
+#else
+/* Final version: environment in EEPROM */
+#define CFG_ENV_IS_IN_EEPROM	1
+#define CFG_ENV_OFFSET		2048
+#define CFG_ENV_SIZE		2048
+#endif
+
+/*-----------------------------------------------------------------------
+ * Hardware Information Block
+ */
+#define CFG_HWINFO_OFFSET	0x0003FFC0	/* offset of HW Info block */
+#define CFG_HWINFO_SIZE		0x00000040	/* size   of HW Info block */
+#define CFG_HWINFO_MAGIC	0x54514D38	/* 'TQM8' */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	16	/* For all MPC8xx CPUs			*/
+#define CFG_CACHELINE_SHIFT	4	/* log base 2 of the above value	*/
+
+/*-----------------------------------------------------------------------
+ * 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
+ *-----------------------------------------------------------------------
+ * we must activate GPL5 in the SIUMCR for CAN
+ */
+#define CFG_SIUMCR	(SIUMCR_DBGC11 | 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_TBF)
+
+/*-----------------------------------------------------------------------
+ * RTCSC - Real-Time Clock Status and Control Register		11-27
+ *-----------------------------------------------------------------------
+ */
+#define CFG_RTCSC	(RTCSC_SEC | RTCSC_ALR | RTCSC_RTF| RTCSC_RTE)
+
+/*-----------------------------------------------------------------------
+ * 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
+ *-----------------------------------------------------------------------
+ * Reset PLL lock status sticky bit, timer expired status bit and timer
+ * interrupt status bit
+ *
+ * If this is a 80 MHz CPU, set PLL multiplication factor to 5 (5*16=80)!
+ */
+#ifdef	CCM_80MHz	/* for 80 MHz, we use a 16 MHz clock * 5 */
+#define CFG_PLPRCR							\
+		( (5-1)<<PLPRCR_MF_SHIFT | PLPRCR_TEXPS | PLPRCR_TMIST )
+#else			/* up to 50 MHz we use a 1:1 clock */
+#define CFG_PLPRCR	(PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
+#endif	/* CCM_80MHz */
+
+/*-----------------------------------------------------------------------
+ * 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
+#ifdef	CCM_80MHz	/* for 80 MHz, we use a 16 MHz clock * 5 */
+#define CFG_SCCR	(/* SCCR_TBS  | */ \
+			 SCCR_COM00   | SCCR_DFSYNC00 | SCCR_DFBRG00  | \
+			 SCCR_DFNL000 | SCCR_DFNH000  | SCCR_DFLCD000 | \
+			 SCCR_DFALCD00)
+#else			/* up to 50 MHz we use a 1:1 clock */
+#define CFG_SCCR	(SCCR_TBS     | \
+			 SCCR_COM00   | SCCR_DFSYNC00 | SCCR_DFBRG00  | \
+			 SCCR_DFNL000 | SCCR_DFNH000  | SCCR_DFLCD000 | \
+			 SCCR_DFALCD00)
+#endif	/* CCM_80MHz */
+
+/*-----------------------------------------------------------------------
+ *
+ * Interrupt Levels
+ *-----------------------------------------------------------------------
+ */
+#define CFG_CPM_INTERRUPT	13	/* SIU_LEVEL6	*/
+
+/*-----------------------------------------------------------------------
+ *
+ *-----------------------------------------------------------------------
+ *
+ */
+#define CFG_DER	0
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0x40000000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0x60000000	/* FLASH bank #0	*/
+
+/* used to re-map FLASH both when starting from SRAM or FLASH:
+ * restrict access enough to keep SRAM working (if any)
+ * but not too much to meddle with FLASH accesses
+ */
+#define CFG_REMAP_OR_AM		0x80000000	/* OR addr mask */
+#define CFG_PRELIM_OR_AM	0xE0000000	/* OR addr mask */
+
+/* FLASH timing: ACS = 11, TRLX = 0, CSNT = 1, SCY = 5, EHTR = 1	*/
+#define CFG_OR_TIMING_FLASH	(OR_CSNT_SAM  | OR_ACS_DIV2 | OR_BI | \
+				 OR_SCY_5_CLK | OR_EHTR)
+
+#define CFG_OR0_REMAP	(CFG_REMAP_OR_AM  | CFG_OR_TIMING_FLASH)
+#define CFG_OR0_PRELIM	(CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH)
+#define CFG_BR0_PRELIM	((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_V )
+
+#define CFG_OR1_REMAP	CFG_OR0_REMAP
+#define CFG_OR1_PRELIM	CFG_OR0_PRELIM
+#define CFG_BR1_PRELIM	((FLASH_BASE1_PRELIM & BR_BA_MSK) | BR_V )
+
+/*
+ * BR2 and OR2 (SDRAM)
+ *
+ */
+#define SDRAM_BASE2_PRELIM	0x00000000	/* SDRAM bank #0	*/
+#define SDRAM_BASE3_PRELIM	0x20000000	/* SDRAM bank #1	*/
+#define	SDRAM_MAX_SIZE		0x04000000	/* max 64 MB per bank	*/
+
+/* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care)	*/
+#define CFG_OR_TIMING_SDRAM	0x00000A00
+
+#define CFG_OR2_PRELIM	(CFG_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM )
+#define CFG_BR2_PRELIM	((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMA | BR_V )
+
+/*
+ * BR3 and OR3 (CAN Controller)
+ */
+#define	CFG_CAN_BASE		0xC0000000	/* CAN mapped at 0xC0000000	*/
+#define CFG_CAN_OR_AM		0xFFFF8000	/* 32 kB address mask		*/
+#define CFG_OR3_CAN		(CFG_CAN_OR_AM | OR_G5LA | OR_BI)
+#define CFG_BR3_CAN		((CFG_CAN_BASE & BR_BA_MSK) | \
+					BR_PS_8 | BR_MS_UPMB | BR_V )
+
+/*
+ * BR4/OR4: PUMA Config
+ *
+ * Memory controller will be used in 2 modes:
+ *
+ * - "read" mode:
+ *	BR4: 0x10100801		OR4: 0xffff8520
+ * - "load" mode (chip select on UPM B):
+ *	BR4: 0x101004c1		OR4: 0xffff8600
+ *
+ * Default initialization is in "read" mode
+ */
+#define PUMA_CONF_BASE		0x10100000	/* PUMA Config */
+#define PUMA_CONF_OR_AM		0xFFFF8000	/* 32 kB */
+#define	PUMA_CONF_LOAD_TIMING	(OR_ACS_DIV2	 | OR_SCY_2_CLK)
+#define PUMA_CONF_READ_TIMING	(OR_G5LA | OR_BI | OR_SCY_2_CLK)
+
+#define PUMA_CONF_BR_LOAD	((PUMA_CONF_BASE & BR_BA_MSK) | \
+					BR_PS_8  | BR_MS_UPMB | BR_V)
+#define PUMA_CONF_OR_LOAD	(PUMA_CONF_OR_AM | PUMA_CONF_LOAD_TIMING)
+
+#define PUMA_CONF_BR_READ	((PUMA_CONF_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define PUMA_CONF_OR_READ	(PUMA_CONF_OR_AM | PUMA_CONF_READ_TIMING)
+
+#define CFG_BR4_PRELIM		PUMA_CONF_BR_READ
+#define CFG_OR4_PRELIM		PUMA_CONF_OR_READ
+
+/*
+ * BR5/OR5: PUMA: SMA Bus 8 Bit
+ *	BR5: 0x10200401		OR5: 0xffe0010a
+ */
+#define PUMA_SMA8_BASE		0x10200000	/* PUMA SMA Bus 8 Bit */
+#define PUMA_SMA8_OR_AM		0xFFE00000	/* 2 MB */
+#define PUMA_SMA8_TIMING	(OR_BI | OR_SCY_0_CLK | OR_EHTR)
+
+#define CFG_BR5_PRELIM		((PUMA_SMA8_BASE & BR_BA_MSK) | BR_PS_8 | BR_V)
+#define CFG_OR5_PRELIM		(PUMA_SMA8_OR_AM | PUMA_SMA8_TIMING | OR_SETA)
+
+/*
+ * BR6/OR6: PUMA: SMA Bus 16 Bit
+ *	BR6: 0x10600801		OR6: 0xffe0010a
+ */
+#define PUMA_SMA16_BASE		0x10600000	/* PUMA SMA Bus 16 Bit */
+#define PUMA_SMA16_OR_AM	0xFFE00000	/* 2 MB */
+#define PUMA_SMA16_TIMING	(OR_BI | OR_SCY_0_CLK | OR_EHTR)
+
+#define CFG_BR6_PRELIM		((PUMA_SMA16_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define CFG_OR6_PRELIM		(PUMA_SMA16_OR_AM | PUMA_SMA16_TIMING | OR_SETA)
+
+/*
+ * BR7/OR7: PUMA: external Flash
+ *	BR7: 0x10a00801		OR7: 0xfe00010a
+ */
+#define PUMA_FLASH_BASE		0x10A00000	/* PUMA external Flash */
+#define PUMA_FLASH_OR_AM	0xFE000000	/* 32 MB */
+#define PUMA_FLASH_TIMING	(OR_BI | OR_SCY_0_CLK | OR_EHTR)
+
+#define CFG_BR7_PRELIM		((PUMA_FLASH_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define CFG_OR7_PRELIM		(PUMA_FLASH_OR_AM | PUMA_FLASH_TIMING | OR_SETA)
+
+
+/*
+ * Memory Periodic Timer Prescaler
+ */
+
+/* periodic timer for refresh */
+#define CFG_MAMR_PTA	97		/* start with divider for 100 MHz	*/
+
+/* refresh rate 15.6 us (= 64 ms / 4K = 62.4 / quad bursts) for <= 128 MBit	*/
+#define CFG_MPTPR_2BK_4K	MPTPR_PTP_DIV16		/* setting for 2 banks	*/
+#define CFG_MPTPR_1BK_4K	MPTPR_PTP_DIV32		/* setting for 1 bank	*/
+
+/* refresh rate 7.8 us (= 64 ms / 8K = 31.2 / quad bursts) for 256 MBit		*/
+#define CFG_MPTPR_2BK_8K	MPTPR_PTP_DIV8		/* setting for 2 banks	*/
+#define CFG_MPTPR_1BK_8K	MPTPR_PTP_DIV16		/* setting for 1 bank	*/
+
+/*
+ * MAMR settings for SDRAM
+ */
+
+/* 8 column SDRAM */
+#define CFG_MAMR_8COL	((CFG_MAMR_PTA << MAMR_PTA_SHIFT)  | MAMR_PTAE	    |	\
+			 MAMR_AMA_TYPE_0 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A11 |	\
+			 MAMR_RLFA_1X	 | MAMR_WLFA_1X	   | MAMR_TLFA_4X)
+/* 9 column SDRAM */
+#define CFG_MAMR_9COL	((CFG_MAMR_PTA << MAMR_PTA_SHIFT)  | MAMR_PTAE	    |	\
+			 MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A10 |	\
+			 MAMR_RLFA_1X	 | MAMR_WLFA_1X	   | MAMR_TLFA_4X)
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define	BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/CPCI405.h b/include/configs/CPCI405.h
new file mode 100644
index 0000000..6b98347
--- /dev/null
+++ b/include/configs/CPCI405.h
@@ -0,0 +1,333 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family   */
+#define CONFIG_CPCI405		1	/* ...on a CPCI405 board	*/
+
+#define CONFIG_BOARD_PRE_INIT   1       /* call board_pre_init()        */
+
+#define CONFIG_SYS_CLK_FREQ     33000000 /* external frequency to pll   */
+
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/
+
+#if 0
+#define CONFIG_PREBOOT                                                          \
+        "crc32 f0207004 ffc 0;"                                                 \
+        "if cmp 0 f0207000 1;"                                                  \
+        "then;echo Old CRC is correct;crc32 f0207004 ff4 f0207000;"             \
+        "else;echo Old CRC is bad;fi"
+#endif
+
+#undef	CONFIG_BOOTARGS
+#define CONFIG_RAMBOOTCOMMAND							\
+	"setenv bootargs root=/dev/ram rw nfsroot=$(serverip):$(rootpath) "	\
+	"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;"	\
+	"bootm ffc00000 ffca0000"
+#define CONFIG_NFSBOOTCOMMAND							\
+	"setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) "	\
+	"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;"	\
+	"bootm ffc00000"
+#define CONFIG_BOOTCOMMAND CONFIG_RAMBOOTCOMMAND
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define	CONFIG_PHY_ADDR		0	/* PHY address			*/
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_IDE	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_EEPROM  )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef  CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+#define	CONFIG_SDRAM_BANK0	1	/* init onboard SDRAM bank 0	*/
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP			/* undef to save memory		*/
+#define CFG_PROMPT	"=> "		/* Monitor Command Prompt	*/
+
+#undef	CFG_HUSH_PARSER			/* use "hush" command parser	*/
+#ifdef	CFG_HUSH_PARSER
+#define	CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+#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_DEVICE_NULLDEV      1       /* include nulldev device       */
+
+#define CFG_CONSOLE_INFO_QUIET  1       /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59   /* ignore ppc405gp errata #59   */
+#define CFG_BASE_BAUD       691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR	0x100000	/* default load address */
+#define CFG_EXTBDINFO	1		/* To use extended board_into (bd_t) */
+
+#define	CFG_HZ		1000		/* decrementer freq: 1 ms ticks	*/
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure as pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support	        */
+#define CONFIG_PCI_HOST	PCI_HOST_AUTO   /* select pci host function     */
+#define CONFIG_PCI_PNP			/* do pci plug-and-play         */
+                                        /* resource configuration       */
+
+#define CONFIG_PCI_SCAN_SHOW            /* print pci devices @ startup  */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE  /* PCI Vendor ID: esd gmbh      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0405  /* PCI Device ID: CPCI-405      */
+#define CFG_PCI_SUBSYS_DEVICEID2 0x0406 /* PCI Device ID: CPCI-405-A    */
+#define CFG_PCI_CLASSCODE       0x0b20  /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0xfc000001      /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+#define CFG_PCI_PTM2LA  0xffc00000      /* point to flash               */
+#define CFG_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ *-----------------------------------------------------------------------
+ */
+#undef  CONFIG_IDE_8xx_DIRECT               /* no pcmcia interface required */
+#undef  CONFIG_IDE_LED                  /* no led for ide supported     */
+#undef  CONFIG_IDE_RESET                /* no reset for ide supported   */
+
+#define	CFG_IDE_MAXBUS	        1		/* max. 1 IDE busses	*/
+#define	CFG_IDE_MAXDEVICE	(CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */
+
+#define	CFG_ATA_BASE_ADDR	0xF0100000
+#define	CFG_ATA_IDE0_OFFSET	0x0000
+
+#define CFG_ATA_DATA_OFFSET	0x0000	/* Offset for data I/O			*/
+#define	CFG_ATA_REG_OFFSET	0x0000	/* Offset for normal register accesses	*/
+#define CFG_ATA_ALT_OFFSET	0x0000	/* Offset for alternate registers	*/
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFFD0000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(192 * 1024)	/* Reserve 196 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */
+#define CFG_FLASH_ADDR0         0x5555  /* 1st address for flash config cycles  */
+#define CFG_FLASH_ADDR1         0x2AAA  /* 2nd address for flash config cycles  */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */
+#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */
+#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */
+
+#define CFG_FLASH_EMPTY_INFO            /* print 'E' for empty sector on flinfo */
+
+#if 1 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM	1	/* use NVRAM for environment vars	*/
+#define CFG_NVRAM_BASE_ADDR	0xf0200000		/* NVRAM base address	*/
+#define CFG_NVRAM_SIZE		(32*1024)		/* NVRAM size		*/
+#define CFG_ENV_SIZE		0x1000		/* Size of Environment vars	*/
+#define CFG_ENV_ADDR		\
+	(CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE)	/* Env	*/
+#define CFG_NVRAM_VXWORKS_OFFS	0x6900		/* Offset for VxWorks eth-addr	*/
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x200   /* 512 bytes may be used for env vars */
+                                   /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x50	/* EEPROM CAT28WC08		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1	/* Bytes of address		*/
+/* mask of address bits that overflow into the "EEPROM chip address"    */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW	0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4	/* The Catalyst CAT24WC08 has	*/
+					/* 16 byte page write mode using*/
+					/* last	4 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0xFF800000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0xFFC00000	/* FLASH bank #1	*/
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization                                  */
+#define CFG_EBC_PB0AP           0x92015480
+#define CFG_EBC_PB0CR           0xFFC5A000  /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization                                  */
+#define CFG_EBC_PB1AP           0x92015480
+#define CFG_EBC_PB1CR           0xFF85A000  /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (CAN0, 1, 2, Codeswitch) initialization                        */
+#define CFG_EBC_PB2AP           0x010053C0  /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR           0xF0018000  /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 3 (CompactFlash IDE) initialization                              */
+#define CFG_EBC_PB3AP           0x010053C0  /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR           0xF011A000  /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 4 (NVRAM) initialization                                         */
+#define CFG_EBC_PB4AP           0x01005280  /* TWT=2,WBN=1,WBF=1,TH=1,SOR=1     */
+#define CFG_EBC_PB4CR           0xF0218000  /* BAS=0xF02,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 5 (Quart) initialization                                         */
+#define CFG_EBC_PB5AP           0x04005B80  /* TWT=8,WBN=1,WBF=1,TH=5,RE=1,SOR=1*/
+#define CFG_EBC_PB5CR           0xF0318000  /* BAS=0xF03,BS=1MB,BU=R/W,BW=8bit  */
+
+/*-----------------------------------------------------------------------
+ * FPGA stuff
+ */
+
+/* FPGA program pin configuration */
+#define CFG_FPGA_PRG            0x04000000  /* FPGA program pin (ppc output) */
+#define CFG_FPGA_CLK            0x02000000  /* FPGA clk pin (ppc output)     */
+#define CFG_FPGA_DATA           0x01000000  /* FPGA data pin (ppc output)    */
+#define CFG_FPGA_INIT           0x00400000  /* FPGA init pin (ppc input)     */
+#define CFG_FPGA_DONE           0x00800000  /* FPGA done pin (ppc input)     */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in data cache)
+ */
+#if 1 /* test-only */
+#define CFG_INIT_DCACHE_CS      7       /* use cs # 7 for data cache memory    */
+
+#define CFG_INIT_RAM_ADDR       0x40000000  /* use data cache                  */
+#else
+#define CFG_INIT_RAM_ADDR	0x00df0000 /* inside of SDRAM                   */
+#endif
+#define CFG_INIT_RAM_END        0x2000  /* End of used area in RAM             */
+#define CFG_GBL_DATA_SIZE      128  /* 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
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/CPCI4052.h b/include/configs/CPCI4052.h
new file mode 100644
index 0000000..0533827
--- /dev/null
+++ b/include/configs/CPCI4052.h
@@ -0,0 +1,378 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family   */
+#define CONFIG_CPCI405		1	/* ...on a CPCI405 board	*/
+#define CONFIG_CPCI405_VER2     1       /* ...version 2                 */
+
+#define CONFIG_BOARD_PRE_INIT   1       /* call board_pre_init()        */
+
+#define CONFIG_SYS_CLK_FREQ     33333333 /* external frequency to pll   */
+
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/
+
+#if 0
+#define CONFIG_PREBOOT                                                          \
+        "crc32 f0207004 ffc 0;"                                                 \
+        "if cmp 0 f0207000 1;"                                                  \
+        "then;echo Old CRC is correct;crc32 f0207004 ff4 f0207000;"             \
+        "else;echo Old CRC is bad;fi"
+#endif
+
+#undef	CONFIG_BOOTARGS
+#define CONFIG_RAMBOOTCOMMAND							\
+	"setenv bootargs root=/dev/ram rw nfsroot=$(serverip):$(rootpath) "	\
+	"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;"	\
+	"bootm ffc00000 ffca0000"
+#define CONFIG_NFSBOOTCOMMAND							\
+	"setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) "	\
+	"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;"	\
+	"bootm ffc00000"
+#define CONFIG_BOOTCOMMAND CONFIG_RAMBOOTCOMMAND
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define	CONFIG_PHY_ADDR		0	/* PHY address			*/
+
+#define CONFIG_RTC_M48T35A	1		/* ST Electronics M48 timekeeper */
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_IDE	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_DATE	| \
+				CFG_CMD_JFFS2	| \
+				CFG_CMD_I2C	| \
+				CFG_CMD_EEPROM  )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef  CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+#define	CONFIG_SDRAM_BANK0	1	/* init onboard SDRAM bank 0	*/
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP			/* undef to save memory		*/
+#define CFG_PROMPT	"=> "		/* Monitor Command Prompt	*/
+
+#undef	CFG_HUSH_PARSER			/* use "hush" command parser	*/
+#ifdef	CFG_HUSH_PARSER
+#define	CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+#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_DEVICE_NULLDEV      1       /* include nulldev device       */
+
+#define CFG_CONSOLE_INFO_QUIET  1       /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59   /* ignore ppc405gp errata #59   */
+#define CFG_BASE_BAUD       691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR	0x100000	/* default load address */
+#define CFG_EXTBDINFO	1		/* To use extended board_into (bd_t) */
+
+#define	CFG_HZ		1000		/* decrementer freq: 1 ms ticks	*/
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure as pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support	        */
+#define CONFIG_PCI_HOST	PCI_HOST_AUTO   /* select pci host function     */
+#define CONFIG_PCI_PNP			/* do pci plug-and-play         */
+                                        /* resource configuration       */
+
+#define CONFIG_PCI_SCAN_SHOW            /* print pci devices @ startup  */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE  /* PCI Vendor ID: esd gmbh      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0405  /* PCI Device ID: CPCI-405      */
+#define CFG_PCI_SUBSYS_DEVICEID2 0x0406 /* PCI Device ID: CPCI-405-A    */
+#define CFG_PCI_CLASSCODE       0x0b20  /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0xfc000001      /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+#define CFG_PCI_PTM2LA  0xffc00000      /* point to flash               */
+#define CFG_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ *-----------------------------------------------------------------------
+ */
+#undef  CONFIG_IDE_8xx_DIRECT               /* no pcmcia interface required */
+#undef  CONFIG_IDE_LED                  /* no led for ide supported     */
+#define CONFIG_IDE_RESET	1	/* reset for ide supported	*/
+
+#define	CFG_IDE_MAXBUS	        1		/* max. 1 IDE busses	*/
+#define	CFG_IDE_MAXDEVICE	(CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */
+
+#define	CFG_ATA_BASE_ADDR	0xF0100000
+#define	CFG_ATA_IDE0_OFFSET	0x0000
+
+#define CFG_ATA_DATA_OFFSET	0x0000	/* Offset for data I/O			*/
+#define	CFG_ATA_REG_OFFSET	0x0000	/* Offset for normal register accesses	*/
+#define CFG_ATA_ALT_OFFSET	0x0000	/* Offset for alternate registers	*/
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFFC0000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(256 * 1024)	/* Reserve 256 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */
+#define CFG_FLASH_ADDR0         0x5555  /* 1st address for flash config cycles  */
+#define CFG_FLASH_ADDR1         0x2AAA  /* 2nd address for flash config cycles  */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */
+#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */
+#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */
+
+#define CFG_FLASH_EMPTY_INFO            /* print 'E' for empty sector on flinfo */
+
+#define CFG_JFFS2_FIRST_BANK    0           /* use for JFFS2 */
+#define CFG_JFFS2_NUM_BANKS     1           /* ! second bank contains U-Boot */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM	1	/* use NVRAM for environment vars	*/
+#define CFG_ENV_SIZE		0x0ff8		/* Size of Environment vars	*/
+#define CFG_ENV_ADDR		\
+	(CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-(CFG_ENV_SIZE+8))	/* Env	*/
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x800   /* 2048 bytes may be used for env vars*/
+                                   /* total size of a CAT24WC16 is 2048 bytes */
+#endif
+
+#define CFG_NVRAM_BASE_ADDR	0xf0200000		/* NVRAM base address	*/
+#define CFG_NVRAM_SIZE		(32*1024)		/* NVRAM size		*/
+#define CFG_NVRAM_VXWORKS_OFFS	0x6900		/* Offset for VxWorks eth-addr	*/
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC16) for environment
+ */
+#define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x50	/* EEPROM CAT28WC08		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1	/* Bytes of address		*/
+/* mask of address bits that overflow into the "EEPROM chip address"    */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW	0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4	/* The Catalyst CAT24WC08 has	*/
+					/* 16 byte page write mode using*/
+					/* last	4 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		16384	/* For IBM 405 CPUs, older 405 ppc's    */
+                                        /* have only 8kB, 16kB is save here     */
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0xFF800000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0xFFC00000	/* FLASH bank #1	*/
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization                                  */
+#define CFG_EBC_PB0AP           0x92015480
+#define CFG_EBC_PB0CR           0xFFC5A000  /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization                                  */
+#define CFG_EBC_PB1AP           0x92015480
+#define CFG_EBC_PB1CR           0xFF85A000  /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (CAN0, 1) initialization                                       */
+#define CFG_EBC_PB2AP           0x010053C0  /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR           0xF0018000  /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 3 (CompactFlash IDE) initialization                              */
+#define CFG_EBC_PB3AP           0x010053C0  /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR           0xF011A000  /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 4 (NVRAM/RTC) initialization                                     */
+#define CFG_EBC_PB4AP           0x01005280  /* TWT=2,WBN=1,WBF=1,TH=1,SOR=1     */
+#define CFG_EBC_PB4CR           0xF0218000  /* BAS=0xF02,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 5 (optional Quart) initialization                                */
+#define CFG_EBC_PB5AP           0x04005B80  /* TWT=8,WBN=1,WBF=1,TH=5,RE=1,SOR=1*/
+#define CFG_EBC_PB5CR           0xF0318000  /* BAS=0xF03,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 6 (FPGA internal) initialization                                 */
+#define CFG_EBC_PB6AP           0x010053C0  /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB6CR           0xF041A000  /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+#define CFG_FPGA_BASE_ADDR      0xF0400000
+
+/*-----------------------------------------------------------------------
+ * FPGA stuff
+ */
+/* FPGA internal regs */
+#define CFG_FPGA_MODE           0x00
+#define CFG_FPGA_STATUS         0x02
+#define CFG_FPGA_TS             0x04
+#define CFG_FPGA_TS_LOW         0x06
+#define CFG_FPGA_TS_CAP0        0x10
+#define CFG_FPGA_TS_CAP0_LOW    0x12
+#define CFG_FPGA_TS_CAP1        0x14
+#define CFG_FPGA_TS_CAP1_LOW    0x16
+#define CFG_FPGA_TS_CAP2        0x18
+#define CFG_FPGA_TS_CAP2_LOW    0x1a
+#define CFG_FPGA_TS_CAP3        0x1c
+#define CFG_FPGA_TS_CAP3_LOW    0x1e
+
+/* FPGA Mode Reg */
+#define CFG_FPGA_MODE_CF_RESET  0x0001
+#define CFG_FPGA_MODE_TS_IRQ_ENABLE 0x0100
+#define CFG_FPGA_MODE_TS_IRQ_CLEAR  0x1000
+#define CFG_FPGA_MODE_TS_CLEAR  0x2000
+
+/* FPGA Status Reg */
+#define CFG_FPGA_STATUS_DIP0    0x0001
+#define CFG_FPGA_STATUS_DIP1    0x0002
+#define CFG_FPGA_STATUS_DIP2    0x0004
+#define CFG_FPGA_STATUS_FLASH   0x0008
+#define CFG_FPGA_STATUS_TS_IRQ  0x1000
+
+#define CFG_FPGA_SPARTAN2       1           /* using Xilinx Spartan 2 now    */
+#define CFG_FPGA_MAX_SIZE       32*1024     /* 32kByte is enough for XC2S15  */
+
+/* FPGA program pin configuration */
+#define CFG_FPGA_PRG            0x04000000  /* FPGA program pin (ppc output) */
+#define CFG_FPGA_CLK            0x02000000  /* FPGA clk pin (ppc output)     */
+#define CFG_FPGA_DATA           0x01000000  /* FPGA data pin (ppc output)    */
+#define CFG_FPGA_INIT           0x00010000  /* FPGA init pin (ppc input)     */
+#define CFG_FPGA_DONE           0x00008000  /* FPGA done pin (ppc input)     */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in data cache)
+ */
+#if 1 /* test-only */
+#define CFG_INIT_DCACHE_CS      7       /* use cs # 7 for data cache memory    */
+
+#define CFG_INIT_RAM_ADDR       0x40000000  /* use data cache                  */
+#else
+#define CFG_INIT_RAM_ADDR	0x00df0000 /* inside of SDRAM                   */
+#endif
+#define CFG_INIT_RAM_END        0x2000  /* End of used area in RAM             */
+#define CFG_GBL_DATA_SIZE      128  /* 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
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/CPCIISER4.h b/include/configs/CPCIISER4.h
new file mode 100644
index 0000000..6c8d7f6
--- /dev/null
+++ b/include/configs/CPCIISER4.h
@@ -0,0 +1,241 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family   */
+#define CONFIG_CPCIISER4	1	/* ...on a CPCIISER4 board	*/
+
+#define CONFIG_BOARD_PRE_INIT   1       /* call board_pre_init()        */
+
+#define CONFIG_SYS_CLK_FREQ     25000000 /* external frequency to pll   */
+
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/
+
+#undef	CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND	"bootm fff00000"
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define	CONFIG_PHY_ADDR		0	/* PHY address			*/
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_EEPROM  )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+#define	CONFIG_SDRAM_BANK0	1	/* init onboard SDRAM bank 0	*/
+
+/*
+ * 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_CONSOLE_INFO_QUIET  1       /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#define CFG_EXT_SERIAL_CLOCK    1843200  /* use external serial clock   */
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR	0x100000	/* default load address */
+#define CFG_EXTBDINFO	1		/* To use extended board_into (bd_t) */
+
+#define	CFG_HZ		1000		/* decrementer freq: 1 ms ticks	*/
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure ar pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support	        */
+#define CONFIG_PCI_HOST	PCI_HOST_AUTO   /* select pci host function     */
+#define CONFIG_PCI_PNP			/* do pci plug-and-play         */
+                                        /* resource configuration       */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE  /* PCI Vendor ID: esd gmbh      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0404  /* PCI Device ID: CPCI-ISER4    */
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0xff000001      /* 16MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+#define CFG_PCI_PTM2LA  0xffe00000      /* point to flash               */
+#define CFG_PCI_PTM2MS  0xffe00001      /* 2MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFFC0000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(256 * 1024)	/* Reserve 256 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */
+#define CFG_FLASH_ADDR0         0x5555  /* 1st address for flash config cycles  */
+#define CFG_FLASH_ADDR1         0x2AAA  /* 2nd address for flash config cycles  */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */
+#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */
+#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */
+
+#define CFG_FLASH_EMPTY_INFO            /* print 'E' for empty sector on flinfo */
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C			/* I2C with hardware support */
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x50	/* EEPROM CAT28WC08		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1	/* Bytes of address		*/
+/* mask of address bits that overflow into the "EEPROM chip address"    */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW	0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4	/* The Catalyst CAT24WC08 has	*/
+					/* 16 byte page write mode using*/
+					/* last	4 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x300   /* 768 bytes may be used for env vars */
+                                   /* total size of a CAT24WC08 is 1024 bytes */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0xFFF00000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0		/* FLASH bank #1	*/
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization                                  */
+#define CFG_EBC_PB0AP           0x92015480
+#define CFG_EBC_PB0CR           0xFFC5A000  /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Uart 8bit) initialization                                     */
+#define CFG_EBC_PB1AP           0x01000480  /* TWT=2,TH=2,no Ready,BEM=0,SOR=1  */
+#define CFG_EBC_PB1CR           0xF0018000  /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 2 (Uart 32bit) initialization                                    */
+#define CFG_EBC_PB2AP           0x000004c0  /* no Ready, BEM=1                  */
+#define CFG_EBC_PB2CR           0xF011C000  /* BAS=0xF01,BS=1MB,BU=R/W,BW=32bit */
+
+/* Memory Bank 3 (FPGA Reset) initialization                                    */
+#define CFG_EBC_PB3AP           0x010004C0  /* no Ready, BEM=1                  */
+#define CFG_EBC_PB3CR           0xF021A000  /* BAS=0xF02,BS=1MB,BU=R/W,BW=16bit */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR	0x00df0000 /* inside of SDRAM                   */
+#define CFG_INIT_RAM_END	0x0f00	/* End of used area in RAM	       */
+#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
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/CRAYL1.h b/include/configs/CRAYL1.h
new file mode 100644
index 0000000..b10d967
--- /dev/null
+++ b/include/configs/CRAYL1.h
@@ -0,0 +1,251 @@
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * David Updegraff, Cray, Inc.  dave@cray.com: our 405 is walnut-lite..
+ *
+ * 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
+
+#define CONFIG_CRAYL1
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU	*/
+#define CONFIG_4xx		    1   /* ...member of PPC405 family */
+#define CONFIG_SYS_CLK_FREQ 25000000
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds	*/
+#define CONFIG_MII		    1	/* MII PHY management */
+#define	CONFIG_PHY_ADDR		1	/* PHY address; handling of ENET */
+#define CONFIG_BOARD_PRE_INIT 1 /* setup for 405gp */
+#define CONFIG_MISC_INIT_R	1	/* so that a misc_init_r() is called */
+
+/* set PRAM to keep U-Boot out, mem= to keep linux out, and initrd_hi to
+ * keep possible initrd ramdisk decompression out.  This is in k (1024 bytes)
+ #define CONFIG_PRAM			16
+ */
+#define	CONFIG_LOADADDR		0x100000
+#undef CONFIG_BOOTARGS
+
+/* the logic is that booting is driven by what env vars get set from DHCP.
+ * Normal DHCP sets things like serverip, rootpath, etc.
+ * if printenv
+ */
+#define	CFG_AUTOLOAD		"yes"
+#define CONFIG_BOOTCOMMAND	"dhcp;"\
+	"setenv bootargs devfs=mount;"\
+	"setenv bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:::off $bootargs;"\
+	"if printenv initrd;"\
+	"then;" \
+	 "setenv initrd_hi $mem;"\
+	 "tftp 1000000 $initrd;"\
+	 "setenv bootargs root=/dev/ram0 rw cwsroot=$serverip:$rootpath $bootargs;"\
+	 "bootm 100000 1000000;"\
+	"else;"\
+	 "setenv bootargs root=/dev/nfs ro nfsroot=$serverip:$rootpath $bootargs;"\
+	 "bootm 100000;"\
+	"fi;"
+
+#define CONFIG_EXTRA_ENV_SETTINGS ""
+
+/*
+ * ..during experiments..
+ #define CONFIG_SERVERIP         10.0.0.1
+ #define CONFIG_ETHADDR          00:40:a6:80:14:5
+ */
+#define CONFIG_HARD_I2C         1		/* hardware support for i2c */
+#define CFG_I2C_SPEED		    400000	/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		    0x7F
+#define CFG_I2C_EEPROM_ADDR     0x57
+#define CFG_I2C_EEPROM_ADDR_LEN 1
+#define CONFIG_IDENT_STRING     "Cray L1"
+#define CONFIG_ENV_OVERWRITE     1
+#define	CFG_HZ		             1000	/* decrementer freq: 1 ms ticks	*/
+#define CFG_HUSH_PARSER			1
+#define CFG_PROMPT_HUSH_PS2		"> "
+
+
+#define CONFIG_COMMANDS	 (\
+	CFG_CMD_BDI|\
+	CFG_CMD_IMI|\
+	CFG_CMD_FLASH|\
+	CFG_CMD_MEMORY|\
+	CFG_CMD_NET|\
+	CFG_CMD_ENV|\
+	CFG_CMD_CONSOLE|\
+	CFG_CMD_ASKENV|\
+	CFG_CMD_ECHO|\
+	CFG_CMD_IMMAP|\
+	CFG_CMD_REGINFO|\
+	CFG_CMD_DHCP|\
+	CFG_CMD_DATE|\
+	CFG_CMD_RUN|\
+	CFG_CMD_I2C|\
+	CFG_CMD_EEPROM|\
+	CFG_CMD_SETGETDCR)
+
+/*
+ * optional BOOTP / DHCP fields
+ */
+#define CONFIG_BOOTP_MASK (\
+	CONFIG_BOOTP_VENDOREX|\
+	CONFIG_BOOTP_SUBNETMASK|\
+	CONFIG_BOOTP_GATEWAY|\
+	CONFIG_BOOTP_DNS|\
+	CONFIG_BOOTP_HOSTNAME|\
+	CONFIG_BOOTP_BOOTFILESIZE|\
+	CONFIG_BOOTP_BOOTPATH)
+
+/*
+ * bauds.  Just to make it compile; in our case, I read the base_baud
+ * from the DCR anyway, so its kinda-tied to the above ref. clock which in turn
+ * drives the system clock.
+ */
+#define CFG_BASE_BAUD       403225
+#define CFG_BAUDRATE_TABLE  \
+    {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_PROMPT	"=> "			/* Monitor Command Prompt	*/
+#define	CFG_CBSIZE	256				/* Console I/O Buffer Size	*/
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS	16				/* max number of command args	*/
+
+
+#define CFG_LOAD_ADDR   	0x100000/* where to load what we get from TFTP */
+#define CFG_TFTP_LOADADDR	CFG_LOAD_ADDR
+#define CFG_EXTBDINFO		1	/* To use extended board_into (bd_t) */
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFC00000
+#define CFG_MONITOR_BASE	TEXT_BASE
+
+#ifndef  CFG_HUSH_PARSER
+#define CFG_MONITOR_LEN		(128 * 1024)	/* Reserve 128 kB for Monitor	*/
+#define CFG_ENV_OFFSET		0x3D0000
+#else
+#define CFG_MONITOR_LEN		(192 * 1024)	/* Reserve 192 kB for Monitor	*/
+#define CFG_ENV_OFFSET		0x3FE000
+#endif
+
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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		*/
+#define CFG_MAX_FLASH_SECT	 64		/* 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)	*/
+
+/* BEG ENVIRONNEMENT FLASH: needs to be a whole FlashSector  */
+#define CFG_ENV_IS_IN_FLASH	1	/* use FLASH for environment vars */
+#define	CFG_ENV_SIZE		0x1000	 /* Total Size of Environment Sector	*/
+#define CFG_ENV_SECT_SIZE	0x10000	 /* see README - env sector total size	*/
+
+/* Memory tests: U-Boot relocates itself to the top of Ram, so its at
+ * 32meg-(128k+some_malloc_space+copy-of-ENV sector)..
+ */
+#define CFG_SDRAM_SIZE		32		/* megs of ram */
+#define CFG_MEMTEST_START	0x2000  /* memtest works from the end of */
+									/* the exception vector table */
+									/* to the end of the DRAM  */
+									/* less monitor and malloc area */
+#define CFG_STACK_USAGE		0x10000 /* Reserve 64k for the stack usage */
+#define CFG_MEM_END_USAGE	( CFG_MONITOR_LEN \
+                                + CFG_MALLOC_LEN \
+                                + CFG_ENV_SECT_SIZE \
+                                + CFG_STACK_USAGE )
+
+#define CFG_MEMTEST_END		(CFG_SDRAM_SIZE * 1024 * 1024 - CFG_MEM_END_USAGE)
+/* END ENVIRONNEMENT FLASH */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration.  Only used to ..?? clear it, I guess..
+ */
+#define CFG_DCACHE_SIZE		16384
+#define CFG_CACHELINE_SIZE	32
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	CFG_FLASH_BASE	/* FLASH bank #0	*/
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in OnChipMem )
+ */
+#if 0
+#define CFG_INIT_RAM_ADDR       0x40000000  /* use data cache               */
+#define CFG_INIT_RAM_END        0x2000  /* End of used area in RAM             */
+#else
+#define CFG_TEMP_STACK_OCM	1
+#define CFG_OCM_DATA_ADDR	0xF0000000
+#define CFG_OCM_DATA_SIZE	0x1000
+#define CFG_INIT_RAM_ADDR	CFG_OCM_DATA_ADDR 	/* inside of On Chip SRAM    */
+#define CFG_INIT_RAM_END	CFG_OCM_DATA_SIZE	/* End of On Chip SRAM	     */
+#endif
+
+#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
+
+/*-----------------------------------------------------------------------
+ * Definitions for Serial Presence Detect EEPROM address
+ */
+#define EEPROM_WRITE_ADDRESS 0xA0
+#define EEPROM_READ_ADDRESS  0xA1
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/CU824.h b/include/configs/CU824.h
new file mode 100644
index 0000000..ed38ef6
--- /dev/null
+++ b/include/configs/CU824.h
@@ -0,0 +1,305 @@
+/*
+ * (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
+ */
+
+/*
+ *
+ * Configuration settings for the CU824 board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X		1
+#define CONFIG_MPC8240		1
+#define CONFIG_CU824		1
+
+
+#define CONFIG_CONS_INDEX	1
+#define CONFIG_BAUDRATE		9600
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_CLOCKS_IN_MHZ	1	/* clocks passsed to Linux in MHz	*/
+
+#define CONFIG_PREBOOT	"echo;echo Type \"run flash_nfs\" to mount root filesystem over NFS;echo"
+
+#define CONFIG_BOOTCOMMAND	"bootm FE020000"	/* autoboot command	*/
+#define CONFIG_BOOTDELAY	5
+
+#define CONFIG_BOOTP_MASK	(CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_DHCP	| \
+				CFG_CMD_PCI	| \
+				0/* 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 memory		*/
+#define CFG_PROMPT	"=> "		/* Monitor Command Prompt	*/
+#define CFG_CBSIZE	256		/* Console I/O Buffer Size	*/
+
+#if 1
+#define	CFG_HUSH_PARSER		1	/* use "hush" command parser	*/
+#endif
+#ifdef	CFG_HUSH_PARSER
+#define	CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+/* Print Buffer Size
+ */
+#define CFG_PBSIZE	(CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+
+#define	CFG_MAXARGS	16		/* max number of command args	*/
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+#define CFG_LOAD_ADDR	0x00100000	/* Default load address		*/
+
+/*-----------------------------------------------------------------------
+ * 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	    0xFF000000
+
+#define CFG_RESET_ADDRESS   0xFFF00100
+
+#define CFG_EUMB_ADDR	    0xFCE00000
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+
+#define CFG_MONITOR_LEN	    (256 << 10) /* Reserve 256 kB for Monitor	*/
+#define CFG_MALLOC_LEN	    (128 << 10) /* Reserve 128 kB for malloc()	*/
+
+#define CFG_MEMTEST_START   0x00004000	/* memtest works on		*/
+#define CFG_MEMTEST_END	    0x02000000	/* 0 ... 32 MB in DRAM		*/
+
+	/* Maximum amount of RAM.
+	 */
+#define CFG_MAX_RAM_SIZE    0x10000000
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+
+	/* Size in bytes reserved for initial data
+	 */
+#define CFG_GBL_DATA_SIZE    128
+
+#define CFG_INIT_RAM_ADDR     0x40000000
+#define CFG_INIT_RAM_END      0x1000
+#define CFG_GBL_DATA_OFFSET  (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE	4
+
+#define CFG_NS16550_CLK		(14745600 / 2)
+
+#define CFG_NS16550_COM1	0xFE800080
+#define CFG_NS16550_COM2	0xFE8000C0
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ */
+
+#define CONFIG_SYS_CLK_FREQ  33000000
+#define CFG_HZ		     1000
+
+	/* Bit-field values for MCCR1.
+	 */
+#define CFG_ROMNAL	    0
+#define CFG_ROMFAL	    7
+
+	/* Bit-field values for MCCR2.
+	 */
+#define CFG_REFINT	    430	    /* Refresh interval			*/
+
+	/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.
+	 */
+#define CFG_BSTOPRE	    192
+
+	/* Bit-field values for MCCR3.
+	 */
+#define CFG_REFREC	    2	    /* Refresh to activate interval	*/
+#define CFG_RDLAT	    3	    /* Data latancy from read command	*/
+
+	/* Bit-field values for MCCR4.
+	 */
+#define CFG_PRETOACT	    2	    /* Precharge to activate interval	*/
+#define CFG_ACTTOPRE	    5	    /* Activate to Precharge interval	*/
+#define CFG_SDMODE_CAS_LAT  2	    /* SDMODE CAS latancy		*/
+#define CFG_SDMODE_WRAP	    0	    /* SDMODE wrap type			*/
+#define CFG_SDMODE_BURSTLEN 2	    /* SDMODE Burst length		*/
+#define CFG_ACTORW	    2
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these vales to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8240 book.
+ */
+
+#define CFG_BANK0_START	    0x00000000
+#define CFG_BANK0_END	    (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE    1
+#define CFG_BANK1_START	    0x3ff00000
+#define CFG_BANK1_END	    0x3fffffff
+#define CFG_BANK1_ENABLE    0
+#define CFG_BANK2_START	    0x3ff00000
+#define CFG_BANK2_END	    0x3fffffff
+#define CFG_BANK2_ENABLE    0
+#define CFG_BANK3_START	    0x3ff00000
+#define CFG_BANK3_END	    0x3fffffff
+#define CFG_BANK3_ENABLE    0
+#define CFG_BANK4_START	    0x3ff00000
+#define CFG_BANK4_END	    0x3fffffff
+#define CFG_BANK4_ENABLE    0
+#define CFG_BANK5_START	    0x3ff00000
+#define CFG_BANK5_END	    0x3fffffff
+#define CFG_BANK5_ENABLE    0
+#define CFG_BANK6_START	    0x3ff00000
+#define CFG_BANK6_END	    0x3fffffff
+#define CFG_BANK6_ENABLE    0
+#define CFG_BANK7_START	    0x3ff00000
+#define CFG_BANK7_END	    0x3fffffff
+#define CFG_BANK7_ENABLE    0
+
+#define CFG_ODCR	    0xff
+
+#define CFG_IBAT0L  (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U  (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L  (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U  (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+#define CFG_IBAT2L  (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U  (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT3L  (0xFC000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U  (0xFC000000 | BATU_BL_64M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L  CFG_IBAT0L
+#define CFG_DBAT0U  CFG_IBAT0U
+#define CFG_DBAT1L  CFG_IBAT1L
+#define CFG_DBAT1U  CFG_IBAT1U
+#define CFG_DBAT2L  CFG_IBAT2L
+#define CFG_DBAT2U  CFG_IBAT2U
+#define CFG_DBAT3L  CFG_IBAT3L
+#define CFG_DBAT3U  CFG_IBAT3U
+
+/*
+ * 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	2	/* Max number of flash banks		*/
+#define CFG_MAX_FLASH_SECT	39	/* Max number of sectors in one bank	*/
+
+#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
+#define CFG_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms)	*/
+
+	/* Warining: environment is not EMBEDDED in the U-Boot code.
+	 * It's stored in flash separately.
+	 */
+#define CFG_ENV_IS_IN_FLASH	    1
+#if 0
+#define CFG_ENV_ADDR		0xFF008000
+#define CFG_ENV_SIZE		0x8000	/* Size of the Environment Sector	*/
+#else
+#define CFG_ENV_ADDR		0xFFFC0000
+#define CFG_ENV_SIZE		0x4000	/* Size of the Environment		*/
+#define CFG_ENV_OFFSET		0	/* starting right at the beginning	*/
+#define CFG_ENV_SECT_SIZE	0x40000 /* Size of the Environment Sector	*/
+#endif
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM		0x02	/* Software reboot			*/
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI			/* include pci support			*/
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI		/* Multi ethernet cards support 	*/
+
+#define CONFIG_TULIP
+#define CONFIG_TULIP_USE_IO
+
+#define CFG_ETH_DEV_FN	     0x7800
+#define CFG_ETH_IOBASE	     0x00104000
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/DU405.h b/include/configs/DU405.h
new file mode 100644
index 0000000..1bf40d9
--- /dev/null
+++ b/include/configs/DU405.h
@@ -0,0 +1,303 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family   */
+#define CONFIG_DU405	        1	/* ...on a DU405 board	        */
+
+#define CONFIG_BOARD_PRE_INIT   1       /* call board_pre_init()        */
+
+#define CONFIG_SYS_CLK_FREQ     25000000 /* external frequency to pll   */
+
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/
+
+#undef	CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND	"bootm fff00000"
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define	CONFIG_PHY_ADDR		0	/* PHY address			*/
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_IDE	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_DATE	| \
+				CFG_CMD_EEPROM  )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+#define CONFIG_RTC_MC146818             /* BQ3285 is MC146818 compatible*/
+#define CFG_RTC_REG_BASE_ADDR	 0xF0000080 /* RTC Base Address         */
+
+#define	CONFIG_SDRAM_BANK0	1	/* init onboard SDRAM bank 0	*/
+
+/*
+ * 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_CONSOLE_INFO_QUIET  1       /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#define CFG_EXT_SERIAL_CLOCK    11059200  /* use external serial clock  */
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR	0x100000	/* default load address */
+#define CFG_EXTBDINFO	1		/* To use extended board_into (bd_t) */
+
+#define	CFG_HZ		1000		/* decrementer freq: 1 ms ticks	*/
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure ar pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support	        */
+#define CONFIG_PCI_HOST	PCI_HOST_AUTO   /* select pci host function     */
+#define CONFIG_PCI_PNP			/* do pci plug-and-play         */
+                                        /* resource configuration       */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE  /* PCI Vendor ID: esd gmbh      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0404  /* PCI Device ID: CPCI-ISER4    */
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0xff000001      /* 16MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+#define CFG_PCI_PTM2LA  0xffe00000      /* point to flash               */
+#define CFG_PCI_PTM2MS  0xffe00001      /* 2MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ *-----------------------------------------------------------------------
+ */
+#undef  CONFIG_IDE_8xx_DIRECT           /* no pcmcia interface required */
+#undef  CONFIG_IDE_LED                  /* no led for ide supported     */
+#undef  CONFIG_IDE_RESET                /* no reset for ide supported   */
+
+#define	CFG_IDE_MAXBUS	        1		/* max. 1 IDE busses	*/
+#define	CFG_IDE_MAXDEVICE	(CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */
+
+#define	CFG_ATA_BASE_ADDR	0xF0100000
+#define	CFG_ATA_IDE0_OFFSET	0x0000
+
+#define CFG_ATA_DATA_OFFSET	0x0000	/* Offset for data I/O			*/
+#define	CFG_ATA_REG_OFFSET	0x0000	/* Offset for normal register accesses	*/
+#define CFG_ATA_ALT_OFFSET	0x0000	/* Offset for alternate registers	*/
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFFD0000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(192 * 1024)	/* Reserve 192 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */
+#define CFG_FLASH_ADDR0         0x5555  /* 1st address for flash config cycles  */
+#define CFG_FLASH_ADDR1         0x2AAA  /* 2nd address for flash config cycles  */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */
+#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */
+#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */
+
+#define CFG_FLASH_EMPTY_INFO            /* print 'E' for empty sector on flinfo */
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x50	/* EEPROM CAT28WC08		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1	/* Bytes of address		*/
+/* mask of address bits that overflow into the "EEPROM chip address"    */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW	0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4	/* The Catalyst CAT24WC08 has	*/
+					/* 16 byte page write mode using*/
+					/* last	4 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x400   /* 1024 bytes may be used for env vars */
+                                   /* total size of a CAT24WC08 is 1024 bytes */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0xFF800000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0xFFC00000	/* FLASH bank #1	*/
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+#define FLASH0_BA       0xFFC00000          /* FLASH 0 Base Address             */
+#define FLASH1_BA       0xFF800000          /* FLASH 1 Base Address             */
+#define CAN_BA          0xF0000000          /* CAN Base Address                 */
+#define DUART_BA        0xF0300000          /* DUART Base Address               */
+#define CF_BA           0xF0100000          /* CompactFlash Base Address        */
+#define SRAM_BA         0xF0200000          /* SRAM Base Address                */
+#define DURAG_IO_BA     0xF0400000          /* DURAG Bus IO Base Address        */
+#define DURAG_MEM_BA    0xF0500000          /* DURAG Bus Mem Base Address       */
+
+#define FPGA_MODE_REG   (DUART_BA+0x80)     /* FPGA Mode Register               */
+
+/* Memory Bank 0 (Flash Bank 0) initialization                                  */
+#define CFG_EBC_PB0AP   0x92015480
+#define CFG_EBC_PB0CR   FLASH0_BA | 0x5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization                                  */
+#define CFG_EBC_PB1AP   0x92015480
+#define CFG_EBC_PB1CR   FLASH1_BA | 0x5A000 /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (CAN0) initialization                                          */
+#define CFG_EBC_PB2AP   0x010053C0   /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR   CAN_BA | 0x18000    /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 3 (DUART) initialization                                         */
+#define CFG_EBC_PB3AP   0x010053C0   /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR   DUART_BA | 0x18000  /* BAS=0xF03,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 4 (CompactFlash IDE) initialization                              */
+#define CFG_EBC_PB4AP   0x010053C0   /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB4CR   CF_BA | 0x1A000     /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 5 (SRAM) initialization                                          */
+#define CFG_EBC_PB5AP   0x010053C0   /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB5CR   SRAM_BA | 0x1A000   /* BAS=0xF02,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 6 (DURAG Bus IO Space) initialization                            */
+#define CFG_EBC_PB6AP   0x010053C0   /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB6CR   DURAG_IO_BA | 0x18000 /* BAS=0xF04,BS=1MB,BU=R/W,BW=8bit*/
+
+/* Memory Bank 7 (DURAG Bus Mem Space) initialization                           */
+#define CFG_EBC_PB7AP   0x010053C0   /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB7CR   DURAG_MEM_BA | 0x18000 /* BAS=0xF05,BS=1MB,BU=R/W,BW=8bit */
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+/* use on chip memory ( OCM ) for temperary stack until sdram is tested */
+#define CFG_TEMP_STACK_OCM        1
+
+/* On Chip Memory location */
+#define CFG_OCM_DATA_ADDR	0xF8000000
+#define CFG_OCM_DATA_SIZE	0x1000
+
+#define CFG_INIT_RAM_ADDR	CFG_OCM_DATA_ADDR /* inside of SDRAM		*/
+#define CFG_INIT_RAM_END	CFG_OCM_DATA_SIZE /* End of used area in RAM	*/
+#define CFG_GBL_DATA_SIZE      128  /* 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
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/EVB64260.h b/include/configs/EVB64260.h
new file mode 100644
index 0000000..fa7e1f6
--- /dev/null
+++ b/include/configs/EVB64260.h
@@ -0,0 +1,428 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
+#include "../board/evb64260/local.h"
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_EVB64260		1	/* this is an EVB64260 board	*/
+#define CFG_GT_6426x        GT_64260 /* with a 64260 system controller */
+
+#define CONFIG_BAUDRATE		38400 	/* console baudrate = 38400	*/
+
+#undef	CONFIG_ECC			/* enable ECC support */
+/* #define CONFIG_EVB64260_750CX  1 */      /* Support the EVB-64260-750CX Board */
+
+/* which initialization functions to call for this board */
+#define CONFIG_MISC_INIT_R	1
+#define CONFIG_BOARD_PRE_INIT	1
+
+#ifndef CONFIG_EVB64260_750CX
+#define CFG_BOARD_NAME		"EVB64260"
+#else
+#define CFG_BOARD_NAME         "EVB64260-750CX"
+#endif
+
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2	"> "
+
+/*
+ * The following defines let you select what serial you want to use
+ * for your console driver.
+ *
+ * what to do:
+ * to use the DUART, undef CONFIG_MPSC.  If you have hacked a serial
+ * cable onto the second DUART channel, change the CFG_DUART port from 1
+ * to 0 below.
+ *
+ * to use the MPSC, #define CONFIG_MPSC.  If you have wired up another
+ * mpsc channel, change CONFIG_MPSC_PORT to the desired value.
+ */
+#define	CONFIG_MPSC
+#define CONFIG_MPSC_PORT	0
+
+#define CONFIG_NET_MULTI        /* attempt all available adapters */
+
+/* define this if you want to enable GT MAC filtering */
+#define CONFIG_GT_USE_MAC_HASH_TABLE
+
+#undef CONFIG_ETHER_PORT_MII	/* use RMII */
+
+#if 1
+#define CONFIG_BOOTDELAY	-1	/* autoboot disabled		*/
+#else
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds	*/
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#undef	CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND						     \
+	"bootp && " 						     \
+	"setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath " \
+	"ip=$ipaddr:$serverip:$gatewayip:" \
+	"$netmask:$hostname:eth0:none; && " \
+	"bootm"
+
+#define CONFIG_LOADS_ECHO	0	/* echo off for serial download	*/
+#define	CFG_LOADS_BAUD_CHANGE		/* allow baudrate changes	*/
+
+#undef	CONFIG_WATCHDOG			/* watchdog disabled		*/
+#undef	CONFIG_ALTIVEC                  /* undef to disable             */
+
+#define CONFIG_BOOTP_MASK	(CONFIG_BOOTP_DEFAULT | \
+				 CONFIG_BOOTP_BOOTFILESIZE)
+
+
+#define CONFIG_COMMANDS	(CONFIG_CMD_DFL | CFG_CMD_ASKENV)
+
+/* 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	0x00400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x00C00000	/* 4 ... 12 MB in DRAM	*/
+
+#define	CFG_LOAD_ADDR		0x00300000	/* default load address	*/
+
+#define	CFG_HZ			1000		/* decr freq: 1ms ticks	*/
+#define CFG_BUS_HZ		100000000	/* 100 MHz		*/
+#define CFG_BUS_CLK		CFG_BUS_HZ
+
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+#ifdef CONFIG_EVB64260_750CX
+#define CONFIG_750CX
+#define CFG_BROKEN_CL2
+#endif
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_RAM_ADDR	0x40000000
+#define	CFG_INIT_RAM_END	0x1000
+#define	CFG_GBL_DATA_SIZE	128  /* size in bytes reserved for init data */
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_RAM_LOCK
+
+
+/*-----------------------------------------------------------------------
+ * 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		0xfff00000
+#define CFG_RESET_ADDRESS	0xfff00100
+#define	CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 kB for Monitor */
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define	CFG_MALLOC_LEN		(256 << 10)	/* Reserve 256 kB for malloc */
+
+/* areas to map different things with the GT in physical space */
+#define CFG_DRAM_BANKS		4
+#define CFG_DFL_GT_REGS		0x14000000	/* boot time GT_REGS */
+
+/* What to put in the bats. */
+#define CFG_MISC_REGION_BASE	0xf0000000
+
+/* Peripheral Device section */
+#define CFG_GT_REGS		0xf8000000
+#define CFG_DEV_BASE		0xfc000000
+
+#define CFG_DEV0_SPACE		CFG_DEV_BASE
+#define CFG_DEV1_SPACE		(CFG_DEV0_SPACE + CFG_DEV0_SIZE)
+#define CFG_DEV2_SPACE		(CFG_DEV1_SPACE + CFG_DEV1_SIZE)
+#define CFG_DEV3_SPACE		(CFG_DEV2_SPACE + CFG_DEV2_SIZE)
+
+#define CFG_DEV0_SIZE		 _8M /* evb64260 sram  @ 0xfc00.0000 */
+#define CFG_DEV1_SIZE		 _8M /* evb64260 rtc   @ 0xfc80.0000 */
+#define CFG_DEV2_SIZE		_16M /* evb64260 duart @ 0xfd00.0000 */
+#define CFG_DEV3_SIZE		_16M /* evb64260 flash @ 0xfe00.0000 */
+
+#define CFG_DEV0_PAR		0x20205093
+#define CFG_DEV1_PAR		0xcfcfffff
+#define CFG_DEV2_PAR		0xc0059bd4
+#define CFG_8BIT_BOOT_PAR	0xc00b5e7c
+#define CFG_32BIT_BOOT_PAR	0xc4a8241c
+        /*   c    4    a      8     2     4    1      c		*/
+        /* 33 22|2222|22 22|111 1|11 11|1 1  |    |		*/
+        /* 10 98|7654|32 10|987 6|54 32|1 098|7 654|3 210	*/
+        /* 11|00|0100|10 10|100|0 00|10 0|100 0|001 1|100	*/
+        /*  3| 0|.... ..| 2| 4 |  0 |  4 |  8  |  3  | 4	*/
+
+#if 0 /* Wrong?? NTL */
+#define CFG_MPP_CONTROL_0	0x53541717	/* InitAct EOT[4] DBurst TCEn[1] */
+						/* DMAAck[1:0] GNT0[1:0] */
+#else
+#define CFG_MPP_CONTROL_0	0x53547777	/* InitAct EOT[4] DBurst TCEn[1] */
+						/* REQ0[1:0] GNT0[1:0] */
+#endif
+#define CFG_MPP_CONTROL_1	0x44009911	/* TCEn[4] TCTcnt[4] GPP[13:12] */
+						/* DMAReq[4] DMAAck[4] WDNMI WDE */
+#if 0 /* Wrong?? NTL */
+#define CFG_MPP_CONTROL_2	0x40091818	/* TCTcnt[0] GPP[22:21] BClkIn */
+						/* DMAAck[1:0] GNT1[1:0] */
+#else
+#define CFG_MPP_CONTROL_2	0x40098888	/* TCTcnt[0] */
+						/* GPP[22] (RS232IntB or PCI1Int) */
+						/* GPP[21] (RS323IntA) */
+						/* BClkIn */
+						/* REQ1[1:0] GNT1[1:0] */
+#endif
+
+#if 0 /* Wrong?? NTL */
+# define CFG_MPP_CONTROL_3	0x00090066	/* GPP[31:29] BClkOut0 */
+						/* GPP[27:26] Int[1:0] */
+#else
+# define CFG_MPP_CONTROL_3	0x22090066      /* MREQ MGNT */
+                                                /* GPP[29]    (PCI1Int) */
+                                                /* BClkOut0 */
+                                                /* GPP[27]    (PCI0Int) */
+                                                /* GPP[26]    (RtcInt or PCI1Int) */
+                                                /* CPUInt[25:24] */
+#endif
+
+# define CFG_SERIAL_PORT_MUX	0x00000102	/* 0=hiZ  1=MPSC0 2=ETH 0 and 2 RMII */
+
+#if 0 /* Wrong?? - NTL */
+# define CFG_GPP_LEVEL_CONTROL	0x000002c6
+#else
+# define CFG_GPP_LEVEL_CONTROL	0x2c600000	/* 0010 1100 0110 0000 */
+                                                /* gpp[29] */
+						/* gpp[27:26] */
+                                                /* gpp[22:21] */
+
+# define CFG_SDRAM_CONFIG	0xd8e18200	/* 0x448 */
+				/* idmas use buffer 1,1
+				   comm use buffer 0
+				   pci use buffer 1,1
+				   cpu use buffer 0
+				   normal load (see also ifdef HVL)
+				   standard SDRAM (see also ifdef REG)
+				   non staggered refresh */
+				/* 31:26  25 23  20 19 18 16 */
+				/* 110110 00 111 0  0  00 1 */
+				/* refresh_count=0x200
+				   phisical interleaving disable
+				   virtual interleaving enable */
+				/* 15 14 13:0 */
+				/* 1  0  0x200 */
+#endif
+
+#define CFG_DUART_IO		CFG_DEV2_SPACE
+#define CFG_DUART_CHAN		1		/* channel to use for console */
+#define CFG_INIT_CHAN1
+#define CFG_INIT_CHAN2
+
+#define SRAM_BASE		CFG_DEV0_SPACE
+#define SRAM_SIZE		0x00100000		/* 1 MB of sram */
+
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+
+#define PCI_HOST_ADAPTER 0              /* configure ar pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI                      /* include pci support          */
+#define CONFIG_PCI_HOST PCI_HOST_FORCE  /* select pci host function     */
+#define CONFIG_PCI_PNP                  /* do pci plug-and-play         */
+
+/* PCI MEMORY MAP section */
+#define CFG_PCI0_MEM_BASE	0x80000000
+#define CFG_PCI0_MEM_SIZE	_128M
+#define CFG_PCI1_MEM_BASE	0x88000000
+#define CFG_PCI1_MEM_SIZE	_128M
+
+#define CFG_PCI0_0_MEM_SPACE	(CFG_PCI0_MEM_BASE)
+#define CFG_PCI1_0_MEM_SPACE	(CFG_PCI1_MEM_BASE)
+
+
+
+/* PCI I/O MAP section */
+#define CFG_PCI0_IO_BASE	0xfa000000
+#define CFG_PCI0_IO_SIZE	_16M
+#define CFG_PCI1_IO_BASE	0xfb000000
+#define CFG_PCI1_IO_SIZE	_16M
+
+#define CFG_PCI0_IO_SPACE	(CFG_PCI0_IO_BASE)
+#define CFG_PCI0_IO_SPACE_PCI	0x00000000
+#define CFG_PCI1_IO_SPACE	(CFG_PCI1_IO_BASE)
+#define CFG_PCI1_IO_SPACE_PCI	0x00000000
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+
+#define CFG_NS16550_REG_SIZE	-4
+
+#define CFG_NS16550_CLK		3686400
+
+#define CFG_NS16550_COM1	(CFG_DUART_IO + 0)
+#define CFG_NS16550_COM2	(CFG_DUART_IO + 0x20)
+
+/*----------------------------------------------------------------------
+ * Initial BAT mappings
+ */
+
+/* NOTES:
+ * 1) GUARDED and WRITE_THRU not allowed in IBATS
+ * 2) CACHEINHIBIT and WRITETHROUGH not allowed together in same BAT
+ */
+
+/* SDRAM */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT0U CFG_IBAT0U
+
+/* init ram */
+#define CFG_IBAT1L  (CFG_INIT_RAM_ADDR | BATL_PP_RW | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U  (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#define CFG_DBAT1L  CFG_IBAT1L
+#define CFG_DBAT1U  CFG_IBAT1U
+
+/* PCI0, PCI1 in one BAT */
+#define CFG_IBAT2L BATL_NO_ACCESS
+#define CFG_IBAT2U CFG_DBAT2U
+#define CFG_DBAT2L (CFG_PCI0_MEM_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT2U (CFG_PCI0_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* GT regs, bootrom, all the devices, PCI I/O */
+#define CFG_IBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW)
+#define CFG_IBAT3U (CFG_MISC_REGION_BASE | BATU_VS | BATU_VP | BATU_BL_256M)
+#define CFG_DBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT3U CFG_IBAT3U
+
+/* I2C speed and slave address (for compatability) defaults */
+#define CFG_I2C_SPEED	400000
+#define CFG_I2C_SLAVE	0x7F
+
+/* I2C addresses for the two DIMM SPD chips */
+#ifndef CONFIG_EVB64260_750CX
+#define DIMM0_I2C_ADDR	0x56
+#define DIMM1_I2C_ADDR	0x54
+#else /* CONFIG_EVB64260_750CX - only has 1 DIMM */
+#define DIMM0_I2C_ADDR  0x54
+#define DIMM1_I2C_ADDR	0x54
+#endif
+
+/*
+ * 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	2	/* max number of memory banks	*/
+#define CFG_MAX_FLASH_SECT	67	/* max number of sectors on one chip */
+
+#define CFG_EXTRA_FLASH_DEVICE	DEVICE3	/* extra flash at device 3 */
+#define CFG_EXTRA_FLASH_WIDTH	4	/* 32 bit */
+
+#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_FLASH_CFI		1
+
+#define	CFG_ENV_IS_IN_FLASH	1
+#define	CFG_ENV_SIZE		0x1000	/* Total Size of Environment Sector */
+#define CFG_ENV_SECT_SIZE	0x10000
+#define CFG_ENV_ADDR    (CFG_FLASH_BASE+CFG_MONITOR_LEN-CFG_ENV_SECT_SIZE)
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32	/* For all MPC74xx CPUs		 */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */
+#endif
+
+/*-----------------------------------------------------------------------
+ * L2CR setup -- make sure this is right for your board!
+ * look in include/mpc74xx.h for the defines used here
+ */
+
+#define CFG_L2
+
+#ifdef CONFIG_750CX
+#define L2_INIT 0
+#else
+#define L2_INIT  	(L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
+			L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
+#endif
+
+#define L2_ENABLE	(L2_INIT | L2CR_L2E)
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define	BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM	0x02		/* Software reboot		    */
+
+#define CFG_BOARD_ASM_INIT      1
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/MUSENKI.h b/include/configs/MUSENKI.h
new file mode 100644
index 0000000..03765a3
--- /dev/null
+++ b/include/configs/MUSENKI.h
@@ -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
+ */
+
+/*
+ *
+ * Configuration settings for the MUSENKI board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X		1
+#define CONFIG_MPC8245		1
+#define CONFIG_MUSENKI		1
+
+
+#define CONFIG_CONS_INDEX	1
+#define CONFIG_BAUDRATE		9600
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_BOOTDELAY	5
+
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) 	*/
+
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#undef CFG_LONGHELP			/* undef to save memory		*/
+#define CFG_PROMPT	"=> "		/* Monitor Command Prompt	*/
+#define CFG_CBSIZE	256		/* Console I/O Buffer Size	*/
+
+/* Print Buffer Size
+ */
+#define CFG_PBSIZE	(CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+#define CFG_MAXARGS	8		/* Max number of command args	*/
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+#define CFG_LOAD_ADDR	0x00100000	/* Default load address		*/
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI      		/* include pci support          */
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI		/* Multi ethernet cards support */
+
+#define CONFIG_TULIP
+
+#define PCI_ENET0_IOADDR		0x80000000
+#define PCI_ENET0_MEMADDR		0x80000000
+#define PCI_ENET1_IOADDR		0x81000000
+#define PCI_ENET1_MEMADDR		0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * 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_BASE0_PRELIM      0xFF800000      /* FLASH bank on RCS#0 */
+#define CFG_FLASH_BASE1_PRELIM      0xFF000000      /* FLASH bank on RCS#1 */
+#define CFG_FLASH_BASE  CFG_FLASH_BASE0_PRELIM
+
+/* even though FLASHP_BASE is FF800000, with 4MB is RCS0, the
+ * reset vector is actually located at FFB00100, but the 8245
+ * takes care of us.
+ */
+#define CFG_RESET_ADDRESS   0xFFF00100
+
+#define CFG_EUMB_ADDR	    0xFC000000
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#define CFG_MONITOR_LEN	    (256 << 10) /* Reserve 256 kB for Monitor	*/
+#define CFG_MALLOC_LEN	    (128 << 10) /* Reserve 128 kB for malloc()	*/
+
+#define CFG_MEMTEST_START   0x00004000	/* memtest works on		*/
+#define CFG_MEMTEST_END	    0x02000000	/* 0 ... 32 MB in DRAM		*/
+
+	/* Maximum amount of RAM.
+	 */
+#define CFG_MAX_RAM_SIZE    0x08000000	/* 0 .. 128 MB of (S)DRAM */
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE	1
+
+#define CFG_NS16550_CLK		get_bus_freq(0)
+
+#define CFG_NS16550_COM1	(CFG_EUMB_ADDR + 0x4500)
+#define CFG_NS16550_COM2	(CFG_EUMB_ADDR + 0x4600)
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+
+/* #define CFG_MONITOR_BASE        TEXT_BASE */
+/*#define CFG_GBL_DATA_SIZE    256*/
+#define CFG_GBL_DATA_SIZE      128
+#define CFG_INIT_RAM_ADDR     0x40000000
+#define CFG_INIT_RAM_END      0x1000
+#define CFG_GBL_DATA_OFFSET  (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ */
+
+#define CONFIG_SYS_CLK_FREQ  33333333	/* external frequency to pll */
+#define CFG_HZ		     1000
+
+	/* Bit-field values for MCCR1.
+	 */
+#define CFG_ROMNAL	    7
+#define CFG_ROMFAL	    11
+#define CFG_DBUS_SIZE       0x3
+
+	/* Bit-field values for MCCR2.
+	 */
+#define CFG_TSWAIT	    0x5		    /* Transaction Start Wait States timer */
+#define CFG_REFINT	    0x400	    /* Refresh interval	FIXME: was 0t430		*/
+
+	/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.
+	 */
+#define CFG_BSTOPRE	    121
+
+	/* Bit-field values for MCCR3.
+	 */
+#define CFG_REFREC	    8	    /* Refresh to activate interval */
+
+	/* Bit-field values for MCCR4.
+	 */
+#define CFG_PRETOACT	    3	    /* Precharge to activate interval FIXME: was 2	*/
+#define CFG_ACTTOPRE	    5	    /* Activate to Precharge interval FIXME: was 5	*/
+#define CFG_ACTORW	    3		/* FIXME was 2 */
+#define CFG_SDMODE_CAS_LAT  3	    /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP	    0	    /* SDMODE wrap type	*/
+#define CFG_REGISTERD_TYPE_BUFFER 1
+#define CFG_EXTROM	    1
+#define CFG_REGDIMM	    0
+
+#define CFG_PGMAX           0x32 /* how long the 8240 reatins the currently accessed page in memory FIXME: was 0x32*/
+
+#define CFG_SDRAM_DSCD	0x20	/* SDRAM data in sample clock delay - note bottom 3 bits MUST be 0 */
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these vales to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8240 book.
+ */
+
+#define CFG_BANK0_START	    0x00000000
+#define CFG_BANK0_END	    (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE    1
+#define CFG_BANK1_START	    0x3ff00000
+#define CFG_BANK1_END	    0x3fffffff
+#define CFG_BANK1_ENABLE    0
+#define CFG_BANK2_START	    0x3ff00000
+#define CFG_BANK2_END	    0x3fffffff
+#define CFG_BANK2_ENABLE    0
+#define CFG_BANK3_START	    0x3ff00000
+#define CFG_BANK3_END	    0x3fffffff
+#define CFG_BANK3_ENABLE    0
+#define CFG_BANK4_START	    0x3ff00000
+#define CFG_BANK4_END	    0x3fffffff
+#define CFG_BANK4_ENABLE    0
+#define CFG_BANK5_START	    0x3ff00000
+#define CFG_BANK5_END	    0x3fffffff
+#define CFG_BANK5_ENABLE    0
+#define CFG_BANK6_START	    0x3ff00000
+#define CFG_BANK6_END	    0x3fffffff
+#define CFG_BANK6_ENABLE    0
+#define CFG_BANK7_START	    0x3ff00000
+#define CFG_BANK7_END	    0x3fffffff
+#define CFG_BANK7_ENABLE    0
+
+#define CFG_ODCR	    0xff
+
+#define CFG_IBAT0L  (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U  (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L  (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U  (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+#define CFG_IBAT2L  (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U  (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT3L  (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U  (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L  CFG_IBAT0L
+#define CFG_DBAT0U  CFG_IBAT0U
+#define CFG_DBAT1L  CFG_IBAT1L
+#define CFG_DBAT1U  CFG_IBAT1U
+#define CFG_DBAT2L  CFG_IBAT2L
+#define CFG_DBAT2U  CFG_IBAT2U
+#define CFG_DBAT3L  CFG_IBAT3L
+#define CFG_DBAT3U  CFG_IBAT3U
+
+/*
+ * 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	2	/* Max number of flash banks		*/
+#define CFG_MAX_FLASH_SECT	64	/* Max number of sectors per flash	*/
+
+#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms) */
+
+
+	/* Warining: environment is not EMBEDDED in the U-Boot code.
+	 * It's stored in flash separately.
+	 */
+#define CFG_ENV_IS_IN_FLASH	    1
+#define CFG_ENV_ADDR		0xFFFF0000
+#define CFG_ENV_SIZE		0x00010000 /* Size of the Environment		*/
+#define CFG_ENV_SECT_SIZE	0x20000 /* Size of the Environment Sector	*/
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM		0x02	/* Software reboot			*/
+
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/MVS1.h b/include/configs/MVS1.h
new file mode 100644
index 0000000..d10fa8f
--- /dev/null
+++ b/include/configs/MVS1.h
@@ -0,0 +1,406 @@
+/*
+ * (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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC823		1	/* This is a MPC823 CPU		*/
+#define CONFIG_MVS		1	/* ...on a MVsensor module	*/
+#define CONFIG_MVS_16BIT_FLASH		/* ...with 16-bit flash access	*/
+#define CONFIG_8xx_GCLK_FREQ	50000000/* ... and a 50 MHz CPU		*/
+
+#define	CONFIG_CLOCKS_IN_MHZ	1	/* clocks passsed to Linux in MHz */
+
+#undef	CONFIG_8xx_CONS_SMC1		/* Console is *NOT* on SMC1	*/
+#define	CONFIG_8xx_CONS_SMC2	1	/* Console is on SMC2		*/
+#undef	CONFIG_8xx_CONS_NONE
+#define CONFIG_BAUDRATE		115200	/* console baudrate 		*/
+#define CONFIG_BOOTDELAY	5	/* autoboot after this many seconds	*/
+
+#define CONFIG_PREBOOT		"echo;echo To mount root over NFS use \"run bootnet\";echo To mount root from FLASH use  \"run bootflash\";echo"
+#define	CONFIG_BOOTARGS		"root=/dev/mtdblock2 rw"
+#define CONFIG_BOOTCOMMAND						\
+    "bootp; "                               				\
+    "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+    "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; "   \
+    "bootm"
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#undef	CFG_LOADS_BAUD_CHANGE		/* don't allow baudrate change	*/
+
+#define	CONFIG_WATCHDOG			/* watchdog disabled/enabled	*/
+
+#undef	CONFIG_STATUS_LED		/* Status LED disabled/enabled	*/
+
+#undef  CONFIG_CAN_DRIVER       /* CAN Driver support disabled  */
+
+#define CONFIG_BOOTP_MASK	(CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_VENDOREX )
+
+#undef CONFIG_MAC_PARTITION
+#undef CONFIG_DOS_PARTITION
+
+#define	CONFIG_RTC_MPC8xx		/* use internal RTC of MPC8xx	*/
+
+/* MVsensor uses a really minimal U-Boot ! */
+#define CONFIG_COMMANDS	       (CFG_CMD_LOADS	| \
+				CFG_CMD_LOADB	| \
+				CFG_CMD_IMI	| \
+				CFG_CMD_FLASH	| \
+				CFG_CMD_MEMORY	| \
+				CFG_CMD_NET	| \
+				CFG_CMD_DHCP	| \
+				CFG_CMD_ENV	| \
+				CFG_CMD_BOOTD	| \
+				CFG_CMD_RUN	)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#undef	CFG_LONGHELP			/* undef to save memory		*/
+#define	CFG_PROMPT		"=> "	/* Monitor Command Prompt	*/
+
+#undef  CFG_HUSH_PARSER			/* Hush parse for U-Boot ?? */
+#ifdef  CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2     "> "
+#endif
+
+#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	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#define	CFG_LOAD_ADDR		0x100000	/* default load address	*/
+
+#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		0xFFF00000
+
+/*-----------------------------------------------------------------------
+ * 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
+
+#define	CFG_MONITOR_LEN		(128 << 10)	/* Reserve 192 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		*/
+#define CFG_MAX_FLASH_SECT	71	/* max number of sectors on one chip (for AMD320DB 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
+
+/* 4MB flash - use bottom sectors of a bottom boot sector flash (16 bit access) */
+#define	CFG_ENV_OFFSET		0x8000	/* Offset of Environment Sector	(bottom boot sector) */
+#define	CFG_ENV_SIZE		0x2000	/* Used Size of Environment Sector 8k	*/
+
+/*-----------------------------------------------------------------------
+ * 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_TBF)
+
+/*-----------------------------------------------------------------------
+ * RTCSC - Real-Time Clock Status and Control Register		11-27
+ *-----------------------------------------------------------------------
+ */
+#define CFG_RTCSC	(RTCSC_SEC | RTCSC_ALR | RTCSC_RTF| RTCSC_RTE)
+
+/*-----------------------------------------------------------------------
+ * 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
+ *-----------------------------------------------------------------------
+ * Reset PLL lock status sticky bit, timer expired status bit and timer
+ * interrupt status bit
+ *
+ */
+#define CFG_PLPRCR	(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)
+
+/*-----------------------------------------------------------------------
+ * PCMCIA stuff
+ *-----------------------------------------------------------------------
+ *
+ */
+#define CFG_PCMCIA_MEM_ADDR	(0xE0000000)
+#define CFG_PCMCIA_MEM_SIZE	( 64 << 20 )
+#define CFG_PCMCIA_DMA_ADDR	(0xE4000000)
+#define CFG_PCMCIA_DMA_SIZE	( 64 << 20 )
+#define CFG_PCMCIA_ATTRB_ADDR	(0xE8000000)
+#define CFG_PCMCIA_ATTRB_SIZE	( 64 << 20 )
+#define CFG_PCMCIA_IO_ADDR	(0xEC000000)
+#define CFG_PCMCIA_IO_SIZE	( 64 << 20 )
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff (Supports IDE harddisk on PCMCIA Adapter)
+ *-----------------------------------------------------------------------
+ */
+
+#define	CONFIG_IDE_PCCARD	0	/* **DON'T** Use IDE with PC Card Adapter	*/
+
+#undef	CONFIG_IDE_PCMCIA		/* Direct IDE    not supported	*/
+#undef	CONFIG_IDE_LED			/* LED   for ide not supported	*/
+#undef	CONFIG_IDE_RESET		/* reset for ide not supported	*/
+
+#define CFG_IDE_MAXBUS		0	/* max. no. of IDE buses			*/
+#define CFG_IDE_MAXDEVICE	0	/* max. no. of drives per IDE bus	*/
+
+
+#define CFG_ATA_IDE0_OFFSET	0x0000
+
+#define CFG_ATA_BASE_ADDR	CFG_PCMCIA_MEM_ADDR
+
+/* Offset for data I/O			*/
+#define CFG_ATA_DATA_OFFSET	(CFG_PCMCIA_MEM_SIZE + 0x320)
+
+/* Offset for normal register accesses	*/
+#define CFG_ATA_REG_OFFSET	(2 * CFG_PCMCIA_MEM_SIZE + 0x320)
+
+/* Offset for alternate registers	*/
+#define CFG_ATA_ALT_OFFSET	0x0100
+
+/*-----------------------------------------------------------------------
+ *
+ *-----------------------------------------------------------------------
+ *
+ */
+/*#define	CFG_DER	0x2002000F*/
+#define CFG_DER	0
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0x40000000	/* FLASH bank #0	*/
+#undef FLASH_BASE1_PRELIM
+
+/* used to re-map FLASH both when starting from SRAM or FLASH:
+ * restrict access enough to keep SRAM working (if any)
+ * but not too much to meddle with FLASH accesses
+ */
+#define CFG_REMAP_OR_AM		0x80000000	/* OR addr mask */
+#define CFG_PRELIM_OR_AM	0xE0000000	/* OR addr mask */
+
+
+/*
+ * FLASH timing:
+ */
+/* 50 MHz CPU - 50 MHz bus: ACS = 00, TRLX = 1, CSNT = 1, SCY = 2, EHTR = 1 */
+#define CFG_OR_TIMING_FLASH	(OR_ACS_DIV1  | OR_TRLX | OR_CSNT_SAM | \
+				 OR_SCY_2_CLK | OR_EHTR | OR_BI)
+/* FLASH timing: ACS = 11, TRLX = 0, CSNT = 1, SCY = 5, EHTR = 1	*/
+/*
+#define CFG_OR_TIMING_FLASH	(OR_CSNT_SAM  | OR_ACS_DIV2 | OR_BI | \
+				 OR_SCY_5_CLK | OR_EHTR)
+*/
+
+#define CFG_OR0_REMAP	(CFG_REMAP_OR_AM  | CFG_OR_TIMING_FLASH)
+#define CFG_OR0_PRELIM	(CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH)
+#ifdef CONFIG_MVS_16BIT_FLASH
+#define CFG_BR0_PRELIM	((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_PS_16 | BR_V )
+#else
+#define CFG_BR0_PRELIM	((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_PS_32 | BR_V )
+#endif
+
+#undef CFG_OR1_REMAP
+#undef CFG_OR1_PRELIM
+#undef CFG_BR1_PRELIM
+/*
+ * BR2/3 and OR2/3 (SDRAM)
+ *
+ */
+#define SDRAM_BASE2_PRELIM	0x00000000	/* SDRAM bank #0	*/
+#undef SDRAM_BASE3_PRELIM
+#define	SDRAM_MAX_SIZE		0x04000000	/* max 64 MB per bank	*/
+
+/* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care)	*/
+#define CFG_OR_TIMING_SDRAM	0x00000A00
+
+#define CFG_OR2_PRELIM	(CFG_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM )
+#define CFG_BR2_PRELIM	((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMA | BR_V )
+
+#undef CFG_OR3_PRELIM
+#undef CFG_BR3_PRELIM
+
+
+/*
+ * Memory Periodic Timer Prescaler
+ *
+ * The Divider for PTA (refresh timer) configuration is based on an
+ * example SDRAM configuration (64 MBit, one bank). The adjustment to
+ * the number of chip selects (NCS) and the actually needed refresh
+ * rate is done by setting MPTPR.
+ *
+ * PTA is calculated from
+ *	PTA = (gclk * Trefresh) / ((2 ^ (2 * DFBRG)) * PTP * NCS)
+ *
+ *	gclk	  CPU clock (not bus clock!)
+ *	Trefresh  Refresh cycle * 4 (four word bursts used)
+ *
+ * 4096  Rows from SDRAM example configuration
+ * 1000  factor s -> ms
+ *   32  PTP (pre-divider from MPTPR) from SDRAM example configuration
+ *    4  Number of refresh cycles per period
+ *   64  Refresh cycle in ms per number of rows
+ * --------------------------------------------
+ * Divider = 4096 * 32 * 1000 / (4 * 64) = 512000
+ *
+ * 50 MHz => 50.000.000 / Divider =  98
+ * 66 Mhz => 66.000.000 / Divider = 129
+ * 80 Mhz => 80.000.000 / Divider = 156
+ */
+#define CFG_MAMR_PTA		 98
+
+/* refresh rate 15.6 us (= 64 ms / 4K = 62.4 / quad bursts) for <= 128 MBit	*/
+#define CFG_MPTPR_2BK_4K	MPTPR_PTP_DIV16		/* setting for 2 banks	*/
+#define CFG_MPTPR_1BK_4K	MPTPR_PTP_DIV32		/* setting for 1 bank	*/
+
+/* refresh rate 7.8 us (= 64 ms / 8K = 31.2 / quad bursts) for 256 MBit		*/
+#define CFG_MPTPR_2BK_8K	MPTPR_PTP_DIV8		/* setting for 2 banks	*/
+#define CFG_MPTPR_1BK_8K	MPTPR_PTP_DIV16		/* setting for 1 bank	*/
+
+/*
+ * MAMR settings for SDRAM
+ */
+
+/* 8 column SDRAM */
+#define CFG_MAMR_8COL	((CFG_MAMR_PTA << MAMR_PTA_SHIFT)  | MAMR_PTAE	    |	\
+			 MAMR_AMA_TYPE_0 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A11 |	\
+			 MAMR_RLFA_1X	 | MAMR_WLFA_1X	   | MAMR_TLFA_4X)
+/* 9 column SDRAM */
+#define CFG_MAMR_9COL	((CFG_MAMR_PTA << MAMR_PTA_SHIFT)  | MAMR_PTAE	    |	\
+			 MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A7 |	\
+			 MAMR_RLFA_1X	 | MAMR_WLFA_1X	   | MAMR_TLFA_4X)
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define	BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/OCRTC.h b/include/configs/OCRTC.h
new file mode 100644
index 0000000..5971fb4
--- /dev/null
+++ b/include/configs/OCRTC.h
@@ -0,0 +1,298 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family   */
+#define CONFIG_OCRTC   		1	/* ...on a OCRTC board	        */
+
+#define CONFIG_BOARD_PRE_INIT   1       /* call board_pre_init()        */
+
+#define CONFIG_SYS_CLK_FREQ     33000000 /* external frequency to pll   */
+
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/
+
+#undef	CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND "go fff00100"
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define	CONFIG_PHY_ADDR		0	/* PHY address			*/
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_ASKENV	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_EEPROM  )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef  CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+#define	CONFIG_SDRAM_BANK0	1	/* init onboard SDRAM bank 0	*/
+
+/*
+ * 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_CONSOLE_INFO_QUIET  1       /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59   /* ignore ppc405gp errata #59   */
+#define CFG_BASE_BAUD       691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR	0x100000	/* default load address */
+#define CFG_EXTBDINFO	1		/* To use extended board_into (bd_t) */
+
+#define	CFG_HZ		1000		/* decrementer freq: 1 ms ticks	*/
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure as pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support	        */
+#define CONFIG_PCI_HOST	PCI_HOST_AUTO   /* select pci host function     */
+#define CONFIG_PCI_PNP			/* do pci plug-and-play         */
+                                        /* resource configuration       */
+
+#define CONFIG_PCI_SCAN_SHOW            /* print pci devices @ startup  */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE  /* PCI Vendor ID: esd gmbh      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0410  /* PCI Device ID: OCRTC         */
+#define CFG_PCI_CLASSCODE       0x0b20  /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0xfc000001      /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+#define CFG_PCI_PTM2LA  0xffc00000      /* point to flash               */
+#define CFG_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFFD0000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(192 * 1024)	/* Reserve 192 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */
+#define CFG_FLASH_ADDR0         0x5555  /* 1st address for flash config cycles  */
+#define CFG_FLASH_ADDR1         0x2AAA  /* 2nd address for flash config cycles  */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */
+#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */
+#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */
+
+#define CFG_FLASH_EMPTY_INFO            /* print 'E' for empty sector on flinfo */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM	1	/* use NVRAM for environment vars	*/
+#define CFG_NVRAM_BASE_ADDR	0xf0200000		/* NVRAM base address	*/
+#define CFG_NVRAM_SIZE		(32*1024)		/* NVRAM size		*/
+#define CFG_ENV_SIZE		0x1000		/* Size of Environment vars	*/
+#define CFG_ENV_ADDR		\
+	(CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE)	/* Env	*/
+#define CFG_NVRAM_VXWORKS_OFFS	0x6900		/* Offset for VxWorks eth-addr	*/
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x300   /* 768 bytes may be used for env vars */
+                                   /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x50	/* EEPROM CAT28WC08		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1	/* Bytes of address		*/
+/* mask of address bits that overflow into the "EEPROM chip address"    */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW	0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4	/* The Catalyst CAT24WC08 has	*/
+					/* 16 byte page write mode using*/
+					/* last	4 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0xFF800000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0xFFC00000	/* FLASH bank #1	*/
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization                                  */
+#define CFG_EBC_PB0AP           0x92015480
+#define CFG_EBC_PB0CR           0xFFC5A000  /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization                                  */
+#define CFG_EBC_PB1AP           0x92015480
+#define CFG_EBC_PB1CR           0xFF85A000  /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (PLD - FPGA-boot) initialization                               */
+#define CFG_EBC_PB2AP           0x02015480  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB2CR           0xF0018000  /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 3 (PLD - OSL) initialization                                     */
+#define CFG_EBC_PB3AP           0x02015480  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB3CR           0xF0118000  /* BAS=0xF01,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 4 (Spartan2 1) initialization                                    */
+#define CFG_EBC_PB4AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB4CR           0xF209C000  /* BAS=0xF20,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 5 (Spartan2 2) initialization                                    */
+#define CFG_EBC_PB5AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB5CR           0xF309C000  /* BAS=0xF30,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 6 (Virtex 1) initialization                                      */
+#define CFG_EBC_PB6AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB6CR           0xF409A000  /* BAS=0xF40,BS=16MB,BU=R/W,BW=16bit*/
+
+/* Memory Bank 7 (Virtex 2) initialization                                      */
+#define CFG_EBC_PB7AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB7CR           0xF509A000  /* BAS=0xF50,BS=16MB,BU=R/W,BW=16bit*/
+
+
+#define CFG_ETHERNET_MAC_ADDR   0x00000000      /* Pass Ethernet MAC to VxWorks */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+/* use on chip memory ( OCM ) for temperary stack until sdram is tested */
+#define CFG_TEMP_STACK_OCM        1
+
+/* On Chip Memory location */
+#define CFG_OCM_DATA_ADDR	0xF8000000
+#define CFG_OCM_DATA_SIZE	0x1000
+
+#define CFG_INIT_RAM_ADDR	CFG_OCM_DATA_ADDR /* inside of SDRAM		*/
+#define CFG_INIT_RAM_END	CFG_OCM_DATA_SIZE /* End of used area in RAM	*/
+#define CFG_GBL_DATA_SIZE      128  /* 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
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/ORSG.h b/include/configs/ORSG.h
new file mode 100644
index 0000000..7c161c6
--- /dev/null
+++ b/include/configs/ORSG.h
@@ -0,0 +1,298 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family   */
+#define CONFIG_ORSG   		1	/* ...on a ORSG board	        */
+
+#define CONFIG_BOARD_PRE_INIT   1       /* call board_pre_init()        */
+
+#define CONFIG_SYS_CLK_FREQ     33000000 /* external frequency to pll   */
+
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/
+
+#undef	CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND "go fff00100"
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define	CONFIG_PHY_ADDR		0	/* PHY address			*/
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_ASKENV	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_EEPROM  )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef  CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+#define	CONFIG_SDRAM_BANK0	1	/* init onboard SDRAM bank 0	*/
+
+/*
+ * 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_CONSOLE_INFO_QUIET  1       /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59   /* ignore ppc405gp errata #59   */
+#define CFG_BASE_BAUD       691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR	0x100000	/* default load address */
+#define CFG_EXTBDINFO	1		/* To use extended board_into (bd_t) */
+
+#define	CFG_HZ		1000		/* decrementer freq: 1 ms ticks	*/
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure as pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support	        */
+#define CONFIG_PCI_HOST	PCI_HOST_ADAPTER /* select pci adapter          */
+#undef  CONFIG_PCI_PNP			/* no pci plug-and-play         */
+                                        /* resource configuration       */
+
+#undef  CONFIG_PCI_SCAN_SHOW            /* print pci devices @ startup  */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE  /* PCI Vendor ID: esd gmbh      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0411  /* PCI Device ID: ORSG          */
+#define CFG_PCI_CLASSCODE       0x0b20  /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0xfc000001      /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+#define CFG_PCI_PTM2LA  0xffc00000      /* point to flash               */
+#define CFG_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFFD0000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(192 * 1024)	/* Reserve 192 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */
+#define CFG_FLASH_ADDR0         0x5555  /* 1st address for flash config cycles  */
+#define CFG_FLASH_ADDR1         0x2AAA  /* 2nd address for flash config cycles  */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */
+#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */
+#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */
+
+#define CFG_FLASH_EMPTY_INFO            /* print 'E' for empty sector on flinfo */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM	1	/* use NVRAM for environment vars	*/
+#define CFG_NVRAM_BASE_ADDR	0xf0200000		/* NVRAM base address	*/
+#define CFG_NVRAM_SIZE		(32*1024)		/* NVRAM size		*/
+#define CFG_ENV_SIZE		0x1000		/* Size of Environment vars	*/
+#define CFG_ENV_ADDR		\
+	(CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE)	/* Env	*/
+#define CFG_NVRAM_VXWORKS_OFFS	0x6900		/* Offset for VxWorks eth-addr	*/
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x300   /* 768 bytes may be used for env vars */
+                                   /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x50	/* EEPROM CAT28WC08		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1	/* Bytes of address		*/
+/* mask of address bits that overflow into the "EEPROM chip address"    */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW	0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4	/* The Catalyst CAT24WC08 has	*/
+					/* 16 byte page write mode using*/
+					/* last	4 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0xFF800000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0xFFC00000	/* FLASH bank #1	*/
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization                                  */
+#define CFG_EBC_PB0AP           0x92015480
+#define CFG_EBC_PB0CR           0xFFC5A000  /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization                                  */
+#define CFG_EBC_PB1AP           0x92015480
+#define CFG_EBC_PB1CR           0xFF85A000  /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (PLD - FPGA-boot) initialization                               */
+#define CFG_EBC_PB2AP           0x02015480  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB2CR           0xF0018000  /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 3 (PLD - OSL) initialization                                     */
+#define CFG_EBC_PB3AP           0x02015480  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB3CR           0xF0118000  /* BAS=0xF01,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 4 (Spartan2 1) initialization                                    */
+#define CFG_EBC_PB4AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB4CR           0xF209C000  /* BAS=0xF20,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 5 (Spartan2 2) initialization                                    */
+#define CFG_EBC_PB5AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB5CR           0xF309C000  /* BAS=0xF30,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 6 (Virtex 1) initialization                                      */
+#define CFG_EBC_PB6AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB6CR           0xF409A000  /* BAS=0xF40,BS=16MB,BU=R/W,BW=16bit*/
+
+/* Memory Bank 7 (Virtex 2) initialization                                      */
+#define CFG_EBC_PB7AP           0x02015580  /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+                                            /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB7CR           0xF509A000  /* BAS=0xF50,BS=16MB,BU=R/W,BW=16bit*/
+
+
+#define CFG_ETHERNET_MAC_ADDR   0x00000000      /* Pass Ethernet MAC to VxWorks */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+/* use on chip memory ( OCM ) for temperary stack until sdram is tested */
+#define CFG_TEMP_STACK_OCM        1
+
+/* On Chip Memory location */
+#define CFG_OCM_DATA_ADDR	0xF8000000
+#define CFG_OCM_DATA_SIZE	0x1000
+
+#define CFG_INIT_RAM_ADDR	CFG_OCM_DATA_ADDR /* inside of SDRAM		*/
+#define CFG_INIT_RAM_END	CFG_OCM_DATA_SIZE /* End of used area in RAM	*/
+#define CFG_GBL_DATA_SIZE      128  /* 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
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/OXC.h b/include/configs/OXC.h
new file mode 100644
index 0000000..7a60e4b
--- /dev/null
+++ b/include/configs/OXC.h
@@ -0,0 +1,312 @@
+/*
+ * (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_MPC824X		1
+#define CONFIG_MPC8240		1
+#define CONFIG_OXC		1
+
+#define CONFIG_BOARD_PRE_INIT	1	/* Call board_pre_init	*/
+
+#define CONFIG_IDENT_STRING     " [oxc] "
+
+#define CONFIG_WATCHDOG		1
+#define CONFIG_SHOW_ACTIVITY	1
+#define CONFIG_SHOW_BOOT_PROGRESS 1
+
+#define CONFIG_CONS_INDEX	1
+#define CONFIG_BAUDRATE		9600
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL | CFG_CMD_ELF)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any)	*/
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		1		/* undef to save memory		*/
+#define CFG_PROMPT		"=> "		/* Monitor Command Prompt	*/
+#define CFG_CBSIZE		256		/* Console I/O Buffer Size	*/
+#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_LOAD_ADDR		0x00100000	/* default load address		*/
+#define CFG_HZ			1000		/* decrementer freq: 1 ms ticks */
+
+#define CONFIG_MISC_INIT_R	1		/* call misc_init_r() on init	*/
+
+/*-----------------------------------------------------------------------
+ * Boot options
+ */
+
+#define CONFIG_SERVERIP		10.0.0.1
+#define CONFIG_GATEWAYIP	10.0.0.1
+#define CONFIG_NETMASK		255.255.255.0
+#define CONFIG_LOADADDR		0x10000
+#define CONFIG_BOOTFILE		"/mnt/ide0/p2/usr/tftp/oxc.elf"
+#define CONFIG_BOOTCOMMAND	"tftp 0x10000 ; bootelf 0x10000"
+#define CONFIG_BOOTDELAY	10
+
+#define CFG_OXC_GENERATE_IP	1		/* Generate IP automatically	*/
+#define CFG_OXC_IPMASK		0x0A000000	/* 10.0.0.x			*/
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ */
+
+#define CONFIG_PCI				/* include pci support		*/
+
+#define CONFIG_NET_MULTI			/* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100				/* Ethernet Express PRO 100	*/
+
+#define PCI_ENET0_IOADDR	0x80000000
+#define PCI_ENET0_MEMADDR	0x80000000
+#define	PCI_ENET1_IOADDR	0x81000000
+#define	PCI_ENET1_MEMADDR	0x81000000
+
+/*-----------------------------------------------------------------------
+ * FLASH
+ */
+
+#define CFG_FLASH_PRELIMBASE	0xFF800000
+#define CFG_FLASH_BASE		(0-flash_info[0].size)
+
+#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	32	/* 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)	*/
+
+/*-----------------------------------------------------------------------
+ * RAM
+ */
+
+#define CFG_SDRAM_BASE		0x00000000
+#define CFG_MAX_RAM_SIZE	0x10000000
+
+#define CFG_RESET_ADDRESS	0xFFF00100
+
+#define CFG_MONITOR_BASE	TEXT_BASE
+#define CFG_MONITOR_LEN		0x00030000
+
+#if (CFG_MONITOR_BASE < CFG_FLASH_PRELIMBASE)
+# define CFG_RAMBOOT		1
+#else
+# undef CFG_RAMBOOT
+#endif
+
+#define CFG_INIT_RAM_ADDR	0x40000000
+#define CFG_INIT_RAM_END	0x1000
+
+#define CFG_GBL_DATA_SIZE	128
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET	CFG_GBL_DATA_OFFSET
+
+#define CFG_MALLOC_LEN		(512 << 10)	/* Reserve 512 kB for malloc()	*/
+
+#define CFG_MEMTEST_START	0x00000000	/* memtest works on		*/
+#define CFG_MEMTEST_END		0x04000000	/* 0 ... 32 MB in DRAM		*/
+
+/*-----------------------------------------------------------------------
+ * Memory mapping
+ */
+
+#define CFG_CPLD_BASE		0xff000000	/* CPLD registers */
+#define CFG_CPLD_WATCHDOG	(CFG_CPLD_BASE)			/* Watchdog */
+#define CFG_CPLD_RESET		(CFG_CPLD_BASE + 0x040000)	/* Minor resets */
+#define CFG_UART_BASE		(CFG_CPLD_BASE + 0x700000)	/* debug UART */
+
+/*-----------------------------------------------------------------------
+ * NS16550 Configuration
+ */
+
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE	-4
+#define CFG_NS16550_CLK		1843200
+#define CFG_NS16550_COM1	CFG_UART_BASE
+
+/*-----------------------------------------------------------------------
+ * I2C Bus
+ */
+
+#define CONFIG_I2C		1		/* I2C support on ... */
+#define CONFIG_HARD_I2C		1		/* ... hardware one */
+#define CFG_I2C_SPEED		400000		/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		0x7F		/* I2C slave address */
+
+#define CFG_I2C_EXPANDER0_ADDR	0x20		/* PCF8574 expander 0 addrerr */
+#define CFG_I2C_EXPANDER1_ADDR	0x21		/* PCF8574 expander 1 addrerr */
+#define CFG_I2C_EXPANDER2_ADDR	0x26		/* PCF8574 expander 2 addrerr */
+
+/*-----------------------------------------------------------------------
+ * Environment
+ */
+
+#define CFG_ENV_IS_IN_FLASH	1
+#define CFG_ENV_ADDR		0xFFF30000	/* Offset of Environment Sector */
+#define CFG_ENV_SIZE		0x00010000	/* Total Size of Environment Sector */
+#define CONFIG_ENV_OVERWRITE    1		/* Allow modifying the environment */
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ  33000000	/* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER  2
+
+#define CFG_EUMB_ADDR		0xFC000000
+
+/* MCCR1 */
+#define CFG_ROMNAL		0	/* rom/flash next access time		*/
+#define CFG_ROMFAL		19	/* rom/flash access time		*/
+
+/* MCCR2 */
+#define CFG_ASRISE		15	/* ASRISE=15 clocks			*/
+#define CFG_ASFALL		3	/* ASFALL=3 clocks			*/
+#define CFG_REFINT		1000	/* REFINT=1000 clocks			*/
+
+/* MCCR3 */
+#define CFG_BSTOPRE		0x35c	/* Burst To Precharge			*/
+#define CFG_REFREC		7	/* Refresh to activate interval		*/
+#define CFG_RDLAT		4	/* data latency from read command	*/
+
+/* MCCR4 */
+#define CFG_PRETOACT		2	/* Precharge to activate interval	*/
+#define CFG_ACTTOPRE		5	/* Activate to Precharge interval	*/
+#define CFG_ACTORW		2	/* Activate to R/W			*/
+#define CFG_SDMODE_CAS_LAT	3	/* SDMODE CAS latency			*/
+#define CFG_SDMODE_WRAP		0	/* SDMODE wrap type			*/
+#define CFG_SDMODE_BURSTLEN	3	/* SDMODE Burst length 2=4, 3=8		*/
+#define CFG_REGISTERD_TYPE_BUFFER   1
+
+/* memory bank settings*/
+/*
+ * only bits 20-29 are actually used from these vales to set the
+ * start/end address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START		0x00000000
+#define CFG_BANK0_END		(CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE	1
+#define CFG_BANK1_START		0x00000000
+#define CFG_BANK1_END		0x00000000
+#define CFG_BANK1_ENABLE	0
+#define CFG_BANK2_START		0x00000000
+#define CFG_BANK2_END		0x00000000
+#define CFG_BANK2_ENABLE	0
+#define CFG_BANK3_START		0x00000000
+#define CFG_BANK3_END		0x00000000
+#define CFG_BANK3_ENABLE	0
+#define CFG_BANK4_START		0x00000000
+#define CFG_BANK4_END		0x00000000
+#define CFG_BANK4_ENABLE	0
+#define CFG_BANK5_START		0x00000000
+#define CFG_BANK5_END		0x00000000
+#define CFG_BANK5_ENABLE	0
+#define CFG_BANK6_START		0x00000000
+#define CFG_BANK6_END		0x00000000
+#define CFG_BANK6_ENABLE	0
+#define CFG_BANK7_START		0x00000000
+#define CFG_BANK7_END		0x00000000
+#define CFG_BANK7_ENABLE	0
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE		0x01
+
+#define CFG_ODCR		0xff	/* configures line driver impedances,	*/
+					/* see 8240 book for bit definitions	*/
+#define CFG_PGMAX		0x32	/* how long the 8240 retains the	*/
+					/* currently accessed page in memory	*/
+					/* see 8240 book for details		*/
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L	(CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U	(CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in DCACHE @ 1GB (no backing mem) */
+#define CFG_IBAT1L	(CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U	(CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory */
+#define CFG_IBAT2L	(0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U	(0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc */
+#define CFG_IBAT3L	(0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U	(0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L	CFG_IBAT0L
+#define CFG_DBAT0U	CFG_IBAT0U
+#define CFG_DBAT1L	CFG_IBAT1L
+#define CFG_DBAT1U	CFG_IBAT1U
+#define CFG_DBAT2L	CFG_IBAT2L
+#define CFG_DBAT2U	CFG_IBAT2U
+#define CFG_DBAT3L	CFG_IBAT3L
+#define CFG_DBAT3U	CFG_IBAT3U
+
+/*
+ * 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 */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32	/* For MPC8240 CPU			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM		0x02	/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/PCI405.h b/include/configs/PCI405.h
new file mode 100644
index 0000000..3f9b8d4
--- /dev/null
+++ b/include/configs/PCI405.h
@@ -0,0 +1,343 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family   */
+#define CONFIG_PCI405		1	/* ...on a PCI405 board	        */
+
+#define CONFIG_BOARD_PRE_INIT   1       /* call board_pre_init()        */
+#define CONFIG_MISC_INIT_R	1	/* call misc_init_r() on init	*/
+
+#define CONFIG_SYS_CLK_FREQ     25000000 /* external frequency to pll   */
+
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/
+
+#if 0
+#define CONFIG_PREBOOT                                                          \
+        "crc32 f0207004 ffc 0;"                                                 \
+        "if cmp 0 f0207000 1;"                                                  \
+        "then;echo Old CRC is correct;crc32 f0207004 ff4 f0207000;"             \
+        "else;echo Old CRC is bad;fi"
+#endif
+
+#undef	CONFIG_BOOTARGS
+#if 1
+#define CONFIG_BOOTCOMMAND							\
+	"bootm fffc0000"
+#else
+#define CONFIG_BOOTCOMMAND							\
+	"mw.l 0 ffffffff; mw.l 4 ffffffff;"                                     \
+        "while cmp 0 4 1; do echo Waiting for Host...;done;"                    \
+        "bootm 400000"
+#endif
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define	CONFIG_PHY_ADDR		0	/* PHY address			*/
+
+#define CONFIG_RTC_M48T35A	1		/* ST Electronics M48 timekeeper */
+
+#define CONFIG_COMMANDS	      ( CONFIG_CMD_DFL	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_DATE	| \
+				CFG_CMD_I2C	| \
+				CFG_CMD_EEPROM  )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef  CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+#define	CONFIG_SDRAM_BANK0	1	/* init onboard SDRAM bank 0	*/
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP			/* undef to save memory		*/
+#define CFG_PROMPT	"=> "		/* Monitor Command Prompt	*/
+
+#define	CFG_HUSH_PARSER			/* use "hush" command parser	*/
+#ifdef	CFG_HUSH_PARSER
+#define	CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+#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_DEVICE_NULLDEV      1       /* include nulldev device       */
+
+#define CFG_CONSOLE_INFO_QUIET  1       /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59   /* ignore ppc405gp errata #59   */
+#define CFG_BASE_BAUD       691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR	0x100000	/* default load address */
+#define CFG_EXTBDINFO	1		/* To use extended board_into (bd_t) */
+
+#define	CFG_HZ		1000		/* decrementer freq: 1 ms ticks	*/
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure as pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support	        */
+#define CONFIG_PCI_HOST	PCI_HOST_ADAPTER /* select pci host function    */
+#undef  CONFIG_PCI_PNP			/* no pci plug-and-play         */
+                                        /* resource configuration       */
+
+#define CONFIG_PCI_SCAN_SHOW            /* print pci devices @ startup  */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE  /* PCI Vendor ID: esd gmbh      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0407  /* PCI Device ID: PCI-405       */
+#define CFG_PCI_CLASSCODE       0x0280  /* PCI Class Code: Network/Other*/
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0xfc000001      /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+
+#if 0 /* test-only */
+#define CFG_PCI_PTM2LA  0xffc00000      /* point to flash               */
+#define CFG_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+#else
+#define CFG_PCI_PTM2LA  0xef600000      /* point to internal regs       */
+#define CFG_PCI_PTM2MS  0xef600001      /* 4MB, enable                  */
+#define CFG_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+#endif
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFFD0000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(192 * 1024)	/* Reserve 196 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */
+#define CFG_FLASH_ADDR0         0x5555  /* 1st address for flash config cycles  */
+#define CFG_FLASH_ADDR1         0x2AAA  /* 2nd address for flash config cycles  */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */
+#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */
+#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */
+
+#define CFG_FLASH_EMPTY_INFO            /* print 'E' for empty sector on flinfo */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM	1	/* use NVRAM for environment vars	*/
+#define CFG_ENV_SIZE		0x0ff8		/* Size of Environment vars	*/
+#define CFG_ENV_ADDR		\
+	(CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-(CFG_ENV_SIZE+8))	/* Env	*/
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x400   /* 1024 bytes may be used for env vars*/
+                                   /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+#define CFG_NVRAM_BASE_ADDR	0xf0200000		/* NVRAM base address	*/
+#define CFG_NVRAM_SIZE		(32*1024)		/* NVRAM size		*/
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC16) for environment
+ */
+#define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x50	/* EEPROM CAT28WC08		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1	/* Bytes of address		*/
+/* mask of address bits that overflow into the "EEPROM chip address"    */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW	0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4	/* The Catalyst CAT24WC08 has	*/
+					/* 16 byte page write mode using*/
+					/* last	4 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM	0xFFE00000	/* FLASH bank #0	*/
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization                                  */
+#define CFG_EBC_PB0AP           0x92015480
+#define CFG_EBC_PB0CR           0xFFC5A000  /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (NVRAM/RTC) initialization                                     */
+#define CFG_EBC_PB1AP           0x01005280  /* TWT=2,WBN=1,WBF=1,TH=1,SOR=1     */
+#define CFG_EBC_PB1CR           0xF0218000  /* BAS=0xF02,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 2 (CAN0, 1) initialization                                       */
+#define CFG_EBC_PB2AP           0x010053C0  /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR           0xF0018000  /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit  */
+
+/* Memory Bank 3 (FPGA internal) initialization                                 */
+#define CFG_EBC_PB3AP           0x010053C0  /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR           0xF041C000  /* BAS=0xF01,BS=1MB,BU=R/W,BW=32bit */
+#define CFG_FPGA_BASE_ADDR      0xF0400000
+
+/*-----------------------------------------------------------------------
+ * FPGA stuff
+ */
+/* FPGA internal regs */
+#define CFG_FPGA_MODE           0x00
+#define CFG_FPGA_STATUS         0x02
+#define CFG_FPGA_TS             0x04
+#define CFG_FPGA_TS_LOW         0x06
+#define CFG_FPGA_TS_CAP0        0x10
+#define CFG_FPGA_TS_CAP0_LOW    0x12
+#define CFG_FPGA_TS_CAP1        0x14
+#define CFG_FPGA_TS_CAP1_LOW    0x16
+#define CFG_FPGA_TS_CAP2        0x18
+#define CFG_FPGA_TS_CAP2_LOW    0x1a
+#define CFG_FPGA_TS_CAP3        0x1c
+#define CFG_FPGA_TS_CAP3_LOW    0x1e
+
+/* FPGA Mode Reg */
+#define CFG_FPGA_MODE_CF_RESET  0x0001
+#define CFG_FPGA_MODE_TS_IRQ_ENABLE 0x0100
+#define CFG_FPGA_MODE_TS_IRQ_CLEAR  0x1000
+#define CFG_FPGA_MODE_TS_CLEAR  0x2000
+
+/* FPGA Status Reg */
+#define CFG_FPGA_STATUS_DIP0    0x0001
+#define CFG_FPGA_STATUS_DIP1    0x0002
+#define CFG_FPGA_STATUS_DIP2    0x0004
+#define CFG_FPGA_STATUS_FLASH   0x0008
+#define CFG_FPGA_STATUS_TS_IRQ  0x1000
+
+#define CFG_FPGA_SPARTAN2       1           /* using Xilinx Spartan 2 now    */
+#define CFG_FPGA_MAX_SIZE       32*1024     /* 32kByte is enough for XC2S15  */
+
+/* FPGA program pin configuration */
+#define CFG_FPGA_PRG            0x04000000  /* FPGA program pin (ppc output) */
+#define CFG_FPGA_CLK            0x02000000  /* FPGA clk pin (ppc output)     */
+#define CFG_FPGA_DATA           0x01000000  /* FPGA data pin (ppc output)    */
+#define CFG_FPGA_INIT           0x00400000  /* FPGA init pin (ppc input)     */
+#define CFG_FPGA_DONE           0x00800000  /* FPGA done pin (ppc input)     */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in data cache)
+ */
+#if 1 /* test-only */
+#define CFG_INIT_DCACHE_CS      7       /* use cs # 7 for data cache memory    */
+
+#define CFG_INIT_RAM_ADDR       0x40000000  /* use data cache                  */
+#else
+#define CFG_INIT_RAM_ADDR	0x00df0000 /* inside of SDRAM                   */
+#endif
+#define CFG_INIT_RAM_END        0x2000  /* End of used area in RAM             */
+#define CFG_GBL_DATA_SIZE      128  /* 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
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h
new file mode 100644
index 0000000..a5fc8d9
--- /dev/null
+++ b/include/configs/PIP405.h
@@ -0,0 +1,374 @@
+/*
+ * (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_405GP		1	/* This is a PPC405 CPU		*/
+#define CONFIG_4xx		1	/* ...member of PPC4xx family	*/
+#define CONFIG_PIP405		1	/* ...on a PIP405 board		*/
+/***********************************************************
+ * Clock
+ ***********************************************************/
+#define CONFIG_SYS_CLK_FREQ	33000000 /* external frequency to pll	*/
+
+/***********************************************************
+ * Command definitions
+ ***********************************************************/
+#define CONFIG_COMMANDS		\
+		       (CONFIG_CMD_DFL	| \
+			CFG_CMD_IDE	| \
+			CFG_CMD_DHCP	| \
+			CFG_CMD_PCI	| \
+			CFG_CMD_CACHE	| \
+			CFG_CMD_IRQ	| \
+			CFG_CMD_EEPROM	| \
+			CFG_CMD_I2C	| \
+			CFG_CMD_REGINFO | \
+			CFG_CMD_FDC	| \
+			CFG_CMD_SCSI	| \
+			CFG_CMD_DATE	| \
+			CFG_CMD_ELF	| \
+			CFG_CMD_USB	| \
+			CFG_CMD_MII	| \
+			CFG_CMD_SDRAM	| \
+			CFG_CMD_DOC	| \
+			CFG_CMD_SAVES   | \
+			CFG_CMD_BSP	)
+/* this must be included AFTER the definition of CONFIG_COMMANDS  (if any) */
+#include <cmd_confdefs.h>
+
+#define	 CFG_HUSH_PARSER
+#define	 CFG_PROMPT_HUSH_PS2 "> "
+/**************************************************************
+ * I2C Stuff:
+ * the PIP405 is equiped with an Atmel 24C128/256 EEPROM at address
+ * 0x53.
+ * Caution: on the same bus is the SPD (Serial Presens Detect
+ * EEPROM of the SDRAM
+ * The Atmel EEPROM uses 16Bit addressing.
+ ***************************************************************/
+#define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CFG_I2C_SPEED		50000	/* I2C speed and slave address */
+#define CFG_I2C_SLAVE		0x7F
+
+#define CFG_I2C_EEPROM_ADDR	0x53
+#define CFG_I2C_EEPROM_ADDR_LEN	2
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x800   /* 2 kBytes may be used for env vars */
+
+#undef CFG_I2C_EEPROM_ADDR_OVERFLOW
+#define CFG_EEPROM_PAGE_WRITE_BITS 6	/* The Atmel 24C128/256 has	*/
+					/* 64 byte page write mode using*/
+					/* last	6 bits of the address	*/
+#define CFG_EEPROM_PAGE_WRITE_ENABLE	/* enable Page write */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10	/* and takes up to 10 msec */
+
+
+/***************************************************************
+ * Definitions for Serial Presence Detect EEPROM address
+ * (to get SDRAM settings)
+ ***************************************************************/
+#define SPD_EEPROM_ADDRESS      0x50
+
+#define CONFIG_BOARD_PRE_INIT
+/**************************************************************
+ * Environment definitions
+ **************************************************************/
+#define CONFIG_BAUDRATE		9600	/* STD Baudrate */
+
+
+#define CONFIG_BOOTDELAY	5
+/* autoboot (do NOT change this set environment variable "bootdelay" to -1 instead) */
+#define CONFIG_BOOT_RETRY_TIME	-10	/* feature is avaiable but not enabled */
+#define CONFIG_ZERO_BOOTDELAY_CHECK  	/* check console even if bootdelay = 0 */
+
+
+#define CONFIG_BOOTCOMMAND	"diskboot 200000 0:1; bootm" /* autoboot command		*/
+#define CONFIG_BOOTARGS		"console=ttyS0,9600 root=/dev/hda5" /* boot arguments */
+
+#define CONFIG_IPADDR		10.0.0.100
+#define CONFIG_SERVERIP		10.0.0.1
+#define CONFIG_PREBOOT
+/***************************************************************
+ * defines if the console is stored in the environment
+ ***************************************************************/
+#define CFG_CONSOLE_IS_IN_ENV	/* stdin, stdout and stderr are in evironment */
+/***************************************************************
+ * defines if an overwrite_console function exists
+ *************************************************************/
+#define CFG_CONSOLE_OVERWRITE_ROUTINE
+#define CFG_CONSOLE_INFO_QUIET
+/***************************************************************
+ * defines if the overwrite_console should be stored in the
+ * environment
+ **************************************************************/
+#undef CFG_CONSOLE_ENV_OVERWRITE
+
+/**************************************************************
+ * loads config
+ *************************************************************/
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+
+/***********************************************************
+ * 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		0x0C00000	/* 1 ... 12 MB in DRAM	*/
+
+#undef	CFG_EXT_SERIAL_CLOCK	       /* no external serial clock used */
+#define CFG_BASE_BAUD       691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE	\
+	{ 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+	 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR		0x200000	/* default load address */
+#define CFG_EXTBDINFO		1	/* To use extended board_into (bd_t) */
+
+#define CFG_HZ		1000		/* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0              /* configure ar pci adapter     */
+#define PCI_HOST_FORCE  1               /* configure as pci host        */
+#define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
+
+#define CONFIG_PCI			/* include pci support		*/
+#define CONFIG_PCI_HOST PCI_HOST_FORCE	/* configure as pci-host	*/
+#define CONFIG_PCI_PNP			/* pci plug-and-play		*/
+					/* resource configuration	*/
+#define CFG_PCI_SUBSYS_VENDORID 0x0000	/* PCI Vendor ID: to-do!!!	*/
+#define CFG_PCI_SUBSYS_DEVICEID 0x0000	/* PCI Device ID: to-do!!!	*/
+#define CFG_PCI_PTM1LA	0x00000000	/* point to sdram		*/
+#define CFG_PCI_PTM1MS	0x80000001	/* 2GB, enable hard-wired to 1	*/
+#define CFG_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
+#define CFG_PCI_PTM2LA	0x00000000	/* disabled			*/
+#define CFG_PCI_PTM2MS	0x00000000	/* disabled			*/
+#define CFG_PCI_PTM2PCI 0x00000000      /* Host: use this pci address   */
+
+/*-----------------------------------------------------------------------
+ * 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		0xFFF80000
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MONITOR_LEN		(512 * 1024)	/* Reserve 512 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 * 1024)	/* 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		*/
+#define CFG_MAX_FLASH_SECT	256	/* 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_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Init Memory Controller:
+ */
+
+#define FLASH_BASE0_PRELIM	0xFFC00000	/* FLASH bank #0	*/
+#define FLASH_BASE1_PRELIM	0		/* FLASH bank #1	*/
+
+/* Configuration Port location */
+#define CONFIG_PORT_ADDR	0xF4000000
+#define MULTI_PURPOSE_SOCKET_ADDR 0xF8000000
+
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in On Chip SRAM)
+ */
+#define CFG_TEMP_STACK_OCM	1
+#define CFG_OCM_DATA_ADDR	0xF0000000
+#define CFG_OCM_DATA_SIZE	0x1000
+#define CFG_INIT_RAM_ADDR	CFG_OCM_DATA_ADDR 	/* inside of On Chip SRAM    */
+#define CFG_INIT_RAM_END	CFG_OCM_DATA_SIZE	/* End of On Chip SRAM	       */
+#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
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+
+/***********************************************************************
+ * External peripheral base address
+ ***********************************************************************/
+#define CFG_ISA_IO_BASE_ADDRESS 0xE8000000
+
+/***********************************************************************
+ * Last Stage Init
+ ***********************************************************************/
+#define CONFIG_LAST_STAGE_INIT
+/************************************************************
+ * Ethernet Stuff
+ ***********************************************************/
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define CONFIG_PHY_ADDR		1	/* PHY address			*/
+#define CONFIG_CS8952_PHY	1	/* its a CS8952 PHY		*/
+/************************************************************
+ * RTC
+ ***********************************************************/
+#define CONFIG_RTC_MC146818
+#undef CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+/************************************************************
+ * IDE/ATA stuff
+ ************************************************************/
+#define CFG_IDE_MAXBUS		2   /* max. 2 IDE busses	*/
+#define CFG_IDE_MAXDEVICE	(CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR	CFG_ISA_IO_BASE_ADDRESS /* base address */
+#define CFG_ATA_IDE0_OFFSET	0x01F0	/* ide0 offste */
+#define CFG_ATA_IDE1_OFFSET	0x0170	/* ide1 offset */
+#define CFG_ATA_DATA_OFFSET	0	/* data reg offset	*/
+#define CFG_ATA_REG_OFFSET	0	/* reg offset */
+#define CFG_ATA_ALT_OFFSET	0x200	/* alternate register offset */
+
+#undef	CONFIG_IDE_8xx_DIRECT		/* no pcmcia interface required */
+#undef	CONFIG_IDE_LED			/* no led for ide supported	*/
+#define CONFIG_IDE_RESET		/* reset for ide supported...	*/
+#define CONFIG_IDE_RESET_ROUTINE	/* with a special reset function */
+
+/************************************************************
+ * ATAPI support (experimental)
+ ************************************************************/
+#define CONFIG_ATAPI			/* enable ATAPI Support */
+
+/************************************************************
+ * SCSI support (experimental) only SYM53C8xx supported
+ ************************************************************/
+#define CONFIG_SCSI_SYM53C8XX
+#define CFG_SCSI_MAX_LUN	8	/* number of supported LUNs */
+#define CFG_SCSI_MAX_SCSI_ID	7	/* maximum SCSI ID (0..6) */
+#define CFG_SCSI_MAX_DEVICE	CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN /* maximum Target devices */
+#define CFG_SCSI_SPIN_UP_TIME	2
+
+/************************************************************
+ * Disk-On-Chip configuration
+ ************************************************************/
+#define CFG_MAX_DOC_DEVICE	1	/* Max number of DOC devices		*/
+#define CFG_DOC_SHORT_TIMEOUT
+#define CFG_DOC_SUPPORT_2000
+#define CFG_DOC_SUPPORT_MILLENNIUM
+
+/************************************************************
+ * DISK Partition support
+ ************************************************************/
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION /* Experimental */
+
+/************************************************************
+ * Keyboard support
+ ************************************************************/
+#define CONFIG_ISA_KEYBOARD
+
+/************************************************************
+ * Video support
+ ************************************************************/
+#define CONFIG_VIDEO			/*To enable video controller support */
+#define CONFIG_VIDEO_CT69000
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_CONSOLE_EXTRA_INFO
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_VIDEO_SW_CURSOR
+#define CONFIG_VIDEO_ONBOARD		/* Video controller is on-board */
+
+/************************************************************
+ * USB support
+ ************************************************************/
+#define CONFIG_USB_UHCI
+#define CONFIG_USB_KEYBOARD
+#define CONFIG_USB_STORAGE
+
+/* Enable needed helper functions */
+#define CFG_DEVICE_DEREGISTER		/* needs device_deregister */
+
+/************************************************************
+ * Debug support
+ ************************************************************/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	230400	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	2	/* which serial port to use */
+#endif
+
+/************************************************************
+ * Ident
+ ************************************************************/
+#define VERSION_TAG "released"
+#define CONFIG_IDENT_STRING "\n(c) 2002 by MPL AG Switzerland, MEV-10066-001 " VERSION_TAG
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/PN62.h b/include/configs/PN62.h
new file mode 100644
index 0000000..0750116
--- /dev/null
+++ b/include/configs/PN62.h
@@ -0,0 +1,301 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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_MPC824X		1
+#define CONFIG_MPC8240		1
+#define CONFIG_PN62		1
+
+#define CONFIG_CONS_INDEX	1
+
+
+#define REMOVE_COMMANDS         ( CFG_CMD_AUTOSCRIPT | \
+ 				  CFG_CMD_LOADS | \
+ 				  CFG_CMD_ENV | \
+ 				  CFG_CMD_FLASH )
+
+#define CONFIG_COMMANDS		( (CONFIG_CMD_DFL & ~REMOVE_COMMANDS) |\
+				  CFG_CMD_PCI |\
+				  CFG_CMD_BSP)
+
+#define CONFIG_BAUDRATE		19200	/* console baudrate		*/
+
+#define CONFIG_BOOTDELAY	1	/* autoboot after n seconds	*/
+
+#define	CONFIG_CLOCKS_IN_MHZ	1	/* clocks passsed to Linux in MHz */
+
+#define CONFIG_SERVERIP		10.0.0.201
+#define CONFIG_IPADDR 		10.0.0.200
+#define CONFIG_ROOTPATH		/opt/eldk/ppc_82xx
+#define CONFIG_NETMASK		255.255.255.0
+#undef CONFIG_BOOTARGS
+#if 0
+/* Boot Linux with NFS root filesystem */
+#define CONFIG_BOOTCOMMAND \
+			"setenv verify y;" \
+       			"setenv bootargs console=ttyS0,19200 mem=31M quiet " \
+			"root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+			"ip=$(ipaddr):$(serverip)::$(netmask):pn62:eth0:off;" \
+			"loadp 100000; bootm"
+			/* "tftpboot 100000 pImage; bootm" */
+#else
+/* Boot Linux with RAMdisk based filesystem (initrd, BusyBox) */
+#define CONFIG_BOOTCOMMAND \
+			"setenv verify n;" \
+       			"setenv bootargs console=ttyS0,19200 mem=31M quiet " \
+			"root=/dev/ram rw " \
+			"ip=$(ipaddr):$(serverip)::$(netmask):pn62:eth0:off;" \
+			"loadp 200000; bootm"
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any)	*/
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		1		/* undef to save memory		*/
+#define CFG_PROMPT		"=> "		/* Monitor Command Prompt	*/
+#define CFG_CBSIZE		256		/* Console I/O Buffer Size	*/
+#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_LOAD_ADDR		0x00100000	/* default load address		*/
+#define CFG_HZ			1000		/* decrementer freq: 1 ms ticks */
+
+#define CONFIG_PRAM		1024		/* reserve 1 MB protected RAM	*/
+
+#define CONFIG_MISC_INIT_R	1		/* call misc_init_r() on init	*/
+
+#define CONFIG_SHOW_BOOT_PROGRESS 1		/* Show boot progress on LEDs   */
+
+/*
+ * PCI stuff
+ */
+#define CONFIG_PCI				/* include pci support		*/
+#define CONFIG_PCI_PNP				/* we need Plug 'n Play		*/
+#if 0
+#define CONFIG_PCI_SCAN_SHOW			/* show PCI auto-scan at boot	*/
+#endif
+
+/*
+ * Networking stuff
+ */
+#define CONFIG_NET_MULTI       			/* Multi ethernet cards support */
+
+#define CONFIG_PCNET				/* there are 2 AMD PCnet 79C973	*/
+#define CONFIG_PCNET_79C973
+
+#define _IO_BASE		0xfe000000	/* points to PCI I/O space	*/
+
+
+/*
+ * 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_MAX_RAM_SIZE	0x10000000
+
+#define CFG_RESET_ADDRESS	0xfff00100
+
+#undef	CFG_RAMBOOT
+#define CFG_MONITOR_LEN		0x00030000
+#define CFG_MONITOR_BASE	TEXT_BASE
+
+/*#define CFG_GBL_DATA_SIZE    256*/
+#define CFG_GBL_DATA_SIZE	128
+
+#define CFG_INIT_RAM_ADDR   	0x40000000
+#define CFG_INIT_RAM_END    	0x1000
+#define CFG_GBL_DATA_OFFSET 	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+
+#define CFG_NO_FLASH		1		/* There is no FLASH memory	*/
+
+#define CFG_ENV_IS_NOWHERE	1		/* Store ENV in memory only	*/
+#define CFG_ENV_OFFSET		0x00004000	/* Offset of Environment Sector */
+#define CFG_ENV_SIZE		0x00002000	/* Total Size of Environment Sector */
+
+#define CFG_MALLOC_LEN		(512 << 10)	/* Reserve 512 kB for malloc()	*/
+
+#define CFG_MEMTEST_START	0x00004000	/* memtest works on		*/
+#define CFG_MEMTEST_END		0x01f00000	/* 0 ... 32 MB in DRAM		*/
+
+/*
+ * Serial port configuration
+ */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE	1
+
+#define CFG_NS16550_CLK		1843200
+
+#define CFG_NS16550_COM1	0xff800008
+#define CFG_NS16550_COM2	0xff800000
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ  33333333	/* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER  3
+
+#define CFG_EUMB_ADDR		0xFCE00000
+
+/* MCCR1 */
+#define CFG_ROMNAL		3	/* rom/flash next access time		*/
+#define CFG_ROMFAL		7	/* rom/flash access time		*/
+
+/* MCCR2 */
+#define CFG_ASRISE		6	/* ASRISE in clocks			*/
+#define CFG_ASFALL		12	/* ASFALL in clocks			*/
+#define CFG_REFINT		5600	/* REFINT in clocks			*/
+
+/* MCCR3 */
+#define CFG_BSTOPRE		0x3cf	/* Burst To Precharge			*/
+#define CFG_REFREC		2	/* Refresh to activate interval		*/
+#define CFG_RDLAT		3	/* data latency from read command	*/
+
+/* MCCR4 */
+#define CFG_PRETOACT		1	/* Precharge to activate interval	*/
+#define CFG_ACTTOPRE		3	/* Activate to Precharge interval	*/
+#define CFG_ACTORW		2	/* Activate to R/W			*/
+#define CFG_SDMODE_CAS_LAT	2	/* SDMODE CAS latency			*/
+#define CFG_SDMODE_WRAP		0	/* SDMODE Wrap type			*/
+#define CFG_SDMODE_BURSTLEN	2	/* SDMODE Burst length 2=4, 3=8		*/
+#define CFG_REGISTERD_TYPE_BUFFER   1
+
+/* Memory bank settings:
+ *
+ * only bits 20-29 are actually used from these vales to set the
+ * start/qend address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START		0x00000000
+#define CFG_BANK0_END		(CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE	1
+#define CFG_BANK1_START		0x00000000
+#define CFG_BANK1_END		0x00000000
+#define CFG_BANK1_ENABLE	0
+#define CFG_BANK2_START		0x00000000
+#define CFG_BANK2_END		0x00000000
+#define CFG_BANK2_ENABLE	0
+#define CFG_BANK3_START		0x00000000
+#define CFG_BANK3_END		0x00000000
+#define CFG_BANK3_ENABLE	0
+#define CFG_BANK4_START		0x00000000
+#define CFG_BANK4_END		0x00000000
+#define CFG_BANK4_ENABLE	0
+#define CFG_BANK5_START		0x00000000
+#define CFG_BANK5_END		0x00000000
+#define CFG_BANK5_ENABLE	0
+#define CFG_BANK6_START		0x00000000
+#define CFG_BANK6_END		0x00000000
+#define CFG_BANK6_ENABLE	0
+#define CFG_BANK7_START		0x00000000
+#define CFG_BANK7_END		0x00000000
+#define CFG_BANK7_ENABLE	0
+
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ * are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE		0x01
+
+#define CFG_ODCR		0xff	/* configures line driver impedances,	*/
+					/* see 8240 book for bit definitions	*/
+#define CFG_PGMAX		0x32	/* how long the 8240 retains the	*/
+					/* currently accessed page in memory	*/
+					/* see 8240 book for details		*/
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L	(CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U	(CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L	(CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U	(CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory space */
+#define CFG_IBAT2L	(0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U	(0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Config addrs, etc */
+#define CFG_IBAT3L	(0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U	(0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L	CFG_IBAT0L
+#define CFG_DBAT0U	CFG_IBAT0U
+#define CFG_DBAT1L	CFG_IBAT1L
+#define CFG_DBAT1U	CFG_IBAT1U
+#define CFG_DBAT2L	CFG_IBAT2L
+#define CFG_DBAT2U	CFG_IBAT2U
+#define CFG_DBAT3L	CFG_IBAT3L
+#define CFG_DBAT3U	CFG_IBAT3U
+
+/*
+ * 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 */
+
+/*
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32	/* For MPC8240 CPU			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */
+#endif
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM		0x02	/* Software reboot			*/
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/Sandpoint8240.h b/include/configs/Sandpoint8240.h
new file mode 100644
index 0000000..0bef321
--- /dev/null
+++ b/include/configs/Sandpoint8240.h
@@ -0,0 +1,377 @@
+/*
+ * (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_MPC824X		1
+#define CONFIG_MPC8240		1
+#define CONFIG_SANDPOINT	1
+
+#if 0
+#define USE_DINK32		1
+#else
+#undef USE_DINK32
+#endif
+
+#define CONFIG_CONS_INDEX	1
+#define CONFIG_BAUDRATE		115200
+#define CONFIG_DRAM_SPEED	100		/* MHz				*/
+
+#define CONFIG_COMMANDS		( (CONFIG_CMD_DFL & ~CFG_CMD_AUTOSCRIPT) | \
+				  CFG_CMD_ELF    | \
+				  CFG_CMD_I2C 	 | \
+				  CFG_CMD_SDRAM	 | \
+				  CFG_CMD_EEPROM | \
+				  CFG_CMD_PCI )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any)	*/
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		1		/* undef to save memory		*/
+#define CFG_PROMPT		"=> "		/* Monitor Command Prompt	*/
+#define CFG_CBSIZE		256		/* Console I/O Buffer Size	*/
+#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_LOAD_ADDR		0x00100000	/* default load address		*/
+#define CFG_HZ			1000		/* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI				/* include pci support		*/
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI			/* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100
+
+#define PCI_ENET0_IOADDR	0x80000000
+#define PCI_ENET0_MEMADDR	0x80000000
+#define	PCI_ENET1_IOADDR	0x81000000
+#define	PCI_ENET1_MEMADDR	0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * 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_MAX_RAM_SIZE	0x10000000
+
+#define CFG_RESET_ADDRESS	0xFFF00100
+
+#if defined (USE_DINK32)
+#define CFG_MONITOR_LEN		0x00030000
+#define CFG_MONITOR_BASE	0x00090000
+#define CFG_RAMBOOT		1
+#define CFG_INIT_RAM_ADDR	(CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#define CFG_INIT_RAM_END	0x10000
+#define CFG_GBL_DATA_SIZE	256  /* 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
+#else
+#undef	CFG_RAMBOOT
+#define CFG_MONITOR_LEN		0x00030000
+#define CFG_MONITOR_BASE	TEXT_BASE
+
+/*#define CFG_GBL_DATA_SIZE    256*/
+#define CFG_GBL_DATA_SIZE	128
+
+#define CFG_INIT_RAM_ADDR     0x40000000
+#define CFG_INIT_RAM_END      0x1000
+#define CFG_GBL_DATA_OFFSET  (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+#endif
+
+#define CFG_FLASH_BASE		0xFFF00000
+#if 0
+#define CFG_FLASH_SIZE		(512 * 1024)	/* sandpoint has tiny eeprom	*/
+#else
+#define CFG_FLASH_SIZE		(1024 * 1024)	/* Unity has onboard 1MByte flash */
+#endif
+#define CFG_ENV_IS_IN_FLASH	1
+#define CFG_ENV_OFFSET		0x00004000	/* Offset of Environment Sector */
+#define CFG_ENV_SIZE		0x00002000	/* Total Size of Environment Sector */
+
+#define CFG_MALLOC_LEN		(512 << 10)	/* Reserve 512 kB for malloc()	*/
+
+#define CFG_MEMTEST_START	0x00000000	/* memtest works on		*/
+#define CFG_MEMTEST_END		0x04000000	/* 0 ... 32 MB in DRAM		*/
+
+#define CFG_EUMB_ADDR		0xFC000000
+
+#define CFG_ISA_MEM		0xFD000000
+#define CFG_ISA_IO		0xFE000000
+
+#define CFG_FLASH_RANGE_BASE	0xFF000000	/* flash memory address range	*/
+#define CFG_FLASH_RANGE_SIZE	0x01000000
+#define FLASH_BASE0_PRELIM	0xFFF00000	/* sandpoint flash		*/
+#define FLASH_BASE1_PRELIM	0xFF000000	/* PMC onboard flash		*/
+
+/*
+ * select i2c support configuration
+ *
+ * Supported configurations are {none, software, hardware} drivers.
+ * If the software driver is chosen, there are some additional
+ * configuration items that the driver uses to drive the port pins.
+ */
+#define CONFIG_HARD_I2C		1		/* To enable I2C support	*/
+#undef  CONFIG_SOFT_I2C				/* I2C bit-banged		*/
+#define CFG_I2C_SPEED		400000		/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		0x7F
+
+#ifdef CONFIG_SOFT_I2C
+#error "Soft I2C is not configured properly.  Please review!"
+#define I2C_PORT		3               /* Port A=0, B=1, C=2, D=3 */
+#define I2C_ACTIVE		(iop->pdir |=  0x00010000)
+#define I2C_TRISTATE		(iop->pdir &= ~0x00010000)
+#define I2C_READ		((iop->pdat & 0x00010000) != 0)
+#define I2C_SDA(bit)		if(bit) iop->pdat |=  0x00010000; \
+				else    iop->pdat &= ~0x00010000
+#define I2C_SCL(bit)		if(bit) iop->pdat |=  0x00020000; \
+				else    iop->pdat &= ~0x00020000
+#define I2C_DELAY		udelay(5)	/* 1/4 I2C clock duration */
+#endif /* CONFIG_SOFT_I2C */
+
+
+#define CFG_I2C_EEPROM_ADDR	0x57		/* EEPROM IS24C02		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1		/* Bytes of address		*/
+#define CFG_EEPROM_PAGE_WRITE_BITS	3	/* write page size		*/
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10	/* takes up to 10 msec		*/
+
+
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CFG_FLASH_BANKS		{ FLASH_BASE0_PRELIM , FLASH_BASE1_PRELIM }
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+
+#define CFG_WINBOND_83C553	1	/*has a winbond bridge			*/
+#define CFG_USE_WINBOND_IDE	0	/*use winbond 83c553 internal IDE ctrlr */
+#define CFG_WINBOND_ISA_CFG_ADDR    0x80005800	/*pci-isa bridge config addr	*/
+#define CFG_WINBOND_IDE_CFG_ADDR    0x80005900	/*ide config addr		*/
+
+#define CFG_IDE_MAXBUS		2   /* max. 2 IDE busses	*/
+#define CFG_IDE_MAXDEVICE	(CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+/*
+ * NS87308 Configuration
+ */
+#define CFG_NS87308			/* Nat Semi super-io controller on ISA bus */
+
+#define CFG_NS87308_BADDR_10	1
+
+#define CFG_NS87308_DEVS	( CFG_NS87308_UART1   | \
+				  CFG_NS87308_UART2   | \
+				  CFG_NS87308_POWRMAN | \
+				  CFG_NS87308_RTC_APC )
+
+#undef  CFG_NS87308_PS2MOD
+
+#define CFG_NS87308_CS0_BASE	0x0076
+#define CFG_NS87308_CS0_CONF	0x30
+#define CFG_NS87308_CS1_BASE	0x0075
+#define CFG_NS87308_CS1_CONF	0x30
+#define CFG_NS87308_CS2_BASE	0x0074
+#define CFG_NS87308_CS2_CONF	0x30
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE	1
+
+#define CFG_NS16550_CLK		1843200
+
+#define CFG_NS16550_COM1	(CFG_ISA_IO + CFG_NS87308_UART1_BASE)
+#define CFG_NS16550_COM2	(CFG_ISA_IO + CFG_NS87308_UART2_BASE)
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ  33000000	/* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER  2
+
+#define CFG_ROMNAL		7	/*rom/flash next access time		*/
+#define CFG_ROMFAL		11	/*rom/flash access time			*/
+
+#define CFG_REFINT	430	/* no of clock cycles between CBR refresh cycles */
+
+/* the following are for SDRAM only*/
+#define CFG_BSTOPRE	121	/* Burst To Precharge, sets open page interval */
+#define CFG_REFREC		8	/* Refresh to activate interval		*/
+#define CFG_RDLAT		4	/* data latency from read command	*/
+#define CFG_PRETOACT		3	/* Precharge to activate interval	*/
+#define CFG_ACTTOPRE		5	/* Activate to Precharge interval	*/
+#define CFG_ACTORW		3	/* Activate to R/W			*/
+#define CFG_SDMODE_CAS_LAT	3	/* SDMODE CAS latency			*/
+#define CFG_SDMODE_WRAP		0	/* SDMODE wrap type			*/
+#define CFG_SDMODE_BURSTLEN	2	/* SDMODE Burst length 2=4, 3=8		*/
+
+#define CFG_REGISTERD_TYPE_BUFFER   1
+
+/* memory bank settings*/
+/*
+ * only bits 20-29 are actually used from these vales to set the
+ * start/end address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START		0x00000000
+#define CFG_BANK0_END		(CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE	1
+#define CFG_BANK1_START		0x3ff00000
+#define CFG_BANK1_END		0x3fffffff
+#define CFG_BANK1_ENABLE	0
+#define CFG_BANK2_START		0x3ff00000
+#define CFG_BANK2_END		0x3fffffff
+#define CFG_BANK2_ENABLE	0
+#define CFG_BANK3_START		0x3ff00000
+#define CFG_BANK3_END		0x3fffffff
+#define CFG_BANK3_ENABLE	0
+#define CFG_BANK4_START		0x00000000
+#define CFG_BANK4_END		0x00000000
+#define CFG_BANK4_ENABLE	0
+#define CFG_BANK5_START		0x00000000
+#define CFG_BANK5_END		0x00000000
+#define CFG_BANK5_ENABLE	0
+#define CFG_BANK6_START		0x00000000
+#define CFG_BANK6_END		0x00000000
+#define CFG_BANK6_ENABLE	0
+#define CFG_BANK7_START		0x00000000
+#define CFG_BANK7_END		0x00000000
+#define CFG_BANK7_ENABLE	0
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE		0x01
+
+#define CFG_ODCR		0xff	/* configures line driver impedances,	*/
+					/* see 8240 book for bit definitions	*/
+#define CFG_PGMAX		0x32	/* how long the 8240 retains the	*/
+					/* currently accessed page in memory	*/
+					/* see 8240 book for details		*/
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L	(CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U	(CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in DCACHE @ 1GB (no backing mem) */
+#if defined(USE_DINK32)
+#define CFG_IBAT1L	(0x40000000 | BATL_PP_00 )
+#define CFG_IBAT1U	(0x40000000 | BATU_BL_128K )
+#else
+#define CFG_IBAT1L	(CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U	(CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#endif
+
+/* PCI memory */
+#define CFG_IBAT2L	(0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U	(0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc */
+#define CFG_IBAT3L	(0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U	(0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L	CFG_IBAT0L
+#define CFG_DBAT0U	CFG_IBAT0U
+#define CFG_DBAT1L	CFG_IBAT1L
+#define CFG_DBAT1U	CFG_IBAT1U
+#define CFG_DBAT2L	CFG_IBAT2L
+#define CFG_DBAT2U	CFG_IBAT2U
+#define CFG_DBAT3L	CFG_IBAT3L
+#define CFG_DBAT3U	CFG_IBAT3U
+
+/*
+ * 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	20	/* 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	32	/* For MPC8240 CPU			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */
+#endif
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM		0x02	/* Software reboot			*/
+
+
+/* values according to the manual */
+
+#define CONFIG_DRAM_50MHZ	1
+#define CONFIG_SDRAM_50MHZ
+
+#undef	NR_8259_INTS
+#define NR_8259_INTS		1
+
+
+#define CONFIG_DISK_SPINUP_TIME 1000000
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/Sandpoint8245.h b/include/configs/Sandpoint8245.h
new file mode 100644
index 0000000..aa45675
--- /dev/null
+++ b/include/configs/Sandpoint8245.h
@@ -0,0 +1,382 @@
+/*
+ * (C) Copyright 2001, 2002
+ * 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_MPC824X		1
+#define CONFIG_MPC8245		1
+#define CONFIG_SANDPOINT	1
+
+#if 0
+#define USE_DINK32		1
+#else
+#undef USE_DINK32
+#endif
+
+#define CONFIG_CONS_INDEX     3               /* set to '3' for on-chip DUART */
+#define CONFIG_BAUDRATE		9600
+#define CONFIG_DRAM_SPEED	100		/* MHz				*/
+
+#define CONFIG_COMMANDS		( CONFIG_CMD_DFL | \
+				  CFG_CMD_ELF    | \
+				  CFG_CMD_I2C 	 | \
+				  CFG_CMD_EEPROM | \
+				  CFG_CMD_PCI )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any)	*/
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		1		/* undef to save memory		*/
+#define CFG_PROMPT		"=> "		/* Monitor Command Prompt	*/
+#define CFG_CBSIZE		256		/* Console I/O Buffer Size	*/
+#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_LOAD_ADDR		0x00100000	/* default load address		*/
+#define CFG_HZ			1000		/* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI				/* include pci support		*/
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI			/* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100
+#define CONFIG_NATSEMI
+#define CONFIG_NS8382X
+
+#define PCI_ENET0_IOADDR	0x80000000
+#define PCI_ENET0_MEMADDR	0x80000000
+#define	PCI_ENET1_IOADDR	0x81000000
+#define	PCI_ENET1_MEMADDR	0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * 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_MAX_RAM_SIZE	0x10000000
+
+#define CFG_RESET_ADDRESS	0xFFF00100
+
+#if defined (USE_DINK32)
+#define CFG_MONITOR_LEN		0x00030000
+#define CFG_MONITOR_BASE	0x00090000
+#define CFG_RAMBOOT		1
+#define CFG_INIT_RAM_ADDR	(CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#define CFG_INIT_RAM_END	0x10000
+#define CFG_GBL_DATA_SIZE	256  /* 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
+#else
+#undef	CFG_RAMBOOT
+#define CFG_MONITOR_LEN		0x00030000
+#define CFG_MONITOR_BASE	TEXT_BASE
+
+/*#define CFG_GBL_DATA_SIZE    256*/
+#define CFG_GBL_DATA_SIZE	128
+
+#define CFG_INIT_RAM_ADDR     0x40000000
+#define CFG_INIT_RAM_END      0x1000
+#define CFG_GBL_DATA_OFFSET  (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+#endif
+
+#define CFG_FLASH_BASE		0xFFF00000
+#if 0
+#define CFG_FLASH_SIZE		(512 * 1024)	/* sandpoint has tiny eeprom	*/
+#else
+#define CFG_FLASH_SIZE		(1024 * 1024)	/* Unity has onboard 1MByte flash */
+#endif
+#define CFG_ENV_IS_IN_FLASH	1
+#define CFG_ENV_OFFSET		0x00004000	/* Offset of Environment Sector */
+#define CFG_ENV_SIZE		0x00002000	/* Total Size of Environment Sector */
+
+#define CFG_MALLOC_LEN		(512 << 10)	/* Reserve 512 kB for malloc()	*/
+
+#define CFG_MEMTEST_START	0x00000000	/* memtest works on		*/
+#define CFG_MEMTEST_END		0x04000000	/* 0 ... 32 MB in DRAM		*/
+
+#define CFG_EUMB_ADDR		0xFC000000
+
+#define CFG_ISA_MEM		0xFD000000
+#define CFG_ISA_IO		0xFE000000
+
+#define CFG_FLASH_RANGE_BASE	0xFF000000	/* flash memory address range	*/
+#define CFG_FLASH_RANGE_SIZE	0x01000000
+#define FLASH_BASE0_PRELIM	0xFFF00000	/* sandpoint flash		*/
+#define FLASH_BASE1_PRELIM	0xFF000000	/* PMC onboard flash		*/
+
+/*
+ * select i2c support configuration
+ *
+ * Supported configurations are {none, software, hardware} drivers.
+ * If the software driver is chosen, there are some additional
+ * configuration items that the driver uses to drive the port pins.
+ */
+#define CONFIG_HARD_I2C		1		/* To enable I2C support	*/
+#undef  CONFIG_SOFT_I2C				/* I2C bit-banged		*/
+#define CFG_I2C_SPEED		400000		/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		0x7F
+
+#ifdef CONFIG_SOFT_I2C
+#error "Soft I2C is not configured properly.  Please review!"
+#define I2C_PORT		3               /* Port A=0, B=1, C=2, D=3 */
+#define I2C_ACTIVE		(iop->pdir |=  0x00010000)
+#define I2C_TRISTATE		(iop->pdir &= ~0x00010000)
+#define I2C_READ		((iop->pdat & 0x00010000) != 0)
+#define I2C_SDA(bit)		if(bit) iop->pdat |=  0x00010000; \
+				else    iop->pdat &= ~0x00010000
+#define I2C_SCL(bit)		if(bit) iop->pdat |=  0x00020000; \
+				else    iop->pdat &= ~0x00020000
+#define I2C_DELAY		udelay(5)	/* 1/4 I2C clock duration */
+#endif /* CONFIG_SOFT_I2C */
+
+#define CFG_I2C_EEPROM_ADDR	0x57		/* EEPROM IS24C02		*/
+#define CFG_I2C_EEPROM_ADDR_LEN	1		/* Bytes of address		*/
+#define CFG_EEPROM_PAGE_WRITE_BITS	3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10	/* and takes up to 10 msec */
+
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CFG_FLASH_BANKS		{ FLASH_BASE0_PRELIM , FLASH_BASE1_PRELIM }
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+
+#define CFG_WINBOND_83C553	1	/*has a winbond bridge			*/
+#define CFG_USE_WINBOND_IDE	0	/*use winbond 83c553 internal IDE ctrlr */
+#define CFG_WINBOND_ISA_CFG_ADDR    0x80005800	/*pci-isa bridge config addr	*/
+#define CFG_WINBOND_IDE_CFG_ADDR    0x80005900	/*ide config addr		*/
+
+#define CFG_IDE_MAXBUS		2   /* max. 2 IDE busses	*/
+#define CFG_IDE_MAXDEVICE	(CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+/*
+ * NS87308 Configuration
+ */
+#define CFG_NS87308			/* Nat Semi super-io controller on ISA bus */
+
+#define CFG_NS87308_BADDR_10	1
+
+#define CFG_NS87308_DEVS	( CFG_NS87308_UART1   | \
+				  CFG_NS87308_UART2   | \
+				  CFG_NS87308_POWRMAN | \
+				  CFG_NS87308_RTC_APC )
+
+#undef  CFG_NS87308_PS2MOD
+
+#define CFG_NS87308_CS0_BASE	0x0076
+#define CFG_NS87308_CS0_CONF	0x30
+#define CFG_NS87308_CS1_BASE	0x0075
+#define CFG_NS87308_CS1_CONF	0x30
+#define CFG_NS87308_CS2_BASE	0x0074
+#define CFG_NS87308_CS2_CONF	0x30
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE	1
+
+#define CFG_NS16550_CLK		1843200
+
+#define CFG_NS16550_COM1	(CFG_ISA_IO + CFG_NS87308_UART1_BASE)
+#define CFG_NS16550_COM2	(CFG_ISA_IO + CFG_NS87308_UART2_BASE)
+#define CFG_NS16550_COM3	(CFG_EUMB_ADDR + 0x4500)
+#define CFG_NS16550_COM4	(CFG_EUMB_ADDR + 0x4600)
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ  33333333	/* external frequency to pll */
+
+#define CFG_ROMNAL		7	/*rom/flash next access time		*/
+#define CFG_ROMFAL		11	/*rom/flash access time			*/
+
+#define CFG_REFINT	430	/* no of clock cycles between CBR refresh cycles */
+
+/* the following are for SDRAM only*/
+#define CFG_BSTOPRE	121	/* Burst To Precharge, sets open page interval */
+#define CFG_REFREC		8	/* Refresh to activate interval		*/
+#define CFG_RDLAT		4	/* data latency from read command	*/
+#define CFG_PRETOACT		3	/* Precharge to activate interval	*/
+#define CFG_ACTTOPRE		5	/* Activate to Precharge interval	*/
+#define CFG_ACTORW		3	/* Activate to R/W			*/
+#define CFG_SDMODE_CAS_LAT	3	/* SDMODE CAS latency			*/
+#define CFG_SDMODE_WRAP		0	/* SDMODE wrap type			*/
+#if 0
+#define CFG_SDMODE_BURSTLEN	2	/* OBSOLETE!  SDMODE Burst length 2=4, 3=8		*/
+#endif
+
+#define CFG_REGISTERD_TYPE_BUFFER   1
+#define CFG_EXTROM 1
+#define CFG_REGDIMM 0
+
+
+/* memory bank settings*/
+/*
+ * only bits 20-29 are actually used from these vales to set the
+ * start/end address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START		0x00000000
+#define CFG_BANK0_END		(CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE	1
+#define CFG_BANK1_START		0x3ff00000
+#define CFG_BANK1_END		0x3fffffff
+#define CFG_BANK1_ENABLE	0
+#define CFG_BANK2_START		0x3ff00000
+#define CFG_BANK2_END		0x3fffffff
+#define CFG_BANK2_ENABLE	0
+#define CFG_BANK3_START		0x3ff00000
+#define CFG_BANK3_END		0x3fffffff
+#define CFG_BANK3_ENABLE	0
+#define CFG_BANK4_START		0x00000000
+#define CFG_BANK4_END		0x00000000
+#define CFG_BANK4_ENABLE	0
+#define CFG_BANK5_START		0x00000000
+#define CFG_BANK5_END		0x00000000
+#define CFG_BANK5_ENABLE	0
+#define CFG_BANK6_START		0x00000000
+#define CFG_BANK6_END		0x00000000
+#define CFG_BANK6_ENABLE	0
+#define CFG_BANK7_START		0x00000000
+#define CFG_BANK7_END		0x00000000
+#define CFG_BANK7_ENABLE	0
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE		0x01
+
+#define CFG_ODCR		0xff	/* configures line driver impedances,	*/
+					/* see 8240 book for bit definitions	*/
+#define CFG_PGMAX		0x32	/* how long the 8240 retains the	*/
+					/* currently accessed page in memory	*/
+					/* see 8240 book for details		*/
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L	(CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U	(CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in DCACHE @ 1GB (no backing mem) */
+#if defined(USE_DINK32)
+#define CFG_IBAT1L	(0x40000000 | BATL_PP_00 )
+#define CFG_IBAT1U	(0x40000000 | BATU_BL_128K )
+#else
+#define CFG_IBAT1L	(CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U	(CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#endif
+
+/* PCI memory */
+#define CFG_IBAT2L	(0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U	(0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc */
+#define CFG_IBAT3L	(0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U	(0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L	CFG_IBAT0L
+#define CFG_DBAT0U	CFG_IBAT0U
+#define CFG_DBAT1L	CFG_IBAT1L
+#define CFG_DBAT1U	CFG_IBAT1U
+#define CFG_DBAT2L	CFG_IBAT2L
+#define CFG_DBAT2U	CFG_IBAT2U
+#define CFG_DBAT3L	CFG_IBAT3L
+#define CFG_DBAT3U	CFG_IBAT3U
+
+/*
+ * 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	2	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	20	/* 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	32	/* For MPC8240 CPU			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */
+#endif
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM		0x02	/* Software reboot			*/
+
+
+/* values according to the manual */
+
+#define CONFIG_DRAM_50MHZ	1
+#define CONFIG_SDRAM_50MHZ
+
+#undef	NR_8259_INTS
+#define NR_8259_INTS		1
+
+
+#define CONFIG_DISK_SPINUP_TIME 1000000
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/ZUMA.h b/include/configs/ZUMA.h
new file mode 100644
index 0000000..4978f7e
--- /dev/null
+++ b/include/configs/ZUMA.h
@@ -0,0 +1,380 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+
+#include <asm/processor.h>
+
+#define CFG_GT_6426x        GT_64260 /* with a 64260 system controller */
+#define CONFIG_ETHER_PORT_MII	/* use two MII ports */
+#define CONFIG_INTEL_LXT97X	/* Intel LXT97X phy */
+
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
+#include "../board/evb64260/local.h"
+
+#define CONFIG_EVB64260		1	/* this is an EVB64260 board	*/
+#define CONFIG_ZUMA_V2		1	/* always define this for ZUMA v2 */
+
+/* #define CONFIG_ZUMA_V2_OLD	1 */	/* backwards compat for old V2 board */
+
+#define CONFIG_BAUDRATE		38400	/* console baudrate = 38400	*/
+
+#define CONFIG_ECC			/* enable ECC support */
+
+#define CONFIG_750CX			/* we have a 750CX/CXe (override local.h) */
+
+/* which initialization functions to call for this board */
+#define CONFIG_MISC_INIT_R
+#define CONFIG_BOARD_PRE_INIT
+#define CFG_BOARD_ASM_INIT
+
+#define CFG_BOARD_NAME		"Zuma APv2"
+
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2	"> "
+
+/*
+ * The following defines let you select what serial you want to use
+ * for your console driver.
+ *
+ * what to do:
+ * to use the DUART, undef CONFIG_MPSC.	 If you have hacked a serial
+ * cable onto the second DUART channel, change the CFG_DUART port from 1
+ * to 0 below.
+ *
+ * to use the MPSC, #define CONFIG_MPSC.  If you have wired up another
+ * mpsc channel, change CONFIG_MPSC_PORT to the desired value.
+ */
+#define CONFIG_MPSC
+
+#define CONFIG_MPSC_PORT	0
+
+#define CONFIG_NET_MULTI        /* attempt all available adapters */
+
+/* define this if you want to enable GT MAC filtering */
+#define CONFIG_GT_USE_MAC_HASH_TABLE
+
+#if 1
+#define CONFIG_BOOTDELAY	-1	/* autoboot disabled		*/
+#else
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds	*/
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#undef	CONFIG_BOOTARGS
+
+#define CONFIG_BOOTCOMMAND							\
+	"tftpboot && "								\
+	"setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath " \
+	"ip=$ipaddr:$serverip:$gatewayip:"				\
+	"$netmask:$hostname:eth0:none panic=5 && bootm"
+
+#define CONFIG_LOADS_ECHO	0	/* echo off for serial download */
+#define CFG_LOADS_BAUD_CHANGE		/* allow baudrate changes	*/
+
+#undef	CONFIG_WATCHDOG			/* watchdog disabled		*/
+#undef	CONFIG_ALTIVEC			/* undef to disable		*/
+
+#define CONFIG_BOOTP_MASK	(CONFIG_BOOTP_DEFAULT | \
+				 CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_MII		/* enable MII commands */
+
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL | \
+				 CFG_CMD_ASKENV | \
+				 CFG_CMD_BSP	| \
+				 CFG_CMD_JFFS2	| \
+				 CFG_CMD_MII	| \
+				 CFG_CMD_DATE)
+
+/* Flash banks JFFS2 should use */
+#define CFG_JFFS2_FIRST_BANK	1
+#define CFG_JFFS2_NUM_BANKS	2
+
+/* 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	0x00400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x00C00000	/* 4 ... 12 MB in DRAM	*/
+
+#define CFG_LOAD_ADDR		0x00300000	/* default load address */
+
+#define CFG_HZ			1000		/* decr freq: 1ms ticks */
+
+#define CFG_BUS_HZ		133000000	/* 133 MHz		*/
+
+#define CFG_BUS_CLK		CFG_BUS_HZ
+
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_RAM_ADDR	0x40000000
+#define CFG_INIT_RAM_END	0x1000
+#define CFG_GBL_DATA_SIZE	128  /* size in bytes reserved for init data */
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_RAM_LOCK
+
+
+/*-----------------------------------------------------------------------
+ * 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		0xfff00000
+#define CFG_RESET_ADDRESS	0xfff00100
+#define CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 kB for Monitor */
+#define CFG_MONITOR_BASE	CFG_FLASH_BASE
+#define CFG_MALLOC_LEN		(256 << 10)	/* Reserve 256 kB for malloc */
+
+/* areas to map different things with the GT in physical space */
+#define CFG_DRAM_BANKS		4
+#define CFG_DFL_GT_REGS		0x14000000	/* boot time GT_REGS */
+
+/* What to put in the bats. */
+#define CFG_MISC_REGION_BASE	0xf0000000
+
+/* Peripheral Device section */
+#define CFG_GT_REGS		0xf8000000	/* later mapped GT_REGS */
+#define CFG_DEV_BASE		0xf0000000
+#define CFG_DEV0_SIZE		_64M /* zuma flash @ 0xf000.0000*/
+#define CFG_DEV1_SIZE		 _8M /* zuma IDE   @ 0xf400.0000 */
+#define CFG_DEV2_SIZE		 _8M /* unused */
+#define CFG_DEV3_SIZE		 _8M /* unused */
+
+#define CFG_DEV0_PAR		0xc498243c
+	/*     c    4     9     8     2	    4     3     c */
+	/* 33 22|2222|22 22|111 1|11 11|1 1  |	   |      */
+	/* 10 98|7654|32 10|987 6|54 32|1 098|7 654|3 210 */
+	/* 11|00|0100|10 01|100|0 00|10 0|100 0|011 1|100 */
+	/*  3| 0|.... ..| 1| 4 |  0 |  4 |   8 |   7 | 4  */
+
+#define CFG_DEV1_PAR		0xc01b6ac5
+	/*     c    0     1     b     6	    a     c     5 */
+	/* 33 22|2222|22 22|111 1|11 11|1 1  |	   |      */
+	/* 10 98|7654|32 10|987 6|54 32|1 098|7 654|3 210 */
+	/* 11|00|0000|00 01|101|1 01|10 1|010 1|100 0|101 */
+	/*  3| 0|.... ..| 1| 5 |  5 |  5 |   5 |   8 | 5  */
+
+
+
+#define CFG_8BIT_BOOT_PAR	0xc00b5e7c
+
+#define CFG_MPP_CONTROL_0	0x00007777 /* GPP[7:4] : REQ0[1:0] GNT0[1:0] */
+#define CFG_MPP_CONTROL_1	0x00000000 /* GPP[15:12] : GPP[11:8] */
+#define CFG_MPP_CONTROL_2	0x00008888 /* GPP[23:20] : REQ1[1:0] GNT1[1:0] */
+#define CFG_MPP_CONTROL_3	0x00000000 /* GPP[31:28] (int[3:0]) */
+					   /* GPP[27:24] (27 is int4, rest are GPP) */
+
+#define CFG_SERIAL_PORT_MUX	0x00001101 /* 11=MPSC1/MPSC0 01=ETH,  0=only MII */
+#define CFG_GPP_LEVEL_CONTROL	0xf8000000 /* interrupt inputs: GPP[31:27] */
+
+#define CFG_SDRAM_CONFIG	0xe4e18200	/* 0x448 */
+				/* idmas use buffer 1,1
+				   comm use buffer 1
+				   pci use buffer 0,0 (pci1->0 pci0->0)
+				   cpu use buffer 1 (R*18)
+				   normal load (see also ifdef HVL)
+				   standard SDRAM (see also ifdef REG)
+				   non staggered refresh */
+				/* 31:26  25 23	 20 19 18 16 */
+				/* 111001 00 111 0  0  00 1 */
+
+				/* refresh count=0x200
+				   phy interleave disable (by default,
+				   set later by dram config..)
+				   virt interleave enable */
+				/* 15 14 13:0 */
+				/* 1  0	 0x200 */
+
+#define CFG_DEV0_SPACE		CFG_DEV_BASE
+#define CFG_DEV1_SPACE		(CFG_DEV0_SPACE + CFG_DEV0_SIZE)
+#define CFG_DEV2_SPACE		(CFG_DEV1_SPACE + CFG_DEV1_SIZE)
+#define CFG_DEV3_SPACE		(CFG_DEV2_SPACE + CFG_DEV2_SIZE)
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ */
+
+#define PCI_HOST_ADAPTER	0	/* configure ar pci adapter	*/
+#define PCI_HOST_FORCE		1	/* configure as pci host	*/
+#define PCI_HOST_AUTO		2	/* detected via arbiter enable	*/
+
+#define CONFIG_PCI			/* include pci support		*/
+#define CONFIG_PCI_HOST PCI_HOST_FORCE	/* select pci host function	*/
+#define CONFIG_PCI_PNP			/* do pci plug-and-play		*/
+
+/* PCI MEMORY MAP section */
+#define CFG_PCI0_MEM_BASE	0x80000000
+#define CFG_PCI0_MEM_SIZE	_128M
+#define CFG_PCI1_MEM_BASE	0x88000000
+#define CFG_PCI1_MEM_SIZE	_128M
+
+#define CFG_PCI0_0_MEM_SPACE	(CFG_PCI0_MEM_BASE)
+#define CFG_PCI1_0_MEM_SPACE	(CFG_PCI1_MEM_BASE)
+
+/* PCI I/O MAP section */
+#define CFG_PCI0_IO_BASE	0xfa000000
+#define CFG_PCI0_IO_SIZE	_16M
+#define CFG_PCI1_IO_BASE	0xfb000000
+#define CFG_PCI1_IO_SIZE	_16M
+
+#define CFG_PCI0_IO_SPACE	(CFG_PCI0_IO_BASE)
+#define CFG_PCI0_IO_SPACE_PCI	0x00000000
+#define CFG_PCI1_IO_SPACE	(CFG_PCI1_IO_BASE)
+#define CFG_PCI1_IO_SPACE_PCI	0x00000000
+
+
+/*----------------------------------------------------------------------
+ * Initial BAT mappings
+ */
+
+/* NOTES:
+ * 1) GUARDED and WRITE_THRU not allowed in IBATS
+ * 2) CACHEINHIBIT and WRITETHROUGH not allowed together in same BAT
+ */
+
+/* SDRAM */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT0U CFG_IBAT0U
+
+/* init ram */
+#define CFG_IBAT1L  (CFG_INIT_RAM_ADDR | BATL_PP_RW | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U  (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#define CFG_DBAT1L  CFG_IBAT1L
+#define CFG_DBAT1U  CFG_IBAT1U
+
+/* PCI0, PCI1 memory space (starting at PCI0 base, mapped in one BAT) */
+#define CFG_IBAT2L BATL_NO_ACCESS
+#define CFG_IBAT2U CFG_DBAT2U
+#define CFG_DBAT2L (CFG_PCI0_MEM_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT2U (CFG_PCI0_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* GT regs, bootrom, all the devices, PCI I/O */
+#define CFG_IBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW)
+#define CFG_IBAT3U (CFG_MISC_REGION_BASE | BATU_VS | BATU_VP | BATU_BL_256M)
+#define CFG_DBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * 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	3	/* max number of memory banks	*/
+#define CFG_MAX_FLASH_SECT	130	/* max number of sectors on one chip */
+
+#define CFG_EXTRA_FLASH_DEVICE	DEVICE0 /* extra flash at device 0 */
+#define CFG_EXTRA_FLASH_WIDTH	2	/* 16 bit */
+
+#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_FLASH_CFI		1
+
+#define CFG_ENV_IS_IN_FLASH	1
+#define CFG_ENV_SIZE		0x1000	/* Total Size of Environment Sector */
+#define CFG_ENV_SECT_SIZE	0x10000 /* see README - env sect real size */
+#define CFG_ENV_ADDR		(0xfff80000 - CFG_ENV_SECT_SIZE)
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32	/* For all MPC74xx CPUs		 */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */
+#endif
+
+/*-----------------------------------------------------------------------
+ * L2CR setup -- make sure this is right for your board!
+ * look in include/mpc74xx.h for the defines used here
+ */
+
+#define CFG_L2
+
+#ifdef CONFIG_750CX
+#define L2_INIT		0
+#else
+#define L2_INIT		(L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
+			L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
+#endif
+
+#define L2_ENABLE	(L2_INIT | L2CR_L2E)
+
+/*------------------------------------------------------------------------
+ * Real time clock
+ */
+#define CONFIG_RTC_DS1302
+
+
+/*------------------------------------------------------------------------
+ * Galileo I2C driver
+ */
+#define CONFIG_GT_I2C
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM	0x02		/* Software reboot		    */
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/shannon.h b/include/configs/shannon.h
new file mode 100644
index 0000000..c281707
--- /dev/null
+++ b/include/configs/shannon.h
@@ -0,0 +1,218 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Configuation settings for the Shannon/TuxScreen/IS2630 WebPhone Board.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * If we are developing, we might want to start armboot from ram
+ * so we MUST NOT initialize critical regs like mem-timing ...
+ */
+
+/*
+ * we just run in non-critical mode now, because we use the Inferno-Loader to
+ * bring us to live
+ */
+#define CONFIG_INFERNO			/* we are using the inferno bootldr */
+#undef CONFIG_INIT_CRITICAL		/* undef for developing */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_SA1100		1	/* This is an SA1100 CPU	*/
+#define CONFIG_SHANNON		1	/* on an SHANNON/TuxScreen Board      */
+
+#undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_MALLOC_SIZE	(CFG_ENV_SIZE + 128*1024)
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_DRIVER_3C589	1
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL3          1	/* we use SERIAL 3  */
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE		115200
+
+#if 0 /* XXX - cannot test IDE anyway, so disabled for now - wd */
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL	| \
+				 CFG_CMD_PCMCIA	| \
+				 CFG_CMD_IDE)
+#endif /* 0 */
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define CONFIG_BOOTDELAY	3
+#define CONFIG_BOOTARGS    	"root=ramfs devfs=mount console=ttySA0,115200"
+#define CONFIG_NETMASK          255.255.0.0
+#define CONFIG_BOOTCOMMAND	"help"
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	230400		/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	2		/* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define	CFG_LONGHELP				/* undef to save memory		*/
+#define	CFG_PROMPT		"TuxScreen # "	/* Monitor Command Prompt	*/
+#define	CFG_CBSIZE		256		/* Console I/O Buffer Size	*/
+#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	0xc0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0xc0800000	/* 4 ... 8 MB in DRAM	*/
+
+#undef  CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */
+
+#define	CFG_LOAD_ADDR		0xd0000000	/* default load address	*/
+
+#define	CFG_HZ			3686400		/* incrementer freq: 3.6864 MHz */
+#define CFG_CPUSPEED		0x09		/* 190 MHz for Shannon */
+
+						/* valid baudrates */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_DOS_PARTITION	1		/* DOS partitiion support */
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE	(128*1024)	/* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ	(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ	(4*1024)	/* FIQ stack */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+/* BE CAREFUL */
+#define CONFIG_NR_DRAM_BANKS	4	   /* we have 4 banks of EDORAM */
+#define PHYS_SDRAM_1		0xc0000000 /* RAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE	0x00400000 /* 4 MB */
+#define PHYS_SDRAM_2		0xc8000000 /* RAM Bank #2 */
+#define PHYS_SDRAM_2_SIZE	0x00400000 /* 4 MB */
+#define PHYS_SDRAM_3            0xd0000000 /* RAM Bank #3 */
+#define PHYS_SDRAM_3_SIZE       0x00400000 /* 4 MB */
+#define PHYS_SDRAM_4            0xd8000000 /* RAM Bank #4 */
+#define PHYS_SDRAM_4_SIZE       0x00400000 /* 4 MB */
+
+
+#define PHYS_FLASH_1		0x00000000 /* Flash Bank #1 */
+#define PHYS_FLASH_SIZE		0x00400000 /* 4 MB */
+
+#define CFG_FLASH_BASE		PHYS_FLASH_1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	(31+4)	/* max number of sectors on one chip	*/
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT	(2*CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT	(2*CFG_HZ) /* Timeout for Flash Write */
+
+#define	CFG_ENV_IS_IN_FLASH	1
+#ifdef CONFIG_INFERNO
+/* we take the last sector, 128 KB in size, but we only use 4 KB of it for stack reasons */
+#define CFG_ENV_ADDR		(PHYS_FLASH_1 + 0x003E0000)	/* Addr of Environment Sector	*/
+#define CFG_ENV_SIZE		0x4000	/* Total Size of Environment Sector	*/
+#else
+#define CFG_ENV_ADDR		(PHYS_FLASH_1 + 0x1C000)	/* Addr of Environment Sector	*/
+#define CFG_ENV_SIZE		0x4000	/* Total Size of Environment Sector	*/
+#endif
+
+/*-----------------------------------------------------------------------
+ * PCMCIA stuff
+ *-----------------------------------------------------------------------
+ *
+ */
+
+/* we pick the upper one */
+
+#define CONFIG_PCMCIA_SLOT_A
+
+#define CFG_PCMCIA_IO_ADDR	(0x20000000)
+#define CFG_PCMCIA_IO_SIZE	( 64 << 20 )
+#define CFG_PCMCIA_DMA_ADDR	(0x24000000)
+#define CFG_PCMCIA_DMA_SIZE	( 64 << 20 )
+#define CFG_PCMCIA_ATTRB_ADDR	(0x2C000000)
+#define CFG_PCMCIA_ATTRB_SIZE	( 64 << 20 )
+#define CFG_PCMCIA_MEM_ADDR	(0x28000000)
+#define CFG_PCMCIA_MEM_SIZE	( 64 << 20 )
+
+/* in fact, MEM and ATTRB are swapped - has to be corrected soon in cmd_pcmcia or so */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff (Supports IDE harddisk on PCMCIA Adapter)
+ *-----------------------------------------------------------------------
+ */
+
+#define	CONFIG_IDE_PCCARD	1	/* Use IDE with PC Card	Adapter	*/
+
+#undef	CONFIG_IDE_PCMCIA		/* Direct IDE    not supported	*/
+#undef	CONFIG_IDE_LED			/* LED   for ide not supported	*/
+#undef	CONFIG_IDE_RESET		/* reset for ide not supported	*/
+
+#define CFG_IDE_MAXBUS		1	/* max. 1 IDE bus		*/
+#define CFG_IDE_MAXDEVICE	1	/* max. 1 drive per IDE bus	*/
+
+#define CFG_ATA_IDE0_OFFSET	0x0000
+
+/* it's simple, all regs are in I/O space */
+#define CFG_ATA_BASE_ADDR	CFG_PCMCIA_ATTRB_ADDR
+
+/* Offset for data I/O			*/
+#define CFG_ATA_DATA_OFFSET	(CFG_ATA_BASE_ADDR)
+
+/* Offset for normal register accesses	*/
+#define CFG_ATA_REG_OFFSET	(CFG_ATA_BASE_ADDR)
+
+/* Offset for alternate registers	*/
+#define CFG_ATA_ALT_OFFSET	(CFG_ATA_BASE_ADDR)
+
+/*-----------------------------------------------------------------------
+ */
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/trab.h b/include/configs/trab.h
new file mode 100644
index 0000000..7096767
--- /dev/null
+++ b/include/configs/trab.h
@@ -0,0 +1,243 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn <gj@denx.de>
+ *
+ * Configuation settings for the TRAB board.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * If we are developing, we might want to start armboot from ram
+ * so we MUST NOT initialize critical regs like mem-timing ...
+ */
+#define CONFIG_INIT_CRITICAL		/* undef for developing */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARM920T		1	/* This is an arm920t CPU	*/
+#define CONFIG_S3C2400		1	/* in a SAMSUNG S3C2400 SoC     */
+#define CONFIG_TRAB		1	/* on a TRAB Board      */
+#undef CONFIG_TRAB_50MHZ		/* run the CPU at 50 MHz */
+
+/* input clock of PLL */
+#define CONFIG_PLL_INPUT_FREQ	12000000 /* TRAB has 12 MHz input clock */
+
+#undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */
+
+#define CONFIG_CMDLINE_TAG	 1	/* enable passing of ATAGs	*/
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG	 1
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_MALLOC_SIZE	(CFG_ENV_SIZE + 128*1024)
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_DRIVER_CS8900	1	/* we have a CS8900 on-board */
+#define CS8900_BASE		0x07000300 /* agrees with WIN CE PA */
+#define CS8900_BUS16		1 /* the Linux driver does accesses as shorts */
+
+#define CONFIG_VFD		1	/* VFD linear frame buffer driver */
+#define VFD_TEST_LOGO		1	/* output a test logo to the VFDs */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL1          1	/* we use SERIAL 1 on TRAB */
+
+#define CONFIG_HWFLOW			/* include RTS/CTS flow control support	*/
+
+#define CONFIG_MODEM_SUPPORT	1	/* enable modem initialization stuff */
+
+#define	CONFIG_MODEM_KEY_MAGIC	"23"	/* hold down these keys to enable modem */
+
+/*
+ * The following enables modem debugging stuff. The dbg() and
+ * 'char screen[1024]' are used for debug printfs. Unfortunately,
+ * it is usable only from BDI
+ */
+#undef CONFIG_MODEM_SUPPORT_DEBUG
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE		115200
+
+#define	CONFIG_TIMESTAMP	1	/* Print timestamp info for images */
+
+#ifdef CONFIG_HWFLOW
+#define CONFIG_COMMANDS_ADD_HWFLOW	CFG_CMD_HWFLOW
+#else
+#define	CONFIG_COMMANDS_ADD_HWFLOW	0
+#endif
+
+#ifdef	CONFIG_VFD
+#define CONFIG_COMMANDS_ADD_VFD		CFG_CMD_VFD
+#else
+#define CONFIG_COMMANDS_ADD_VFD		0
+#endif
+
+#ifndef USE_920T_MMU
+#define CONFIG_COMMANDS		((CONFIG_CMD_DFL & ~CFG_CMD_CACHE) | \
+				 CFG_CMD_BSP			| \
+				 CONFIG_COMMANDS_ADD_HWFLOW	| \
+				 CONFIG_COMMANDS_ADD_VFD	)
+#else
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL			| \
+				 CFG_CMD_BSP			| \
+				 CONFIG_COMMANDS_ADD_HWFLOW	| \
+				 CONFIG_COMMANDS_ADD_VFD	)
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+#define CONFIG_BOOTDELAY	5
+#define CONFIG_PREBOOT		"echo;echo *** booting ***;echo"
+#define CONFIG_BOOTARGS    	"console=ttyS0"
+#define CONFIG_ETHADDR		00:D0:93:00:61:11
+#define CONFIG_NETMASK          255.255.255.0
+#define CONFIG_IPADDR		192.168.3.27
+#define CONFIG_SERVERIP		192.168.3.1
+#define CONFIG_BOOTCOMMAND	"run flash_nfs"
+#define	CONFIG_EXTRA_ENV_SETTINGS	\
+	"nfs_args=setenv bootargs root=/dev/nfs rw " \
+		"nfsroot=$(serverip):$(rootpath)\0" \
+	"rootpath=/opt/eldk/arm_920TDI\0" \
+	"ram_args=setenv bootargs root=/dev/ram rw\0" \
+	"add_net=setenv bootargs $(bootargs) ethaddr=$(ethaddr) " \
+		"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off\0" \
+	"add_misc=setenv bootargs $(bootargs) console=ttyS0 panic=1\0" \
+	"load=tftp 0xC100000 /tftpboot/TRAB/u-boot.bin\0" \
+	"update=protect off 1:0-7;era 1:0-7;cp.b 0xc100000 0 $(filesize);" \
+		"setenv filesize;saveenv\0" \
+	"loadfile=/tftpboot/TRAB/pImage\0" \
+	"loadaddr=c400000\0" \
+	"net_load=tftpboot $(loadaddr) $(loadfile)\0" \
+	"net_nfs=run net_load nfs_args add_net add_misc;bootm\0" \
+	"kernel_addr=00040000\0" \
+	"flash_nfs=run nfs_args add_net add_misc;bootm $(kernel_addr)\0" \
+	"mdm_init1=ATZ\0" \
+	"mdm_init2=ATS0=1\0" \
+	"mdm_flow_control=rts/cts\0"
+
+#if 0	/* disabled for development */
+#define	CONFIG_AUTOBOOT_KEYED		/* Enable password protection	*/
+#define CONFIG_AUTOBOOT_PROMPT	"\nEnter password - autoboot in %d sec...\n"
+#define CONFIG_AUTOBOOT_DELAY_STR	"system"	/* 1st password	*/
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	115200		/* speed to run kgdb serial port */
+/* what's this ? it's not used anywhere */
+#define CONFIG_KGDB_SER_INDEX	1		/* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define	CFG_LONGHELP				/* undef to save memory		*/
+#define	CFG_PROMPT		"TRAB # "	/* Monitor Command Prompt	*/
+#define	CFG_CBSIZE		256		/* Console I/O Buffer Size	*/
+#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	0x0c000000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0d000000	/* 16 MB in DRAM	*/
+
+#undef  CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */
+
+#define	CFG_LOAD_ADDR		0x0cf00000	/* default load address	*/
+
+#ifdef CONFIG_TRAB_50MHZ
+/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
+/* it to wrap 100 times (total 1562500) to get 1 sec. */
+/* this should _really_ be calculated !! */
+#define	CFG_HZ			1562500
+#else
+/* the PWM TImer 4 uses a counter of 10390 for 10 ms, so we need */
+/* it to wrap 100 times (total 1039000) to get 1 sec. */
+/* this should _really_ be calculated !! */
+#define	CFG_HZ			1039000
+#endif
+
+/* valid baudrates */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_MISC_INIT_R		/* have misc_init_r() function	*/
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE	(128*1024)	/* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ	(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ	(4*1024)	/* FIQ stack */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS	1	   /* we have 1 bank of DRAM */
+#define PHYS_SDRAM_1		0x0c000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE	0x01000000 /* 16 MB */
+
+#define PHYS_FLASH_1		0x00000000 /* Flash Bank #1 */
+#define PHYS_FLASH_SIZE		0x00800000 /* 8 MB */
+
+/* The following #defines are needed to get flash environment right */
+#define	CFG_MONITOR_BASE	PHYS_FLASH_1
+#define	CFG_MONITOR_LEN		(256 << 10)
+
+#define CFG_FLASH_BASE		PHYS_FLASH_1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks */
+#define CFG_MAX_FLASH_SECT	(71)	/* max number of sectors on one chip */
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT	(2*CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT	(2*CFG_HZ) /* Timeout for Flash Write */
+
+#define	CFG_ENV_IS_IN_FLASH	1
+
+/* Address and size of Primary Environment Sector	*/
+#define CFG_ENV_ADDR		(PHYS_FLASH_1 + 0x4000)
+#define CFG_ENV_SIZE		0x4000
+
+/* Address and size of Redundant Environment Sector	*/
+#define CFG_ENV_OFFSET_REDUND	(CFG_ENV_ADDR+CFG_ENV_SIZE)
+#define CFG_ENV_SIZE_REDUND	(CFG_ENV_SIZE)
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/utx8245.h b/include/configs/utx8245.h
new file mode 100644
index 0000000..5aec47a
--- /dev/null
+++ b/include/configs/utx8245.h
@@ -0,0 +1,346 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Gregory E. Allen, gallen@arlut.utexas.edu
+ * Matthew E. Karger, karger@arlut.utexas.edu
+ * Applied Research Laboratories, The University of Texas at Austin
+ *
+ * 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
+ */
+
+/*
+ *
+ * Configuration settings for the utx8245 board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X		1
+#define CONFIG_MPC8245		1
+#define CONFIG_UTX8245		1
+#define DEBUG				1
+
+#define CONFIG_CONS_INDEX	1
+#define CONFIG_BAUDRATE		57600
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_BOOTDELAY	5
+#define CONFIG_AUTOBOOT_PROMPT 	"autoboot in %d seconds\n"
+#define CONFIG_BOOTCOMMAND	"bootm FF920000 FF800000"	/* autoboot command	*/
+#define CONFIG_BOOTARGS		"root=/dev/ram console=ttyS0,57600" /* RAMdisk */
+#define CONFIG_ETHADDR		41:52:4c:61:00:01	/* MAC address */
+#define CONFIG_SERVERIP		10.8.17.105
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_COMMANDS		(CFG_CMD_DFL | CFG_CMD_BDI | CFG_CMD_PCI \
+								| CFG_CMD_FLASH | CFG_CMD_MEMORY \
+								| CFG_CMD_ENV | CFG_CMD_CONSOLE \
+								| CFG_CMD_LOADS | CFG_CMD_LOADB \
+								| CFG_CMD_IMI | CFG_CMD_CACHE \
+								| CFG_CMD_RUN | CFG_CMD_ECHO \
+								| CFG_CMD_REGINFO | CFG_CMD_NET\
+								| CFG_CMD_DHCP)
+
+/* 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	*/
+#define CFG_CBSIZE	256		/* Console I/O Buffer Size	*/
+
+/* Print Buffer Size */
+#define CFG_PBSIZE	(CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+
+#define	CFG_MAXARGS	16		/* max number of command args	*/
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+#define CFG_LOAD_ADDR	0x00100000	/* Default load address		*/
+
+
+/*-----------------------------------------------------------------------
+ * PCI configuration
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI				/* include pci support		*/
+#undef CONFIG_PCI_PNP
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_NET_MULTI
+#define CONFIG_EEPRO100
+
+#define PCI_ENET0_IOADDR	0x80000000
+#define PCI_ENET0_MEMADDR	0x80000000
+#define PCI_FIREWIRE_IOADDR	0x81000000
+#define PCI_FIREWIRE_MEMADDR	0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * 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_MAX_RAM_SIZE    0x10000000	/* amount of SDRAM  */
+
+
+/* even though FLASHP_BASE is FF800000, with 2MB on RCS0, the
+ * reset vector is actually located at FF800100, but the 8245
+ * takes care of us.
+ */
+#define CFG_RESET_ADDRESS   0xFFF00100
+
+#define CFG_EUMB_ADDR	    0xFC000000
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+
+#define CFG_MONITOR_LEN	    (256 << 10) /* Reserve 256 kB for Monitor	*/
+#define CFG_MALLOC_LEN	    (128 << 10) /* Reserve 128 kB for malloc()	*/
+
+/*#define CFG_DRAM_TEST		1 */
+#define CFG_MEMTEST_START   0x00003000	/* memtest works on	0...256 MB	*/
+#define CFG_MEMTEST_END	    0x0ff8ffa8	/* in SDRAM, skips exception */
+										/* vectors and U-Boot */
+
+
+/*--------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ *------------------------------------------------------------------*/
+#define CFG_GBL_DATA_SIZE    128	/* Size in bytes reserved for */
+									/* initial data */
+#define CFG_INIT_RAM_ADDR     0x40000000
+#define CFG_INIT_RAM_END      0x1000
+#define CFG_GBL_DATA_OFFSET  (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+/*--------------------------------------------------------------------
+ * NS16550 Configuration
+ *------------------------------------------------------------------*/
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE	1
+
+#define CFG_NS16550_CLK		get_bus_freq(0)
+
+#define CFG_NS16550_COM1	(CFG_EUMB_ADDR + 0x4500)
+#define CFG_NS16550_COM2	(CFG_EUMB_ADDR + 0x4600)
+
+/*--------------------------------------------------------------------
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ *------------------------------------------------------------------*/
+
+#define CONFIG_SYS_CLK_FREQ  33000000
+#define CFG_HZ				1000
+
+#define CFG_ETH_DEV_FN	     0x7800
+#define CFG_ETH_IOBASE	     0x00104000
+
+
+/*--------------------------------------------------------------------
+ *	Memory Control Configuration Register values
+ *	- see sec. 4.12 of MPC8245 UM
+ *------------------------------------------------------------------*/
+
+/* MCCR1 */
+#define CFG_ROMNAL	    0
+#define CFG_ROMFAL	    2			/* (tacc=70ns)*mem_freq - 2 */
+#define CFG_BANK0_ROW	2			/* SDRAM bank 7-0 row address */
+#define CFG_BANK1_ROW	2			/* 	bit count */
+#define CFG_BANK2_ROW	0
+#define CFG_BANK3_ROW	0
+#define CFG_BANK4_ROW	0
+#define CFG_BANK5_ROW	0
+#define CFG_BANK6_ROW	0
+#define CFG_BANK7_ROW	0
+
+/* MCCR2, refresh interval clock cycles */
+#define CFG_REFINT	    480	    /* 33 MHz SDRAM clock was 480 */
+
+/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4 */
+#define CFG_BSTOPRE	    1023	/* burst to precharge[0..9], */
+								/* sets open page interval */
+
+/* MCCR3 */
+#define CFG_REFREC	    5	    /* Refresh to activate interval, trc */
+
+/* MCCR4 */
+#define CFG_PRETOACT	    2	    /* trp */
+#define CFG_ACTTOPRE	    7	    /* trcd + (burst length - 1) + tdrl */
+#define CFG_SDMODE_CAS_LAT  3	    /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP	    0	    /* SDMODE wrap type, sequential */
+#define CFG_ACTORW	    	2		/* trcd min */
+#define CFG_DBUS_SIZE2		1		/* set for 8-bit RCS1, clear for 32,64 */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+#define CFG_EXTROM	    1
+#define CFG_REGDIMM	    0
+
+/* calculate according to formula in sec. 6-22 of 8245 UM */
+#define CFG_PGMAX           50		/* how long the 8245 retains the */
+									/* currently accessed page in memory */
+									/* was 45 */
+
+#define CFG_SDRAM_DSCD	0x20	/* SDRAM data in sample clock delay - note */
+								/* bottom 3 bits MUST be 0 */
+
+#define CFG_DLL_MAX_DELAY	0x04
+#define CFG_DLL_EXTEND	0x80
+#define CFG_PCI_HOLD_DEL 0x20
+
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these values to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8245 user manual.
+ */
+
+#define CFG_BANK0_START	    0x00000000
+#define CFG_BANK0_END	    (CFG_MAX_RAM_SIZE/2 - 1)
+#define CFG_BANK0_ENABLE    1
+#define CFG_BANK1_START	    CFG_MAX_RAM_SIZE/2
+#define CFG_BANK1_END	    (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK1_ENABLE    1
+#define CFG_BANK2_START	    0x3ff00000		/* not available in this design */
+#define CFG_BANK2_END	    0x3fffffff
+#define CFG_BANK2_ENABLE    0
+#define CFG_BANK3_START	    0x3ff00000
+#define CFG_BANK3_END	    0x3fffffff
+#define CFG_BANK3_ENABLE    0
+#define CFG_BANK4_START	    0x3ff00000
+#define CFG_BANK4_END	    0x3fffffff
+#define CFG_BANK4_ENABLE    0
+#define CFG_BANK5_START	    0x3ff00000
+#define CFG_BANK5_END	    0x3fffffff
+#define CFG_BANK5_ENABLE    0
+#define CFG_BANK6_START	    0x3ff00000
+#define CFG_BANK6_END	    0x3fffffff
+#define CFG_BANK6_ENABLE    0
+#define CFG_BANK7_START	    0x3ff00000
+#define CFG_BANK7_END	    0x3fffffff
+#define CFG_BANK7_ENABLE    0
+
+/*--------------------------------------------------------------------
+ * 4.4 - Output Driver Control Register
+ *------------------------------------------------------------------*/
+#define CFG_ODCR	    0xe5
+
+/*--------------------------------------------------------------------
+ * 4.8 - Error Handling Registers
+ *------------------------------------------------------------------*/
+#define CFG_ERRENR1	0x11	/* enable SDRAM refresh overflow error */
+
+/* SDRAM 0-256 MB */
+#define CFG_IBAT0L  (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U  (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in dcache */
+#define CFG_IBAT1L  (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U  (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory */
+#define CFG_IBAT2L  (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U  (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc. */
+#define CFG_IBAT3L  (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U  (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L  CFG_IBAT0L
+#define CFG_DBAT0U  CFG_IBAT0U
+#define CFG_DBAT1L  CFG_IBAT1L
+#define CFG_DBAT1U  CFG_IBAT1U
+#define CFG_DBAT2L  CFG_IBAT2L
+#define CFG_DBAT2U  CFG_IBAT2U
+#define CFG_DBAT3L  CFG_IBAT3L
+#define CFG_DBAT3U  CFG_IBAT3U
+
+/*
+ * 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 (AMD AM29LV116D)
+ */
+#define CFG_FLASH_BASE	    0xFF800000
+
+#define CFG_MAX_FLASH_BANKS	1	/* Max number of flash banks */
+#define CFG_MAX_FLASH_SECT	35	/* Max number of sectors in one bank */
+
+#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
+#define CFG_FLASH_WRITE_TOUT	500		/* Timeout for Flash Write (in ms)	*/
+
+	/* Warning: environment is not EMBEDDED in the U-Boot code.
+	 * It's stored in flash separately.
+	 */
+#define CFG_ENV_IS_IN_FLASH	    1
+
+#define CFG_ENV_ADDR		0xFF9FA000	/* flash sector SA33 */
+#define CFG_ENV_SIZE		0x2000		/* Size of the Environment */
+#define CFG_ENV_OFFSET		0			/* starting right at the beginning */
+#define CFG_ENV_SECT_SIZE	0x2000 		/* Size of the Environment Sector */
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE	32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM		0x02	/* Software reboot			*/
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/dtt.h b/include/dtt.h
new file mode 100644
index 0000000..f3d95ff
--- /dev/null
+++ b/include/dtt.h
@@ -0,0 +1,67 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.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
+ */
+
+/*
+ * Digital Thermometers and Thermostats.
+ */
+#ifndef _DTT_H_
+#define _DTT_H_
+
+#if defined(CONFIG_DTT_LM75) || defined(CONFIG_DTT_DS1621)
+#define CONFIG_DTT				/* We have a DTT */
+
+#define DTT_COMMERCIAL_MAX_TEMP	70		/* 0 - +70 C */
+#define DTT_INDUSTRIAL_MAX_TEMP	85		/* -40 - +85 C */
+#define DTT_AUTOMOTIVE_MAX_TEMP	105		/* -40 - +105 C */
+#ifndef CFG_DTT_MAX_TEMP
+#define CFG_DTT_MAX_TEMP DTT_COMMERCIAL_MAX_TEMP
+#endif
+#ifndef CFG_DTT_HYSTERESIS
+#define CFG_DTT_HYSTERESIS	5		/* 5 C */
+#endif
+
+extern int dtt_init (void);
+extern int dtt_read(int sensor, int reg);
+extern int dtt_write(int sensor, int reg, int val);
+extern int dtt_get_temp(int sensor);
+#endif
+
+#if defined(CONFIG_DTT_LM75)
+#define DTT_READ_TEMP		0x0
+#define DTT_CONFIG		0x1
+#define DTT_TEMP_HYST		0x2
+#define DTT_TEMP_SET		0x3
+#endif
+
+#if defined(CONFIG_DTT_DS1621)
+#define DTT_READ_TEMP		0xAA
+#define DTT_READ_COUNTER	0xA8
+#define DTT_READ_SLOPE		0xA9
+#define DTT_WRITE_START_CONV	0xEE
+#define DTT_WRITE_STOP_CONV	0x22
+#define DTT_TEMP_HIGH		0xA1
+#define DTT_TEMP_LOW		0xA2
+#define DTT_CONFIG		0xAC
+#endif
+
+#endif /* _DTT_H_ */
diff --git a/include/environment.h b/include/environment.h
new file mode 100644
index 0000000..fe8465b
--- /dev/null
+++ b/include/environment.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2002
+ * 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
+ */
+
+#ifndef _ENVIRONMENT_H_
+#define _ENVIRONMENT_H_	1
+
+/**************************************************************************
+ *
+ * The "environment" is stored as a list of '\0' terminated
+ * "name=value" strings. The end of the list is marked by a double
+ * '\0'. New entries are always added at the end. Deleting an entry
+ * shifts the remaining entries to the front. Replacing an entry is a
+ * combination of deleting the old value and adding the new one.
+ *
+ * The environment is preceeded by a 32 bit CRC over the data part.
+ *
+ **************************************************************************
+ */
+
+#if defined(CFG_ENV_IS_IN_FLASH)
+# ifndef  CFG_ENV_ADDR
+#  define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET)
+# endif
+# ifndef  CFG_ENV_OFFSET
+#  define CFG_ENV_OFFSET (CFG_ENV_ADDR - CFG_FLASH_BASE)
+# endif
+# if !defined(CFG_ENV_ADDR_REDUND) && defined(CFG_ENV_OFFSET_REDUND)
+#  define CFG_ENV_ADDR_REDUND	(CFG_FLASH_BASE + CFG_ENV_OFFSET_REDUND)
+# endif
+# ifndef  CFG_ENV_SIZE
+#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE
+# endif
+# if defined(CFG_ENV_ADDR_REDUND) && !defined(CFG_ENV_SIZE_REDUND)
+#  define CFG_ENV_SIZE_REDUND	CFG_ENV_SIZE
+# endif
+# if (CFG_ENV_ADDR >= CFG_MONITOR_BASE) && \
+     (CFG_ENV_ADDR+CFG_ENV_SIZE) <= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#  define ENV_IS_EMBEDDED	1
+# endif
+# if defined(CFG_ENV_ADDR_REDUND) || defined(CFG_ENV_OFFSET_REDUND)
+#  define CFG_REDUNDAND_ENVIRONMENT	1
+# endif
+#endif	/* CFG_ENV_IS_IN_FLASH */
+
+
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+# define ENV_HEADER_SIZE	(sizeof(unsigned long) + 1)
+#else
+# define ENV_HEADER_SIZE	(sizeof(unsigned long))
+#endif
+
+
+#define ENV_SIZE (CFG_ENV_SIZE - ENV_HEADER_SIZE)
+
+typedef	struct environment_s {
+	unsigned long	crc;		/* CRC32 over data bytes	*/
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+	unsigned char	flags;		/* active/obsolete flags	*/
+#endif
+	unsigned char	data[ENV_SIZE]; /* Environment data		*/
+} env_t;
+
+#endif	/* _ENVIRONMENT_H_ */
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
new file mode 100644
index 0000000..cff850f
--- /dev/null
+++ b/include/linux/byteorder/generic.h
@@ -0,0 +1,180 @@
+#ifndef _LINUX_BYTEORDER_GENERIC_H
+#define _LINUX_BYTEORDER_GENERIC_H
+
+/*
+ * linux/byteorder_generic.h
+ * Generic Byte-reordering support
+ *
+ * Francois-Rene Rideau <fare@tunes.org> 19970707
+ *    gathered all the good ideas from all asm-foo/byteorder.h into one file,
+ *    cleaned them up.
+ *    I hope it is compliant with non-GCC compilers.
+ *    I decided to put __BYTEORDER_HAS_U64__ in byteorder.h,
+ *    because I wasn't sure it would be ok to put it in types.h
+ *    Upgraded it to 2.1.43
+ * Francois-Rene Rideau <fare@tunes.org> 19971012
+ *    Upgraded it to 2.1.57
+ *    to please Linus T., replaced huge #ifdef's between little/big endian
+ *    by nestedly #include'd files.
+ * Francois-Rene Rideau <fare@tunes.org> 19971205
+ *    Made it to 2.1.71; now a facelift:
+ *    Put files under include/linux/byteorder/
+ *    Split swab from generic support.
+ *
+ * TODO:
+ *   = Regular kernel maintainers could also replace all these manual
+ *    byteswap macros that remain, disseminated among drivers,
+ *    after some grep or the sources...
+ *   = Linus might want to rename all these macros and files to fit his taste,
+ *    to fit his personal naming scheme.
+ *   = it seems that a few drivers would also appreciate
+ *    nybble swapping support...
+ *   = every architecture could add their byteswap macro in asm/byteorder.h
+ *    see how some architectures already do (i386, alpha, ppc, etc)
+ *   = cpu_to_beXX and beXX_to_cpu might some day need to be well
+ *    distinguished throughout the kernel. This is not the case currently,
+ *    since little endian, big endian, and pdp endian machines needn't it.
+ *    But this might be the case for, say, a port of Linux to 20/21 bit
+ *    architectures (and F21 Linux addict around?).
+ */
+
+/*
+ * The following macros are to be defined by <asm/byteorder.h>:
+ *
+ * Conversion of long and short int between network and host format
+ *	ntohl(__u32 x)
+ *	ntohs(__u16 x)
+ *	htonl(__u32 x)
+ *	htons(__u16 x)
+ * It seems that some programs (which? where? or perhaps a standard? POSIX?)
+ * might like the above to be functions, not macros (why?).
+ * if that's true, then detect them, and take measures.
+ * Anyway, the measure is: define only ___ntohl as a macro instead,
+ * and in a separate file, have
+ * unsigned long inline ntohl(x){return ___ntohl(x);}
+ *
+ * The same for constant arguments
+ *	__constant_ntohl(__u32 x)
+ *	__constant_ntohs(__u16 x)
+ *	__constant_htonl(__u32 x)
+ *	__constant_htons(__u16 x)
+ *
+ * Conversion of XX-bit integers (16- 32- or 64-)
+ * between native CPU format and little/big endian format
+ * 64-bit stuff only defined for proper architectures
+ *	cpu_to_[bl]eXX(__uXX x)
+ *	[bl]eXX_to_cpu(__uXX x)
+ *
+ * The same, but takes a pointer to the value to convert
+ *	cpu_to_[bl]eXXp(__uXX x)
+ *	[bl]eXX_to_cpup(__uXX x)
+ *
+ * The same, but change in situ
+ *	cpu_to_[bl]eXXs(__uXX x)
+ *	[bl]eXX_to_cpus(__uXX x)
+ *
+ * See asm-foo/byteorder.h for examples of how to provide
+ * architecture-optimized versions
+ *
+ */
+
+
+#if defined(__KERNEL__)
+/*
+ * inside the kernel, we can use nicknames;
+ * outside of it, we must avoid POSIX namespace pollution...
+ */
+#define cpu_to_le64 __cpu_to_le64
+#define le64_to_cpu __le64_to_cpu
+#define cpu_to_le32 __cpu_to_le32
+#define le32_to_cpu __le32_to_cpu
+#define cpu_to_le16 __cpu_to_le16
+#define le16_to_cpu __le16_to_cpu
+#define cpu_to_be64 __cpu_to_be64
+#define be64_to_cpu __be64_to_cpu
+#define cpu_to_be32 __cpu_to_be32
+#define be32_to_cpu __be32_to_cpu
+#define cpu_to_be16 __cpu_to_be16
+#define be16_to_cpu __be16_to_cpu
+#define cpu_to_le64p __cpu_to_le64p
+#define le64_to_cpup __le64_to_cpup
+#define cpu_to_le32p __cpu_to_le32p
+#define le32_to_cpup __le32_to_cpup
+#define cpu_to_le16p __cpu_to_le16p
+#define le16_to_cpup __le16_to_cpup
+#define cpu_to_be64p __cpu_to_be64p
+#define be64_to_cpup __be64_to_cpup
+#define cpu_to_be32p __cpu_to_be32p
+#define be32_to_cpup __be32_to_cpup
+#define cpu_to_be16p __cpu_to_be16p
+#define be16_to_cpup __be16_to_cpup
+#define cpu_to_le64s __cpu_to_le64s
+#define le64_to_cpus __le64_to_cpus
+#define cpu_to_le32s __cpu_to_le32s
+#define le32_to_cpus __le32_to_cpus
+#define cpu_to_le16s __cpu_to_le16s
+#define le16_to_cpus __le16_to_cpus
+#define cpu_to_be64s __cpu_to_be64s
+#define be64_to_cpus __be64_to_cpus
+#define cpu_to_be32s __cpu_to_be32s
+#define be32_to_cpus __be32_to_cpus
+#define cpu_to_be16s __cpu_to_be16s
+#define be16_to_cpus __be16_to_cpus
+#endif
+
+
+/*
+ * Handle ntohl and suches. These have various compatibility
+ * issues - like we want to give the prototype even though we
+ * also have a macro for them in case some strange program
+ * wants to take the address of the thing or something..
+ *
+ * Note that these used to return a "long" in libc5, even though
+ * long is often 64-bit these days.. Thus the casts.
+ *
+ * They have to be macros in order to do the constant folding
+ * correctly - if the argument passed into a inline function
+ * it is no longer constant according to gcc..
+ */
+
+#undef ntohl
+#undef ntohs
+#undef htonl
+#undef htons
+
+/*
+ * Do the prototypes. Somebody might want to take the
+ * address or some such sick thing..
+ */
+#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2)
+extern __u32			ntohl(__u32);
+extern __u32			htonl(__u32);
+#else
+extern unsigned long int	ntohl(unsigned long int);
+extern unsigned long int	htonl(unsigned long int);
+#endif
+extern unsigned short int	ntohs(unsigned short int);
+extern unsigned short int	htons(unsigned short int);
+
+
+#if defined(__GNUC__) && (__GNUC__ >= 2)
+
+#define ___htonl(x) __cpu_to_be32(x)
+#define ___htons(x) __cpu_to_be16(x)
+#define ___ntohl(x) __be32_to_cpu(x)
+#define ___ntohs(x) __be16_to_cpu(x)
+
+#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2)
+#define htonl(x) ___htonl(x)
+#define ntohl(x) ___ntohl(x)
+#else
+#define htonl(x) ((unsigned long)___htonl(x))
+#define ntohl(x) ((unsigned long)___ntohl(x))
+#endif
+#define htons(x) ___htons(x)
+#define ntohs(x) ___ntohs(x)
+
+#endif /* OPTIMIZE */
+
+
+#endif /* _LINUX_BYTEORDER_GENERIC_H */
diff --git a/include/mpc824x.h b/include/mpc824x.h
new file mode 100644
index 0000000..0cd7898
--- /dev/null
+++ b/include/mpc824x.h
@@ -0,0 +1,575 @@
+/*
+ * Copyright Rob Taylor, Flying Pig Systems Ltd. 2000.
+ * Copyright (C) 2001, James Dougherty, jfd@cs.stanford.edu
+ *
+ * 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
+ */
+
+#ifndef __MPC824X_H__
+#define __MPC824X_H__
+
+#include <config.h>
+
+/* CPU Types */
+#define CPU_TYPE_601		0x01		/* PPC 601	 CPU */
+#define CPU_TYPE_602		0x02		/* PPC 602	 CPU */
+#define CPU_TYPE_603		0x03		/* PPC 603	 CPU */
+#define CPU_TYPE_603E		0x06		/* PPC 603e	 CPU */
+#define CPU_TYPE_603P		0x07		/* PPC 603p	 CPU */
+#define CPU_TYPE_604		0x04		/* PPC 604	 CPU */
+#define CPU_TYPE_604E		0x09		/* PPC 604e	 CPU */
+#define CPU_TYPE_604R		0x0a		/* PPC 604r	 CPU */
+#define CPU_TYPE_750		0x08		/* PPC 750	 CPU */
+#define CPU_TYPE_8240		0x81		/* PPC 8240	 CPU */
+#define CPU_TYPE_8245		0x8081		/* PPC 8245/8241 CPU */
+#define _CACHE_ALIGN_SIZE	32		/* cache line size */
+
+/* spr976 - DMISS data tlb miss address register
+ * spr977 - DCMP data tlb miss compare register
+ * spr978 - HASH1 PTEG1 address register
+ * spr980 - HASH2 PTEG2 address register
+ * IMISS  - instruction tlb miss address register
+ * ICMP	  - instruction TLB mis compare register
+ * RPA	  - real page address register
+ * HID0	  - hardware implemntation register
+ * HID2	  - instruction address breakpoint register
+ */
+
+/* Kahlua/MPC8240 defines */
+#define VEN_DEV_ID		0x00021057	/* Vendor and Dev. ID for MPC106 */
+#define KAHLUA_ID		0x00031057	/* Vendor & Dev Id for Kahlua's PCI */
+#define KAHLUA2_ID	        0x00061057      /* 8245 is aka Kahlua-2 */
+#define BMC_BASE		0x80000000	/* Kahlua ID in PCI Memory space */
+#define CHRP_REG_ADDR		0xfec00000	/* MPC107 Config, Map B */
+#define CHRP_REG_DATA		0xfee00000	/* MPC107 Config, Map B */
+#define CHRP_ISA_MEM_PHYS	0xfd000000
+#define CHRP_ISA_MEM_BUS	0x00000000
+#define CHRP_ISA_MEM_SIZE	0x01000000
+#define CHRP_ISA_IO_PHYS	0xfe000000
+#define CHRP_ISA_IO_BUS		0x00000000
+#define CHRP_ISA_IO_SIZE	0x00800000
+#define CHRP_PCI_IO_PHYS	0xfe800000
+#define CHRP_PCI_IO_BUS		0x00800000
+#define CHRP_PCI_IO_SIZE	0x00400000
+#define CHRP_PCI_MEM_PHYS	0x80000000
+#define CHRP_PCI_MEM_BUS	0x80000000
+#define CHRP_PCI_MEM_SIZE	0x7d000000
+#define	CHRP_PCI_MEMORY_PHYS	0x00000000
+#define	CHRP_PCI_MEMORY_BUS	0x00000000
+#define CHRP_PCI_MEMORY_SIZE	0x40000000
+#define PREP_REG_ADDR		0x80000cf8	/* MPC107 Config, Map A */
+#define PREP_REG_DATA		0x80000cfc	/* MPC107 Config, Map A */
+#define PREP_ISA_IO_PHYS	0x80000000
+#define PREP_ISA_IO_BUS		0x00000000
+#define PREP_ISA_IO_SIZE	0x00800000
+#define PREP_PCI_IO_PHYS	0x81000000
+#define PREP_PCI_IO_BUS		0x01000000
+#define PREP_PCI_IO_SIZE	0x3e800000
+#define PREP_PCI_MEM_PHYS	0xc0000000
+#define PREP_PCI_MEM_BUS	0x00000000
+#define PREP_PCI_MEM_SIZE	0x3f000000
+#define	PREP_PCI_MEMORY_PHYS	0x00000000
+#define	PREP_PCI_MEMORY_BUS	0x80000000
+#define	PREP_PCI_MEMORY_SIZE	0x80000000
+#define MPC107_PCI_CMD		0x80000004	/* MPC107 PCI cmd reg */
+#define MPC107_PCI_STAT 	0x80000006	/* MPC107 PCI status reg */
+#define PROC_INT1_ADR		0x800000a8	/* MPC107 Processor i/f cfg1 */
+#define PROC_INT2_ADR		0x800000ac	/* MPC107 Processor i/f cfg2 */
+#define MEM_CONT1_ADR		0x800000f0	/* MPC107 Memory control config. 1 */
+#define MEM_CONT2_ADR		0x800000f4	/* MPC107 Memory control config. 2 */
+#define MEM_CONT3_ADR		0x800000f8	/* MPC107 Memory control config. 3 */
+#define MEM_CONT4_ADR		0x800000fc	/* MPC107 Memory control config. 4 */
+#define MEM_ERREN1_ADR		0x800000c0	/* MPC107 Memory error enable 1 */
+#define MEM_START1_ADR		0x80000080	/* MPC107 Memory starting addr */
+#define MEM_START2_ADR		0x80000084	/* MPC107 Memory starting addr-lo */
+#define XMEM_START1_ADR 	0x80000088	/* MPC107 Extended mem. start addr-hi*/
+#define XMEM_START2_ADR 	0x8000008c	/* MPC107 Extended mem. start addr-lo*/
+#define MEM_END1_ADR		0x80000090	/* MPC107 Memory ending address */
+#define MEM_END2_ADR		0x80000094	/* MPC107 Memory ending addr-lo */
+#define XMEM_END1_ADR		0x80000098	/* MPC107 Extended mem. end addrs-hi */
+#define XMEM_END2_ADR		0x8000009c	/* MPC107 Extended mem. end addrs-lo*/
+#define OUT_DRV_CONT		0x80000073	/* MPC107 Output Driver Control reg */
+#define MEM_EN_ADR		0x800000a0	/* Memory bank enable */
+#define PAGE_MODE		0x800000a3	/* MPC107 Page Mode Counter/Timer */
+
+/*-----------------------------------------------------------------------
+ * Exception offsets (PowerPC standard)
+ */
+#define EXC_OFF_RESERVED0	0x0000	/* Reserved */
+#define EXC_OFF_SYS_RESET	0x0100	/* System reset */
+#define EXC_OFF_MACH_CHCK	0x0200	/* Machine Check */
+#define EXC_OFF_DATA_STOR	0x0300	/* Data Storage */
+#define EXC_OFF_INS_STOR	0x0400	/* Instruction Storage */
+#define EXC_OFF_EXTERNAL	0x0500	/* External */
+#define EXC_OFF_ALIGN		0x0600	/* Alignment */
+#define EXC_OFF_PROGRAM		0x0700	/* Program */
+#define EXC_OFF_FPUNAVAIL	0x0800	/* Floating-point Unavailable */
+#define EXC_OFF_DECR		0x0900	/* Decrementer */
+#define EXC_OFF_RESERVED1	0x0A00	/* Reserved */
+#define EXC_OFF_RESERVED2	0x0B00	/* Reserved */
+#define EXC_OFF_SYS_CALL	0x0C00	/* System Call */
+#define EXC_OFF_TRACE		0x0D00	/* Trace */
+#define EXC_OFF_FPUNASSIST	0x0E00	/* Floating-point Assist */
+
+	/* 0x0E10 - 0x0FFF are marked reserved in The PowerPC Architecture book */
+	/* these found in DINK code  - may not apply to 8240*/
+#define EXC_OFF_PMI		0x0F00	/* Performance Monitoring Interrupt */
+#define EXC_OFF_VMXUI		0x0F20	/* VMX (AltiVec) Unavailable Interrupt */
+
+	/* 0x1000 - 0x2FFF are implementation specific */
+	/* these found in DINK code  - may not apply to 8240 */
+#define EXC_OFF_ITME		0x1000	/* Instruction Translation Miss Exception */
+#define EXC_OFF_DLTME		0x1100	/* Data Load Translation Miss Exception */
+#define EXC_OFF_DSTME		0x1200	/* Data Store Translation Miss Exception */
+#define EXC_OFF_IABE		0x1300	/* Instruction Addr Breakpoint Exception */
+#define EXC_OFF_SMIE		0x1400	/* System Management Interrupt Exception */
+#define EXC_OFF_JMDDI		0x1600	/* Java Mode denorm detect Interr -- WTF??*/
+#define EXC_OFF_RMTE		0x2000	/* Run Mode or Trace Exception */
+
+#define MAP_A_CONFIG_ADDR_HIGH	0x8000	/* Upper half of CONFIG_ADDR for Map A */
+#define MAP_A_CONFIG_ADDR_LOW	0x0CF8	/* Lower half of CONFIG_ADDR for Map A */
+#define MAP_A_CONFIG_DATA_HIGH	0x8000	/* Upper half of CONFIG_DAT for Map A */
+#define MAP_A_CONFIG_DATA_LOW	0x0CFC	/* Lower half of CONFIG_DAT for Map A */
+#define MAP_B_CONFIG_ADDR_HIGH	0xfec0	/* Upper half of CONFIG_ADDR for Map B */
+#define MAP_B_CONFIG_ADDR_LOW	0x0000	/* Lower half of CONFIG_ADDR for Map B */
+#define MAP_B_CONFIG_DATA_HIGH	0xfee0	/* Upper half of CONFIG_DAT for Map B */
+#define MAP_B_CONFIG_DATA_LOW	0x0000	/* Lower half of CONFIG_DAT for Map B */
+
+
+#if defined(CFG_ADDR_MAP_A)
+#define CONFIG_ADDR_HIGH    MAP_A_CONFIG_ADDR_HIGH  /* Upper half of CONFIG_ADDR */
+#define CONFIG_ADDR_LOW	    MAP_A_CONFIG_ADDR_LOW   /* Lower half of CONFIG_ADDR */
+#define CONFIG_DATA_HIGH    MAP_A_CONFIG_DATA_HIGH  /* Upper half of CONFIG_DAT */
+#define CONFIG_DATA_LOW	    MAP_A_CONFIG_DATA_LOW   /* Lower half of CONFIG_DAT */
+#else /* Assume Map B, default */
+#define CONFIG_ADDR_HIGH    MAP_B_CONFIG_ADDR_HIGH  /* Upper half of CONFIG_ADDR */
+#define CONFIG_ADDR_LOW	    MAP_B_CONFIG_ADDR_LOW   /* Lower half of CONFIG_ADDR */
+#define CONFIG_DATA_HIGH    MAP_B_CONFIG_DATA_HIGH  /* Upper half of CONFIG_DAT */
+#define CONFIG_DATA_LOW	    MAP_B_CONFIG_DATA_LOW   /* Lower half of CONFIG_DAT */
+#endif
+
+#define CONFIG_ADDR	(CONFIG_ADDR_HIGH << 16 | CONFIG_ADDR_LOW)
+
+#define CONFIG_DATA	(CONFIG_DATA_HIGH << 16 | CONFIG_DATA_LOW)
+
+/* Macros to write to config registers. addr should be a constant in all cases */
+
+#define CONFIG_WRITE_BYTE( addr, data ) \
+  __asm__ __volatile__( \
+  " stwbrx %1, 0, %0\n \
+    sync\n \
+    stb %3, %4(%2)\n \
+    sync " \
+  : /* no output */ \
+  : "r" (CONFIG_ADDR), "r" ((addr) & ~3), \
+    "b" (CONFIG_DATA), "r" (data), \
+    "n" ((addr) & 3));
+
+#define CONFIG_WRITE_HALFWORD( addr, data ) \
+  __asm__ __volatile__( \
+  " stwbrx %1, 0, %0\n \
+    sync\n \
+    sthbrx %3, %4, %2\n \
+    sync " \
+  : /* no output */ \
+  : "r" (CONFIG_ADDR), "r" ((addr) & ~3), \
+    "r" (CONFIG_DATA), "r" (data), \
+    "b" ((addr) & 3));
+
+/* this assumes it's writeing on word boundaries*/
+#define CONFIG_WRITE_WORD( addr, data ) \
+  __asm__ __volatile__( \
+  " stwbrx %1, 0, %0\n \
+    sync\n \
+    stwbrx %3, 0, %2\n \
+    sync " \
+  : /* no output */ \
+  : "r" (CONFIG_ADDR), "r" (addr), \
+    "r" (CONFIG_DATA), "r" (data));
+
+/* Configuration register reads*/
+
+#define CONFIG_READ_BYTE( addr, reg ) \
+  __asm__ ( \
+  " stwbrx %1, 0, %2\n \
+    sync\n \
+    lbz	  %0, %4(%3)\n \
+    sync " \
+  : "=r" (reg) \
+  : "r" ((addr) & ~3), "r" (CONFIG_ADDR), \
+    "b" (CONFIG_DATA), "n" ((addr) & 3));
+
+
+#define CONFIG_READ_HALFWORD( addr, reg ) \
+  __asm__ ( \
+  " stwbrx %1, 0, %2\n \
+    sync\n \
+    lhbrx %0, %4, %3\n \
+    sync " \
+  : "=r" (reg) \
+  : "r" ((addr) & ~3), "r" (CONFIG_ADDR), \
+    "r" (CONFIG_DATA), \
+    "b" ((addr) & 3));
+
+/* this assumes it's reading on word boundaries*/
+#define CONFIG_READ_WORD( addr, reg ) \
+  __asm__ ( \
+  " stwbrx %1, 0, %2\n \
+    sync\n \
+    lwbrx %0, 0, %3\n \
+    sync " \
+  : "=r" (reg) \
+  : "r" (addr), "r" (CONFIG_ADDR),\
+    "r" (CONFIG_DATA));
+
+/*
+ *  configuration register 'addresses'.
+ *  These are described in chaper 5 of the 8240 users manual.
+ *  Where the register has an abreviation in the manual, this has
+ *  been usaed here, otherwise a name in keeping with the norm has
+ *  been invented.
+ *  Note that some of these registers aren't documented in the manual.
+ */
+
+#define PCICR		0x80000004  /* PCI Command Register */
+#define PCISR		0x80000006  /* PCI Status Register */
+#define REVID		0x80000008  /* CPU revision id */
+#define PIR		0x80000009  /* PCI Programming Interface Register */
+#define PBCCR		0x8000000b  /* PCI Base Class Code Register */
+#define PCLSR		0x8000000c  /* Processor Cache Line Size Register */
+#define PLTR		0x8000000d  /* PCI Latancy Timer Register */
+#define PHTR		0x8000000e  /* PCI Header Type Register */
+#define BISTCTRL	0x8000000f  /* BIST Control */
+#define LMBAR		0x80000010  /* Local Base Addres Register */
+#define PCSRBAR		0x80000014  /* PCSR Base Address Register */
+#define ILR		0x8000003c  /* PCI Interrupt Line Register */
+#define IPR		0x8000003d  /* Interrupt Pin Register */
+#define MINGNT		0x8000003e  /* MIN GNI */
+#define MAXLAT		0x8000003f  /* MAX LAT */
+#define PCIACR		0x80000046  /* PCI Arbiter Control Register */
+#define PMCR1		0x80000070  /* Power management config. 1 */
+#define PMCR2		0x80000072  /* Power management config. 2 */
+#define ODCR		0x80000073  /* Output Driver Control Register */
+#define CLKDCR		0x80000074  /* CLK Driver Control Register */
+#if defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define MIOCR1		0x80000076  /* Miscellaneous I/O Control Register 1 */
+#define MIOCR2		0x80000077  /* Miscellaneous I/O Control Register 2 */
+#endif
+#define EUMBBAR		0x80000078  /* Embedded Utilities Memory Block Base Address Register */
+#define EUMBBAR_VAL	0x80500000  /* PCI Relocation offset for EUMB region */
+#define EUMBSIZE	0x00100000  /* Size of EUMB region */
+
+#define MSAR1		0x80000080  /* Memory Starting Address Register 1 */
+#define MSAR2		0x80000084  /* Memory Starting Address Register 2 */
+#define EMSAR1		0x80000088  /* Extended Memory Starting Address Register 1*/
+#define EMSAR2		0x8000008c  /* Extended Memory Starting Address Register 2*/
+#define MEAR1		0x80000090  /* Memory Ending Address Register 1 */
+#define MEAR2		0x80000094  /* Memory Ending Address Register 2 */
+#define EMEAR1		0x80000098  /* Extended Memory Ending Address Register 1 */
+#define EMEAR2		0x8000009c  /* Extended Memory Ending Address Register 2 */
+#define MBER		0x800000a0  /* Memory bank Enable Register*/
+#define MPMR		0x800000a3  /* Memory Page Mode Register (stores PGMAX) */
+#define PICR1		0x800000a8  /* Processor Interface Configuration Register 1 */
+#define PICR2		0x800000ac  /* Processor Interface Configuration Register 2 */
+#define ECCSBECR	0x800000b8  /* ECC Single-Bit Error Counter Register */
+#define ECCSBETR	0x800000b8  /* ECC Single-Bit Error Trigger Register */
+#define ERRENR1		0x800000c0  /* Error Enableing Register 1 */
+#define ERRENR2		0x800000c4  /* Error Enableing Register 2 */
+#define ERRDR1		0x800000c1  /* Error Detection Register 1 */
+#define IPBESR		0x800000c3  /* Internal Processor Error Status Register */
+#define ERRDR2		0x800000c5  /* Error Detection Register 2 */
+#define PBESR		0x800000c7  /* PCI Bus Error Status Register */
+#define PBEAR		0x800000c8  /* Processor/PCI Bus Error Status Register */
+#define AMBOR		0x800000e0  /* Address Map B Options Register */
+#define MCCR1		0x800000f0  /* Memory Control Configuration Register 1 */
+#define MCCR2		0x800000f4  /* Memory Control Configuration Register 2 */
+#define MCCR3		0x800000f8  /* Memory Control Configuration Register 3 */
+#define MCCR4		0x800000fc  /* Memory Control Configuration Register 4 */
+
+/* some values for some of the above */
+
+#define PICR1_CF_APARK		0x00000008
+#define PICR1_LE_MODE		0x00000020
+#define PICR1_ST_GATH_EN	0x00000040
+#if defined(CONFIG_MPC8240)
+#define PICR1_EN_PCS		0x00000080 /* according to dink code, sets the 8240 to handle pci config space */
+#elif defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define PICR1_NO_BUSW_CK	0x00000080 /* no bus width check for flash writes */
+#define PICR1_DEC		0x00000100 /* Time Base enable on 8245/8241 */
+#define ERCR1		        0x800000d0  /* Extended ROM Configuration Register 1 */
+#define ERCR2		        0x800000d4  /* Extended ROM Configuration Register 2 */
+#define ERCR3		        0x800000d8  /* Extended ROM Configuration Register 3 */
+#define ERCR4		        0x800000dc  /* Extended ROM Configuration Register 4 */
+#define MIOCR1		        0x80000076  /* Miscellaneous I/O Control Register 1 */
+#define MIOCR1_ADR_X	        0x80000074  /* Miscellaneous I/O Control Register 1 */
+#define MIOCR1_SHIFT	        2
+#define MIOCR2		        0x80000077  /* Miscellaneous I/O Control Register 2 */
+#define MIOCR2_ADR_X	        0x80000074  /* Miscellaneous I/O Control Register 1 */
+#define MIOCR2_SHIFT	        3
+#define ODCR_ADR_X	        0x80000070	/* Output Driver Control register */
+#define ODCR_SHIFT              3
+#define PMCR2_ADR	        0x80000072	/* Power Mgmnt Cfg 2 register */
+#define PMCR2_ADR_X	        0x80000070
+#define PMCR2_SHIFT             3
+#define PMCR1_ADR	        0x80000070	/* Power Mgmnt Cfg 1 reister */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+#define PICR1_CF_DPARK		0x00000200
+#define PICR1_MCP_EN		0x00000800
+#define PICR1_FLASH_WR_EN	0x00001000
+#ifdef CONFIG_MPC8240
+#define PICR1_ADDRESS_MAP	0x00010000
+#define PIRC1_MSK		0xff000000
+#endif
+#define PICR1_PROC_TYPE_MSK	0x00060000
+#define PICR1_PROC_TYPE_603E	0x00040000
+#define PICR1_RCS0		0x00100000
+
+#define PICR2_CF_SNOOP_WS_MASK	0x000c0000
+#define PICR2_CF_SNOOP_WS_0WS	0x00000000
+#define PICR2_CF_SNOOP_WS_1WS	0x00040000
+#define PICR2_CF_SNOOP_WS_2WS	0x00080000
+#define PICR2_CF_SNOOP_WS_3WS	0x000c0000
+#define PICR2_CF_APHASE_WS_MASK 0x0000000c
+#define PICR2_CF_APHASE_WS_0WS	0x00000000
+#define PICR2_CF_APHASE_WS_1WS	0x00000004
+#define PICR2_CF_APHASE_WS_2WS	0x00000008
+#define PICR2_CF_APHASE_WS_3WS	0x0000000c
+
+#define MCCR1_ROMNAL_SHIFT	28
+#define MCCR1_ROMNAL_MSK	0xf0000000
+#define MCCR1_ROMFAL_SHIFT	23
+#define MCCR1_ROMFAL_MSK	0x0f800000
+#define MCCR1_DBUS_SIZE0        0x00400000
+#define MCCR1_BURST		0x00100000
+#define MCCR1_MEMGO		0x00080000
+#define MCCR1_SREN		0x00040000
+#if defined(CONFIG_MPC8240)
+#define MCCR1_RAM_TYPE		0x00020000
+#elif defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define MCCR1_SDRAM_EN		0x00020000
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+#define MCCR1_PCKEN		0x00010000
+#define MCCR1_BANK1ROW_SHIFT	2
+#define MCCR1_BANK2ROW_SHIFT	4
+#define MCCR1_BANK3ROW_SHIFT	6
+#define MCCR1_BANK4ROW_SHIFT	8
+#define MCCR1_BANK5ROW_SHIFT	10
+#define MCCR1_BANK6ROW_SHIFT	12
+#define MCCR1_BANK7ROW_SHIFT	14
+
+#define MCCR2_TS_WAIT_TIMER_MSK 0xe0000000
+#define MCCR2_TS_WAIT_TIMER_SHIFT 29
+#define MCCR2_ASRISE_MSK	0x1e000000
+#define MCCR2_ASRISE_SHIFT	25
+#define MCCR2_ASFALL_MSK	0x01e00000
+#define MCCR2_ASFALL_SHIFT	21
+
+#define MCCR2_INLINE_PAR_NOT_ECC    0x00100000
+#define MCCR2_WRITE_PARITY_CHK	0x00080000
+#define MCCR2_INLFRD_PARECC_CHK_EN  0x00040000
+#ifdef CONFIG_MPC8240
+#define MCCR2_ECC_EN		0x00020000
+#define MCCR2_EDO		0x00010000
+#endif
+#define MCCR2_REFINT_MSK	0x0000fffc
+#define MCCR2_REFINT_SHIFT	2
+#define MCCR2_RSV_PG		0x00000002
+#define MCCR2_PMW_PAR		0x00000001
+
+#define MCCR3_BSTOPRE2TO5_MSK	0xf0000000 /*BSTOPRE[2-5]*/
+#define MCCR3_BSTOPRE2TO5_SHIFT 28
+#define MCCR3_REFREC_MSK	0x0f000000
+#define MCCR3_REFREC_SHIFT	24
+#ifdef CONFIG_MPC8240
+#define MCCR3_RDLAT_MSK		0x00f00000
+#define MCCR3_RDLAT_SHIFT	20
+#define MCCR3_CPX		0x00010000
+#define MCCR3_RAS6P_MSK		0x00078000
+#define MCCR3_RAS6P_SHIFT	15
+#define MCCR3_CAS5_MSK		0x00007000
+#define MCCR3_CAS5_SHIFT	12
+#define MCCR3_CP4_MSK		0x00000e00
+#define MCCR3_CP4_SHIFT		9
+#define MCCR3_CAS3_MSK		0x000001c0
+#define MCCR3_CAS3_SHIFT	6
+#define MCCR3_RCD2_MSK		0x00000038
+#define MCCR3_RCD2_SHIFT	3
+#define MCCR3_RP1_MSK		0x00000007
+#define MCCR3_RP1_SHIFT		0
+#endif
+
+#define MCCR4_PRETOACT_MSK	0xf0000000
+#define MCCR4_PRETOACT_SHIFT	28
+#define MCCR4_ACTTOPRE_MSK	0x0f000000
+#define MCCR4_ACTTOPRE_SHIFT	24
+#define MCCR4_WMODE		0x00800000
+#define MCCR4_INLINE		0x00400000
+#if defined(CONFIG_MPC8240)
+#define MCCR4_BIT21		0x00200000 /* this include cos DINK code sets it- unknown function*/
+#elif defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define MCCR4_EXTROM		0x00200000 /* enables Extended ROM space */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+#define MCCR4_REGISTERED	0x00100000
+#define MCCR4_BSTOPRE0TO1_MSK	0x000c0000 /*BSTOPRE[0-1]*/
+#define MCCR4_BSTOPRE0TO1_SHIFT 18
+#define MCCR4_REGDIMM		0x00008000
+#define MCCR4_SDMODE_MSK	0x00007f00
+#define MCCR4_SDMODE_SHIFT	8
+#define MCCR4_ACTTORW_MSK	0x000000f0
+#define MCCR4_ACTTORW_SHIFT	4
+#define MCCR4_BSTOPRE6TO9_MSK	0x0000000f /*BSTOPRE[6-9]*/
+#define MCCR4_BSTOPRE6TO9_SHIFT 0
+#define MCCR4_DBUS_SIZE2_SHIFT	17
+
+#define MICR_ADDR_MASK		0x0ff00000
+#define MICR_ADDR_SHIFT		20
+#define MICR_EADDR_MASK		0x30000000
+#define MICR_EADDR_SHIFT	28
+
+#define BATU_BEPI_MSK		0xfffe0000
+#define BATU_BL_MSK		0x00001ffc
+
+#define BATU_BL_128K		0x00000000
+#define BATU_BL_256K		0x00000004
+#define BATU_BL_512K		0x0000000c
+#define BATU_BL_1M		0x0000001c
+#define BATU_BL_2M		0x0000003c
+#define BATU_BL_4M		0x0000007c
+#define BATU_BL_8M		0x000000fc
+#define BATU_BL_16M		0x000001fc
+#define BATU_BL_32M		0x000003fc
+#define BATU_BL_64M		0x000007fc
+#define BATU_BL_128M		0x00000ffc
+#define BATU_BL_256M		0x00001ffc
+
+#define BATU_VS			0x00000002
+#define BATU_VP			0x00000001
+
+#define BATL_BRPN_MSK		0xfffe0000
+#define BATL_WIMG_MSK		0x00000078
+
+#define BATL_WRITETHROUGH	0x00000040
+#define BATL_CACHEINHIBIT	0x00000020
+#define BATL_MEMCOHERENCE	0x00000010
+#define BATL_GUARDEDSTORAGE	0x00000008
+
+#define BATL_PP_MSK		0x00000003
+#define BATL_PP_00		0x00000000 /* No access */
+#define BATL_PP_01		0x00000001 /* Read-only */
+#define BATL_PP_10		0x00000002 /* Read-write */
+#define BATL_PP_11		0x00000003
+
+/*
+ * I'd attempt to do defines for the PP bits, but it's use is a bit
+ * too complex, see the PowerPC Operating Environment Architecture
+ * section in the PowerPc arch book, chapter 4.
+ */
+
+/*eumb and epic config*/
+
+#define EPIC_FPR		0x00041000
+#define EPIC_GCR		0x00041020
+#define EPIC_EICR		0x00041030
+#define EPIC_EVI		0x00041080
+#define EPIC_PI			0x00041090
+#define EPIC_SVR		0x000410E0
+#define EPIC_TFRR		0x000410F0
+
+/*
+ * Note the information for these is rather mangled in the 8240 manual.
+ * These are guesses.
+ */
+
+#define EPIC_GTCCR0		0x00041100
+#define EPIC_GTCCR1		0x00041140
+#define EPIC_GTCCR2		0x00041180
+#define EPIC_GTCCR3		0x000411C0
+#define EPIC_GTBCR0		0x00041110
+#define EPIC_GTBCR1		0x00041150
+#define EPIC_GTBCR2		0x00041190
+#define EPIC_GTBCR3		0x000411D0
+#define EPIC_GTVPR0		0x00041120
+#define EPIC_GTVPR1		0x00041160
+#define EPIC_GTVPR2		0x000411a0
+#define EPIC_GTVPR3		0x000411e0
+#define EPIC_GTDR0		0x00041130
+#define EPIC_GTDR1		0x00041170
+#define EPIC_GTDR2		0x000411b0
+#define EPIC_GTDR3		0x000411f0
+
+#define EPIC_IVPR0		0x00050200
+#define EPIC_IVPR1		0x00050220
+#define EPIC_IVPR2		0x00050240
+#define EPIC_IVPR3		0x00050260
+#define EPIC_IVPR4		0x00050280
+
+#define EPIC_SVPR0		0x00050200
+#define EPIC_SVPR1		0x00050220
+#define EPIC_SVPR2		0x00050240
+#define EPIC_SVPR3		0x00050260
+#define EPIC_SVPR4		0x00050280
+#define EPIC_SVPR5		0x000502A0
+#define EPIC_SVPR6		0x000502C0
+#define EPIC_SVPR7		0x000502E0
+#define EPIC_SVPR8		0x00050300
+#define EPIC_SVPR9		0x00050320
+#define EPIC_SVPRa		0x00050340
+#define EPIC_SVPRb		0x00050360
+#define EPIC_SVPRc		0x00050380
+#define EPIC_SVPRd		0x000503A0
+#define EPIC_SVPRe		0x000503C0
+#define EPIC_SVPRf		0x000503E0
+
+/* MPC8240 Byte Swap/PCI Support Macros */
+#define BYTE_SWAP_16_BIT(x)    ( (((x) & 0x00ff) << 8) | ( (x) >> 8) )
+#define LONGSWAP(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
+		     (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
+#define PCISWAP(x)   LONGSWAP(x)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * MPC107 Support
+ *
+ */
+unsigned int mpc824x_mpc107_getreg(unsigned int regNum);
+void mpc824x_mpc107_setreg(unsigned int regNum, unsigned int regVal);
+void mpc824x_mpc107_write8(unsigned int address, unsigned char data);
+void mpc824x_mpc107_write16(unsigned int address, unsigned short data);
+void mpc824x_mpc107_write32(unsigned int address, unsigned int data);
+unsigned char mpc824x_mpc107_read8(unsigned int address);
+unsigned short mpc824x_mpc107_read16(unsigned int address);
+unsigned int mpc824x_mpc107_read32(unsigned int address);
+unsigned int mpc824x_eummbar_read(unsigned int regNum);
+void mpc824x_eummbar_write(unsigned int regNum, unsigned int regVal);
+
+#ifdef CONFIG_PCI
+struct pci_controller;
+void pci_cpm824x_init(struct pci_controller* hose);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __MPC824X_H__ */
diff --git a/include/pci.h b/include/pci.h
new file mode 100644
index 0000000..4875375
--- /dev/null
+++ b/include/pci.h
@@ -0,0 +1,475 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * 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
+ * aloong with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _PCI_H
+#define _PCI_H
+
+/*
+ * Under PCI, each device has 256 bytes of configuration address space,
+ * of which the first 64 bytes are standardized as follows:
+ */
+#define PCI_VENDOR_ID		0x00	/* 16 bits */
+#define PCI_DEVICE_ID		0x02	/* 16 bits */
+#define PCI_COMMAND		0x04	/* 16 bits */
+#define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
+#define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
+#define  PCI_COMMAND_MASTER	0x4	/* Enable bus mastering */
+#define  PCI_COMMAND_SPECIAL	0x8	/* Enable response to special cycles */
+#define  PCI_COMMAND_INVALIDATE 0x10	/* Use memory write and invalidate */
+#define  PCI_COMMAND_VGA_PALETTE 0x20	/* Enable palette snooping */
+#define  PCI_COMMAND_PARITY	0x40	/* Enable parity checking */
+#define  PCI_COMMAND_WAIT	0x80	/* Enable address/data stepping */
+#define  PCI_COMMAND_SERR	0x100	/* Enable SERR */
+#define  PCI_COMMAND_FAST_BACK	0x200	/* Enable back-to-back writes */
+
+#define PCI_STATUS		0x06	/* 16 bits */
+#define  PCI_STATUS_CAP_LIST	0x10	/* Support Capability List */
+#define  PCI_STATUS_66MHZ	0x20	/* Support 66 Mhz PCI 2.1 bus */
+#define  PCI_STATUS_UDF		0x40	/* Support User Definable Features [obsolete] */
+#define  PCI_STATUS_FAST_BACK	0x80	/* Accept fast-back to back */
+#define  PCI_STATUS_PARITY	0x100	/* Detected parity error */
+#define  PCI_STATUS_DEVSEL_MASK 0x600	/* DEVSEL timing */
+#define  PCI_STATUS_DEVSEL_FAST 0x000
+#define  PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define  PCI_STATUS_DEVSEL_SLOW 0x400
+#define  PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
+#define  PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
+#define  PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
+#define  PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
+#define  PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
+
+#define PCI_CLASS_REVISION	0x08	/* High 24 bits are class, low 8
+					   revision */
+#define PCI_REVISION_ID		0x08	/* Revision ID */
+#define PCI_CLASS_PROG		0x09	/* Reg. Level Programming Interface */
+#define PCI_CLASS_DEVICE	0x0a	/* Device class */
+#define PCI_CLASS_CODE		0x0b	/* Device class code */
+#define PCI_CLASS_SUB_CODE	0x0a	/* Device sub-class code */
+
+#define PCI_CACHE_LINE_SIZE	0x0c	/* 8 bits */
+#define PCI_LATENCY_TIMER	0x0d	/* 8 bits */
+#define PCI_HEADER_TYPE		0x0e	/* 8 bits */
+#define  PCI_HEADER_TYPE_NORMAL 0
+#define  PCI_HEADER_TYPE_BRIDGE 1
+#define  PCI_HEADER_TYPE_CARDBUS 2
+
+#define PCI_BIST		0x0f	/* 8 bits */
+#define PCI_BIST_CODE_MASK	0x0f	/* Return result */
+#define PCI_BIST_START		0x40	/* 1 to start BIST, 2 secs or less */
+#define PCI_BIST_CAPABLE	0x80	/* 1 if BIST capable */
+
+/*
+ * Base addresses specify locations in memory or I/O space.
+ * Decoded size can be determined by writing a value of
+ * 0xffffffff to the register, and reading it back.  Only
+ * 1 bits are decoded.
+ */
+#define PCI_BASE_ADDRESS_0	0x10	/* 32 bits */
+#define PCI_BASE_ADDRESS_1	0x14	/* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2	0x18	/* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3	0x1c	/* 32 bits */
+#define PCI_BASE_ADDRESS_4	0x20	/* 32 bits */
+#define PCI_BASE_ADDRESS_5	0x24	/* 32 bits */
+#define  PCI_BASE_ADDRESS_SPACE 0x01	/* 0 = memory, 1 = I/O */
+#define  PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define  PCI_BASE_ADDRESS_MEM_TYPE_32	0x00	/* 32 bit address */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_1M	0x02	/* Below 1M [obsolete] */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_64	0x04	/* 64 bit address */
+#define  PCI_BASE_ADDRESS_MEM_PREFETCH	0x08	/* prefetchable? */
+#define  PCI_BASE_ADDRESS_MEM_MASK	(~0x0fUL)
+#define  PCI_BASE_ADDRESS_IO_MASK	(~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS		0x28
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID	0x2e
+#define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
+#define  PCI_ROM_ADDRESS_ENABLE 0x01
+#define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
+
+#define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
+
+/* 0x35-0x3b are reserved */
+#define PCI_INTERRUPT_LINE	0x3c	/* 8 bits */
+#define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */
+#define PCI_MIN_GNT		0x3e	/* 8 bits */
+#define PCI_MAX_LAT		0x3f	/* 8 bits */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS		0x18	/* Primary bus number */
+#define PCI_SECONDARY_BUS	0x19	/* Secondary bus number */
+#define PCI_SUBORDINATE_BUS	0x1a	/* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER	0x1b	/* Latency timer for secondary interface */
+#define PCI_IO_BASE		0x1c	/* I/O range behind the bridge */
+#define PCI_IO_LIMIT		0x1d
+#define  PCI_IO_RANGE_TYPE_MASK 0x0f	/* I/O bridging type */
+#define  PCI_IO_RANGE_TYPE_16	0x00
+#define  PCI_IO_RANGE_TYPE_32	0x01
+#define  PCI_IO_RANGE_MASK	~0x0f
+#define PCI_SEC_STATUS		0x1e	/* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE		0x20	/* Memory range behind */
+#define PCI_MEMORY_LIMIT	0x22
+#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0f
+#define  PCI_MEMORY_RANGE_MASK	~0x0f
+#define PCI_PREF_MEMORY_BASE	0x24	/* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT	0x26
+#define  PCI_PREF_RANGE_TYPE_MASK 0x0f
+#define  PCI_PREF_RANGE_TYPE_32 0x00
+#define  PCI_PREF_RANGE_TYPE_64 0x01
+#define  PCI_PREF_RANGE_MASK	~0x0f
+#define PCI_PREF_BASE_UPPER32	0x28	/* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32	0x2c
+#define PCI_IO_BASE_UPPER16	0x30	/* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16	0x32
+/* 0x34 same as for htype 0 */
+/* 0x35-0x3b is reserved */
+#define PCI_ROM_ADDRESS1	0x38	/* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL	0x3e
+#define  PCI_BRIDGE_CTL_PARITY	0x01	/* Enable parity detection on secondary interface */
+#define  PCI_BRIDGE_CTL_SERR	0x02	/* The same for SERR forwarding */
+#define  PCI_BRIDGE_CTL_NO_ISA	0x04	/* Disable bridging of ISA ports */
+#define  PCI_BRIDGE_CTL_VGA	0x08	/* Forward VGA addresses */
+#define  PCI_BRIDGE_CTL_MASTER_ABORT 0x20  /* Report master aborts */
+#define  PCI_BRIDGE_CTL_BUS_RESET 0x40	/* Secondary bus reset */
+#define  PCI_BRIDGE_CTL_FAST_BACK 0x80	/* Fast Back2Back enabled on secondary interface */
+
+/* Header type 2 (CardBus bridges) */
+#define PCI_CB_CAPABILITY_LIST	0x14
+/* 0x15 reserved */
+#define PCI_CB_SEC_STATUS	0x16	/* Secondary status */
+#define PCI_CB_PRIMARY_BUS	0x18	/* PCI bus number */
+#define PCI_CB_CARD_BUS		0x19	/* CardBus bus number */
+#define PCI_CB_SUBORDINATE_BUS	0x1a	/* Subordinate bus number */
+#define PCI_CB_LATENCY_TIMER	0x1b	/* CardBus latency timer */
+#define PCI_CB_MEMORY_BASE_0	0x1c
+#define PCI_CB_MEMORY_LIMIT_0	0x20
+#define PCI_CB_MEMORY_BASE_1	0x24
+#define PCI_CB_MEMORY_LIMIT_1	0x28
+#define PCI_CB_IO_BASE_0	0x2c
+#define PCI_CB_IO_BASE_0_HI	0x2e
+#define PCI_CB_IO_LIMIT_0	0x30
+#define PCI_CB_IO_LIMIT_0_HI	0x32
+#define PCI_CB_IO_BASE_1	0x34
+#define PCI_CB_IO_BASE_1_HI	0x36
+#define PCI_CB_IO_LIMIT_1	0x38
+#define PCI_CB_IO_LIMIT_1_HI	0x3a
+#define  PCI_CB_IO_RANGE_MASK	~0x03
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_CB_BRIDGE_CONTROL	0x3e
+#define  PCI_CB_BRIDGE_CTL_PARITY	0x01	/* Similar to standard bridge control register */
+#define  PCI_CB_BRIDGE_CTL_SERR		0x02
+#define  PCI_CB_BRIDGE_CTL_ISA		0x04
+#define  PCI_CB_BRIDGE_CTL_VGA		0x08
+#define  PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
+#define  PCI_CB_BRIDGE_CTL_CB_RESET	0x40	/* CardBus reset */
+#define  PCI_CB_BRIDGE_CTL_16BIT_INT	0x80	/* Enable interrupt for 16-bit cards */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100	/* Prefetch enable for both memory regions */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define  PCI_CB_BRIDGE_CTL_POST_WRITES	0x400
+#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
+#define PCI_CB_SUBSYSTEM_ID	0x42
+#define PCI_CB_LEGACY_MODE_BASE 0x44	/* 16-bit PC Card legacy mode base address (ExCa) */
+/* 0x48-0x7f reserved */
+
+/* Capability lists */
+
+#define PCI_CAP_LIST_ID		0	/* Capability ID */
+#define  PCI_CAP_ID_PM		0x01	/* Power Management */
+#define  PCI_CAP_ID_AGP		0x02	/* Accelerated Graphics Port */
+#define  PCI_CAP_ID_VPD		0x03	/* Vital Product Data */
+#define  PCI_CAP_ID_SLOTID	0x04	/* Slot Identification */
+#define  PCI_CAP_ID_MSI		0x05	/* Message Signalled Interrupts */
+#define  PCI_CAP_ID_CHSWP	0x06	/* CompactPCI HotSwap */
+#define PCI_CAP_LIST_NEXT	1	/* Next capability in the list */
+#define PCI_CAP_FLAGS		2	/* Capability defined flags (16 bits) */
+#define PCI_CAP_SIZEOF		4
+
+/* Power Management Registers */
+
+#define  PCI_PM_CAP_VER_MASK	0x0007	/* Version */
+#define  PCI_PM_CAP_PME_CLOCK	0x0008	/* PME clock required */
+#define  PCI_PM_CAP_AUX_POWER	0x0010	/* Auxilliary power support */
+#define  PCI_PM_CAP_DSI		0x0020	/* Device specific initialization */
+#define  PCI_PM_CAP_D1		0x0200	/* D1 power state support */
+#define  PCI_PM_CAP_D2		0x0400	/* D2 power state support */
+#define  PCI_PM_CAP_PME		0x0800	/* PME pin supported */
+#define PCI_PM_CTRL		4	/* PM control and status register */
+#define  PCI_PM_CTRL_STATE_MASK 0x0003	/* Current power state (D0 to D3) */
+#define  PCI_PM_CTRL_PME_ENABLE 0x0100	/* PME pin enable */
+#define  PCI_PM_CTRL_DATA_SEL_MASK	0x1e00	/* Data select (??) */
+#define  PCI_PM_CTRL_DATA_SCALE_MASK	0x6000	/* Data scale (??) */
+#define  PCI_PM_CTRL_PME_STATUS 0x8000	/* PME pin status */
+#define PCI_PM_PPB_EXTENSIONS	6	/* PPB support extensions (??) */
+#define  PCI_PM_PPB_B2_B3	0x40	/* Stop clock when in D3hot (??) */
+#define  PCI_PM_BPCC_ENABLE	0x80	/* Bus power/clock control enable (??) */
+#define PCI_PM_DATA_REGISTER	7	/* (??) */
+#define PCI_PM_SIZEOF		8
+
+/* AGP registers */
+
+#define PCI_AGP_VERSION		2	/* BCD version number */
+#define PCI_AGP_RFU		3	/* Rest of capability flags */
+#define PCI_AGP_STATUS		4	/* Status register */
+#define  PCI_AGP_STATUS_RQ_MASK 0xff000000	/* Maximum number of requests - 1 */
+#define  PCI_AGP_STATUS_SBA	0x0200	/* Sideband addressing supported */
+#define  PCI_AGP_STATUS_64BIT	0x0020	/* 64-bit addressing supported */
+#define  PCI_AGP_STATUS_FW	0x0010	/* FW transfers supported */
+#define  PCI_AGP_STATUS_RATE4	0x0004	/* 4x transfer rate supported */
+#define  PCI_AGP_STATUS_RATE2	0x0002	/* 2x transfer rate supported */
+#define  PCI_AGP_STATUS_RATE1	0x0001	/* 1x transfer rate supported */
+#define PCI_AGP_COMMAND		8	/* Control register */
+#define  PCI_AGP_COMMAND_RQ_MASK 0xff000000  /* Master: Maximum number of requests */
+#define  PCI_AGP_COMMAND_SBA	0x0200	/* Sideband addressing enabled */
+#define  PCI_AGP_COMMAND_AGP	0x0100	/* Allow processing of AGP transactions */
+#define  PCI_AGP_COMMAND_64BIT	0x0020	/* Allow processing of 64-bit addresses */
+#define  PCI_AGP_COMMAND_FW	0x0010	/* Force FW transfers */
+#define  PCI_AGP_COMMAND_RATE4	0x0004	/* Use 4x rate */
+#define  PCI_AGP_COMMAND_RATE2	0x0002	/* Use 4x rate */
+#define  PCI_AGP_COMMAND_RATE1	0x0001	/* Use 4x rate */
+#define PCI_AGP_SIZEOF		12
+
+/* Slot Identification */
+
+#define PCI_SID_ESR		2	/* Expansion Slot Register */
+#define  PCI_SID_ESR_NSLOTS	0x1f	/* Number of expansion slots available */
+#define  PCI_SID_ESR_FIC	0x20	/* First In Chassis Flag */
+#define PCI_SID_CHASSIS_NR	3	/* Chassis Number */
+
+/* Message Signalled Interrupts registers */
+
+#define PCI_MSI_FLAGS		2	/* Various flags */
+#define  PCI_MSI_FLAGS_64BIT	0x80	/* 64-bit addresses allowed */
+#define  PCI_MSI_FLAGS_QSIZE	0x70	/* Message queue size configured */
+#define  PCI_MSI_FLAGS_QMASK	0x0e	/* Maximum queue size available */
+#define  PCI_MSI_FLAGS_ENABLE	0x01	/* MSI feature enabled */
+#define PCI_MSI_RFU		3	/* Rest of capability flags */
+#define PCI_MSI_ADDRESS_LO	4	/* Lower 32 bits */
+#define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+#define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
+#define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
+
+#define PCI_MAX_PCI_DEVICES	32
+#define PCI_MAX_PCI_FUNCTIONS	8
+
+/* Include the ID list */
+
+#include <pci_ids.h>
+
+struct pci_region {
+	unsigned long bus_start;		/* Start on the bus */
+	unsigned long phys_start;		/* Start in physical address space */
+	unsigned long size;			/* Size */
+	unsigned long flags;			/* Resource flags */
+
+	unsigned long bus_lower;
+};
+
+#define PCI_REGION_MEM		0x00000000	/* PCI memory space */
+#define PCI_REGION_IO		0x00000001	/* PCI IO space */
+#define PCI_REGION_TYPE		0x00000001
+
+#define PCI_REGION_MEMORY	0x00000100	/* System memory */
+#define PCI_REGION_RO		0x00000200	/* Read-only memory */
+
+extern __inline__ void pci_set_region(struct pci_region *reg,
+				      unsigned long bus_start,
+				      unsigned long phys_start,
+				      unsigned long size,
+				      unsigned long flags) {
+	reg->bus_start	= bus_start;
+	reg->phys_start = phys_start;
+	reg->size	= size;
+	reg->flags	= flags;
+}
+
+typedef int pci_dev_t;
+
+#define PCI_BUS(d)	(((d) >> 16) & 0xff)
+#define PCI_DEV(d)	(((d) >> 11) & 0x1f)
+#define PCI_FUNC(d)	(((d) >> 8) & 0x7)
+#define PCI_BDF(b,d,f)	((b) << 16 | (d) << 11 | (f) << 8)
+
+#define PCI_ANY_ID (~0)
+
+struct pci_device_id {
+	unsigned int vendor, device;		/* Vendor and device ID or PCI_ANY_ID */
+};
+
+struct pci_controller;
+
+struct pci_config_table {
+	unsigned int vendor, device;		/* Vendor and device ID or PCI_ANY_ID */
+	unsigned int class;			/* Class ID, or  PCI_ANY_ID */
+	unsigned int bus;			/* Bus number, or PCI_ANY_ID */
+	unsigned int dev;			/* Device number, or PCI_ANY_ID */
+	unsigned int func;			/* Function number, or PCI_ANY_ID */
+
+	void (*config_device)(struct pci_controller* hose, pci_dev_t dev,
+			      struct pci_config_table *);
+	unsigned long priv[3];
+};
+
+extern void pci_cfgfunc_nothing(struct pci_controller* hose, pci_dev_t dev,
+				struct pci_config_table *);
+extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev,
+				      struct pci_config_table *);
+
+#define MAX_PCI_REGIONS		7
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	struct pci_controller *next;
+
+	int first_busno;
+	int last_busno;
+
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+
+	struct pci_region regions[MAX_PCI_REGIONS];
+	int region_count;
+
+	struct pci_config_table *config_table;
+
+	void (*fixup_irq)(struct pci_controller *, pci_dev_t);
+
+	/* Low-level architecture-dependent routines */
+	int (*read_byte)(struct pci_controller*, pci_dev_t, int where, u8 *);
+	int (*read_word)(struct pci_controller*, pci_dev_t, int where, u16 *);
+	int (*read_dword)(struct pci_controller*, pci_dev_t, int where, u32 *);
+	int (*write_byte)(struct pci_controller*, pci_dev_t, int where, u8);
+	int (*write_word)(struct pci_controller*, pci_dev_t, int where, u16);
+	int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
+
+	/* Used by auto config */
+	struct pci_region *pci_mem, *pci_io;
+
+	/* Used by ppc405 autoconfig*/
+	struct pci_region *pci_fb;
+};
+
+extern __inline__ void pci_set_ops(struct pci_controller *hose,
+				   int (*read_byte)(struct pci_controller*,
+						    pci_dev_t, int where, u8 *),
+				   int (*read_word)(struct pci_controller*,
+						    pci_dev_t, int where, u16 *),
+				   int (*read_dword)(struct pci_controller*,
+						     pci_dev_t, int where, u32 *),
+				   int (*write_byte)(struct pci_controller*,
+						     pci_dev_t, int where, u8),
+				   int (*write_word)(struct pci_controller*,
+						     pci_dev_t, int where, u16),
+				   int (*write_dword)(struct pci_controller*,
+						      pci_dev_t, int where, u32)) {
+	hose->read_byte   = read_byte;
+	hose->read_word   = read_word;
+	hose->read_dword  = read_dword;
+	hose->write_byte  = write_byte;
+	hose->write_word  = write_word;
+	hose->write_dword = write_dword;
+}
+
+extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
+
+extern unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
+					  unsigned long addr, unsigned long flags);
+extern unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
+					  unsigned long addr, unsigned long flags);
+
+#define pci_phys_to_bus(dev, addr, flags) \
+	pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
+#define pci_bus_to_phys(dev, addr, flags) \
+	pci_hose_bus_to_phys(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
+
+#define pci_phys_to_mem(dev, addr)	pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
+#define pci_mem_to_phys(dev, addr)	pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
+#define pci_phys_to_io(dev, addr)	pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
+#define pci_io_to_phys(dev, addr)	pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+
+extern int pci_hose_read_config_byte(struct pci_controller *hose,
+				     pci_dev_t dev, int where, u8 *val);
+extern int pci_hose_read_config_word(struct pci_controller *hose,
+				     pci_dev_t dev, int where, u16 *val);
+extern int pci_hose_read_config_dword(struct pci_controller *hose,
+				      pci_dev_t dev, int where, u32 *val);
+extern int pci_hose_write_config_byte(struct pci_controller *hose,
+				      pci_dev_t dev, int where, u8 val);
+extern int pci_hose_write_config_word(struct pci_controller *hose,
+				      pci_dev_t dev, int where, u16 val);
+extern int pci_hose_write_config_dword(struct pci_controller *hose,
+				       pci_dev_t dev, int where, u32 val);
+
+extern int pci_read_config_byte(pci_dev_t dev, int where, u8 *val);
+extern int pci_read_config_word(pci_dev_t dev, int where, u16 *val);
+extern int pci_read_config_dword(pci_dev_t dev, int where, u32 *val);
+extern int pci_write_config_byte(pci_dev_t dev, int where, u8 val);
+extern int pci_write_config_word(pci_dev_t dev, int where, u16 val);
+extern int pci_write_config_dword(pci_dev_t dev, int where, u32 val);
+
+extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose,
+					       pci_dev_t dev, int where, u8 *val);
+extern int pci_hose_read_config_word_via_dword(struct pci_controller *hose,
+					       pci_dev_t dev, int where, u16 *val);
+extern int pci_hose_write_config_byte_via_dword(struct pci_controller *hose,
+						pci_dev_t dev, int where, u8 val);
+extern int pci_hose_write_config_word_via_dword(struct pci_controller *hose,
+						pci_dev_t dev, int where, u16 val);
+
+extern void pci_register_hose(struct pci_controller* hose);
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+extern int pci_hose_scan(struct pci_controller *hose);
+extern int pci_hose_scan_bus(struct pci_controller *hose, int bus);
+
+extern void pciauto_region_init(struct pci_region* res);
+extern void pciauto_region_align(struct pci_region *res, unsigned long size);
+extern int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
+extern void pciauto_setup_device(struct pci_controller *hose,
+				 pci_dev_t dev, int bars_num,
+				 struct pci_region *mem,
+				 struct pci_region *io);
+void pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
+
+extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
+extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
+
+extern int pci_hose_config_device(struct pci_controller *hose,
+				  pci_dev_t dev,
+				  unsigned long io,
+				  unsigned long mem,
+				  unsigned long command);
+
+#ifdef CONFIG_MPC824X
+extern void pci_mpc824x_init (struct pci_controller *hose);
+#endif
+
+#endif	/* _PCI_H */
diff --git a/include/smiLynxEM.h b/include/smiLynxEM.h
new file mode 100644
index 0000000..cdd2f24
--- /dev/null
+++ b/include/smiLynxEM.h
@@ -0,0 +1,179 @@
+/*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * smiLynxEM.h
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ *
+ *  modification history
+ *  --------------------
+ *  04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ */
+
+#ifndef _SMI_LYNX_EM_H_
+#define _SMI_LYNX_EM_H_
+
+/*
+ * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
+ */
+#define VIDEO_MEM_SIZE  0x400000
+
+/*
+ * Supported video modes for SMI Lynx E/EM/EM+
+ */
+#define VIDEO_MODES             7
+#define DUAL_800_600            0   /* SMI710:VGA1:75Hz     (pitch=1600) */
+                                    /*        VGA2:60/120Hz (pitch=1600) */
+                                    /* SMI810:VGA1:75Hz     (pitch=1600) */
+                                    /*        VGA2:75Hz     (pitch=1600) */
+#define DUAL_1024_768           1   /* VGA1:75Hz VGA2:73Hz (pitch=2048)  */
+#define SINGLE_800_600          2   /* VGA1:75Hz (pitch=800)             */
+#define SINGLE_1024_768         3   /* VGA1:75Hz (pitch=1024)            */
+#define SINGLE_1280_1024        4   /* VGA1:75Hz (pitch=1280)            */
+#define TV_MODE_CCIR            5   /* VGA1:50Hz (h=720;v=576;pitch=720) */
+#define TV_MODE_EIA             6   /* VGA1:60Hz (h=720;v=484;pitch=720) */
+
+
+/*
+ * ISA mapped regs
+ */
+#define SMI_INDX_C4             (pGD->isaBase + 0x03c4)    /* index reg */
+#define SMI_DATA_C5             (pGD->isaBase + 0x03c5)    /* data reg */
+#define SMI_INDX_D4             (pGD->isaBase + 0x03d4)    /* index reg */
+#define SMI_DATA_D5             (pGD->isaBase + 0x03d5)    /* data reg */
+#define SMI_INDX_CE             (pGD->isaBase + 0x03ce)    /* index reg */
+#define SMI_DATA_CF             (pGD->isaBase + 0x03cf)    /* data reg */
+#define SMI_LOCK_REG            (pGD->isaBase + 0x03c3)    /* unlock/lock ext crt reg */
+#define SMI_MISC_REG            (pGD->isaBase + 0x03c2)    /* misc reg */
+#define SMI_LUT_MASK            (pGD->isaBase + 0x03c6)    /* lut mask reg */
+#define SMI_LUT_START           (pGD->isaBase + 0x03c8)    /* lut start index */
+#define SMI_LUT_RGB             (pGD->isaBase + 0x03c9)    /* lut colors auto incr.*/
+
+
+/*
+ * Video processor control
+ */
+typedef struct {
+    unsigned int   control;
+    unsigned int   colorKey;
+    unsigned int   colorKeyMask;
+    unsigned int   start;
+    unsigned short offset;
+    unsigned short width;
+    unsigned int   fifoPrio;
+    unsigned int   fifoERL;
+    unsigned int   YUVtoRGB;
+} SmiVideoProc;
+
+/*
+ * Video window control
+ */
+typedef struct {
+    unsigned short top;
+    unsigned short left;
+    unsigned short bottom;
+    unsigned short right;
+    unsigned int   srcStart;
+    unsigned short width;
+    unsigned short offset;
+    unsigned char  hStretch;
+    unsigned char  vStretch;
+} SmiVideoWin;
+
+/*
+ * Capture port control
+ */
+typedef struct {
+    unsigned int   control;
+    unsigned short topClip;
+    unsigned short leftClip;
+    unsigned short srcHeight;
+    unsigned short srcWidth;
+    unsigned int   srcBufStart1;
+    unsigned int   srcBufStart2;
+    unsigned short srcOffset;
+    unsigned short fifoControl;
+} SmiCapturePort;
+
+
+/******************************************************************************/
+/* Export Graphic Driver Control                                              */
+/******************************************************************************/
+
+typedef struct {
+    unsigned int isaBase;
+    unsigned int pciBase;
+    unsigned int dprBase;
+    unsigned int vprBase;
+    unsigned int cprBase;
+    unsigned int frameAdrs;
+    unsigned int memSize;
+    unsigned int mode;
+    unsigned int gdfIndex;
+    unsigned int gdfBytesPP;
+    unsigned int fg;
+    unsigned int bg;
+    unsigned int plnSizeX;
+    unsigned int plnSizeY;
+    unsigned int winSizeX;
+    unsigned int winSizeY;
+    char modeIdent[80];
+} GraphicDevice;
+
+extern GraphicDevice smi;
+
+
+/******************************************************************************/
+/* Export Graphic Functions                                                   */
+/******************************************************************************/
+
+void *video_hw_init (void);       /* returns GraphicDevice struct or NULL */
+
+void video_hw_bitblt (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int src_x,           /* source pos x */
+    unsigned int src_y,           /* source pos y */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y            /* frame height */
+    );
+
+void video_hw_rectfill (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y,           /* frame height */
+    unsigned int color            /* fill color */
+     );
+
+void video_set_lut (
+    unsigned int index,           /* color number */
+    unsigned char r,              /* red */
+    unsigned char g,              /* green */
+    unsigned char b               /* blue */
+    );
+
+#endif /*_SMI_LYNX_EM_H_ */
diff --git a/include/spartan2.h b/include/spartan2.h
new file mode 100644
index 0000000..42806e3
--- /dev/null
+++ b/include/spartan2.h
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.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
+ *
+ */
+
+#ifndef _SPARTAN2_H_
+#define _SPARTAN2_H_
+
+#include <xilinx.h>
+
+extern int Spartan2_load( Xilinx_desc *desc, void *image, size_t size );
+extern int Spartan2_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int Spartan2_info( Xilinx_desc *desc );
+extern int Spartan2_reloc( Xilinx_desc *desc, ulong reloc_off );
+
+/* Slave Parallel Implementation function table */
+typedef struct {
+	Xilinx_pre_fn	pre;
+	Xilinx_pgm_fn	pgm;
+	Xilinx_init_fn	init;
+	Xilinx_err_fn	err;
+	Xilinx_done_fn	done;
+	Xilinx_clk_fn	clk;
+	Xilinx_cs_fn	cs;
+	Xilinx_wr_fn	wr;
+	Xilinx_rdata_fn	rdata;
+	Xilinx_wdata_fn	wdata;
+	Xilinx_busy_fn	busy;
+	Xilinx_abort_fn	abort;
+	Xilinx_post_fn	post;
+	int           	relocated;
+} Xilinx_Spartan2_Slave_Parallel_fns;
+
+/* Slave Serial Implementation function table */
+typedef struct {
+	Xilinx_pgm_fn	pgm;
+	Xilinx_clk_fn	clk;
+	Xilinx_rdata_fn	rdata;
+	Xilinx_wdata_fn	wdata;
+	int           	relocated;
+} Xilinx_Spartan2_Slave_Serial_fns;
+
+/* Device Image Sizes
+ *********************************************************************/
+/* Spartan-II (2.5V) */
+#define XILINX_XC2S15_SIZE  	197728/8
+#define XILINX_XC2S30_SIZE  	336800/8
+#define XILINX_XC2S50_SIZE  	559232/8
+#define XILINX_XC2S100_SIZE 	781248/8
+#define XILINX_XC2S150_SIZE 	1040128/8
+
+/* Descriptor Macros
+ *********************************************************************/
+/* Spartan-II devices */
+#define XILINX_XC2S15_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S15_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S30_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S30_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S50_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S50_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S100_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S100_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S150_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie }
+
+#endif /* _SPARTAN2_H_ */
+
diff --git a/include/status_led.h b/include/status_led.h
new file mode 100644
index 0000000..9b2de3e
--- /dev/null
+++ b/include/status_led.h
@@ -0,0 +1,263 @@
+/*
+ * (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
+ */
+
+/*
+ * The purpose of this code is to signal the operational status of a
+ * target which usually boots over the network; while running in
+ * PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
+ * message has been received, the LED is turned off. The Linux
+ * kernel, once it is running, will start blinking the LED again,
+ * with another frequency.
+ */
+
+#ifndef _STATUS_LED_H_
+#define	_STATUS_LED_H_
+
+#ifdef CONFIG_STATUS_LED
+
+#define STATUS_LED_OFF		0
+#define STATUS_LED_BLINKING	1
+#define STATUS_LED_ON		2
+
+void status_led_tick (unsigned long timestamp);
+void status_led_set  (int led, int state);
+
+/*****  TQM8xxL  ********************************************************/
+#if defined(CONFIG_TQM8xxL)
+# define STATUS_LED_PAR		im_cpm.cp_pbpar
+# define STATUS_LED_DIR		im_cpm.cp_pbdir
+# define STATUS_LED_ODR		im_cpm.cp_pbodr
+# define STATUS_LED_DAT		im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT		0x00000001
+# define STATUS_LED_PERIOD	(CFG_HZ / 2)
+# define STATUS_LED_STATE	STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE	1		/* LED on for bit == 1	*/
+
+# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */
+
+/*****  MVS v1  **********************************************************/
+#elif (defined(CONFIG_MVS) && CONFIG_MVS < 2)
+# define STATUS_LED_PAR		im_ioport.iop_pdpar
+# define STATUS_LED_DIR		im_ioport.iop_pddir
+# undef  STATUS_LED_ODR
+# define STATUS_LED_DAT		im_ioport.iop_pddat
+
+# define STATUS_LED_BIT		0x00000001
+# define STATUS_LED_PERIOD	(CFG_HZ / 2)
+# define STATUS_LED_STATE	STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE	1		/* LED on for bit == 1	*/
+
+# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */
+
+/*****  ETX_094  ********************************************************/
+#elif defined(CONFIG_ETX094)
+
+# define STATUS_LED_PAR		im_ioport.iop_pdpar
+# define STATUS_LED_DIR		im_ioport.iop_pddir
+# undef  STATUS_LED_ODR
+# define STATUS_LED_DAT		im_ioport.iop_pddat
+
+# define STATUS_LED_BIT		0x00000001
+# define STATUS_LED_PERIOD	(CFG_HZ / 2)
+# define STATUS_LED_STATE	STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE	0		/* LED on for bit == 0	*/
+
+# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */
+
+/*****  GEN860T  *********************************************************/
+#elif defined(CONFIG_GEN860T)
+
+# define STATUS_LED_PAR			im_ioport.iop_papar
+# define STATUS_LED_DIR			im_ioport.iop_padir
+# define STATUS_LED_ODR			im_ioport.iop_paodr
+# define STATUS_LED_DAT			im_ioport.iop_padat
+
+# define STATUS_LED_BIT			0x0800	/* Red LED 0 is on PA.4	*/
+# define STATUS_LED_PERIOD		(CFG_HZ / 2)
+# define STATUS_LED_STATE		STATUS_LED_BLINKING
+# define STATUS_LED_BIT1		0x0400	/* Grn LED 1 is on PA.5	*/
+# define STATUS_LED_PERIOD1		(CFG_HZ / 2)
+# define STATUS_LED_STATE1		STATUS_LED_BLINKING
+# define STATUS_LED_BIT2		0x0080	/* Red LED 2 is on PA.8	*/
+# define STATUS_LED_PERIOD2		(CFG_HZ / 2)
+# define STATUS_LED_STATE2		STATUS_LED_BLINKING
+# define STATUS_LED_BIT3		0x0040	/* Grn LED 3 is on PA.9	*/
+# define STATUS_LED_PERIOD3		(CFG_HZ / 2)
+# define STATUS_LED_STATE3		STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE		1	/* LED on for bit == 1	*/
+# define STATUS_LED_BOOT		0	/* Boot status on LED 1	*/
+
+/*****  IVMS8  **********************************************************/
+#elif defined(CONFIG_IVMS8)
+
+# define STATUS_LED_PAR		im_cpm.cp_pbpar
+# define STATUS_LED_DIR		im_cpm.cp_pbdir
+# define STATUS_LED_ODR		im_cpm.cp_pbodr
+# define STATUS_LED_DAT		im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT		0x00000010	/* LED 0 is on PB.27	*/
+# define STATUS_LED_PERIOD	(1 * CFG_HZ)
+# define STATUS_LED_STATE	STATUS_LED_OFF
+# define STATUS_LED_BIT1	0x00000020	/* LED 1 is on PB.26	*/
+# define STATUS_LED_PERIOD1	(1 * CFG_HZ)
+# define STATUS_LED_STATE1	STATUS_LED_OFF
+/* IDE LED usable for other purposes, too */
+# define STATUS_LED_BIT2	0x00000008	/* LED 2 is on PB.28	*/
+# define STATUS_LED_PERIOD2	(1 * CFG_HZ)
+# define STATUS_LED_STATE2	STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE	1		/* LED on for bit == 1	*/
+
+# define STATUS_ILOCK_SWITCH	0x00800000	/* ILOCK switch in IRQ4	*/
+
+# define STATUS_ILOCK_PERIOD	(CFG_HZ / 10)	/* about every 100 ms	*/
+
+# define STATUS_LED_YELLOW	0
+# define STATUS_LED_GREEN	1
+# define STATUS_LED_BOOT	2		/* IDE LED used for boot status */
+
+/*****  IVML24  *********************************************************/
+#elif defined(CONFIG_IVML24)
+
+# define STATUS_LED_PAR		im_cpm.cp_pbpar
+# define STATUS_LED_DIR		im_cpm.cp_pbdir
+# define STATUS_LED_ODR		im_cpm.cp_pbodr
+# define STATUS_LED_DAT		im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT		0x00000010	/* LED 0 is on PB.27	*/
+# define STATUS_LED_PERIOD	(1 * CFG_HZ)
+# define STATUS_LED_STATE	STATUS_LED_OFF
+# define STATUS_LED_BIT1	0x00000020	/* LED 1 is on PB.26	*/
+# define STATUS_LED_PERIOD1	(1 * CFG_HZ)
+# define STATUS_LED_STATE1	STATUS_LED_OFF
+/* IDE LED usable for other purposes, too */
+# define STATUS_LED_BIT2	0x00000008	/* LED 2 is on PB.28	*/
+# define STATUS_LED_PERIOD2	(1 * CFG_HZ)
+# define STATUS_LED_STATE2	STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE	1		/* LED on for bit == 1	*/
+
+# define STATUS_ILOCK_SWITCH	0x00004000	/* ILOCK is on PB.17	*/
+
+# define STATUS_ILOCK_PERIOD	(CFG_HZ / 10)	/* about every 100 ms	*/
+
+# define STATUS_LED_YELLOW	0
+# define STATUS_LED_GREEN	1
+# define STATUS_LED_BOOT	2		/* IDE LED used for boot status */
+
+/*****  LANTEC  *********************************************************/
+#elif defined(CONFIG_LANTEC)
+
+# define STATUS_LED_PAR		im_ioport.iop_pdpar
+# define STATUS_LED_DIR		im_ioport.iop_pddir
+# undef  STATUS_LED_ODR
+# define STATUS_LED_DAT		im_ioport.iop_pddat
+
+# if CONFIG_LATEC < 2
+#  define STATUS_LED_BIT	0x1000
+# else
+#  define STATUS_LED_BIT	0x0800
+# endif
+# define STATUS_LED_PERIOD	(CFG_HZ / 2)
+# define STATUS_LED_STATE	STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE	0		/* LED on for bit == 0 */
+
+# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */
+
+/*****  PCU E  and  CCM  ************************************************/
+#elif (defined(CONFIG_PCU_E) || defined(CONFIG_CCM))
+
+# define STATUS_LED_PAR		im_cpm.cp_pbpar
+# define STATUS_LED_DIR		im_cpm.cp_pbdir
+# define STATUS_LED_ODR		im_cpm.cp_pbodr
+# define STATUS_LED_DAT		im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT		0x00010000	/* green LED is on PB.15 */
+# define STATUS_LED_PERIOD	(CFG_HZ / 2)
+# define STATUS_LED_STATE	STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE	1		/* LED on for bit == 1 */
+
+# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */
+
+/*****  ICU862   ********************************************************/
+#elif defined(CONFIG_ICU862)
+
+# define STATUS_LED_PAR		im_ioport.iop_papar
+# define STATUS_LED_DIR		im_ioport.iop_padir
+# define STATUS_LED_ODR		im_ioport.iop_paodr
+# define STATUS_LED_DAT		im_ioport.iop_padat
+
+# define STATUS_LED_BIT		0x4000		/* LED 0 is on PA.1 */
+# define STATUS_LED_PERIOD	(CFG_HZ / 2)
+# define STATUS_LED_STATE	STATUS_LED_BLINKING
+# define STATUS_LED_BIT1	0x1000		/* LED 1 is on PA.3 */
+# define STATUS_LED_PERIOD1	(CFG_HZ)
+# define STATUS_LED_STATE1	STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE	1		/* LED on for bit == 1	*/
+
+# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */
+
+/*****  Someone else defines these  *************************************/
+#elif defined(STATUS_LED_PAR)
+
+  /*
+   * ADVICE: Define in your board configuration file rather than
+   * filling this file up with lots of custom board stuff.
+   */
+
+/*****  NetVia   ********************************************************/
+#elif defined(CONFIG_NETVIA)
+
+#define STATUS_LED_PAR		im_ioport.iop_pdpar
+#define STATUS_LED_DIR		im_ioport.iop_pddir
+#undef  STATUS_LED_ODR
+#define STATUS_LED_DAT		im_ioport.iop_pddat
+
+# define STATUS_LED_BIT		0x0080			/* PD.8 */
+# define STATUS_LED_PERIOD	(CFG_HZ / 2)
+# define STATUS_LED_STATE	STATUS_LED_BLINKING
+
+# define STATUS_LED_BIT1	0x0040			/* PD.9 */
+# define STATUS_LED_PERIOD1	(CFG_HZ / 2)
+# define STATUS_LED_STATE1	STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE	0		/* LED on for bit == 0	*/
+# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */
+
+/************************************************************************/
+#else
+# error Status LED configuration missing
+#endif
+/************************************************************************/
+
+#endif	/* CONFIG_STATUS_LED	*/
+
+#endif	/* _STATUS_LED_H_	*/
diff --git a/include/video_fb.h b/include/video_fb.h
new file mode 100644
index 0000000..a9e4275
--- /dev/null
+++ b/include/video_fb.h
@@ -0,0 +1,115 @@
+                                                                                    /*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * smiLynxEM.h
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ *
+ *  modification history
+ *  --------------------
+ *  04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ */
+
+#ifndef _VIDEO_FB_H_
+#define _VIDEO_FB_H_
+
+#define CONSOLE_BG_COL            0x00
+#define CONSOLE_FG_COL            0xa0
+
+/*
+ * Graphic Data Format (GDF) bits for VIDEO_DATA_FORMAT
+ */
+#define GDF__8BIT_INDEX         0
+#define GDF_15BIT_555RGB        1
+#define GDF_16BIT_565RGB        2
+#define GDF_32BIT_X888RGB       3
+#define GDF_24BIT_888RGB        4
+#define GDF__8BIT_332RGB        5
+
+/******************************************************************************/
+/* Export Graphic Driver Control                                              */
+/******************************************************************************/
+
+typedef struct {
+    unsigned int isaBase;
+    unsigned int pciBase;
+    unsigned int dprBase;
+    unsigned int vprBase;
+    unsigned int cprBase;
+    unsigned int frameAdrs;
+    unsigned int memSize;
+    unsigned int mode;
+    unsigned int gdfIndex;
+    unsigned int gdfBytesPP;
+    unsigned int fg;
+    unsigned int bg;
+    unsigned int plnSizeX;
+    unsigned int plnSizeY;
+    unsigned int winSizeX;
+    unsigned int winSizeY;
+    char modeIdent[80];
+} GraphicDevice;
+
+
+/******************************************************************************/
+/* Export Graphic Functions                                                   */
+/******************************************************************************/
+
+void *video_hw_init (void);       /* returns GraphicDevice struct or NULL */
+
+#ifdef VIDEO_HW_BITBLT
+void video_hw_bitblt (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int src_x,           /* source pos x */
+    unsigned int src_y,           /* source pos y */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y            /* frame height */
+    );
+#endif
+
+#ifdef VIDEO_HW_RECTFILL
+void video_hw_rectfill (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y,           /* frame height */
+    unsigned int color            /* fill color */
+     );
+#endif
+
+void video_set_lut (
+    unsigned int index,           /* color number */
+    unsigned char r,              /* red */
+    unsigned char g,              /* green */
+    unsigned char b               /* blue */
+    );
+#ifdef CONFIG_VIDEO_HW_CURSOR
+void video_set_hw_cursor(int x, int y); /* x y in pixel */
+void video_init_hw_cursor(int font_width, int font_height);
+#endif
+
+#endif /*_VIDEO_FB_H_ */
diff --git a/include/virtex2.h b/include/virtex2.h
new file mode 100644
index 0000000..f59227b
--- /dev/null
+++ b/include/virtex2.h
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * Keith Outwater, keith_outwater@mvis.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
+ *
+ */
+
+#ifndef _VIRTEX2_H_
+#define _VIRTEX2_H_
+
+#include <xilinx.h>
+
+extern int Virtex2_load( Xilinx_desc *desc, void *image, size_t size );
+extern int Virtex2_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int Virtex2_info( Xilinx_desc *desc );
+extern int Virtex2_reloc( Xilinx_desc *desc, ulong reloc_off );
+
+/*
+ * Slave SelectMap Implementation function table.
+ */
+typedef struct {
+	Xilinx_pre_fn	pre;
+	Xilinx_pgm_fn	pgm;
+	Xilinx_init_fn	init;
+	Xilinx_err_fn	err;
+	Xilinx_done_fn	done;
+	Xilinx_clk_fn	clk;
+	Xilinx_cs_fn	cs;
+	Xilinx_wr_fn	wr;
+	Xilinx_rdata_fn	rdata;
+	Xilinx_wdata_fn	wdata;
+	Xilinx_busy_fn	busy;
+	Xilinx_abort_fn	abort;
+	Xilinx_post_fn	post;
+	int           	relocated;
+} Xilinx_Virtex2_Slave_SelectMap_fns;
+
+/* Slave Serial Implementation function table */
+typedef struct {
+	Xilinx_pgm_fn	pgm;
+	Xilinx_clk_fn	clk;
+	Xilinx_rdata_fn	rdata;
+	Xilinx_wdata_fn	wdata;
+	int           	relocated;
+} Xilinx_Virtex2_Slave_Serial_fns;
+
+/* Device Image Sizes (in bytes)
+ *********************************************************************/
+#define XILINX_XC2V40_SIZE		(338208 / 8)
+#define XILINX_XC2V80_SIZE		(597408 / 8)
+#define XILINX_XC2V250_SIZE		(1591584 / 8)
+#define XILINX_XC2V500_SIZE		(2557857 / 8)
+#define XILINX_XC2V1000_SIZE	(3749408 / 8)
+#define XILINX_XC2V1500_SIZE	(5166240 / 8)
+#define XILINX_XC2V2000_SIZE	(6808352 / 8)
+#define XILINX_XC2V3000_SIZE	(9589408 / 8)
+#define XILINX_XC2V4000_SIZE	(14220192 / 8)
+#define XILINX_XC2V6000_SIZE	(19752096 / 8)
+#define XILINX_XC2V8000_SIZE	(26185120 / 8)
+#define XILINX_XC2V10000_SIZE	(33519264 / 8)
+
+/* Descriptor Macros
+ *********************************************************************/
+#define XILINX_XC2V40_DESC(iface, fn_table, cookie)	\
+{ Xilinx_Virtex2, iface, XILINX_XC2V40_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V80_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V80_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V250_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V250_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V500_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V500_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V1000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V1000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V1500_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V1500_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V2000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V2000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V3000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V3000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V4000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V4000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V6000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V6000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V8000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V8000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V10000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V10000_SIZE, fn_table, cookie }
+
+#endif /* _VIRTEX2_H_ */
+
+/* vim: set ts=4 tw=78: */
diff --git a/include/xilinx.h b/include/xilinx.h
new file mode 100644
index 0000000..b87cfe2
--- /dev/null
+++ b/include/xilinx.h
@@ -0,0 +1,102 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.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
+ *
+ */
+
+#include <fpga.h>
+
+#ifndef _XILINX_H_
+#define _XILINX_H_
+
+/* Xilinx Model definitions
+ *********************************************************************/
+#define CFG_SPARTAN2 			CFG_FPGA_DEV( 0x1 )
+#define CFG_VIRTEX_E 			CFG_FPGA_DEV( 0x2 )
+#define CFG_VIRTEX2	 			CFG_FPGA_DEV( 0x4 )
+#define CFG_XILINX_SPARTAN2 	(CFG_FPGA_XILINX | CFG_SPARTAN2)
+#define CFG_XILINX_VIRTEX_E 	(CFG_FPGA_XILINX | CFG_VIRTEX_E)
+#define CFG_XILINX_VIRTEX2	 	(CFG_FPGA_XILINX | CFG_VIRTEX2)
+/* XXX - Add new models here */
+
+
+/* Xilinx Interface definitions
+ *********************************************************************/
+#define CFG_XILINX_IF_SS	CFG_FPGA_IF( 0x1 )	/* slave serial 	*/
+#define CFG_XILINX_IF_MS	CFG_FPGA_IF( 0x2 )	/* master serial	*/
+#define CFG_XILINX_IF_SP	CFG_FPGA_IF( 0x4 )	/* slave parallel 	*/
+#define CFG_XILINX_IF_JTAG	CFG_FPGA_IF( 0x8 )	/* jtag				*/
+#define CFG_XILINX_IF_MSM	CFG_FPGA_IF( 0x10 )	/* master selectmap	*/
+#define CFG_XILINX_IF_SSM	CFG_FPGA_IF( 0x20 )	/* slave selectmap	*/
+
+/* Xilinx types
+ *********************************************************************/
+typedef enum {					/* typedef Xilinx_iface	*/
+	min_xilinx_iface_type,		/* low range check value */
+    slave_serial,				/* serial data and external clock */
+    master_serial,				/* serial data w/ internal clock (not used) */
+    slave_parallel,				/* parallel data w/ external latch */
+    jtag_mode,					/* jtag/tap serial (not used ) */
+	master_selectmap,			/* master SelectMap (virtex2)		*/
+	slave_selectmap,			/* slave SelectMap (virtex2)		*/
+    max_xilinx_iface_type		/* insert all new types before this */
+} Xilinx_iface;					/* end, typedef Xilinx_iface */
+
+typedef enum {					/* typedef Xilinx_Family */
+	min_xilinx_type,			/* low range check value */
+    Xilinx_Spartan2,			/* Spartan-II Family */
+    Xilinx_VirtexE,				/* Virtex-E Family */
+    Xilinx_Virtex2,				/* Virtex2 Family */
+    max_xilinx_type				/* insert all new types before this */
+} Xilinx_Family;				/* end, typedef Xilinx_Family */
+
+typedef struct {				/* typedef Xilinx_desc */
+    Xilinx_Family    family;	/* part type */
+    Xilinx_iface     iface;		/* interface type */
+    size_t           size;		/* bytes of data part can accept */
+	void *           iface_fns;	/* interface function table */
+    int              cookie;	/* implementation specific cookie */
+} Xilinx_desc;					/* end, typedef Xilinx_desc */
+
+/* Generic Xilinx Functions
+ *********************************************************************/
+extern int xilinx_load( Xilinx_desc *desc, void *image, size_t size );
+extern int xilinx_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int xilinx_info( Xilinx_desc *desc );
+extern int xilinx_reloc( Xilinx_desc *desc, ulong reloc_offset );
+
+/* Board specific implementation specific function types
+ *********************************************************************/
+typedef int (*Xilinx_pgm_fn)( int assert_pgm, int flush, int cookie );
+typedef int (*Xilinx_init_fn)( int cookie );
+typedef int (*Xilinx_err_fn)( int cookie );
+typedef int (*Xilinx_done_fn)( int cookie );
+typedef int (*Xilinx_clk_fn)( int assert_clk, int flush, int cookie );
+typedef int (*Xilinx_cs_fn)( int assert_cs, int flush, int cookie );
+typedef int (*Xilinx_wr_fn)( int assert_write, int flush, int cookie );
+typedef int (*Xilinx_rdata_fn)( unsigned char *data, int cookie );
+typedef int (*Xilinx_wdata_fn)( unsigned char data, int flush, int cookie );
+typedef int (*Xilinx_busy_fn)( int cookie );
+typedef int (*Xilinx_abort_fn)( int cookie );
+typedef int (*Xilinx_pre_fn)( int cookie );
+typedef int (*Xilinx_post_fn)( int cookie );
+
+#endif  /* _XILINX_H_ */
diff --git a/lib_arm/_udivsi3.S b/lib_arm/_udivsi3.S
new file mode 100644
index 0000000..19454c1
--- /dev/null
+++ b/lib_arm/_udivsi3.S
@@ -0,0 +1,77 @@
+/* # 1 "libgcc1.S" */
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+dividend	.req	r0
+divisor		.req	r1
+result		.req	r2
+curbit		.req	r3
+ip		.req	r12
+sp		.req	r13
+lr		.req	r14
+pc		.req	r15
+	.text
+	.globl	 __udivsi3
+	.type  __udivsi3       ,function
+	.align	0
+ __udivsi3      :
+	cmp	divisor, #0
+	beq	Ldiv0
+	mov	curbit, #1
+	mov	result, #0
+	cmp	dividend, divisor
+	bcc	Lgot_result
+Loop1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	Loop1
+Lbignum:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	Lbignum
+Loop3:
+	@ Test for possible subtractions, and note which bits
+	@ are done in the result.  On the final pass, this may subtract
+	@ too much from the dividend, but the result will be ok, since the
+	@ "bit" will have been shifted out at the bottom.
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	orrcs	result, result, curbit
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	result, result, curbit, lsr #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	result, result, curbit, lsr #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	result, result, curbit, lsr #3
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	Loop3
+Lgot_result:
+	mov	r0, result
+	mov 	pc, lr
+Ldiv0:
+	str	lr, [sp, #-4]!
+	bl	 __div0       (PLT)
+	mov	r0, #0			@ about as wrong as it could be
+	ldmia	sp!, {pc}
+	.size  __udivsi3       , . -  __udivsi3
+/* # 235 "libgcc1.S" */
+/* # 320 "libgcc1.S" */
+/* # 421 "libgcc1.S" */
+/* # 433 "libgcc1.S" */
+/* # 456 "libgcc1.S" */
+/* # 500 "libgcc1.S" */
+/* # 580 "libgcc1.S" */
diff --git a/lib_arm/_umodsi3.S b/lib_arm/_umodsi3.S
new file mode 100644
index 0000000..899ffbf
--- /dev/null
+++ b/lib_arm/_umodsi3.S
@@ -0,0 +1,88 @@
+/* # 1 "libgcc1.S" */
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+/* # 145 "libgcc1.S" */
+dividend	.req	r0
+divisor		.req	r1
+overdone	.req	r2
+curbit		.req	r3
+ip		.req	r12
+sp		.req	r13
+lr		.req	r14
+pc		.req	r15
+	.text
+	.globl	 __umodsi3
+	.type  __umodsi3       ,function
+	.align 0
+ __umodsi3      :
+	cmp	divisor, #0
+	beq	Ldiv0
+	mov	curbit, #1
+	cmp	dividend, divisor
+	movcc  	pc, lr
+Loop1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	Loop1
+Lbignum:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	Lbignum
+Loop3:
+	@ Test for possible subtractions.  On the final pass, this may
+	@ subtract too much from the dividend, so keep track of which
+	@ subtractions are done, we can fix them up afterwards...
+	mov	overdone, #0
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	overdone, overdone, curbit, ror #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	overdone, overdone, curbit, ror #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	overdone, overdone, curbit, ror #3
+	mov	ip, curbit
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	Loop3
+	@ Any subtractions that we should not have done will be recorded in
+	@ the top three bits of "overdone".  Exactly which were not needed
+	@ are governed by the position of the bit, stored in ip.
+	@ If we terminated early, because dividend became zero,
+	@ then none of the below will match, since the bit in ip will not be
+	@ in the bottom nibble.
+	ands	overdone, overdone, #0xe0000000
+	moveq  	pc, lr				@ No fixups needed
+	tst	overdone, ip, ror #3
+	addne	dividend, dividend, divisor, lsr #3
+	tst	overdone, ip, ror #2
+	addne	dividend, dividend, divisor, lsr #2
+	tst	overdone, ip, ror #1
+	addne	dividend, dividend, divisor, lsr #1
+	mov 	pc, lr
+Ldiv0:
+	str	lr, [sp, #-4]!
+	bl	 __div0       (PLT)
+	mov	r0, #0			@ about as wrong as it could be
+	ldmia	sp!, {pc}
+	.size  __umodsi3       , . -  __umodsi3
+/* # 320 "libgcc1.S" */
+/* # 421 "libgcc1.S" */
+/* # 433 "libgcc1.S" */
+/* # 456 "libgcc1.S" */
+/* # 500 "libgcc1.S" */
+/* # 580 "libgcc1.S" */
diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c
new file mode 100644
index 0000000..e5b8faa
--- /dev/null
+++ b/lib_arm/armlinux.c
@@ -0,0 +1,324 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * 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_boot.h>
+#include <image.h>
+#include <zlib.h>
+#include <asm/byteorder.h>
+
+#include <asm/setup.h>
+#define tag_size(type)  ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
+#define tag_next(t)     ((struct tag *)((u32 *)(t) + (t)->hdr.size))
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_VFD)
+static void setup_start_tag(bd_t *bd);
+static void setup_memory_tags(bd_t *bd);
+static void setup_commandline_tag(bd_t *bd, char *commandline);
+#if 0
+static void setup_ramdisk_tag(bd_t *bd);
+#endif
+static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
+static void setup_end_tag(bd_t *bd);
+#if defined (CONFIG_VFD)
+static void setup_videolfb_tag(gd_t *gd);
+#endif
+
+
+static struct tag *params;
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
+
+extern image_header_t header;           /* from cmd_bootm.c */
+
+
+void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		ulong addr, ulong *len_ptr, int   verify)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    ulong len = 0, checksum;
+    ulong initrd_start, initrd_end;
+    ulong data;
+    void (*theKernel)(int zero, int arch);
+    image_header_t *hdr = &header;
+    bd_t *bd = gd->bd;
+#ifdef CONFIG_CMDLINE_TAG
+    char *commandline = getenv("bootargs");
+#endif
+
+    theKernel = (void (*)(int, int))ntohl(hdr->ih_ep);
+
+    /*
+     * Check if there is an initrd image
+     */
+    if (argc >= 3) {
+	addr = simple_strtoul(argv[2], NULL, 16);
+
+	printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
+
+	/* Copy header so we can blank CRC field for re-calculation */
+	memcpy (&header, (char *)addr, sizeof(image_header_t));
+
+	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+	    printf ("Bad Magic Number\n");
+	    do_reset (cmdtp, flag, argc, argv);
+	}
+
+	data = (ulong)&header;
+	len  = sizeof(image_header_t);
+
+	checksum = ntohl(hdr->ih_hcrc);
+	hdr->ih_hcrc = 0;
+
+	if (crc32 (0, (char *)data, len) != checksum) {
+	    printf ("Bad Header Checksum\n");
+	    do_reset (cmdtp, flag, argc, argv);
+	}
+
+	print_image_hdr (hdr);
+
+	data = addr + sizeof(image_header_t);
+	len  = ntohl(hdr->ih_size);
+
+	if (verify) {
+	    ulong csum = 0;
+
+	    printf ("   Verifying Checksum ... ");
+	    csum = crc32 (0, (char *)data, len);
+	    if (csum != ntohl(hdr->ih_dcrc)) {
+		printf ("Bad Data CRC\n");
+		do_reset (cmdtp, flag, argc, argv);
+	    }
+	    printf ("OK\n");
+	}
+
+	if ((hdr->ih_os   != IH_OS_LINUX)	||
+	    (hdr->ih_arch != IH_CPU_ARM)	||
+	    (hdr->ih_type != IH_TYPE_RAMDISK)	) {
+	    printf ("No Linux ARM Ramdisk Image\n");
+	    do_reset (cmdtp, flag, argc, argv);
+	}
+
+	/*
+	 * Now check if we have a multifile image
+	 */
+    } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
+	ulong tail    = ntohl(len_ptr[0]) % 4;
+	int i;
+
+	/* skip kernel length and terminator */
+	data = (ulong)(&len_ptr[2]);
+	/* skip any additional image length fields */
+	for (i=1; len_ptr[i]; ++i)
+	  data += 4;
+	/* add kernel length, and align */
+	data += ntohl(len_ptr[0]);
+	if (tail) {
+	    data += 4 - tail;
+	}
+
+	len   = ntohl(len_ptr[1]);
+
+    } else {
+	/*
+	 * no initrd image
+	 */
+	data = 0;
+    }
+
+#ifdef	DEBUG
+    if (!data) {
+	printf ("No initrd\n");
+    }
+#endif
+
+    if (data) {
+	initrd_start = data;
+	initrd_end   = initrd_start + len;
+    } else {
+	initrd_start = 0;
+	initrd_end = 0;
+    }
+
+#ifdef DEBUG
+    printf ("## Transferring control to Linux (at address %08lx) ...\n",
+	    (ulong)theKernel);
+#endif
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_VFD)
+    setup_start_tag(bd);
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+    setup_memory_tags(bd);
+#endif
+#ifdef CONFIG_CMDLINE_TAG
+    setup_commandline_tag(bd, commandline);
+#endif
+#ifdef CONFIG_INITRD_TAG
+    setup_initrd_tag(bd, initrd_start, initrd_end);
+#endif
+#if 0
+    setup_ramdisk_tag(bd);
+#endif
+#if defined (CONFIG_VFD)
+    setup_videolfb_tag(gd);
+#endif
+    setup_end_tag(bd);
+#endif
+
+    /* we assume that the kernel is in place */
+    printf("\nStarting kernel ...\n\n");
+
+    cleanup_before_linux();
+
+    theKernel(0, bd->bi_arch_number);
+}
+
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_VFD)
+static void setup_start_tag(bd_t *bd)
+{
+    params = (struct tag *)bd->bi_boot_params;
+
+    params->hdr.tag = ATAG_CORE;
+    params->hdr.size = tag_size(tag_core);
+
+    params->u.core.flags = 0;
+    params->u.core.pagesize = 0;
+    params->u.core.rootdev = 0;
+
+    params = tag_next(params);
+}
+
+
+static void setup_memory_tags(bd_t *bd)
+{
+    int i;
+
+    for(i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+	params->hdr.tag = ATAG_MEM;
+	params->hdr.size = tag_size(tag_mem32);
+
+	params->u.mem.start = bd->bi_dram[i].start;
+	params->u.mem.size = bd->bi_dram[i].size;
+
+	params = tag_next(params);
+    }
+}
+
+
+static void setup_commandline_tag(bd_t *bd, char *commandline)
+{
+    char *p;
+
+    /* eat leading white space */
+    for(p = commandline; *p == ' '; p++)
+      ;
+
+    /* skip non-existent command lines so the kernel will still
+     * use its default command line.
+     */
+    if(*p == '\0')
+      return;
+
+    params->hdr.tag = ATAG_CMDLINE;
+    params->hdr.size = (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
+
+    strcpy(params->u.cmdline.cmdline, p);
+
+    params = tag_next(params);
+}
+
+
+#ifndef ATAG_INITRD2
+#define ATAG_INITRD2    0x54420005
+#endif
+static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
+{
+    /* an ATAG_INITRD node tells the kernel where the compressed
+     * ramdisk can be found. ATAG_RDIMG is a better name, actually.
+     */
+    params->hdr.tag = ATAG_INITRD2;
+    params->hdr.size = tag_size(tag_initrd);
+
+    params->u.initrd.start = initrd_start;
+    params->u.initrd.size = initrd_end - initrd_start;
+
+    params = tag_next(params);
+}
+
+
+#if 0
+static void setup_ramdisk_tag(bd_t *bd)
+{
+    /* an ATAG_RAMDISK node tells the kernel how large the
+     * decompressed ramdisk will become.
+     */
+    params->hdr.tag = ATAG_RAMDISK;
+    params->hdr.size = tag_size(tag_ramdisk);
+
+    params->u.ramdisk.start = 0;
+    /*params->u.ramdisk.size = RAMDISK_SIZE; */
+    params->u.ramdisk.flags = 1;	/* automatically load ramdisk */
+
+    params = tag_next(params);
+}
+#endif /* 0 */
+
+#if defined (CONFIG_VFD)
+static void setup_videolfb_tag(gd_t *gd)
+{
+    /* An ATAG_VIDEOLFB node tells the kernel where and how large
+     * the framebuffer for video was allocated (among other things).
+     * Note that a _physical_ address is passed !
+     *
+     * We only use it to pass the address and size, the other entries
+     * in the tag_videolfb are not of interest.
+     */
+    params->hdr.tag = ATAG_VIDEOLFB;
+    params->hdr.size = tag_size(tag_videolfb);
+
+    params->u.videolfb.lfb_base = (u32)gd->fb_base;
+    /* 7168 = 256*4*56/8 - actually 2 pages (8192 bytes) are allocated */
+    params->u.videolfb.lfb_size = 7168;
+
+    params = tag_next(params);
+}
+#endif
+
+static void setup_end_tag(bd_t *bd)
+{
+    params->hdr.tag = ATAG_NONE;
+    params->hdr.size = 0;
+}
+
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
diff --git a/lib_arm/board.c b/lib_arm/board.c
new file mode 100644
index 0000000..e58529f
--- /dev/null
+++ b/lib_arm/board.c
@@ -0,0 +1,382 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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 <command.h>
+#include <devices.h>
+#include <version.h>
+#include <net.h>
+
+
+const char version_string[] =
+	U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
+
+#ifdef CONFIG_DRIVER_CS8900
+extern void cs8900_get_enetaddr (uchar * addr);
+#endif
+
+/*
+ * Begin and End of memory area for malloc(), and current "brk"
+ */
+static ulong mem_malloc_start = 0;
+static ulong mem_malloc_end = 0;
+static ulong mem_malloc_brk = 0;
+
+static void mem_malloc_init (ulong dest_addr)
+{
+	mem_malloc_start = dest_addr;
+	mem_malloc_end = dest_addr + CONFIG_MALLOC_SIZE;
+	mem_malloc_brk = mem_malloc_start;
+
+	memset ((void *) mem_malloc_start, 0,
+			mem_malloc_end - mem_malloc_start);
+}
+
+void *sbrk (ptrdiff_t increment)
+{
+	ulong old = mem_malloc_brk;
+	ulong new = old + increment;
+
+	if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
+		return (NULL);
+	}
+	mem_malloc_brk = new;
+
+	return ((void *) old);
+}
+
+/************************************************************************
+ * Init Utilities							*
+ ************************************************************************
+ * Some of this code should be moved into the core functions,
+ * or dropped completely,
+ * but let's get it working (again) first...
+ */
+
+static int init_baudrate (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	uchar tmp[64];	/* long enough for environment variables */
+	int i = getenv_r ("baudrate", tmp, sizeof (tmp));
+
+	gd->baudrate = (i > 0)
+			? (int) simple_strtoul (tmp, NULL, 10)
+			: CONFIG_BAUDRATE;
+
+	return (0);
+}
+
+static int display_banner (void)
+{
+
+	printf ("\n\n%s\n\n", version_string);
+	printf ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
+		_armboot_start, _armboot_end_data, _armboot_end);
+#ifdef CONFIG_MODEM_SUPPORT
+	puts ("Modem Support enabled\n");
+#endif
+#ifdef CONFIG_USE_IRQ
+	printf ("IRQ Stack: %08lx\n", IRQ_STACK_START);
+	printf ("FIQ Stack: %08lx\n", FIQ_STACK_START);
+#endif
+	return (0);
+}
+
+/*
+ * WARNING: this code looks "cleaner" than the PowerPC version, but
+ * has the disadvantage that you either get nothing, or everything.
+ * On PowerPC, you might see "DRAM: " before the system hangs - which
+ * gives a simple yet clear indication which part of the
+ * initialization if failing.
+ */
+static int display_dram_config (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	int i;
+
+	puts ("DRAM Configuration:\n");
+
+	for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
+		printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
+		print_size (gd->bd->bi_dram[i].size, "\n");
+	}
+
+	return (0);
+}
+
+static void display_flash_config (ulong size)
+{
+	puts ("Flash: ");
+	print_size (size, "\n");
+}
+
+
+
+/*
+ * Breath some life into the board...
+ *
+ * Initialize an SMC for serial comms, and carry out some hardware
+ * tests.
+ *
+ * The first part of initialization is running from Flash memory;
+ * its main purpose is to initialize the RAM so that we
+ * can relocate the monitor code to RAM.
+ */
+
+/*
+ * All attempts to come up with a "common" initialization sequence
+ * that works for all boards and architectures failed: some of the
+ * requirements are just _too_ different. To get rid of the resulting
+ * mess of board dependend #ifdef'ed code we now make the whole
+ * initialization sequence configurable to the user.
+ *
+ * The requirements for any new initalization function is simple: it
+ * receives a pointer to the "global data" structure as it's only
+ * argument, and returns an integer return code, where 0 means
+ * "continue" and != 0 means "fatal error, hang the system".
+ */
+typedef int (init_fnc_t) (void);
+
+init_fnc_t *init_sequence[] = {
+	cpu_init,		/* basic cpu dependent setup */
+	board_init,		/* basic board dependent setup */
+	interrupt_init,		/* set up exceptions */
+	env_init,		/* initialize environment */
+	init_baudrate,		/* initialze baudrate settings */
+	serial_init,		/* serial communications setup */
+	display_banner,
+	dram_init,		/* configure available RAM banks */
+	display_dram_config,
+
+	NULL,
+};
+
+void start_armboot (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	ulong size;
+	gd_t gd_data;
+	bd_t bd_data;
+	init_fnc_t **init_fnc_ptr;
+#ifdef CONFIG_VFD
+	unsigned long addr;
+#endif
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = &gd_data;
+	memset (gd, 0, sizeof (gd_t));
+	gd->bd = &bd_data;
+	memset (gd->bd, 0, sizeof (bd_t));
+
+	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+		if ((*init_fnc_ptr)() != 0) {
+			hang ();
+		}
+	}
+
+	/* configure available FLASH banks */
+	size = flash_init ();
+	display_flash_config (size);
+
+#ifdef CONFIG_VFD
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+	/*
+	 * reserve memory for VFD display (always full pages)
+	 */
+	/* armboot_real_end is defined in the board-specific linker script */
+	addr = (_armboot_real_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+	size = vfd_setmem (addr);
+	gd->fb_base = addr;
+	/* round to the next page boundary */
+	addr += size;
+	addr = (addr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+	mem_malloc_init (addr);
+#else
+	/* armboot_real_end is defined in the board-specific linker script */
+	mem_malloc_init (_armboot_real_end);
+#endif /* CONFIG_VFD */
+
+#ifdef CONFIG_VFD
+	/* must do this after the framebuffer is allocated */
+	drv_vfd_init();
+#endif
+	/* initialize environment */
+	env_relocate ();
+
+	/* IP Address */
+	bd_data.bi_ip_addr = getenv_IPaddr ("ipaddr");
+
+	/* MAC Address */
+	{
+		int i;
+		ulong reg;
+		char *s, *e;
+		uchar tmp[64];
+
+		i = getenv_r ("ethaddr", tmp, sizeof (tmp));
+		s = (i > 0) ? tmp : NULL;
+
+		for (reg = 0; reg < 6; ++reg) {
+			bd_data.bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+			if (s)
+				s = (*e) ? e + 1 : e;
+		}
+	}
+
+#if defined(CONFIG_MISC_INIT_R)
+	/* miscellaneous platform dependent initialisations */
+	misc_init_r ();
+#endif
+
+	/* enable exceptions */
+	enable_interrupts ();
+
+#ifdef CONFIG_DRIVER_CS8900
+	if (!getenv ("ethaddr")) {
+		cs8900_get_enetaddr (gd->bd->bi_enetaddr);
+	}
+#endif
+
+#ifdef BOARD_POST_INIT
+	board_post_init ();
+#endif
+
+	/* main_loop() can return to retry autoboot, if so just run it again. */
+	for (;;) {
+		main_loop ();
+	}
+
+	/* NOTREACHED - no way out of command loop except booting */
+}
+
+void hang (void)
+{
+	puts ("### ERROR ### Please RESET the board ###\n");
+	for (;;);
+}
+
+#ifdef CONFIG_MODEM_SUPPORT
+/* called from main loop (common/main.c) */
+extern void  dbg(const char *fmt, ...);
+int mdm_init (void)
+{
+	char env_str[16];
+	char *init_str;
+	int i;
+	extern char console_buffer[];
+	static inline void mdm_readline(char *buf, int bufsiz);
+	extern void enable_putc(void);
+	extern int hwflow_onoff(int);
+
+	enable_putc(); /* enable serial_putc() */
+
+#ifdef CONFIG_HWFLOW
+	init_str = getenv("mdm_flow_control");
+	if (init_str && (strcmp(init_str, "rts/cts") == 0))
+		hwflow_onoff (1);
+	else
+		hwflow_onoff(-1);
+#endif
+
+	for (i = 1;;i++) {
+		sprintf(env_str, "mdm_init%d", i);
+		if ((init_str = getenv(env_str)) != NULL) {
+			serial_puts(init_str);
+			serial_puts("\n");
+			for(;;) {
+				mdm_readline(console_buffer, CFG_CBSIZE);
+				dbg("ini%d: [%s]", i, console_buffer);
+
+				if ((strcmp(console_buffer, "OK") == 0) ||
+					(strcmp(console_buffer, "ERROR") == 0)) {
+					dbg("ini%d: cmd done", i);
+					break;
+				} else /* in case we are originating call ... */
+					if (strncmp(console_buffer, "CONNECT", 7) == 0) {
+						dbg("ini%d: connect", i);
+						return 0;
+					}
+			}
+		} else
+			break; /* no init string - stop modem init */
+
+		udelay(100000);
+	}
+
+	udelay(100000);
+
+	/* final stage - wait for connect */
+	for(;i > 1;) { /* if 'i' > 1 - wait for connection
+				  message from modem */
+		mdm_readline(console_buffer, CFG_CBSIZE);
+		dbg("ini_f: [%s]", console_buffer);
+		if (strncmp(console_buffer, "CONNECT", 7) == 0) {
+			dbg("ini_f: connected");
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+/* 'inline' - We have to do it fast */
+static inline void mdm_readline(char *buf, int bufsiz)
+{
+	char c;
+	char *p;
+	int n;
+
+	n = 0;
+	p = buf;
+	for(;;) {
+		c = serial_getc();
+
+		/*		dbg("(%c)", c); */
+
+		switch(c) {
+		case '\r':
+			break;
+		case '\n':
+			*p = '\0';
+			return;
+
+		default:
+			if(n++ > bufsiz) {
+				*p = '\0';
+				return; /* sanity check */
+			}
+			*p = c;
+			p++;
+			break;
+		}
+	}
+}
+#endif	/* CONFIG_MODEM_SUPPORT */
diff --git a/lib_generic/string.c b/lib_generic/string.c
new file mode 100644
index 0000000..1e1e2e3
--- /dev/null
+++ b/lib_generic/string.c
@@ -0,0 +1,574 @@
+/*
+ *  linux/lib/string.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/*
+ * stupid library routines.. The optimized versions should generally be found
+ * as inline code in <asm-xx/string.h>
+ *
+ * These are buggy as well..
+ *
+ * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
+ * -  Added strsep() which will replace strtok() soon (because strsep() is
+ *    reentrant and should be faster). Use only strsep() in new code, please.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <malloc.h>
+
+#ifdef	CONFIG_ARM
+#undef  __HAVE_ARCH_MEMCMP
+#undef  __HAVE_ARCH_MEMCPY
+#undef  __HAVE_ARCH_MEMMOVE
+#undef  __HAVE_ARCH_MEMSET
+#undef  __HAVE_ARCH_BCOPY
+#undef  __HAVE_ARCH_STRCAT
+#undef  __HAVE_ARCH_STRCHR
+#undef  __HAVE_ARCH_STRCMP
+#undef  __HAVE_ARCH_STRCPY
+#undef  __HAVE_ARCH_STRLEN
+#undef  __HAVE_ARCH_STRNCPY
+#else
+#define __HAVE_ARCH_MEMCMP
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_STRCAT
+#define __HAVE_ARCH_STRCMP
+#define __HAVE_ARCH_STRCPY
+#define __HAVE_ARCH_STRLEN
+#define __HAVE_ARCH_STRNCPY
+#endif
+
+#ifndef __HAVE_ARCH_STRNICMP
+/**
+ * strnicmp - Case insensitive, length-limited string comparison
+ * @s1: One string
+ * @s2: The other string
+ * @len: the maximum number of characters to compare
+ */
+int strnicmp(const char *s1, const char *s2, size_t len)
+{
+	/* Yes, Virginia, it had better be unsigned */
+	unsigned char c1, c2;
+
+	c1 = 0;	c2 = 0;
+	if (len) {
+		do {
+			c1 = *s1; c2 = *s2;
+			s1++; s2++;
+			if (!c1)
+				break;
+			if (!c2)
+				break;
+			if (c1 == c2)
+				continue;
+			c1 = tolower(c1);
+			c2 = tolower(c2);
+			if (c1 != c2)
+				break;
+		} while (--len);
+	}
+	return (int)c1 - (int)c2;
+}
+#endif
+
+char * ___strtok;
+
+#ifndef __HAVE_ARCH_STRCPY
+/**
+ * strcpy - Copy a %NUL terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ */
+char * strcpy(char * dest,const char *src)
+{
+	char *tmp = dest;
+
+	while ((*dest++ = *src++) != '\0')
+		/* nothing */;
+	return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCPY
+/**
+ * strncpy - Copy a length-limited, %NUL-terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @count: The maximum number of bytes to copy
+ *
+ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
+ * However, the result is not %NUL-terminated if the source exceeds
+ * @count bytes.
+ */
+char * strncpy(char * dest,const char *src,size_t count)
+{
+	char *tmp = dest;
+
+	while (count-- && (*dest++ = *src++) != '\0')
+		/* nothing */;
+
+	return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCAT
+/**
+ * strcat - Append one %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ */
+char * strcat(char * dest, const char * src)
+{
+	char *tmp = dest;
+
+	while (*dest)
+		dest++;
+	while ((*dest++ = *src++) != '\0')
+		;
+
+	return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCAT
+/**
+ * strncat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The maximum numbers of bytes to copy
+ *
+ * Note that in contrast to strncpy, strncat ensures the result is
+ * terminated.
+ */
+char * strncat(char *dest, const char *src, size_t count)
+{
+	char *tmp = dest;
+
+	if (count) {
+		while (*dest)
+			dest++;
+		while ((*dest++ = *src++)) {
+			if (--count == 0) {
+				*dest = '\0';
+				break;
+			}
+		}
+	}
+
+	return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCMP
+/**
+ * strcmp - Compare two strings
+ * @cs: One string
+ * @ct: Another string
+ */
+int strcmp(const char * cs,const char * ct)
+{
+	register signed char __res;
+
+	while (1) {
+		if ((__res = *cs - *ct++) != 0 || !*cs++)
+			break;
+	}
+
+	return __res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCMP
+/**
+ * strncmp - Compare two length-limited strings
+ * @cs: One string
+ * @ct: Another string
+ * @count: The maximum number of bytes to compare
+ */
+int strncmp(const char * cs,const char * ct,size_t count)
+{
+	register signed char __res = 0;
+
+	while (count) {
+		if ((__res = *cs - *ct++) != 0 || !*cs++)
+			break;
+		count--;
+	}
+
+	return __res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCHR
+/**
+ * strchr - Find the first occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strchr(const char * s, int c)
+{
+	for(; *s != (char) c; ++s)
+		if (*s == '\0')
+			return NULL;
+	return (char *) s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRRCHR
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strrchr(const char * s, int c)
+{
+       const char *p = s + strlen(s);
+       do {
+           if (*p == (char)c)
+               return (char *)p;
+       } while (--p >= s);
+       return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRLEN
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char * s)
+{
+	const char *sc;
+
+	for (sc = s; *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNLEN
+/**
+ * strnlen - Find the length of a length-limited string
+ * @s: The string to be sized
+ * @count: The maximum number of bytes to search
+ */
+size_t strnlen(const char * s, size_t count)
+{
+	const char *sc;
+
+	for (sc = s; count-- && *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRDUP
+char * strdup(const char *s)
+{
+	char *new;
+
+	if ((s == NULL)	||
+	    ((new = malloc (strlen(s) + 1)) == NULL) ) {
+		return NULL;
+	}
+
+	strcpy (new, s);
+	return new;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSPN
+/**
+ * strspn - Calculate the length of the initial substring of @s which only
+ * 	contain letters in @accept
+ * @s: The string to be searched
+ * @accept: The string to search for
+ */
+size_t strspn(const char *s, const char *accept)
+{
+	const char *p;
+	const char *a;
+	size_t count = 0;
+
+	for (p = s; *p != '\0'; ++p) {
+		for (a = accept; *a != '\0'; ++a) {
+			if (*p == *a)
+				break;
+		}
+		if (*a == '\0')
+			return count;
+		++count;
+	}
+
+	return count;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRPBRK
+/**
+ * strpbrk - Find the first occurrence of a set of characters
+ * @cs: The string to be searched
+ * @ct: The characters to search for
+ */
+char * strpbrk(const char * cs,const char * ct)
+{
+	const char *sc1,*sc2;
+
+	for( sc1 = cs; *sc1 != '\0'; ++sc1) {
+		for( sc2 = ct; *sc2 != '\0'; ++sc2) {
+			if (*sc1 == *sc2)
+				return (char *) sc1;
+		}
+	}
+	return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRTOK
+/**
+ * strtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * WARNING: strtok is deprecated, use strsep instead.
+ */
+char * strtok(char * s,const char * ct)
+{
+	char *sbegin, *send;
+
+	sbegin  = s ? s : ___strtok;
+	if (!sbegin) {
+		return NULL;
+	}
+	sbegin += strspn(sbegin,ct);
+	if (*sbegin == '\0') {
+		___strtok = NULL;
+		return( NULL );
+	}
+	send = strpbrk( sbegin, ct);
+	if (send && *send != '\0')
+		*send++ = '\0';
+	___strtok = send;
+	return (sbegin);
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSEP
+/**
+ * strsep - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * strsep() updates @s to point after the token, ready for the next call.
+ *
+ * It returns empty tokens, too, behaving exactly like the libc function
+ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
+ * Same semantics, slimmer shape. ;)
+ */
+char * strsep(char **s, const char *ct)
+{
+	char *sbegin = *s, *end;
+
+	if (sbegin == NULL)
+		return NULL;
+
+	end = strpbrk(sbegin, ct);
+	if (end)
+		*end++ = '\0';
+	*s = end;
+
+	return sbegin;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMSET
+/**
+ * memset - Fill a region of memory with the given value
+ * @s: Pointer to the start of the area.
+ * @c: The byte to fill the area with
+ * @count: The size of the area.
+ *
+ * Do not use memset() to access IO space, use memset_io() instead.
+ */
+void * memset(void * s,int c,size_t count)
+{
+	char *xs = (char *) s;
+
+	while (count--)
+		*xs++ = c;
+
+	return s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_BCOPY
+/**
+ * bcopy - Copy one area of memory to another
+ * @src: Where to copy from
+ * @dest: Where to copy to
+ * @count: The size of the area.
+ *
+ * Note that this is the same as memcpy(), with the arguments reversed.
+ * memcpy() is the standard, bcopy() is a legacy BSD function.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+char * bcopy(const char * src, char * dest, int count)
+{
+	char *tmp = dest;
+
+	while (count--)
+		*tmp++ = *src++;
+
+	return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCPY
+/**
+ * memcpy - Copy one area of memory to another
+ * @dest: Where to copy to
+ * @src: Where to copy from
+ * @count: The size of the area.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+void * memcpy(void * dest,const void *src,size_t count)
+{
+	char *tmp = (char *) dest, *s = (char *) src;
+
+	while (count--)
+		*tmp++ = *s++;
+
+	return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMMOVE
+/**
+ * memmove - Copy one area of memory to another
+ * @dest: Where to copy to
+ * @src: Where to copy from
+ * @count: The size of the area.
+ *
+ * Unlike memcpy(), memmove() copes with overlapping areas.
+ */
+void * memmove(void * dest,const void *src,size_t count)
+{
+	char *tmp, *s;
+
+	if (dest <= src) {
+		tmp = (char *) dest;
+		s = (char *) src;
+		while (count--)
+			*tmp++ = *s++;
+		}
+	else {
+		tmp = (char *) dest + count;
+		s = (char *) src + count;
+		while (count--)
+			*--tmp = *--s;
+		}
+
+	return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCMP
+/**
+ * memcmp - Compare two areas of memory
+ * @cs: One area of memory
+ * @ct: Another area of memory
+ * @count: The size of the area.
+ */
+int memcmp(const void * cs,const void * ct,size_t count)
+{
+	const unsigned char *su1, *su2;
+	int res = 0;
+
+	for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+		if ((res = *su1 - *su2) != 0)
+			break;
+	return res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMSCAN
+/**
+ * memscan - Find a character in an area of memory.
+ * @addr: The memory area
+ * @c: The byte to search for
+ * @size: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or 1 byte past
+ * the area if @c is not found
+ */
+void * memscan(void * addr, int c, size_t size)
+{
+	unsigned char * p = (unsigned char *) addr;
+
+	while (size) {
+		if (*p == c)
+			return (void *) p;
+		p++;
+		size--;
+	}
+  	return (void *) p;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSTR
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char * strstr(const char * s1,const char * s2)
+{
+	int l1, l2;
+
+	l2 = strlen(s2);
+	if (!l2)
+		return (char *) s1;
+	l1 = strlen(s1);
+	while (l1 >= l2) {
+		l1--;
+		if (!memcmp(s1,s2,l2))
+			return (char *) s1;
+		s1++;
+	}
+	return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCHR
+/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+	const unsigned char *p = s;
+	while (n-- != 0) {
+        	if ((unsigned char)c == *p++) {
+			return (void *)(p-1);
+		}
+	}
+	return NULL;
+}
+
+#endif
diff --git a/net/eth.c b/net/eth.c
new file mode 100644
index 0000000..3b06440
--- /dev/null
+++ b/net/eth.c
@@ -0,0 +1,292 @@
+/*
+ * (C) Copyright 2001, 2002
+ * 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 <command.h>
+#include <net.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)
+
+#ifdef CFG_GT_6426x
+extern int gt6426x_eth_initialize(bd_t *bis);
+#endif
+
+extern int eepro100_initialize(bd_t*);
+extern int natsemi_initialize(bd_t*);
+extern int ns8382x_initialize(bd_t*);
+extern int dc21x4x_initialize(bd_t*);
+extern int pcnet_initialize(bd_t*);
+extern int fec_initialize(bd_t*);
+extern int scc_initialize(bd_t*);
+
+static struct eth_device *eth_devices, *eth_current;
+
+struct eth_device *eth_get_dev(void)
+{
+	return eth_current;
+}
+
+int eth_get_dev_index (void)
+{
+	struct eth_device *dev;
+	int num = 0;
+
+	if (!eth_devices) {
+		return (-1);
+	}
+
+	for (dev = eth_devices; dev; dev = dev->next) {
+		if (dev == eth_current)
+			break;
+		++num;
+	}
+
+	if (dev) {
+		return (num);
+	}
+
+	return (0);
+}
+
+int eth_register(struct eth_device* dev)
+{
+	struct eth_device *d;
+
+	if (!eth_devices) {
+		eth_current = eth_devices = dev;
+	} else {
+		for (d=eth_devices; d->next!=eth_devices; d=d->next);
+		d->next = dev;
+	}
+
+	dev->state = ETH_STATE_INIT;
+	dev->next  = eth_devices;
+
+	return 0;
+}
+
+int eth_initialize(bd_t *bis)
+{
+	unsigned char enetvar[32], env_enetaddr[6];
+	int i, eth_number = 0;
+	char *tmp, *end;
+
+	eth_devices = NULL;
+	eth_current = NULL;
+
+#ifdef CONFIG_EEPRO100
+	eepro100_initialize(bis);
+#endif
+#ifdef CONFIG_TULIP
+	dc21x4x_initialize(bis);
+#endif
+#ifdef CONFIG_PCNET
+	pcnet_initialize(bis);
+#endif
+#ifdef CFG_GT_6426x
+	gt6426x_eth_initialize(bis);
+#endif
+#ifdef CONFIG_NATSEMI
+	natsemi_initialize(bis);
+#endif
+#ifdef CONFIG_NS8382X
+	ns8382x_initialize(bis);
+#endif
+#ifdef SCC_ENET
+	scc_initialize(bis);
+#endif
+#ifdef FEC_ENET
+	fec_initialize(bis);
+#endif
+
+	if (!eth_devices) {
+		puts ("No ethernet found.\n");
+	} else {
+		struct eth_device *dev = eth_devices;
+		char *ethprime = getenv ("ethprime");
+
+		do {
+			if (eth_number)
+				puts (", ");
+
+			printf("%s", dev->name);
+
+			if (ethprime && strcmp (dev->name, ethprime) == 0) {
+				eth_current = dev;
+				puts (" [PRIME]");
+			}
+
+			sprintf(enetvar, eth_number ? "eth%daddr" : "ethaddr", eth_number);
+			tmp = getenv (enetvar);
+
+			for (i=0; i<6; i++) {
+				env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+				if (tmp)
+					tmp = (*end) ? end+1 : end;
+			}
+
+			if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
+				if (memcmp(dev->enetaddr, "\0\0\0\0\0\0", 6) &&
+				    memcmp(dev->enetaddr, env_enetaddr, 6))
+				{
+					printf("\nWarning: %s HW address don't match:\n", dev->name);
+					printf("Address in SROM is         "
+					       "%02X:%02X:%02X:%02X:%02X:%02X\n",
+					       dev->enetaddr[0], dev->enetaddr[1],
+					       dev->enetaddr[2], dev->enetaddr[3],
+					       dev->enetaddr[4], dev->enetaddr[5]);
+					printf("Address in environment is  "
+					       "%02X:%02X:%02X:%02X:%02X:%02X\n",
+					       env_enetaddr[0], env_enetaddr[1],
+					       env_enetaddr[2], env_enetaddr[3],
+					       env_enetaddr[4], env_enetaddr[5]);
+				}
+
+				memcpy(dev->enetaddr, env_enetaddr, 6);
+			}
+
+			eth_number++;
+			dev = dev->next;
+		} while(dev != eth_devices);
+
+		putc ('\n');
+	}
+
+	return eth_number;
+}
+
+void eth_set_enetaddr(int num, char *addr) {
+	struct eth_device *dev;
+	unsigned char enetaddr[6];
+	char *end;
+	int i;
+
+#ifdef DEBUG
+	printf("eth_set_enetaddr(num=%d, addr=%s)\n", num, addr);
+#endif
+	if (!eth_devices)
+		return;
+
+	for (i=0; i<6; i++) {
+		enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
+		if (addr)
+			addr = (*end) ? end+1 : end;
+	}
+
+	dev = eth_devices;
+	while(num-- > 0) {
+		dev = dev->next;
+
+		if (dev == eth_devices)
+			return;
+	}
+
+#ifdef DEBUG
+	printf("Setting new HW address on %s\n", dev->name);
+	printf("New Address is             "
+	       "%02X:%02X:%02X:%02X:%02X:%02X\n",
+	       dev->enetaddr[0], dev->enetaddr[1],
+	       dev->enetaddr[2], dev->enetaddr[3],
+	       dev->enetaddr[4], dev->enetaddr[5]);
+#endif
+
+	memcpy(dev->enetaddr, enetaddr, 6);
+}
+
+int eth_init(bd_t *bis)
+{
+	struct eth_device* old_current;
+
+	if (!eth_current)
+		return 0;
+
+	old_current = eth_current;
+	do {
+#ifdef DEBUG
+		printf("Trying %s\n", eth_current->name);
+#endif
+
+		if (eth_current->init(eth_current, bis)) {
+			eth_current->state = ETH_STATE_ACTIVE;
+
+			printf("%s configured\n", eth_current->name);
+			return 1;
+		}
+
+#ifdef DEBUG
+		puts ("FAIL\n");
+#endif
+
+		eth_try_another(0);
+	} while (old_current != eth_current);
+
+	return 0;
+}
+
+void eth_halt(void)
+{
+	if (!eth_current)
+		return;
+
+	eth_current->halt(eth_current);
+
+	eth_current->state = ETH_STATE_PASSIVE;
+}
+
+int eth_send(volatile void *packet, int length)
+{
+	if (!eth_current)
+		return -1;
+
+	return eth_current->send(eth_current, packet, length);
+}
+
+int eth_rx(void)
+{
+	if (!eth_current)
+		return -1;
+
+	return eth_current->recv(eth_current);
+}
+
+void eth_try_another(int first_restart)
+{
+	static struct eth_device *first_failed = NULL;
+
+	if (!eth_current)
+		return;
+
+	if (first_restart)
+	{
+		first_failed = eth_current;
+	}
+
+	eth_current = eth_current->next;
+
+	if (first_failed == eth_current)
+	{
+		NetRestartWrap = 1;
+	}
+}
+
+#endif
diff --git a/post/cache_8xx.S b/post/cache_8xx.S
new file mode 100644
index 0000000..4c1c295
--- /dev/null
+++ b/post/cache_8xx.S
@@ -0,0 +1,495 @@
+/*
+ *  Copyright (C) 2002 Wolfgang Denk <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 <config.h>
+
+#ifdef CONFIG_POST
+#if defined(CONFIG_MPC823) || \
+    defined(CONFIG_MPC850) || \
+    defined(CONFIG_MPC855) || \
+    defined(CONFIG_MPC860) || \
+    defined(CONFIG_MPC824X)
+
+#include <post.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+
+#if CONFIG_POST & CFG_POST_CACHE
+
+	.text
+
+cache_post_dinvalidate:
+	lis	r10, IDC_INVALL@h
+	mtspr	DC_CST, r10
+	blr
+
+cache_post_iinvalidate:
+	lis	r10, IDC_INVALL@h
+	mtspr	IC_CST, r10
+	isync
+	blr
+
+cache_post_ddisable:
+	lis	r10, IDC_DISABLE@h
+	mtspr	DC_CST, r10
+	blr
+
+cache_post_dwb:
+	lis	r10, IDC_ENABLE@h
+	mtspr	DC_CST, r10
+	lis	r10, DC_CFWT@h
+	mtspr	DC_CST, r10
+	blr
+
+cache_post_dwt:
+	lis	r10, IDC_ENABLE@h
+	mtspr	DC_CST, r10
+	lis	r10, DC_SFWT@h
+	mtspr	DC_CST, r10
+	blr
+
+cache_post_idisable:
+	lis	r10, IDC_DISABLE@h
+	mtspr	IC_CST, r10
+	isync
+	blr
+
+cache_post_ienable:
+	lis	r10, IDC_ENABLE@h
+	mtspr	IC_CST, r10
+	isync
+	blr
+
+cache_post_iunlock:
+	lis	r10, IDC_UNALL@h
+	mtspr	IC_CST, r10
+	isync
+	blr
+
+cache_post_ilock:
+	mtspr	IC_ADR, r3
+	lis	r10, IDC_LDLCK@h
+	mtspr	IC_CST, r10
+	isync
+	blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+	.global cache_post_test1
+cache_post_test1:
+	mflr	r0
+	stw	r0, 4(r1)
+
+	stwu	r3, -4(r1)
+	stwu	r4, -4(r1)
+
+	bl	cache_post_dwb
+	bl	cache_post_dinvalidate
+
+	/* Write the negative pattern to the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	li	r0, 0xff
+	lwz	r3, 4(r1)
+	subi	r3, r3, 1
+1:
+	stbu	r0, 1(r3)
+	bdnz	1b
+
+	/* Read the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	lwz	r4, 4(r1)
+	subi	r4, r4, 1
+	li	r3, 0
+1:
+	lbzu	r0, 1(r4)
+	cmpli	cr0, r0, 0xff
+	beq	2f
+	li	r3, -1
+	b	3f
+2:
+	bdnz	1b
+3:
+
+	bl	cache_post_ddisable
+	bl	cache_post_dinvalidate
+
+	addi	r1, r1, 8
+
+	lwz	r0, 4(r1)
+	mtlr	r0
+	blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * turn off the data cache
+ * write the negative pattern to the area
+ * turn on the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+	.global cache_post_test2
+cache_post_test2:
+	mflr	r0
+	stw	r0, 4(r1)
+
+	stwu	r3, -4(r1)
+	stwu	r4, -4(r1)
+
+	bl	cache_post_dwb
+	bl	cache_post_dinvalidate
+
+	/* Write the zero pattern to the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	li	r0, 0
+	lwz	r3, 4(r1)
+	subi	r3, r3, 1
+1:
+	stbu	r0, 1(r3)
+	bdnz	1b
+
+	bl	cache_post_ddisable
+
+	/* Write the negative pattern to the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	li	r0, 0xff
+	lwz	r3, 4(r1)
+	subi	r3, r3, 1
+1:
+	stbu	r0, 1(r3)
+	bdnz	1b
+
+	bl	cache_post_dwb
+
+	/* Read the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	lwz	r4, 4(r1)
+	subi	r4, r4, 1
+	li	r3, 0
+1:
+	lbzu	r0, 1(r4)
+	cmpli	cr0, r0, 0xff
+	beq	2f
+	li	r3, -1
+	b	3f
+2:
+	bdnz	1b
+3:
+
+	bl	cache_post_ddisable
+	bl	cache_post_dinvalidate
+
+	addi	r1, r1, 8
+
+	lwz	r0, 4(r1)
+	mtlr	r0
+	blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * flush the data cache
+ * write the negative pattern to the area
+ * turn off the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+	.global cache_post_test3
+cache_post_test3:
+	mflr	r0
+	stw	r0, 4(r1)
+
+	stwu	r3, -4(r1)
+	stwu	r4, -4(r1)
+
+	bl	cache_post_ddisable
+	bl	cache_post_dinvalidate
+
+	/* Write the zero pattern to the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	li	r0, 0
+	lwz	r3, 4(r1)
+	subi	r3, r3, 1
+1:
+	stbu	r0, 1(r3)
+	bdnz	1b
+
+	bl	cache_post_dwt
+	bl	cache_post_dinvalidate
+
+	/* Write the negative pattern to the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	li	r0, 0xff
+	lwz	r3, 4(r1)
+	subi	r3, r3, 1
+1:
+	stbu	r0, 1(r3)
+	bdnz	1b
+
+	bl	cache_post_ddisable
+	bl	cache_post_dinvalidate
+
+	/* Read the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	lwz	r4, 4(r1)
+	subi	r4, r4, 1
+	li	r3, 0
+1:
+	lbzu	r0, 1(r4)
+	cmpli	cr0, r0, 0xff
+	beq	2f
+	li	r3, -1
+	b	3f
+2:
+	bdnz	1b
+3:
+
+	addi	r1, r1, 8
+
+	lwz	r0, 4(r1)
+	mtlr	r0
+	blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * flush the data cache
+ * write the zero pattern to the area
+ * invalidate the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+	.global cache_post_test4
+cache_post_test4:
+	mflr	r0
+	stw	r0, 4(r1)
+
+	stwu	r3, -4(r1)
+	stwu	r4, -4(r1)
+
+	bl	cache_post_ddisable
+	bl	cache_post_dinvalidate
+
+	/* Write the negative pattern to the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	li	r0, 0xff
+	lwz	r3, 4(r1)
+	subi	r3, r3, 1
+1:
+	stbu	r0, 1(r3)
+	bdnz	1b
+
+	bl	cache_post_dwb
+	bl	cache_post_dinvalidate
+
+	/* Write the zero pattern to the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	li	r0, 0
+	lwz	r3, 4(r1)
+	subi	r3, r3, 1
+1:
+	stbu	r0, 1(r3)
+	bdnz	1b
+
+	bl	cache_post_ddisable
+	bl	cache_post_dinvalidate
+
+	/* Read the test area */
+	lwz	r0, 0(r1)
+	mtctr	r0
+	lwz	r4, 4(r1)
+	subi	r4, r4, 1
+	li	r3, 0
+1:
+	lbzu	r0, 1(r4)
+	cmpli	cr0, r0, 0xff
+	beq	2f
+	li	r3, -1
+	b	3f
+2:
+	bdnz	1b
+3:
+
+	addi	r1, r1, 8
+
+	lwz	r0, 4(r1)
+	mtlr	r0
+	blr
+
+cache_post_test5_1:
+	li	r3, 0
+cache_post_test5_2:
+	li	r3, -1
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+*/
+	.global cache_post_test5
+cache_post_test5:
+	mflr	r0
+	stw	r0, 4(r1)
+
+	bl	cache_post_ienable
+	bl	cache_post_iunlock
+	bl	cache_post_iinvalidate
+
+	/* Compute r9 = cache_post_test5_reloc */
+	bl	cache_post_test5_reloc
+cache_post_test5_reloc:
+	mflr	r9
+
+	/* Copy the test instruction to cache_post_test5_data */
+	lis	r3, (cache_post_test5_1 - cache_post_test5_reloc)@h
+	ori	r3, r3, (cache_post_test5_1 - cache_post_test5_reloc)@l
+	add	r3, r3, r9
+	lis	r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+	ori	r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+	add	r4, r4, r9
+	lwz	r0, 0(r3)
+	stw	r0, 0(r4)
+
+	bl	cache_post_iinvalidate
+
+	/* Lock the branch instruction */
+	lis	r3, (cache_post_test5_data - cache_post_test5_reloc)@h
+	ori	r3, r3, (cache_post_test5_data - cache_post_test5_reloc)@l
+	add	r3, r3, r9
+	bl	cache_post_ilock
+
+	/* Replace the test instruction */
+	lis	r3, (cache_post_test5_2 - cache_post_test5_reloc)@h
+	ori	r3, r3, (cache_post_test5_2 - cache_post_test5_reloc)@l
+	add	r3, r3, r9
+	lis	r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+	ori	r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+	add	r4, r4, r9
+	lwz	r0, 0(r3)
+	stw	r0, 0(r4)
+
+	bl	cache_post_iinvalidate
+
+	/* Execute to the test instruction */
+cache_post_test5_data:
+	nop
+
+	bl	cache_post_iunlock
+
+	lwz	r0, 4(r1)
+	mtlr	r0
+	blr
+
+cache_post_test6_1:
+	li	r3, -1
+cache_post_test6_2:
+	li	r3, 0
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+ */
+	.global cache_post_test6
+cache_post_test6:
+	mflr	r0
+	stw	r0, 4(r1)
+
+	bl	cache_post_ienable
+	bl	cache_post_iunlock
+	bl	cache_post_iinvalidate
+
+	/* Compute r9 = cache_post_test6_reloc */
+	bl	cache_post_test6_reloc
+cache_post_test6_reloc:
+	mflr	r9
+
+	/* Copy the test instruction to cache_post_test6_data */
+	lis	r3, (cache_post_test6_1 - cache_post_test6_reloc)@h
+	ori	r3, r3, (cache_post_test6_1 - cache_post_test6_reloc)@l
+	add	r3, r3, r9
+	lis	r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+	ori	r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+	add	r4, r4, r9
+	lwz	r0, 0(r3)
+	stw	r0, 0(r4)
+
+	bl	cache_post_iinvalidate
+
+	/* Replace the test instruction */
+	lis	r3, (cache_post_test6_2 - cache_post_test6_reloc)@h
+	ori	r3, r3, (cache_post_test6_2 - cache_post_test6_reloc)@l
+	add	r3, r3, r9
+	lis	r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+	ori	r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+	add	r4, r4, r9
+	lwz	r0, 0(r3)
+	stw	r0, 0(r4)
+
+	bl	cache_post_iinvalidate
+
+	/* Execute to the test instruction */
+cache_post_test6_data:
+	nop
+
+	lwz	r0, 4(r1)
+	mtlr	r0
+	blr
+
+#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 || MPC824X */
+#endif /* CONFIG_POST & CFG_POST_CACHE */
+#endif /* CONFIG_POST */
diff --git a/post/cpu.c b/post/cpu.c
new file mode 100644
index 0000000..6b8fc6e
--- /dev/null
+++ b/post/cpu.c
@@ -0,0 +1,132 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ *
+ * This test checks the arithmetic logic unit (ALU) of CPU.
+ * It tests independently various groups of instructions using
+ * run-time modification of the code to reduce the memory footprint.
+ * For more details refer to post/cpu/ *.c files.
+ */
+
+#ifdef CONFIG_POST
+
+#include <watchdog.h>
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern int cpu_post_test_cmp (void);
+extern int cpu_post_test_cmpi (void);
+extern int cpu_post_test_two (void);
+extern int cpu_post_test_twox (void);
+extern int cpu_post_test_three (void);
+extern int cpu_post_test_threex (void);
+extern int cpu_post_test_threei (void);
+extern int cpu_post_test_andi (void);
+extern int cpu_post_test_srawi (void);
+extern int cpu_post_test_rlwnm (void);
+extern int cpu_post_test_rlwinm (void);
+extern int cpu_post_test_rlwimi (void);
+extern int cpu_post_test_store (void);
+extern int cpu_post_test_load (void);
+extern int cpu_post_test_cr (void);
+extern int cpu_post_test_b (void);
+extern int cpu_post_test_multi (void);
+extern int cpu_post_test_string (void);
+extern int cpu_post_test_complex (void);
+
+ulong cpu_post_makecr (long v)
+{
+	ulong cr = 0;
+
+	if (v < 0)
+		cr |= 0x80000000;
+	if (v > 0)
+		cr |= 0x40000000;
+	if (v == 0)
+		cr |= 0x20000000;
+
+	return cr;
+}
+
+int cpu_post_test (int flags)
+{
+	int ic = icache_status ();
+	int ret = 0;
+
+	if (ic)
+		icache_disable ();
+
+	if (ret == 0)
+		ret = cpu_post_test_cmp ();
+	if (ret == 0)
+		ret = cpu_post_test_cmpi ();
+	if (ret == 0)
+		ret = cpu_post_test_two ();
+	if (ret == 0)
+		ret = cpu_post_test_twox ();
+	if (ret == 0)
+		ret = cpu_post_test_three ();
+	if (ret == 0)
+		ret = cpu_post_test_threex ();
+	if (ret == 0)
+		ret = cpu_post_test_threei ();
+	WATCHDOG_RESET();
+	if (ret == 0)
+		ret = cpu_post_test_andi ();
+	if (ret == 0)
+		ret = cpu_post_test_srawi ();
+	if (ret == 0)
+		ret = cpu_post_test_rlwnm ();
+	if (ret == 0)
+		ret = cpu_post_test_rlwinm ();
+	if (ret == 0)
+		ret = cpu_post_test_rlwimi ();
+	if (ret == 0)
+		ret = cpu_post_test_store ();
+	if (ret == 0)
+		ret = cpu_post_test_load ();
+	WATCHDOG_RESET();
+	if (ret == 0)
+		ret = cpu_post_test_cr ();
+	if (ret == 0)
+		ret = cpu_post_test_b ();
+	if (ret == 0)
+		ret = cpu_post_test_multi ();
+	if (ret == 0)
+		ret = cpu_post_test_string ();
+	if (ret == 0)
+		ret = cpu_post_test_complex ();
+
+	if (ic)
+		icache_enable ();
+
+	return ret;
+}
+
+#endif /* CONFIG_POST & CFG_POST_CPU */
+#endif /* CONFIG_POST */
diff --git a/post/cpu/b.c b/post/cpu/b.c
new file mode 100644
index 0000000..1ae22cc
--- /dev/null
+++ b/post/cpu/b.c
@@ -0,0 +1,197 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Branch instructions:		b, bl, bc
+ *
+ * The first 2 instructions (b, bl) are verified by jumping
+ * to a fixed address and checking whether control was transfered
+ * to that very point. For the bl instruction the value of the
+ * link register is checked as well (using mfspr).
+ * To verify the bc instruction various combinations of the BI/BO
+ * fields, the CTR and the condition register values are
+ * checked. The list of such combinations is pre-built and
+ * linked in U-Boot at build time.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+extern void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
+    ulong cr);
+
+static int cpu_post_test_bc (ulong cmd, ulong bo, ulong bi,
+    int pjump, int dec, int link, ulong pctr, ulong cr)
+{
+    int ret = 0;
+    ulong lr = 0;
+    ulong ctr = pctr;
+    ulong jump;
+
+    unsigned long code[] =
+    {
+	ASM_MTCR(6),
+	ASM_MFLR(6),
+	ASM_MTCTR(3),
+	ASM_MTLR(4),
+	ASM_LI(5, 1),
+	ASM_3O(cmd, bo, bi, 8),
+	ASM_LI(5, 0),
+	ASM_MFCTR(3),
+	ASM_MFLR(4),
+	ASM_MTLR(6),
+	ASM_BLR,
+    };
+
+    cpu_post_exec_31 (code, &ctr, &lr, &jump, cr);
+
+    if (ret == 0)
+	ret = pjump == jump ? 0 : -1;
+    if (ret == 0)
+    {
+	if (dec)
+	    ret = pctr == ctr + 1 ? 0 : -1;
+	else
+	    ret = pctr == ctr ? 0 : -1;
+    }
+    if (ret == 0)
+    {
+    	if (link)
+            ret = lr == (ulong) code + 24 ? 0 : -1;
+	else
+	    ret = lr == 0 ? 0 : -1;
+    }
+
+    return ret;
+}
+
+int cpu_post_test_b (void)
+{
+    int ret = 0;
+    unsigned int i;
+
+    if (ret == 0)
+    {
+    	ulong code[] =
+	{
+	   ASM_MFLR(4),
+	   ASM_MTLR(3),
+	   ASM_B(4),
+	   ASM_MFLR(3),
+	   ASM_MTLR(4),
+	   ASM_BLR,
+	};
+	ulong res;
+
+	cpu_post_exec_11 (code, &res, 0);
+
+	ret = res == 0 ? 0 : -1;
+
+    	if (ret != 0)
+    	{
+            post_log ("Error at b1 test !\n");
+    	}
+    }
+
+    if (ret == 0)
+    {
+    	ulong code[] =
+	{
+	   ASM_MFLR(4),
+	   ASM_MTLR(3),
+	   ASM_BL(4),
+	   ASM_MFLR(3),
+	   ASM_MTLR(4),
+	   ASM_BLR,
+	};
+	ulong res;
+
+	cpu_post_exec_11 (code, &res, 0);
+
+	ret = res == (ulong)code + 12 ? 0 : -1;
+
+    	if (ret != 0)
+    	{
+            post_log ("Error at b2 test !\n");
+    	}
+    }
+
+    if (ret == 0)
+    {
+        ulong cc, cd;
+	int cond;
+	ulong ctr;
+	int link;
+
+	i = 0;
+
+	for (cc = 0; cc < 4 && ret == 0; cc++)
+	{
+	    for (cd = 0; cd < 4 && ret == 0; cd++)
+	    {
+	        for (link = 0; link <= 1 && ret == 0; link++)
+		{
+		    for (cond = 0; cond <= 1 && ret == 0; cond++)
+		    {
+		        for (ctr = 1; ctr <= 2 && ret == 0; ctr++)
+			{
+			    int dec = cd < 2;
+			    int cr = cond ? 0x80000000 : 0x00000000;
+			    int jumpc = cc >= 2 ||
+			                (cc == 0 && !cond) ||
+    			    		(cc == 1 && cond);
+			    int jumpd = cd >= 2 ||
+			                (cd == 0 && ctr != 1) ||
+    			    		(cd == 1 && ctr == 1);
+			    int jump = jumpc && jumpd;
+
+			    ret = cpu_post_test_bc (link ? OP_BCL : OP_BC,
+			        (cc << 3) + (cd << 1), 0, jump, dec, link,
+				ctr, cr);
+
+		    	    if (ret != 0)
+		    	    {
+		                post_log ("Error at b3 test %d !\n", i);
+		            }
+
+			    i++;
+			}
+		    }
+		}
+	    }
+	}
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/cmp.c b/post/cpu/cmp.c
new file mode 100644
index 0000000..789a24c
--- /dev/null
+++ b/post/cpu/cmp.c
@@ -0,0 +1,133 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Integer compare instructions:	cmpw, cmplw
+ *
+ * To verify these instructions the test runs them with
+ * different combinations of operands, reads the condition
+ * register value and compares it with the expected one.
+ * The test contains a pre-built table
+ * containing the description of each test case: the instruction,
+ * the values of the operands, the condition field to save
+ * the result in and the expected result.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2);
+
+static struct cpu_post_cmp_s
+{
+    ulong cmd;
+    ulong op1;
+    ulong op2;
+    ulong cr;
+    ulong res;
+} cpu_post_cmp_table[] =
+{
+    {
+	OP_CMPW,
+	123,
+	123,
+	2,
+	0x02
+    },
+    {
+	OP_CMPW,
+	123,
+	133,
+	3,
+	0x08
+    },
+    {
+	OP_CMPW,
+	123,
+	-133,
+	4,
+	0x04
+    },
+    {
+	OP_CMPLW,
+	123,
+	123,
+	2,
+	0x02
+    },
+    {
+	OP_CMPLW,
+	123,
+	-133,
+	3,
+	0x08
+    },
+    {
+	OP_CMPLW,
+	123,
+	113,
+	4,
+	0x04
+    },
+};
+static unsigned int cpu_post_cmp_size =
+    sizeof (cpu_post_cmp_table) / sizeof (struct cpu_post_cmp_s);
+
+int cpu_post_test_cmp (void)
+{
+    int ret = 0;
+    unsigned int i;
+
+    for (i = 0; i < cpu_post_cmp_size && ret == 0; i++)
+    {
+	struct cpu_post_cmp_s *test = cpu_post_cmp_table + i;
+    	unsigned long code[] =
+	{
+	    ASM_2C(test->cmd, test->cr, 3, 4),
+	    ASM_MFCR(3),
+	    ASM_BLR
+	};
+	ulong res;
+
+	cpu_post_exec_12 (code, & res, test->op1, test->op2);
+
+	ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
+
+	if (ret != 0)
+	{
+	    post_log ("Error at cmp test %d !\n", i);
+	}
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/cmpi.c b/post/cpu/cmpi.c
new file mode 100644
index 0000000..e0c2aaf
--- /dev/null
+++ b/post/cpu/cmpi.c
@@ -0,0 +1,133 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Integer compare instructions:	cmpwi, cmplwi
+ *
+ * To verify these instructions the test runs them with
+ * different combinations of operands, reads the condition
+ * register value and compares it with the expected one.
+ * The test contains a pre-built table
+ * containing the description of each test case: the instruction,
+ * the values of the operands, the condition field to save
+ * the result in and the expected result.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+
+static struct cpu_post_cmpi_s
+{
+    ulong cmd;
+    ulong op1;
+    ushort op2;
+    ulong cr;
+    ulong res;
+} cpu_post_cmpi_table[] =
+{
+    {
+	OP_CMPWI,
+	123,
+	123,
+	2,
+	0x02
+    },
+    {
+	OP_CMPWI,
+	123,
+	133,
+	3,
+	0x08
+    },
+    {
+	OP_CMPWI,
+	123,
+	-133,
+	4,
+	0x04
+    },
+    {
+	OP_CMPLWI,
+	123,
+	123,
+	2,
+	0x02
+    },
+    {
+	OP_CMPLWI,
+	123,
+	-133,
+	3,
+	0x08
+    },
+    {
+	OP_CMPLWI,
+	123,
+	113,
+	4,
+	0x04
+    },
+};
+static unsigned int cpu_post_cmpi_size =
+    sizeof (cpu_post_cmpi_table) / sizeof (struct cpu_post_cmpi_s);
+
+int cpu_post_test_cmpi (void)
+{
+    int ret = 0;
+    unsigned int i;
+
+    for (i = 0; i < cpu_post_cmpi_size && ret == 0; i++)
+    {
+	struct cpu_post_cmpi_s *test = cpu_post_cmpi_table + i;
+    	unsigned long code[] =
+	{
+	    ASM_1IC(test->cmd, test->cr, 3, test->op2),
+	    ASM_MFCR(3),
+	    ASM_BLR
+	};
+	ulong res;
+
+	cpu_post_exec_11 (code, & res, test->op1);
+
+	ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
+
+	if (ret != 0)
+	{
+	    post_log ("Error at cmpi test %d !\n", i);
+	}
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/cr.c b/post/cpu/cr.c
new file mode 100644
index 0000000..8e38729
--- /dev/null
+++ b/post/cpu/cr.c
@@ -0,0 +1,356 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Condition register istructions:	mtcr, mfcr, mcrxr,
+ *					crand, crandc, cror, crorc, crxor,
+ *					crnand, crnor, creqv, mcrf
+ *
+ * The mtcrf/mfcr instructions is tested by loading different
+ * values into the condition register (mtcrf), moving its value
+ * to a general-purpose register (mfcr) and comparing this value
+ * with the expected one.
+ * The mcrxr instruction is tested by loading a fixed value
+ * into the XER register (mtspr), moving XER value to the
+ * condition register (mcrxr), moving it to a general-purpose
+ * register (mfcr) and comparing the value of this register with
+ * the expected one.
+ * The rest of instructions is tested by loading a fixed
+ * value into the condition register (mtcrf), executing each
+ * instruction several times to modify all 4-bit condition
+ * fields, moving the value of the conditional register to a
+ * general-purpose register (mfcr) and comparing it with the
+ * expected one.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
+
+static ulong cpu_post_cr_table1[] =
+{
+    0xaaaaaaaa,
+    0x55555555,
+};
+static unsigned int cpu_post_cr_size1 =
+    sizeof (cpu_post_cr_table1) / sizeof (ulong);
+
+static struct cpu_post_cr_s2 {
+    ulong xer;
+    ulong cr;
+} cpu_post_cr_table2[] =
+{
+    {
+    	0xa0000000,
+	1
+    },
+    {
+    	0x40000000,
+	5
+    },
+};
+static unsigned int cpu_post_cr_size2 =
+    sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);
+
+static struct cpu_post_cr_s3 {
+    ulong cr;
+    ulong cs;
+    ulong cd;
+    ulong res;
+} cpu_post_cr_table3[] =
+{
+    {
+    	0x01234567,
+	0,
+	4,
+	0x01230567
+    },
+    {
+    	0x01234567,
+	7,
+	0,
+	0x71234567
+    },
+};
+static unsigned int cpu_post_cr_size3 =
+    sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);
+
+static struct cpu_post_cr_s4 {
+    ulong cmd;
+    ulong cr;
+    ulong op1;
+    ulong op2;
+    ulong op3;
+    ulong res;
+} cpu_post_cr_table4[] =
+{
+    {
+	OP_CRAND,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x0000ffff
+    },
+    {
+	OP_CRAND,
+    	0x0000ffff,
+	16,
+	17,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CRANDC,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x0000ffff
+    },
+    {
+	OP_CRANDC,
+    	0x0000ffff,
+	16,
+	0,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CROR,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CROR,
+    	0x0000ffff,
+	0,
+	1,
+	0,
+    	0x0000ffff
+    },
+    {
+	OP_CRORC,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x0000ffff
+    },
+    {
+	OP_CRORC,
+    	0x0000ffff,
+	0,
+	0,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CRXOR,
+    	0x0000ffff,
+	0,
+	0,
+	0,
+    	0x0000ffff
+    },
+    {
+	OP_CRXOR,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CRNAND,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CRNAND,
+    	0x0000ffff,
+	16,
+	17,
+	0,
+    	0x0000ffff
+    },
+    {
+	OP_CRNOR,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x0000ffff
+    },
+    {
+	OP_CRNOR,
+    	0x0000ffff,
+	0,
+	1,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CREQV,
+    	0x0000ffff,
+	0,
+	0,
+	0,
+    	0x8000ffff
+    },
+    {
+	OP_CREQV,
+    	0x0000ffff,
+	0,
+	16,
+	0,
+    	0x0000ffff
+    },
+};
+static unsigned int cpu_post_cr_size4 =
+    sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);
+
+int cpu_post_test_cr (void)
+{
+    int ret = 0;
+    unsigned int i;
+    unsigned long cr_sav;
+
+    asm ( "mfcr %0" : "=r" (cr_sav) : );
+
+    for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
+    {
+	ulong cr = cpu_post_cr_table1[i];
+	ulong res;
+
+    	unsigned long code[] =
+	{
+	    ASM_MTCR(3),
+	    ASM_MFCR(3),
+	    ASM_BLR,
+	};
+
+	cpu_post_exec_11 (code, &res, cr);
+
+	ret = res == cr ? 0 : -1;
+
+    	if (ret != 0)
+    	{
+            post_log ("Error at cr1 test %d !\n", i);
+    	}
+    }
+
+    for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
+    {
+	struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
+	ulong res;
+	ulong xer;
+
+    	unsigned long code[] =
+	{
+	    ASM_MTXER(3),
+	    ASM_MCRXR(test->cr),
+	    ASM_MFCR(3),
+	    ASM_MFXER(4),
+	    ASM_BLR,
+	};
+
+	cpu_post_exec_21x (code, &res, &xer, test->xer);
+
+	ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
+	      0 : -1;
+
+    	if (ret != 0)
+    	{
+            post_log ("Error at cr2 test %d !\n", i);
+    	}
+    }
+
+    for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
+    {
+	struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
+	ulong res;
+
+    	unsigned long code[] =
+	{
+	    ASM_MTCR(3),
+	    ASM_MCRF(test->cd, test->cs),
+	    ASM_MFCR(3),
+	    ASM_BLR,
+	};
+
+	cpu_post_exec_11 (code, &res, test->cr);
+
+	ret = res == test->res ? 0 : -1;
+
+    	if (ret != 0)
+    	{
+            post_log ("Error at cr3 test %d !\n", i);
+    	}
+    }
+
+    for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
+    {
+	struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
+	ulong res;
+
+    	unsigned long code[] =
+	{
+	    ASM_MTCR(3),
+	    ASM_12F(test->cmd, test->op3, test->op1, test->op2),
+	    ASM_MFCR(3),
+	    ASM_BLR,
+	};
+
+	cpu_post_exec_11 (code, &res, test->cr);
+
+	ret = res == test->res ? 0 : -1;
+
+    	if (ret != 0)
+    	{
+            post_log ("Error at cr4 test %d !\n", i);
+    	}
+    }
+
+    asm ( "mtcr %0" : : "r" (cr_sav));
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/three.c b/post/cpu/three.c
new file mode 100644
index 0000000..c2d7476
--- /dev/null
+++ b/post/cpu/three.c
@@ -0,0 +1,259 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Ternary instructions		instr rD,rA,rB
+ *
+ * Arithmetic instructions:	add, addc, adde, subf, subfc, subfe,
+ *				mullw, mulhw, mulhwu, divw, divwu
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+    ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_three_s
+{
+    ulong cmd;
+    ulong op1;
+    ulong op2;
+    ulong res;
+} cpu_post_three_table[] =
+{
+    {
+    	OP_ADD,
+	100,
+	200,
+	300
+    },
+    {
+    	OP_ADD,
+	100,
+	-200,
+	-100
+    },
+    {
+    	OP_ADDC,
+	100,
+	200,
+	300
+    },
+    {
+    	OP_ADDC,
+	100,
+	-200,
+	-100
+    },
+    {
+    	OP_ADDE,
+	100,
+	200,
+	300
+    },
+    {
+    	OP_ADDE,
+	100,
+	-200,
+	-100
+    },
+    {
+    	OP_SUBF,
+	100,
+	200,
+	100
+    },
+    {
+    	OP_SUBF,
+	300,
+	200,
+	-100
+    },
+    {
+    	OP_SUBFC,
+	100,
+	200,
+	100
+    },
+    {
+    	OP_SUBFC,
+	300,
+	200,
+	-100
+    },
+    {
+    	OP_SUBFE,
+	100,
+	200,
+	200 + ~100
+    },
+    {
+    	OP_SUBFE,
+	300,
+	200,
+	200 + ~300
+    },
+    {
+    	OP_MULLW,
+	200,
+	300,
+	200 * 300
+    },
+    {
+    	OP_MULHW,
+	0x10000000,
+	0x10000000,
+	0x1000000
+    },
+    {
+    	OP_MULHWU,
+	0x80000000,
+	0x80000000,
+	0x40000000
+    },
+    {
+    	OP_DIVW,
+	-20,
+	5,
+	-4
+    },
+    {
+    	OP_DIVWU,
+	0x8000,
+	0x200,
+	0x40
+    },
+};
+static unsigned int cpu_post_three_size =
+    sizeof (cpu_post_three_table) / sizeof (struct cpu_post_three_s);
+
+int cpu_post_test_three (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_three_size && ret == 0; i++)
+    {
+	struct cpu_post_three_s *test = cpu_post_three_table + i;
+
+	for (reg = 0; reg < 32 && ret == 0; reg++)
+	{
+	    unsigned int reg0 = (reg + 0) % 32;
+	    unsigned int reg1 = (reg + 1) % 32;
+	    unsigned int reg2 = (reg + 2) % 32;
+	    unsigned int stk = reg < 16 ? 31 : 15;
+    	    unsigned long code[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -24),
+		ASM_STW(3, stk, 12),
+		ASM_STW(4, stk, 16),
+		ASM_STW(reg0, stk, 8),
+		ASM_STW(reg1, stk, 4),
+		ASM_STW(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 12),
+		ASM_LWZ(reg0, stk, 16),
+		ASM_12(test->cmd, reg2, reg1, reg0),
+		ASM_STW(reg2, stk, 12),
+		ASM_LWZ(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 4),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_LWZ(3, stk, 12),
+		ASM_ADDI(1, stk, 24),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+    	    unsigned long codecr[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -24),
+		ASM_STW(3, stk, 12),
+		ASM_STW(4, stk, 16),
+		ASM_STW(reg0, stk, 8),
+		ASM_STW(reg1, stk, 4),
+		ASM_STW(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 12),
+		ASM_LWZ(reg0, stk, 16),
+		ASM_12(test->cmd, reg2, reg1, reg0) | BIT_C,
+		ASM_STW(reg2, stk, 12),
+		ASM_LWZ(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 4),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_LWZ(3, stk, 12),
+		ASM_ADDI(1, stk, 24),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+	    ulong res;
+	    ulong cr;
+
+	    if (ret == 0)
+	    {
+ 	    	cr = 0;
+	    	cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
+
+	    	ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at three test %d !\n", i);
+	    	}
+	    }
+
+	    if (ret == 0)
+	    {
+	    	cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
+
+	    	ret = res == test->res &&
+		      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at three test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/threei.c b/post/cpu/threei.c
new file mode 100644
index 0000000..79f0178
--- /dev/null
+++ b/post/cpu/threei.c
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Ternary instructions		instr rA,rS,UIMM
+ *
+ * Logic instructions:		ori, oris, xori, xoris
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_threei_s
+{
+    ulong cmd;
+    ulong op1;
+    ushort op2;
+    ulong res;
+} cpu_post_threei_table[] =
+{
+    {
+    	OP_ORI,
+	0x80000000,
+	0xffff,
+	0x8000ffff
+    },
+    {
+    	OP_ORIS,
+	0x00008000,
+	0xffff,
+	0xffff8000
+    },
+    {
+    	OP_XORI,
+	0x8000ffff,
+	0xffff,
+	0x80000000
+    },
+    {
+    	OP_XORIS,
+	0x00008000,
+	0xffff,
+	0xffff8000
+    },
+};
+static unsigned int cpu_post_threei_size =
+    sizeof (cpu_post_threei_table) / sizeof (struct cpu_post_threei_s);
+
+int cpu_post_test_threei (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_threei_size && ret == 0; i++)
+    {
+	struct cpu_post_threei_s *test = cpu_post_threei_table + i;
+
+	for (reg = 0; reg < 32 && ret == 0; reg++)
+	{
+	    unsigned int reg0 = (reg + 0) % 32;
+	    unsigned int reg1 = (reg + 1) % 32;
+	    unsigned int stk = reg < 16 ? 31 : 15;
+    	    unsigned long code[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -16),
+		ASM_STW(3, stk, 8),
+		ASM_STW(reg0, stk, 4),
+		ASM_STW(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_11IX(test->cmd, reg1, reg0, test->op2),
+		ASM_STW(reg1, stk, 8),
+		ASM_LWZ(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 4),
+		ASM_LWZ(3, stk, 8),
+		ASM_ADDI(1, stk, 16),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+	    ulong res;
+	    ulong cr;
+
+ 	    cr = 0;
+	    cpu_post_exec_21 (code, & cr, & res, test->op1);
+
+	    ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    if (ret != 0)
+	    {
+	        post_log ("Error at threei test %d !\n", i);
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/threex.c b/post/cpu/threex.c
new file mode 100644
index 0000000..2c72063
--- /dev/null
+++ b/post/cpu/threex.c
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Ternary instructions		instr rA,rS,rB
+ *
+ * Logic instructions:		or, orc, xor, nand, nor, eqv
+ * Shift instructions:		slw, srw, sraw
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+    ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_threex_s
+{
+    ulong cmd;
+    ulong op1;
+    ulong op2;
+    ulong res;
+} cpu_post_threex_table[] =
+{
+    {
+    	OP_OR,
+	0x1234,
+	0x5678,
+	0x1234 | 0x5678
+    },
+    {
+    	OP_ORC,
+	0x1234,
+	0x5678,
+	0x1234 | ~0x5678
+    },
+    {
+    	OP_XOR,
+	0x1234,
+	0x5678,
+	0x1234 ^ 0x5678
+    },
+    {
+    	OP_NAND,
+	0x1234,
+	0x5678,
+	~(0x1234 & 0x5678)
+    },
+    {
+    	OP_NOR,
+	0x1234,
+	0x5678,
+	~(0x1234 | 0x5678)
+    },
+    {
+    	OP_EQV,
+	0x1234,
+	0x5678,
+	~(0x1234 ^ 0x5678)
+    },
+    {
+    	OP_SLW,
+	0x80,
+	16,
+	0x800000
+    },
+    {
+    	OP_SLW,
+	0x80,
+	32,
+	0
+    },
+    {
+    	OP_SRW,
+	0x800000,
+	16,
+	0x80
+    },
+    {
+    	OP_SRW,
+	0x800000,
+	32,
+	0
+    },
+    {
+    	OP_SRAW,
+	0x80000000,
+	3,
+	0xf0000000
+    },
+    {
+    	OP_SRAW,
+	0x8000,
+	3,
+	0x1000
+    },
+};
+static unsigned int cpu_post_threex_size =
+    sizeof (cpu_post_threex_table) / sizeof (struct cpu_post_threex_s);
+
+int cpu_post_test_threex (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_threex_size && ret == 0; i++)
+    {
+	struct cpu_post_threex_s *test = cpu_post_threex_table + i;
+
+	for (reg = 0; reg < 32 && ret == 0; reg++)
+	{
+	    unsigned int reg0 = (reg + 0) % 32;
+	    unsigned int reg1 = (reg + 1) % 32;
+	    unsigned int reg2 = (reg + 2) % 32;
+	    unsigned int stk = reg < 16 ? 31 : 15;
+    	    unsigned long code[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -24),
+		ASM_STW(3, stk, 12),
+		ASM_STW(4, stk, 16),
+		ASM_STW(reg0, stk, 8),
+		ASM_STW(reg1, stk, 4),
+		ASM_STW(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 12),
+		ASM_LWZ(reg0, stk, 16),
+		ASM_12X(test->cmd, reg2, reg1, reg0),
+		ASM_STW(reg2, stk, 12),
+		ASM_LWZ(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 4),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_LWZ(3, stk, 12),
+		ASM_ADDI(1, stk, 24),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+    	    unsigned long codecr[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -24),
+		ASM_STW(3, stk, 12),
+		ASM_STW(4, stk, 16),
+		ASM_STW(reg0, stk, 8),
+		ASM_STW(reg1, stk, 4),
+		ASM_STW(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 12),
+		ASM_LWZ(reg0, stk, 16),
+		ASM_12X(test->cmd, reg2, reg1, reg0) | BIT_C,
+		ASM_STW(reg2, stk, 12),
+		ASM_LWZ(reg2, stk, 0),
+		ASM_LWZ(reg1, stk, 4),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_LWZ(3, stk, 12),
+		ASM_ADDI(1, stk, 24),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+	    ulong res;
+	    ulong cr;
+
+	    if (ret == 0)
+	    {
+ 	    	cr = 0;
+	    	cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
+
+	    	ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at threex test %d !\n", i);
+	    	}
+	    }
+
+	    if (ret == 0)
+	    {
+	    	cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
+
+	    	ret = res == test->res &&
+		      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at threex test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/two.c b/post/cpu/two.c
new file mode 100644
index 0000000..6075714
--- /dev/null
+++ b/post/cpu/two.c
@@ -0,0 +1,176 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Binary instructions		instr rD,rA
+ *
+ * Logic instructions:		neg
+ * Arithmetic instructions:	addme, addze, subfme, subfze
+
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_two_s
+{
+    ulong cmd;
+    ulong op;
+    ulong res;
+} cpu_post_two_table[] =
+{
+    {
+    	OP_NEG,
+	3,
+	-3
+    },
+    {
+    	OP_NEG,
+	5,
+	-5
+    },
+    {
+        OP_ADDME,
+	6,
+	5
+    },
+    {
+        OP_ADDZE,
+	5,
+	5
+    },
+    {
+        OP_SUBFME,
+	6,
+	~6 - 1
+    },
+    {
+        OP_SUBFZE,
+	5,
+	~5
+    },
+};
+static unsigned int cpu_post_two_size =
+    sizeof (cpu_post_two_table) / sizeof (struct cpu_post_two_s);
+
+int cpu_post_test_two (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_two_size && ret == 0; i++)
+    {
+	struct cpu_post_two_s *test = cpu_post_two_table + i;
+
+	for (reg = 0; reg < 32 && ret == 0; reg++)
+	{
+	    unsigned int reg0 = (reg + 0) % 32;
+	    unsigned int reg1 = (reg + 1) % 32;
+	    unsigned int stk = reg < 16 ? 31 : 15;
+    	    unsigned long code[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -16),
+		ASM_STW(3, stk, 8),
+		ASM_STW(reg0, stk, 4),
+		ASM_STW(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_11(test->cmd, reg1, reg0),
+		ASM_STW(reg1, stk, 8),
+		ASM_LWZ(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 4),
+		ASM_LWZ(3, stk, 8),
+		ASM_ADDI(1, stk, 16),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+    	    unsigned long codecr[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -16),
+		ASM_STW(3, stk, 8),
+		ASM_STW(reg0, stk, 4),
+		ASM_STW(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_11(test->cmd, reg1, reg0) | BIT_C,
+		ASM_STW(reg1, stk, 8),
+		ASM_LWZ(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 4),
+		ASM_LWZ(3, stk, 8),
+		ASM_ADDI(1, stk, 16),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+	    ulong res;
+	    ulong cr;
+
+	    if (ret == 0)
+	    {
+ 	    	cr = 0;
+	    	cpu_post_exec_21 (code, & cr, & res, test->op);
+
+	    	ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at two test %d !\n", i);
+	    	}
+	    }
+
+	    if (ret == 0)
+	    {
+	    	cpu_post_exec_21 (codecr, & cr, & res, test->op);
+
+	    	ret = res == test->res &&
+		      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at two test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/cpu/twox.c b/post/cpu/twox.c
new file mode 100644
index 0000000..48d9954
--- /dev/null
+++ b/post/cpu/twox.c
@@ -0,0 +1,176 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * CPU test
+ * Binary instructions		instr rA,rS
+ *
+ * Logic instructions:		cntlzw
+ * Arithmetic instructions:	extsb, extsh
+
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_twox_s
+{
+    ulong cmd;
+    ulong op;
+    ulong res;
+} cpu_post_twox_table[] =
+{
+    {
+    	OP_EXTSB,
+	3,
+	3
+    },
+    {
+    	OP_EXTSB,
+	0xff,
+	-1
+    },
+    {
+    	OP_EXTSH,
+	3,
+	3
+    },
+    {
+    	OP_EXTSH,
+	0xff,
+	0xff
+    },
+    {
+    	OP_EXTSH,
+	0xffff,
+	-1
+    },
+    {
+    	OP_CNTLZW,
+	0x000fffff,
+	12
+    },
+};
+static unsigned int cpu_post_twox_size =
+    sizeof (cpu_post_twox_table) / sizeof (struct cpu_post_twox_s);
+
+int cpu_post_test_twox (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_twox_size && ret == 0; i++)
+    {
+	struct cpu_post_twox_s *test = cpu_post_twox_table + i;
+
+	for (reg = 0; reg < 32 && ret == 0; reg++)
+	{
+	    unsigned int reg0 = (reg + 0) % 32;
+	    unsigned int reg1 = (reg + 1) % 32;
+	    unsigned int stk = reg < 16 ? 31 : 15;
+    	    unsigned long code[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -16),
+		ASM_STW(3, stk, 8),
+		ASM_STW(reg0, stk, 4),
+		ASM_STW(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_11X(test->cmd, reg1, reg0),
+		ASM_STW(reg1, stk, 8),
+		ASM_LWZ(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 4),
+		ASM_LWZ(3, stk, 8),
+		ASM_ADDI(1, stk, 16),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+    	    unsigned long codecr[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -16),
+		ASM_STW(3, stk, 8),
+		ASM_STW(reg0, stk, 4),
+		ASM_STW(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 8),
+		ASM_11X(test->cmd, reg1, reg0) | BIT_C,
+		ASM_STW(reg1, stk, 8),
+		ASM_LWZ(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 4),
+		ASM_LWZ(3, stk, 8),
+		ASM_ADDI(1, stk, 16),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+	    ulong res;
+	    ulong cr;
+
+	    if (ret == 0)
+	    {
+ 	    	cr = 0;
+	    	cpu_post_exec_21 (code, & cr, & res, test->op);
+
+	    	ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at twox test %d !\n", i);
+	    	}
+	    }
+
+	    if (ret == 0)
+	    {
+	    	cpu_post_exec_21 (codecr, & cr, & res, test->op);
+
+	    	ret = res == test->res &&
+		      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at twox test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/ether.c b/post/ether.c
new file mode 100644
index 0000000..5b42ca7
--- /dev/null
+++ b/post/ether.c
@@ -0,0 +1,646 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/*
+ * Ethernet test
+ *
+ * The Serial Communication Controllers (SCC) listed in ctlr_list array below
+ * are tested in the loopback ethernet mode.
+ * The controllers are configured accordingly and several packets
+ * are transmitted. The configurable test parameters are:
+ *   MIN_PACKET_LENGTH - minimum size of packet to transmit
+ *   MAX_PACKET_LENGTH - maximum size of packet to transmit
+ *   TEST_NUM - number of tests
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if defined(CONFIG_8xx)
+#include <commproc.h>
+#elif defined(CONFIG_MPC8260)
+#include <asm/cpm_8260.h>
+#else
+#error "Apparently a bad configuration, please fix."
+#endif
+
+#include <command.h>
+#include <net.h>
+
+#if CONFIG_POST & CFG_POST_ETHER
+
+#define MIN_PACKET_LENGTH	64
+#define MAX_PACKET_LENGTH	256
+#define TEST_NUM		1
+
+#define CTLR_SCC 0
+
+extern void spi_init_f (void);
+extern void spi_init_r (void);
+
+/* The list of controllers to test */
+#if defined(CONFIG_MPC823)
+static int ctlr_list[][2] = { {CTLR_SCC, 1} };
+#else
+static int ctlr_list[][2] = { };
+#endif
+
+#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0]))
+
+static struct {
+	void (*init) (int index);
+	int (*send) (int index, volatile void *packet, int length);
+	int (*recv) (int index, void *packet, int length);
+} ctlr_proc[1];
+
+static char *ctlr_name[1] = { "SCC" };
+
+static int used_by_uart[1] = { -1 };
+static int used_by_ether[1] = { -1 };
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH  1520
+
+#define TX_BUF_CNT 2
+
+#define TOUT_LOOP 100
+
+static char txbuf[DBUF_LENGTH];
+
+static uint rxIdx;		/* index of the current RX buffer */
+static uint txIdx;		/* index of the current TX buffer */
+
+/*
+  * SCC Ethernet Tx and Rx buffer descriptors allocated at the
+  *  immr->udata_bd address on Dual-Port RAM
+  * Provide for Double Buffering
+  */
+
+typedef volatile struct CommonBufferDescriptor {
+	cbd_t rxbd[PKTBUFSRX];		/* Rx BD */
+	cbd_t txbd[TX_BUF_CNT];		/* Tx BD */
+} RTXBD;
+
+static RTXBD *rtx;
+
+  /*
+   * SCC callbacks
+   */
+
+static void scc_init (int scc_index)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	bd_t *bd = gd->bd;
+
+	static int proff[] =
+			{ PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
+	static unsigned int cpm_cr[] =
+			{ CPM_CR_CH_SCC1, CPM_CR_CH_SCC2, CPM_CR_CH_SCC3,
+CPM_CR_CH_SCC4 };
+
+	int i;
+	scc_enet_t *pram_ptr;
+
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+	immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
+			~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+#if defined(CONFIG_FADS)
+#if defined(CONFIG_MPC860T)
+	/* The FADS860T doesn't use the MODEM_EN or DATA_VOICE signals. */
+	*((uint *) BCSR4) &= ~BCSR4_ETHLOOP;
+	*((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL;
+	*((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#else
+	*((uint *) BCSR4) &= ~(BCSR4_ETHLOOP | BCSR4_MODEM_EN);
+	*((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL | BCSR4_DATA_VOICE;
+	*((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif
+#endif
+
+	pram_ptr = (scc_enet_t *) & (immr->im_cpm.cp_dparam[proff[scc_index]]);
+
+	rxIdx = 0;
+	txIdx = 0;
+
+#ifdef CFG_ALLOC_DPRAM
+	rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
+					 dpram_alloc_align (sizeof (RTXBD), 8));
+#else
+	rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_SCC_BASE);
+#endif
+
+#if 0
+
+#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
+	/* Configure port A pins for Txd and Rxd.
+	 */
+	immr->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+	immr->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
+	immr->im_ioport.iop_paodr &= ~PA_ENET_TXD;
+#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
+	/* Configure port B pins for Txd and Rxd.
+	 */
+	immr->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD);
+	immr->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
+	immr->im_cpm.cp_pbodr &= ~PB_ENET_TXD;
+#else
+#error Configuration Error: exactly ONE of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
+#endif
+
+#if defined(PC_ENET_LBK)
+	/* Configure port C pins to disable External Loopback
+	 */
+	immr->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
+	immr->im_ioport.iop_pcdir |= PC_ENET_LBK;
+	immr->im_ioport.iop_pcso &= ~PC_ENET_LBK;
+	immr->im_ioport.iop_pcdat &= ~PC_ENET_LBK;	/* Disable Loopback */
+#endif /* PC_ENET_LBK */
+
+	/* Configure port C pins to enable CLSN and RENA.
+	 */
+	immr->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	immr->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	immr->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+
+	/* Configure port A for TCLK and RCLK.
+	 */
+	immr->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+	immr->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+
+	/*
+	 * Configure Serial Interface clock routing -- see section 16.7.5.3
+	 * First, clear all SCC bits to zero, then set the ones we want.
+	 */
+
+	immr->im_cpm.cp_sicr &= ~SICR_ENET_MASK;
+	immr->im_cpm.cp_sicr |= SICR_ENET_CLKRT;
+#else
+	/*
+	 * SCC2 receive clock is BRG2
+	 * SCC2 transmit clock is BRG3
+	 */
+	immr->im_cpm.cp_brgc2 = 0x0001000C;
+	immr->im_cpm.cp_brgc3 = 0x0001000C;
+
+	immr->im_cpm.cp_sicr &= ~0x00003F00;
+	immr->im_cpm.cp_sicr |=  0x00000a00;
+#endif /* 0 */
+
+
+	/*
+	 * Initialize SDCR -- see section 16.9.23.7
+	 * SDMA configuration register
+	 */
+	immr->im_siu_conf.sc_sdcr = 0x01;
+
+
+	/*
+	 * Setup SCC Ethernet Parameter RAM
+	 */
+
+	pram_ptr->sen_genscc.scc_rfcr = 0x18;	/* Normal Operation and Mot byte ordering */
+	pram_ptr->sen_genscc.scc_tfcr = 0x18;	/* Mot byte ordering, Normal access */
+
+	pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH;	/* max. ET package len 1520 */
+
+	pram_ptr->sen_genscc.scc_rbase = (unsigned int) (&rtx->rxbd[0]);	/* Set RXBD tbl start at Dual Port */
+	pram_ptr->sen_genscc.scc_tbase = (unsigned int) (&rtx->txbd[0]);	/* Set TXBD tbl start at Dual Port */
+
+	/*
+	 * Setup Receiver Buffer Descriptors (13.14.24.18)
+	 * Settings:
+	 *     Empty, Wrap
+	 */
+
+	for (i = 0; i < PKTBUFSRX; i++) {
+		rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+		rtx->rxbd[i].cbd_datlen = 0;	/* Reset */
+		rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+	}
+
+	rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+	/*
+	 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+	 * Settings:
+	 *    Add PADs to Short FRAMES, Wrap, Last, Tx CRC
+	 */
+
+	for (i = 0; i < TX_BUF_CNT; i++) {
+		rtx->txbd[i].cbd_sc =
+				(BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+		rtx->txbd[i].cbd_datlen = 0;	/* Reset */
+		rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
+	}
+
+	rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+	/*
+	 * Enter Command:  Initialize Rx Params for SCC
+	 */
+
+	do {				/* Spin until ready to issue command    */
+		__asm__ ("eieio");
+	} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+	/* Issue command */
+	immr->im_cpm.cp_cpcr =
+			((CPM_CR_INIT_RX << 8) | (cpm_cr[scc_index] << 4) |
+			 CPM_CR_FLG);
+	do {				/* Spin until command processed     */
+		__asm__ ("eieio");
+	} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+	/*
+	 * Ethernet Specific Parameter RAM
+	 *     see table 13-16, pg. 660,
+	 *     pg. 681 (example with suggested settings)
+	 */
+
+	pram_ptr->sen_cpres = ~(0x0);	/* Preset CRC */
+	pram_ptr->sen_cmask = 0xdebb20e3;	/* Constant Mask for CRC */
+	pram_ptr->sen_crcec = 0x0;	/* Error Counter CRC (unused) */
+	pram_ptr->sen_alec = 0x0;	/* Alignment Error Counter (unused) */
+	pram_ptr->sen_disfc = 0x0;	/* Discard Frame Counter (unused) */
+	pram_ptr->sen_pads = 0x8888;	/* Short Frame PAD Characters */
+
+	pram_ptr->sen_retlim = 15;	/* Retry Limit Threshold */
+	pram_ptr->sen_maxflr = 1518;	/* MAX Frame Length Register */
+	pram_ptr->sen_minflr = 64;	/* MIN Frame Length Register */
+
+	pram_ptr->sen_maxd1 = DBUF_LENGTH;	/* MAX DMA1 Length Register */
+	pram_ptr->sen_maxd2 = DBUF_LENGTH;	/* MAX DMA2 Length Register */
+
+	pram_ptr->sen_gaddr1 = 0x0;	/* Group Address Filter 1 (unused) */
+	pram_ptr->sen_gaddr2 = 0x0;	/* Group Address Filter 2 (unused) */
+	pram_ptr->sen_gaddr3 = 0x0;	/* Group Address Filter 3 (unused) */
+	pram_ptr->sen_gaddr4 = 0x0;	/* Group Address Filter 4 (unused) */
+
+#define ea bd->bi_enetaddr
+	pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
+	pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
+	pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
+#undef ea
+
+	pram_ptr->sen_pper = 0x0;	/* Persistence (unused) */
+	pram_ptr->sen_iaddr1 = 0x0;	/* Individual Address Filter 1 (unused) */
+	pram_ptr->sen_iaddr2 = 0x0;	/* Individual Address Filter 2 (unused) */
+	pram_ptr->sen_iaddr3 = 0x0;	/* Individual Address Filter 3 (unused) */
+	pram_ptr->sen_iaddr4 = 0x0;	/* Individual Address Filter 4 (unused) */
+	pram_ptr->sen_taddrh = 0x0;	/* Tmp Address (MSB) (unused) */
+	pram_ptr->sen_taddrm = 0x0;	/* Tmp Address (unused) */
+	pram_ptr->sen_taddrl = 0x0;	/* Tmp Address (LSB) (unused) */
+
+	/*
+	 * Enter Command:  Initialize Tx Params for SCC
+	 */
+
+	do {				/* Spin until ready to issue command    */
+		__asm__ ("eieio");
+	} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+	/* Issue command */
+	immr->im_cpm.cp_cpcr =
+			((CPM_CR_INIT_TX << 8) | (cpm_cr[scc_index] << 4) |
+			 CPM_CR_FLG);
+	do {				/* Spin until command processed     */
+		__asm__ ("eieio");
+	} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+	/*
+	 * Mask all Events in SCCM - we use polling mode
+	 */
+	immr->im_cpm.cp_scc[scc_index].scc_sccm = 0;
+
+	/*
+	 * Clear Events in SCCE -- Clear bits by writing 1's
+	 */
+
+	immr->im_cpm.cp_scc[scc_index].scc_scce = ~(0x0);
+
+
+	/*
+	 * Initialize GSMR High 32-Bits
+	 * Settings:  Normal Mode
+	 */
+
+	immr->im_cpm.cp_scc[scc_index].scc_gsmrh = 0;
+
+	/*
+	 * Initialize GSMR Low 32-Bits, but do not Enable Transmit/Receive
+	 * Settings:
+	 *     TCI = Invert
+	 *     TPL =  48 bits
+	 *     TPP = Repeating 10's
+	 *     LOOP = Loopback
+	 *     MODE = Ethernet
+	 */
+
+	immr->im_cpm.cp_scc[scc_index].scc_gsmrl = (SCC_GSMRL_TCI |
+												SCC_GSMRL_TPL_48 |
+												SCC_GSMRL_TPP_10 |
+												SCC_GSMRL_DIAG_LOOP |
+												SCC_GSMRL_MODE_ENET);
+
+	/*
+	 * Initialize the DSR -- see section 13.14.4 (pg. 513) v0.4
+	 */
+
+	immr->im_cpm.cp_scc[scc_index].scc_dsr = 0xd555;
+
+	/*
+	 * Initialize the PSMR
+	 * Settings:
+	 *  CRC = 32-Bit CCITT
+	 *  NIB = Begin searching for SFD 22 bits after RENA
+	 *  LPB = Loopback Enable (Needed when FDE is set)
+	 */
+	immr->im_cpm.cp_scc[scc_index].scc_psmr = SCC_PSMR_ENCRC |
+			SCC_PSMR_NIB22 | SCC_PSMR_LPB;
+
+#if 0
+	/*
+	 * Configure Ethernet TENA Signal
+	 */
+
+#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA))
+	immr->im_ioport.iop_pcpar |= PC_ENET_TENA;
+	immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
+#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA))
+	immr->im_cpm.cp_pbpar |= PB_ENET_TENA;
+	immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
+#else
+#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined
+#endif
+
+#if defined(CONFIG_ADS) && defined(CONFIG_MPC860)
+	/*
+	 * Port C is used to control the PHY,MC68160.
+	 */
+	immr->im_ioport.iop_pcdir |=
+			(PC_ENET_ETHLOOP | PC_ENET_TPFLDL | PC_ENET_TPSQEL);
+
+	immr->im_ioport.iop_pcdat |= PC_ENET_TPFLDL;
+	immr->im_ioport.iop_pcdat &= ~(PC_ENET_ETHLOOP | PC_ENET_TPSQEL);
+	*((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif /* MPC860ADS */
+
+#if defined(CONFIG_AMX860)
+	/*
+	 * Port B is used to control the PHY,MC68160.
+	 */
+	immr->im_cpm.cp_pbdir |=
+			(PB_ENET_ETHLOOP | PB_ENET_TPFLDL | PB_ENET_TPSQEL);
+
+	immr->im_cpm.cp_pbdat |= PB_ENET_TPFLDL;
+	immr->im_cpm.cp_pbdat &= ~(PB_ENET_ETHLOOP | PB_ENET_TPSQEL);
+
+	immr->im_ioport.iop_pddir |= PD_ENET_ETH_EN;
+	immr->im_ioport.iop_pddat &= ~PD_ENET_ETH_EN;
+#endif /* AMX860 */
+
+#endif /* 0 */
+
+#ifdef CONFIG_RPXCLASSIC
+	*((uchar *) BCSR0) &= ~BCSR0_ETHLPBK;
+	*((uchar *) BCSR0) |= (BCSR0_ETHEN | BCSR0_COLTEST | BCSR0_FULLDPLX);
+#endif
+
+#ifdef CONFIG_RPXLITE
+	*((uchar *) BCSR0) |= BCSR0_ETHEN;
+#endif
+
+#ifdef CONFIG_MBX
+	board_ether_init ();
+#endif
+
+	/*
+	 * Set the ENT/ENR bits in the GSMR Low -- Enable Transmit/Receive
+	 */
+
+	immr->im_cpm.cp_scc[scc_index].scc_gsmrl |=
+			(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	/*
+	 * Work around transmit problem with first eth packet
+	 */
+#if defined (CONFIG_FADS)
+	udelay (10000);				/* wait 10 ms */
+#elif defined (CONFIG_AMX860) || defined(CONFIG_RPXCLASSIC)
+	udelay (100000);			/* wait 100 ms */
+#endif
+}
+
+static int scc_send (int index, volatile void *packet, int length)
+{
+	int i, j = 0;
+
+	while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+		udelay (1);		/* will also trigger Wd if needed */
+		j++;
+	}
+	if (j >= TOUT_LOOP)
+		printf ("TX not ready\n");
+	rtx->txbd[txIdx].cbd_bufaddr = (uint) packet;
+	rtx->txbd[txIdx].cbd_datlen = length;
+	rtx->txbd[txIdx].cbd_sc |=
+			(BD_ENET_TX_READY | BD_ENET_TX_LAST | BD_ENET_TX_WRAP);
+	while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+		udelay (1);		/* will also trigger Wd if needed */
+		j++;
+	}
+	if (j >= TOUT_LOOP)
+		printf ("TX timeout\n");
+	i = (rtx->txbd[txIdx].
+		 cbd_sc & BD_ENET_TX_STATS) /* return only status bits */ ;
+	return i;
+}
+
+static int scc_recv (int index, void *packet, int max_length)
+{
+	int length = -1;
+
+	if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+		goto Done;		/* nothing received */
+	}
+
+	if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) {
+		length = rtx->rxbd[rxIdx].cbd_datlen - 4;
+		memcpy (packet,
+				(void *) (NetRxPackets[rxIdx]),
+				length < max_length ? length : max_length);
+	}
+
+	/* Give the buffer back to the SCC. */
+	rtx->rxbd[rxIdx].cbd_datlen = 0;
+
+	/* wrap around buffer index when necessary */
+	if ((rxIdx + 1) >= PKTBUFSRX) {
+		rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
+				(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+		rxIdx = 0;
+	} else {
+		rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+		rxIdx++;
+	}
+
+  Done:
+	return length;
+}
+
+  /*
+   * Test routines
+   */
+
+static void packet_fill (char *packet, int length)
+{
+	char c = (char) length;
+	int i;
+
+	packet[0] = 0xFF;
+	packet[1] = 0xFF;
+	packet[2] = 0xFF;
+	packet[3] = 0xFF;
+	packet[4] = 0xFF;
+	packet[5] = 0xFF;
+
+	for (i = 6; i < length; i++) {
+		packet[i] = c++;
+	}
+}
+
+static int packet_check (char *packet, int length)
+{
+	char c = (char) length;
+	int i;
+
+	for (i = 6; i < length; i++) {
+		if (packet[i] != c++)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int test_ctlr (int ctlr, int index)
+{
+	int res = -1;
+	char packet_send[MAX_PACKET_LENGTH];
+	char packet_recv[MAX_PACKET_LENGTH];
+	int length;
+	int i;
+	int l;
+
+	ctlr_proc[ctlr].init (index);
+
+	for (i = 0; i < TEST_NUM; i++) {
+		for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) {
+			packet_fill (packet_send, l);
+
+			ctlr_proc[ctlr].send (index, packet_send, l);
+
+			length = ctlr_proc[ctlr].recv (index, packet_recv,
+							MAX_PACKET_LENGTH);
+
+			if (length != l || packet_check (packet_recv, length) < 0) {
+				goto Done;
+			}
+		}
+	}
+
+	res = 0;
+
+  Done:
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+	if (used_by_uart[ctlr] == index) {
+		serial_init ();
+	}
+#endif
+
+#if defined(SCC_ENET)
+	if (used_by_ether[ctlr] == index) {
+		DECLARE_GLOBAL_DATA_PTR;
+
+		eth_init (gd->bd);
+	}
+#endif
+
+	/*
+	 * SCC2 Ethernet parameter RAM space overlaps
+	 * the SPI parameter RAM space. So we need to restore
+	 * the SPI configuration after SCC2 ethernet test.
+	 */
+#if defined(CONFIG_SPI)
+	if (ctlr == CTLR_SCC && index == 1) {
+		spi_init_f ();
+		spi_init_r ();
+	}
+#endif
+
+	if (res != 0) {
+		post_log ("ethernet %s%d test failed\n", ctlr_name[ctlr],
+				  index + 1);
+	}
+
+	return res;
+}
+
+int ether_post_test (int flags)
+{
+	int res = 0;
+	int i;
+
+#if defined(CONFIG_8xx_CONS_SCC1)
+	used_by_uart[CTLR_SCC] = 0;
+#elif defined(CONFIG_8xx_CONS_SCC2)
+	used_by_uart[CTLR_SCC] = 1;
+#elif defined(CONFIG_8xx_CONS_SCC3)
+	used_by_uart[CTLR_SCC] = 2;
+#elif defined(CONFIG_8xx_CONS_SCC4)
+	used_by_uart[CTLR_SCC] = 3;
+#endif
+
+#if defined(SCC_ENET)
+	used_by_ether[CTLR_SCC] = SCC_ENET;
+#endif
+
+	ctlr_proc[CTLR_SCC].init = scc_init;
+	ctlr_proc[CTLR_SCC].send = scc_send;
+	ctlr_proc[CTLR_SCC].recv = scc_recv;
+
+	for (i = 0; i < CTRL_LIST_SIZE; i++) {
+		if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
+			res = -1;
+		}
+	}
+
+	return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_ETHER */
+
+#endif /* CONFIG_POST */
diff --git a/post/memory.c b/post/memory.c
new file mode 100644
index 0000000..7d55a6d
--- /dev/null
+++ b/post/memory.c
@@ -0,0 +1,481 @@
+/*
+ * (C) Copyright 2002
+ * 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>
+
+/* Memory test
+ *
+ * General observations:
+ * o The recommended test sequence is to test the data lines: if they are
+ *   broken, nothing else will work properly.  Then test the address
+ *   lines.  Finally, test the cells in the memory now that the test
+ *   program knows that the address and data lines work properly.
+ *   This sequence also helps isolate and identify what is faulty.
+ *
+ * o For the address line test, it is a good idea to use the base
+ *   address of the lowest memory location, which causes a '1' bit to
+ *   walk through a field of zeros on the address lines and the highest
+ *   memory location, which causes a '0' bit to walk through a field of
+ *   '1's on the address line.
+ *
+ * o Floating buses can fool memory tests if the test routine writes
+ *   a value and then reads it back immediately.  The problem is, the
+ *   write will charge the residual capacitance on the data bus so the
+ *   bus retains its state briefely.  When the test program reads the
+ *   value back immediately, the capacitance of the bus can allow it
+ *   to read back what was written, even though the memory circuitry
+ *   is broken.  To avoid this, the test program should write a test
+ *   pattern to the target location, write a different pattern elsewhere
+ *   to charge the residual capacitance in a differnt manner, then read
+ *   the target location back.
+ *
+ * o Always read the target location EXACTLY ONCE and save it in a local
+ *   variable.  The problem with reading the target location more than
+ *   once is that the second and subsequent reads may work properly,
+ *   resulting in a failed test that tells the poor technician that
+ *   "Memory error at 00000000, wrote aaaaaaaa, read aaaaaaaa" which
+ *   doesn't help him one bit and causes puzzled phone calls.  Been there,
+ *   done that.
+ *
+ * Data line test:
+ * ---------------
+ * This tests data lines for shorts and opens by forcing adjacent data
+ * to opposite states. Because the data lines could be routed in an
+ * arbitrary manner the must ensure test patterns ensure that every case
+ * is tested. By using the following series of binary patterns every
+ * combination of adjacent bits is test regardless of routing.
+ *
+ *     ...101010101010101010101010
+ *     ...110011001100110011001100
+ *     ...111100001111000011110000
+ *     ...111111110000000011111111
+ *
+ * Carrying this out, gives us six hex patterns as follows:
+ *
+ *     0xaaaaaaaaaaaaaaaa
+ *     0xcccccccccccccccc
+ *     0xf0f0f0f0f0f0f0f0
+ *     0xff00ff00ff00ff00
+ *     0xffff0000ffff0000
+ *     0xffffffff00000000
+ *
+ * To test for short and opens to other signals on our boards, we
+ * simply test with the 1's complemnt of the paterns as well, resulting
+ * in twelve patterns total.
+ *
+ * After writing a test pattern. a special pattern 0x0123456789ABCDEF is
+ * written to a different address in case the data lines are floating.
+ * Thus, if a byte lane fails, you will see part of the special
+ * pattern in that byte lane when the test runs.  For example, if the
+ * xx__xxxxxxxxxxxx byte line fails, you will see aa23aaaaaaaaaaaa
+ * (for the 'a' test pattern).
+ *
+ * Address line test:
+ * ------------------
+ *  This function performs a test to verify that all the address lines
+ *  hooked up to the RAM work properly.  If there is an address line
+ *  fault, it usually shows up as two different locations in the address
+ *  map (related by the faulty address line) mapping to one physical
+ *  memory storage location.  The artifact that shows up is writing to
+ *  the first location "changes" the second location.
+ *
+ * To test all address lines, we start with the given base address and
+ * xor the address with a '1' bit to flip one address line.  For each
+ * test, we shift the '1' bit left to test the next address line.
+ *
+ * In the actual code, we start with address sizeof(ulong) since our
+ * test pattern we use is a ulong and thus, if we tried to test lower
+ * order address bits, it wouldn't work because our pattern would
+ * overwrite itself.
+ *
+ * Example for a 4 bit address space with the base at 0000:
+ *   0000 <- base
+ *   0001 <- test 1
+ *   0010 <- test 2
+ *   0100 <- test 3
+ *   1000 <- test 4
+ * Example for a 4 bit address space with the base at 0010:
+ *   0010 <- base
+ *   0011 <- test 1
+ *   0000 <- (below the base address, skipped)
+ *   0110 <- test 2
+ *   1010 <- test 3
+ *
+ * The test locations are successively tested to make sure that they are
+ * not "mirrored" onto the base address due to a faulty address line.
+ * Note that the base and each test location are related by one address
+ * line flipped.  Note that the base address need not be all zeros.
+ *
+ * Memory tests 1-4:
+ * -----------------
+ * These tests verify RAM using sequential writes and reads
+ * to/from RAM. There are several test cases that use different patterns to
+ * verify RAM. Each test case fills a region of RAM with one pattern and
+ * then reads the region back and compares its contents with the pattern.
+ * The following patterns are used:
+ *
+ *  1a) zero pattern (0x00000000)
+ *  1b) negative pattern (0xffffffff)
+ *  1c) checkerboard pattern (0x55555555)
+ *  1d) checkerboard pattern (0xaaaaaaaa)
+ *  2)  bit-flip pattern ((1 << (offset % 32))
+ *  3)  address pattern (offset)
+ *  4)  address pattern (~offset)
+ *
+ * Being run in normal mode, the test verifies only small 4Kb
+ * regions of RAM around each 1Mb boundary. For example, for 64Mb
+ * RAM the following areas are verified: 0x00000000-0x00000800,
+ * 0x000ff800-0x00100800, 0x001ff800-0x00200800, ..., 0x03fff800-
+ * 0x04000000. If the test is run in power-fail mode, it verifies
+ * the whole RAM.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_MEMORY
+
+/*
+ * Define INJECT_*_ERRORS for testing error detection in the presence of
+ * _good_ hardware.
+ */
+#undef  INJECT_DATA_ERRORS
+#undef  INJECT_ADDRESS_ERRORS
+
+#ifdef INJECT_DATA_ERRORS
+#warning "Injecting data line errors for testing purposes"
+#endif
+
+#ifdef INJECT_ADDRESS_ERRORS
+#warning "Injecting address line errors for testing purposes"
+#endif
+
+
+/*
+ * This function performs a double word move from the data at
+ * the source pointer to the location at the destination pointer.
+ * This is helpful for testing memory on processors which have a 64 bit
+ * wide data bus.
+ *
+ * On those PowerPC with FPU, use assembly and a floating point move:
+ * this does a 64 bit move.
+ *
+ * For other processors, let the compiler generate the best code it can.
+ */
+static void move64(unsigned long long *src, unsigned long long *dest)
+{
+#if defined(CONFIG_MPC8260) || defined(CONFIG_MPC824X)
+	asm ("lfd  0, 0(3)\n\t" /* fpr0	  =  *scr	*/
+	 "stfd 0, 0(4)"		/* *dest  =  fpr0	*/
+	 : : : "fr0" );		/* Clobbers fr0		*/
+    return;
+#else
+	*dest = *src;
+#endif
+}
+
+/*
+ * This is 64 bit wide test patterns.  Note that they reside in ROM
+ * (which presumably works) and the tests write them to RAM which may
+ * not work.
+ *
+ * The "otherpattern" is written to drive the data bus to values other
+ * than the test pattern.  This is for detecting floating bus lines.
+ *
+ */
+const static unsigned long long pattern[] = {
+    0xaaaaaaaaaaaaaaaa,
+    0xcccccccccccccccc,
+    0xf0f0f0f0f0f0f0f0,
+    0xff00ff00ff00ff00,
+    0xffff0000ffff0000,
+    0xffffffff00000000,
+    0x00000000ffffffff,
+    0x0000ffff0000ffff,
+    0x00ff00ff00ff00ff,
+    0x0f0f0f0f0f0f0f0f,
+    0x3333333333333333,
+    0x5555555555555555};
+const unsigned long long otherpattern = 0x0123456789abcdef;
+
+
+static int memory_post_dataline(unsigned long long * pmem)
+{
+	unsigned long long temp64;
+	int num_patterns = sizeof(pattern)/ sizeof(pattern[0]);
+	int i;
+	unsigned int hi, lo, pathi, patlo;
+	int ret = 0;
+
+	for ( i = 0; i < num_patterns; i++) {
+		move64((unsigned long long *)&(pattern[i]), pmem++);
+		/*
+		 * Put a different pattern on the data lines: otherwise they
+		 * may float long enough to read back what we wrote.
+		 */
+		move64((unsigned long long *)&otherpattern, pmem--);
+		move64(pmem, &temp64);
+
+#ifdef INJECT_DATA_ERRORS
+		temp64 ^= 0x00008000;
+#endif
+
+		if (temp64 != pattern[i]){
+			pathi = (pattern[i]>>32) & 0xffffffff;
+			patlo = pattern[i] & 0xffffffff;
+
+			hi = (temp64>>32) & 0xffffffff;
+			lo = temp64 & 0xffffffff;
+
+			post_log ("Memory (date line) error at %08x, "
+				  "wrote %08x%08x, read %08x%08x !\n",
+					  pmem, pathi, patlo, hi, lo);
+			ret = -1;
+		}
+	}
+	return ret;
+}
+
+static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size)
+{
+	ulong *target;
+	ulong *end;
+	ulong readback;
+	ulong xor;
+	int   ret = 0;
+
+	end = base + size;
+	xor = 0;
+	for(xor = sizeof(ulong); xor > 0; xor <<= 1) {
+		target = (ulong *)((ulong)testaddr ^ xor);
+		if((target >= base) && (target < end)) {
+			*testaddr = ~*target;
+			readback  = *target;
+
+#ifdef INJECT_ADDRESS_ERRORS
+			if(xor == 0x00008000) {
+				readback = *testaddr;
+			}
+#endif
+			if(readback == *testaddr) {
+				post_log ("Memory (address line) error at %08x<->%08x, "
+				  	"XOR value %08x !\n",
+					testaddr, target, xor);
+				ret = -1;
+			}
+		}
+	}
+	return ret;
+}
+
+static int memory_post_test1 (unsigned long start,
+			      unsigned long size,
+			      unsigned long val)
+{
+	unsigned long i;
+	ulong *mem = (ulong *) start;
+	ulong readback;
+	int ret = 0;
+
+	for (i = 0; i < size / sizeof (ulong); i++) {
+		mem[i] = val;
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+		readback = mem[i];
+		if (readback != val) {
+			post_log ("Memory error at %08x, "
+				  "wrote %08x, read %08x !\n",
+					  mem + i, val, readback);
+
+			ret = -1;
+			break;
+		}
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	return ret;
+}
+
+static int memory_post_test2 (unsigned long start, unsigned long size)
+{
+	unsigned long i;
+	ulong *mem = (ulong *) start;
+	ulong readback;
+	int ret = 0;
+
+	for (i = 0; i < size / sizeof (ulong); i++) {
+		mem[i] = 1 << (i % 32);
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+		readback = mem[i];
+		if (readback != (1 << (i % 32))) {
+			post_log ("Memory error at %08x, "
+				  "wrote %08x, read %08x !\n",
+					  mem + i, 1 << (i % 32), readback);
+
+			ret = -1;
+			break;
+		}
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	return ret;
+}
+
+static int memory_post_test3 (unsigned long start, unsigned long size)
+{
+	unsigned long i;
+	ulong *mem = (ulong *) start;
+	ulong readback;
+	int ret = 0;
+
+	for (i = 0; i < size / sizeof (ulong); i++) {
+		mem[i] = i;
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+		readback = mem[i];
+		if (readback != i) {
+			post_log ("Memory error at %08x, "
+				  "wrote %08x, read %08x !\n",
+					  mem + i, i, readback);
+
+			ret = -1;
+			break;
+		}
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	return ret;
+}
+
+static int memory_post_test4 (unsigned long start, unsigned long size)
+{
+	unsigned long i;
+	ulong *mem = (ulong *) start;
+	ulong readback;
+	int ret = 0;
+
+	for (i = 0; i < size / sizeof (ulong); i++) {
+		mem[i] = ~i;
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+		readback = mem[i];
+		if (readback != ~i) {
+			post_log ("Memory error at %08x, "
+				  "wrote %08x, read %08x !\n",
+					  mem + i, ~i, readback);
+
+			ret = -1;
+			break;
+		}
+		if (i % 1024 == 0)
+			WATCHDOG_RESET ();
+	}
+
+	return ret;
+}
+
+static int memory_post_tests (unsigned long start, unsigned long size)
+{
+	int ret = 0;
+
+	if (ret == 0)
+		ret = memory_post_dataline ((long long *)start);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_addrline ((long *)start, (long *)start, size);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_addrline ((long *)(start + size - 8),
+					    (long *)start, size);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_test1 (start, size, 0x00000000);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_test1 (start, size, 0xffffffff);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_test1 (start, size, 0x55555555);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_test1 (start, size, 0xaaaaaaaa);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_test2 (start, size);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_test3 (start, size);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_test4 (start, size);
+	WATCHDOG_RESET ();
+
+	return ret;
+}
+
+int memory_post_test (int flags)
+{
+	int ret = 0;
+	DECLARE_GLOBAL_DATA_PTR;
+	bd_t *bd = gd->bd;
+	unsigned long memsize = (bd->bi_memsize >= 256 << 20 ?
+				 256 << 20 : bd->bi_memsize) - (1 << 20);
+
+
+	if (flags & POST_POWERFAIL) {
+		ret = memory_post_tests (CFG_SDRAM_BASE, memsize);
+	} else {			/* POST_POWERNORMAL */
+
+		unsigned long i;
+
+		for (i = 0; i < (memsize >> 20) && ret == 0; i++) {
+			if (ret == 0)
+				ret = memory_post_tests (i << 20, 0x800);
+			if (ret == 0)
+				ret = memory_post_tests ((i << 20) + 0xff800, 0x800);
+		}
+	}
+
+	return ret;
+}
+
+#endif /* CONFIG_POST & CFG_POST_MEMORY */
+#endif /* CONFIG_POST */
diff --git a/rtc/ds1556.c b/rtc/ds1556.c
new file mode 100644
index 0000000..dd9ea5e
--- /dev/null
+++ b/rtc/ds1556.c
@@ -0,0 +1,206 @@
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS1556:
+ * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for the DS1556 RTC
+ */
+
+/*#define	RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+
+#if defined(CONFIG_RTC_DS1556) && (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void  rtc_write( unsigned int addr, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_BASE		( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR		( RTC_BASE + 0xf )
+#define RTC_MONTH		( RTC_BASE + 0xe )
+#define RTC_DAY_OF_MONTH	( RTC_BASE + 0xd )
+#define RTC_DAY_OF_WEEK		( RTC_BASE + 0xc )
+#define RTC_HOURS		( RTC_BASE + 0xb )
+#define RTC_MINUTES		( RTC_BASE + 0xa )
+#define RTC_SECONDS		( RTC_BASE + 0x9 )
+#define RTC_CENTURY		( RTC_BASE + 0x8 )
+
+#define RTC_CONTROLA		RTC_CENTURY
+#define RTC_CONTROLB		RTC_SECONDS
+#define RTC_CONTROLC		RTC_BASE
+
+#define RTC_CA_WRITE		0x80
+#define RTC_CA_READ		0x40
+
+#define RTC_CB_OSC_DISABLE	0x80
+
+#define RTC_CC_BATTERY_FLAG	0x10
+#define RTC_CC_FREQ_TEST	0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+	uchar sec, min, hour;
+	uchar mday, wday, mon, year;
+
+	int century;
+
+	uchar reg_a;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	/* lock clock registers for read */
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+	sec     = rtc_read( RTC_SECONDS );
+	min     = rtc_read( RTC_MINUTES );
+	hour    = rtc_read( RTC_HOURS );
+	mday    = rtc_read( RTC_DAY_OF_MONTH );
+	wday    = rtc_read( RTC_DAY_OF_WEEK );
+	mon     = rtc_read( RTC_MONTH );
+	year    = rtc_read( RTC_YEAR );
+	century = rtc_read( RTC_CENTURY );
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %02x mon/cent: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, century, mon, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+	tmp->tm_min  = bcd2bin( min  & 0x7F );
+	tmp->tm_hour = bcd2bin( hour & 0x3F );
+	tmp->tm_mday = bcd2bin( mday & 0x3F );
+	tmp->tm_mon  = bcd2bin( mon & 0x1F );
+	tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+	/* glue year from century and year in century */
+	tmp->tm_year = bcd2bin( year ) +
+		( bcd2bin( century & 0x3F ) * 100 );
+
+	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 )
+{
+	uchar reg_a;
+#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
+	/* lock clock registers for write */
+	reg_a = rtc_read( RTC_CONTROLA );
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+	rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+	rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+	rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+	rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+	rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+	rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+	/* break year up into century and year in century */
+	rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+	rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+	uchar reg_a, reg_b, reg_c;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	reg_b = rtc_read( RTC_CONTROLB );
+
+	if ( reg_b & RTC_CB_OSC_DISABLE )
+	{
+		printf( "real-time-clock was stopped. Now starting...\n" );
+		reg_a |= RTC_CA_WRITE;
+		reg_b &= ~RTC_CB_OSC_DISABLE;
+
+		rtc_write( RTC_CONTROLA, reg_a );
+		rtc_write( RTC_CONTROLB, reg_b );
+	}
+
+	/* make sure read/write clock register bits are cleared */
+	reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+	rtc_write( RTC_CONTROLA, reg_a );
+
+	reg_c = rtc_read( RTC_CONTROLC );
+	if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+		printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+	uchar val = *(volatile unsigned char*)(addr);
+#ifdef RTC_DEBUG
+	printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+	return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+	printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+	*(volatile unsigned char*)(addr) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif	/* CONFIG_RTC_DS1556 && CFG_CMD_DATE */