Merge with /home/hs/jupiter/u-boot
diff --git a/CHANGELOG b/CHANGELOG
index ff386c9..6e26105 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,443 @@
+commit 638dd1458bbdc2a55d4b9e25c5c4e1f838a5dc72
+Author: Sergei Poselenov <sposelenov@emcraft.com>
+Date:	Tue Feb 27 12:40:16 2007 +0300
+
+    MCC200 update - add LCD Progress Indicator
+
+commit 6c7cac8c4fce0ea2bf8e15ed8658d87974155b44
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Feb 22 07:43:34 2007 +0100
+
+    [PATCH] get_dev() now unconditionally uses manual relocation
+
+    Since the relocation fix is not included yet and we're not sure how
+    it will be added, this patch removes code that required relocation
+    to be fixed for now.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 8274ec0bd01d2feb2c7f095eba78d42ea009798b
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Feb 22 07:40:23 2007 +0100
+
+    [PATCH] Change systemace driver to select 8 & 16bit mode
+
+    As suggested by Grant Likely this patch enables the Xilinx SystemACE
+    driver to select 8 or 16bit mode upon startup.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 3a197b2fe49d6fa03978e60af2394efe9c70b527
+Author: Haiying Wang <Haiying.Wang@freescale.com>
+Date:	Wed Feb 21 16:52:31 2007 +0100
+
+    [PATCH v3] Add sync to ensure flash_write_cmd is fully finished
+
+    Some CPUs like PPC, BLACKFIN need sync() to ensure cfi flash write command
+    is fully finished. The sync() is defined in each CPU's io.h file. For
+    those CPUs which do not need sync for now, a dummy sync() is defined in
+    their io.h as well.
+
+    Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+
+commit da04995c7dc6772013a9a0dc5c767f190c402478
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Feb 21 13:44:34 2007 +0100
+
+    [PATCH] Fix problem in systemace driver (ace_writew instead of ace_write)
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 751bb57107d78978ae08e697c3deba816f5be091
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 13:21:57 2007 +0100
+
+    [PATCH] Fix relocation problem with "new" get_dev() function
+
+    This patch enables the "new" get_dev() function for block devices
+    introduced by Grant Likely to be used on systems that still suffer
+    from the relocation problems (manual relocation neede because of
+    problems with linker script).
+
+    Hopefully we can resolve this relocation issue soon for all platform
+    so we don't need this additional code anymore.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit d93e2212f962668b3dce091ff5edc33f2347fe37
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 13:17:42 2007 +0100
+
+    [PATCH] Update SystemACE driver for 16bit access
+
+    This patch removes some problems when the Xilinx SystemACE driver
+    is used with 16bit access on an big endian platform (like the
+    AMCC Katmai).
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 874bb7b88fe9b4648e1288a387af2e31014a72f3
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 13:15:40 2007 +0100
+
+    [PATCH] Clean up Katmai (440SPe) linker script
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 4745acaa1a603b67f6b9b7970365ebadd7d6586f
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 10:57:08 2007 +0100
+
+    [PATCH] Add support for the AMCC Katmai (440SPe) eval board
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 0dc018ece13effc689e47479ea9ebf1c98a507f5
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 10:51:26 2007 +0100
+
+    [PATCH] I2C: Add support for multiple I2C busses for RTC & DTT
+
+    This patch switches to the desired I2C bus when the date/dtt
+    commands are called. This can be configured using the
+    CFG_RTC_BUS_NUM and/or CFG_DTT_BUS_NUM defines.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 4037ed3b63923cfcec27f784a89057c3cbabcedb
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 10:43:34 2007 +0100
+
+    [PATCH] PPC4xx: Add 440SP(e) DDR2 SPD DIMM support
+
+    This patch adds support for the DDR2 controller used on the
+    440SP and 440SPe. It is tested on the Katmai (440SPe) eval
+    board and works fine with the following DIMM modules:
+
+    - Corsair CM2X512-5400C4 (512MByte per DIMM)
+    - Kingston ValueRAM KVR667D2N5/512 (512MByte per DIMM)
+    - Kingston ValueRAM KVR667D2N5K2/2G (1GByte per DIMM)
+
+    This patch also adds the nice functionality to dynamically
+    create the TLB entries for the SDRAM (tlb.c). So we should
+    never run into such problems with wrong (too short) TLB
+    initialization again on these platforms.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 36d830c9830379045f5daa9f542ac1c990c70068
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 10:35:42 2007 +0100
+
+    [PATCH] PPC4xx: Split 4xx SPD SDRAM init routines into 2 files
+
+    Since the existing 4xx SPD SDRAM initialization routines for the
+    405 SDRAM controller and the 440 DDR controller don't have much in
+    common this patch splits both drivers into different files.
+
+    This is in preparation for the 440 DDR2 controller support (440SP/e).
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 79b2d0bb2eae09602448f7a7cb56530d2f31e6c6
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Feb 20 10:27:08 2007 +0100
+
+    [PATCH] PPC4xx: Add support for multiple I2C busses
+
+    This patch adds support for multiple I2C busses on the PPC4xx
+    platforms. Define CONFIG_I2C_MULTI_BUS in the board config file
+    to make use of this feature.
+
+    It also merges the 405 and 440 i2c header files into one common
+    file 4xx_i2c.h.
+
+    Also the 4xx i2c reset procedure is reworked since I experienced
+    some problems with the first access on the 440SPe Katmai board.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit eb867a76238fb38e952c37871b16d0d7fd61c95f
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:05:45 2007 +0100
+
+    [PATCH 9_9] Use "void *" not "unsigned long *" for block dev read_write buffer pointers
+
+    Block device read/write is anonymous data; there is no need to use a
+    typed pointer.  void * is fine.  Also add a hook for block_read functions
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 53758fa20e935cc87eeb0519ed365df753a6f289
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:05:38 2007 +0100
+
+    [PATCH 8_9] Add block_write hook to block_dev_desc_t
+
+    Preparation for future patches which support block device writing
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit f4852ebe6ca946a509667eb68be42026f837be76
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:05:31 2007 +0100
+
+    [PATCH 7_9] Replace ace_readw_ace_writeb functions with macros
+
+    Register read/write does not need to be wrapped in a full function.  The
+    patch replaces them with macros.
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 3a8ce9af6fcb5744a7851b4440c07688acc40844
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:05:23 2007 +0100
+
+    [PATCH 6_9] Move common_cmd_ace.c to drivers_systemace.c
+
+    The code in this file is not a command; it is a device driver.  Put it in
+    the correct place.	There are zero functional changes in this patch, it
+    only moves the file.
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 984618f3e7794c783ec8d1511e74c6ee2d69bfe4
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:05:16 2007 +0100
+
+    [PATCH 5_9] Whitespace fixup on common_cmd_ace.c (using Lindent)
+
+    This patch is in preparation of additional changes to the sysace driver.
+    May as well take this opportunity to fixup the inconsistent whitespace since
+    this file is about to undergo major changes anyway.
+
+    There are zero functional changes in this patch.  It only cleans up the
+    the whitespace.
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 80ba981d940471fe7e539e64fa3d2bd80002beda
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:05:07 2007 +0100
+
+    [PATCH 4_4] Remove local implementation of isprint() in ft_build.c
+
+    isprint is already defined in ctype.c
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit c95c4280d751ca078c2ff58228d2f2b44ccf0600
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:05:00 2007 +0100
+
+    [PATCH 3_9] Move buffer print code from md command to common function
+
+    Printing a buffer is a darn useful thing.  Move the buffer print code
+    into print_buffer() in lib_generic/
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 99b0f0fd3fbf2572ae1a7723dd90cffc8e85130a
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:04:52 2007 +0100
+
+    [PATCH 2_4] Use config.h, not xparameters.h, for xilinx targets
+
+    Change the xilinx device drivers and board code to include config.h
+    instead of xparameters.h directly.	config.h always includes the
+    correct xparameters file.  This change reduces the posibility of
+    including the wrong file when adding a new xilinx board port
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 735dd97b1b20e777d059c7b389fe9d70cd3f80c7
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:	Tue Feb 20 09:04:34 2007 +0100
+
+    [PATCH 1_4] Merge common get_dev() routines for block devices
+
+    Each of the filesystem drivers duplicate the get_dev routine.  This change
+    merges them into a single function in part.c
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit f5fcc3c20b65554e98a165542c36ee0c610a2d81
+Author: Wolfgang Denk <wd@pollux.denx.de>
+Date:	Mon Feb 19 23:09:51 2007 +0100
+
+    MCC200: Software Updater: allow both "ramdisk" and "filesystem" types
+    as root file system images.
+
+commit 489c696ae7211218961d159e43e722d74c36fcbc
+Author: Sergei Poselenov <sposelenov@emcraft.com>
+Date:	Wed Feb 14 14:30:28 2007 +0300
+
+    MCC200: Extensions to Software Update Mechanism
+
+    Update / extend Software Update Mechanism for MCC200 board:
+
+    - Add support for rootfs image added. The environment variables
+      "rootfs_st" and "rootfs_nd" can be used to override the default
+      values of the image start and end.
+    - Remove excessive key check code.
+    - Code cleanup.
+
+commit 4be23a12f23f1372634edc3215137b09768b7949
+Author: Stefan Roese <sr@denx.de>
+Date:	Mon Feb 19 08:23:15 2007 +0100
+
+    [PATCH] Update Sequoia EBC configuration (NOR FLASH)
+
+    As spotted by Matthias Fuchs, the READY input should not be
+    enabled for the NOR FLASH on the Sequoia board.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 497d012e5be0194e1084073d0081eb1a844796b2
+Author: Gary Jennejohn <garyj@pollux.denx.de>
+Date:	Mon Feb 12 13:11:50 2007 +0100
+
+    LPC2292: patch from Siemens.
+
+commit b0b1a920aebead0d44146e73676ae9d80fffc8e2
+Author: Stefan Roese <sr@denx.de>
+Date:	Sat Feb 10 08:49:31 2007 +0100
+
+    [PATCH] Add missing p3mx.h file to repository (ups)
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 53d4a4983fb9b3ae5f7b2f10c599aca2b1b4034a
+Author: Bartlomiej Sieka <tur@semihalf.com>
+Date:	Fri Feb 9 10:45:42 2007 +0100
+
+    [Motion-PRO] Preliminary support for the Motion-PRO board.
+
+commit 5a753f98c6a01bd1c61a9a3f95e8329a35f62994
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Feb 7 16:51:08 2007 +0100
+
+    [PATCH] Update some AMCC 4xx board config files (set initrd_high)
+
+    Some boards that can have more than 768MBytes of SDRAM need to
+    set "initrd_high", so that the initrd can be accessed by the
+    Linux kernel.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 7372ca68227930d03cffa548310524cad5b96733
+Author: Stefan Roese <sr@denx.de>
+Date:	Fri Feb 2 12:44:22 2007 +0100
+
+    [PATCH] Correctly display PCI arbiter en-/disabled on some 4xx boards
+
+    Previously the strapping DCR/SDR was read to determine if the internal PCI
+    arbiter is enabled or not. This strapping bit can be overridden, so now
+    the current status is read from the correct DCR/SDR register.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 2aa54f651a42d198673318f07a20c89a43e4d197
+Author: Stefan Roese <sr@denx.de>
+Date:	Fri Feb 2 12:42:08 2007 +0100
+
+    [PATCH] Change configuration output of Sycamore, Yellowstone & Rainier
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 23744d6b5bf17592eb6a0ef4f318f6089f55993b
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Feb 1 13:22:41 2007 +0100
+
+    [PATCH] Remove PCI-PNP configuration from Sequoia/Rainier config file
+
+    When PCI PNP is enabled the pci pnp configuration routine is called
+    which sets the PCI_CACHE_SIZE_LINE to 8. This seems to generate some
+    problems with some PCI cards. For now disable the PCI PNP configuration.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 2902fadade3be7659467e8d074048c6b7068f5c0
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Jan 31 16:56:10 2007 +0100
+
+    [PATCH] Update 440EPx/440GRx cpu detection
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit d5ea287b02a6945c3977410e364a879dd1a555c8
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Jan 31 16:38:04 2007 +0100
+
+    [PATCH] Update esd cpci5200 files
+
+    Signed-off-by: Reinhard Arlt <reinhard.arlt@esd-electronics.com>
+
+commit 8b7d1f0ab7d7c4fe3160bbf74a7e9690d9f3a3ab
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Jan 31 16:37:34 2007 +0100
+
+    [PATCH] Add support for esd mecp5200 board
+
+    Signed-off-by: Reinhard Arlt <reinhard.arlt@esd-electronics.com>
+
+commit 71a4e5fda8b60044ab9f46069fa1cfa26bdd07ff
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Jan 31 12:38:50 2007 +0100
+
+    [PATCH] Remove unneccessary yellowstone board config file
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit e802594b6fa1b166308820c276b96dc0d7cc731c
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Jan 30 17:06:10 2007 +0100
+
+    [PATCH] Update Sequoia (440EPx) config file
+
+    The config file now handles the 2nd target, the Rainier (440GRx)
+    evaluation board better. Additionally the PPC input clock was
+    adjusted to match the correct value of 33.0 MHz.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 700200c67e73b83751418abe7815840dca8fd6cb
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Jan 30 17:04:19 2007 +0100
+
+    [PATCH] Merge Yosemite & Yellowstone board ports
+
+    Now the AMCC eval boards Yosemite (440EP) and Yellowstone (440GR)
+    share one config file and all board specific files. This way we
+    don't have to maintain two different sets of files for nearly
+    identical boards.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 1bbf5eae322f5f1f6427ecc3ac13a0cb7dba8ad6
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Jan 30 15:01:49 2007 +0100
+
+    [PATCH] Update Prodrive SCPU (PDNB3 variant) board
+
+    SCPU doesn't use redundant environment in flash.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 6304430ed642ea8fa15c9e5af965ac2e033eec45
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Jan 30 12:51:07 2007 +0100
+
+    [PATCH] alpr: Update alpr board config file
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit f8db84f132b1e335f20f96138a1f09ed97b08664
+Author: Wolfgang Denk <wd@pollux.denx.de>
+Date:	Tue Jan 30 00:50:40 2007 +0100
+
+    LPC2292 SODIMM port coding style cleanup.
+
 commit 6bd2447ee47ee23c18d2b3c7ccd5a20f7626f5b3
 Author: Gary Jennejohn <garyj@pollux.denx.de>
 Date:	Wed Jan 24 12:16:56 2007 +0100
diff --git a/MAINTAINERS b/MAINTAINERS
index f90c5a6..1d0a8df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -288,6 +288,7 @@
 	bamboo			PPC440EP
 	bunbinga		PPC405EP
 	ebony			PPC440GP
+	katmai			PPC440SPe
 	ocotea			PPC440GX
 	p3p440			PPC440GP
 	pcs440ep		PPC440EP
diff --git a/MAKEALL b/MAKEALL
index d943cee..8431b3e 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -37,9 +37,10 @@
 LIST_5xxx="	\
 	BC3450		cpci5200	EVAL5200	fo300		\
 	icecube_5100	icecube_5200	lite5200b	mcc200		\
-	mecp5200	o2dnt		pf5200		PM520		\
-	TB5200		Total5100	Total5200	Total5200_Rev2	\
-	TQM5200		TQM5200_B	TQM5200S	v38b		\
+	mecp5200	motionpro	o2dnt		pf5200		\
+	PM520		TB5200		Total5100	Total5200	\
+	Total5200_Rev2	TQM5200		TQM5200_B	TQM5200S	\
+	v38b								\
 "
 
 #########################################################################
@@ -81,15 +82,15 @@
 	CRAYL1		csb272		csb472		DASA_SIM	\
 	DP405		DU405		ebony		ERIC		\
 	EXBITGEN	G2000		HH405		HUB405		\
-	JSE		KAREF		luan		METROBOX	\
-	MIP405		MIP405T		ML2		ml300		\
-	ocotea		OCRTC		ORSG		p3p440		\
-	PCI405		pcs440ep	PIP405		PLU405		\
-	PMC405		PPChameleonEVB	sbc405		sc3		\
-	sequoia		sequoia_nand	taishan		VOH405		\
-	VOM405		W7OLMC		W7OLMG		walnut		\
-	WUH405		XPEDITE1K	yellowstone	yosemite	\
-	yucca								\
+	JSE		KAREF		katmai		luan		\
+	METROBOX	MIP405		MIP405T		ML2		\
+	ml300		ocotea		OCRTC		ORSG		\
+	p3p440		PCI405		pcs440ep	PIP405		\
+	PLU405		PMC405		PPChameleonEVB	sbc405		\
+	sc3		sequoia		sequoia_nand	taishan		\
+	VOH405		VOM405		W7OLMC		W7OLMG		\
+	walnut		WUH405		XPEDITE1K	yellowstone	\
+	yosemite	yucca						\
 "
 
 #########################################################################
diff --git a/Makefile b/Makefile
index f337ab0..e139d76 100644
--- a/Makefile
+++ b/Makefile
@@ -118,7 +118,7 @@
 export	ARCH CPU BOARD VENDOR SOC
 
 ifndef CROSS_COMPILE
-ifeq ($(HOSTARCH),ppc)
+ifeq ($(HOSTARCH),$(ARCH))
 CROSS_COMPILE =
 else
 ifeq ($(ARCH),ppc)
@@ -128,12 +128,8 @@
 CROSS_COMPILE = arm-linux-
 endif
 ifeq ($(ARCH),i386)
-ifeq ($(HOSTARCH),i386)
-CROSS_COMPILE =
-else
 CROSS_COMPILE = i386-linux-
 endif
-endif
 ifeq ($(ARCH),mips)
 CROSS_COMPILE = mips_4KC-
 endif
@@ -207,7 +203,13 @@
 LIBS += drivers/qe/qe.a
 endif
 LIBS += drivers/sk98lin/libsk98lin.a
-LIBS += post/libpost.a post/cpu/libcpu.a
+LIBS += post/libpost.a post/drivers/libpostdrivers.a
+LIBS += $(shell if [ -d post/lib_$(ARCH) ]; then echo \
+	"post/lib_$(ARCH)/libpost$(ARCH).a"; fi)
+LIBS += $(shell if [ -d post/cpu/$(CPU) ]; then echo \
+	"post/cpu/$(CPU)/libpost$(CPU).a"; fi)
+LIBS += $(shell if [ -d post/board/$(BOARDDIR) ]; then echo \
+	"post/board/$(BOARDDIR)/libpost$(BOARD).a"; fi)
 LIBS += common/libcommon.a
 LIBS += $(BOARDLIBS)
 
@@ -220,9 +222,8 @@
 # The "tools" are needed early, so put this first
 # Don't include stuff already done in $(LIBS)
 SUBDIRS	= tools \
-	  examples \
-	  post \
-	  post/cpu
+	  examples
+
 .PHONY : $(SUBDIRS)
 
 ifeq ($(CONFIG_NAND_U_BOOT),y)
@@ -610,6 +611,9 @@
 	@$(MKCONFIG) -n $@ -a TQM5200 ppc mpc5xxx tqm5200
 uc101_config:         unconfig
 	@$(MKCONFIG) uc101 ppc mpc5xxx uc101
+motionpro_config:         unconfig
+	@$(MKCONFIG) motionpro ppc mpc5xxx motionpro
+
 
 #########################################################################
 ## MPC8xx Systems
@@ -1095,6 +1099,9 @@
 KAREF_config: unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx karef sandburst
 
+katmai_config:	unconfig
+	@$(MKCONFIG) $(@:_config=) ppc ppc4xx katmai amcc
+
 luan_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx luan amcc
 
diff --git a/README b/README
index ecfd1f8..1542864 100644
--- a/README
+++ b/README
@@ -1347,6 +1347,16 @@
 		If defined, then this indicates the I2C bus number for DDR SPD.
 		If not defined, then U-Boot assumes that SPD is on I2C bus 0.
 
+		CFG_RTC_BUS_NUM
+
+		If defined, then this indicates the I2C bus number for the RTC.
+		If not defined, then U-Boot assumes that RTC is on I2C bus 0.
+
+		CFG_DTT_BUS_NUM
+
+		If defined, then this indicates the I2C bus number for the DTT.
+		If not defined, then U-Boot assumes that DTT is on I2C bus 0.
+
 		CONFIG_FSL_I2C
 
 		Define this option if you want to use Freescale's I2C driver in
diff --git a/board/amcc/katmai/Makefile b/board/amcc/katmai/Makefile
new file mode 100644
index 0000000..d06a402
--- /dev/null
+++ b/board/amcc/katmai/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2007
+# 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	= $(obj)lib$(BOARD).a
+
+COBJS	= $(BOARD).o cmd_katmai.o
+SOBJS	= init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend *~
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/amcc/katmai/cmd_katmai.c b/board/amcc/katmai/cmd_katmai.c
new file mode 100644
index 0000000..684f6a5
--- /dev/null
+++ b/board/amcc/katmai/cmd_katmai.c
@@ -0,0 +1,267 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@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 <i2c.h>
+#include <asm/byteorder.h>
+
+static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	uchar	chip;
+	ulong	data;
+	int	nbytes;
+	extern char console_buffer[];
+
+	char sysClock[4];
+	char cpuClock[4];
+	char plbClock[4];
+	char pcixClock[4];
+
+	if (argc < 3) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	if (strcmp(argv[2], "prom0") == 0)
+		chip = IIC0_BOOTPROM_ADDR;
+	else
+		chip = IIC0_ALT_BOOTPROM_ADDR;
+
+	do {
+		printf("enter sys clock frequency 33 or 66 Mhz or quit to abort\n");
+		nbytes = readline (" ? ");
+
+		if (strcmp(console_buffer, "quit") == 0)
+			return 0;
+
+		if ((strcmp(console_buffer, "33") != 0) &
+		    (strcmp(console_buffer, "66") != 0))
+			nbytes=0;
+
+		strcpy(sysClock, console_buffer);
+
+	} while (nbytes == 0);
+
+	do {
+		if (strcmp(sysClock, "66") == 0) {
+			printf("enter cpu clock frequency 400, 533 Mhz or quit to abort\n");
+		} else {
+#ifdef	CONFIG_STRESS
+			printf("enter cpu clock frequency 400, 500, 533, 667 Mhz or quit to abort\n");
+#else
+			printf("enter cpu clock frequency 400, 500, 533 Mhz or quit to abort\n");
+#endif
+		}
+		nbytes = readline (" ? ");
+
+		if (strcmp(console_buffer, "quit") == 0)
+			return 0;
+
+		if (strcmp(sysClock, "66") == 0) {
+			if ((strcmp(console_buffer, "400") != 0) &
+			    (strcmp(console_buffer, "533") != 0)
+#ifdef	CONFIG_STRESS
+			    & (strcmp(console_buffer, "667") != 0)
+#endif
+				) {
+				nbytes = 0;
+			}
+		} else {
+			if ((strcmp(console_buffer, "400") != 0) &
+			    (strcmp(console_buffer, "500") != 0) &
+			    (strcmp(console_buffer, "533") != 0)
+#ifdef	CONFIG_STRESS
+			    & (strcmp(console_buffer, "667") != 0)
+#endif
+				) {
+				nbytes = 0;
+			}
+		}
+
+		strcpy(cpuClock, console_buffer);
+
+	} while (nbytes == 0);
+
+	if (strcmp(cpuClock, "500") == 0)
+		strcpy(plbClock, "166");
+	else if (strcmp(cpuClock, "533") == 0)
+		strcpy(plbClock, "133");
+	else {
+		do {
+			if (strcmp(cpuClock, "400") == 0)
+				printf("enter plb clock frequency 100, 133 Mhz or quit to abort\n");
+
+#ifdef	CONFIG_STRESS
+			if (strcmp(cpuClock, "667") == 0)
+				printf("enter plb clock frequency 133, 166 Mhz or quit to abort\n");
+
+#endif
+			nbytes = readline (" ? ");
+
+			if (strcmp(console_buffer, "quit") == 0)
+				return 0;
+
+			if (strcmp(cpuClock, "400") == 0) {
+				if ((strcmp(console_buffer, "100") != 0) &
+				    (strcmp(console_buffer, "133") != 0))
+					nbytes = 0;
+			}
+#ifdef	CONFIG_STRESS
+			if (strcmp(cpuClock, "667") == 0) {
+				if ((strcmp(console_buffer, "133") != 0) &
+				    (strcmp(console_buffer, "166") != 0))
+					nbytes = 0;
+			}
+#endif
+			strcpy(plbClock, console_buffer);
+
+		} while (nbytes == 0);
+	}
+
+	do {
+		printf("enter Pci-X clock frequency 33, 66, 100 or 133 Mhz or quit to abort\n");
+		nbytes = readline (" ? ");
+
+		if (strcmp(console_buffer, "quit") == 0)
+			return 0;
+
+		if ((strcmp(console_buffer, "33") != 0) &
+		    (strcmp(console_buffer, "66") != 0) &
+		    (strcmp(console_buffer, "100") != 0) &
+		    (strcmp(console_buffer, "133") != 0)) {
+			nbytes = 0;
+		}
+		strcpy(pcixClock, console_buffer);
+
+	} while (nbytes == 0);
+
+	printf("\nsys clk   = %sMhz\n", sysClock);
+	printf("cpu clk   = %sMhz\n", cpuClock);
+	printf("plb clk   = %sMhz\n", plbClock);
+	printf("Pci-X clk = %sMhz\n", pcixClock);
+
+	do {
+		printf("\npress [y] to write I2C bootstrap \n");
+		printf("or [n] to abort.  \n");
+		printf("Don't forget to set board switches \n");
+		printf("according to your choice before re-starting \n");
+		printf("(refer to 440spe_uboot_kit_um_1_01.pdf) \n");
+
+		nbytes = readline (" ? ");
+		if (strcmp(console_buffer, "n") == 0)
+			return 0;
+
+	} while (nbytes == 0);
+
+	if (strcmp(sysClock, "33") == 0) {
+		if ((strcmp(cpuClock, "400") == 0) &
+		    (strcmp(plbClock, "100") == 0))
+			data = 0x8678c206;
+
+		if ((strcmp(cpuClock, "400") == 0) &
+		    (strcmp(plbClock, "133") == 0))
+			data = 0x8678c2c6;
+
+		if ((strcmp(cpuClock, "500") == 0))
+			data = 0x8778f2c6;
+
+		if ((strcmp(cpuClock, "533") == 0))
+			data = 0x87790252;
+
+#ifdef	CONFIG_STRESS
+		if ((strcmp(cpuClock, "667") == 0) &
+		    (strcmp(plbClock, "133") == 0))
+			data = 0x87794256;
+
+		if ((strcmp(cpuClock, "667") == 0) &
+		    (strcmp(plbClock, "166") == 0))
+			data = 0x87794206;
+
+#endif
+	}
+	if (strcmp(sysClock, "66") == 0) {
+		if ((strcmp(cpuClock, "400") == 0) &
+		    (strcmp(plbClock, "100") == 0))
+			data = 0x84706206;
+
+		if ((strcmp(cpuClock, "400") == 0) &
+		    (strcmp(plbClock, "133") == 0))
+			data = 0x847062c6;
+
+		if ((strcmp(cpuClock, "533") == 0))
+			data = 0x85708206;
+
+#ifdef	CONFIG_STRESS
+		if ((strcmp(cpuClock, "667") == 0) &
+		    (strcmp(plbClock, "133") == 0))
+			data = 0x8570a256;
+
+		if ((strcmp(cpuClock, "667") == 0) &
+		    (strcmp(plbClock, "166") == 0))
+			data = 0x8570a206;
+
+#endif
+	}
+
+#ifdef	DEBUG
+	printf(" pin strap0 to write in i2c  = %x\n", data);
+#endif	/* DEBUG */
+
+	if (i2c_write(chip, 0, 1, (uchar *)&data, 4) != 0)
+		printf("Error writing strap0 in %s\n", argv[2]);
+
+	if (strcmp(pcixClock, "33") == 0)
+		data = 0x00000701;
+
+	if (strcmp(pcixClock, "66") == 0)
+		data = 0x00000601;
+
+	if (strcmp(pcixClock, "100") == 0)
+		data = 0x00000501;
+
+	if (strcmp(pcixClock, "133") == 0)
+		data = 0x00000401;
+
+	if (strcmp(plbClock, "166") == 0)
+		data |= 0x05950000;
+	else
+		data |= 0x05A50000;
+
+#ifdef	DEBUG
+	printf(" pin strap1 to write in i2c  = %x\n", data);
+#endif	/* DEBUG */
+
+	udelay(1000);
+	if (i2c_write(chip, 4, 1, (uchar *)&data, 4) != 0)
+		printf("Error writing strap1 in %s\n", argv[2]);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	bootstrap,	3,	1,	do_bootstrap,
+	"bootstrap - program the serial device strap\n",
+	"wrclk [prom0|prom1] - program the serial device strap\n"
+	);
diff --git a/board/amcc/katmai/config.mk b/board/amcc/katmai/config.mk
new file mode 100644
index 0000000..115c1ae
--- /dev/null
+++ b/board/amcc/katmai/config.mk
@@ -0,0 +1,38 @@
+#
+# (C) Copyright 2006
+# 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
+#
+
+#
+# AMCC 440SPe Evaluation (Katmai) board
+#
+
+TEXT_BASE = 0xfffc0000
+
+PLATFORM_CPPFLAGS += -DCONFIG_440=1
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
+
+ifeq ($(dbcr),1)
+PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
+endif
diff --git a/board/amcc/katmai/init.S b/board/amcc/katmai/init.S
new file mode 100644
index 0000000..6b024ee
--- /dev/null
+++ b/board/amcc/katmai/init.S
@@ -0,0 +1,118 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ *  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>
+#include <asm-ppc/mmu.h>
+
+/**************************************************************************
+ * 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"
+
+/**************************************************************************
+ * TLB table for revA
+ *************************************************************************/
+	.globl tlbtabA
+tlbtabA:
+	tlbtab_start
+
+	/*
+	 * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
+	 * speed up boot process. It is patched after relocation to enable SA_I
+	 */
+	tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+	/*
+	 * TLB entries for SDRAM are not needed on this platform.
+	 * They are dynamically generated in the SPD DDR(2) detection
+	 * routine.
+	 */
+
+	tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
+	tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I)
+
+	tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+
+	tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbtab_end
+
+/**************************************************************************
+ * TLB table for revB
+ *
+ * Notice: revB of the 440SPe chip is very strict about PLB real addresses
+ * and ranges to be mapped for config space: it seems to only work with
+ * d_nnnn_nnnn range (hangs the core upon config transaction attempts when
+ * set otherwise) while revA uses c_nnnn_nnnn.
+ *************************************************************************/
+	.globl tlbtabB
+tlbtabB:
+	tlbtab_start
+
+	/*
+	 * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
+	 * speed up boot process. It is patched after relocation to enable SA_I
+	 */
+	tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+	/*
+	 * TLB entries for SDRAM are not needed on this platform.
+	 * They are dynamically generated in the SPD DDR(2) detection
+	 * routine.
+	 */
+
+	tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
+
+	tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I)
+
+	tlbentry(CFG_ACE_BASE, SZ_1K, 0xE0000000, 4,AC_R|AC_W|SA_G|SA_I)
+
+	tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+
+	tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+	tlbtab_end
diff --git a/board/amcc/katmai/katmai.c b/board/amcc/katmai/katmai.c
new file mode 100644
index 0000000..fbf1a98
--- /dev/null
+++ b/board/amcc/katmai/katmai.c
@@ -0,0 +1,529 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@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 <i2c.h>
+#include <asm-ppc/io.h>
+
+#include "../cpu/ppc4xx/440spe_pcie.h"
+
+#undef PCIE_ENDPOINT
+/* #define PCIE_ENDPOINT 1 */
+
+int ppc440spe_init_pcie_rootport(int port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+
+int board_early_init_f (void)
+{
+	unsigned long mfr;
+
+	/*----------------------------------------------------------------------+
+	 * Interrupt controller setup for the Katmai 440SPe Evaluation board.
+	 *-----------------------------------------------------------------------+
+	 *-----------------------------------------------------------------------+
+	 * Interrupt | Source                            | Pol.  | Sensi.| Crit. |
+	 *-----------+-----------------------------------+-------+-------+-------+
+	 * IRQ 00    | UART0                             | High  | Level | Non   |
+	 * IRQ 01    | UART1                             | High  | Level | Non   |
+	 * IRQ 02    | IIC0                              | High  | Level | Non   |
+	 * IRQ 03    | IIC1                              | High  | Level | Non   |
+	 * IRQ 04    | PCI0X0 MSG IN                     | High  | Level | Non   |
+	 * IRQ 05    | PCI0X0 CMD Write                  | High  | Level | Non   |
+	 * IRQ 06    | PCI0X0 Power Mgt                  | High  | Level | Non   |
+	 * IRQ 07    | PCI0X0 VPD Access                 | Rising| Edge  | Non   |
+	 * IRQ 08    | PCI0X0 MSI level 0                | High  | Lvl/ed| Non   |
+	 * IRQ 09    | External IRQ 15 - (PCI-Express)   | pgm H | Pgm   | Non   |
+	 * IRQ 10    | UIC2 Non-critical Int.            | NA    | NA    | Non   |
+	 * IRQ 11    | UIC2 Critical Interrupt           | NA    | NA    | Crit  |
+	 * IRQ 12    | PCI Express MSI Level 0           | Rising| Edge  | Non   |
+	 * IRQ 13    | PCI Express MSI Level 1           | Rising| Edge  | Non   |
+	 * IRQ 14    | PCI Express MSI Level 2           | Rising| Edge  | Non   |
+	 * IRQ 15    | PCI Express MSI Level 3           | Rising| Edge  | Non   |
+	 * IRQ 16    | UIC3 Non-critical Int.            | NA    | NA    | Non   |
+	 * IRQ 17    | UIC3 Critical Interrupt           | NA    | NA    | Crit  |
+	 * IRQ 18    | External IRQ 14 - (PCI-Express)   | Pgm   | Pgm   | Non   |
+	 * IRQ 19    | DMA Channel 0 FIFO Full           | High  | Level | Non   |
+	 * IRQ 20    | DMA Channel 0 Stat FIFO           | High  | Level | Non   |
+	 * IRQ 21    | DMA Channel 1 FIFO Full           | High  | Level | Non   |
+	 * IRQ 22    | DMA Channel 1 Stat FIFO           | High  | Level | Non   |
+	 * IRQ 23    | I2O Inbound Doorbell              | High  | Level | Non   |
+	 * IRQ 24    | Inbound Post List FIFO Not Empt   | High  | Level | Non   |
+	 * IRQ 25    | I2O Region 0 LL PLB Write         | High  | Level | Non   |
+	 * IRQ 26    | I2O Region 1 LL PLB Write         | High  | Level | Non   |
+	 * IRQ 27    | I2O Region 0 HB PLB Write         | High  | Level | Non   |
+	 * IRQ 28    | I2O Region 1 HB PLB Write         | High  | Level | Non   |
+	 * IRQ 29    | GPT Down Count Timer              | Rising| Edge  | Non   |
+	 * IRQ 30    | UIC1 Non-critical Int.            | NA    | NA    | Non   |
+	 * IRQ 31    | UIC1 Critical Interrupt           | NA    | NA    | Crit. |
+	 *------------------------------------------------------------------------
+	 * IRQ 32    | Ext. IRQ 13 - (PCI-Express)       |pgm (H)|pgm/Lvl| Non   |
+	 * IRQ 33    | MAL Serr                          | High  | Level | Non   |
+	 * IRQ 34    | MAL Txde                          | High  | Level | Non   |
+	 * IRQ 35    | MAL Rxde                          | High  | Level | Non   |
+	 * IRQ 36    | DMC CE or DMC UE                  | High  | Level | Non   |
+	 * IRQ 37    | EBC or UART2                      | High  |Lvl Edg| Non   |
+	 * IRQ 38    | MAL TX EOB                        | High  | Level | Non   |
+	 * IRQ 39    | MAL RX EOB                        | High  | Level | Non   |
+	 * IRQ 40    | PCIX0 MSI Level 1                 | High  |Lvl Edg| Non   |
+	 * IRQ 41    | PCIX0 MSI level 2                 | High  |Lvl Edg| Non   |
+	 * IRQ 42    | PCIX0 MSI level 3                 | High  |Lvl Edg| Non   |
+	 * IRQ 43    | L2 Cache                          | Risin | Edge  | Non   |
+	 * IRQ 44    | GPT Compare Timer 0               | Risin | Edge  | Non   |
+	 * IRQ 45    | GPT Compare Timer 1               | Risin | Edge  | Non   |
+	 * IRQ 46    | GPT Compare Timer 2               | Risin | Edge  | Non   |
+	 * IRQ 47    | GPT Compare Timer 3               | Risin | Edge  | Non   |
+	 * IRQ 48    | GPT Compare Timer 4               | Risin | Edge  | Non   |
+	 * IRQ 49    | Ext. IRQ 12 - PCI-X               |pgm/Fal|pgm/Lvl| Non   |
+	 * IRQ 50    | Ext. IRQ 11 -                     |pgm (H)|pgm/Lvl| Non   |
+	 * IRQ 51    | Ext. IRQ 10 -                     |pgm (H)|pgm/Lvl| Non   |
+	 * IRQ 52    | Ext. IRQ 9                        |pgm (H)|pgm/Lvl| Non   |
+	 * IRQ 53    | Ext. IRQ 8                        |pgm (H)|pgm/Lvl| Non   |
+	 * IRQ 54    | DMA Error                         | High  | Level | Non   |
+	 * IRQ 55    | DMA I2O Error                     | High  | Level | Non   |
+	 * IRQ 56    | Serial ROM                        | High  | Level | Non   |
+	 * IRQ 57    | PCIX0 Error                       | High  | Edge  | Non   |
+	 * IRQ 58    | Ext. IRQ 7-                       |pgm (H)|pgm/Lvl| Non   |
+	 * IRQ 59    | Ext. IRQ 6-                       |pgm (H)|pgm/Lvl| Non   |
+	 * IRQ 60    | EMAC0 Interrupt                   | High  | Level | Non   |
+	 * IRQ 61    | EMAC0 Wake-up                     | High  | Level | Non   |
+	 * IRQ 62    | Reserved                          | High  | Level | Non   |
+	 * IRQ 63    | XOR                               | High  | Level | Non   |
+	 *-----------------------------------------------------------------------
+	 * IRQ 64    | PE0 AL                            | High  | Level | Non   |
+	 * IRQ 65    | PE0 VPD Access                    | Risin | Edge  | Non   |
+	 * IRQ 66    | PE0 Hot Reset Request             | Risin | Edge  | Non   |
+	 * IRQ 67    | PE0 Hot Reset Request             | Falli | Edge  | Non   |
+	 * IRQ 68    | PE0 TCR                           | High  | Level | Non   |
+	 * IRQ 69    | PE0 BusMaster VCO                 | Falli | Edge  | Non   |
+	 * IRQ 70    | PE0 DCR Error                     | High  | Level | Non   |
+	 * IRQ 71    | Reserved                          | N/A   | N/A   | Non   |
+	 * IRQ 72    | PE1 AL                            | High  | Level | Non   |
+	 * IRQ 73    | PE1 VPD Access                    | Risin | Edge  | Non   |
+	 * IRQ 74    | PE1 Hot Reset Request             | Risin | Edge  | Non   |
+	 * IRQ 75    | PE1 Hot Reset Request             | Falli | Edge  | Non   |
+	 * IRQ 76    | PE1 TCR                           | High  | Level | Non   |
+	 * IRQ 77    | PE1 BusMaster VCO                 | Falli | Edge  | Non   |
+	 * IRQ 78    | PE1 DCR Error                     | High  | Level | Non   |
+	 * IRQ 79    | Reserved                          | N/A   | N/A   | Non   |
+	 * IRQ 80    | PE2 AL                            | High  | Level | Non   |
+	 * IRQ 81    | PE2 VPD Access                    | Risin | Edge  | Non   |
+	 * IRQ 82    | PE2 Hot Reset Request             | Risin | Edge  | Non   |
+	 * IRQ 83    | PE2 Hot Reset Request             | Falli | Edge  | Non   |
+	 * IRQ 84    | PE2 TCR                           | High  | Level | Non   |
+	 * IRQ 85    | PE2 BusMaster VCO                 | Falli | Edge  | Non   |
+	 * IRQ 86    | PE2 DCR Error                     | High  | Level | Non   |
+	 * IRQ 87    | Reserved                          | N/A   | N/A   | Non   |
+	 * IRQ 88    | External IRQ(5)                   | Progr | Progr | Non   |
+	 * IRQ 89    | External IRQ 4 - Ethernet         | Progr | Progr | Non   |
+	 * IRQ 90    | External IRQ 3 - PCI-X            | Progr | Progr | Non   |
+	 * IRQ 91    | External IRQ 2 - PCI-X            | Progr | Progr | Non   |
+	 * IRQ 92    | External IRQ 1 - PCI-X            | Progr | Progr | Non   |
+	 * IRQ 93    | External IRQ 0 - PCI-X            | Progr | Progr | Non   |
+	 * IRQ 94    | Reserved                          | N/A   | N/A   | Non   |
+	 * IRQ 95    | Reserved                          | N/A   | N/A   | Non   |
+	 *-----------------------------------------------------------------------
+	 * IRQ 96    | PE0 INTA                          | High  | Level | Non   |
+	 * IRQ 97    | PE0 INTB                          | High  | Level | Non   |
+	 * IRQ 98    | PE0 INTC                          | High  | Level | Non   |
+	 * IRQ 99    | PE0 INTD                          | High  | Level | Non   |
+	 * IRQ 100   | PE1 INTA                          | High  | Level | Non   |
+	 * IRQ 101   | PE1 INTB                          | High  | Level | Non   |
+	 * IRQ 102   | PE1 INTC                          | High  | Level | Non   |
+	 * IRQ 103   | PE1 INTD                          | High  | Level | Non   |
+	 * IRQ 104   | PE2 INTA                          | High  | Level | Non   |
+	 * IRQ 105   | PE2 INTB                          | High  | Level | Non   |
+	 * IRQ 106   | PE2 INTC                          | High  | Level | Non   |
+	 * IRQ 107   | PE2 INTD                          | Risin | Edge  | Non   |
+	 * IRQ 108   | PCI Express MSI Level 4           | Risin | Edge  | Non   |
+	 * IRQ 109   | PCI Express MSI Level 5           | Risin | Edge  | Non   |
+	 * IRQ 110   | PCI Express MSI Level 6           | Risin | Edge  | Non   |
+	 * IRQ 111   | PCI Express MSI Level 7           | Risin | Edge  | Non   |
+	 * IRQ 116   | PCI Express MSI Level 12          | Risin | Edge  | Non   |
+	 * IRQ 112   | PCI Express MSI Level 8           | Risin | Edge  | Non   |
+	 * IRQ 113   | PCI Express MSI Level 9           | Risin | Edge  | Non   |
+	 * IRQ 114   | PCI Express MSI Level 10          | Risin | Edge  | Non   |
+	 * IRQ 115   | PCI Express MSI Level 11          | Risin | Edge  | Non   |
+	 * IRQ 117   | PCI Express MSI Level 13          | Risin | Edge  | Non   |
+	 * IRQ 118   | PCI Express MSI Level 14          | Risin | Edge  | Non   |
+	 * IRQ 119   | PCI Express MSI Level 15          | Risin | Edge  | Non   |
+	 * IRQ 120   | PCI Express MSI Level 16          | Risin | Edge  | Non   |
+	 * IRQ 121   | PCI Express MSI Level 17          | Risin | Edge  | Non   |
+	 * IRQ 122   | PCI Express MSI Level 18          | Risin | Edge  | Non   |
+	 * IRQ 123   | PCI Express MSI Level 19          | Risin | Edge  | Non   |
+	 * IRQ 124   | PCI Express MSI Level 20          | Risin | Edge  | Non   |
+	 * IRQ 125   | PCI Express MSI Level 21          | Risin | Edge  | Non   |
+	 * IRQ 126   | PCI Express MSI Level 22          | Risin | Edge  | Non   |
+	 * IRQ 127   | PCI Express MSI Level 23          | Risin | Edge  | Non   |
+	 *-----------+-----------------------------------+-------+-------+-------+ */
+	/*-------------------------------------------------------------------------+
+	 * Put UICs in PowerPC440SPemode.
+	 * Initialise UIC registers.  Clear all interrupts.  Disable all interrupts.
+	 * Set critical interrupt values.  Set interrupt polarities.  Set interrupt
+	 * trigger levels.  Make bit 0 High  priority.  Clear all interrupts again.
+	 *------------------------------------------------------------------------*/
+	mtdcr (uic3sr, 0xffffffff);	/* Clear all interrupts */
+	mtdcr (uic3er, 0x00000000);	/* disable all interrupts */
+	mtdcr (uic3cr, 0x00000000);	/* Set Critical / Non Critical interrupts: */
+	mtdcr (uic3pr, 0xffffffff);	/* Set Interrupt Polarities*/
+	mtdcr (uic3tr, 0x001fffff);	/* Set Interrupt Trigger Levels */
+	mtdcr (uic3vr, 0x00000001);	/* Set Vect base=0,INT31 Highest priority */
+	mtdcr (uic3sr, 0x00000000);	/* clear all  interrupts*/
+	mtdcr (uic3sr, 0xffffffff);	/* clear all  interrupts*/
+
+
+	mtdcr (uic2sr, 0xffffffff);	/* Clear all interrupts */
+	mtdcr (uic2er, 0x00000000);	/* disable all interrupts*/
+	mtdcr (uic2cr, 0x00000000);	/* Set Critical / Non Critical interrupts*/
+	mtdcr (uic2pr, 0xebebebff);	/* Set Interrupt Polarities*/
+	mtdcr (uic2tr, 0x74747400);	/* Set Interrupt Trigger Levels */
+	mtdcr (uic2vr, 0x00000001);	/* Set Vect base=0,INT31 Highest priority */
+	mtdcr (uic2sr, 0x00000000);	/* clear all interrupts */
+	mtdcr (uic2sr, 0xffffffff);	/* clear all interrupts */
+
+	mtdcr (uic1sr, 0xffffffff);	/* Clear all interrupts*/
+	mtdcr (uic1er, 0x00000000);	/* disable all interrupts*/
+	mtdcr (uic1cr, 0x00000000);	/* Set Critical / Non Critical interrupts*/
+	mtdcr (uic1pr, 0xffffffff);	/* Set Interrupt Polarities */
+	mtdcr (uic1tr, 0x001f8040);	/* Set Interrupt Trigger Levels*/
+	mtdcr (uic1vr, 0x00000001);	/* Set Vect base=0,INT31 Highest priority */
+	mtdcr (uic1sr, 0x00000000);	/* clear all interrupts*/
+	mtdcr (uic1sr, 0xffffffff);	/* clear all interrupts*/
+
+	mtdcr (uic0sr, 0xffffffff);	/* Clear all interrupts */
+	mtdcr (uic0er, 0x00000000);	/* disable all interrupts excepted cascade    to be checked */
+	mtdcr (uic0cr, 0x00104001);	/* Set Critical / Non Critical interrupts*/
+	mtdcr (uic0pr, 0xffffffff);	/* Set Interrupt Polarities*/
+	mtdcr (uic0tr, 0x010f0004);	/* Set Interrupt Trigger Levels */
+	mtdcr (uic0vr, 0x00000001);	/* Set Vect base=0,INT31 Highest priority */
+	mtdcr (uic0sr, 0x00000000);	/* clear all interrupts*/
+	mtdcr (uic0sr, 0xffffffff);	/* clear all interrupts*/
+
+/* SDR0_MFR should be part of Ethernet init */
+	mfsdr (sdr_mfr, mfr);
+	mfr &= ~SDR0_MFR_ECS_MASK;
+/*	mtsdr(sdr_mfr, mfr); */
+
+	mtsdr(SDR0_PFC0, CFG_PFC0);
+
+	out32(GPIO0_OR, CFG_GPIO_OR);
+	out32(GPIO0_ODR, CFG_GPIO_ODR);
+	out32(GPIO0_TCR, CFG_GPIO_TCR);
+
+	return 0;
+}
+
+int checkboard (void)
+{
+	char *s = getenv("serial#");
+
+	printf("Board: Katmai - AMCC 440SPe Evaluation Board");
+	if (s != NULL) {
+		puts(", serial# ");
+		puts(s);
+	}
+	putc('\n');
+
+	return 0;
+}
+
+#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
+
+/*************************************************************************
+ *  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 katmai board is always configured as the host & requires the
+	 *	PCI arbiter to be enabled.
+	 *-------------------------------------------------------------------*/
+	mfsdr(sdr_sdstp1, strap);
+	if( (strap & SDR0_SDSTP1_PAE_MASK) == 0 ) {
+		printf("PCI: SDR0_STRP1[%08lX] - PCI Arbiter disabled.\n",strap);
+		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) */
+
+#if defined(CONFIG_PCI)
+/*************************************************************************
+ *  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.
+ *
+ *
+ ************************************************************************/
+int is_pci_host(struct pci_controller *hose)
+{
+	/* The katmai board is always configured as host. */
+	return 1;
+}
+
+int katmai_pcie_card_present(int port)
+{
+	u32 val;
+
+	val = in32(GPIO0_IR);
+	switch (port) {
+	case 0:
+		return !(val & GPIO_VAL(CFG_GPIO_PCIE_PRESENT0));
+	case 1:
+		return !(val & GPIO_VAL(CFG_GPIO_PCIE_PRESENT1));
+	case 2:
+		return !(val & GPIO_VAL(CFG_GPIO_PCIE_PRESENT2));
+	default:
+		return 0;
+	}
+}
+
+static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
+
+void pcie_setup_hoses(void)
+{
+	struct pci_controller *hose;
+	int i, bus;
+
+	/*
+	 * assume we're called after the PCIX hose is initialized, which takes
+	 * bus ID 0 and therefore start numbering PCIe's from 1.
+	 */
+	bus = 1;
+	for (i = 0; i <= 2; i++) {
+		/* Check for katmai card presence */
+		if (!katmai_pcie_card_present(i))
+			continue;
+
+#ifdef PCIE_ENDPOINT
+ 		if (ppc440spe_init_pcie_endport(i)) {
+#else
+		if (ppc440spe_init_pcie_rootport(i)) {
+#endif
+			printf("PCIE%d: initialization failed\n", i);
+			continue;
+		}
+
+		hose = &pcie_hose[i];
+		hose->first_busno = bus;
+		hose->last_busno  = bus;
+		bus++;
+
+		/* setup mem resource */
+		pci_set_region(hose->regions + 0,
+			       CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE,
+			       CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE,
+			       CFG_PCIE_MEMSIZE,
+			       PCI_REGION_MEM
+			);
+		hose->region_count = 1;
+		pci_register_hose(hose);
+
+#ifdef PCIE_ENDPOINT
+		ppc440spe_setup_pcie_endpoint(hose, i);
+		/*
+		 * Reson for no scanning is endpoint can not generate
+		 * upstream configuration accesses.
+		 */
+#else
+		ppc440spe_setup_pcie_rootpoint(hose, i);
+		/*
+		 * Config access can only go down stream
+		 */
+		hose->last_busno = pci_hose_scan(hose);
+#endif
+	}
+}
+#endif	/* defined(CONFIG_PCI) */
+
+int misc_init_f (void)
+{
+	uint reg;
+#if defined(CONFIG_STRESS)
+	uint i ;
+	uint disp;
+#endif
+
+	/* minimal init for PCIe */
+#if 0 /* test-only: test endpoint at some time, for now rootpoint only */
+	/* pci express 0 Endpoint Mode */
+	mfsdr(SDR0_PE0DLPSET, reg);
+	reg &= (~0x00400000);
+	mtsdr(SDR0_PE0DLPSET, reg);
+#else
+	/* pci express 0 Rootpoint  Mode */
+	mfsdr(SDR0_PE0DLPSET, reg);
+	reg |= 0x00400000;
+	mtsdr(SDR0_PE0DLPSET, reg);
+#endif
+	/* pci express 1 Rootpoint  Mode */
+	mfsdr(SDR0_PE1DLPSET, reg);
+	reg |= 0x00400000;
+	mtsdr(SDR0_PE1DLPSET, reg);
+	/* pci express 2 Rootpoint  Mode */
+	mfsdr(SDR0_PE2DLPSET, reg);
+	reg |= 0x00400000;
+	mtsdr(SDR0_PE2DLPSET, reg);
+
+#if defined(CONFIG_STRESS)
+	/*
+	 * All this setting done by linux only needed by stress an charac. test
+	 * procedure
+	 * PCIe 1 Rootpoint PCIe2 Endpoint
+	 * PCIe 0 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level
+	 */
+	for (i=0,disp=0; i<8; i++,disp+=3) {
+		mfsdr(SDR0_PE0HSSSET1L0+disp, reg);
+		reg |= 0x33000000;
+		mtsdr(SDR0_PE0HSSSET1L0+disp, reg);
+	}
+
+	/*PCIe 1 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level */
+	for (i=0,disp=0; i<4; i++,disp+=3) {
+		mfsdr(SDR0_PE1HSSSET1L0+disp, reg);
+		reg |= 0x33000000;
+		mtsdr(SDR0_PE1HSSSET1L0+disp, reg);
+	}
+
+	/*PCIE 2 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level */
+	for (i=0,disp=0; i<4; i++,disp+=3) {
+		mfsdr(SDR0_PE2HSSSET1L0+disp, reg);
+		reg |= 0x33000000;
+		mtsdr(SDR0_PE2HSSSET1L0+disp, reg);
+	}
+
+	reg = 0x21242222;
+	mtsdr(SDR0_PE2UTLSET1, reg);
+	reg = 0x11000000;
+	mtsdr(SDR0_PE2UTLSET2, reg);
+	/* pci express 1 Endpoint  Mode */
+	reg = 0x00004000;
+	mtsdr(SDR0_PE2DLPSET, reg);
+
+	mtsdr(SDR0_UART1, 0x2080005a);	/* patch for TG */
+#endif
+
+	return 0;
+}
+
+#ifdef CONFIG_POST
+/*
+ * Returns 1 if keys pressed to start the power-on long-running tests
+ * Called from board_init_f().
+ */
+int post_hotkeys_pressed(void)
+{
+	return (ctrlc());
+}
+#endif
diff --git a/board/amcc/katmai/u-boot.lds b/board/amcc/katmai/u-boot.lds
new file mode 100644
index 0000000..bf8fc5d
--- /dev/null
+++ b/board/amcc/katmai/u-boot.lds
@@ -0,0 +1,141 @@
+/*
+ * (C) Copyright 2004
+ * 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
+{
+  .resetvec 0xFFFFFFFC :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  .bootpg 0xFFFFF000 :
+  {
+    cpu/ppc4xx/start.o	(.bootpg)
+  } = 0xffff
+
+  /* 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/ppc4xx/start.o		(.text)
+    board/amcc/katmai/init.o	(.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+    *(.eh_frame)
+  }
+  .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 = .);
+
+  . = .;
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  . = .;
+  __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/amcc/luan/init.S b/board/amcc/luan/init.S
index 7830ebd..d5ee117 100644
--- a/board/amcc/luan/init.S
+++ b/board/amcc/luan/init.S
@@ -1,73 +1,31 @@
 /*
-*
-* 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
-*/
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ *  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)
-
+#include <asm-ppc/mmu.h>
 
 /**************************************************************************
  * TLB TABLE
@@ -80,53 +38,37 @@
  *
  *************************************************************************/
 
-    .section .bootpg,"ax"
-    .globl tlbtab
+	.section .bootpg,"ax"
+	.globl tlbtab
 
 tlbtab:
-    tlbtab_start
+	tlbtab_start
 
-#if (CFG_LARGE_FLASH == 0xffc00000)	/* if booting from large flash */
-    /* large flash */
-    tlbentry( 0xffc00000,         SZ_1M, 0xffc00000,          1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
-    tlbentry( 0xffd00000,         SZ_1M, 0xffd00000,          1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
-    tlbentry( 0xffe00000,         SZ_1M, 0xffe00000,          1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
-    tlbentry( 0xfff00000,         SZ_1M, 0xfff00000,          1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
+	/*
+	 * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
+	 * speed up boot process. It is patched after relocation to enable SA_I
+	 */
+	tlbentry(0xfff00000, SZ_1M, 0xfff00000, 1, AC_R|AC_W|AC_X|SA_G)
 
-    tlbentry( 0xff800000,         SZ_1M, 0xff800000,          1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-    tlbentry( 0xff900000,         SZ_1M, 0xff900000,          1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
-#else					/* else booting from small flash */
-    tlbentry( 0xffe00000,         SZ_1M, 0xffe00000,          1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-    tlbentry( 0xfff00000,         SZ_1M, 0xfff00000,          1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
+	tlbentry(0xffc00000, SZ_1M, 0xffc00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+	tlbentry(0xffd00000, SZ_1M, 0xffd00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+	tlbentry(0xffe00000, SZ_1M, 0xffe00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+	tlbentry(0xff900000, SZ_1M, 0xff900000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+	tlbentry(CFG_EPLD_BASE, SZ_256K, 0xff000000, 1, AC_R|AC_W|SA_G|SA_I)
 
-    tlbentry( 0xff800000,         SZ_1M, 0xff800000,          1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-    tlbentry( 0xff900000,         SZ_1M, 0xff900000,          1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-    tlbentry( 0xffa00000,         SZ_1M, 0xffa00000,          1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-    tlbentry( 0xffb00000,         SZ_1M, 0xffb00000,          1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-#endif
+	/*
+	 * TLB entries for SDRAM are not needed on this platform.
+	 * They are dynamically generated in the SPD DDR(2) detection
+	 * routine.
+	 */
 
-    tlbentry( CFG_EPLD_BASE,    SZ_256K, 0xff000000,          1, AC_R|AC_W|SA_G|SA_I )
+	/* internal ram (l2 cache) */
+	tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x80000000, 0, AC_R|AC_W|AC_X|SA_I)
 
-#if (CFG_SRAM_BASE != 0)		/* if SRAM up high and SDRAM at zero */
-    tlbentry( 0x00000000, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
-    tlbentry( 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
-#elif (CFG_SMALL_FLASH == 0xff900000)	/* else SRAM at 0 */
-    tlbentry( 0x00000000,   SZ_1M, 0xff800000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-#elif (CFG_SMALL_FLASH == 0xfff00000)
-    tlbentry( 0x00000000,   SZ_1M, 0xffe00000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-#else
-    #error DONT KNOW SRAM LOCATION
-#endif
+	/* peripherals at f0000000 */
+	tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, CFG_PERIPHERAL_BASE, 1, AC_R|AC_W|SA_G|SA_I)
 
-    /* internal ram (l2 cache) */
-    tlbentry( CFG_ISRAM_BASE,    SZ_256K, 0x80000000,      0, AC_R|AC_W|AC_X|SA_I )
-
-    /* peripherals at f0000000 */
-    tlbentry( CFG_PERIPHERAL_BASE, SZ_4K, CFG_PERIPHERAL_BASE, 1, AC_R|AC_W|SA_G|SA_I )
-
-    /* PCI */
-#if (CONFIG_COMMANDS & CFG_CMD_PCI)
-    tlbentry( CFG_PCI_BASE,    SZ_256M, 0x00000000, 9, AC_R|AC_W|SA_G|SA_I )
-    tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 9, AC_R|AC_W|SA_G|SA_I )
-#endif
-    tlbtab_end
+	/* PCI */
+	tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 9, AC_R|AC_W|SA_G|SA_I)
+	tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 9, AC_R|AC_W|SA_G|SA_I)
+	tlbtab_end
diff --git a/board/amcc/luan/luan.c b/board/amcc/luan/luan.c
index 06a57f6c..778aafc 100644
--- a/board/amcc/luan/luan.c
+++ b/board/amcc/luan/luan.c
@@ -106,105 +106,6 @@
 
 
 /*************************************************************************
- *  long int fixed_sdram()
- *
- ************************************************************************/
-static long int fixed_sdram(void)
-{					/* DDR2 init from BDI2000 script */
-	mtdcr( 0x10, 0x00000021 );	/* MCIF0_MCOPT2 - zero DCEN bit */
-	mtdcr( 0x11, 0x84000000 );
-	mtdcr( 0x10, 0x00000020 );	/* MCIF0_MCOPT1 - no ECC, 64 bits, 4 banks, DDR2 */
-	mtdcr( 0x11, 0x2D122000 );
-	mtdcr( 0x10, 0x00000026 );	/* MCIF0_CODT  - die termination on */
-	mtdcr( 0x11, 0x00800026 );
-	mtdcr( 0x10, 0x00000081 );	/* MCIF0_WRDTR - Write DQS Adv 90 + Fractional DQS Delay */
-	mtdcr( 0x11, 0x82000800 );
-	mtdcr( 0x10, 0x00000080 );	/* MCIF0_CLKTR - advance addr clock by 180 deg */
-	mtdcr( 0x11, 0x80000000 );
-	mtdcr( 0x10, 0x00000040 );	/* MCIF0_MB0CF - turn on CS0, N x 10 coll */
-	mtdcr( 0x11, 0x00000201 );
-	mtdcr( 0x10, 0x00000044 );	/* MCIF0_MB1CF - turn on CS0, N x 10 coll */
-	mtdcr( 0x11, 0x00000201 );
-	mtdcr( 0x10, 0x00000030 );	/* MCIF0_RTR   - refresh every 7.8125uS */
-	mtdcr( 0x11, 0x08200000 );
-	mtdcr( 0x10, 0x00000085 );	/* MCIF0_SDTR1 - timing register 1 */
-	mtdcr( 0x11, 0x80201000 );
-	mtdcr( 0x10, 0x00000086 );	/* MCIF0_SDTR2 - timing register 2 */
-	mtdcr( 0x11, 0x42103242 );
-	mtdcr( 0x10, 0x00000087 );	/* MCIF0_SDTR3 - timing register 3 */
-	mtdcr( 0x11, 0x0C100D14 );
-	mtdcr( 0x10, 0x00000088 );	/* MCIF0_MMODE - CAS is 4 cycles */
-	mtdcr( 0x11, 0x00000642 );
-	mtdcr( 0x10, 0x00000089 );	/* MCIF0_MEMODE - diff DQS disabled */
-	mtdcr( 0x11, 0x00000400 );	/*		  ODT term disabled */
-
-	mtdcr( 0x10, 0x00000050 );	/* MCIF0_INITPLR0 - NOP */
-	mtdcr( 0x11, 0x81b80000 );
-	mtdcr( 0x10, 0x00000051 );	/* MCIF0_INITPLR1 - PRE */
-	mtdcr( 0x11, 0x82100400 );
-	mtdcr( 0x10, 0x00000052 );	/* MCIF0_INITPLR2 - EMR2 */
-	mtdcr( 0x11, 0x80820000 );
-	mtdcr( 0x10, 0x00000053 );	/* MCIF0_INITPLR3 - EMR3 */
-	mtdcr( 0x11, 0x80830000 );
-	mtdcr( 0x10, 0x00000054 );	/* MCIF0_INITPLR4 - EMR DLL ENABLE */
-	mtdcr( 0x11, 0x80810000 );
-	mtdcr( 0x10, 0x00000055 );	/* MCIF0_INITPLR5 - MR DLL RESET */
-	mtdcr( 0x11, 0x80800542 );
-	mtdcr( 0x10, 0x00000056 );	/* MCIF0_INITPLR6 - PRE */
-	mtdcr( 0x11, 0x82100400 );
-	mtdcr( 0x10, 0x00000057 );	/* MCIF0_INITPLR7 - refresh */
-	mtdcr( 0x11, 0x99080000 );
-	mtdcr( 0x10, 0x00000058 );	/* MCIF0_INITPLR8 */
-	mtdcr( 0x11, 0x99080000 );
-	mtdcr( 0x10, 0x00000059 );	/* MCIF0_INITPLR9 */
-	mtdcr( 0x11, 0x99080000 );
-	mtdcr( 0x10, 0x0000005A );	/* MCIF0_INITPLR10 */
-	mtdcr( 0x11, 0x99080000 );
-	mtdcr( 0x10, 0x0000005B );	/* MCIF0_INITPLR11 - MR */
-	mtdcr( 0x11, 0x80800442 );
-	mtdcr( 0x10, 0x0000005C );	/* MCIF0_INITPLR12 - EMR OCD Default */
-	mtdcr( 0x11, 0x80810380 );
-	mtdcr( 0x10, 0x0000005D );	/* MCIF0_INITPLR13 - EMR OCD exit */
-	mtdcr( 0x11, 0x80810000 );
-	udelay( 10*1000 );
-
-	mtdcr( 0x10, 0x00000021 );	/* MCIF0_MCOPT2 - execute preloaded init */
-	mtdcr( 0x11, 0x28000000 );	/*		  set DC_EN */
-	udelay( 100*1000 );
-
-	mtdcr( 0x40, 0x0000F800 );	/* MQ0_B0BAS: base addr 00000000 / 256MB */
-	mtdcr( 0x41, 0x1000F800 );	/* MQ0_B1BAS: base addr 10000000 / 256MB */
-
-	mtdcr( 0x10, 0x00000078 );	/* MCIF0_RDCC - auto set read stage */
-	mtdcr( 0x11, 0x00000000 );
-	mtdcr( 0x10, 0x00000070 );	/* MCIF0_RQDC - read DQS delay control */
-	mtdcr( 0x11, 0x8000003A );	/*		enabled, frac DQS delay */
-	mtdcr( 0x10, 0x00000074 );	/* MCIF0_RFDC - two clock feedback delay */
-	mtdcr( 0x11, 0x00000200 );
-
-	return  512 << 20;
-}
-
-
-/*************************************************************************
- *  long int initdram
- *
- ************************************************************************/
-long int initdram( int board_type )
-{
-	long dram_size = 0;
-
-#if defined(CONFIG_SPD_EEPROM)
-	dram_size = spd_sdram (0);
-#else
-	dram_size = fixed_sdram ();
-#endif
-
-	return  dram_size;
-}
-
-
-/*************************************************************************
  *  int testdram()
  *
  ************************************************************************/
diff --git a/board/amcc/luan/u-boot.lds b/board/amcc/luan/u-boot.lds
index d122f49..72ce685 100644
--- a/board/amcc/luan/u-boot.lds
+++ b/board/amcc/luan/u-boot.lds
@@ -68,19 +68,6 @@
 
     cpu/ppc4xx/start.o	(.text)
     board/amcc/luan/init.o	(.text)
-    cpu/ppc4xx/kgdb.o	(.text)
-    cpu/ppc4xx/traps.o	(.text)
-    cpu/ppc4xx/interrupts.o	(.text)
-    cpu/ppc4xx/serial.o	(.text)
-    cpu/ppc4xx/cpu_init.o	(.text)
-    cpu/ppc4xx/speed.o	(.text)
-    common/dlmalloc.o	(.text)
-    lib_generic/crc32.o		(.text)
-    lib_ppc/extable.o	(.text)
-    lib_generic/zlib.o		(.text)
-
-/*    . = env_offset;*/
-/*    common/environment.o(.text)*/
 
     *(.text)
     *(.fixup)
diff --git a/board/amcc/ocotea/init.S b/board/amcc/ocotea/init.S
index 7e0b132..d211c71 100644
--- a/board/amcc/ocotea/init.S
+++ b/board/amcc/ocotea/init.S
@@ -22,55 +22,7 @@
 
 #include <ppc_asm.tmpl>
 #include <config.h>
-
-/* General */
-#define TLB_VALID   0x00000200
-#define _256M       0x10000000
-
-/* 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_8M       0x00000060
-#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)
-
+#include <asm-ppc/mmu.h>
 
 /**************************************************************************
  * TLB TABLE
@@ -83,19 +35,23 @@
  *
  *************************************************************************/
 
-    .section .bootpg,"ax"
-    .globl tlbtab
+	.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_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
-    tlbentry( CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
-    tlbentry( CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 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
+	tlbtab_start
+
+	tlbentry(0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+
+	/*
+	 * TLB entries for SDRAM are not needed on this platform.
+	 * They are dynamically generated in the SPD DDR(2) detection
+	 * routine.
+	 */
+
+	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_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/amcc/sequoia/sdram.c b/board/amcc/sequoia/sdram.c
index 77f1438..f8b837e 100644
--- a/board/amcc/sequoia/sdram.c
+++ b/board/amcc/sequoia/sdram.c
@@ -6,7 +6,7 @@
  * Alain Saurel,            AMCC/IBM, alain.saurel@fr.ibm.com
  * Robert Snyder,           AMCC/IBM, rob.snyder@fr.ibm.com
  *
- * (C) Copyright 2006
+ * (C) Copyright 2006-2007
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  * This program is free software; you can redistribute it and/or
@@ -379,16 +379,18 @@
 long int initdram (int board_type)
 {
 #if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
+	ulong speed = get_bus_freq(0);
+
 	mtsdram(DDR0_02, 0x00000000);
 
 	mtsdram(DDR0_00, 0x0000190A);
 	mtsdram(DDR0_01, 0x01000000);
 	mtsdram(DDR0_03, 0x02030602);
-	mtsdram(DDR0_04, 0x13030300);
-	mtsdram(DDR0_05, 0x0202050E);
-	mtsdram(DDR0_06, 0x0104C823);
+	mtsdram(DDR0_04, 0x0A020200);
+	mtsdram(DDR0_05, 0x02020308);
+	mtsdram(DDR0_06, 0x0102C812);
 	mtsdram(DDR0_07, 0x000D0100);
-	mtsdram(DDR0_08, 0x02360001);
+	mtsdram(DDR0_08, 0x02430001);
 	mtsdram(DDR0_09, 0x00011D5F);
 	mtsdram(DDR0_10, 0x00000300);
 	mtsdram(DDR0_11, 0x0027C800);
@@ -402,13 +404,16 @@
 	mtsdram(DDR0_22, 0x00267F0B);
 	mtsdram(DDR0_23, 0x00000000);
 	mtsdram(DDR0_24, 0x01010002);
-	mtsdram(DDR0_26, 0x5B260181);
+	if (speed > 133333333)
+		mtsdram(DDR0_26, 0x5B26050C);
+	else
+		mtsdram(DDR0_26, 0x5B260408);
 	mtsdram(DDR0_27, 0x0000682B);
 	mtsdram(DDR0_28, 0x00000000);
 	mtsdram(DDR0_31, 0x00000000);
 	mtsdram(DDR0_42, 0x01000006);
-	mtsdram(DDR0_43, 0x050A0200);
-	mtsdram(DDR0_44, 0x00000005);
+	mtsdram(DDR0_43, 0x030A0200);
+	mtsdram(DDR0_44, 0x00000003);
 	mtsdram(DDR0_02, 0x00000001);
 
 	wait_for_dlllock();
diff --git a/board/amcc/yucca/init.S b/board/amcc/yucca/init.S
index c9eca68..c92dcf7 100644
--- a/board/amcc/yucca/init.S
+++ b/board/amcc/yucca/init.S
@@ -1,4 +1,7 @@
 /*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
  *  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
  *
  * See file CREDITS for list of people who contributed to this
@@ -19,56 +22,10 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
-/* port to AMCC 440SPE evaluatioon board - SG April 12,2005  */
 
 #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)
+#include <asm-ppc/mmu.h>
 
 /**************************************************************************
  * TLB TABLE
@@ -89,12 +46,18 @@
 	.globl tlbtabA
 tlbtabA:
 	tlbtab_start
-	tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
 
-	tlbentry(CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
-	tlbentry(CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
-	tlbentry(CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
-	tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+	/*
+	 * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
+	 * speed up boot process. It is patched after relocation to enable SA_I
+	 */
+	tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+	/*
+	 * TLB entries for SDRAM are not needed on this platform.
+	 * They are dynamically generated in the SPD DDR(2) detection
+	 * routine.
+	 */
 
 	tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
 	tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
@@ -126,12 +89,18 @@
 	.globl tlbtabB
 tlbtabB:
 	tlbtab_start
-	tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
 
-	tlbentry(CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
-	tlbentry(CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
-	tlbentry(CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
-	tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+	/*
+	 * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
+	 * speed up boot process. It is patched after relocation to enable SA_I
+	 */
+	tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+	/*
+	 * TLB entries for SDRAM are not needed on this platform.
+	 * They are dynamically generated in the SPD DDR(2) detection
+	 * routine.
+	 */
 
 	tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
 	tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
diff --git a/board/amcc/yucca/yucca.c b/board/amcc/yucca/yucca.c
index e9b34dd..90eaab1 100644
--- a/board/amcc/yucca/yucca.c
+++ b/board/amcc/yucca/yucca.c
@@ -44,8 +44,6 @@
 char *remove_l_w_space(char *in_str );
 char *remove_t_w_space(char *in_str );
 int get_console_port(void);
-unsigned long ppcMfcpr(unsigned long cpr_reg);
-unsigned long ppcMfsdr(unsigned long sdr_reg);
 
 int ppc440spe_init_pcie_rootport(int port);
 void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
@@ -221,7 +219,7 @@
 	 |
 	 +-------------------------------------------------------------------*/
 	/* Read Pin Strap Register in PPC440SP */
-	sdr0_pinstp = ppcMfsdr(SDR0_PINSTP);
+	mfsdr(SDR0_PINSTP, sdr0_pinstp);
 	bootstrap_settings = sdr0_pinstp & SDR0_PINSTP_BOOTSTRAP_MASK;
 
 	switch (bootstrap_settings) {
@@ -246,7 +244,7 @@
 			 * Boot Settings in IIC EEprom address 0x50 or 0x54
 			 * Read Serial Device Strap Register1 in PPC440SPe
 			 */
-			sdr0_sdstp1 = ppcMfsdr(SDR0_SDSTP1);
+			mfsdr(SDR0_SDSTP1, sdr0_sdstp1);
 			boot_selection = sdr0_sdstp1 & SDR0_SDSTP1_ERPN_MASK;
 			ebc_data_width = sdr0_sdstp1 & SDR0_SDSTP1_EBCW_MASK;
 
@@ -564,277 +562,6 @@
 	return 0;
 }
 
-static long int yucca_probe_for_dimms(void)
-{
-	int 	dimm_installed[MAXDIMMS];
-	int	dimm_num, result;
-	int	dimms_found = 0;
-	uchar	dimm_addr = IIC0_DIMM0_ADDR;
-	uchar   dimm_spd_data[MAX_SPD_BYTES];
-
-	for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
-		/* check if there is a chip at the dimm address	*/
-		switch (dimm_num) {
-			case 0:
-				dimm_addr = IIC0_DIMM0_ADDR;
-				break;
-			case 1:
-				dimm_addr = IIC0_DIMM1_ADDR;
-				break;
-		}
-
-		result = i2c_probe(dimm_addr);
-
-		memset(dimm_spd_data, 0, MAX_SPD_BYTES * sizeof(char));
-		if (result == 0) {
-			/* read first byte of SPD data, if there is any data */
-			result = i2c_read(dimm_addr, 0, 1, dimm_spd_data, 1);
-
-			if (result == 0) {
-				result = dimm_spd_data[0];
-				result = result > MAX_SPD_BYTES ?
-						MAX_SPD_BYTES : result;
-				result = i2c_read(dimm_addr, 0, 1,
-							dimm_spd_data, result);
-			}
-		}
-
-		if ((result == 0) &&
-		    (dimm_spd_data[64] == MICRON_SPD_JEDEC_ID)) {
-			dimm_installed[dimm_num] = TRUE;
-			dimms_found++;
-			debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num);
-		} else {
-			dimm_installed[dimm_num] = FALSE;
-			debug("DIMM slot %d: Not populated or cannot sucessfully probe the DIMM\n", dimm_num);
-		}
-	}
-
-	if (dimms_found == 0) {
-		printf("ERROR - No memory installed.  Install a DDR-SDRAM DIMM.\n\n");
-		hang();
-	}
-
-	if (dimm_installed[0] != TRUE) {
-		printf("\nERROR - DIMM slot 0 must be populated before DIMM slot 1.\n");
-		printf("        Unsupported configuration. Move DIMM module from DIMM slot 1 to slot 0.\n\n");
-		hang();
-	}
-
-	return dimms_found;
-}
-
-/*************************************************************************
- * init SDRAM controller with fixed value
- * the initialization values are for 2x MICRON DDR2
- * PN: MT18HTF6472DY-53EB2
- * 512MB, DDR2, 533, CL4, ECC, REG
- ************************************************************************/
-static long int fixed_sdram(void)
-{
-	long int yucca_dimms = 0;
-
-	yucca_dimms = yucca_probe_for_dimms();
-
-	/* SDRAM0_MCOPT2 (0X21) Clear DCEN BIT	*/
-	mtdcr( 0x10, 0x00000021 );
-	mtdcr( 0x11, 0x84000000 );
-
-	/* SDRAM0_MCOPT1 (0X20) ECC OFF / 64 bits / 4 banks / DDR2	*/
-	mtdcr( 0x10, 0x00000020 );
-	mtdcr( 0x11, 0x2D122000 );
-
-	/* SET MCIF0_CODT   Die Termination On	*/
-	mtdcr( 0x10, 0x00000026 );
-	if (yucca_dimms == 2)
-		mtdcr( 0x11, 0x2A800021 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x11, 0x02800021 );
-
-	/* On-Die Termination for Bank 0	*/
-	mtdcr( 0x10, 0x00000022 );
-	if (yucca_dimms == 2)
-		mtdcr( 0x11, 0x18000000 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x11, 0x06000000 );
-
-	/*	On-Die Termination for Bank 1	*/
-	mtdcr( 0x10, 0x00000023 );
-	if (yucca_dimms == 2)
-		mtdcr( 0x11, 0x18000000 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x11, 0x01800000 );
-
-	/*	On-Die Termination for Bank 2	*/
-	mtdcr( 0x10, 0x00000024 );
-	if (yucca_dimms == 2)
-		mtdcr( 0x11, 0x01800000 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x11, 0x00000000 );
-
-	/*	On-Die Termination for Bank 3	*/
-	mtdcr( 0x10, 0x00000025 );
-	if (yucca_dimms == 2)
-		mtdcr( 0x11, 0x01800000 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x11, 0x00000000 );
-
-	/* Refresh Time register (0x30) Refresh every 7.8125uS	*/
-	mtdcr( 0x10, 0x00000030 );
-	mtdcr( 0x11, 0x08200000 );
-
-	/* SET MCIF0_MMODE  	 CL 4	*/
-	mtdcr( 0x10, 0x00000088 );
-	mtdcr( 0x11, 0x00000642 );
-
-	/* MCIF0_MEMODE	*/
-	mtdcr( 0x10, 0x00000089 );
-	mtdcr( 0x11, 0x00000004 );
-
-	/*SET MCIF0_MB0CF 	*/
-	mtdcr( 0x10, 0x00000040 );
-	mtdcr( 0x11, 0x00000201 );
-
-	/* SET MCIF0_MB1CF 	*/
-	mtdcr( 0x10, 0x00000044 );
-	mtdcr( 0x11, 0x00000201 );
-
-	/* SET MCIF0_MB2CF 	*/
-	mtdcr( 0x10, 0x00000048 );
-	if (yucca_dimms == 2)
-		mtdcr( 0x11, 0x00000201 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x11, 0x00000000 );
-
-	/* SET MCIF0_MB3CF 	*/
-	mtdcr( 0x10, 0x0000004c );
-	if (yucca_dimms == 2)
-		mtdcr( 0x11, 0x00000201 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x11, 0x00000000 );
-
-	/* SET MCIF0_INITPLR0  # NOP		*/
-	mtdcr( 0x10, 0x00000050 );
-	mtdcr( 0x11, 0xB5380000 );
-
-	/* SET MCIF0_INITPLR1  # PRE		*/
-	mtdcr( 0x10, 0x00000051 );
-	mtdcr( 0x11, 0x82100400 );
-
-	/* SET MCIF0_INITPLR2  # EMR2		*/
-	mtdcr( 0x10, 0x00000052 );
-	mtdcr( 0x11, 0x80820000 );
-
-	/* SET MCIF0_INITPLR3  # EMR3		*/
-	mtdcr( 0x10, 0x00000053 );
-	mtdcr( 0x11, 0x80830000 );
-
-	/* SET MCIF0_INITPLR4  # EMR DLL ENABLE	*/
-	mtdcr( 0x10, 0x00000054 );
-	mtdcr( 0x11, 0x80810000 );
-
-	/* SET MCIF0_INITPLR5  # MR DLL RESET	*/
-	mtdcr( 0x10, 0x00000055 );
-	mtdcr( 0x11, 0x80800542 );
-
-	/* SET MCIF0_INITPLR6  # PRE		*/
-	mtdcr( 0x10, 0x00000056 );
-	mtdcr( 0x11, 0x82100400 );
-
-	/* SET MCIF0_INITPLR7  # Refresh	*/
-	mtdcr( 0x10, 0x00000057 );
-	mtdcr( 0x11, 0x8A080000 );
-
-	/* SET MCIF0_INITPLR8  # Refresh	*/
-	mtdcr( 0x10, 0x00000058 );
-	mtdcr( 0x11, 0x8A080000 );
-
-	/* SET MCIF0_INITPLR9  # Refresh	*/
-	mtdcr( 0x10, 0x00000059 );
-	mtdcr( 0x11, 0x8A080000 );
-
-	/* SET MCIF0_INITPLR10 # Refresh	*/
-	mtdcr( 0x10, 0x0000005A );
-	mtdcr( 0x11, 0x8A080000 );
-
-	/* SET MCIF0_INITPLR11 # MR		*/
-	mtdcr( 0x10, 0x0000005B );
-	mtdcr( 0x11, 0x80800442 );
-
-	/* SET MCIF0_INITPLR12 # EMR OCD Default*/
-	mtdcr( 0x10, 0x0000005C );
-	mtdcr( 0x11, 0x80810380 );
-
-	/* SET MCIF0_INITPLR13 # EMR OCD Exit	*/
-	mtdcr( 0x10, 0x0000005D );
-	mtdcr( 0x11, 0x80810000 );
-
-	/* 0x80: Adv Addr clock by 180 deg	*/
-	mtdcr( 0x10, 0x00000080 );
-	mtdcr( 0x11, 0x80000000 );
-
-	/* 0x21: Exit self refresh, set DC_EN	*/
-	mtdcr( 0x10, 0x00000021 );
-	mtdcr( 0x11, 0x28000000 );
-
-	/* 0x81: Write DQS Adv 90 + Fractional DQS Delay	*/
-	mtdcr( 0x10, 0x00000081 );
-	mtdcr( 0x11, 0x80000800 );
-
-	/* MCIF0_SDTR1	*/
-	mtdcr( 0x10, 0x00000085 );
-	mtdcr( 0x11, 0x80201000 );
-
-	/* MCIF0_SDTR2	*/
-	mtdcr( 0x10, 0x00000086 );
-	mtdcr( 0x11, 0x42103242 );
-
-	/* MCIF0_SDTR3	*/
-	mtdcr( 0x10, 0x00000087 );
-	mtdcr( 0x11, 0x0C100D14 );
-
-	/* SET MQ0_B0BAS  base addr 00000000 / 256MB	*/
-	mtdcr( 0x40, 0x0000F800 );
-
-	/* SET MQ0_B1BAS  base addr 10000000 / 256MB	*/
-	mtdcr( 0x41, 0x0400F800 );
-
-	/* SET MQ0_B2BAS  base addr 20000000 / 256MB	*/
-	if (yucca_dimms == 2)
-		mtdcr( 0x42, 0x0800F800 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x42, 0x00000000 );
-
-	/* SET MQ0_B3BAS  base addr 30000000 / 256MB	*/
-	if (yucca_dimms == 2)
-		mtdcr( 0x43, 0x0C00F800 );
-	else if (yucca_dimms == 1)
-		mtdcr( 0x43, 0x00000000 );
-
-	/* SDRAM_RQDC	*/
-	mtdcr( 0x10, 0x00000070 );
-	mtdcr( 0x11, 0x8000003F );
-
-	/* SDRAM_RDCC	*/
-	mtdcr( 0x10, 0x00000078 );
-	mtdcr( 0x11, 0x80000000 );
-
-	/* SDRAM_RFDC	*/
-	mtdcr( 0x10, 0x00000074 );
-	mtdcr( 0x11, 0x00000220 );
-
-	return (yucca_dimms * 512) << 20;
-}
-
-long int initdram (int board_type)
-{
-	long dram_size = 0;
-
-	dram_size = fixed_sdram();
-
-	return dram_size;
-}
-
 #if defined(CFG_DRAM_TEST)
 int testdram (void)
 {
@@ -1267,42 +994,3 @@
 #endif
 	return (BOARD_OPTION_NOT_SELECTED);
 }
-
-/*---------------------------------------------------------------------------+
- | ppcMfcpr.
- +---------------------------------------------------------------------------*/
-unsigned long ppcMfcpr(unsigned long cpr_reg)
-{
-	unsigned long msr;
-	unsigned long cpr_cfgaddr_temp;
-	unsigned long cpr_value;
-
-	msr = (mfmsr () & ~(MSR_EE));
-	cpr_cfgaddr_temp =  mfdcr(CPR0_CFGADDR);
-	mtdcr(CPR0_CFGADDR, cpr_reg);
-	cpr_value =  mfdcr(CPR0_CFGDATA);
-	mtdcr(CPR0_CFGADDR, cpr_cfgaddr_temp);
-	mtmsr(msr);
-
-	return (cpr_value);
-}
-
-/*----------------------------------------------------------------------------+
-| Indirect Access of the System DCR's (SDR)
-| ppcMfsdr
-+----------------------------------------------------------------------------*/
-unsigned long ppcMfsdr(unsigned long sdr_reg)
-{
-	unsigned long msr;
-	unsigned long sdr_cfgaddr_temp;
-	unsigned long sdr_value;
-
-	msr = (mfmsr () & ~(MSR_EE));
-	sdr_cfgaddr_temp =  mfdcr(SDR0_CFGADDR);
-	mtdcr(SDR0_CFGADDR, sdr_reg);
-	sdr_value =  mfdcr(SDR0_CFGDATA);
-	mtdcr(SDR0_CFGADDR, sdr_cfgaddr_temp);
-	mtmsr(msr);
-
-	return (sdr_value);
-}
diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c
index a7114eb..a0fac7f 100644
--- a/board/cray/L1/L1.c
+++ b/board/cray/L1/L1.c
@@ -23,7 +23,7 @@
 
 #include <common.h>
 #include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
 #include <command.h>
 #include <rtc.h>
 #include <post.h>
diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c
index 5cd3423..001fd68 100644
--- a/board/esd/common/auto_update.c
+++ b/board/esd/common/auto_update.c
@@ -33,6 +33,7 @@
 #include <asm/byteorder.h>
 #include <linux/mtd/nand_legacy.h>
 #include <fat.h>
+#include <part.h>
 
 #include "auto_update.h"
 
@@ -71,8 +72,6 @@
 extern int flash_sect_erase(ulong, ulong);
 extern int flash_sect_protect (int, ulong, ulong);
 extern int flash_write (char *, ulong, ulong);
-/* change char* to void* to shutup the compiler */
-extern block_dev_desc_t *get_dev (char*, int);
 
 #if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY)
 /* references to names in cmd_nand.c */
diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c
index 36bb7ce..17e3568 100644
--- a/board/esd/cpci750/cpci750.c
+++ b/board/esd/cpci750/cpci750.c
@@ -366,12 +366,12 @@
 	dcache_lock ();
 #endif
 	if (flash_info[3].size < CFG_FLASH_INCREMENT) {
-	        unsigned int flash_offset;
+		unsigned int flash_offset;
 		unsigned int l;
 
 		flash_offset =  CFG_FLASH_INCREMENT - flash_info[3].size;
 		for (l = 0; l < CFG_MAX_FLASH_SECT; l++) {
-		        if (flash_info[3].start[l] != 0) {
+			if (flash_info[3].start[l] != 0) {
 			      flash_info[3].start[l] += flash_offset;
 			}
 		}
@@ -503,7 +503,7 @@
 {
 	asm ("lfd  0, 0(3)\n\t"	/* fpr0   =  *scr       */
 	     "stfd 0, 0(4)"	/* *dest  =  fpr0       */
-      : : : "fr0");		/* Clobbers fr0         */
+      : : : "fr0");		/* Clobbers fr0		*/
 	return;
 }
 
@@ -581,9 +581,9 @@
 		move64 (&(pattern[i]), pmem);
 		move64 (pmem, &temp64);
 
-		/* hi = (temp64>>32) & 0xffffffff;          */
-		/* lo = temp64 & 0xffffffff;                */
-		/* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
+		/* hi = (temp64>>32) & 0xffffffff;		*/
+		/* lo = temp64 & 0xffffffff;			*/
+		/* printf("\ntemp64 = 0x%08x%08x", hi, lo);	*/
 
 		hi = (pattern[i] >> 32) & 0xffffffff;
 		lo = pattern[i] & 0xffffffff;
@@ -856,11 +856,11 @@
 }
 #endif /* CFG_DRAM_TEST */
 
-/* ronen - the below functions are used by the bootm function           */
+/* ronen - the below functions are used by the bootm function		*/
 /*  - we map the base register to fbe00000 (same mapping as in the LSP) */
 /*  - we turn off the RX gig dmas - to prevent the dma from overunning  */
-/*    the kernel data areas.                                            */
-/*  - we diable and invalidate the icache and dcache.                   */
+/*    the kernel data areas.						*/
+/*  - we diable and invalidate the icache and dcache.			*/
 void my_remap_gt_regs_bootm (u32 cur_loc, u32 new_loc)
 {
 	u32 temp;
@@ -911,13 +911,11 @@
 	GT_REG_READ(0x3d4, &reset_sample_high);
 	printf("Reset configuration 0x%08x 0x%08x\n", reset_sample_low, reset_sample_high);
 
-        return(0);
+	return(0);
 }
 
-
 U_BOOT_CMD(
 	show_cfg,	1,	1,	do_show_cfg,
 	"show_cfg- Show Marvell strapping register\n",
 	"Show Marvell strapping register (ResetSampleLow ResetSampleHigh)\n"
 	);
-
diff --git a/board/esd/du405/du405.c b/board/esd/du405/du405.c
index a019ce4..6943213 100644
--- a/board/esd/du405/du405.c
+++ b/board/esd/du405/du405.c
@@ -25,7 +25,7 @@
 #include "du405.h"
 #include <asm/processor.h>
 #include <ppc4xx.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
 #include <command.h>
 
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/hmi1001/hmi1001.c b/board/hmi1001/hmi1001.c
index 237e863..9fa0e74 100644
--- a/board/hmi1001/hmi1001.c
+++ b/board/hmi1001/hmi1001.c
@@ -103,9 +103,9 @@
 
 	/* find RAM size using SDRAM CS0 only */
 	sdram_start(0);
-	test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
+	test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
 	sdram_start(1);
-	test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
+	test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
 	if (test1 > test2) {
 		sdram_start(0);
 		dramsize = test1;
@@ -179,7 +179,7 @@
 	return kbd_data;
 }
 
-static int compare_magic (const struct kbd_data_t *kbd_data, uchar *str)
+static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
 {
 	char s1 = str[0];
 	char s2;
@@ -222,11 +222,11 @@
 	return 0;
 }
 
-static uchar *key_match (const struct kbd_data_t *kbd_data)
+static char *key_match (const struct kbd_data_t *kbd_data)
 {
-	uchar magic[sizeof (kbd_magic_prefix) + 1];
-	uchar *suffix;
-	uchar *kbd_magic_keys;
+	char magic[sizeof (kbd_magic_prefix) + 1];
+	char *suffix;
+	char *kbd_magic_keys;
 
 	/*
 	 * The following string defines the characters that can be appended
@@ -247,7 +247,7 @@
 		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
 
 		if (compare_magic(kbd_data, getenv(magic)) == 0) {
-			uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+			char cmd_name[sizeof (kbd_command_prefix) + 1];
 			char *cmd;
 
 			sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
@@ -267,7 +267,7 @@
 #ifdef CONFIG_PREBOOT
 	struct kbd_data_t kbd_data;
 	/* Decode keys */
-	uchar *str = strdup (key_match (get_keys (&kbd_data)));
+	char *str = strdup (key_match (get_keys (&kbd_data)));
 	/* Set or delete definition */
 	setenv ("preboot", str);
 	free (str);
diff --git a/board/lpc2292sodimm/lpc2292sodimm.c b/board/lpc2292sodimm/lpc2292sodimm.c
index de04c66..d212c63 100644
--- a/board/lpc2292sodimm/lpc2292sodimm.c
+++ b/board/lpc2292sodimm/lpc2292sodimm.c
@@ -46,7 +46,7 @@
 	gd->bd->bi_arch_number = 83;
 
 	/* location of boot parameters */
-	gd->bd->bi_boot_params = 0xc0000100;
+	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
 	return 0;
 }
diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c
index f1bb721..90d03ec 100644
--- a/board/mcc200/auto_update.c
+++ b/board/mcc200/auto_update.c
@@ -23,6 +23,7 @@
 #include <image.h>
 #include <asm/byteorder.h>
 #include <usb.h>
+#include <part.h>
 
 #ifdef CFG_HUSH_PARSER
 #include <hush.h>
@@ -47,25 +48,6 @@
 #error "must define CFG_CMD_FAT"
 #endif
 
-/*
- * Check whether a USB memory stick is plugged in.
- * If one is found:
- *	1) if prepare.img ist found load it into memory. If it is
- *		valid then run it.
- *	2) if preinst.img is found load it into memory. If it is
- *		valid then run it. Update the EEPROM.
- *	3) if firmw_01.img is found load it into memory. If it is valid,
- *		burn it into FLASH and update the EEPROM.
- *	4) if kernl_01.img is found load it into memory. If it is valid,
- *		burn it into FLASH and update the EEPROM.
- *	5) if app.img is found load it into memory. If it is valid,
- *		burn it into FLASH and update the EEPROM.
- *	6) if disk.img is found load it into memory. If it is valid,
- *		burn it into FLASH and update the EEPROM.
- *	7) if postinst.img is found load it into memory. If it is
- *		valid then run it. Update the EEPROM.
- */
-
 #undef AU_DEBUG
 
 #undef debug
@@ -78,6 +60,7 @@
 /* possible names of files on the USB stick. */
 #define AU_FIRMWARE	"u-boot.img"
 #define AU_KERNEL	"kernel.img"
+#define AU_ROOTFS	"rootfs.img"
 
 struct flash_layout {
 	long start;
@@ -89,33 +72,47 @@
 #define AU_FL_FIRMWARE_ND	0xfC03FFFF
 #define AU_FL_KERNEL_ST		0xfC0C0000
 #define AU_FL_KERNEL_ND		0xfC1BFFFF
+#define AU_FL_ROOTFS_ST		0xFC1C0000
+#define AU_FL_ROOTFS_ND		0xFCFBFFFF
 
 static int au_usb_stor_curr_dev; /* current device */
 
 /* index of each file in the following arrays */
 #define IDX_FIRMWARE	0
 #define IDX_KERNEL	1
+#define IDX_ROOTFS	2
 
 /* max. number of files which could interest us */
-#define AU_MAXFILES 2
+#define AU_MAXFILES 3
 
 /* pointers to file names */
-char *aufile[AU_MAXFILES];
+char *aufile[AU_MAXFILES] = {
+	AU_FIRMWARE,
+	AU_KERNEL,
+	AU_ROOTFS
+};
 
 /* sizes of flash areas for each file */
-long ausize[AU_MAXFILES];
+long ausize[AU_MAXFILES] = {
+	(AU_FL_FIRMWARE_ND + 1) - AU_FL_FIRMWARE_ST,
+	(AU_FL_KERNEL_ND   + 1) - AU_FL_KERNEL_ST,
+	(AU_FL_ROOTFS_ND   + 1) - AU_FL_ROOTFS_ST,
+};
 
 /* array of flash areas start and end addresses */
-struct flash_layout aufl_layout[AU_MAXFILES] = { \
-	{AU_FL_FIRMWARE_ST, AU_FL_FIRMWARE_ND,}, \
-	{AU_FL_KERNEL_ST, AU_FL_KERNEL_ND,}, \
+struct flash_layout aufl_layout[AU_MAXFILES] = {
+	{ AU_FL_FIRMWARE_ST,	AU_FL_FIRMWARE_ND, },
+	{ AU_FL_KERNEL_ST,	AU_FL_KERNEL_ND,   },
+	{ AU_FL_ROOTFS_ST,	AU_FL_ROOTFS_ND,   },
 };
 
+ulong totsize;
+
 /* where to load files into memory */
 #define LOAD_ADDR ((unsigned char *)0x00200000)
 
-/* the app is the largest image */
-#define MAX_LOADSZ ausize[IDX_KERNEL]
+/* the root file system is the largest image */
+#define MAX_LOADSZ ausize[IDX_ROOTFS]
 
 /*i2c address of the keypad status*/
 #define I2C_PSOC_KEYPAD_ADDR	0x53
@@ -134,9 +131,12 @@
 extern int flash_sect_erase(ulong, ulong);
 extern int flash_sect_protect (int, ulong, ulong);
 extern int flash_write (char *, ulong, ulong);
-/* change char* to void* to shutup the compiler */
-extern block_dev_desc_t *get_dev (char*, int);
 extern int u_boot_hush_start(void);
+#ifdef CONFIG_PROGRESSBAR
+extern void show_progress(int, int);
+extern void lcd_puts (char *);
+extern void lcd_enable(void);
+#endif
 
 int au_check_cksum_valid(int idx, long nbytes)
 {
@@ -162,8 +162,7 @@
 int au_check_header_valid(int idx, long nbytes)
 {
 	image_header_t *hdr;
-	unsigned long checksum;
-	unsigned char buf[4];
+	unsigned long checksum, fsize;
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	/* check the easy ones first */
@@ -176,10 +175,12 @@
 #endif
 	if (nbytes < sizeof(*hdr)) {
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) {
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	/* check the hdr CRC */
@@ -188,30 +189,46 @@
 
 	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
 		printf ("Image %s bad header checksum\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	hdr->ih_hcrc = htonl(checksum);
 	/* check the type - could do this all in one gigantic if() */
 	if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
+		ausize[idx] = 0;
+		return -1;
+	}
+	if ((idx == IDX_ROOTFS) &&
+		( (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM) )
+	   ) {
+		printf ("Image %s wrong type\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	/* recycle checksum */
 	checksum = ntohl(hdr->ih_size);
-	/* for kernel and app the image header must also fit into flash */
-	if (idx != IDX_FIRMWARE)
+
+	fsize = checksum + sizeof(*hdr);
+	/* for kernel and ramdisk the image header must also fit into flash */
+	if (idx == IDX_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK)
 		checksum += sizeof(*hdr);
+
 	/* check the size does not exceed space in flash. HUSH scripts */
-	/* all have ausize[] set to 0 */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
 		printf ("Image %s is bigger than FLASH\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
-	return 0;
+	/* Update with the real filesize */
+	ausize[idx] = fsize;
+
+	return checksum; /* return size to be written to flash */
 }
 
 int au_do_update(int idx, long sz)
@@ -256,8 +273,12 @@
 	debug ("flash_sect_erase(%lx, %lx);\n", start, end);
 	flash_sect_erase(start, end);
 	wait_ms(100);
+#ifdef CONFIG_PROGRESSBAR
+	show_progress(end - start, totsize);
+#endif
+
 	/* strip the header - except for the kernel and ramdisk */
-	if (hdr->ih_type == IH_TYPE_KERNEL) {
+	if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
 		addr = (char *)hdr;
 		off = sizeof(*hdr);
 		nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
@@ -280,9 +301,13 @@
 		return -1;
 	}
 
-	/* check the dcrc of the copy */
+#ifdef CONFIG_PROGRESSBAR
+	show_progress(nbytes, totsize);
+#endif
+
+	/* check the data CRC of the copy */
 	if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
-		printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]);
+		printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]);
 		return -1;
 	}
 
@@ -302,10 +327,10 @@
 {
 	block_dev_desc_t *stor_dev;
 	long sz;
-	int i, res, bitmap_first, cnt, old_ctrlc, got_ctrlc;
+	int i, res = 0, bitmap_first, cnt, old_ctrlc, got_ctrlc;
 	char *env;
 	long start, end;
-	char keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0};
+	uchar keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0};
 
 	/*
 	 * Read keypad status
@@ -317,14 +342,11 @@
 	/*
 	 * Check keypad
 	 */
-	if ( !(keypad_status1[0] & KEYPAD_MASK_HI) ||
-	      (keypad_status1[0] != keypad_status2[0])) {
-		return 0;
-	}
 	if ( !(keypad_status1[1] & KEYPAD_MASK_LO) ||
 	      (keypad_status1[1] != keypad_status2[1])) {
 		return 0;
 	}
+
 	au_usb_stor_curr_dev = -1;
 	/* start USB */
 	if (usb_stop() < 0) {
@@ -359,14 +381,6 @@
 		debug ("file_fat_detectfs failed\n");
 	}
 
-	/* initialize the array of file names */
-	memset(aufile, 0, sizeof(aufile));
-	aufile[IDX_FIRMWARE] = AU_FIRMWARE;
-	aufile[IDX_KERNEL] = AU_KERNEL;
-	/* initialize the array of flash sizes */
-	memset(ausize, 0, sizeof(ausize));
-	ausize[IDX_FIRMWARE] = (AU_FL_FIRMWARE_ND + 1) - AU_FL_FIRMWARE_ST;
-	ausize[IDX_KERNEL] = (AU_FL_KERNEL_ND + 1) - AU_FL_KERNEL_ST;
 	/*
 	 * now check whether start and end are defined using environment
 	 * variables.
@@ -381,8 +395,8 @@
 		end = simple_strtoul(env, NULL, 16);
 	if (start >= 0 && end && end > start) {
 		ausize[IDX_FIRMWARE] = (end + 1) - start;
-		aufl_layout[0].start = start;
-		aufl_layout[0].end = end;
+		aufl_layout[IDX_FIRMWARE].start = start;
+		aufl_layout[IDX_FIRMWARE].end = end;
 	}
 	start = -1;
 	end = 0;
@@ -394,32 +408,73 @@
 		end = simple_strtoul(env, NULL, 16);
 	if (start >= 0 && end && end > start) {
 		ausize[IDX_KERNEL] = (end + 1) - start;
-		aufl_layout[1].start = start;
-		aufl_layout[1].end = end;
+		aufl_layout[IDX_KERNEL].start = start;
+		aufl_layout[IDX_KERNEL].end = end;
 	}
+	start = -1;
+	end = 0;
+	env = getenv("rootfs_st");
+	if (env != NULL)
+		start = simple_strtoul(env, NULL, 16);
+	env = getenv("rootfs_nd");
+	if (env != NULL)
+		end = simple_strtoul(env, NULL, 16);
+	if (start >= 0 && end && end > start) {
+		ausize[IDX_ROOTFS] = (end + 1) - start;
+		aufl_layout[IDX_ROOTFS].start = start;
+		aufl_layout[IDX_ROOTFS].end = end;
+	}
+
 	/* make certain that HUSH is runnable */
 	u_boot_hush_start();
 	/* make sure that we see CTRL-C and save the old state */
 	old_ctrlc = disable_ctrlc(0);
 
 	bitmap_first = 0;
-	/* just loop thru all the possible files */
+
+	/* validate the images first */
 	for (i = 0; i < AU_MAXFILES; i++) {
+		ulong imsize;
 		/* just read the header */
 		sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
 		debug ("read %s sz %ld hdr %d\n",
 			aufile[i], sz, sizeof(image_header_t));
 		if (sz <= 0 || sz < sizeof(image_header_t)) {
 			debug ("%s not found\n", aufile[i]);
+			ausize[i] = 0;
 			continue;
 		}
-		if (au_check_header_valid(i, sz) < 0) {
+		/* au_check_header_valid() updates ausize[] */
+		if ((imsize = au_check_header_valid(i, sz)) < 0) {
 			debug ("%s header not valid\n", aufile[i]);
 			continue;
 		}
-		sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ);
+		/* totsize accounts for image size and flash erase size */
+		totsize += (imsize + (aufl_layout[i].end - aufl_layout[i].start));
+	}
+
+#ifdef CONFIG_PROGRESSBAR
+	if (totsize) {
+		lcd_puts(" Update in progress\n");
+		lcd_enable();
+	}
+#endif
+
+	/* just loop thru all the possible files */
+	for (i = 0; i < AU_MAXFILES && totsize; i++) {
+		if (!ausize[i]) {
+			continue;
+		}
+		sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);
+
 		debug ("read %s sz %ld hdr %d\n",
 			aufile[i], sz, sizeof(image_header_t));
+
+		if (sz != ausize[i]) {
+			printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz);
+			continue;
+		}
+
 		if (sz <= 0 || sz <= sizeof(image_header_t)) {
 			debug ("%s not found\n", aufile[i]);
 			continue;
@@ -443,8 +498,8 @@
 			}
 			cnt++;
 #ifdef AU_TEST_ONLY
-		} while (res < 0 && cnt < 3);
-		if (cnt < 3)
+		} while (res < 0 && cnt < (AU_MAXFILES + 1));
+		if (cnt < (AU_MAXFILES + 1))
 #else
 		} while (res < 0);
 #endif
@@ -452,6 +507,16 @@
 	usb_stop();
 	/* restore the old state */
 	disable_ctrlc(old_ctrlc);
+#ifdef CONFIG_PROGRESSBAR
+	if (totsize) {
+		if (!res) {
+			lcd_puts("\n  Update completed\n");
+		} else {
+			lcd_puts("\n   Update error\n");
+		}
+		lcd_enable();
+	}
+#endif
 	return 0;
 }
 #endif /* CONFIG_AUTO_UPDATE */
diff --git a/board/mcc200/lcd.c b/board/mcc200/lcd.c
index b262516..98b86d1 100644
--- a/board/mcc200/lcd.c
+++ b/board/mcc200/lcd.c
@@ -24,13 +24,13 @@
 
 #ifdef CONFIG_LCD
 
-#define SWAPPED_LCD
+#undef SWAPPED_LCD /* For the previous h/w version */
 /*
  *  The name of the device used for communication
  * with the PSoC.
  */
 #define PSOC_PSC	MPC5XXX_PSC2
-#define PSOC_BAUD	500000UL
+#define PSOC_BAUD	230400UL
 
 #define RTS_ASSERT	1
 #define RTS_NEGATE	0
@@ -181,10 +181,35 @@
 		udelay (PSOC_WAIT_TIME);
 	}
 	if (!retries) {
-		printf ("%s Error: PSoC doesn't respond on "
+		printf ("%s Warning: PSoC doesn't respond on "
 			"RTS NEGATE\n",	__FUNCTION__);
 	}
 
 	return;
 }
+#ifdef CONFIG_PROGRESSBAR
+
+#define FONT_WIDTH      8 /* the same as VIDEO_FONT_WIDTH in video_font.h */
+void show_progress (int size, int tot)
+{
+	int cnt;
+	int i;
+	static int rc = 0;
+
+	rc += size;
+
+	cnt = ((LCD_WIDTH/FONT_WIDTH) * rc) / tot;
+
+	rc -= (cnt * tot) / (LCD_WIDTH/FONT_WIDTH);
+
+	for (i = 0; i < cnt; i++) {
+		lcd_putc(0xdc);
+	}
+
+	if (cnt) {
+		lcd_enable(); /* MCC200-specific - send the framebuffer to PSoC */
+	}
+}
+
+#endif
 #endif /* CONFIG_LCD */
diff --git a/board/motionpro/Makefile b/board/motionpro/Makefile
new file mode 100644
index 0000000..698ead1
--- /dev/null
+++ b/board/motionpro/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2003-2007
+# 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	= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/motionpro/config.mk b/board/motionpro/config.mk
new file mode 100644
index 0000000..e7934d2
--- /dev/null
+++ b/board/motionpro/config.mk
@@ -0,0 +1,30 @@
+#
+# (C) Copyright 2006-2007
+# 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
+#
+
+#
+# Promess Motion-PRO
+#
+
+TEXT_BASE = 0xfff00000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/motionpro/motionpro.c b/board/motionpro/motionpro.c
new file mode 100644
index 0000000..d60d233
--- /dev/null
+++ b/board/motionpro/motionpro.c
@@ -0,0 +1,172 @@
+/*
+ * (C) Copyright 2003-2007
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * modified for Promess PRO - by Andy Joseph, andy@promessdev.com
+ * modified for Promess PRO-Motion - by Robert McCullough, rob@promessdev.com
+ * modified by Chris M. Tumas 6/20/06 Change CAS latency to 2 from 3
+ * Also changed the refresh for 100Mhz operation
+ *
+ * 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 <mpc5xxx.h>
+
+
+/* Kollmorgen DPR initialization data */
+struct init_elem {
+	unsigned long addr;
+	unsigned len;
+	char *data;
+	} init_seq[] = {
+		{0x500003F2, 2, "\x86\x00"},		/* HW parameter */
+		{0x500003F0, 2, "\x00\x00"},
+		{0x500003EC, 4, "\x00\x80\xc1\x52"},	/* Magic word */
+	};
+
+/*
+ * Initialize Kollmorgen DPR
+ */
+static void kollmorgen_init(void)
+{
+	unsigned i, j;
+	vu_char *p;
+
+	for (i = 0; i < sizeof(init_seq) / sizeof(struct init_elem); ++i) {
+		p = (vu_char *)init_seq[i].addr;
+		for (j = 0; j < init_seq[i].len; ++j)
+			*(p + j) = *(init_seq[i].data + j);
+	}
+
+	printf("DPR:   Kollmorgen DPR initialized\n");
+}
+
+
+/*
+ * Early board initalization.
+ */
+int board_early_init_r(void)
+{
+	/* Now, when we are in RAM, disable Boot Chipselect and enable CS0 */
+	*(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25);
+	*(vu_long *)MPC5XXX_ADDECR |= (1 << 16);
+
+	/* Initialize Kollmorgen DPR */
+	kollmorgen_init();
+
+	return 0;
+}
+
+
+#ifndef CFG_RAMBOOT
+/*
+ * Helper function to initialize SDRAM controller.
+ */
+static void sdram_start (int hi_addr)
+{
+	long hi_addr_bit = hi_addr ? 0x01000000 : 0;
+
+	/* unlock mode register */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 |
+						hi_addr_bit;
+
+	/* precharge all banks */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
+						hi_addr_bit;
+
+	/* auto refresh */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
+						hi_addr_bit;
+
+	/* auto refresh, second time */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
+						hi_addr_bit;
+
+	/* set mode register */
+	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
+
+	/* normal operation */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
+}
+#endif /* !CFG_RAMBOOT */
+
+
+/*
+ * Initalize SDRAM - configure SDRAM controller, detect memory size.
+ */
+long int initdram (int board_type)
+{
+	ulong dramsize = 0;
+#ifndef CFG_RAMBOOT
+	ulong test1, test2;
+
+	/* configure SDRAM start/end for detection */
+	*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */
+	*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */
+
+	/* setup config registers */
+	*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
+	*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
+
+	sdram_start(0);
+	test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
+	sdram_start(1);
+	test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
+	if (test1 > test2) {
+		sdram_start(0);
+		dramsize = test1;
+	} else {
+		dramsize = test2;
+	}
+
+	/* memory smaller than 1MB is impossible */
+	if (dramsize < (1 << 20))
+		dramsize = 0;
+
+	/* set SDRAM CS0 size according to the amount of RAM found */
+	if (dramsize > 0) {
+		*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 +
+			__builtin_ffs(dramsize >> 20) - 1;
+	} else {
+		*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
+	}
+
+	/* let SDRAM CS1 start right after CS0 and disable it */
+	*(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize;
+
+#else /* !CFG_RAMBOOT */
+	/* retrieve size of memory connected to SDRAM CS0 */
+	dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
+	if (dramsize >= 0x13)
+		dramsize = (1 << (dramsize - 0x13)) << 20;
+	else
+		dramsize = 0;
+#endif /* CFG_RAMBOOT */
+
+	/* return total ram size */
+	return dramsize;
+}
+
+
+int checkboard (void)
+{
+	puts("Board: Promess Motion-PRO board\n");
+	return 0;
+}
diff --git a/board/motionpro/u-boot.lds b/board/motionpro/u-boot.lds
new file mode 100644
index 0000000..8fa9c0f
--- /dev/null
+++ b/board/motionpro/u-boot.lds
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2003-2007
+ * 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/mpc5xxx/start.o	(.text)
+    *(.text)
+    *(.fixup)
+    *(.got1)
+    . = ALIGN(16);
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+    *(.eh_frame)
+  }
+  .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 = .);
+
+  . = .;
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  . = .;
+  __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/mpl/common/memtst.c b/board/mpl/common/memtst.c
index ff1190a..1d28513 100644
--- a/board/mpl/common/memtst.c
+++ b/board/mpl/common/memtst.c
@@ -48,7 +48,7 @@
 
 #include <common.h>
 #include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/mpl/mip405/mip405.c b/board/mpl/mip405/mip405.c
index 34f3289..4b1c1c0 100644
--- a/board/mpl/mip405/mip405.c
+++ b/board/mpl/mip405/mip405.c
@@ -65,7 +65,7 @@
 #include <common.h>
 #include "mip405.h"
 #include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
 #include <miiphy.h>
 #include "../common/common_util.h"
 #include <i2c.h>
@@ -73,9 +73,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-extern block_dev_desc_t * scsi_get_dev(int dev);
-extern block_dev_desc_t * ide_get_dev(int dev);
-
 #undef SDRAM_DEBUG
 #define ENABLE_ECC /* for ecc boards */
 #define FALSE           0
diff --git a/board/prodrive/p3mx/p3mx.h b/board/prodrive/p3mx/p3mx.h
new file mode 100644
index 0000000..1caae6b
--- /dev/null
+++ b/board/prodrive/p3mx/p3mx.h
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2005
+ *
+ * Roel Loeffen, (C) Copyright 2006 Prodrive B.V. roel.loeffen@prodrive.nl
+ *
+ * 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 __P3MX_H__
+#define __P3MX_H__
+
+#define LED_OFF		1
+#define LED_GREEN	2
+#define LED_RED		3
+#define LED_ORANGE	4
+
+#endif /* __P3MX_H__ */
diff --git a/board/sandburst/common/ppc440gx_i2c.c b/board/sandburst/common/ppc440gx_i2c.c
index 859dd7a..1e3dffb 100644
--- a/board/sandburst/common/ppc440gx_i2c.c
+++ b/board/sandburst/common/ppc440gx_i2c.c
@@ -27,13 +27,8 @@
  */
 #include <common.h>
 #include <ppc4xx.h>
-#if defined(CONFIG_440)
-#   include <440_i2c.h>
-#else
-#   include <405gp_i2c.h>
-#endif
+#include <4xx_i2c.h>
 #include <i2c.h>
-#include <440_i2c.h>
 #include <command.h>
 #include "ppc440gx_i2c.h"
 
diff --git a/board/sandburst/common/ppc440gx_i2c.h b/board/sandburst/common/ppc440gx_i2c.h
index cd4fc86..10000f5 100644
--- a/board/sandburst/common/ppc440gx_i2c.h
+++ b/board/sandburst/common/ppc440gx_i2c.h
@@ -27,11 +27,7 @@
  */
 #include <common.h>
 #include <ppc4xx.h>
-#if defined(CONFIG_440)
-#   include <440_i2c.h>
-#else
-#   include <405gp_i2c.h>
-#endif
+#include <4xx_i2c.h>
 #include <i2c.h>
 
 #ifdef CONFIG_HARD_I2C
diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c
index d2c8d44..f4074ae 100644
--- a/board/trab/auto_update.c
+++ b/board/trab/auto_update.c
@@ -203,7 +203,6 @@
 /* change char* to void* to shutup the compiler */
 extern int i2c_write_multiple (uchar, uint, int, void *, int);
 extern int i2c_read_multiple (uchar, uint, int, void *, int);
-extern block_dev_desc_t *get_dev (char*, int);
 extern int u_boot_hush_start(void);
 
 int
diff --git a/board/uc101/uc101.c b/board/uc101/uc101.c
index b803585..7a6b3be 100644
--- a/board/uc101/uc101.c
+++ b/board/uc101/uc101.c
@@ -170,9 +170,9 @@
 
 	/* find RAM size using SDRAM CS0 only */
 	sdram_start(0);
-	test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
+	test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
 	sdram_start(1);
-	test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
+	test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
 	if (test1 > test2) {
 		sdram_start(0);
 		dramsize = test1;
@@ -266,7 +266,7 @@
 	return kbd_data;
 }
 
-static int compare_magic (const struct kbd_data_t *kbd_data, uchar *str)
+static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
 {
 	char s1 = str[0];
 
@@ -283,11 +283,11 @@
 	return 0;
 }
 
-static uchar *key_match (const struct kbd_data_t *kbd_data)
+static char *key_match (const struct kbd_data_t *kbd_data)
 {
-	uchar magic[sizeof (kbd_magic_prefix) + 1];
-	uchar *suffix;
-	uchar *kbd_magic_keys;
+	char magic[sizeof (kbd_magic_prefix) + 1];
+	char *suffix;
+	char *kbd_magic_keys;
 
 	/*
 	 * The following string defines the characters that can be appended
@@ -308,7 +308,7 @@
 		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
 
 		if (compare_magic(kbd_data, getenv(magic)) == 0) {
-			uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+			char cmd_name[sizeof (kbd_command_prefix) + 1];
 			char *cmd;
 
 			sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
@@ -331,7 +331,7 @@
 #ifdef CONFIG_PREBOOT
 	struct kbd_data_t kbd_data;
 	/* Decode keys */
-	uchar *str = strdup (key_match (get_keys (&kbd_data)));
+	char *str = strdup (key_match (get_keys (&kbd_data)));
 	/* Set or delete definition */
 	setenv ("preboot", str);
 	free (str);
diff --git a/board/xilinx/ml300/Makefile b/board/xilinx/ml300/Makefile
index 02c22fb..05ad235 100644
--- a/board/xilinx/ml300/Makefile
+++ b/board/xilinx/ml300/Makefile
@@ -28,7 +28,7 @@
 $(shell mkdir -p $(obj)../xilinx_iic)
 endif
 
-INCS		:= -I../ml300 -I../common -I../xilinx_enet -I../xilinx_iic
+INCS		:= -I../common -I../xilinx_enet -I../xilinx_iic
 CFLAGS		+= $(INCS)
 HOST_CFLAGS	+= $(INCS)
 
diff --git a/board/xilinx/ml300/ml300.c b/board/xilinx/ml300/ml300.c
index dad562f..60f0bc2 100644
--- a/board/xilinx/ml300/ml300.c
+++ b/board/xilinx/ml300/ml300.c
@@ -38,9 +38,9 @@
  *
  */
 
+#include <config.h>
 #include <common.h>
 #include <asm/processor.h>
-#include "xparameters.h"
 
 #ifdef CFG_ENV_IS_IN_EEPROM
 extern void convert_env(void);
diff --git a/board/xilinx/ml300/serial.c b/board/xilinx/ml300/serial.c
index c204b88..9b03f89 100644
--- a/board/xilinx/ml300/serial.c
+++ b/board/xilinx/ml300/serial.c
@@ -40,8 +40,7 @@
 #include <asm/processor.h>
 #include <common.h>
 #include <command.h>
-#include <configs/ml300.h>
-#include "xparameters.h"
+#include <config.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c
index b30e897..f159cb6 100644
--- a/board/xilinx/xilinx_enet/emac_adapter.c
+++ b/board/xilinx/xilinx_enet/emac_adapter.c
@@ -37,9 +37,9 @@
 *
 ******************************************************************************/
 
+#include <config.h>
 #include <common.h>
 #include <net.h>
-#include "xparameters.h"
 #include "xemac.h"
 
 #if defined(XPAR_EMAC_0_DEVICE_ID)
diff --git a/board/xilinx/xilinx_enet/xemac.h b/board/xilinx/xilinx_enet/xemac.h
index ed704bf..584cb7a 100644
--- a/board/xilinx/xilinx_enet/xemac.h
+++ b/board/xilinx/xilinx_enet/xemac.h
@@ -257,9 +257,9 @@
 
 /***************************** Include Files *********************************/
 
+#include <config.h>
 #include "xbasic_types.h"
 #include "xstatus.h"
-#include "xparameters.h"
 #include "xpacket_fifo_v1_00_b.h"	/* Uses v1.00b of Packet Fifo */
 #include "xdma_channel.h"
 
diff --git a/board/xilinx/xilinx_enet/xemac_g.c b/board/xilinx/xilinx_enet/xemac_g.c
index 9340f91..d985157 100644
--- a/board/xilinx/xilinx_enet/xemac_g.c
+++ b/board/xilinx/xilinx_enet/xemac_g.c
@@ -43,7 +43,7 @@
 *
 *******************************************************************/
 
-#include "xparameters.h"
+#include <config.h>
 #include "xemac.h"
 
 /*
diff --git a/board/xilinx/xilinx_iic/iic_adapter.c b/board/xilinx/xilinx_iic/iic_adapter.c
index 163fe15..37dce03 100644
--- a/board/xilinx/xilinx_iic/iic_adapter.c
+++ b/board/xilinx/xilinx_iic/iic_adapter.c
@@ -37,10 +37,10 @@
 *
 ******************************************************************************/
 
+#include <config.h>
 #include <common.h>
 #include <environment.h>
 #include <net.h>
-#include "xparameters.h"
 
 #ifdef CFG_ENV_IS_IN_EEPROM
 #include <i2c.h>
diff --git a/common/Makefile b/common/Makefile
index 0106088..6f81c4a 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -27,8 +27,7 @@
 
 AOBJS	=
 
-COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o \
-	  cmd_ace.o cmd_autoscript.o \
+COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \
 	  cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
 	  cmd_cache.o cmd_console.o \
 	  cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
diff --git a/common/cmd_ace.c b/common/cmd_ace.c
deleted file mode 100644
index b6d6105..0000000
--- a/common/cmd_ace.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 2004 Picture Elements, Inc.
- *    Stephen Williams (XXXXXXXXXXXXXXXX)
- *
- *    This source code is free software; you can redistribute it
- *    and/or modify it in source code form 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
- */
-#ident "$Id:$"
-
-/*
- * The Xilinx SystemACE chip support is activated by defining
- * CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE
- * to set the base address of the device. This code currently
- * assumes that the chip is connected via a byte-wide bus.
- *
- * The CONFIG_SYSTEMACE also adds to fat support the device class
- * "ace" that allows the user to execute "fatls ace 0" and the
- * like. This works by making the systemace_get_dev function
- * available to cmd_fat.c:get_dev and filling in a block device
- * description that has all the bits needed for FAT support to
- * read sectors.
- *
- * According to Xilinx technical support, before accessing the
- * SystemACE CF you need to set the following control bits:
- * 	FORCECFGMODE : 1
- * 	CFGMODE : 0
- * 	CFGSTART : 0
- */
-
-# include  <common.h>
-# include  <command.h>
-# include  <systemace.h>
-# include  <part.h>
-# include  <asm/io.h>
-
-#ifdef CONFIG_SYSTEMACE
-
-/*
- * The ace_readw and writew functions read/write 16bit words, but the
- * offset value is the BYTE offset as most used in the Xilinx
- * datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined
- * to be the base address for the chip, usually in the local
- * peripheral bus.
- */
-static unsigned ace_readw(unsigned offset)
-{
-#if (CFG_SYSTEMACE_WIDTH == 8)
-  u16 temp;
-
-#if !defined(__BIG_ENDIAN)
-  temp =((u16)readb(CFG_SYSTEMACE_BASE+offset) << 8);
-  temp |= (u16)readb(CFG_SYSTEMACE_BASE+offset+1);
-#else
-  temp = (u16)readb(CFG_SYSTEMACE_BASE+offset);
-  temp |=((u16)readb(CFG_SYSTEMACE_BASE+offset+1) << 8);
-#endif
-  return temp;
-#else
-  return readw(CFG_SYSTEMACE_BASE+offset);
-#endif
-}
-
-static void ace_writew(unsigned val, unsigned offset)
-{
-#if (CFG_SYSTEMACE_WIDTH == 8)
-#if !defined(__BIG_ENDIAN)
-  writeb((u8)(val>>8), CFG_SYSTEMACE_BASE+offset);
-  writeb((u8)val, CFG_SYSTEMACE_BASE+offset+1);
-#else
-  writeb((u8)val, CFG_SYSTEMACE_BASE+offset);
-  writeb((u8)(val>>8), CFG_SYSTEMACE_BASE+offset+1);
-#endif
-#else
-  writew(val, CFG_SYSTEMACE_BASE+offset);
-#endif
-}
-
-/* */
-
-static unsigned long systemace_read(int dev,
-				    unsigned long start,
-				    unsigned long blkcnt,
-				    unsigned long *buffer);
-
-static block_dev_desc_t systemace_dev = {0};
-
-static int get_cf_lock(void)
-{
-      int retry = 10;
-
-	/* CONTROLREG = LOCKREG */
-      unsigned val=ace_readw(0x18);
-      val|=0x0002;
-      ace_writew((val&0xffff), 0x18);
-
-	/* Wait for MPULOCK in STATUSREG[15:0] */
-      while (! (ace_readw(0x04) & 0x0002)) {
-
-	    if (retry < 0)
-		  return -1;
-
-	    udelay(100000);
-	    retry -= 1;
-      }
-
-      return 0;
-}
-
-static void release_cf_lock(void)
-{
-	unsigned val=ace_readw(0x18);
-	val&=~(0x0002);
-	ace_writew((val&0xffff), 0x18);
-}
-
-block_dev_desc_t *  systemace_get_dev(int dev)
-{
-	/* The first time through this, the systemace_dev object is
-	   not yet initialized. In that case, fill it in. */
-      if (systemace_dev.blksz == 0) {
-	    systemace_dev.if_type   = IF_TYPE_UNKNOWN;
-	    systemace_dev.dev	    = 0;
-	    systemace_dev.part_type = PART_TYPE_UNKNOWN;
-	    systemace_dev.type      = DEV_TYPE_HARDDISK;
-	    systemace_dev.blksz     = 512;
-	    systemace_dev.removable = 1;
-	    systemace_dev.block_read = systemace_read;
-
-	    init_part(&systemace_dev);
-
-      }
-
-      return &systemace_dev;
-}
-
-/*
- * This function is called (by dereferencing the block_read pointer in
- * the dev_desc) to read blocks of data. The return value is the
- * number of blocks read. A zero return indicates an error.
- */
-static unsigned long systemace_read(int dev,
-				    unsigned long start,
-				    unsigned long blkcnt,
-				    unsigned long *buffer)
-{
-      int retry;
-      unsigned blk_countdown;
-      unsigned char*dp = (unsigned char*)buffer;
-      unsigned val;
-
-      if (get_cf_lock() < 0) {
-	    unsigned status = ace_readw(0x04);
-
-	      /* If CFDETECT is false, card is missing. */
-	    if (! (status&0x0010)) {
-		  printf("** CompactFlash card not present. **\n");
-		  return 0;
-	    }
-
-	    printf("**** ACE locked away from me (STATUSREG=%04x)\n", status);
-	    return 0;
-      }
-
-#ifdef DEBUG_SYSTEMACE
-      printf("... systemace read %lu sectors at %lu\n", blkcnt, start);
-#endif
-
-      retry = 2000;
-      for (;;) {
-	    val = ace_readw(0x04);
-
-	      /* If CFDETECT is false, card is missing. */
-	    if (! (val & 0x0010)) {
-		  printf("**** ACE CompactFlash not found.\n");
-		  release_cf_lock();
-		  return 0;
-	    }
-
-	      /* If RDYFORCMD, then we are ready to go. */
-	    if (val & 0x0100)
-		  break;
-
-	    if (retry < 0) {
-		  printf("**** SystemACE not ready.\n");
-		  release_cf_lock();
-		  return 0;
-	    }
-
-	    udelay(1000);
-	    retry -= 1;
-      }
-
-	/* The SystemACE can only transfer 256 sectors at a time, so
-	   limit the current chunk of sectors. The blk_countdown
-	   variable is the number of sectors left to transfer. */
-
-      blk_countdown = blkcnt;
-      while (blk_countdown > 0) {
-	    unsigned trans = blk_countdown;
-
-	    if (trans > 256) trans = 256;
-
-#ifdef DEBUG_SYSTEMACE
-	    printf("... transfer %lu sector in a chunk\n", trans);
-#endif
-	      /* Write LBA block address */
-	    ace_writew((start>> 0) & 0xffff, 0x10);
-	    ace_writew((start>>16) & 0x00ff, 0x12);
-
-	      /* NOTE: in the Write Sector count below, a count of 0
-		 causes a transfer of 256, so &0xff gives the right
-		 value for whatever transfer count we want. */
-
-	      /* Write sector count | ReadMemCardData. */
-	    ace_writew((trans&0xff) | 0x0300, 0x14);
-
-	    /* Reset the configruation controller */
-	    val = ace_readw(0x18);
-	    val|=0x0080;
-	    ace_writew(val, 0x18);
-
-	    retry = trans * 16;
-	    while (retry > 0) {
-		  int idx;
-
-		    /* Wait for buffer to become ready. */
-		  while (! (ace_readw(0x04) & 0x0020)) {
-			udelay(100);
-		  }
-
-		    /* Read 16 words of 2bytes from the sector buffer. */
-		  for (idx = 0 ;  idx < 16 ;  idx += 1) {
-			unsigned short val = ace_readw(0x40);
-			*dp++ = val & 0xff;
-			*dp++ = (val>>8) & 0xff;
-		  }
-
-		  retry -= 1;
-	    }
-
-	    /* Clear the configruation controller reset */
-	    val = ace_readw(0x18);
-	    val&=~0x0080;
-	    ace_writew(val, 0x18);
-
-	      /* Count the blocks we transfer this time. */
-	    start += trans;
-	    blk_countdown -= trans;
-      }
-
-      release_cf_lock();
-
-      return blkcnt;
-}
-#endif	/* CONFIG_SYSTEMACE */
diff --git a/common/cmd_date.c b/common/cmd_date.c
index 84932f7..33d2e56 100644
--- a/common/cmd_date.c
+++ b/common/cmd_date.c
@@ -27,6 +27,7 @@
 #include <common.h>
 #include <command.h>
 #include <rtc.h>
+#include <i2c.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -44,6 +45,11 @@
 {
 	struct rtc_time tm;
 	int rcode = 0;
+	int old_bus;
+
+	/* switch to correct I2C bus */
+	old_bus = I2C_GET_BUS();
+	I2C_SET_BUS(CFG_RTC_BUS_NUM);
 
 	switch (argc) {
 	case 2:			/* set date & time */
@@ -56,7 +62,7 @@
 			/* insert new date & time */
 			if (mk_date (argv[1], &tm) != 0) {
 				puts ("## Bad date format\n");
-				return 1;
+				break;
 			}
 			/* and write to RTC */
 			rtc_set (&tm);
@@ -71,11 +77,15 @@
 				"unknown " : RELOC(weekdays[tm.tm_wday]),
 			tm.tm_hour, tm.tm_min, tm.tm_sec);
 
-		return 0;
+		break;
 	default:
 		printf ("Usage:\n%s\n", cmdtp->usage);
 		rcode = 1;
 	}
+
+	/* switch back to original I2C bus */
+	I2C_SET_BUS(old_bus);
+
 	return rcode;
 }
 
diff --git a/common/cmd_dtt.c b/common/cmd_dtt.c
index 9db64e9..4f7b049 100644
--- a/common/cmd_dtt.c
+++ b/common/cmd_dtt.c
@@ -28,19 +28,27 @@
 #if (CONFIG_COMMANDS & CFG_CMD_DTT)
 
 #include <dtt.h>
+#include <i2c.h>
 
 int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
 	int i;
 	unsigned char sensors[] = CONFIG_DTT_SENSORS;
+	int old_bus;
+
+	/* switch to correct I2C bus */
+	old_bus = I2C_GET_BUS();
+	I2C_SET_BUS(CFG_DTT_BUS_NUM);
 
 	/*
 	 * Loop through sensors, read
 	 * temperature, and output it.
 	 */
-	for (i = 0; i < sizeof (sensors); i++) {
+	for (i = 0; i < sizeof (sensors); i++)
 		printf ("DTT%d: %i C\n", i + 1, dtt_get_temp (sensors[i]));
-	}
+
+	/* switch back to original I2C bus */
+	I2C_SET_BUS(old_bus);
 
 	return 0;
 }	/* do_dtt() */
diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c
index 5db42f2..94bd9b6 100644
--- a/common/cmd_ext2.c
+++ b/common/cmd_ext2.c
@@ -33,6 +33,7 @@
  * Ext2fs support
  */
 #include <common.h>
+#include <part.h>
 
 #if (CONFIG_COMMANDS & CFG_CMD_EXT2)
 #include <config.h>
@@ -57,41 +58,6 @@
 #define PRINTF(fmt,args...)
 #endif
 
-static block_dev_desc_t *get_dev (char* ifname, int dev)
-{
-#if (CONFIG_COMMANDS & CFG_CMD_IDE)
-	if (strncmp(ifname,"ide",3)==0) {
-		extern block_dev_desc_t * ide_get_dev(int dev);
-		return((dev >= CFG_IDE_MAXDEVICE) ? NULL : ide_get_dev(dev));
-	}
-#endif
-#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
-	if (strncmp(ifname,"scsi",4)==0) {
-		extern block_dev_desc_t * scsi_get_dev(int dev);
-		return((dev >= CFG_SCSI_MAXDEVICE) ? NULL : scsi_get_dev(dev));
-	}
-#endif
-#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
-	if (strncmp(ifname,"usb",3)==0) {
-		extern block_dev_desc_t * usb_stor_get_dev(int dev);
-		return((dev >= USB_MAX_STOR_DEV) ? NULL : usb_stor_get_dev(dev));
-	}
-#endif
-#if defined(CONFIG_MMC)
-	if (strncmp(ifname,"mmc",3)==0) {
-		extern block_dev_desc_t *  mmc_get_dev(int dev);
-		return((dev >= 1) ? NULL : mmc_get_dev(dev));
-	}
-#endif
-#if defined(CONFIG_SYSTEMACE)
-	if (strcmp(ifname,"ace")==0) {
-		extern block_dev_desc_t *  systemace_get_dev(int dev);
-		return((dev >= 1) ? NULL : systemace_get_dev(dev));
-	}
-#endif
-	return(NULL);
-}
-
 int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	char *filename = "/";
@@ -106,7 +72,7 @@
 		return(1);
 	}
 	dev = (int)simple_strtoul (argv[2], &ep, 16);
-	dev_desc=get_dev(argv[1],dev);
+	dev_desc = get_dev(argv[1],dev);
 
 	if (dev_desc == NULL) {
 		printf ("\n** Block device %s %d not supported\n", argv[1], dev);
@@ -210,7 +176,7 @@
 	}
 
 	dev = (int)simple_strtoul (argv[2], &ep, 16);
-	dev_desc=get_dev(argv[1],dev);
+	dev_desc = get_dev(argv[1],dev);
 	if (dev_desc==NULL) {
 		printf ("\n** Block device %s %d not supported\n", argv[1], dev);
 		return(1);
diff --git a/common/cmd_fat.c b/common/cmd_fat.c
index 6844c10..afaf299 100644
--- a/common/cmd_fat.c
+++ b/common/cmd_fat.c
@@ -29,6 +29,7 @@
 #include <s_record.h>
 #include <net.h>
 #include <ata.h>
+#include <part.h>
 
 #if (CONFIG_COMMANDS & CFG_CMD_FAT)
 
@@ -37,42 +38,6 @@
 #include <fat.h>
 
 
-block_dev_desc_t *get_dev (char* ifname, int dev)
-{
-#if (CONFIG_COMMANDS & CFG_CMD_IDE)
-	if (strncmp(ifname,"ide",3)==0) {
-		extern block_dev_desc_t * ide_get_dev(int dev);
-		return(ide_get_dev(dev));
-	}
-#endif
-#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
-	if (strncmp(ifname,"scsi",4)==0) {
-		extern block_dev_desc_t * scsi_get_dev(int dev);
-		return(scsi_get_dev(dev));
-	}
-#endif
-#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
-	if (strncmp(ifname,"usb",3)==0) {
-		extern block_dev_desc_t * usb_stor_get_dev(int dev);
-		return(usb_stor_get_dev(dev));
-	}
-#endif
-#if defined(CONFIG_MMC)
-	if (strncmp(ifname,"mmc",3)==0) {
-		extern block_dev_desc_t *  mmc_get_dev(int dev);
-		return(mmc_get_dev(dev));
-	}
-#endif
-#if defined(CONFIG_SYSTEMACE)
-	if (strcmp(ifname,"ace")==0) {
-		extern block_dev_desc_t *  systemace_get_dev(int dev);
-		return(systemace_get_dev(dev));
-	}
-#endif
-	return NULL;
-}
-
-
 int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	long size;
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index a415502..2e185cc 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -31,20 +31,26 @@
 #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
+
 #ifdef CONFIG_MPC5xxx
 #include <mpc5xxx.h>
 #endif
+
 #include <ide.h>
 #include <ata.h>
+
 #ifdef CONFIG_STATUS_LED
 # include <status_led.h>
 #endif
+
 #ifndef __PPC__
 #include <asm/io.h>
 #ifdef __MIPS__
@@ -182,7 +188,7 @@
 
 #ifdef CONFIG_ATAPI
 static void	atapi_inquiry(block_dev_desc_t *dev_desc);
-ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer);
+ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer);
 #endif
 
 
@@ -697,7 +703,7 @@
 
 block_dev_desc_t * ide_get_dev(int dev)
 {
-	return ((block_dev_desc_t *)&ide_dev_desc[dev]);
+	return (dev < CFG_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL;
 }
 
 
@@ -1227,7 +1233,7 @@
 
 /* ------------------------------------------------------------------------- */
 
-ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
+ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer)
 {
 	ulong n = 0;
 	unsigned char c;
@@ -1347,7 +1353,7 @@
 /* ------------------------------------------------------------------------- */
 
 
-ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
+ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, void *buffer)
 {
 	ulong n = 0;
 	unsigned char c;
@@ -2009,7 +2015,7 @@
 #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, lbaint_t blknr, ulong blkcnt, ulong *buffer)
+ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer)
 {
 	ulong n = 0;
 	unsigned char ccb[12]; /* Command descriptor block */
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index d0fae6b..fcbb023 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -92,8 +92,9 @@
 int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	ulong	addr, length;
-	ulong	i, nbytes, linebytes;
-	u_char	*cp;
+#if defined(CONFIG_HAS_DATAFLASH)
+	ulong	nbytes, linebytes;
+#endif
 	int	size;
 	int rc = 0;
 
@@ -128,6 +129,7 @@
 			length = simple_strtoul(argv[2], NULL, 16);
 	}
 
+#if defined(CONFIG_HAS_DATAFLASH)
 	/* Print the lines.
 	 *
 	 * We buffer all read data, so we can make sure data is read only
@@ -136,64 +138,25 @@
 	nbytes = length * size;
 	do {
 		char	linebuf[DISP_LINE_LEN];
-		uint	*uip = (uint   *)linebuf;
-		ushort	*usp = (ushort *)linebuf;
-		u_char	*ucp = (u_char *)linebuf;
-#ifdef CONFIG_HAS_DATAFLASH
-		int rc;
-#endif
-		printf("%08lx:", addr);
+		void* p;
 		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
 
-#ifdef CONFIG_HAS_DATAFLASH
-		if ((rc = read_dataflash(addr, (linebytes/size)*size, linebuf)) == DATAFLASH_OK){
-			/* if outside dataflash */
-			/*if (rc != 1) {
-				dataflash_perror (rc);
-				return (1);
-			}*/
-			for (i=0; i<linebytes; i+= size) {
-				if (size == 4) {
-					printf(" %08x", *uip++);
-				} else if (size == 2) {
-					printf(" %04x", *usp++);
-				} else {
-					printf(" %02x", *ucp++);
-				}
-				addr += size;
-			}
+		rc = read_dataflash(addr, (linebytes/size)*size, linebuf);
+		p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr;
+		print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
 
-		} else {	/* addr does not correspond to DataFlash */
-#endif
-		for (i=0; i<linebytes; i+= size) {
-			if (size == 4) {
-				printf(" %08x", (*uip++ = *((uint *)addr)));
-			} else if (size == 2) {
-				printf(" %04x", (*usp++ = *((ushort *)addr)));
-			} else {
-				printf(" %02x", (*ucp++ = *((u_char *)addr)));
-			}
-			addr += size;
-		}
-#ifdef CONFIG_HAS_DATAFLASH
-		}
-#endif
-		puts ("    ");
-		cp = (u_char *)linebuf;
-		for (i=0; i<linebytes; i++) {
-			if ((*cp < 0x20) || (*cp > 0x7e))
-				putc ('.');
-			else
-				printf("%c", *cp);
-			cp++;
-		}
-		putc ('\n');
 		nbytes -= linebytes;
+		addr += linebytes;
 		if (ctrlc()) {
 			rc = 1;
 			break;
 		}
 	} while (nbytes > 0);
+#else
+	/* Print the lines. */
+	print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size);
+	addr += size*length;
+#endif
 
 	dp_last_addr = addr;
 	dp_last_length = length;
diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c
index 508ffcb..09c86e6 100644
--- a/common/cmd_reiser.c
+++ b/common/cmd_reiser.c
@@ -35,6 +35,7 @@
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
 #include <reiserfs.h>
+#include <part.h>
 
 #ifndef CONFIG_DOS_PARTITION
 #error DOS partition support must be selected
@@ -48,41 +49,6 @@
 #define PRINTF(fmt,args...)
 #endif
 
-static block_dev_desc_t *get_dev (char* ifname, int dev)
-{
-#if (CONFIG_COMMANDS & CFG_CMD_IDE)
-	if (strncmp(ifname,"ide",3)==0) {
-		extern block_dev_desc_t * ide_get_dev(int dev);
-		return((dev >= CFG_IDE_MAXDEVICE) ? NULL : ide_get_dev(dev));
-	}
-#endif
-#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
-	if (strncmp(ifname,"scsi",4)==0) {
-		extern block_dev_desc_t * scsi_get_dev(int dev);
-		return((dev >= CFG_SCSI_MAXDEVICE) ? NULL : scsi_get_dev(dev));
-	}
-#endif
-#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
-	if (strncmp(ifname,"usb",3)==0) {
-		extern block_dev_desc_t * usb_stor_get_dev(int dev);
-		return((dev >= USB_MAX_STOR_DEV) ? NULL : usb_stor_get_dev(dev));
-	}
-#endif
-#if defined(CONFIG_MMC)
-	if (strncmp(ifname,"mmc",3)==0) {
-		extern block_dev_desc_t *  mmc_get_dev(int dev);
-		return((dev >= 1) ? NULL : mmc_get_dev(dev));
-	}
-#endif
-#if defined(CONFIG_SYSTEMACE)
-	if (strcmp(ifname,"ace")==0) {
-		extern block_dev_desc_t *  systemace_get_dev(int dev);
-		return((dev >= 1) ? NULL : systemace_get_dev(dev));
-	}
-#endif
-	return NULL;
-}
-
 int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	char *filename = "/";
@@ -97,7 +63,7 @@
 		return 1;
 	}
 	dev = (int)simple_strtoul (argv[2], &ep, 16);
-	dev_desc=get_dev(argv[1],dev);
+	dev_desc = get_dev(argv[1],dev);
 
 	if (dev_desc == NULL) {
 		printf ("\n** Block device %s %d not supported\n", argv[1], dev);
@@ -196,7 +162,7 @@
 	}
 
 	dev = (int)simple_strtoul (argv[2], &ep, 16);
-	dev_desc=get_dev(argv[1],dev);
+	dev_desc = get_dev(argv[1],dev);
 	if (dev_desc==NULL) {
 		printf ("\n** Block device %s %d not supported\n", argv[1], dev);
 		return 1;
diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c
index cc08743..da36ed9 100644
--- a/common/cmd_scsi.c
+++ b/common/cmd_scsi.c
@@ -74,7 +74,7 @@
 void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
 
 
-ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer);
+ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer);
 
 
 /*********************************************************************************
@@ -194,7 +194,7 @@
 
 block_dev_desc_t * scsi_get_dev(int dev)
 {
-	return((block_dev_desc_t *)&scsi_dev_desc[dev]);
+	return (dev < CFG_SCSI_MAX_DEVICE) ? &scsi_dev_desc[dev] : NULL;
 }
 
 
@@ -424,7 +424,7 @@
 
 #define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */
 
-ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer)
+ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer)
 {
 	ulong start,blks, buf_addr;
 	unsigned short smallblks;
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 28c05aa..904df71 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -28,6 +28,7 @@
 #include <common.h>
 #include <command.h>
 #include <asm/byteorder.h>
+#include <part.h>
 
 #if (CONFIG_COMMANDS & CFG_CMD_USB)
 
diff --git a/common/ft_build.c b/common/ft_build.c
index 980e40f..5a0575e 100644
--- a/common/ft_build.c
+++ b/common/ft_build.c
@@ -29,6 +29,7 @@
 #include <stddef.h>
 
 #include <ft_build.h>
+#include <linux/ctype.h>
 
 #undef DEBUG
 
@@ -180,11 +181,6 @@
 	bph->dt_strings_size = cxt->p_end - cxt->p;
 }
 
-static inline int isprint(int c)
-{
-	return c >= 0x20 && c <= 0x7e;
-}
-
 static int is_printable_string(const void *data, int len)
 {
 	const char *s = data;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 06ea99b..196ceb7 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -56,6 +56,7 @@
 
 
 #if (CONFIG_COMMANDS & CFG_CMD_USB)
+#include <part.h>
 #include <usb.h>
 
 #ifdef CONFIG_USB_STORAGE
@@ -168,13 +169,13 @@
 
 int usb_stor_get_info(struct usb_device *dev, struct us_data *us, block_dev_desc_t *dev_desc);
 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss);
-unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer);
+unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void *buffer);
 struct usb_device * usb_get_dev_index(int index);
 void uhci_show_temp_int_td(void);
 
 block_dev_desc_t *usb_stor_get_dev(int index)
 {
-	return &usb_dev_desc[index];
+	return (index < USB_MAX_STOR_DEV) ? &usb_dev_desc[index] : NULL;
 }
 
 
@@ -940,7 +941,7 @@
 
 #define USB_MAX_READ_BLK 20
 
-unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer)
+unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void *buffer)
 {
 	unsigned long start,blks, buf_addr;
 	unsigned short smallblks;
diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c
index d6ee121..13a3870 100644
--- a/cpu/mpc5xxx/fec.c
+++ b/cpu/mpc5xxx/fec.c
@@ -878,13 +878,13 @@
 	fec->eth = (ethernet_regs *)MPC5XXX_FEC;
 	fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
 	fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
-#if defined(CONFIG_CANMB)   || defined(CONFIG_HMI1001)	|| \
-    defined(CONFIG_ICECUBE) || defined(CONFIG_INKA4X0)	|| \
-    defined(CONFIG_JUPITER) || \
-    defined(CONFIG_MCC200)  || defined(CONFIG_O2DNT)	|| \
-    defined(CONFIG_PM520)   || defined(CONFIG_TOP5200)	|| \
-    defined(CONFIG_TQM5200) || defined(CONFIG_V38B)	|| \
-    defined(CONFIG_UC101)
+#if defined(CONFIG_CANMB)    || defined(CONFIG_HMI1001)	|| \
+    defined(CONFIG_ICECUBE)  || defined(CONFIG_INKA4X0)	|| \
+    defined(CONFIG_JUPITER)  || defined(CONFIG_MCC200)	|| \
+    defined(CONFIG_MOTIONPRO)|| defined(CONFIG_O2DNT)	|| \
+    defined(CONFIG_PM520)    || defined(CONFIG_TOP5200)	|| \
+    defined(CONFIG_TQM5200)  || defined(CONFIG_UC101)	|| \
+    defined(CONFIG_V38B)
 # ifndef CONFIG_FEC_10MBIT
 	fec->xcv_type = MII100;
 # else
diff --git a/cpu/ppc4xx/40x_spd_sdram.c b/cpu/ppc4xx/40x_spd_sdram.c
new file mode 100644
index 0000000..19c4f76
--- /dev/null
+++ b/cpu/ppc4xx/40x_spd_sdram.c
@@ -0,0 +1,469 @@
+/*
+ * cpu/ppc4xx/40x_spd_sdram.c
+ * This SPD SDRAM detection code supports IBM/AMCC PPC44x cpu with a
+ * SDRAM controller. Those are all current 405 PPC's.
+ *
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com
+ *
+ * Based on code by:
+ *
+ * Kenneth Johansson ,Ericsson AB.
+ * kenneth.johansson@etx.ericsson.se
+ *
+ * hacked up by bill hunter. fixed so we could run before
+ * serial_init and console_init. previous version avoided this by
+ * running out of cache memory during serial/console init, then running
+ * this code later.
+ *
+ * (C) Copyright 2002
+ * Jun Gu, Artesyn Technology, jung@artesyncp.com
+ * Support for AMCC 440 based on OpenBIOS draminit.c from IBM.
+ *
+ * (C) Copyright 2005
+ * Stefan Roese, DENX Software Engineering, sr@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 <asm/processor.h>
+#include <i2c.h>
+#include <ppc4xx.h>
+
+#if defined(CONFIG_SPD_EEPROM) && !defined(CONFIG_440)
+
+/*
+ * Set default values
+ */
+#ifndef CFG_I2C_SPEED
+#define CFG_I2C_SPEED	50000
+#endif
+
+#ifndef CFG_I2C_SLAVE
+#define CFG_I2C_SLAVE	0xFE
+#endif
+
+#define ONE_BILLION	1000000000
+
+#define	 SDRAM0_CFG_DCE		0x80000000
+#define	 SDRAM0_CFG_SRE		0x40000000
+#define	 SDRAM0_CFG_PME		0x20000000
+#define	 SDRAM0_CFG_MEMCHK	0x10000000
+#define	 SDRAM0_CFG_REGEN	0x08000000
+#define	 SDRAM0_CFG_ECCDD	0x00400000
+#define	 SDRAM0_CFG_EMDULR	0x00200000
+#define	 SDRAM0_CFG_DRW_SHIFT	(31-6)
+#define	 SDRAM0_CFG_BRPF_SHIFT	(31-8)
+
+#define	 SDRAM0_TR_CASL_SHIFT	(31-8)
+#define	 SDRAM0_TR_PTA_SHIFT	(31-13)
+#define	 SDRAM0_TR_CTP_SHIFT	(31-15)
+#define	 SDRAM0_TR_LDF_SHIFT	(31-17)
+#define	 SDRAM0_TR_RFTA_SHIFT	(31-29)
+#define	 SDRAM0_TR_RCD_SHIFT	(31-31)
+
+#define	 SDRAM0_RTR_SHIFT	(31-15)
+#define	 SDRAM0_ECCCFG_SHIFT	(31-11)
+
+/* SDRAM0_CFG enable macro  */
+#define SDRAM0_CFG_BRPF(x) ( ( x & 0x3)<< SDRAM0_CFG_BRPF_SHIFT )
+
+#define SDRAM0_BXCR_SZ_MASK	0x000e0000
+#define SDRAM0_BXCR_AM_MASK	0x0000e000
+
+#define SDRAM0_BXCR_SZ_SHIFT	(31-14)
+#define SDRAM0_BXCR_AM_SHIFT	(31-18)
+
+#define SDRAM0_BXCR_SZ(x)	( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) )
+#define SDRAM0_BXCR_AM(x)	( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) )
+
+#ifdef CONFIG_SPDDRAM_SILENT
+# define SPD_ERR(x) do { return 0; } while (0)
+#else
+# define SPD_ERR(x) do { printf(x); return(0); } while (0)
+#endif
+
+#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))
+
+/* function prototypes */
+int spd_read(uint addr);
+
+
+/*
+ * This function is reading data from the DIMM module EEPROM over the SPD bus
+ * and uses that to program the sdram controller.
+ *
+ * This works on boards that has the same schematics that the AMCC walnut has.
+ *
+ * Input: null for default I2C spd functions or a pointer to a custom function
+ * returning spd_data.
+ */
+
+long int spd_sdram(int(read_spd)(uint addr))
+{
+	int tmp,row,col;
+	int total_size,bank_size,bank_code;
+	int ecc_on;
+	int mode;
+	int bank_cnt;
+
+	int sdram0_pmit=0x07c00000;
+#ifndef CONFIG_405EP /* not on PPC405EP */
+	int sdram0_besr0=-1;
+	int sdram0_besr1=-1;
+	int sdram0_eccesr=-1;
+#endif
+	int sdram0_ecccfg;
+
+	int sdram0_rtr=0;
+	int sdram0_tr=0;
+
+	int sdram0_b0cr;
+	int sdram0_b1cr;
+	int sdram0_b2cr;
+	int sdram0_b3cr;
+
+	int sdram0_cfg=0;
+
+	int t_rp;
+	int t_rcd;
+	int t_ras;
+	int t_rc;
+	int min_cas;
+
+	PPC405_SYS_INFO sys_info;
+	unsigned long bus_period_x_10;
+
+	/*
+	 * get the board info
+	 */
+	get_sys_info(&sys_info);
+	bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
+
+	if (read_spd == 0){
+		read_spd=spd_read;
+		/*
+		 * Make sure I2C controller is initialized
+		 * before continuing.
+		 */
+		i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+	}
+
+	/* Make shure we are using SDRAM */
+	if (read_spd(2) != 0x04) {
+		SPD_ERR("SDRAM - non SDRAM memory module found\n");
+	}
+
+	/* ------------------------------------------------------------------
+	 * configure memory timing register
+	 *
+	 * data from DIMM:
+	 * 27	IN Row Precharge Time ( t RP)
+	 * 29	MIN RAS to CAS Delay ( t RCD)
+	 * 127	 Component and Clock Detail ,clk0-clk3, junction temp, CAS
+	 * -------------------------------------------------------------------*/
+
+	/*
+	 * first figure out which cas latency mode to use
+	 * use the min supported mode
+	 */
+
+	tmp = read_spd(127) & 0x6;
+	if (tmp == 0x02) {		/* only cas = 2 supported */
+		min_cas = 2;
+/*		t_ck = read_spd(9); */
+/*		t_ac = read_spd(10); */
+	} else if (tmp == 0x04) {	/* only cas = 3 supported */
+		min_cas = 3;
+/*		t_ck = read_spd(9); */
+/*		t_ac = read_spd(10); */
+	} else if (tmp == 0x06) {	/* 2,3 supported, so use 2 */
+		min_cas = 2;
+/*		t_ck = read_spd(23); */
+/*		t_ac = read_spd(24); */
+	} else {
+		SPD_ERR("SDRAM - unsupported CAS latency \n");
+	}
+
+	/* get some timing values, t_rp,t_rcd,t_ras,t_rc
+	 */
+	t_rp = read_spd(27);
+	t_rcd = read_spd(29);
+	t_ras = read_spd(30);
+	t_rc = t_ras + t_rp;
+
+	/* The following timing calcs subtract 1 before deviding.
+	 * this has effect of using ceiling instead of floor rounding,
+	 * and also subtracting 1 to convert number to reg value
+	 */
+	/* set up CASL */
+	sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT;
+	/* set up PTA */
+	sdram0_tr |= ((((t_rp - 1) * 10)/bus_period_x_10) & 0x3) << SDRAM0_TR_PTA_SHIFT;
+	/* set up CTP */
+	tmp = (((t_rc - t_rcd - t_rp -1) * 10) / bus_period_x_10) & 0x3;
+	if (tmp < 1)
+		tmp = 1;
+	sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT;
+	/* set LDF	= 2 cycles, reg value = 1 */
+	sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT;
+	/* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */
+	tmp = (((t_rc - 1) * 10) / bus_period_x_10) - 3;
+	if (tmp < 0)
+		tmp = 0;
+	if (tmp > 6)
+		tmp = 6;
+	sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT;
+	/* set RCD = t_rcd/bus_period*/
+	sdram0_tr |= ((((t_rcd - 1) * 10) / bus_period_x_10) &0x3) << SDRAM0_TR_RCD_SHIFT ;
+
+
+	/*------------------------------------------------------------------
+	 * configure RTR register
+	 * -------------------------------------------------------------------*/
+	row = read_spd(3);
+	col = read_spd(4);
+	tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */
+	switch (tmp) {
+	case 0x00:
+		tmp = 15625;
+		break;
+	case 0x01:
+		tmp = 15625 / 4;
+		break;
+	case 0x02:
+		tmp = 15625 / 2;
+		break;
+	case 0x03:
+		tmp = 15625 * 2;
+		break;
+	case 0x04:
+		tmp = 15625 * 4;
+		break;
+	case 0x05:
+		tmp = 15625 * 8;
+		break;
+	default:
+		SPD_ERR("SDRAM - Bad refresh period \n");
+	}
+	/* convert from nsec to bus cycles */
+	tmp = (tmp * 10) / bus_period_x_10;
+	sdram0_rtr = (tmp & 0x3ff8) <<	SDRAM0_RTR_SHIFT;
+
+	/*------------------------------------------------------------------
+	 * determine the number of banks used
+	 * -------------------------------------------------------------------*/
+	/* byte 7:6 is module data width */
+	if (read_spd(7) != 0)
+		SPD_ERR("SDRAM - unsupported module width\n");
+	tmp = read_spd(6);
+	if (tmp < 32)
+		SPD_ERR("SDRAM - unsupported module width\n");
+	else if (tmp < 64)
+		bank_cnt = 1;		/* one bank per sdram side */
+	else if (tmp < 73)
+		bank_cnt = 2;	/* need two banks per side */
+	else if (tmp < 161)
+		bank_cnt = 4;	/* need four banks per side */
+	else
+		SPD_ERR("SDRAM - unsupported module width\n");
+
+	/* byte 5 is the module row count (refered to as dimm "sides") */
+	tmp = read_spd(5);
+	if (tmp == 1)
+		;
+	else if (tmp==2)
+		bank_cnt *= 2;
+	else if (tmp==4)
+		bank_cnt *= 4;
+	else
+		bank_cnt = 8;		/* 8 is an error code */
+
+	if (bank_cnt > 4)	/* we only have 4 banks to work with */
+		SPD_ERR("SDRAM - unsupported module rows for this width\n");
+
+	/* now check for ECC ability of module. We only support ECC
+	 *   on 32 bit wide devices with 8 bit ECC.
+	 */
+	if ((read_spd(11)==2) && (read_spd(6)==40) && (read_spd(14)==8)) {
+		sdram0_ecccfg = 0xf << SDRAM0_ECCCFG_SHIFT;
+		ecc_on = 1;
+	} else {
+		sdram0_ecccfg = 0;
+		ecc_on = 0;
+	}
+
+	/*------------------------------------------------------------------
+	 * calculate total size
+	 * -------------------------------------------------------------------*/
+	/* calculate total size and do sanity check */
+	tmp = read_spd(31);
+	total_size = 1 << 22;	/* total_size = 4MB */
+	/* now multiply 4M by the smallest device row density */
+	/* note that we don't support asymetric rows */
+	while (((tmp & 0x0001) == 0) && (tmp != 0)) {
+		total_size = total_size << 1;
+		tmp = tmp >> 1;
+	}
+	total_size *= read_spd(5);	/* mult by module rows (dimm sides) */
+
+	/*------------------------------------------------------------------
+	 * map	rows * cols * banks to a mode
+	 * -------------------------------------------------------------------*/
+
+	switch (row) {
+	case 11:
+		switch (col) {
+		case 8:
+			mode=4; /* mode 5 */
+			break;
+		case 9:
+		case 10:
+			mode=0; /* mode 1 */
+			break;
+		default:
+			SPD_ERR("SDRAM - unsupported mode\n");
+		}
+		break;
+	case 12:
+		switch (col) {
+		case 8:
+			mode=3; /* mode 4 */
+			break;
+		case 9:
+		case 10:
+			mode=1; /* mode 2 */
+			break;
+		default:
+			SPD_ERR("SDRAM - unsupported mode\n");
+		}
+		break;
+	case 13:
+		switch (col) {
+		case 8:
+			mode=5; /* mode 6 */
+			break;
+		case 9:
+		case 10:
+			if (read_spd(17) == 2)
+				mode = 6; /* mode 7 */
+			else
+				mode = 2; /* mode 3 */
+			break;
+		case 11:
+			mode = 2; /* mode 3 */
+			break;
+		default:
+			SPD_ERR("SDRAM - unsupported mode\n");
+		}
+		break;
+	default:
+		SPD_ERR("SDRAM - unsupported mode\n");
+	}
+
+	/*------------------------------------------------------------------
+	 * using the calculated values, compute the bank
+	 * config register values.
+	 * -------------------------------------------------------------------*/
+	sdram0_b1cr = 0;
+	sdram0_b2cr = 0;
+	sdram0_b3cr = 0;
+
+	/* compute the size of each bank */
+	bank_size = total_size / bank_cnt;
+	/* convert bank size to bank size code for ppc4xx
+	   by takeing log2(bank_size) - 22 */
+	tmp = bank_size;		/* start with tmp = bank_size */
+	bank_code = 0;			/* and bank_code = 0 */
+	while (tmp > 1) {		/* this takes log2 of tmp */
+		bank_code++;		/* and stores result in bank_code */
+		tmp = tmp >> 1;
+	}				/* bank_code is now log2(bank_size) */
+	bank_code -= 22;		/* subtract 22 to get the code */
+
+	tmp = SDRAM0_BXCR_SZ(bank_code) | SDRAM0_BXCR_AM(mode) | 1;
+	sdram0_b0cr = (bank_size * 0) | tmp;
+#ifndef CONFIG_405EP /* not on PPC405EP */
+	if (bank_cnt > 1)
+		sdram0_b2cr = (bank_size * 1) | tmp;
+	if (bank_cnt > 2)
+		sdram0_b1cr = (bank_size * 2) | tmp;
+	if (bank_cnt > 3)
+		sdram0_b3cr = (bank_size * 3) | tmp;
+#else
+	/* PPC405EP chip only supports two SDRAM banks */
+	if (bank_cnt > 1)
+		sdram0_b1cr = (bank_size * 1) | tmp;
+	if (bank_cnt > 2)
+		total_size = 2 * bank_size;
+#endif
+
+	/*
+	 *   enable sdram controller DCE=1
+	 *  enable burst read prefetch to 32 bytes BRPF=2
+	 *  leave other functions off
+	 */
+
+	/*------------------------------------------------------------------
+	 * now that we've done our calculations, we are ready to
+	 * program all the registers.
+	 * -------------------------------------------------------------------*/
+
+#define mtsdram0(reg, data)  mtdcr(memcfga,reg);mtdcr(memcfgd,data)
+	/* disable memcontroller so updates work */
+	mtsdram0( mem_mcopt1, 0 );
+
+#ifndef CONFIG_405EP /* not on PPC405EP */
+	mtsdram0( mem_besra , sdram0_besr0 );
+	mtsdram0( mem_besrb , sdram0_besr1 );
+	mtsdram0( mem_ecccf , sdram0_ecccfg );
+	mtsdram0( mem_eccerr, sdram0_eccesr );
+#endif
+	mtsdram0( mem_rtr   , sdram0_rtr );
+	mtsdram0( mem_pmit  , sdram0_pmit );
+	mtsdram0( mem_mb0cf , sdram0_b0cr );
+	mtsdram0( mem_mb1cf , sdram0_b1cr );
+#ifndef CONFIG_405EP /* not on PPC405EP */
+	mtsdram0( mem_mb2cf , sdram0_b2cr );
+	mtsdram0( mem_mb3cf , sdram0_b3cr );
+#endif
+	mtsdram0( mem_sdtr1 , sdram0_tr );
+
+	/* SDRAM have a power on delay,	 500 micro should do */
+	udelay(500);
+	sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR;
+	if (ecc_on)
+		sdram0_cfg |= SDRAM0_CFG_MEMCHK;
+	mtsdram0(mem_mcopt1, sdram0_cfg);
+
+	return (total_size);
+}
+
+int spd_read(uint addr)
+{
+	uchar data[2];
+
+	if (i2c_read(SPD_EEPROM_ADDRESS, addr, 1, data, 1) == 0)
+		return (int)data[0];
+	else
+		return 0;
+}
+
+#endif /* CONFIG_SPD_EEPROM */
diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/44x_spd_ddr.c
similarity index 77%
rename from cpu/ppc4xx/spd_sdram.c
rename to cpu/ppc4xx/44x_spd_ddr.c
index c24456b..10b4c18 100644
--- a/cpu/ppc4xx/spd_sdram.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -1,4 +1,8 @@
 /*
+ * cpu/ppc4xx/44x_spd_ddr.c
+ * This SPD DDR detection code supports IBM/AMCC PPC44x cpu with a
+ * DDR controller. Those are 440GP/GX/EP/GR.
+ *
  * (C) Copyright 2001
  * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com
  *
@@ -42,8 +46,11 @@
 #include <asm/processor.h>
 #include <i2c.h>
 #include <ppc4xx.h>
+#include <asm/mmu.h>
 
-#ifdef CONFIG_SPD_EEPROM
+#if defined(CONFIG_SPD_EEPROM) &&					\
+	(defined(CONFIG_440GP) || defined(CONFIG_440GX) ||		\
+	 defined(CONFIG_440EP) || defined(CONFIG_440GR))
 
 /*
  * Set default values
@@ -58,414 +65,6 @@
 
 #define ONE_BILLION	1000000000
 
-#ifndef	 CONFIG_440		/* for 405 WALNUT/SYCAMORE/BUBINGA boards */
-
-#define	 SDRAM0_CFG_DCE		0x80000000
-#define	 SDRAM0_CFG_SRE		0x40000000
-#define	 SDRAM0_CFG_PME		0x20000000
-#define	 SDRAM0_CFG_MEMCHK	0x10000000
-#define	 SDRAM0_CFG_REGEN	0x08000000
-#define	 SDRAM0_CFG_ECCDD	0x00400000
-#define	 SDRAM0_CFG_EMDULR	0x00200000
-#define	 SDRAM0_CFG_DRW_SHIFT	(31-6)
-#define	 SDRAM0_CFG_BRPF_SHIFT	(31-8)
-
-#define	 SDRAM0_TR_CASL_SHIFT	(31-8)
-#define	 SDRAM0_TR_PTA_SHIFT	(31-13)
-#define	 SDRAM0_TR_CTP_SHIFT	(31-15)
-#define	 SDRAM0_TR_LDF_SHIFT	(31-17)
-#define	 SDRAM0_TR_RFTA_SHIFT	(31-29)
-#define	 SDRAM0_TR_RCD_SHIFT	(31-31)
-
-#define	 SDRAM0_RTR_SHIFT	(31-15)
-#define	 SDRAM0_ECCCFG_SHIFT	(31-11)
-
-/* SDRAM0_CFG enable macro  */
-#define SDRAM0_CFG_BRPF(x) ( ( x & 0x3)<< SDRAM0_CFG_BRPF_SHIFT )
-
-#define SDRAM0_BXCR_SZ_MASK	0x000e0000
-#define SDRAM0_BXCR_AM_MASK	0x0000e000
-
-#define SDRAM0_BXCR_SZ_SHIFT	(31-14)
-#define SDRAM0_BXCR_AM_SHIFT	(31-18)
-
-#define SDRAM0_BXCR_SZ(x)	( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) )
-#define SDRAM0_BXCR_AM(x)	( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) )
-
-#ifdef CONFIG_SPDDRAM_SILENT
-# define SPD_ERR(x) do { return 0; } while (0)
-#else
-# define SPD_ERR(x) do { printf(x); return(0); } while (0)
-#endif
-
-#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))
-
-/* function prototypes */
-int spd_read(uint addr);
-
-
-/*
- * This function is reading data from the DIMM module EEPROM over the SPD bus
- * and uses that to program the sdram controller.
- *
- * This works on boards that has the same schematics that the AMCC walnut has.
- *
- * Input: null for default I2C spd functions or a pointer to a custom function
- * returning spd_data.
- */
-
-long int spd_sdram(int(read_spd)(uint addr))
-{
-	int tmp,row,col;
-	int total_size,bank_size,bank_code;
-	int ecc_on;
-	int mode;
-	int bank_cnt;
-
-	int sdram0_pmit=0x07c00000;
-#ifndef CONFIG_405EP /* not on PPC405EP */
-	int sdram0_besr0=-1;
-	int sdram0_besr1=-1;
-	int sdram0_eccesr=-1;
-#endif
-	int sdram0_ecccfg;
-
-	int sdram0_rtr=0;
-	int sdram0_tr=0;
-
-	int sdram0_b0cr;
-	int sdram0_b1cr;
-	int sdram0_b2cr;
-	int sdram0_b3cr;
-
-	int sdram0_cfg=0;
-
-	int t_rp;
-	int t_rcd;
-	int t_ras;
-	int t_rc;
-	int min_cas;
-
-	PPC405_SYS_INFO sys_info;
-	unsigned long bus_period_x_10;
-
-	/*
-	 * get the board info
-	 */
-	get_sys_info(&sys_info);
-	bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
-
-	if (read_spd == 0){
-		read_spd=spd_read;
-		/*
-		 * Make sure I2C controller is initialized
-		 * before continuing.
-		 */
-		i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
-	}
-
-	/* Make shure we are using SDRAM */
-	if (read_spd(2) != 0x04) {
-		SPD_ERR("SDRAM - non SDRAM memory module found\n");
-	}
-
-	/* ------------------------------------------------------------------
-	 * configure memory timing register
-	 *
-	 * data from DIMM:
-	 * 27	IN Row Precharge Time ( t RP)
-	 * 29	MIN RAS to CAS Delay ( t RCD)
-	 * 127	 Component and Clock Detail ,clk0-clk3, junction temp, CAS
-	 * -------------------------------------------------------------------*/
-
-	/*
-	 * first figure out which cas latency mode to use
-	 * use the min supported mode
-	 */
-
-	tmp = read_spd(127) & 0x6;
-	if (tmp == 0x02) {		/* only cas = 2 supported */
-		min_cas = 2;
-/*		t_ck = read_spd(9); */
-/*		t_ac = read_spd(10); */
-	} else if (tmp == 0x04) {	/* only cas = 3 supported */
-		min_cas = 3;
-/*		t_ck = read_spd(9); */
-/*		t_ac = read_spd(10); */
-	} else if (tmp == 0x06) {	/* 2,3 supported, so use 2 */
-		min_cas = 2;
-/*		t_ck = read_spd(23); */
-/*		t_ac = read_spd(24); */
-	} else {
-		SPD_ERR("SDRAM - unsupported CAS latency \n");
-	}
-
-	/* get some timing values, t_rp,t_rcd,t_ras,t_rc
-	 */
-	t_rp = read_spd(27);
-	t_rcd = read_spd(29);
-	t_ras = read_spd(30);
-	t_rc = t_ras + t_rp;
-
-	/* The following timing calcs subtract 1 before deviding.
-	 * this has effect of using ceiling instead of floor rounding,
-	 * and also subtracting 1 to convert number to reg value
-	 */
-	/* set up CASL */
-	sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT;
-	/* set up PTA */
-	sdram0_tr |= ((((t_rp - 1) * 10)/bus_period_x_10) & 0x3) << SDRAM0_TR_PTA_SHIFT;
-	/* set up CTP */
-	tmp = (((t_rc - t_rcd - t_rp -1) * 10) / bus_period_x_10) & 0x3;
-	if (tmp < 1)
-		tmp = 1;
-	sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT;
-	/* set LDF	= 2 cycles, reg value = 1 */
-	sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT;
-	/* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */
-	tmp = (((t_rc - 1) * 10) / bus_period_x_10) - 3;
-	if (tmp < 0)
-		tmp = 0;
-	if (tmp > 6)
-		tmp = 6;
-	sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT;
-	/* set RCD = t_rcd/bus_period*/
-	sdram0_tr |= ((((t_rcd - 1) * 10) / bus_period_x_10) &0x3) << SDRAM0_TR_RCD_SHIFT ;
-
-
-	/*------------------------------------------------------------------
-	 * configure RTR register
-	 * -------------------------------------------------------------------*/
-	row = read_spd(3);
-	col = read_spd(4);
-	tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */
-	switch (tmp) {
-	case 0x00:
-		tmp = 15625;
-		break;
-	case 0x01:
-		tmp = 15625 / 4;
-		break;
-	case 0x02:
-		tmp = 15625 / 2;
-		break;
-	case 0x03:
-		tmp = 15625 * 2;
-		break;
-	case 0x04:
-		tmp = 15625 * 4;
-		break;
-	case 0x05:
-		tmp = 15625 * 8;
-		break;
-	default:
-		SPD_ERR("SDRAM - Bad refresh period \n");
-	}
-	/* convert from nsec to bus cycles */
-	tmp = (tmp * 10) / bus_period_x_10;
-	sdram0_rtr = (tmp & 0x3ff8) <<	SDRAM0_RTR_SHIFT;
-
-	/*------------------------------------------------------------------
-	 * determine the number of banks used
-	 * -------------------------------------------------------------------*/
-	/* byte 7:6 is module data width */
-	if (read_spd(7) != 0)
-		SPD_ERR("SDRAM - unsupported module width\n");
-	tmp = read_spd(6);
-	if (tmp < 32)
-		SPD_ERR("SDRAM - unsupported module width\n");
-	else if (tmp < 64)
-		bank_cnt = 1;		/* one bank per sdram side */
-	else if (tmp < 73)
-		bank_cnt = 2;	/* need two banks per side */
-	else if (tmp < 161)
-		bank_cnt = 4;	/* need four banks per side */
-	else
-		SPD_ERR("SDRAM - unsupported module width\n");
-
-	/* byte 5 is the module row count (refered to as dimm "sides") */
-	tmp = read_spd(5);
-	if (tmp == 1)
-		;
-	else if (tmp==2)
-		bank_cnt *= 2;
-	else if (tmp==4)
-		bank_cnt *= 4;
-	else
-		bank_cnt = 8;		/* 8 is an error code */
-
-	if (bank_cnt > 4)	/* we only have 4 banks to work with */
-		SPD_ERR("SDRAM - unsupported module rows for this width\n");
-
-	/* now check for ECC ability of module. We only support ECC
-	 *   on 32 bit wide devices with 8 bit ECC.
-	 */
-	if ((read_spd(11)==2) && (read_spd(6)==40) && (read_spd(14)==8)) {
-		sdram0_ecccfg = 0xf << SDRAM0_ECCCFG_SHIFT;
-		ecc_on = 1;
-	} else {
-		sdram0_ecccfg = 0;
-		ecc_on = 0;
-	}
-
-	/*------------------------------------------------------------------
-	 * calculate total size
-	 * -------------------------------------------------------------------*/
-	/* calculate total size and do sanity check */
-	tmp = read_spd(31);
-	total_size = 1 << 22;	/* total_size = 4MB */
-	/* now multiply 4M by the smallest device row density */
-	/* note that we don't support asymetric rows */
-	while (((tmp & 0x0001) == 0) && (tmp != 0)) {
-		total_size = total_size << 1;
-		tmp = tmp >> 1;
-	}
-	total_size *= read_spd(5);	/* mult by module rows (dimm sides) */
-
-	/*------------------------------------------------------------------
-	 * map	rows * cols * banks to a mode
-	 * -------------------------------------------------------------------*/
-
-	switch (row) {
-	case 11:
-		switch (col) {
-		case 8:
-			mode=4; /* mode 5 */
-			break;
-		case 9:
-		case 10:
-			mode=0; /* mode 1 */
-			break;
-		default:
-			SPD_ERR("SDRAM - unsupported mode\n");
-		}
-		break;
-	case 12:
-		switch (col) {
-		case 8:
-			mode=3; /* mode 4 */
-			break;
-		case 9:
-		case 10:
-			mode=1; /* mode 2 */
-			break;
-		default:
-			SPD_ERR("SDRAM - unsupported mode\n");
-		}
-		break;
-	case 13:
-		switch (col) {
-		case 8:
-			mode=5; /* mode 6 */
-			break;
-		case 9:
-		case 10:
-			if (read_spd(17) == 2)
-				mode = 6; /* mode 7 */
-			else
-				mode = 2; /* mode 3 */
-			break;
-		case 11:
-			mode = 2; /* mode 3 */
-			break;
-		default:
-			SPD_ERR("SDRAM - unsupported mode\n");
-		}
-		break;
-	default:
-		SPD_ERR("SDRAM - unsupported mode\n");
-	}
-
-	/*------------------------------------------------------------------
-	 * using the calculated values, compute the bank
-	 * config register values.
-	 * -------------------------------------------------------------------*/
-	sdram0_b1cr = 0;
-	sdram0_b2cr = 0;
-	sdram0_b3cr = 0;
-
-	/* compute the size of each bank */
-	bank_size = total_size / bank_cnt;
-	/* convert bank size to bank size code for ppc4xx
-	   by takeing log2(bank_size) - 22 */
-	tmp = bank_size;		/* start with tmp = bank_size */
-	bank_code = 0;			/* and bank_code = 0 */
-	while (tmp > 1) {		/* this takes log2 of tmp */
-		bank_code++;		/* and stores result in bank_code */
-		tmp = tmp >> 1;
-	}				/* bank_code is now log2(bank_size) */
-	bank_code -= 22;		/* subtract 22 to get the code */
-
-	tmp = SDRAM0_BXCR_SZ(bank_code) | SDRAM0_BXCR_AM(mode) | 1;
-	sdram0_b0cr = (bank_size * 0) | tmp;
-#ifndef CONFIG_405EP /* not on PPC405EP */
-	if (bank_cnt > 1)
-		sdram0_b2cr = (bank_size * 1) | tmp;
-	if (bank_cnt > 2)
-		sdram0_b1cr = (bank_size * 2) | tmp;
-	if (bank_cnt > 3)
-		sdram0_b3cr = (bank_size * 3) | tmp;
-#else
-	/* PPC405EP chip only supports two SDRAM banks */
-	if (bank_cnt > 1)
-		sdram0_b1cr = (bank_size * 1) | tmp;
-	if (bank_cnt > 2)
-		total_size = 2 * bank_size;
-#endif
-
-	/*
-	 *   enable sdram controller DCE=1
-	 *  enable burst read prefetch to 32 bytes BRPF=2
-	 *  leave other functions off
-	 */
-
-	/*------------------------------------------------------------------
-	 * now that we've done our calculations, we are ready to
-	 * program all the registers.
-	 * -------------------------------------------------------------------*/
-
-#define mtsdram0(reg, data)  mtdcr(memcfga,reg);mtdcr(memcfgd,data)
-	/* disable memcontroller so updates work */
-	mtsdram0( mem_mcopt1, 0 );
-
-#ifndef CONFIG_405EP /* not on PPC405EP */
-	mtsdram0( mem_besra , sdram0_besr0 );
-	mtsdram0( mem_besrb , sdram0_besr1 );
-	mtsdram0( mem_ecccf , sdram0_ecccfg );
-	mtsdram0( mem_eccerr, sdram0_eccesr );
-#endif
-	mtsdram0( mem_rtr   , sdram0_rtr );
-	mtsdram0( mem_pmit  , sdram0_pmit );
-	mtsdram0( mem_mb0cf , sdram0_b0cr );
-	mtsdram0( mem_mb1cf , sdram0_b1cr );
-#ifndef CONFIG_405EP /* not on PPC405EP */
-	mtsdram0( mem_mb2cf , sdram0_b2cr );
-	mtsdram0( mem_mb3cf , sdram0_b3cr );
-#endif
-	mtsdram0( mem_sdtr1 , sdram0_tr );
-
-	/* SDRAM have a power on delay,	 500 micro should do */
-	udelay(500);
-	sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR;
-	if (ecc_on)
-		sdram0_cfg |= SDRAM0_CFG_MEMCHK;
-	mtsdram0(mem_mcopt1, sdram0_cfg);
-
-	return (total_size);
-}
-
-int spd_read(uint addr)
-{
-	uchar data[2];
-
-	if (i2c_read(SPD_EEPROM_ADDRESS, addr, 1, data, 1) == 0)
-		return (int)data[0];
-	else
-		return 0;
-}
-
-#else /* CONFIG_440 */
-
 /*-----------------------------------------------------------------------------
   |  Memory Controller Options 0
   +-----------------------------------------------------------------------------*/
@@ -631,6 +230,22 @@
 #define TRUE			1
 #define FALSE			0
 
+/*
+ * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
+ * region. Right now the cache should still be disabled in U-Boot because of the
+ * EMAC driver, that need it's buffer descriptor to be located in non cached
+ * memory.
+ *
+ * If at some time this restriction doesn't apply anymore, just define
+ * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * everything correctly.
+ */
+#ifdef CFG_ENABLE_SDRAM_CACHE
+#define MY_TLB_WORD2_I_ENABLE	0			/* enable caching on SDRAM */
+#else
+#define MY_TLB_WORD2_I_ENABLE	TLB_WORD2_I_ENABLE	/* disable caching on SDRAM */
+#endif
+
 const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
 	{0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
 	 0xFFFFFFFF, 0xFFFFFFFF},
@@ -661,6 +276,7 @@
 #ifdef CFG_SIMULATE_SPD_EEPROM
 extern unsigned char cfg_simulate_spd_eeprom[128];
 #endif
+void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
 
 unsigned char spd_read(uchar chip, uint addr);
 
@@ -779,6 +395,11 @@
 	total_size = program_bxcr(dimm_populated, iic0_dimm_addr,
 				  num_dimm_banks);
 
+#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
+	/* and program tlb entries for this size (dynamic) */
+	program_tlb(0, total_size, MY_TLB_WORD2_I_ENABLE);
+#endif
+
 	/*
 	 * program SDRAM Clock Timing Register (SDRAM0_CLKTR)
 	 */
@@ -1732,11 +1353,11 @@
 			 */
 			cr |= SDRAM_BXCR_SDBE;
 
-			for (i = 0; i < num_banks; i++) {
-				bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
+ 			for (i = 0; i < num_banks; i++) {
+				bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].bank_size_bytes =
 					(4 * 1024 * 1024) * bank_size_id;
-				bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
-			}
+				bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].cr = cr;
+ 			}
 		}
 	}
 
@@ -1825,7 +1446,4 @@
 			SDRAM_CFG0_MCHK_CHK);
 	}
 }
-
-#endif /* CONFIG_440 */
-
 #endif /* CONFIG_SPD_EEPROM */
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
new file mode 100644
index 0000000..83c9911
--- /dev/null
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -0,0 +1,2954 @@
+/*
+ * cpu/ppc4xx/44x_spd_ddr2.c
+ * This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
+ * DDR2 controller (non Denali Core). Those are 440SP/SPe.
+ *
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * COPYRIGHT   AMCC   CORPORATION 2004
+ *
+ * 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 for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
+#include <common.h>
+#include <command.h>
+#include <ppc4xx.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+
+#if defined(CONFIG_SPD_EEPROM) &&				\
+	(defined(CONFIG_440SP) || defined(CONFIG_440SPE))
+
+/*-----------------------------------------------------------------------------+
+ * Defines
+ *-----------------------------------------------------------------------------*/
+#ifndef	TRUE
+#define TRUE		1
+#endif
+#ifndef FALSE
+#define FALSE		0
+#endif
+
+#define SDRAM_DDR1	1
+#define SDRAM_DDR2	2
+#define SDRAM_NONE	0
+
+#define MAXDIMMS 	2
+#define MAXRANKS 	4
+#define MAXBXCF		4
+#define MAX_SPD_BYTES	256   /* Max number of bytes on the DIMM's SPD EEPROM */
+
+#define ONE_BILLION	1000000000
+
+#define MULDIV64(m1, m2, d)	(u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
+
+#define CMD_NOP		(7 << 19)
+#define CMD_PRECHARGE	(2 << 19)
+#define CMD_REFRESH	(1 << 19)
+#define CMD_EMR		(0 << 19)
+#define CMD_READ	(5 << 19)
+#define CMD_WRITE	(4 << 19)
+
+#define SELECT_MR	(0 << 16)
+#define SELECT_EMR	(1 << 16)
+#define SELECT_EMR2	(2 << 16)
+#define SELECT_EMR3	(3 << 16)
+
+/* MR */
+#define DLL_RESET	0x00000100
+
+#define WRITE_RECOV_2	(1 << 9)
+#define WRITE_RECOV_3	(2 << 9)
+#define WRITE_RECOV_4	(3 << 9)
+#define WRITE_RECOV_5	(4 << 9)
+#define WRITE_RECOV_6	(5 << 9)
+
+#define BURST_LEN_4	0x00000002
+
+/* EMR */
+#define ODT_0_OHM	0x00000000
+#define ODT_50_OHM	0x00000044
+#define ODT_75_OHM	0x00000004
+#define ODT_150_OHM	0x00000040
+
+#define ODS_FULL	0x00000000
+#define ODS_REDUCED	0x00000002
+
+/* defines for ODT (On Die Termination) of the 440SP(e) DDR2 controller */
+#define ODT_EB0R	(0x80000000 >> 8)
+#define ODT_EB0W	(0x80000000 >> 7)
+#define CALC_ODT_R(n)	(ODT_EB0R << (n << 1))
+#define CALC_ODT_W(n)	(ODT_EB0W << (n << 1))
+#define CALC_ODT_RW(n)	(CALC_ODT_R(n) | CALC_ODT_W(n))
+
+/* Defines for the Read Cycle Delay test */
+#define NUMMEMTESTS 8
+#define NUMMEMWORDS 8
+
+#define CONFIG_ECC_ERROR_RESET		/* test-only: see description below, at check_ecc() */
+
+/*
+ * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
+ * region. Right now the cache should still be disabled in U-Boot because of the
+ * EMAC driver, that need it's buffer descriptor to be located in non cached
+ * memory.
+ *
+ * If at some time this restriction doesn't apply anymore, just define
+ * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * everything correctly.
+ */
+#ifdef CFG_ENABLE_SDRAM_CACHE
+#define MY_TLB_WORD2_I_ENABLE	0			/* enable caching on SDRAM */
+#else
+#define MY_TLB_WORD2_I_ENABLE	TLB_WORD2_I_ENABLE	/* disable caching on SDRAM */
+#endif
+
+/* Private Structure Definitions */
+
+/* enum only to ease code for cas latency setting */
+typedef enum ddr_cas_id {
+	DDR_CAS_2      = 20,
+	DDR_CAS_2_5    = 25,
+	DDR_CAS_3      = 30,
+	DDR_CAS_4      = 40,
+	DDR_CAS_5      = 50
+} ddr_cas_id_t;
+
+/*-----------------------------------------------------------------------------+
+ * Prototypes
+ *-----------------------------------------------------------------------------*/
+static unsigned long sdram_memsize(void);
+void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
+static void get_spd_info(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks);
+static void check_mem_type(unsigned long *dimm_populated,
+			   unsigned char *iic0_dimm_addr,
+			   unsigned long num_dimm_banks);
+static void check_frequency(unsigned long *dimm_populated,
+			    unsigned char *iic0_dimm_addr,
+			    unsigned long num_dimm_banks);
+static void check_rank_number(unsigned long *dimm_populated,
+			      unsigned char *iic0_dimm_addr,
+			      unsigned long num_dimm_banks);
+static void check_voltage_type(unsigned long *dimm_populated,
+			       unsigned char *iic0_dimm_addr,
+			       unsigned long num_dimm_banks);
+static void program_memory_queue(unsigned long *dimm_populated,
+				 unsigned char *iic0_dimm_addr,
+				 unsigned long num_dimm_banks);
+static void program_codt(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks);
+static void program_mode(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks,
+			 ddr_cas_id_t *selected_cas,
+			 int *write_recovery);
+static void program_tr(unsigned long *dimm_populated,
+		       unsigned char *iic0_dimm_addr,
+		       unsigned long num_dimm_banks);
+static void program_rtr(unsigned long *dimm_populated,
+			unsigned char *iic0_dimm_addr,
+			unsigned long num_dimm_banks);
+static void program_bxcf(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks);
+static void program_copt1(unsigned long *dimm_populated,
+			  unsigned char *iic0_dimm_addr,
+			  unsigned long num_dimm_banks);
+static void program_initplr(unsigned long *dimm_populated,
+			    unsigned char *iic0_dimm_addr,
+			    unsigned long num_dimm_banks,
+			    ddr_cas_id_t selected_cas,
+			    int write_recovery);
+static unsigned long is_ecc_enabled(void);
+#ifdef CONFIG_DDR_ECC
+static void program_ecc(unsigned long *dimm_populated,
+			unsigned char *iic0_dimm_addr,
+			unsigned long num_dimm_banks,
+			unsigned long tlb_word2_i_value);
+static void program_ecc_addr(unsigned long start_address,
+			     unsigned long num_bytes,
+			     unsigned long tlb_word2_i_value);
+#endif
+static void program_DQS_calibration(unsigned long *dimm_populated,
+				    unsigned char *iic0_dimm_addr,
+				    unsigned long num_dimm_banks);
+#ifdef HARD_CODED_DQS /* calibration test with hardvalues */
+static void	test(void);
+#else
+static void	DQS_calibration_process(void);
+#endif
+#if defined(DEBUG)
+static void ppc440sp_sdram_register_dump(void);
+#endif
+int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+void dcbz_area(u32 start_address, u32 num_bytes);
+void dflush(void);
+
+static u32 mfdcr_any(u32 dcr)
+{
+	u32 val;
+
+	switch (dcr) {
+	case SDRAM_R0BAS + 0:
+		val = mfdcr(SDRAM_R0BAS + 0);
+		break;
+	case SDRAM_R0BAS + 1:
+		val = mfdcr(SDRAM_R0BAS + 1);
+		break;
+	case SDRAM_R0BAS + 2:
+		val = mfdcr(SDRAM_R0BAS + 2);
+		break;
+	case SDRAM_R0BAS + 3:
+		val = mfdcr(SDRAM_R0BAS + 3);
+		break;
+	default:
+		printf("DCR %d not defined in case statement!!!\n", dcr);
+		val = 0; /* just to satisfy the compiler */
+	}
+
+	return val;
+}
+
+static void mtdcr_any(u32 dcr, u32 val)
+{
+	switch (dcr) {
+	case SDRAM_R0BAS + 0:
+		mtdcr(SDRAM_R0BAS + 0, val);
+		break;
+	case SDRAM_R0BAS + 1:
+		mtdcr(SDRAM_R0BAS + 1, val);
+		break;
+	case SDRAM_R0BAS + 2:
+		mtdcr(SDRAM_R0BAS + 2, val);
+		break;
+	case SDRAM_R0BAS + 3:
+		mtdcr(SDRAM_R0BAS + 3, val);
+		break;
+	default:
+		printf("DCR %d not defined in case statement!!!\n", dcr);
+	}
+}
+
+static unsigned char spd_read(uchar chip, uint addr)
+{
+	unsigned char data[2];
+
+	if (i2c_probe(chip) == 0)
+		if (i2c_read(chip, addr, 1, data, 1) == 0)
+			return data[0];
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------------------+
+ * sdram_memsize
+ *-----------------------------------------------------------------------------*/
+static unsigned long sdram_memsize(void)
+{
+	unsigned long mem_size;
+	unsigned long mcopt2;
+	unsigned long mcstat;
+	unsigned long mb0cf;
+	unsigned long sdsz;
+	unsigned long i;
+
+	mem_size = 0;
+
+	mfsdram(SDRAM_MCOPT2, mcopt2);
+	mfsdram(SDRAM_MCSTAT, mcstat);
+
+	/* DDR controller must be enabled and not in self-refresh. */
+	/* Otherwise memsize is zero. */
+	if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
+	    && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
+	    && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
+		== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
+		for (i = 0; i < MAXBXCF; i++) {
+			mfsdram(SDRAM_MB0CF + (i << 2), mb0cf);
+			/* Banks enabled */
+			if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
+				sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK;
+
+				switch(sdsz) {
+				case SDRAM_RXBAS_SDSZ_8:
+					mem_size+=8;
+					break;
+				case SDRAM_RXBAS_SDSZ_16:
+					mem_size+=16;
+					break;
+				case SDRAM_RXBAS_SDSZ_32:
+					mem_size+=32;
+					break;
+				case SDRAM_RXBAS_SDSZ_64:
+					mem_size+=64;
+					break;
+				case SDRAM_RXBAS_SDSZ_128:
+					mem_size+=128;
+					break;
+				case SDRAM_RXBAS_SDSZ_256:
+					mem_size+=256;
+					break;
+				case SDRAM_RXBAS_SDSZ_512:
+					mem_size+=512;
+					break;
+				case SDRAM_RXBAS_SDSZ_1024:
+					mem_size+=1024;
+					break;
+				case SDRAM_RXBAS_SDSZ_2048:
+					mem_size+=2048;
+					break;
+				case SDRAM_RXBAS_SDSZ_4096:
+					mem_size+=4096;
+					break;
+				default:
+					mem_size=0;
+					break;
+				}
+			}
+		}
+	}
+
+	mem_size *= 1024 * 1024;
+	return(mem_size);
+}
+
+/*-----------------------------------------------------------------------------+
+ * initdram.  Initializes the 440SP Memory Queue and DDR SDRAM controller.
+ * Note: This routine runs from flash with a stack set up in the chip's
+ * sram space.  It is important that the routine does not require .sbss, .bss or
+ * .data sections.  It also cannot call routines that require these sections.
+ *-----------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------
+ * Function:	 initdram
+ * Description:  Configures SDRAM memory banks for DDR operation.
+ *		 Auto Memory Configuration option reads the DDR SDRAM EEPROMs
+ *		 via the IIC bus and then configures the DDR SDRAM memory
+ *		 banks appropriately. If Auto Memory Configuration is
+ *		 not used, it is assumed that no DIMM is plugged
+ *-----------------------------------------------------------------------------*/
+long int initdram(int board_type)
+{
+	unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS;
+	unsigned char spd0[MAX_SPD_BYTES];
+	unsigned char spd1[MAX_SPD_BYTES];
+	unsigned char *dimm_spd[MAXDIMMS];
+	unsigned long dimm_populated[MAXDIMMS];
+	unsigned long num_dimm_banks;		    /* on board dimm banks */
+	unsigned long val;
+	ddr_cas_id_t  selected_cas;
+	int write_recovery;
+	unsigned long dram_size = 0;
+
+	num_dimm_banks = sizeof(iic0_dimm_addr);
+
+	/*------------------------------------------------------------------
+	 * Set up an array of SPD matrixes.
+	 *-----------------------------------------------------------------*/
+	dimm_spd[0] = spd0;
+	dimm_spd[1] = spd1;
+
+	/*------------------------------------------------------------------
+	 * Reset the DDR-SDRAM controller.
+	 *-----------------------------------------------------------------*/
+	mtsdr(SDR0_SRST, (0x80000000 >> 10));
+	mtsdr(SDR0_SRST, 0x00000000);
+
+	/*
+	 * Make sure I2C controller is initialized
+	 * before continuing.
+	 */
+
+	/* switch to correct I2C bus */
+	I2C_SET_BUS(CFG_SPD_BUS_NUM);
+	i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+	/*------------------------------------------------------------------
+	 * Clear out the serial presence detect buffers.
+	 * Perform IIC reads from the dimm.  Fill in the spds.
+	 * Check to see if the dimm slots are populated
+	 *-----------------------------------------------------------------*/
+	get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Check the memory type for the dimms plugged.
+	 *-----------------------------------------------------------------*/
+	check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Check the frequency supported for the dimms plugged.
+	 *-----------------------------------------------------------------*/
+	check_frequency(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Check the total rank number.
+	 *-----------------------------------------------------------------*/
+	check_rank_number(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Check the voltage type for the dimms plugged.
+	 *-----------------------------------------------------------------*/
+	check_voltage_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Program SDRAM controller options 2 register
+	 * Except Enabling of the memory controller.
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MCOPT2, val);
+	mtsdram(SDRAM_MCOPT2,
+		(val &
+		 ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_PMEN_MASK |
+		   SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_XSRP_MASK |
+		   SDRAM_MCOPT2_ISIE_MASK))
+		| (SDRAM_MCOPT2_SREN_ENTER | SDRAM_MCOPT2_PMEN_DISABLE |
+		   SDRAM_MCOPT2_IPTR_IDLE | SDRAM_MCOPT2_XSRP_ALLOW |
+		   SDRAM_MCOPT2_ISIE_ENABLE));
+
+	/*------------------------------------------------------------------
+	 * Program SDRAM controller options 1 register
+	 * Note: Does not enable the memory controller.
+	 *-----------------------------------------------------------------*/
+	program_copt1(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Controller On Die Termination Register
+	 *-----------------------------------------------------------------*/
+	program_codt(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Program SDRAM refresh register.
+	 *-----------------------------------------------------------------*/
+	program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Program SDRAM mode register.
+	 *-----------------------------------------------------------------*/
+	program_mode(dimm_populated, iic0_dimm_addr, num_dimm_banks,
+		     &selected_cas, &write_recovery);
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Write Data/DM/DQS Clock Timing Reg
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_WRDTR, val);
+	mtsdram(SDRAM_WRDTR, (val & ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) |
+		(SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV));
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Clock Timing Register
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_CLKTR, val);
+	mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | SDRAM_CLKTR_CLKP_0_DEG);
+
+	/*------------------------------------------------------------------
+	 * Program the BxCF registers.
+	 *-----------------------------------------------------------------*/
+	program_bxcf(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Program SDRAM timing registers.
+	 *-----------------------------------------------------------------*/
+	program_tr(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Set the Extended Mode register
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MEMODE, val);
+	mtsdram(SDRAM_MEMODE,
+		(val & ~(SDRAM_MEMODE_DIC_MASK  | SDRAM_MEMODE_DLL_MASK |
+			 SDRAM_MEMODE_RTT_MASK | SDRAM_MEMODE_DQS_MASK)) |
+		(SDRAM_MEMODE_DIC_NORMAL | SDRAM_MEMODE_DLL_ENABLE
+		 | SDRAM_MEMODE_RTT_150OHM | SDRAM_MEMODE_DQS_ENABLE));
+
+	/*------------------------------------------------------------------
+	 * Program Initialization preload registers.
+	 *-----------------------------------------------------------------*/
+	program_initplr(dimm_populated, iic0_dimm_addr, num_dimm_banks,
+			selected_cas, write_recovery);
+
+	/*------------------------------------------------------------------
+	 * Delay to ensure 200usec have elapsed since reset.
+	 *-----------------------------------------------------------------*/
+	udelay(400);
+
+	/*------------------------------------------------------------------
+	 * Set the memory queue core base addr.
+	 *-----------------------------------------------------------------*/
+	program_memory_queue(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+	/*------------------------------------------------------------------
+	 * Program SDRAM controller options 2 register
+	 * Enable the memory controller.
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MCOPT2, val);
+	mtsdram(SDRAM_MCOPT2,
+		(val & ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_DCEN_MASK |
+			 SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_ISIE_MASK)) |
+		(SDRAM_MCOPT2_DCEN_ENABLE | SDRAM_MCOPT2_IPTR_EXECUTE));
+
+	/*------------------------------------------------------------------
+	 * Wait for SDRAM_CFG0_DC_EN to complete.
+	 *-----------------------------------------------------------------*/
+	do {
+		mfsdram(SDRAM_MCSTAT, val);
+	} while ((val & SDRAM_MCSTAT_MIC_MASK) == SDRAM_MCSTAT_MIC_NOTCOMP);
+
+	/* get installed memory size */
+	dram_size = sdram_memsize();
+
+	/* and program tlb entries for this size (dynamic) */
+	program_tlb(0, dram_size, MY_TLB_WORD2_I_ENABLE);
+
+	/*------------------------------------------------------------------
+	 * DQS calibration.
+	 *-----------------------------------------------------------------*/
+	program_DQS_calibration(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+
+#ifdef CONFIG_DDR_ECC
+	/*------------------------------------------------------------------
+	 * If ecc is enabled, initialize the parity bits.
+	 *-----------------------------------------------------------------*/
+	program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks, MY_TLB_WORD2_I_ENABLE);
+#endif
+
+#ifdef DEBUG
+	ppc440sp_sdram_register_dump();
+#endif
+
+	return dram_size;
+}
+
+static void get_spd_info(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long dimm_found;
+	unsigned char num_of_bytes;
+	unsigned char total_size;
+
+	dimm_found = FALSE;
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		num_of_bytes = 0;
+		total_size = 0;
+
+		num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0);
+		debug("\nspd_read(0x%x) returned %d\n",
+		      iic0_dimm_addr[dimm_num], num_of_bytes);
+		total_size = spd_read(iic0_dimm_addr[dimm_num], 1);
+		debug("spd_read(0x%x) returned %d\n",
+		      iic0_dimm_addr[dimm_num], total_size);
+
+		if ((num_of_bytes != 0) && (total_size != 0)) {
+			dimm_populated[dimm_num] = TRUE;
+			dimm_found = TRUE;
+			debug("DIMM slot %lu: populated\n", dimm_num);
+		} else {
+			dimm_populated[dimm_num] = FALSE;
+			debug("DIMM slot %lu: Not populated\n", dimm_num);
+		}
+	}
+
+	if (dimm_found == FALSE) {
+		printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
+		hang();
+	}
+}
+
+#ifdef CONFIG_ADD_RAM_INFO
+void board_add_ram_info(int use_default)
+{
+	if (is_ecc_enabled())
+		puts(" (ECC enabled)");
+	else
+		puts(" (ECC not enabled)");
+}
+#endif
+
+/*------------------------------------------------------------------
+ * For the memory DIMMs installed, this routine verifies that they
+ * really are DDR specific DIMMs.
+ *-----------------------------------------------------------------*/
+static void check_mem_type(unsigned long *dimm_populated,
+			   unsigned char *iic0_dimm_addr,
+			   unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long dimm_type;
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] == TRUE) {
+			dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2);
+			switch (dimm_type) {
+			case 1:
+				printf("ERROR: Standard Fast Page Mode DRAM DIMM detected in "
+				       "slot %d.\n", (unsigned int)dimm_num);
+				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			case 2:
+				printf("ERROR: EDO DIMM detected in slot %d.\n",
+				       (unsigned int)dimm_num);
+				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			case 3:
+				printf("ERROR: Pipelined Nibble DIMM detected in slot %d.\n",
+				       (unsigned int)dimm_num);
+				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			case 4:
+				printf("ERROR: SDRAM DIMM detected in slot %d.\n",
+				       (unsigned int)dimm_num);
+				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			case 5:
+				printf("ERROR: Multiplexed ROM DIMM detected in slot %d.\n",
+				       (unsigned int)dimm_num);
+				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			case 6:
+				printf("ERROR: SGRAM DIMM detected in slot %d.\n",
+				       (unsigned int)dimm_num);
+				printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			case 7:
+				debug("DIMM slot %d: DDR1 SDRAM detected\n", dimm_num);
+				dimm_populated[dimm_num] = SDRAM_DDR1;
+				break;
+			case 8:
+				debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num);
+				dimm_populated[dimm_num] = SDRAM_DDR2;
+				break;
+			default:
+				printf("ERROR: Unknown DIMM detected in slot %d.\n",
+				       (unsigned int)dimm_num);
+				printf("Only DDR1 and DDR2 SDRAM DIMMs are supported.\n");
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			}
+		}
+	}
+	for (dimm_num = 1; dimm_num < num_dimm_banks; dimm_num++) {
+		if ((dimm_populated[dimm_num-1] != SDRAM_NONE)
+		    && (dimm_populated[dimm_num]   != SDRAM_NONE)
+		    && (dimm_populated[dimm_num-1] != dimm_populated[dimm_num])) {
+			printf("ERROR: DIMM's DDR1 and DDR2 type can not be mixed.\n");
+			hang();
+		}
+	}
+}
+
+/*------------------------------------------------------------------
+ * For the memory DIMMs installed, this routine verifies that
+ * frequency previously calculated is supported.
+ *-----------------------------------------------------------------*/
+static void check_frequency(unsigned long *dimm_populated,
+			    unsigned char *iic0_dimm_addr,
+			    unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long tcyc_reg;
+	unsigned long cycle_time;
+	unsigned long calc_cycle_time;
+	unsigned long sdram_freq;
+	unsigned long sdr_ddrpll;
+	PPC440_SYS_INFO board_cfg;
+
+	/*------------------------------------------------------------------
+	 * Get the board configuration info.
+	 *-----------------------------------------------------------------*/
+	get_sys_info(&board_cfg);
+
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
+	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
+
+	/*
+	 * calc_cycle_time is calculated from DDR frequency set by board/chip
+	 * and is expressed in multiple of 10 picoseconds
+	 * to match the way DIMM cycle time is calculated below.
+	 */
+	calc_cycle_time = MULDIV64(ONE_BILLION, 100, sdram_freq);
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);
+			/*
+			 * Byte 9, Cycle time for CAS Latency=X, is split into two nibbles:
+			 * the higher order nibble (bits 4-7) designates the cycle time
+			 * to a granularity of 1ns;
+			 * the value presented by the lower order nibble (bits 0-3)
+			 * has a granularity of .1ns and is added to the value designated
+			 * by the higher nibble. In addition, four lines of the lower order
+			 * nibble are assigned to support +.25,+.33, +.66 and +.75.
+			 */
+			 /* Convert from hex to decimal */
+			if ((tcyc_reg & 0x0F) == 0x0D)
+				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 75;
+			else if ((tcyc_reg & 0x0F) == 0x0C)
+				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 66;
+			else if ((tcyc_reg & 0x0F) == 0x0B)
+				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 33;
+			else if ((tcyc_reg & 0x0F) == 0x0A)
+				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 25;
+			else
+				cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) +
+					((tcyc_reg & 0x0F)*10);
+
+			if  (cycle_time > (calc_cycle_time + 10)) {
+				/*
+				 * the provided sdram cycle_time is too small
+				 * for the available DIMM cycle_time.
+				 * The additionnal 100ps is here to accept a small incertainty.
+				 */
+				printf("ERROR: DRAM DIMM detected with cycle_time %d ps in "
+				       "slot %d \n while calculated cycle time is %d ps.\n",
+				       (unsigned int)(cycle_time*10),
+				       (unsigned int)dimm_num,
+				       (unsigned int)(calc_cycle_time*10));
+				printf("Replace the DIMM, or change DDR frequency via "
+				       "strapping bits.\n\n");
+				hang();
+			}
+		}
+	}
+}
+
+/*------------------------------------------------------------------
+ * For the memory DIMMs installed, this routine verifies two
+ * ranks/banks maximum are availables.
+ *-----------------------------------------------------------------*/
+static void check_rank_number(unsigned long *dimm_populated,
+			      unsigned char *iic0_dimm_addr,
+			      unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long dimm_rank;
+	unsigned long total_rank = 0;
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			dimm_rank = spd_read(iic0_dimm_addr[dimm_num], 5);
+			if (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08)
+				dimm_rank = (dimm_rank & 0x0F) +1;
+			else
+				dimm_rank = dimm_rank & 0x0F;
+
+
+			if (dimm_rank > MAXRANKS) {
+				printf("ERROR: DRAM DIMM detected with %d ranks in "
+				       "slot %d is not supported.\n", dimm_rank, dimm_num);
+				printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+			} else
+				total_rank += dimm_rank;
+		}
+		if (total_rank > MAXRANKS) {
+			printf("ERROR: DRAM DIMM detected with a total of %d ranks "
+			       "for all slots.\n", (unsigned int)total_rank);
+			printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);
+			printf("Remove one of the DIMM modules.\n\n");
+			hang();
+		}
+	}
+}
+
+/*------------------------------------------------------------------
+ * only support 2.5V modules.
+ * This routine verifies this.
+ *-----------------------------------------------------------------*/
+static void check_voltage_type(unsigned long *dimm_populated,
+			       unsigned char *iic0_dimm_addr,
+			       unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long voltage_type;
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8);
+			switch (voltage_type) {
+			case 0x00:
+				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
+				printf("This DIMM is 5.0 Volt/TTL.\n");
+				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
+				       (unsigned int)dimm_num);
+				hang();
+				break;
+			case 0x01:
+				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
+				printf("This DIMM is LVTTL.\n");
+				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
+				       (unsigned int)dimm_num);
+				hang();
+				break;
+			case 0x02:
+				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
+				printf("This DIMM is 1.5 Volt.\n");
+				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
+				       (unsigned int)dimm_num);
+				hang();
+				break;
+			case 0x03:
+				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
+				printf("This DIMM is 3.3 Volt/TTL.\n");
+				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
+				       (unsigned int)dimm_num);
+				hang();
+				break;
+			case 0x04:
+				/* 2.5 Voltage only for DDR1 */
+				break;
+			case 0x05:
+				/* 1.8 Voltage only for DDR2 */
+				break;
+			default:
+				printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
+				printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
+				       (unsigned int)dimm_num);
+				hang();
+				break;
+			}
+		}
+	}
+}
+
+/*-----------------------------------------------------------------------------+
+ * program_copt1.
+ *-----------------------------------------------------------------------------*/
+static void program_copt1(unsigned long *dimm_populated,
+			  unsigned char *iic0_dimm_addr,
+			  unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long mcopt1;
+	unsigned long ecc_enabled;
+	unsigned long ecc = 0;
+	unsigned long data_width = 0;
+	unsigned long dimm_32bit;
+	unsigned long dimm_64bit;
+	unsigned long registered = 0;
+	unsigned long attribute = 0;
+	unsigned long buf0, buf1; /* TODO: code to be changed for IOP1.6 to support 4 DIMMs */
+	unsigned long bankcount;
+	unsigned long ddrtype;
+	unsigned long val;
+
+#ifdef CONFIG_DDR_ECC
+	ecc_enabled = TRUE;
+#else
+	ecc_enabled = FALSE;
+#endif
+	dimm_32bit = FALSE;
+	dimm_64bit = FALSE;
+	buf0 = FALSE;
+	buf1 = FALSE;
+
+	/*------------------------------------------------------------------
+	 * Set memory controller options reg 1, SDRAM_MCOPT1.
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MCOPT1, val);
+	mcopt1 = val & ~(SDRAM_MCOPT1_MCHK_MASK | SDRAM_MCOPT1_RDEN_MASK |
+			 SDRAM_MCOPT1_PMU_MASK  | SDRAM_MCOPT1_DMWD_MASK |
+			 SDRAM_MCOPT1_UIOS_MASK | SDRAM_MCOPT1_BCNT_MASK |
+			 SDRAM_MCOPT1_DDR_TYPE_MASK | SDRAM_MCOPT1_RWOO_MASK |
+			 SDRAM_MCOPT1_WOOO_MASK | SDRAM_MCOPT1_DCOO_MASK |
+			 SDRAM_MCOPT1_DREF_MASK);
+
+	mcopt1 |= SDRAM_MCOPT1_QDEP;
+	mcopt1 |= SDRAM_MCOPT1_PMU_OPEN;
+	mcopt1 |= SDRAM_MCOPT1_RWOO_DISABLED;
+	mcopt1 |= SDRAM_MCOPT1_WOOO_DISABLED;
+	mcopt1 |= SDRAM_MCOPT1_DCOO_DISABLED;
+	mcopt1 |= SDRAM_MCOPT1_DREF_NORMAL;
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			/* test ecc support */
+			ecc = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 11);
+			if (ecc != 0x02) /* ecc not supported */
+				ecc_enabled = FALSE;
+
+			/* test bank count */
+			bankcount = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 17);
+			if (bankcount == 0x04) /* bank count = 4 */
+				mcopt1 |= SDRAM_MCOPT1_4_BANKS;
+			else /* bank count = 8 */
+				mcopt1 |= SDRAM_MCOPT1_8_BANKS;
+
+			/* test DDR type */
+			ddrtype = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2);
+			/* test for buffered/unbuffered, registered, differential clocks */
+			registered = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 20);
+			attribute = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 21);
+
+			/* TODO: code to be changed for IOP1.6 to support 4 DIMMs */
+			if (dimm_num == 0) {
+				if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */
+					mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE;
+				if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */
+					mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE;
+				if (registered == 1) { /* DDR2 always buffered */
+					/* TODO: what about above  comments ? */
+					mcopt1 |= SDRAM_MCOPT1_RDEN;
+					buf0 = TRUE;
+				} else {
+					/* TODO: the mask 0x02 doesn't match Samsung def for byte 21. */
+					if ((attribute & 0x02) == 0x00) {
+						/* buffered not supported */
+						buf0 = FALSE;
+					} else {
+						mcopt1 |= SDRAM_MCOPT1_RDEN;
+						buf0 = TRUE;
+					}
+				}
+			}
+			else if (dimm_num == 1) {
+				if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */
+					mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE;
+				if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */
+					mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE;
+				if (registered == 1) {
+					/* DDR2 always buffered */
+					mcopt1 |= SDRAM_MCOPT1_RDEN;
+					buf1 = TRUE;
+				} else {
+					if ((attribute & 0x02) == 0x00) {
+						/* buffered not supported */
+						buf1 = FALSE;
+					} else {
+						mcopt1 |= SDRAM_MCOPT1_RDEN;
+						buf1 = TRUE;
+					}
+				}
+			}
+
+			/* Note that for DDR2 the byte 7 is reserved, but OK to keep code as is. */
+			data_width = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 6) +
+				(((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 7)) << 8);
+
+			switch (data_width) {
+			case 72:
+			case 64:
+				dimm_64bit = TRUE;
+				break;
+			case 40:
+			case 32:
+				dimm_32bit = TRUE;
+				break;
+			default:
+				printf("WARNING: Detected a DIMM with a data width of %d bits.\n",
+				       data_width);
+				printf("Only DIMMs with 32 or 64 bit DDR-SDRAM widths are supported.\n");
+				break;
+			}
+		}
+	}
+
+	/* verify matching properties */
+	if ((dimm_populated[0] != SDRAM_NONE) && (dimm_populated[1] != SDRAM_NONE)) {
+		if (buf0 != buf1) {
+			printf("ERROR: DIMM's buffered/unbuffered, registered, clocking don't match.\n");
+			hang();
+		}
+	}
+
+	if ((dimm_64bit == TRUE) && (dimm_32bit == TRUE)) {
+		printf("ERROR: Cannot mix 32 bit and 64 bit DDR-SDRAM DIMMs together.\n");
+		hang();
+	}
+	else if ((dimm_64bit == TRUE) && (dimm_32bit == FALSE)) {
+		mcopt1 |= SDRAM_MCOPT1_DMWD_64;
+	} else if ((dimm_64bit == FALSE) && (dimm_32bit == TRUE)) {
+		mcopt1 |= SDRAM_MCOPT1_DMWD_32;
+	} else {
+		printf("ERROR: Please install only 32 or 64 bit DDR-SDRAM DIMMs.\n\n");
+		hang();
+	}
+
+	if (ecc_enabled == TRUE)
+		mcopt1 |= SDRAM_MCOPT1_MCHK_GEN;
+	else
+		mcopt1 |= SDRAM_MCOPT1_MCHK_NON;
+
+	mtsdram(SDRAM_MCOPT1, mcopt1);
+}
+
+/*-----------------------------------------------------------------------------+
+ * program_codt.
+ *-----------------------------------------------------------------------------*/
+static void program_codt(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks)
+{
+	unsigned long codt;
+	unsigned long modt0 = 0;
+	unsigned long modt1 = 0;
+	unsigned long modt2 = 0;
+	unsigned long modt3 = 0;
+	unsigned char dimm_num;
+	unsigned char dimm_rank;
+	unsigned char total_rank = 0;
+	unsigned char total_dimm = 0;
+	unsigned char dimm_type = 0;
+	unsigned char firstSlot = 0;
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Controller On Die Termination Register
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_CODT, codt);
+	codt |= (SDRAM_CODT_IO_NMODE
+		 & (~SDRAM_CODT_DQS_SINGLE_END
+		    & ~SDRAM_CODT_CKSE_SINGLE_END
+		    & ~SDRAM_CODT_FEEBBACK_RCV_SINGLE_END
+		    & ~SDRAM_CODT_FEEBBACK_DRV_SINGLE_END));
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			dimm_rank = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 5);
+			if (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08) {
+				dimm_rank = (dimm_rank & 0x0F) + 1;
+				dimm_type = SDRAM_DDR2;
+			} else {
+				dimm_rank = dimm_rank & 0x0F;
+				dimm_type = SDRAM_DDR1;
+			}
+
+			total_rank += dimm_rank;
+			total_dimm++;
+			if ((dimm_num == 0) && (total_dimm == 1))
+				firstSlot = TRUE;
+			else
+				firstSlot = FALSE;
+		}
+	}
+	if (dimm_type == SDRAM_DDR2) {
+		codt |= SDRAM_CODT_DQS_1_8_V_DDR2;
+		if ((total_dimm == 1) && (firstSlot == TRUE)) {
+			if (total_rank == 1) {
+				codt |= CALC_ODT_R(0);
+				modt0 = CALC_ODT_W(0);
+				modt1 = 0x00000000;
+				modt2 = 0x00000000;
+				modt3 = 0x00000000;
+			}
+			if (total_rank == 2) {
+				codt |= CALC_ODT_R(0) | CALC_ODT_R(1);
+				modt0 = CALC_ODT_W(0);
+				modt1 = CALC_ODT_W(0);
+				modt2 = 0x00000000;
+				modt3 = 0x00000000;
+			}
+		} else if ((total_dimm == 1) && (firstSlot != TRUE)) {
+			if (total_rank == 1) {
+				codt |= CALC_ODT_R(2);
+				modt0 = 0x00000000;
+				modt1 = 0x00000000;
+				modt2 = CALC_ODT_W(2);
+				modt3 = 0x00000000;
+			}
+			if (total_rank == 2) {
+				codt |= CALC_ODT_R(2) | CALC_ODT_R(3);
+				modt0 = 0x00000000;
+				modt1 = 0x00000000;
+				modt2 = CALC_ODT_W(2);
+				modt3 = CALC_ODT_W(2);
+			}
+		}
+		if (total_dimm == 2) {
+			if (total_rank == 2) {
+				codt |= CALC_ODT_R(0) | CALC_ODT_R(2);
+				modt0 = CALC_ODT_RW(2);
+				modt1 = 0x00000000;
+				modt2 = CALC_ODT_RW(0);
+				modt3 = 0x00000000;
+			}
+			if (total_rank == 4) {
+				codt |= CALC_ODT_R(0) | CALC_ODT_R(1) | CALC_ODT_R(2) | CALC_ODT_R(3);
+				modt0 = CALC_ODT_RW(2);
+				modt1 = 0x00000000;
+				modt2 = CALC_ODT_RW(0);
+				modt3 = 0x00000000;
+			}
+		}
+  	} else {
+		codt |= SDRAM_CODT_DQS_2_5_V_DDR1;
+		modt0 = 0x00000000;
+		modt1 = 0x00000000;
+		modt2 = 0x00000000;
+		modt3 = 0x00000000;
+
+		if (total_dimm == 1) {
+			if (total_rank == 1)
+				codt |= 0x00800000;
+			if (total_rank == 2)
+				codt |= 0x02800000;
+		}
+		if (total_dimm == 2) {
+			if (total_rank == 2)
+				codt |= 0x08800000;
+			if (total_rank == 4)
+				codt |= 0x2a800000;
+		}
+	}
+
+	debug("nb of dimm %d\n", total_dimm);
+	debug("nb of rank %d\n", total_rank);
+	if (total_dimm == 1)
+		debug("dimm in slot %d\n", firstSlot);
+
+	mtsdram(SDRAM_CODT, codt);
+	mtsdram(SDRAM_MODT0, modt0);
+	mtsdram(SDRAM_MODT1, modt1);
+	mtsdram(SDRAM_MODT2, modt2);
+	mtsdram(SDRAM_MODT3, modt3);
+}
+
+/*-----------------------------------------------------------------------------+
+ * program_initplr.
+ *-----------------------------------------------------------------------------*/
+static void program_initplr(unsigned long *dimm_populated,
+			    unsigned char *iic0_dimm_addr,
+			    unsigned long num_dimm_banks,
+			    ddr_cas_id_t selected_cas,
+			    int write_recovery)
+{
+	u32 cas = 0;
+	u32 odt = 0;
+	u32 ods = 0;
+	u32 mr;
+	u32 wr;
+	u32 emr;
+	u32 emr2;
+	u32 emr3;
+	int dimm_num;
+	int total_dimm = 0;
+
+	/******************************************************
+	 ** Assumption: if more than one DIMM, all DIMMs are the same
+	 **		as already checked in check_memory_type
+	 ******************************************************/
+
+	if ((dimm_populated[0] == SDRAM_DDR1) || (dimm_populated[1] == SDRAM_DDR1)) {
+		mtsdram(SDRAM_INITPLR0, 0x81B80000);
+		mtsdram(SDRAM_INITPLR1, 0x81900400);
+		mtsdram(SDRAM_INITPLR2, 0x81810000);
+		mtsdram(SDRAM_INITPLR3, 0xff800162);
+		mtsdram(SDRAM_INITPLR4, 0x81900400);
+		mtsdram(SDRAM_INITPLR5, 0x86080000);
+		mtsdram(SDRAM_INITPLR6, 0x86080000);
+		mtsdram(SDRAM_INITPLR7, 0x81000062);
+	} else if ((dimm_populated[0] == SDRAM_DDR2) || (dimm_populated[1] == SDRAM_DDR2)) {
+		switch (selected_cas) {
+		case DDR_CAS_3:
+			cas = 3 << 4;
+			break;
+		case DDR_CAS_4:
+			cas = 4 << 4;
+			break;
+		case DDR_CAS_5:
+			cas = 5 << 4;
+			break;
+		default:
+			printf("ERROR: ucode error on selected_cas value %d", selected_cas);
+			hang();
+			break;
+		}
+
+#if 0
+		/*
+		 * ToDo - Still a problem with the write recovery:
+		 * On the Corsair CM2X512-5400C4 module, setting write recovery
+		 * in the INITPLR reg to the value calculated in program_mode()
+		 * results in not correctly working DDR2 memory (crash after
+		 * relocation).
+		 *
+		 * So for now, set the write recovery to 3. This seems to work
+		 * on the Corair module too.
+		 *
+		 * 2007-03-01, sr
+		 */
+		switch (write_recovery) {
+		case 3:
+			wr = WRITE_RECOV_3;
+			break;
+		case 4:
+			wr = WRITE_RECOV_4;
+			break;
+		case 5:
+			wr = WRITE_RECOV_5;
+			break;
+		case 6:
+			wr = WRITE_RECOV_6;
+			break;
+		default:
+			printf("ERROR: write recovery not support (%d)", write_recovery);
+			hang();
+			break;
+		}
+#else
+		wr = WRITE_RECOV_3; /* test-only, see description above */
+#endif
+
+		for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++)
+			if (dimm_populated[dimm_num] != SDRAM_NONE)
+				total_dimm++;
+		if (total_dimm == 1) {
+			odt = ODT_150_OHM;
+			ods = ODS_FULL;
+		} else if (total_dimm == 2) {
+			odt = ODT_75_OHM;
+			ods = ODS_REDUCED;
+		} else {
+			printf("ERROR: Unsupported number of DIMM's (%d)", total_dimm);
+			hang();
+		}
+
+		mr = CMD_EMR | SELECT_MR | BURST_LEN_4 | wr | cas;
+		emr = CMD_EMR | SELECT_EMR | odt | ods;
+		emr2 = CMD_EMR | SELECT_EMR2;
+		emr3 = CMD_EMR | SELECT_EMR3;
+		mtsdram(SDRAM_INITPLR0,  0xB5000000 | CMD_NOP);		/* NOP */
+		udelay(1000);
+		mtsdram(SDRAM_INITPLR1,  0x82000400 | CMD_PRECHARGE);	/* precharge 8 DDR clock cycle */
+		mtsdram(SDRAM_INITPLR2,  0x80800000 | emr2);		/* EMR2 */
+		mtsdram(SDRAM_INITPLR3,  0x80800000 | emr3);		/* EMR3 */
+		mtsdram(SDRAM_INITPLR4,  0x80800000 | emr);		/* EMR DLL ENABLE */
+		mtsdram(SDRAM_INITPLR5,  0x80800000 | mr | DLL_RESET);	/* MR w/ DLL reset */
+		udelay(1000);
+		mtsdram(SDRAM_INITPLR6,  0x82000400 | CMD_PRECHARGE);	/* precharge 8 DDR clock cycle */
+		mtsdram(SDRAM_INITPLR7,  0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
+		mtsdram(SDRAM_INITPLR8,  0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
+		mtsdram(SDRAM_INITPLR9,  0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
+		mtsdram(SDRAM_INITPLR10, 0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
+		mtsdram(SDRAM_INITPLR11, 0x80000000 | mr);		/* MR w/o DLL reset */
+		mtsdram(SDRAM_INITPLR12, 0x80800380 | emr);		/* EMR OCD Default */
+		mtsdram(SDRAM_INITPLR13, 0x80800000 | emr);		/* EMR OCD Exit */
+	} else {
+		printf("ERROR: ucode error as unknown DDR type in program_initplr");
+		hang();
+	}
+}
+
+/*------------------------------------------------------------------
+ * This routine programs the SDRAM_MMODE register.
+ * the selected_cas is an output parameter, that will be passed
+ * by caller to call the above program_initplr( )
+ *-----------------------------------------------------------------*/
+static void program_mode(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks,
+			 ddr_cas_id_t *selected_cas,
+			 int *write_recovery)
+{
+	unsigned long dimm_num;
+	unsigned long sdram_ddr1;
+	unsigned long t_wr_ns;
+	unsigned long t_wr_clk;
+	unsigned long cas_bit;
+	unsigned long cas_index;
+	unsigned long sdram_freq;
+	unsigned long ddr_check;
+	unsigned long mmode;
+	unsigned long tcyc_reg;
+	unsigned long cycle_2_0_clk;
+	unsigned long cycle_2_5_clk;
+	unsigned long cycle_3_0_clk;
+	unsigned long cycle_4_0_clk;
+	unsigned long cycle_5_0_clk;
+	unsigned long max_2_0_tcyc_ns_x_100;
+	unsigned long max_2_5_tcyc_ns_x_100;
+	unsigned long max_3_0_tcyc_ns_x_100;
+	unsigned long max_4_0_tcyc_ns_x_100;
+	unsigned long max_5_0_tcyc_ns_x_100;
+	unsigned long cycle_time_ns_x_100[3];
+	PPC440_SYS_INFO board_cfg;
+	unsigned char cas_2_0_available;
+	unsigned char cas_2_5_available;
+	unsigned char cas_3_0_available;
+	unsigned char cas_4_0_available;
+	unsigned char cas_5_0_available;
+	unsigned long sdr_ddrpll;
+
+	/*------------------------------------------------------------------
+	 * Get the board configuration info.
+	 *-----------------------------------------------------------------*/
+	get_sys_info(&board_cfg);
+
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
+	sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1);
+
+	/*------------------------------------------------------------------
+	 * Handle the timing.  We need to find the worst case timing of all
+	 * the dimm modules installed.
+	 *-----------------------------------------------------------------*/
+	t_wr_ns = 0;
+	cas_2_0_available = TRUE;
+	cas_2_5_available = TRUE;
+	cas_3_0_available = TRUE;
+	cas_4_0_available = TRUE;
+	cas_5_0_available = TRUE;
+	max_2_0_tcyc_ns_x_100 = 10;
+	max_2_5_tcyc_ns_x_100 = 10;
+	max_3_0_tcyc_ns_x_100 = 10;
+	max_4_0_tcyc_ns_x_100 = 10;
+	max_5_0_tcyc_ns_x_100 = 10;
+	sdram_ddr1 = TRUE;
+
+	/* loop through all the DIMM slots on the board */
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		/* If a dimm is installed in a particular slot ... */
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			if (dimm_populated[dimm_num] == SDRAM_DDR1)
+				sdram_ddr1 = TRUE;
+			else
+				sdram_ddr1 = FALSE;
+
+			/* t_wr_ns = max(t_wr_ns, (unsigned long)dimm_spd[dimm_num][36] >> 2); */ /*  not used in this loop. */
+			cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18);
+
+			/* For a particular DIMM, grab the three CAS values it supports */
+			for (cas_index = 0; cas_index < 3; cas_index++) {
+				switch (cas_index) {
+				case 0:
+					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);
+					break;
+				case 1:
+					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23);
+					break;
+				default:
+					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25);
+					break;
+				}
+
+				if ((tcyc_reg & 0x0F) >= 10) {
+					if ((tcyc_reg & 0x0F) == 0x0D) {
+						/* Convert from hex to decimal */
+						cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + 75;
+					} else {
+						printf("ERROR: SPD reported Tcyc is incorrect for DIMM "
+						       "in slot %d\n", (unsigned int)dimm_num);
+						hang();
+					}
+				} else {
+					/* Convert from hex to decimal */
+					cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) +
+						((tcyc_reg & 0x0F)*10);
+				}
+			}
+
+			/* The rest of this routine determines if CAS 2.0, 2.5, 3.0, 4.0 and 5.0 are */
+			/* supported for a particular DIMM. */
+			cas_index = 0;
+
+			if (sdram_ddr1) {
+				/*
+				 * DDR devices use the following bitmask for CAS latency:
+				 *  Bit   7    6    5    4    3    2    1    0
+				 *       TBD  4.0  3.5  3.0  2.5  2.0  1.5  1.0
+				 */
+				if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
+					max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+					cas_index++;
+				} else {
+					if (cas_index != 0)
+						cas_index++;
+					cas_4_0_available = FALSE;
+				}
+
+				if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
+					max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+					cas_index++;
+				} else {
+					if (cas_index != 0)
+						cas_index++;
+					cas_3_0_available = FALSE;
+				}
+
+				if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
+					max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+					cas_index++;
+				} else {
+					if (cas_index != 0)
+						cas_index++;
+					cas_2_5_available = FALSE;
+				}
+
+				if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
+					max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+					cas_index++;
+				} else {
+					if (cas_index != 0)
+						cas_index++;
+					cas_2_0_available = FALSE;
+				}
+			} else {
+				/*
+				 * DDR2 devices use the following bitmask for CAS latency:
+				 *  Bit   7    6    5    4    3    2    1    0
+				 *       TBD  6.0  5.0  4.0  3.0  2.0  TBD  TBD
+				 */
+				if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
+					max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+					cas_index++;
+				} else {
+					if (cas_index != 0)
+						cas_index++;
+					cas_5_0_available = FALSE;
+				}
+
+				if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
+					max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+					cas_index++;
+				} else {
+					if (cas_index != 0)
+						cas_index++;
+					cas_4_0_available = FALSE;
+				}
+
+				if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
+					max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+					cas_index++;
+				} else {
+					if (cas_index != 0)
+						cas_index++;
+					cas_3_0_available = FALSE;
+				}
+			}
+		}
+	}
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM mode, SDRAM_MMODE
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MMODE, mmode);
+	mmode = mmode & ~(SDRAM_MMODE_WR_MASK | SDRAM_MMODE_DCL_MASK);
+
+	/* add 10 here because of rounding problems */
+	cycle_2_0_clk = MULDIV64(ONE_BILLION, 100, max_2_0_tcyc_ns_x_100) + 10;
+	cycle_2_5_clk = MULDIV64(ONE_BILLION, 100, max_2_5_tcyc_ns_x_100) + 10;
+	cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100) + 10;
+	cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100) + 10;
+	cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100) + 10;
+
+	if (sdram_ddr1 == TRUE) { /* DDR1 */
+		if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) {
+			mmode |= SDRAM_MMODE_DCL_DDR1_2_0_CLK;
+			*selected_cas = DDR_CAS_2;
+		} else if ((cas_2_5_available == TRUE) && (sdram_freq <= cycle_2_5_clk)) {
+			mmode |= SDRAM_MMODE_DCL_DDR1_2_5_CLK;
+			*selected_cas = DDR_CAS_2_5;
+		} else if ((cas_3_0_available == TRUE) && (sdram_freq <= cycle_3_0_clk)) {
+			mmode |= SDRAM_MMODE_DCL_DDR1_3_0_CLK;
+			*selected_cas = DDR_CAS_3;
+		} else {
+			printf("ERROR: Cannot find a supported CAS latency with the installed DIMMs.\n");
+			printf("Only DIMMs DDR1 with CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
+			printf("Make sure the PLB speed is within the supported range of the DIMMs.\n\n");
+			hang();
+		}
+	} else { /* DDR2 */
+		if ((cas_3_0_available == TRUE) && (sdram_freq <= cycle_3_0_clk)) {
+			mmode |= SDRAM_MMODE_DCL_DDR2_3_0_CLK;
+			*selected_cas = DDR_CAS_3;
+		} else if ((cas_4_0_available == TRUE) && (sdram_freq <= cycle_4_0_clk)) {
+			mmode |= SDRAM_MMODE_DCL_DDR2_4_0_CLK;
+			*selected_cas = DDR_CAS_4;
+		} else if ((cas_5_0_available == TRUE) && (sdram_freq <= cycle_5_0_clk)) {
+			mmode |= SDRAM_MMODE_DCL_DDR2_5_0_CLK;
+			*selected_cas = DDR_CAS_5;
+		} else {
+			printf("ERROR: Cannot find a supported CAS latency with the installed DIMMs.\n");
+			printf("Only DIMMs DDR2 with CAS latencies of 3.0, 4.0, and 5.0 are supported.\n");
+			printf("Make sure the PLB speed is within the supported range of the DIMMs.\n");
+			printf("cas3=%d cas4=%d cas5=%d\n",
+			       cas_3_0_available, cas_4_0_available, cas_5_0_available);
+			printf("sdram_freq=%d cycle3=%d cycle4=%d cycle5=%d\n\n",
+			       sdram_freq, cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk);
+			hang();
+		}
+	}
+
+	if (sdram_ddr1 == TRUE)
+		mmode |= SDRAM_MMODE_WR_DDR1;
+	else {
+
+		/* loop through all the DIMM slots on the board */
+		for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+			/* If a dimm is installed in a particular slot ... */
+			if (dimm_populated[dimm_num] != SDRAM_NONE)
+				t_wr_ns = max(t_wr_ns,
+					      spd_read(iic0_dimm_addr[dimm_num], 36) >> 2);
+		}
+
+		/*
+		 * convert from nanoseconds to ddr clocks
+		 * round up if necessary
+		 */
+		t_wr_clk = MULDIV64(sdram_freq, t_wr_ns, ONE_BILLION);
+		ddr_check = MULDIV64(ONE_BILLION, t_wr_clk, t_wr_ns);
+		if (sdram_freq != ddr_check)
+			t_wr_clk++;
+
+		switch (t_wr_clk) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+			mmode |= SDRAM_MMODE_WR_DDR2_3_CYC;
+			break;
+		case 4:
+			mmode |= SDRAM_MMODE_WR_DDR2_4_CYC;
+			break;
+		case 5:
+			mmode |= SDRAM_MMODE_WR_DDR2_5_CYC;
+			break;
+		default:
+			mmode |= SDRAM_MMODE_WR_DDR2_6_CYC;
+			break;
+		}
+		*write_recovery = t_wr_clk;
+	}
+
+	debug("CAS latency = %d\n", *selected_cas);
+	debug("Write recovery = %d\n", *write_recovery);
+
+	mtsdram(SDRAM_MMODE, mmode);
+}
+
+/*-----------------------------------------------------------------------------+
+ * program_rtr.
+ *-----------------------------------------------------------------------------*/
+static void program_rtr(unsigned long *dimm_populated,
+			unsigned char *iic0_dimm_addr,
+			unsigned long num_dimm_banks)
+{
+	PPC440_SYS_INFO board_cfg;
+	unsigned long max_refresh_rate;
+	unsigned long dimm_num;
+	unsigned long refresh_rate_type;
+	unsigned long refresh_rate;
+	unsigned long rint;
+	unsigned long sdram_freq;
+	unsigned long sdr_ddrpll;
+	unsigned long val;
+
+	/*------------------------------------------------------------------
+	 * Get the board configuration info.
+	 *-----------------------------------------------------------------*/
+	get_sys_info(&board_cfg);
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Refresh Timing Register, SDRAM_RTR
+	 *-----------------------------------------------------------------*/
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
+	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
+
+	max_refresh_rate = 0;
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+
+			refresh_rate_type = spd_read(iic0_dimm_addr[dimm_num], 12);
+			refresh_rate_type &= 0x7F;
+			switch (refresh_rate_type) {
+			case 0:
+				refresh_rate =  15625;
+				break;
+			case 1:
+				refresh_rate =   3906;
+				break;
+			case 2:
+				refresh_rate =   7812;
+				break;
+			case 3:
+				refresh_rate =  31250;
+				break;
+			case 4:
+				refresh_rate =  62500;
+				break;
+			case 5:
+				refresh_rate = 125000;
+				break;
+			default:
+				refresh_rate = 0;
+				printf("ERROR: DIMM %d unsupported refresh rate/type.\n",
+				       (unsigned int)dimm_num);
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+				break;
+			}
+
+			max_refresh_rate = max(max_refresh_rate, refresh_rate);
+		}
+	}
+
+	rint = MULDIV64(sdram_freq, max_refresh_rate, ONE_BILLION);
+	mfsdram(SDRAM_RTR, val);
+	mtsdram(SDRAM_RTR, (val & ~SDRAM_RTR_RINT_MASK) |
+		(SDRAM_RTR_RINT_ENCODE(rint)));
+}
+
+/*------------------------------------------------------------------
+ * This routine programs the SDRAM_TRx registers.
+ *-----------------------------------------------------------------*/
+static void program_tr(unsigned long *dimm_populated,
+		       unsigned char *iic0_dimm_addr,
+		       unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long sdram_ddr1;
+	unsigned long t_rp_ns;
+	unsigned long t_rcd_ns;
+	unsigned long t_rrd_ns;
+	unsigned long t_ras_ns;
+	unsigned long t_rc_ns;
+	unsigned long t_rfc_ns;
+	unsigned long t_wpc_ns;
+	unsigned long t_wtr_ns;
+	unsigned long t_rpc_ns;
+	unsigned long t_rp_clk;
+	unsigned long t_rcd_clk;
+	unsigned long t_rrd_clk;
+	unsigned long t_ras_clk;
+	unsigned long t_rc_clk;
+	unsigned long t_rfc_clk;
+	unsigned long t_wpc_clk;
+	unsigned long t_wtr_clk;
+	unsigned long t_rpc_clk;
+	unsigned long sdtr1, sdtr2, sdtr3;
+	unsigned long ddr_check;
+	unsigned long sdram_freq;
+	unsigned long sdr_ddrpll;
+
+	PPC440_SYS_INFO board_cfg;
+
+	/*------------------------------------------------------------------
+	 * Get the board configuration info.
+	 *-----------------------------------------------------------------*/
+	get_sys_info(&board_cfg);
+
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
+	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
+
+	/*------------------------------------------------------------------
+	 * Handle the timing.  We need to find the worst case timing of all
+	 * the dimm modules installed.
+	 *-----------------------------------------------------------------*/
+	t_rp_ns = 0;
+	t_rrd_ns = 0;
+	t_rcd_ns = 0;
+	t_ras_ns = 0;
+	t_rc_ns = 0;
+	t_rfc_ns = 0;
+	t_wpc_ns = 0;
+	t_wtr_ns = 0;
+	t_rpc_ns = 0;
+	sdram_ddr1 = TRUE;
+
+	/* loop through all the DIMM slots on the board */
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		/* If a dimm is installed in a particular slot ... */
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			if (dimm_populated[dimm_num] == SDRAM_DDR2)
+				sdram_ddr1 = TRUE;
+			else
+				sdram_ddr1 = FALSE;
+
+			t_rcd_ns = max(t_rcd_ns, spd_read(iic0_dimm_addr[dimm_num], 29) >> 2);
+			t_rrd_ns = max(t_rrd_ns, spd_read(iic0_dimm_addr[dimm_num], 28) >> 2);
+			t_rp_ns  = max(t_rp_ns,  spd_read(iic0_dimm_addr[dimm_num], 27) >> 2);
+			t_ras_ns = max(t_ras_ns, spd_read(iic0_dimm_addr[dimm_num], 30));
+			t_rc_ns  = max(t_rc_ns,  spd_read(iic0_dimm_addr[dimm_num], 41));
+			t_rfc_ns = max(t_rfc_ns, spd_read(iic0_dimm_addr[dimm_num], 42));
+		}
+	}
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Timing Reg 1, SDRAM_TR1
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_SDTR1, sdtr1);
+	sdtr1 &= ~(SDRAM_SDTR1_LDOF_MASK | SDRAM_SDTR1_RTW_MASK |
+		   SDRAM_SDTR1_WTWO_MASK | SDRAM_SDTR1_RTRO_MASK);
+
+	/* default values */
+	sdtr1 |= SDRAM_SDTR1_LDOF_2_CLK;
+	sdtr1 |= SDRAM_SDTR1_RTW_2_CLK;
+
+	/* normal operations */
+	sdtr1 |= SDRAM_SDTR1_WTWO_0_CLK;
+	sdtr1 |= SDRAM_SDTR1_RTRO_1_CLK;
+
+	mtsdram(SDRAM_SDTR1, sdtr1);
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Timing Reg 2, SDRAM_TR2
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_SDTR2, sdtr2);
+	sdtr2 &= ~(SDRAM_SDTR2_RCD_MASK  | SDRAM_SDTR2_WTR_MASK |
+		   SDRAM_SDTR2_XSNR_MASK | SDRAM_SDTR2_WPC_MASK |
+		   SDRAM_SDTR2_RPC_MASK  | SDRAM_SDTR2_RP_MASK  |
+		   SDRAM_SDTR2_RRD_MASK);
+
+	/*
+	 * convert t_rcd from nanoseconds to ddr clocks
+	 * round up if necessary
+	 */
+	t_rcd_clk = MULDIV64(sdram_freq, t_rcd_ns, ONE_BILLION);
+	ddr_check = MULDIV64(ONE_BILLION, t_rcd_clk, t_rcd_ns);
+	if (sdram_freq != ddr_check)
+		t_rcd_clk++;
+
+	switch (t_rcd_clk) {
+	case 0:
+	case 1:
+		sdtr2 |= SDRAM_SDTR2_RCD_1_CLK;
+		break;
+	case 2:
+		sdtr2 |= SDRAM_SDTR2_RCD_2_CLK;
+		break;
+	case 3:
+		sdtr2 |= SDRAM_SDTR2_RCD_3_CLK;
+		break;
+	case 4:
+		sdtr2 |= SDRAM_SDTR2_RCD_4_CLK;
+		break;
+	default:
+		sdtr2 |= SDRAM_SDTR2_RCD_5_CLK;
+		break;
+	}
+
+	if (sdram_ddr1 == TRUE) { /* DDR1 */
+		if (sdram_freq < 200000000) {
+			sdtr2 |= SDRAM_SDTR2_WTR_1_CLK;
+			sdtr2 |= SDRAM_SDTR2_WPC_2_CLK;
+			sdtr2 |= SDRAM_SDTR2_RPC_2_CLK;
+		} else {
+			sdtr2 |= SDRAM_SDTR2_WTR_2_CLK;
+			sdtr2 |= SDRAM_SDTR2_WPC_3_CLK;
+			sdtr2 |= SDRAM_SDTR2_RPC_2_CLK;
+		}
+	} else { /* DDR2 */
+		/* loop through all the DIMM slots on the board */
+		for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+			/* If a dimm is installed in a particular slot ... */
+			if (dimm_populated[dimm_num] != SDRAM_NONE) {
+				t_wpc_ns = max(t_wtr_ns, spd_read(iic0_dimm_addr[dimm_num], 36) >> 2);
+				t_wtr_ns = max(t_wtr_ns, spd_read(iic0_dimm_addr[dimm_num], 37) >> 2);
+				t_rpc_ns = max(t_rpc_ns, spd_read(iic0_dimm_addr[dimm_num], 38) >> 2);
+			}
+		}
+
+		/*
+		 * convert from nanoseconds to ddr clocks
+		 * round up if necessary
+		 */
+		t_wpc_clk = MULDIV64(sdram_freq, t_wpc_ns, ONE_BILLION);
+		ddr_check = MULDIV64(ONE_BILLION, t_wpc_clk, t_wpc_ns);
+		if (sdram_freq != ddr_check)
+			t_wpc_clk++;
+
+		switch (t_wpc_clk) {
+		case 0:
+		case 1:
+		case 2:
+			sdtr2 |= SDRAM_SDTR2_WPC_2_CLK;
+			break;
+		case 3:
+			sdtr2 |= SDRAM_SDTR2_WPC_3_CLK;
+			break;
+		case 4:
+			sdtr2 |= SDRAM_SDTR2_WPC_4_CLK;
+			break;
+		case 5:
+			sdtr2 |= SDRAM_SDTR2_WPC_5_CLK;
+			break;
+		default:
+			sdtr2 |= SDRAM_SDTR2_WPC_6_CLK;
+			break;
+		}
+
+		/*
+		 * convert from nanoseconds to ddr clocks
+		 * round up if necessary
+		 */
+		t_wtr_clk = MULDIV64(sdram_freq, t_wtr_ns, ONE_BILLION);
+		ddr_check = MULDIV64(ONE_BILLION, t_wtr_clk, t_wtr_ns);
+		if (sdram_freq != ddr_check)
+			t_wtr_clk++;
+
+		switch (t_wtr_clk) {
+		case 0:
+		case 1:
+			sdtr2 |= SDRAM_SDTR2_WTR_1_CLK;
+			break;
+		case 2:
+			sdtr2 |= SDRAM_SDTR2_WTR_2_CLK;
+			break;
+		case 3:
+			sdtr2 |= SDRAM_SDTR2_WTR_3_CLK;
+			break;
+		default:
+			sdtr2 |= SDRAM_SDTR2_WTR_4_CLK;
+			break;
+		}
+
+		/*
+		 * convert from nanoseconds to ddr clocks
+		 * round up if necessary
+		 */
+		t_rpc_clk = MULDIV64(sdram_freq, t_rpc_ns, ONE_BILLION);
+		ddr_check = MULDIV64(ONE_BILLION, t_rpc_clk, t_rpc_ns);
+		if (sdram_freq != ddr_check)
+			t_rpc_clk++;
+
+		switch (t_rpc_clk) {
+		case 0:
+		case 1:
+		case 2:
+			sdtr2 |= SDRAM_SDTR2_RPC_2_CLK;
+			break;
+		case 3:
+			sdtr2 |= SDRAM_SDTR2_RPC_3_CLK;
+			break;
+		default:
+			sdtr2 |= SDRAM_SDTR2_RPC_4_CLK;
+			break;
+		}
+	}
+
+	/* default value */
+	sdtr2 |= SDRAM_SDTR2_XSNR_16_CLK;
+
+	/*
+	 * convert t_rrd from nanoseconds to ddr clocks
+	 * round up if necessary
+	 */
+	t_rrd_clk = MULDIV64(sdram_freq, t_rrd_ns, ONE_BILLION);
+	ddr_check = MULDIV64(ONE_BILLION, t_rrd_clk, t_rrd_ns);
+	if (sdram_freq != ddr_check)
+		t_rrd_clk++;
+
+	if (t_rrd_clk == 3)
+		sdtr2 |= SDRAM_SDTR2_RRD_3_CLK;
+	else
+		sdtr2 |= SDRAM_SDTR2_RRD_2_CLK;
+
+	/*
+	 * convert t_rp from nanoseconds to ddr clocks
+	 * round up if necessary
+	 */
+	t_rp_clk = MULDIV64(sdram_freq, t_rp_ns, ONE_BILLION);
+	ddr_check = MULDIV64(ONE_BILLION, t_rp_clk, t_rp_ns);
+	if (sdram_freq != ddr_check)
+		t_rp_clk++;
+
+	switch (t_rp_clk) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+		sdtr2 |= SDRAM_SDTR2_RP_3_CLK;
+		break;
+	case 4:
+		sdtr2 |= SDRAM_SDTR2_RP_4_CLK;
+		break;
+	case 5:
+		sdtr2 |= SDRAM_SDTR2_RP_5_CLK;
+		break;
+	case 6:
+		sdtr2 |= SDRAM_SDTR2_RP_6_CLK;
+		break;
+	default:
+		sdtr2 |= SDRAM_SDTR2_RP_7_CLK;
+		break;
+	}
+
+	mtsdram(SDRAM_SDTR2, sdtr2);
+
+	/*------------------------------------------------------------------
+	 * Set the SDRAM Timing Reg 3, SDRAM_TR3
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_SDTR3, sdtr3);
+	sdtr3 &= ~(SDRAM_SDTR3_RAS_MASK  | SDRAM_SDTR3_RC_MASK |
+		   SDRAM_SDTR3_XCS_MASK | SDRAM_SDTR3_RFC_MASK);
+
+	/*
+	 * convert t_ras from nanoseconds to ddr clocks
+	 * round up if necessary
+	 */
+	t_ras_clk = MULDIV64(sdram_freq, t_ras_ns, ONE_BILLION);
+	ddr_check = MULDIV64(ONE_BILLION, t_ras_clk, t_ras_ns);
+	if (sdram_freq != ddr_check)
+		t_ras_clk++;
+
+	sdtr3 |= SDRAM_SDTR3_RAS_ENCODE(t_ras_clk);
+
+	/*
+	 * convert t_rc from nanoseconds to ddr clocks
+	 * round up if necessary
+	 */
+	t_rc_clk = MULDIV64(sdram_freq, t_rc_ns, ONE_BILLION);
+	ddr_check = MULDIV64(ONE_BILLION, t_rc_clk, t_rc_ns);
+	if (sdram_freq != ddr_check)
+		t_rc_clk++;
+
+	sdtr3 |= SDRAM_SDTR3_RC_ENCODE(t_rc_clk);
+
+	/* default xcs value */
+	sdtr3 |= SDRAM_SDTR3_XCS;
+
+	/*
+	 * convert t_rfc from nanoseconds to ddr clocks
+	 * round up if necessary
+	 */
+	t_rfc_clk = MULDIV64(sdram_freq, t_rfc_ns, ONE_BILLION);
+	ddr_check = MULDIV64(ONE_BILLION, t_rfc_clk, t_rfc_ns);
+	if (sdram_freq != ddr_check)
+		t_rfc_clk++;
+
+	sdtr3 |= SDRAM_SDTR3_RFC_ENCODE(t_rfc_clk);
+
+	mtsdram(SDRAM_SDTR3, sdtr3);
+}
+
+/*-----------------------------------------------------------------------------+
+ * program_bxcf.
+ *-----------------------------------------------------------------------------*/
+static void program_bxcf(unsigned long *dimm_populated,
+			 unsigned char *iic0_dimm_addr,
+			 unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long num_col_addr;
+	unsigned long num_ranks;
+	unsigned long num_banks;
+	unsigned long mode;
+	unsigned long ind_rank;
+	unsigned long ind;
+	unsigned long ind_bank;
+	unsigned long bank_0_populated;
+
+	/*------------------------------------------------------------------
+	 * Set the BxCF regs.  First, wipe out the bank config registers.
+	 *-----------------------------------------------------------------*/
+	mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF);
+	mtdcr(SDRAMC_CFGDATA, 0x00000000);
+	mtdcr(SDRAMC_CFGADDR, SDRAM_MB1CF);
+	mtdcr(SDRAMC_CFGDATA, 0x00000000);
+	mtdcr(SDRAMC_CFGADDR, SDRAM_MB2CF);
+	mtdcr(SDRAMC_CFGDATA, 0x00000000);
+	mtdcr(SDRAMC_CFGADDR, SDRAM_MB3CF);
+	mtdcr(SDRAMC_CFGDATA, 0x00000000);
+
+	mode = SDRAM_BXCF_M_BE_ENABLE;
+
+	bank_0_populated = 0;
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);
+			num_ranks = spd_read(iic0_dimm_addr[dimm_num], 5);
+			if ((spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08)
+				num_ranks = (num_ranks & 0x0F) +1;
+			else
+				num_ranks = num_ranks & 0x0F;
+
+			num_banks = spd_read(iic0_dimm_addr[dimm_num], 17);
+
+			for (ind_bank = 0; ind_bank < 2; ind_bank++) {
+				if (num_banks == 4)
+					ind = 0;
+				else
+					ind = 5;
+				switch (num_col_addr) {
+				case 0x08:
+					mode |= (SDRAM_BXCF_M_AM_0 + ind);
+					break;
+				case 0x09:
+					mode |= (SDRAM_BXCF_M_AM_1 + ind);
+					break;
+				case 0x0A:
+					mode |= (SDRAM_BXCF_M_AM_2 + ind);
+					break;
+				case 0x0B:
+					mode |= (SDRAM_BXCF_M_AM_3 + ind);
+					break;
+				case 0x0C:
+					mode |= (SDRAM_BXCF_M_AM_4 + ind);
+					break;
+				default:
+					printf("DDR-SDRAM: DIMM %d BxCF configuration.\n",
+					       (unsigned int)dimm_num);
+					printf("ERROR: Unsupported value for number of "
+					       "column addresses: %d.\n", (unsigned int)num_col_addr);
+					printf("Replace the DIMM module with a supported DIMM.\n\n");
+					hang();
+				}
+			}
+
+			if ((dimm_populated[dimm_num] != SDRAM_NONE)&& (dimm_num ==1))
+				bank_0_populated = 1;
+
+			for (ind_rank = 0; ind_rank < num_ranks; ind_rank++) {
+				mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF + ((dimm_num + bank_0_populated + ind_rank) << 2));
+				mtdcr(SDRAMC_CFGDATA, mode);
+			}
+		}
+	}
+}
+
+/*------------------------------------------------------------------
+ * program memory queue.
+ *-----------------------------------------------------------------*/
+static void program_memory_queue(unsigned long *dimm_populated,
+				 unsigned char *iic0_dimm_addr,
+				 unsigned long num_dimm_banks)
+{
+	unsigned long dimm_num;
+	unsigned long rank_base_addr;
+	unsigned long rank_reg;
+	unsigned long rank_size_bytes;
+	unsigned long rank_size_id;
+	unsigned long num_ranks;
+	unsigned long baseadd_size;
+	unsigned long i;
+	unsigned long bank_0_populated = 0;
+
+	/*------------------------------------------------------------------
+	 * Reset the rank_base_address.
+	 *-----------------------------------------------------------------*/
+	rank_reg   = SDRAM_R0BAS;
+
+	rank_base_addr = 0x00000000;
+
+	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+		if (dimm_populated[dimm_num] != SDRAM_NONE) {
+			num_ranks = spd_read(iic0_dimm_addr[dimm_num], 5);
+			if ((spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08)
+				num_ranks = (num_ranks & 0x0F) + 1;
+			else
+				num_ranks = num_ranks & 0x0F;
+
+			rank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);
+
+			/*------------------------------------------------------------------
+			 * Set the sizes
+			 *-----------------------------------------------------------------*/
+			baseadd_size = 0;
+			rank_size_bytes = 4 * 1024 * 1024 * rank_size_id;
+			switch (rank_size_id) {
+			case 0x02:
+				baseadd_size |= SDRAM_RXBAS_SDSZ_8;
+				break;
+			case 0x04:
+				baseadd_size |= SDRAM_RXBAS_SDSZ_16;
+				break;
+			case 0x08:
+				baseadd_size |= SDRAM_RXBAS_SDSZ_32;
+				break;
+			case 0x10:
+				baseadd_size |= SDRAM_RXBAS_SDSZ_64;
+				break;
+			case 0x20:
+				baseadd_size |= SDRAM_RXBAS_SDSZ_128;
+				break;
+			case 0x40:
+				baseadd_size |= SDRAM_RXBAS_SDSZ_256;
+				break;
+			case 0x80:
+				baseadd_size |= SDRAM_RXBAS_SDSZ_512;
+				break;
+			default:
+				printf("DDR-SDRAM: DIMM %d memory queue configuration.\n",
+				       (unsigned int)dimm_num);
+				printf("ERROR: Unsupported value for the banksize: %d.\n",
+				       (unsigned int)rank_size_id);
+				printf("Replace the DIMM module with a supported DIMM.\n\n");
+				hang();
+			}
+
+			if ((dimm_populated[dimm_num] != SDRAM_NONE) && (dimm_num == 1))
+				bank_0_populated = 1;
+
+			for (i = 0; i < num_ranks; i++)	{
+				mtdcr_any(rank_reg+i+dimm_num+bank_0_populated,
+					  (SDRAM_RXBAS_SDBA_ENCODE(rank_base_addr) |
+					   baseadd_size));
+				rank_base_addr += rank_size_bytes;
+			}
+		}
+	}
+}
+
+/*-----------------------------------------------------------------------------+
+ * is_ecc_enabled.
+ *-----------------------------------------------------------------------------*/
+static unsigned long is_ecc_enabled(void)
+{
+	unsigned long dimm_num;
+	unsigned long ecc;
+	unsigned long val;
+
+	ecc = 0;
+	/* loop through all the DIMM slots on the board */
+	for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
+		mfsdram(SDRAM_MCOPT1, val);
+		ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val));
+	}
+
+	return ecc;
+}
+
+#ifdef CONFIG_DDR_ECC
+/*-----------------------------------------------------------------------------+
+ * program_ecc.
+ *-----------------------------------------------------------------------------*/
+static void program_ecc(unsigned long *dimm_populated,
+			unsigned char *iic0_dimm_addr,
+			unsigned long num_dimm_banks,
+			unsigned long tlb_word2_i_value)
+{
+	unsigned long mcopt1;
+	unsigned long mcopt2;
+	unsigned long mcstat;
+	unsigned long dimm_num;
+	unsigned long ecc;
+
+	ecc = 0;
+	/* loop through all the DIMM slots on the board */
+	for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
+		/* If a dimm is installed in a particular slot ... */
+		if (dimm_populated[dimm_num] != SDRAM_NONE)
+			ecc = max(ecc, spd_read(iic0_dimm_addr[dimm_num], 11));
+	}
+	if (ecc == 0)
+		return;
+
+	mfsdram(SDRAM_MCOPT1, mcopt1);
+	mfsdram(SDRAM_MCOPT2, mcopt2);
+
+	if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
+		/* DDR controller must be enabled and not in self-refresh. */
+		mfsdram(SDRAM_MCSTAT, mcstat);
+		if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
+		    && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
+		    && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
+			== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
+
+			program_ecc_addr(0, sdram_memsize(), tlb_word2_i_value);
+		}
+	}
+
+	return;
+}
+
+#ifdef CONFIG_ECC_ERROR_RESET
+/*
+ * Check for ECC errors and reset board upon any error here
+ *
+ * On the Katmai 440SPe eval board, from time to time, the first
+ * lword write access after DDR2 initializazion with ECC checking
+ * enabled, leads to an ECC error. I couldn't find a configuration
+ * without this happening. On my board with the current setup it
+ * happens about 1 from 10 times.
+ *
+ * The ECC modules used for testing are:
+ * - Kingston ValueRAM KVR667D2E5/512 (tested with 1 and 2 DIMM's)
+ *
+ * This has to get fixed for the Katmai and tested for the other
+ * board (440SP/440SPe) that will eventually use this code in the
+ * future.
+ *
+ * 2007-03-01, sr
+ */
+static void check_ecc(void)
+{
+	u32 val;
+
+	mfsdram(SDRAM_ECCCR, val);
+	if (val != 0) {
+		printf("\nECC error: MCIF0_ECCES=%08lx MQ0_ESL=%08lx address=%08lx\n",
+		       val, mfdcr(0x4c), mfdcr(0x4e));
+		printf("ECC error occured, resetting board...\n");
+		do_reset(NULL, 0, 0, NULL);
+	}
+}
+#endif
+
+static void wait_ddr_idle(void)
+{
+	u32 val;
+
+	do {
+		mfsdram(SDRAM_MCSTAT, val);
+	} while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
+}
+
+/*-----------------------------------------------------------------------------+
+ * program_ecc_addr.
+ *-----------------------------------------------------------------------------*/
+static void program_ecc_addr(unsigned long start_address,
+			     unsigned long num_bytes,
+			     unsigned long tlb_word2_i_value)
+{
+	unsigned long current_address;
+	unsigned long end_address;
+	unsigned long address_increment;
+	unsigned long mcopt1;
+	char str[] = "ECC generation...";
+	int i;
+
+	current_address = start_address;
+	mfsdram(SDRAM_MCOPT1, mcopt1);
+	if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
+		mtsdram(SDRAM_MCOPT1,
+			(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN);
+		sync();
+		eieio();
+		wait_ddr_idle();
+
+		puts(str);
+		if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) {
+			/* ECC bit set method for non-cached memory */
+			if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32)
+				address_increment = 4;
+			else
+				address_increment = 8;
+			end_address = current_address + num_bytes;
+
+			while (current_address < end_address) {
+				*((unsigned long *)current_address) = 0x00000000;
+				current_address += address_increment;
+			}
+		} else {
+			/* ECC bit set method for cached memory */
+			dcbz_area(start_address, num_bytes);
+			dflush();
+		}
+		for (i=0; i<strlen(str); i++)
+			putc('\b');
+
+		sync();
+		eieio();
+		wait_ddr_idle();
+
+		/* clear ECC error repoting registers */
+		mtsdram(SDRAM_ECCCR, 0xffffffff);
+		mtdcr(0x4c, 0xffffffff);
+
+		mtsdram(SDRAM_MCOPT1,
+			(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP);
+		sync();
+		eieio();
+		wait_ddr_idle();
+
+#ifdef CONFIG_ECC_ERROR_RESET
+		/*
+		 * One write to 0 is enough to trigger this ECC error
+		 * (see description above)
+		 */
+		out_be32(0, 0x12345678);
+		check_ecc();
+#endif
+	}
+}
+#endif
+
+/*-----------------------------------------------------------------------------+
+ * program_DQS_calibration.
+ *-----------------------------------------------------------------------------*/
+static void program_DQS_calibration(unsigned long *dimm_populated,
+				    unsigned char *iic0_dimm_addr,
+				    unsigned long num_dimm_banks)
+{
+	unsigned long val;
+
+#ifdef HARD_CODED_DQS /* calibration test with hardvalues */
+	mtsdram(SDRAM_RQDC, 0x80000037);
+	mtsdram(SDRAM_RDCC, 0x40000000);
+	mtsdram(SDRAM_RFDC, 0x000001DF);
+
+	test();
+#else
+	/*------------------------------------------------------------------
+	 * Program RDCC register
+	 * Read sample cycle auto-update enable
+	 *-----------------------------------------------------------------*/
+
+	/*
+	 * Modified for the Katmai platform:  with some DIMMs, the DDR2
+	 * controller automatically selects the T2 read cycle, but this
+	 * proves unreliable.  Go ahead and force the DDR2 controller
+	 * to use the T4 sample and disable the automatic update of the
+	 * RDSS field.
+	 */
+	mfsdram(SDRAM_RDCC, val);
+	mtsdram(SDRAM_RDCC,
+		(val & ~(SDRAM_RDCC_RDSS_MASK | SDRAM_RDCC_RSAE_MASK))
+		| (SDRAM_RDCC_RDSS_T4 | SDRAM_RDCC_RSAE_DISABLE));
+
+	/*------------------------------------------------------------------
+	 * Program RQDC register
+	 * Internal DQS delay mechanism enable
+	 *-----------------------------------------------------------------*/
+	mtsdram(SDRAM_RQDC, (SDRAM_RQDC_RQDE_ENABLE|SDRAM_RQDC_RQFD_ENCODE(0x38)));
+
+	/*------------------------------------------------------------------
+	 * Program RFDC register
+	 * Set Feedback Fractional Oversample
+	 * Auto-detect read sample cycle enable
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_RFDC, val);
+	mtsdram(SDRAM_RFDC,
+		(val & ~(SDRAM_RFDC_ARSE_MASK | SDRAM_RFDC_RFOS_MASK |
+			 SDRAM_RFDC_RFFD_MASK))
+		| (SDRAM_RFDC_ARSE_ENABLE | SDRAM_RFDC_RFOS_ENCODE(0) |
+		   SDRAM_RFDC_RFFD_ENCODE(0)));
+
+	DQS_calibration_process();
+#endif
+}
+
+static u32 short_mem_test(void)
+{
+	u32 *membase;
+	u32 bxcr_num;
+	u32 bxcf;
+	int i;
+	int j;
+	u32 test[NUMMEMTESTS][NUMMEMWORDS] = {
+		{0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+		 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},
+		{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+		 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},
+		{0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+		 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},
+		{0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+		 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},
+		{0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+		 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},
+		{0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+		 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
+		{0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+		 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
+		{0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+		 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55} };
+
+	for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
+		mfsdram(SDRAM_MB0CF + (bxcr_num << 2), bxcf);
+
+		/* Banks enabled */
+		if ((bxcf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
+
+			/* Bank is enabled */
+			membase = (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num)));
+
+			/*------------------------------------------------------------------
+			 * Run the short memory test.
+			 *-----------------------------------------------------------------*/
+			for (i = 0; i < NUMMEMTESTS; i++) {
+				for (j = 0; j < NUMMEMWORDS; j++) {
+					membase[j] = test[i][j];
+					ppcDcbf((u32)&(membase[j]));
+				}
+				sync();
+				for (j = 0; j < NUMMEMWORDS; j++) {
+					if (membase[j] != test[i][j]) {
+						ppcDcbf((u32)&(membase[j]));
+						break;
+					}
+					ppcDcbf((u32)&(membase[j]));
+				}
+				sync();
+				if (j < NUMMEMWORDS)
+					break;
+			}
+			if (i < NUMMEMTESTS)
+				break;
+		}	/* if bank enabled */
+	}		/* for bxcf_num */
+
+	return bxcr_num;
+}
+
+#ifndef HARD_CODED_DQS
+/*-----------------------------------------------------------------------------+
+ * DQS_calibration_process.
+ *-----------------------------------------------------------------------------*/
+static void DQS_calibration_process(void)
+{
+	unsigned long ecc_temp;
+	unsigned long rfdc_reg;
+	unsigned long rffd;
+	unsigned long rqdc_reg;
+	unsigned long rqfd;
+	unsigned long bxcr_num;
+	unsigned long val;
+	long rqfd_average;
+	long rffd_average;
+	long max_start;
+	long min_end;
+	unsigned long begin_rqfd[MAXRANKS];
+	unsigned long begin_rffd[MAXRANKS];
+	unsigned long end_rqfd[MAXRANKS];
+	unsigned long end_rffd[MAXRANKS];
+	char window_found;
+	unsigned long dlycal;
+	unsigned long dly_val;
+	unsigned long max_pass_length;
+	unsigned long current_pass_length;
+	unsigned long current_fail_length;
+	unsigned long current_start;
+	long max_end;
+	unsigned char fail_found;
+	unsigned char pass_found;
+
+	/*------------------------------------------------------------------
+	 * Test to determine the best read clock delay tuning bits.
+	 *
+	 * Before the DDR controller can be used, the read clock delay needs to be
+	 * set.  This is SDRAM_RQDC[RQFD] and SDRAM_RFDC[RFFD].
+	 * This value cannot be hardcoded into the program because it changes
+	 * depending on the board's setup and environment.
+	 * To do this, all delay values are tested to see if they
+	 * work or not.  By doing this, you get groups of fails with groups of
+	 * passing values.  The idea is to find the start and end of a passing
+	 * window and take the center of it to use as the read clock delay.
+	 *
+	 * A failure has to be seen first so that when we hit a pass, we know
+	 * that it is truely the start of the window.  If we get passing values
+	 * to start off with, we don't know if we are at the start of the window.
+	 *
+	 * The code assumes that a failure will always be found.
+	 * If a failure is not found, there is no easy way to get the middle
+	 * of the passing window.  I guess we can pretty much pick any value
+	 * but some values will be better than others.  Since the lowest speed
+	 * we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed),
+	 * from experimentation it is safe to say you will always have a failure.
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MCOPT1, ecc_temp);
+	ecc_temp &= SDRAM_MCOPT1_MCHK_MASK;
+	mfsdram(SDRAM_MCOPT1, val);
+	mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) |
+		SDRAM_MCOPT1_MCHK_NON);
+
+	max_start = 0;
+	min_end = 0;
+	begin_rqfd[0] = 0;
+	begin_rffd[0] = 0;
+	begin_rqfd[1] = 0;
+	begin_rffd[1] = 0;
+	end_rqfd[0] = 0;
+	end_rffd[0] = 0;
+	end_rqfd[1] = 0;
+	end_rffd[1] = 0;
+	window_found = FALSE;
+
+	max_pass_length = 0;
+	max_start = 0;
+	max_end = 0;
+	current_pass_length = 0;
+	current_fail_length = 0;
+	current_start = 0;
+	window_found = FALSE;
+	fail_found = FALSE;
+	pass_found = FALSE;
+
+	/* first fix RQDC[RQFD] to an average of 80 degre phase shift to find RFDC[RFFD] */
+	/* rqdc_reg = mfsdram(SDRAM_RQDC) & ~(SDRAM_RQDC_RQFD_MASK); */
+
+	/*
+	 * get the delay line calibration register value
+	 */
+	mfsdram(SDRAM_DLCR, dlycal);
+	dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2;
+
+	for (rffd = 0; rffd <= SDRAM_RFDC_RFFD_MAX; rffd++) {
+		mfsdram(SDRAM_RFDC, rfdc_reg);
+		rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);
+
+		/*------------------------------------------------------------------
+		 * Set the timing reg for the test.
+		 *-----------------------------------------------------------------*/
+		mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd));
+
+		/* do the small memory test */
+		bxcr_num = short_mem_test();
+
+		/*------------------------------------------------------------------
+		 * See if the rffd value passed.
+		 *-----------------------------------------------------------------*/
+		if (bxcr_num == MAXBXCF) {
+			if (fail_found == TRUE) {
+				pass_found = TRUE;
+				if (current_pass_length == 0)
+					current_start = rffd;
+
+				current_fail_length = 0;
+				current_pass_length++;
+
+				if (current_pass_length > max_pass_length) {
+					max_pass_length = current_pass_length;
+					max_start = current_start;
+					max_end = rffd;
+				}
+			}
+		} else {
+			current_pass_length = 0;
+			current_fail_length++;
+
+			if (current_fail_length >= (dly_val >> 2)) {
+				if (fail_found == FALSE) {
+					fail_found = TRUE;
+				} else if (pass_found == TRUE) {
+					window_found = TRUE;
+					break;
+				}
+			}
+		}
+	}		/* for rffd */
+
+	/*------------------------------------------------------------------
+	 * Set the average RFFD value
+	 *-----------------------------------------------------------------*/
+	rffd_average = ((max_start + max_end) >> 1);
+
+	if (rffd_average < 0)
+		rffd_average = 0;
+
+	if (rffd_average > SDRAM_RFDC_RFFD_MAX)
+		rffd_average = SDRAM_RFDC_RFFD_MAX;
+	/* now fix RFDC[RFFD] found and find RQDC[RQFD] */
+	mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
+
+	max_pass_length = 0;
+	max_start = 0;
+	max_end = 0;
+	current_pass_length = 0;
+	current_fail_length = 0;
+	current_start = 0;
+	window_found = FALSE;
+	fail_found = FALSE;
+	pass_found = FALSE;
+
+	for (rqfd = 0; rqfd <= SDRAM_RQDC_RQFD_MAX; rqfd++) {
+		mfsdram(SDRAM_RQDC, rqdc_reg);
+		rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);
+
+		/*------------------------------------------------------------------
+		 * Set the timing reg for the test.
+		 *-----------------------------------------------------------------*/
+		mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd));
+
+		/* do the small memory test */
+		bxcr_num = short_mem_test();
+
+		/*------------------------------------------------------------------
+		 * See if the rffd value passed.
+		 *-----------------------------------------------------------------*/
+		if (bxcr_num == MAXBXCF) {
+			if (fail_found == TRUE) {
+				pass_found = TRUE;
+				if (current_pass_length == 0)
+					current_start = rqfd;
+
+				current_fail_length = 0;
+				current_pass_length++;
+
+				if (current_pass_length > max_pass_length) {
+					max_pass_length = current_pass_length;
+					max_start = current_start;
+					max_end = rqfd;
+				}
+			}
+		} else {
+			current_pass_length = 0;
+			current_fail_length++;
+
+			if (fail_found == FALSE) {
+				fail_found = TRUE;
+			} else if (pass_found == TRUE) {
+				window_found = TRUE;
+				break;
+			}
+		}
+	}
+
+	/*------------------------------------------------------------------
+	 * Make sure we found the valid read passing window.  Halt if not
+	 *-----------------------------------------------------------------*/
+	if (window_found == FALSE) {
+		printf("ERROR: Cannot determine a common read delay for the "
+		       "DIMM(s) installed.\n");
+		debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__);
+		hang();
+	}
+
+	rqfd_average = ((max_start + max_end) >> 1);
+
+	if (rqfd_average < 0)
+		rqfd_average = 0;
+
+	if (rqfd_average > SDRAM_RQDC_RQFD_MAX)
+		rqfd_average = SDRAM_RQDC_RQFD_MAX;
+
+	/*------------------------------------------------------------------
+	 * Restore the ECC variable to what it originally was
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MCOPT1, val);
+	mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | ecc_temp);
+
+	mtsdram(SDRAM_RQDC,
+		(rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
+		SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
+
+	mfsdram(SDRAM_DLCR, val);
+	debug("%s[%d] DLCR: 0x%08X\n", __FUNCTION__, __LINE__, val);
+	mfsdram(SDRAM_RQDC, val);
+	debug("%s[%d] RQDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
+	mfsdram(SDRAM_RFDC, val);
+	debug("%s[%d] RFDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
+}
+#else /* calibration test with hardvalues */
+/*-----------------------------------------------------------------------------+
+ * DQS_calibration_process.
+ *-----------------------------------------------------------------------------*/
+static void test(void)
+{
+	unsigned long dimm_num;
+	unsigned long ecc_temp;
+	unsigned long i, j;
+	unsigned long *membase;
+	unsigned long bxcf[MAXRANKS];
+	unsigned long val;
+	char window_found;
+	char begin_found[MAXDIMMS];
+	char end_found[MAXDIMMS];
+	char search_end[MAXDIMMS];
+	unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
+		{0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+		 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},
+		{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+		 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},
+		{0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+		 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},
+		{0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+		 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},
+		{0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+		 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},
+		{0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+		 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
+		{0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+		 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
+		{0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+		 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55} };
+
+	/*------------------------------------------------------------------
+	 * Test to determine the best read clock delay tuning bits.
+	 *
+	 * Before the DDR controller can be used, the read clock delay needs to be
+	 * set.  This is SDRAM_RQDC[RQFD] and SDRAM_RFDC[RFFD].
+	 * This value cannot be hardcoded into the program because it changes
+	 * depending on the board's setup and environment.
+	 * To do this, all delay values are tested to see if they
+	 * work or not.  By doing this, you get groups of fails with groups of
+	 * passing values.  The idea is to find the start and end of a passing
+	 * window and take the center of it to use as the read clock delay.
+	 *
+	 * A failure has to be seen first so that when we hit a pass, we know
+	 * that it is truely the start of the window.  If we get passing values
+	 * to start off with, we don't know if we are at the start of the window.
+	 *
+	 * The code assumes that a failure will always be found.
+	 * If a failure is not found, there is no easy way to get the middle
+	 * of the passing window.  I guess we can pretty much pick any value
+	 * but some values will be better than others.  Since the lowest speed
+	 * we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed),
+	 * from experimentation it is safe to say you will always have a failure.
+	 *-----------------------------------------------------------------*/
+	mfsdram(SDRAM_MCOPT1, ecc_temp);
+	ecc_temp &= SDRAM_MCOPT1_MCHK_MASK;
+	mfsdram(SDRAM_MCOPT1, val);
+	mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) |
+		SDRAM_MCOPT1_MCHK_NON);
+
+	window_found = FALSE;
+	begin_found[0] = FALSE;
+	end_found[0] = FALSE;
+	search_end[0] = FALSE;
+	begin_found[1] = FALSE;
+	end_found[1] = FALSE;
+	search_end[1] = FALSE;
+
+	for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
+		mfsdram(SDRAM_MB0CF + (bxcr_num << 2), bxcf[bxcr_num]);
+
+		/* Banks enabled */
+		if ((bxcf[dimm_num] & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
+
+			/* Bank is enabled */
+			membase =
+				(unsigned long*)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+dimm_num)));
+
+			/*------------------------------------------------------------------
+			 * Run the short memory test.
+			 *-----------------------------------------------------------------*/
+			for (i = 0; i < NUMMEMTESTS; i++) {
+				for (j = 0; j < NUMMEMWORDS; j++) {
+					membase[j] = test[i][j];
+					ppcDcbf((u32)&(membase[j]));
+				}
+				sync();
+				for (j = 0; j < NUMMEMWORDS; j++) {
+					if (membase[j] != test[i][j]) {
+						ppcDcbf((u32)&(membase[j]));
+						break;
+					}
+					ppcDcbf((u32)&(membase[j]));
+				}
+				sync();
+				if (j < NUMMEMWORDS)
+					break;
+			}
+
+			/*------------------------------------------------------------------
+			 * See if the rffd value passed.
+			 *-----------------------------------------------------------------*/
+			if (i < NUMMEMTESTS) {
+				if ((end_found[dimm_num] == FALSE) &&
+				    (search_end[dimm_num] == TRUE)) {
+					end_found[dimm_num] = TRUE;
+				}
+				if ((end_found[0] == TRUE) &&
+				    (end_found[1] == TRUE))
+					break;
+			} else {
+				if (begin_found[dimm_num] == FALSE) {
+					begin_found[dimm_num] = TRUE;
+					search_end[dimm_num] = TRUE;
+				}
+			}
+		} else {
+			begin_found[dimm_num] = TRUE;
+			end_found[dimm_num] = TRUE;
+		}
+	}
+
+	if ((begin_found[0] == TRUE) && (begin_found[1] == TRUE))
+		window_found = TRUE;
+
+	/*------------------------------------------------------------------
+	 * Make sure we found the valid read passing window.  Halt if not
+	 *-----------------------------------------------------------------*/
+	if (window_found == FALSE) {
+		printf("ERROR: Cannot determine a common read delay for the "
+		       "DIMM(s) installed.\n");
+		hang();
+	}
+
+	/*------------------------------------------------------------------
+	 * Restore the ECC variable to what it originally was
+	 *-----------------------------------------------------------------*/
+	mtsdram(SDRAM_MCOPT1,
+		(ppcMfdcr_sdram(SDRAM_MCOPT1) & ~SDRAM_MCOPT1_MCHK_MASK)
+		| ecc_temp);
+}
+#endif
+
+#if defined(DEBUG)
+static void ppc440sp_sdram_register_dump(void)
+{
+	unsigned int sdram_reg;
+	unsigned int sdram_data;
+	unsigned int dcr_data;
+
+	printf("\n  Register Dump:\n");
+	sdram_reg = SDRAM_MCSTAT;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MCSTAT    = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_MCOPT1;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MCOPT1    = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_MCOPT2;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MCOPT2    = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_MODT0;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MODT0     = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_MODT1;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MODT1     = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_MODT2;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MODT2     = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_MODT3;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MODT3     = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_CODT;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_CODT      = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_VVPR;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_VVPR      = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_OPARS;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_OPARS     = 0x%08X\n", sdram_data);
+	/*
+	 * OPAR2 is only used as a trigger register.
+	 * No data is contained in this register, and reading or writing
+	 * to is can cause bad things to happen (hangs).  Just skip it
+	 * and report NA
+	 * sdram_reg = SDRAM_OPAR2;
+	 * mfsdram(sdram_reg, sdram_data);
+	 * printf("        SDRAM_OPAR2     = 0x%08X\n", sdram_data);
+	 */
+	printf("        SDRAM_OPART     = N/A       ");
+	sdram_reg = SDRAM_RTR;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_RTR       = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_MB0CF;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MB0CF     = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_MB1CF;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MB1CF     = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_MB2CF;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MB2CF     = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_MB3CF;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MB3CF     = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR0;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR0  = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR1;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR1  = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR2;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR2  = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR3;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR3  = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR4;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR4  = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR5;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR5  = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR6;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR6  = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR7;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR7  = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR8;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR8  = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR9;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR9  = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR10;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR10 = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR11;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR11 = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR12;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR12 = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR13;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR13 = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_INITPLR14;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR14 = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_INITPLR15;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_INITPLR15 = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_RQDC;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_RQDC      = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_RFDC;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_RFDC      = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_RDCC;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_RDCC      = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_DLCR;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_DLCR      = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_CLKTR;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_CLKTR     = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_WRDTR;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_WRDTR     = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_SDTR1;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_SDTR1     = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_SDTR2;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_SDTR2     = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_SDTR3;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_SDTR3     = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_MMODE;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MMODE     = 0x%08X\n", sdram_data);
+	sdram_reg = SDRAM_MEMODE;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_MEMODE    = 0x%08X", sdram_data);
+	sdram_reg = SDRAM_ECCCR;
+	mfsdram(sdram_reg, sdram_data);
+	printf("        SDRAM_ECCCR     = 0x%08X\n\n", sdram_data);
+
+	dcr_data = mfdcr(SDRAM_R0BAS);
+	printf("        MQ0_B0BAS       = 0x%08X", dcr_data);
+	dcr_data = mfdcr(SDRAM_R1BAS);
+	printf("        MQ1_B0BAS       = 0x%08X\n", dcr_data);
+	dcr_data = mfdcr(SDRAM_R2BAS);
+	printf("        MQ2_B0BAS       = 0x%08X", dcr_data);
+	dcr_data = mfdcr(SDRAM_R3BAS);
+	printf("        MQ3_B0BAS       = 0x%08X\n", dcr_data);
+}
+#endif
+#endif /* CONFIG_SPD_EEPROM */
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index baecf70..96f0f62 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -31,7 +31,8 @@
 	  bedbug_405.o commproc.o \
 	  cpu.o cpu_init.o i2c.o interrupts.o \
 	  miiphy.o ndfc.o sdram.o serial.o \
-	  spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o \
+	  40x_spd_sdram.o 44x_spd_ddr.o 44x_spd_ddr2.o speed.o \
+	  tlb.o traps.o usb_ohci.o usbdev.o \
 	  440spe_pcie.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index ae24591..82ae443 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -314,7 +314,7 @@
 #endif
 
 #if defined (CFG_EBC_CFG)
-	mtebc(epcr, CFG_EBC_CFG);
+	mtebc(EBC0_CFG, CFG_EBC_CFG);
 #endif
 
 #if defined(CONFIG_WATCHDOG)
diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c
index 7db1cd8..0b056a1 100644
--- a/cpu/ppc4xx/i2c.c
+++ b/cpu/ppc4xx/i2c.c
@@ -1,91 +1,100 @@
-/*****************************************************************************/
-/* I2C Bus interface initialisation and I2C Commands                         */
-/* for PPC405GP		                                                     */
-/* Author : AS HARNOIS                                                       */
-/* Date   : 13.Dec.00                                                        */
-/*****************************************************************************/
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * based on work by Anne Sophie Harnois <anne-sophie.harnois@nextream.fr>
+ *
+ * (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
+ */
 
 #include <common.h>
 #include <ppc4xx.h>
-#if defined(CONFIG_440)
-#   include <440_i2c.h>
-#else
-#   include <405gp_i2c.h>
-#endif
+#include <4xx_i2c.h>
 #include <i2c.h>
+#include <asm-ppc/io.h>
 
 #ifdef CONFIG_HARD_I2C
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#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 */
+#if defined(CONFIG_I2C_MULTI_BUS)
+/* Initialize the bus pointer to whatever one the SPD EEPROM is on.
+ * Default is bus 0.  This is necessary because the DDR initialization
+ * runs from ROM, and we can't switch buses because we can't modify
+ * the global variables.
+ */
+#ifdef CFG_SPD_BUS_NUM
+static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM;
+#else
+static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0;
+#endif
+#endif /* CONFIG_I2C_MULTI_BUS */
 
-#define IIC_TIMEOUT 1			/* 1 seconde */
-
-
-static void _i2c_bus_reset (void)
+static void _i2c_bus_reset(void)
 {
-	int i, status;
+	int i;
+	u8 dc;
 
 	/* Reset status register */
 	/* write 1 in SCMP and IRQA to clear these fields */
-	out8 (IIC_STS, 0x0A);
+	out_8((u8 *)IIC_STS, 0x0A);
 
 	/* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
-	out8 (IIC_EXTSTS, 0x8F);
-	__asm__ volatile ("eieio");
+	out_8((u8 *)IIC_EXTSTS, 0x8F);
 
-	/*
-	 * 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");
+    	/* Place chip in the reset state */
+	out_8((u8 *)IIC_XTCNTLSS, IIC_XTCNTLSS_SRST);
 
-	/* 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;
+	/* Check if bus is free */
+	dc = in_8((u8 *)IIC_DIRECTCNTL);
+	if (!DIRCTNL_FREE(dc)){
+		/* Try to set bus free state */
+		out_8((u8 *)IIC_DIRECTCNTL, IIC_DIRCNTL_SDAC | IIC_DIRCNTL_SCC);
+
+		/* Wait until we regain bus control */
+		for (i = 0; i < 100; ++i) {
+			dc = in_8((u8 *)IIC_DIRECTCNTL);
+			if (DIRCTNL_FREE(dc))
+				break;
+
+			/* Toggle SCL line */
+			dc ^= IIC_DIRCNTL_SCC;
+			out_8((u8 *)IIC_DIRECTCNTL, dc);
+			udelay(10);
+			dc ^= IIC_DIRCNTL_SCC;
+			out_8((u8 *)IIC_DIRECTCNTL, dc);
 		}
 	}
-	/* 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 */
+
+	/* Remove reset */
+	out_8((u8 *)IIC_XTCNTLSS, 0);
 }
 
-void i2c_init (int speed, int slaveadd)
+void i2c_init(int speed, int slaveadd)
 {
 	sys_info_t sysInfo;
 	unsigned long freqOPB;
 	int val, divisor;
+	int bus;
 
 #ifdef CFG_I2C_INIT_BOARD
 	/* call board specific i2c bus reset routine before accessing the   */
@@ -94,101 +103,100 @@
 	i2c_init_board();
 #endif
 
-	/* Handle possible failed I2C state */
-	/* FIXME: put this into i2c_init_board()? */
-	_i2c_bus_reset ();
+	for (bus = 0; bus < CFG_MAX_I2C_BUS; bus++) {
+		I2C_SET_BUS(bus);
 
-	/* clear lo master address */
-	out8 (IIC_LMADR, 0);
+		/* Handle possible failed I2C state */
+		/* FIXME: put this into i2c_init_board()? */
+		_i2c_bus_reset();
 
-	/* clear hi master address */
-	out8 (IIC_HMADR, 0);
+		/* clear lo master address */
+		out_8((u8 *)IIC_LMADR, 0);
 
-	/* clear lo slave address */
-	out8 (IIC_LSADR, 0);
+		/* clear hi master address */
+		out_8((u8 *)IIC_HMADR, 0);
 
-	/* clear hi slave address */
-	out8 (IIC_HSADR, 0);
+		/* clear lo slave address */
+		out_8((u8 *)IIC_LSADR, 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);
+		/* clear hi slave address */
+		out_8((u8 *)IIC_HSADR, 0);
 
-	/* no interrupts */
-	out8 (IIC_INTRMSK, 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;
+		out_8((u8 *)IIC_CLKDIV, divisor);
 
-	/* clear transfer count */
-	out8 (IIC_XFRCNT, 0);
+		/* no interrupts */
+		out_8((u8 *)IIC_INTRMSK, 0);
 
-	/* clear extended control & stat */
-	/* write 1 in SRC SRS SWC SWS to clear these fields */
-	out8 (IIC_XTCNTLSS, 0xF0);
+		/* clear transfer count */
+		out_8((u8 *)IIC_XFRCNT, 0);
 
-	/* Mode Control Register
-	   Flush Slave/Master data buffer */
-	out8 (IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
-	__asm__ volatile ("eieio");
+		/* clear extended control & stat */
+		/* write 1 in SRC SRS SWC SWS to clear these fields */
+		out_8((u8 *)IIC_XTCNTLSS, 0xF0);
 
+		/* Mode Control Register
+		   Flush Slave/Master data buffer */
+		out_8((u8 *)IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
 
-	val = in8(IIC_MDCNTL);
-	__asm__ volatile ("eieio");
+		val = in_8((u8 *)IIC_MDCNTL);
 
-	/* Ignore General Call, slave transfers are ignored,
-	   disable interrupts, exit unknown bus state, enable hold
-	   SCL
-	   100kHz normaly or FastMode for 400kHz and above
-	*/
+		/* 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;
+		val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL;
+		if (speed >= 400000)
+			val |= IIC_MDCNTL_FSM;
+		out_8((u8 *)IIC_MDCNTL, val);
+
+		/* clear control reg */
+		out_8((u8 *)IIC_CNTL, 0x00);
 	}
-	out8 (IIC_MDCNTL, val);
 
-	/* clear control reg */
-	out8 (IIC_CNTL, 0x00);
-	__asm__ volatile ("eieio");
-
+	/* set to SPD bus as default bus upon powerup */
+	I2C_SET_BUS(CFG_SPD_BUS_NUM);
 }
 
 /*
-  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 )
+ * 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 out_8((u8 *)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;
@@ -198,97 +206,88 @@
 	int i;
 	uchar creg;
 
-	if( data == 0 || data_len == 0 ){
-		/*Don't support data transfer of no length or to address 0*/
+	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 ){
+	if (addr && addr_len) {
 		ptr = addr;
 		cnt = addr_len;
 		reading = 0;
-	}else{
+	} else {
 		ptr = data;
 		cnt = data_len;
 		reading = cmd_type;
 	}
 
-	/*Clear Stop Complete Bit*/
-	out8(IIC_STS,IIC_STS_SCMP);
+	/* Clear Stop Complete Bit */
+	out_8((u8 *)IIC_STS, IIC_STS_SCMP);
 	/* Check init */
-	i=10;
+	i = 10;
 	do {
 		/* Get status */
-		status = in8(IIC_STS);
-		__asm__ volatile("eieio");
+		status = in_8((u8 *)IIC_STS);
 		i--;
-	} while ((status & IIC_STS_PT) && (i>0));
+	} 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*/
+	/* flush the Master/Slave Databuffers */
+	out_8((u8 *)IIC_MDCNTL, ((in_8((u8 *)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");
+	out_8((u8 *)IIC_HMADR, 0);
+	out_8((u8 *)IIC_LMADR, chip);
 
 	tran = 0;
 	result = IIC_OK;
 	creg = 0;
 
-	while ( tran != cnt && (result == IIC_OK)) {
+	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
-		*/
+		 * 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) )
+		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++) {
+		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");
+				out_8((u8 *)IIC_MDBUF, ptr[tran+j]);
+		out_8((u8 *)IIC_CNTL, creg);
 
 		/* 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;
+		 * 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);
+			status = in_8((u8 *)IIC_STS);
+			udelay(10);
 			i--;
-		} while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR)
-			 && (i>0));
+		} while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) && (i > 0));
 
 		if (status & IIC_STS_ERR) {
 			result = IIC_NOK;
-			status = in8 (IIC_EXTSTS);
+			status = in_8((u8 *)IIC_EXTSTS);
 			/* Lost arbitration? */
 			if (status & IIC_EXTSTS_LA)
 				result = IIC_NOK_LA;
@@ -306,34 +305,32 @@
 			/* 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");
-				}
+				 * 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] = in_8((u8 *)IIC_MDBUF);
 			} else
 				result = IIC_NOK_DATA;
 		}
 		creg = 0;
-		tran+=bc;
-		if( ptr == addr && tran == cnt ) {
+		tran += bc;
+		if (ptr == addr && tran == cnt) {
 			ptr = data;
 			cnt = data_len;
 			tran = 0;
 			reading = cmd_type;
-			if( reading )
+			if (reading)
 				creg = IIC_CNTL_RPST;
 		}
 	}
 	return (result);
 }
 
-int i2c_probe (uchar chip)
+int i2c_probe(uchar chip)
 {
 	uchar buf[1];
 
@@ -344,21 +341,21 @@
 	 * 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);
+	return (i2c_transfer(1, chip << 1, 0,0, buf, 1) != 0);
 }
 
 
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
 {
 	uchar xaddr[4];
 	int ret;
 
-	if ( alen > 4 ) {
+	if (alen > 4) {
 		printf ("I2C read: addr len %d not supported\n", alen);
 		return 1;
 	}
 
-	if ( alen > 0 ) {
+	if (alen > 0) {
 		xaddr[0] = (addr >> 24) & 0xFF;
 		xaddr[1] = (addr >> 16) & 0xFF;
 		xaddr[2] = (addr >> 8) & 0xFF;
@@ -378,10 +375,10 @@
 	 * still be one byte because the extra address bits are
 	 * hidden in the chip address.
 	 */
-	if( alen > 0 )
+	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) {
+	if ((ret = i2c_transfer(1, chip<<1, &xaddr[4-alen], alen, buffer, len)) != 0) {
 		if (gd->have_console)
 			printf( "I2c read: failed %d\n", ret);
 		return 1;
@@ -389,16 +386,17 @@
 	return 0;
 }
 
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
 {
 	uchar xaddr[4];
 
-	if ( alen > 4 ) {
+	if (alen > 4) {
 		printf ("I2C write: addr len %d not supported\n", alen);
 		return 1;
 
 	}
-	if ( alen > 0 ) {
+
+	if (alen > 0) {
 		xaddr[0] = (addr >> 24) & 0xFF;
 		xaddr[1] = (addr >> 16) & 0xFF;
 		xaddr[2] = (addr >> 8) & 0xFF;
@@ -417,11 +415,11 @@
 	 * still be one byte because the extra address bits are
 	 * hidden in the chip address.
 	 */
-	if( alen > 0 )
+	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);
+	return (i2c_transfer(0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
 }
 
 /*-----------------------------------------------------------------------
@@ -433,7 +431,7 @@
 
 	i2c_read(i2c_addr, reg, 1, &buf, 1);
 
-	return(buf);
+	return (buf);
 }
 
 /*-----------------------------------------------------------------------
@@ -443,4 +441,38 @@
 {
 	i2c_write(i2c_addr, reg, 1, &val, 1);
 }
+
+#if defined(CONFIG_I2C_MULTI_BUS)
+/*
+ * Functions for multiple I2C bus handling
+ */
+unsigned int i2c_get_bus_num(void)
+{
+	return i2c_bus_num;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if (bus >= CFG_MAX_I2C_BUS)
+		return -1;
+
+	i2c_bus_num = bus;
+
+	return 0;
+}
+
+/* TODO: add 100/400k switching */
+unsigned int i2c_get_bus_speed(void)
+{
+	return CFG_I2C_SPEED;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+	if (speed != CFG_I2C_SPEED)
+		return -1;
+
+	return 0;
+}
+#endif	/* CONFIG_I2C_MULTI_BUS */
 #endif	/* CONFIG_HARD_I2C */
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index 2d16a83..06220c3 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -331,7 +331,7 @@
 	unsigned long m;
 	unsigned long prbdv0;
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_YUCCA)
 	unsigned long sys_freq;
 	unsigned long sys_per=0;
 	unsigned long msr;
@@ -348,7 +348,7 @@
 	/*-------------------------------------------------------------------------+
 	 | Calculate the system clock speed from the period.
 	 +-------------------------------------------------------------------------*/
-	sys_freq=(ONE_BILLION/sys_per)*1000;
+	sys_freq = (ONE_BILLION / sys_per) * 1000;
 #endif
 
 	/* Extract configured divisors */
@@ -385,17 +385,17 @@
 		m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
 
 	/* Now calculate the individual clocks */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_YUCCA)
 	sysInfo->freqVCOMhz = (m * sys_freq) ;
 #else
-	sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
+	sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m >> 1);
 #endif
 	sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
 	sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
 	sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
 	sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_YUCCA)
 	/* Determine PCI Clock Period */
 	pci_clock_per = determine_pci_clock_per();
 	sysInfo->freqPCI = (ONE_BILLION/pci_clock_per) * 1000;
@@ -408,7 +408,7 @@
 
 #endif
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_YUCCA)
 unsigned long determine_sysper(void)
 {
 	unsigned int fpga_clocking_reg;
@@ -583,7 +583,6 @@
 	}
 
 	return(sys_per);
-
 }
 
 /*-------------------------------------------------------------------------+
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 8e000d3..54be37c 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -1361,7 +1361,7 @@
 relocate_code:
 #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
     defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
-    defined(CONFIG_440SPE)
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	/*
 	 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
 	 * to speed up the boot process. Now this cache needs to be disabled.
@@ -1856,3 +1856,103 @@
 				     /* execution will continue from the poweron */
 				     /* vector of 0xfffffffc */
 #endif /* CONFIG_405EP */
+
+#if defined(CONFIG_440)
+#define function_prolog(func_name)      .text; \
+					.align 2; \
+					.globl func_name; \
+					func_name:
+#define function_epilog(func_name)      .type func_name,@function; \
+					.size func_name,.-func_name
+
+/*----------------------------------------------------------------------------+
+| mttlb3.
++----------------------------------------------------------------------------*/
+	function_prolog(mttlb3)
+	TLBWE(4,3,2)
+	blr
+	function_epilog(mttlb3)
+
+/*----------------------------------------------------------------------------+
+| mftlb3.
++----------------------------------------------------------------------------*/
+	function_prolog(mftlb3)
+	TLBRE(3,3,2)
+	blr
+	function_epilog(mftlb3)
+
+/*----------------------------------------------------------------------------+
+| mttlb2.
++----------------------------------------------------------------------------*/
+	function_prolog(mttlb2)
+	TLBWE(4,3,1)
+	blr
+	function_epilog(mttlb2)
+
+/*----------------------------------------------------------------------------+
+| mftlb2.
++----------------------------------------------------------------------------*/
+	function_prolog(mftlb2)
+	TLBRE(3,3,1)
+	blr
+	function_epilog(mftlb2)
+
+/*----------------------------------------------------------------------------+
+| mttlb1.
++----------------------------------------------------------------------------*/
+	function_prolog(mttlb1)
+	TLBWE(4,3,0)
+	blr
+	function_epilog(mttlb1)
+
+/*----------------------------------------------------------------------------+
+| mftlb1.
++----------------------------------------------------------------------------*/
+	function_prolog(mftlb1)
+	TLBRE(3,3,0)
+	blr
+	function_epilog(mftlb1)
+
+/*----------------------------------------------------------------------------+
+| dcbz_area.
++----------------------------------------------------------------------------*/
+	function_prolog(dcbz_area)
+	rlwinm. r5,r4,0,27,31
+	rlwinm  r5,r4,27,5,31
+	beq     ..d_ra2
+	addi    r5,r5,0x0001
+..d_ra2:mtctr   r5
+..d_ag2:dcbz    r0,r3
+	addi    r3,r3,32
+	bdnz    ..d_ag2
+	sync
+	blr
+	function_epilog(dcbz_area)
+
+/*----------------------------------------------------------------------------+
+| dflush.  Assume 32K at vector address is cachable.
++----------------------------------------------------------------------------*/
+	function_prolog(dflush)
+	mfmsr   r9
+	rlwinm  r8,r9,0,15,13
+	rlwinm  r8,r8,0,17,15
+	mtmsr   r8
+	addi    r3,r0,0x0000
+	mtspr   dvlim,r3
+	mfspr   r3,ivpr
+	addi    r4,r0,1024
+	mtctr   r4
+..dflush_loop:
+	lwz     r6,0x0(r3)
+	addi    r3,r3,32
+	bdnz    ..dflush_loop
+	addi    r3,r3,-32
+	mtctr   r4
+..ag:   dcbf    r0,r3
+	addi    r3,r3,-32
+	bdnz    ..ag
+	sync
+	mtmsr   r9
+	blr
+	function_epilog(dflush)
+#endif /* CONFIG_440 */
diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c
new file mode 100644
index 0000000..50344a4
--- /dev/null
+++ b/cpu/ppc4xx/tlb.c
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@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>
+
+#if defined(CONFIG_440)
+
+#include <ppc4xx.h>
+#include <ppc440.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+
+typedef struct region {
+	unsigned long base;
+	unsigned long size;
+	unsigned long tlb_word2_i_value;
+} region_t;
+
+static int add_tlb_entry(unsigned long base_addr,
+			 unsigned long tlb_word0_size_value,
+			 unsigned long tlb_word2_i_value)
+{
+	int i;
+	unsigned long tlb_word0_value;
+	unsigned long tlb_word1_value;
+	unsigned long tlb_word2_value;
+
+	/* First, find the index of a TLB entry not being used */
+	for (i=0; i<PPC4XX_TLB_SIZE; i++) {
+		tlb_word0_value = mftlb1(i);
+		if ((tlb_word0_value & TLB_WORD0_V_MASK) == TLB_WORD0_V_DISABLE)
+			break;
+	}
+	if (i >= PPC4XX_TLB_SIZE)
+		return -1;
+
+	/* Second, create the TLB entry */
+	tlb_word0_value = TLB_WORD0_EPN_ENCODE(base_addr) | TLB_WORD0_V_ENABLE |
+		TLB_WORD0_TS_0 | tlb_word0_size_value;
+	tlb_word1_value = TLB_WORD1_RPN_ENCODE(base_addr) | TLB_WORD1_ERPN_ENCODE(0);
+	tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
+		TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
+		TLB_WORD2_W_DISABLE | tlb_word2_i_value |
+		TLB_WORD2_M_DISABLE | TLB_WORD2_G_DISABLE |
+		TLB_WORD2_E_DISABLE | TLB_WORD2_UX_ENABLE |
+		TLB_WORD2_UW_ENABLE | TLB_WORD2_UR_ENABLE |
+		TLB_WORD2_SX_ENABLE | TLB_WORD2_SW_ENABLE |
+		TLB_WORD2_SR_ENABLE;
+
+	/* Wait for all memory accesses to complete */
+	sync();
+
+	/* Third, add the TLB entries */
+	mttlb1(i, tlb_word0_value);
+	mttlb2(i, tlb_word1_value);
+	mttlb3(i, tlb_word2_value);
+
+	/* Execute an ISYNC instruction so that the new TLB entry takes effect */
+	asm("isync");
+
+	return 0;
+}
+
+static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
+			     unsigned long tlb_word2_i_value)
+{
+	int rc;
+	int tlb_i;
+
+	tlb_i = tlb_word2_i_value;
+	while (mem_size != 0) {
+		rc = 0;
+		/* Add the TLB entries in to map the region. */
+		if (((base_addr & TLB_256MB_ALIGN_MASK) == base_addr) &&
+		    (mem_size >= TLB_256MB_SIZE)) {
+			/* Add a 256MB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
+				mem_size -= TLB_256MB_SIZE;
+				base_addr += TLB_256MB_SIZE;
+			}
+		} else if (((base_addr & TLB_16MB_ALIGN_MASK) == base_addr) &&
+			   (mem_size >= TLB_16MB_SIZE)) {
+			/* Add a 16MB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
+				mem_size -= TLB_16MB_SIZE;
+				base_addr += TLB_16MB_SIZE;
+			}
+		} else if (((base_addr & TLB_1MB_ALIGN_MASK) == base_addr) &&
+			   (mem_size >= TLB_1MB_SIZE)) {
+			/* Add a 1MB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
+				mem_size -= TLB_1MB_SIZE;
+				base_addr += TLB_1MB_SIZE;
+			}
+		} else if (((base_addr & TLB_256KB_ALIGN_MASK) == base_addr) &&
+			   (mem_size >= TLB_256KB_SIZE)) {
+			/* Add a 256KB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
+				mem_size -= TLB_256KB_SIZE;
+				base_addr += TLB_256KB_SIZE;
+			}
+		} else if (((base_addr & TLB_64KB_ALIGN_MASK) == base_addr) &&
+			   (mem_size >= TLB_64KB_SIZE)) {
+			/* Add a 64KB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
+				mem_size -= TLB_64KB_SIZE;
+				base_addr += TLB_64KB_SIZE;
+			}
+		} else if (((base_addr & TLB_16KB_ALIGN_MASK) == base_addr) &&
+			   (mem_size >= TLB_16KB_SIZE)) {
+			/* Add a 16KB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
+				mem_size -= TLB_16KB_SIZE;
+				base_addr += TLB_16KB_SIZE;
+			}
+		} else if (((base_addr & TLB_4KB_ALIGN_MASK) == base_addr) &&
+			   (mem_size >= TLB_4KB_SIZE)) {
+			/* Add a 4KB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
+				mem_size -= TLB_4KB_SIZE;
+				base_addr += TLB_4KB_SIZE;
+			}
+		} else if (((base_addr & TLB_1KB_ALIGN_MASK) == base_addr) &&
+			   (mem_size >= TLB_1KB_SIZE)) {
+			/* Add a 1KB TLB entry */
+			if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
+				mem_size -= TLB_1KB_SIZE;
+				base_addr += TLB_1KB_SIZE;
+			}
+		} else {
+			printf("ERROR: no TLB size exists for the base address 0x%0X.\n",
+				base_addr);
+		}
+
+		if (rc != 0)
+			printf("ERROR: no TLB entries available for the base addr 0x%0X.\n",
+				base_addr);
+	}
+
+	return;
+}
+
+/*
+ * Program one (or multiple) TLB entries for one memory region
+ *
+ * Common usage for boards with SDRAM DIMM modules to dynamically
+ * configure the TLB's for the SDRAM
+ */
+void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value)
+{
+	region_t region_array;
+
+	region_array.base = start;
+	region_array.size = size;
+	region_array.tlb_word2_i_value = tlb_word2_i_value;	/* en-/disable cache */
+
+	/* Call the routine to add in the tlb entries for the memory regions */
+	program_tlb_addr(region_array.base, region_array.size,
+			 region_array.tlb_word2_i_value);
+
+	return;
+}
+
+#endif /* CONFIG_440 */
diff --git a/cpu/pxa/mmc.c b/cpu/pxa/mmc.c
index f7020ee..0fbaa16 100644
--- a/cpu/pxa/mmc.c
+++ b/cpu/pxa/mmc.c
@@ -37,7 +37,7 @@
 
 block_dev_desc_t * mmc_get_dev(int dev)
 {
-	return ((block_dev_desc_t *)&mmc_dev);
+	return (dev == 0) ? &mmc_dev : NULL;
 }
 
 /*
@@ -363,7 +363,7 @@
 
 ulong
 /****************************************************/
-mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
+mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst)
 /****************************************************/
 {
 	int mmc_block_size = MMC_BLOCK_SIZE;
diff --git a/disk/part.c b/disk/part.c
index 2255e72..9e8bd4f 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -24,6 +24,7 @@
 #include <common.h>
 #include <command.h>
 #include <ide.h>
+#include <part.h>
 
 #undef	PART_DEBUG
 
@@ -39,6 +40,58 @@
      defined(CONFIG_MMC) || \
      defined(CONFIG_SYSTEMACE) )
 
+struct block_drvr {
+	char *name;
+	block_dev_desc_t* (*get_dev)(int dev);
+};
+
+static const struct block_drvr block_drvr[] = {
+#if (CONFIG_COMMANDS & CFG_CMD_IDE)
+	{ .name = "ide", .get_dev = ide_get_dev, },
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+	{ .name = "scsi", .get_dev = scsi_get_dev, },
+#endif
+#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
+	{ .name = "usb", .get_dev = usb_stor_get_dev, },
+#endif
+#if defined(CONFIG_MMC)
+	{ .name = "mmc", .get_dev = mmc_get_dev, },
+#endif
+#if defined(CONFIG_SYSTEMACE)
+	{ .name = "ace", .get_dev = systemace_get_dev, },
+#endif
+	{ },
+};
+
+DECLARE_GLOBAL_DATA_PTR;
+
+block_dev_desc_t *get_dev(char* ifname, int dev)
+{
+	const struct block_drvr *drvr = block_drvr;
+	block_dev_desc_t* (*reloc_get_dev)(int dev);
+
+	while (drvr->name) {
+		reloc_get_dev = drvr->get_dev + gd->reloc_off;
+		if (strncmp(ifname, drvr->name, strlen(drvr->name)) == 0)
+			return reloc_get_dev(dev);
+		drvr++;
+	}
+	return NULL;
+}
+#else
+block_dev_desc_t *get_dev(char* ifname, int dev)
+{
+	return NULL;
+}
+#endif
+
+#if ((CONFIG_COMMANDS & CFG_CMD_IDE)	|| \
+     (CONFIG_COMMANDS & CFG_CMD_SCSI)	|| \
+     (CONFIG_COMMANDS & CFG_CMD_USB)	|| \
+     defined(CONFIG_MMC) || \
+     defined(CONFIG_SYSTEMACE) )
+
 /* ------------------------------------------------------------------------- */
 /*
  * reports device info to the user
diff --git a/drivers/Makefile b/drivers/Makefile
index 5a369df..fffc22a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -44,7 +44,7 @@
 	  serial.o serial_max3100.o \
 	  serial_pl010.o serial_pl011.o serial_xuartlite.o \
 	  sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
-	  status_led.o sym53c8xx.o ahci.o \
+	  status_led.o sym53c8xx.o systemace.o ahci.o \
 	  ti_pci1410a.o tigon3.o tsec.o \
 	  usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
 	  videomodes.o w83c553f.o \
diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c
index 696f9a4..5579a1e 100644
--- a/drivers/cfi_flash.c
+++ b/drivers/cfi_flash.c
@@ -36,6 +36,7 @@
 
 #include <common.h>
 #include <asm/processor.h>
+#include <asm/io.h>
 #include <asm/byteorder.h>
 #include <environment.h>
 #ifdef	CFG_FLASH_CFI_DRIVER
@@ -931,27 +932,18 @@
 		debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
 		       cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		*addr.cp = cword.c;
-#ifdef CONFIG_BLACKFIN
-		asm("ssync;");
-#endif
 		break;
 	case FLASH_CFI_16BIT:
 		debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
 		       cmd, cword.w,
 		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		*addr.wp = cword.w;
-#ifdef CONFIG_BLACKFIN
-		asm("ssync;");
-#endif
 		break;
 	case FLASH_CFI_32BIT:
 		debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
 		       cmd, cword.l,
 		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		*addr.lp = cword.l;
-#ifdef CONFIG_BLACKFIN
-		asm("ssync;");
-#endif
 		break;
 	case FLASH_CFI_64BIT:
 #ifdef DEBUG
@@ -966,11 +958,11 @@
 		}
 #endif
 		*addr.llp = cword.ll;
-#ifdef CONFIG_BLACKFIN
-		asm("ssync;");
-#endif
 		break;
 	}
+
+	/* Ensure all the instructions are fully finished */
+	sync();
 }
 
 static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
diff --git a/drivers/systemace.c b/drivers/systemace.c
new file mode 100644
index 0000000..3848d9c
--- /dev/null
+++ b/drivers/systemace.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2004 Picture Elements, Inc.
+ *    Stephen Williams (XXXXXXXXXXXXXXXX)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form 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 Xilinx SystemACE chip support is activated by defining
+ * CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE
+ * to set the base address of the device. This code currently
+ * assumes that the chip is connected via a byte-wide bus.
+ *
+ * The CONFIG_SYSTEMACE also adds to fat support the device class
+ * "ace" that allows the user to execute "fatls ace 0" and the
+ * like. This works by making the systemace_get_dev function
+ * available to cmd_fat.c:get_dev and filling in a block device
+ * description that has all the bits needed for FAT support to
+ * read sectors.
+ *
+ * According to Xilinx technical support, before accessing the
+ * SystemACE CF you need to set the following control bits:
+ *      FORCECFGMODE : 1
+ *      CFGMODE : 0
+ *      CFGSTART : 0
+ */
+
+#include <common.h>
+#include <command.h>
+#include <systemace.h>
+#include <part.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SYSTEMACE
+
+/*
+ * The ace_readw and writew functions read/write 16bit words, but the
+ * offset value is the BYTE offset as most used in the Xilinx
+ * datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined
+ * to be the base address for the chip, usually in the local
+ * peripheral bus.
+ */
+#if (CFG_SYSTEMACE_WIDTH == 8)
+#if !defined(__BIG_ENDIAN)
+#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)<<8) | \
+			(readb(CFG_SYSTEMACE_BASE+off+1)))
+#define ace_writew(val, off) {writeb(val>>8, CFG_SYSTEMACE_BASE+off); \
+			      writeb(val, CFG_SYSTEMACE_BASE+off+1);}
+#else
+#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)) | \
+			(readb(CFG_SYSTEMACE_BASE+off+1)<<8))
+#define ace_writew(val, off) {writeb(val, CFG_SYSTEMACE_BASE+off); \
+			      writeb(val>>8, CFG_SYSTEMACE_BASE+off+1);}
+#endif
+#else
+#define ace_readw(off) (in16(CFG_SYSTEMACE_BASE+off))
+#define ace_writew(val, off) (out16(CFG_SYSTEMACE_BASE+off,val))
+#endif
+
+/* */
+
+static unsigned long systemace_read(int dev, unsigned long start,
+				    unsigned long blkcnt, void *buffer);
+
+static block_dev_desc_t systemace_dev = { 0 };
+
+static int get_cf_lock(void)
+{
+	int retry = 10;
+
+	/* CONTROLREG = LOCKREG */
+	unsigned val = ace_readw(0x18);
+	val |= 0x0002;
+	ace_writew((val & 0xffff), 0x18);
+
+	/* Wait for MPULOCK in STATUSREG[15:0] */
+	while (!(ace_readw(0x04) & 0x0002)) {
+
+		if (retry < 0)
+			return -1;
+
+		udelay(100000);
+		retry -= 1;
+	}
+
+	return 0;
+}
+
+static void release_cf_lock(void)
+{
+	unsigned val = ace_readw(0x18);
+	val &= ~(0x0002);
+	ace_writew((val & 0xffff), 0x18);
+}
+
+block_dev_desc_t *systemace_get_dev(int dev)
+{
+	/* The first time through this, the systemace_dev object is
+	   not yet initialized. In that case, fill it in. */
+	if (systemace_dev.blksz == 0) {
+		systemace_dev.if_type = IF_TYPE_UNKNOWN;
+		systemace_dev.dev = 0;
+		systemace_dev.part_type = PART_TYPE_UNKNOWN;
+		systemace_dev.type = DEV_TYPE_HARDDISK;
+		systemace_dev.blksz = 512;
+		systemace_dev.removable = 1;
+		systemace_dev.block_read = systemace_read;
+
+		/*
+		 * Ensure the correct bus mode (8/16 bits) gets enabled
+		 */
+		ace_writew(CFG_SYSTEMACE_WIDTH == 8 ? 0 : 0x0001, 0);
+
+		init_part(&systemace_dev);
+
+	}
+
+	return &systemace_dev;
+}
+
+/*
+ * This function is called (by dereferencing the block_read pointer in
+ * the dev_desc) to read blocks of data. The return value is the
+ * number of blocks read. A zero return indicates an error.
+ */
+static unsigned long systemace_read(int dev, unsigned long start,
+				    unsigned long blkcnt, void *buffer)
+{
+	int retry;
+	unsigned blk_countdown;
+	unsigned char *dp = buffer;
+	unsigned val;
+
+	if (get_cf_lock() < 0) {
+		unsigned status = ace_readw(0x04);
+
+		/* If CFDETECT is false, card is missing. */
+		if (!(status & 0x0010)) {
+			printf("** CompactFlash card not present. **\n");
+			return 0;
+		}
+
+		printf("**** ACE locked away from me (STATUSREG=%04x)\n",
+		       status);
+		return 0;
+	}
+#ifdef DEBUG_SYSTEMACE
+	printf("... systemace read %lu sectors at %lu\n", blkcnt, start);
+#endif
+
+	retry = 2000;
+	for (;;) {
+		val = ace_readw(0x04);
+
+		/* If CFDETECT is false, card is missing. */
+		if (!(val & 0x0010)) {
+			printf("**** ACE CompactFlash not found.\n");
+			release_cf_lock();
+			return 0;
+		}
+
+		/* If RDYFORCMD, then we are ready to go. */
+		if (val & 0x0100)
+			break;
+
+		if (retry < 0) {
+			printf("**** SystemACE not ready.\n");
+			release_cf_lock();
+			return 0;
+		}
+
+		udelay(1000);
+		retry -= 1;
+	}
+
+	/* The SystemACE can only transfer 256 sectors at a time, so
+	   limit the current chunk of sectors. The blk_countdown
+	   variable is the number of sectors left to transfer. */
+
+	blk_countdown = blkcnt;
+	while (blk_countdown > 0) {
+		unsigned trans = blk_countdown;
+
+		if (trans > 256)
+			trans = 256;
+
+#ifdef DEBUG_SYSTEMACE
+		printf("... transfer %lu sector in a chunk\n", trans);
+#endif
+		/* Write LBA block address */
+		ace_writew((start >> 0) & 0xffff, 0x10);
+		ace_writew((start >> 16) & 0x0fff, 0x12);
+
+		/* NOTE: in the Write Sector count below, a count of 0
+		   causes a transfer of 256, so &0xff gives the right
+		   value for whatever transfer count we want. */
+
+		/* Write sector count | ReadMemCardData. */
+		ace_writew((trans & 0xff) | 0x0300, 0x14);
+
+		/* Reset the configruation controller */
+		val = ace_readw(0x18);
+		val |= 0x0080;
+		ace_writew(val, 0x18);
+
+		retry = trans * 16;
+		while (retry > 0) {
+			int idx;
+
+			/* Wait for buffer to become ready. */
+			while (!(ace_readw(0x04) & 0x0020)) {
+				udelay(100);
+			}
+
+			/* Read 16 words of 2bytes from the sector buffer. */
+			for (idx = 0; idx < 16; idx += 1) {
+				unsigned short val = ace_readw(0x40);
+				*dp++ = val & 0xff;
+				*dp++ = (val >> 8) & 0xff;
+			}
+
+			retry -= 1;
+		}
+
+		/* Clear the configruation controller reset */
+		val = ace_readw(0x18);
+		val &= ~0x0080;
+		ace_writew(val, 0x18);
+
+		/* Count the blocks we transfer this time. */
+		start += trans;
+		blk_countdown -= trans;
+	}
+
+	release_cf_lock();
+
+	return blkcnt;
+}
+#endif /* CONFIG_SYSTEMACE */
diff --git a/dtt/adm1021.c b/dtt/adm1021.c
index 14c38f0..9f65cfb27 100644
--- a/dtt/adm1021.c
+++ b/dtt/adm1021.c
@@ -144,12 +144,15 @@
 	unsigned char sensors[] = CONFIG_DTT_SENSORS;
 	const char *const header = "DTT:   ";
 
+	/* switch to correct I2C bus */
+	I2C_SET_BUS(CFG_DTT_BUS_NUM);
+
 	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]));
+		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);
diff --git a/include/405gp_i2c.h b/include/405gp_i2c.h
deleted file mode 100644
index 5a9a497..0000000
--- a/include/405gp_i2c.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _405gp_i2c_h_
-#define _405gp_i2c_h_
-
-#define	   I2C_REGISTERS_BASE_ADDRESS 0xEF600500
-#define    IIC_MDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICMDBUF)
-#define    IIC_SDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICSDBUF)
-#define    IIC_LMADR	(I2C_REGISTERS_BASE_ADDRESS+IICLMADR)
-#define    IIC_HMADR	(I2C_REGISTERS_BASE_ADDRESS+IICHMADR)
-#define    IIC_CNTL	(I2C_REGISTERS_BASE_ADDRESS+IICCNTL)
-#define    IIC_MDCNTL	(I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL)
-#define    IIC_STS	(I2C_REGISTERS_BASE_ADDRESS+IICSTS)
-#define    IIC_EXTSTS	(I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS)
-#define    IIC_LSADR	(I2C_REGISTERS_BASE_ADDRESS+IICLSADR)
-#define    IIC_HSADR	(I2C_REGISTERS_BASE_ADDRESS+IICHSADR)
-#define    IIC_CLKDIV	(I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV)
-#define    IIC_INTRMSK	(I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK)
-#define    IIC_XFRCNT	(I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT)
-#define    IIC_XTCNTLSS	(I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS)
-#define    IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL)
-
-/* MDCNTL Register Bit definition */
-#define    IIC_MDCNTL_HSCL 0x01
-#define    IIC_MDCNTL_EUBS 0x02
-#define    IIC_MDCNTL_EINT 0x04
-#define    IIC_MDCNTL_ESM  0x08
-#define    IIC_MDCNTL_FSM  0x10
-#define    IIC_MDCNTL_EGC  0x20
-#define    IIC_MDCNTL_FMDB 0x40
-#define    IIC_MDCNTL_FSDB 0x80
-
-/* CNTL Register Bit definition */
-#define    IIC_CNTL_PT     0x01
-#define    IIC_CNTL_READ   0x02
-#define    IIC_CNTL_CHT    0x04
-#define    IIC_CNTL_RPST   0x08
-/* bit 2/3 for Transfer count*/
-#define    IIC_CNTL_AMD    0x40
-#define    IIC_CNTL_HMT    0x80
-
-/* STS Register Bit definition */
-#define    IIC_STS_PT	   0X01
-#define    IIC_STS_IRQA    0x02
-#define    IIC_STS_ERR	   0X04
-#define    IIC_STS_SCMP    0x08
-#define    IIC_STS_MDBF    0x10
-#define    IIC_STS_MDBS    0X20
-#define    IIC_STS_SLPR    0x40
-#define    IIC_STS_SSS     0x80
-
-/* EXTSTS Register Bit definition */
-#define    IIC_EXTSTS_XFRA 0X01
-#define    IIC_EXTSTS_ICT  0X02
-#define    IIC_EXTSTS_LA   0X04
-
-/* XTCNTLSS Register Bit definition */
-#define    IIC_XTCNTLSS_SRST  0x01
-#define    IIC_XTCNTLSS_EPI   0x02
-#define    IIC_XTCNTLSS_SDBF  0x04
-#define    IIC_XTCNTLSS_SBDD  0x08
-#define    IIC_XTCNTLSS_SWS   0x10
-#define    IIC_XTCNTLSS_SWC   0x20
-#define    IIC_XTCNTLSS_SRS   0x40
-#define    IIC_XTCNTLSS_SRC   0x80
-#endif
diff --git a/include/440_i2c.h b/include/440_i2c.h
deleted file mode 100644
index 0c2bf36..0000000
--- a/include/440_i2c.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _440_i2c_h_
-#define _440_i2c_h_
-
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-#define    I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000700)
-#else
-#define    I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000400)
-#endif /*CONFIG_440EP CONFIG_440GR*/
-
-#define	   I2C_REGISTERS_BASE_ADDRESS I2C_BASE_ADDR
-#define    IIC_MDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICMDBUF)
-#define    IIC_SDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICSDBUF)
-#define    IIC_LMADR	(I2C_REGISTERS_BASE_ADDRESS+IICLMADR)
-#define    IIC_HMADR	(I2C_REGISTERS_BASE_ADDRESS+IICHMADR)
-#define    IIC_CNTL	(I2C_REGISTERS_BASE_ADDRESS+IICCNTL)
-#define    IIC_MDCNTL	(I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL)
-#define    IIC_STS	(I2C_REGISTERS_BASE_ADDRESS+IICSTS)
-#define    IIC_EXTSTS	(I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS)
-#define    IIC_LSADR	(I2C_REGISTERS_BASE_ADDRESS+IICLSADR)
-#define    IIC_HSADR	(I2C_REGISTERS_BASE_ADDRESS+IICHSADR)
-#define    IIC_CLKDIV	(I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV)
-#define    IIC_INTRMSK	(I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK)
-#define    IIC_XFRCNT	(I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT)
-#define    IIC_XTCNTLSS	(I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS)
-#define    IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL)
-
-/* MDCNTL Register Bit definition */
-#define    IIC_MDCNTL_HSCL 0x01
-#define    IIC_MDCNTL_EUBS 0x02
-#define    IIC_MDCNTL_EINT 0x04
-#define    IIC_MDCNTL_ESM  0x08
-#define    IIC_MDCNTL_FSM  0x10
-#define    IIC_MDCNTL_EGC  0x20
-#define    IIC_MDCNTL_FMDB 0x40
-#define    IIC_MDCNTL_FSDB 0x80
-
-/* CNTL Register Bit definition */
-#define    IIC_CNTL_PT     0x01
-#define    IIC_CNTL_READ   0x02
-#define    IIC_CNTL_CHT    0x04
-#define    IIC_CNTL_RPST   0x08
-/* bit 2/3 for Transfer count*/
-#define    IIC_CNTL_AMD    0x40
-#define    IIC_CNTL_HMT    0x80
-
-/* STS Register Bit definition */
-#define    IIC_STS_PT	   0X01
-#define    IIC_STS_IRQA    0x02
-#define    IIC_STS_ERR	   0X04
-#define    IIC_STS_SCMP    0x08
-#define    IIC_STS_MDBF    0x10
-#define    IIC_STS_MDBS    0X20
-#define    IIC_STS_SLPR    0x40
-#define    IIC_STS_SSS     0x80
-
-/* EXTSTS Register Bit definition */
-#define    IIC_EXTSTS_XFRA 0X01
-#define    IIC_EXTSTS_ICT  0X02
-#define    IIC_EXTSTS_LA   0X04
-
-/* XTCNTLSS Register Bit definition */
-#define    IIC_XTCNTLSS_SRST  0x01
-#define    IIC_XTCNTLSS_EPI   0x02
-#define    IIC_XTCNTLSS_SDBF  0x04
-#define    IIC_XTCNTLSS_SBDD  0x08
-#define    IIC_XTCNTLSS_SWS   0x10
-#define    IIC_XTCNTLSS_SWC   0x20
-#define    IIC_XTCNTLSS_SRS   0x40
-#define    IIC_XTCNTLSS_SRC   0x80
-#endif
diff --git a/include/4xx_i2c.h b/include/4xx_i2c.h
new file mode 100644
index 0000000..66b7997
--- /dev/null
+++ b/include/4xx_i2c.h
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@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 _4xx_i2c_h_
+#define _4xx_i2c_h_
+
+#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 second */
+
+#if defined(CONFIG_I2C_MULTI_BUS)
+#define I2C_BUS_OFFS	(i2c_bus_num * 0x100)
+#else
+#define I2C_BUS_OFFS	(0x000)
+#endif /* CONFIG_I2C_MULTI_BUS */
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define I2C_BASE_ADDR	(CFG_PERIPHERAL_BASE + 0x00000700 + I2C_BUS_OFFS)
+#elif defined(CONFIG_440)
+/* all remaining 440 variants */
+#define I2C_BASE_ADDR	(CFG_PERIPHERAL_BASE + 0x00000400 + I2C_BUS_OFFS)
+#else
+/* all 405 variants */
+#define I2C_BASE_ADDR	(0xEF600500 + I2C_BUS_OFFS)
+#endif
+
+#define I2C_REGISTERS_BASE_ADDRESS I2C_BASE_ADDR
+#define IIC_MDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICMDBUF)
+#define IIC_SDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICSDBUF)
+#define IIC_LMADR	(I2C_REGISTERS_BASE_ADDRESS+IICLMADR)
+#define IIC_HMADR	(I2C_REGISTERS_BASE_ADDRESS+IICHMADR)
+#define IIC_CNTL	(I2C_REGISTERS_BASE_ADDRESS+IICCNTL)
+#define IIC_MDCNTL	(I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL)
+#define IIC_STS		(I2C_REGISTERS_BASE_ADDRESS+IICSTS)
+#define IIC_EXTSTS	(I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS)
+#define IIC_LSADR	(I2C_REGISTERS_BASE_ADDRESS+IICLSADR)
+#define IIC_HSADR	(I2C_REGISTERS_BASE_ADDRESS+IICHSADR)
+#define IIC_CLKDIV	(I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV)
+#define IIC_INTRMSK	(I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK)
+#define IIC_XFRCNT	(I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT)
+#define IIC_XTCNTLSS	(I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS)
+#define IIC_DIRECTCNTL	(I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL)
+
+/* MDCNTL Register Bit definition */
+#define IIC_MDCNTL_HSCL		0x01
+#define IIC_MDCNTL_EUBS		0x02
+#define IIC_MDCNTL_EINT		0x04
+#define IIC_MDCNTL_ESM		0x08
+#define IIC_MDCNTL_FSM		0x10
+#define IIC_MDCNTL_EGC		0x20
+#define IIC_MDCNTL_FMDB		0x40
+#define IIC_MDCNTL_FSDB		0x80
+
+/* CNTL Register Bit definition */
+#define IIC_CNTL_PT		0x01
+#define IIC_CNTL_READ		0x02
+#define IIC_CNTL_CHT		0x04
+#define IIC_CNTL_RPST		0x08
+/* bit 2/3 for Transfer count*/
+#define IIC_CNTL_AMD		0x40
+#define IIC_CNTL_HMT		0x80
+
+/* STS Register Bit definition */
+#define IIC_STS_PT		0x01
+#define IIC_STS_IRQA		0x02
+#define IIC_STS_ERR		0x04
+#define IIC_STS_SCMP		0x08
+#define IIC_STS_MDBF		0x10
+#define IIC_STS_MDBS		0x20
+#define IIC_STS_SLPR		0x40
+#define IIC_STS_SSS		0x80
+
+/* EXTSTS Register Bit definition */
+#define IIC_EXTSTS_XFRA		0x01
+#define IIC_EXTSTS_ICT		0x02
+#define IIC_EXTSTS_LA		0x04
+
+/* XTCNTLSS Register Bit definition */
+#define IIC_XTCNTLSS_SRST	0x01
+#define IIC_XTCNTLSS_EPI	0x02
+#define IIC_XTCNTLSS_SDBF	0x04
+#define IIC_XTCNTLSS_SBDD	0x08
+#define IIC_XTCNTLSS_SWS	0x10
+#define IIC_XTCNTLSS_SWC	0x20
+#define IIC_XTCNTLSS_SRS	0x40
+#define IIC_XTCNTLSS_SRC	0x80
+
+/* IICx_DIRECTCNTL register */
+#define IIC_DIRCNTL_SDAC	0x08
+#define IIC_DIRCNTL_SCC		0x04
+#define IIC_DIRCNTL_MSDA	0x02
+#define IIC_DIRCNTL_MSC		0x01
+
+#define DIRCTNL_FREE(v)		(((v) & 0x0f) == 0x0f)
+#endif
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 648a10d..47c18e7 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -29,6 +29,10 @@
 #include <asm/arch/hardware.h>
 #endif	/* XXX###XXX */
 
+static inline void sync(void)
+{
+}
+
 /*
  * Generic virtual read/write.  Note that we don't support half-word
  * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h
index e86c456..3c0d569 100644
--- a/include/asm-avr32/io.h
+++ b/include/asm-avr32/io.h
@@ -89,4 +89,8 @@
 
 #endif /* __KERNEL__ */
 
+static inline void sync(void)
+{
+}
+
 #endif /* __ASM_AVR32_IO_H */
diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h
index e5b388e..fc27194 100644
--- a/include/asm-blackfin/io.h
+++ b/include/asm-blackfin/io.h
@@ -25,6 +25,11 @@
 #ifndef _BLACKFIN_IO_H
 #define _BLACKFIN_IO_H
 
+static inline void sync(void)
+{
+	__asm__ __volatile__ asm("ssync" : : : "memory");
+}
+
 #ifdef __KERNEL__
 
 #include <linux/config.h>
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index 85d44aa..e64d788 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -201,4 +201,8 @@
 __OUTS(w)
 __OUTS(l)
 
+static inline void sync(void)
+{
+}
+
 #endif
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index 79a9626..7bbdefb 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -1 +1,8 @@
-/* */
+#ifndef __ASM_M68K_IO_H_
+#define __ASM_M68K_IO_H_
+
+static inline void sync(void)
+{
+}
+
+#endif /* __ASM_M68K_IO_H_ */
diff --git a/include/asm-microblaze/io.h b/include/asm-microblaze/io.h
index 3359045..1c77ade 100644
--- a/include/asm-microblaze/io.h
+++ b/include/asm-microblaze/io.h
@@ -125,4 +125,8 @@
 #define ioremap_writethrough(physaddr, size)	(physaddr)
 #define ioremap_fullcache(physaddr, size)	(physaddr)
 
+static inline void sync(void)
+{
+}
+
 #endif /* __MICROBLAZE_IO_H__ */
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 857fb03..cd4d5dc 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -447,4 +447,8 @@
 #define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
 #define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
 
+static inline void sync(void)
+{
+}
+
 #endif /* _ASM_IO_H */
diff --git a/include/asm-nios/io.h b/include/asm-nios/io.h
index 07499d9..d77695a 100644
--- a/include/asm-nios/io.h
+++ b/include/asm-nios/io.h
@@ -97,4 +97,8 @@
 	while (count--) outl (*p++, port);
 }
 
+static inline void sync(void)
+{
+}
+
 #endif /* __ASM_NIOS_IO_H_ */
diff --git a/include/asm-nios2/io.h b/include/asm-nios2/io.h
index 0fab53b..5bb5322 100644
--- a/include/asm-nios2/io.h
+++ b/include/asm-nios2/io.h
@@ -24,7 +24,10 @@
 #ifndef __ASM_NIOS2_IO_H_
 #define __ASM_NIOS2_IO_H_
 
-#define sync() asm volatile ("sync" : : : "memory");
+static inline void sync(void)
+{
+	__asm__ __volatile__ ("sync" : : : "memory");
+}
 
 extern unsigned char inb (unsigned char *port);
 extern unsigned short inw (unsigned short *port);
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 8e5fe11..bbc9ba0 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -95,8 +95,15 @@
  * Acts as a barrier to ensure all previous I/O accesses have
  * completed before any further ones are issued.
  */
-#define eieio() __asm__ __volatile__ ("eieio" : : : "memory");
-#define sync()  __asm__ __volatile__ ("sync" : : : "memory");
+static inline void eieio(void)
+{
+	__asm__ __volatile__ ("eieio" : : : "memory");
+}
+
+static inline void sync(void)
+{
+	__asm__ __volatile__ ("sync" : : : "memory");
+}
 
 /* Enforce in-order execution of data I/O.
  * No distinction between read/write on PPC; use eieio for all three.
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h
index 914f28b..b226825 100644
--- a/include/asm-ppc/mmu.h
+++ b/include/asm-ppc/mmu.h
@@ -335,41 +335,6 @@
  * instructions.
  */
 
-#define	TLB_LO          1
-#define	TLB_HI          0
-
-#define	TLB_DATA        TLB_LO
-#define	TLB_TAG         TLB_HI
-
-/* Tag portion */
-
-#define TLB_EPN_MASK    0xFFFFFC00      /* Effective Page Number */
-#define TLB_PAGESZ_MASK 0x00000380
-#define TLB_PAGESZ(x)   (((x) & 0x7) << 7)
-#define   PAGESZ_1K		0
-#define   PAGESZ_4K             1
-#define   PAGESZ_16K            2
-#define   PAGESZ_64K            3
-#define   PAGESZ_256K           4
-#define   PAGESZ_1M             5
-#define   PAGESZ_4M             6
-#define   PAGESZ_16M            7
-#define TLB_VALID       0x00000040      /* Entry is valid */
-
-/* Data portion */
-
-#define TLB_RPN_MASK    0xFFFFFC00      /* Real Page Number */
-#define TLB_PERM_MASK   0x00000300
-#define TLB_EX          0x00000200      /* Instruction execution allowed */
-#define TLB_WR          0x00000100      /* Writes permitted */
-#define TLB_ZSEL_MASK   0x000000F0
-#define TLB_ZSEL(x)     (((x) & 0xF) << 4)
-#define TLB_ATTR_MASK   0x0000000F
-#define TLB_W           0x00000008      /* Caching is write-through */
-#define TLB_I           0x00000004      /* Caching is inhibited */
-#define TLB_M           0x00000002      /* Memory is coherent */
-#define TLB_G           0x00000001      /* Memory is guarded from prefetch */
-
 /*
  * e500 support
  */
@@ -482,7 +447,162 @@
 #define LAWAR_SIZE_16G		(LAWAR_SIZE_BASE+23)
 #define LAWAR_SIZE_32G		(LAWAR_SIZE_BASE+24)
 
-#ifdef CONFIG_440SPE
+#ifdef CONFIG_440
+/* 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 specific defines.
++----------------------------------------------------------------------------*/
+#define TLB_256MB_ALIGN_MASK 0xF0000000
+#define TLB_16MB_ALIGN_MASK  0xFF000000
+#define TLB_1MB_ALIGN_MASK   0xFFF00000
+#define TLB_256KB_ALIGN_MASK 0xFFFC0000
+#define TLB_64KB_ALIGN_MASK  0xFFFF0000
+#define TLB_16KB_ALIGN_MASK  0xFFFFC000
+#define TLB_4KB_ALIGN_MASK   0xFFFFF000
+#define TLB_1KB_ALIGN_MASK   0xFFFFFC00
+#define TLB_256MB_SIZE       0x10000000
+#define TLB_16MB_SIZE        0x01000000
+#define TLB_1MB_SIZE         0x00100000
+#define TLB_256KB_SIZE       0x00040000
+#define TLB_64KB_SIZE        0x00010000
+#define TLB_16KB_SIZE        0x00004000
+#define TLB_4KB_SIZE         0x00001000
+#define TLB_1KB_SIZE         0x00000400
+
+#define TLB_WORD0_EPN_MASK   0xFFFFFC00
+#define TLB_WORD0_EPN_ENCODE(n) (((unsigned long)(n))&0xFFFFFC00)
+#define TLB_WORD0_EPN_DECODE(n) (((unsigned long)(n))&0xFFFFFC00)
+#define TLB_WORD0_V_MASK     0x00000200
+#define TLB_WORD0_V_ENABLE   0x00000200
+#define TLB_WORD0_V_DISABLE  0x00000000
+#define TLB_WORD0_TS_MASK    0x00000100
+#define TLB_WORD0_TS_1       0x00000100
+#define TLB_WORD0_TS_0       0x00000000
+#define TLB_WORD0_SIZE_MASK  0x000000F0
+#define TLB_WORD0_SIZE_1KB   0x00000000
+#define TLB_WORD0_SIZE_4KB   0x00000010
+#define TLB_WORD0_SIZE_16KB  0x00000020
+#define TLB_WORD0_SIZE_64KB  0x00000030
+#define TLB_WORD0_SIZE_256KB 0x00000040
+#define TLB_WORD0_SIZE_1MB   0x00000050
+#define TLB_WORD0_SIZE_16MB  0x00000070
+#define TLB_WORD0_SIZE_256MB 0x00000090
+#define TLB_WORD0_TPAR_MASK  0x0000000F
+#define TLB_WORD0_TPAR_ENCODE(n) ((((unsigned long)(n))&0x0F)<<0)
+#define TLB_WORD0_TPAR_DECODE(n) ((((unsigned long)(n))>>0)&0x0F)
+
+#define TLB_WORD1_RPN_MASK   0xFFFFFC00
+#define TLB_WORD1_RPN_ENCODE(n) (((unsigned long)(n))&0xFFFFFC00)
+#define TLB_WORD1_RPN_DECODE(n) (((unsigned long)(n))&0xFFFFFC00)
+#define TLB_WORD1_PAR1_MASK  0x00000300
+#define TLB_WORD1_PAR1_ENCODE(n) ((((unsigned long)(n))&0x03)<<8)
+#define TLB_WORD1_PAR1_DECODE(n) ((((unsigned long)(n))>>8)&0x03)
+#define TLB_WORD1_PAR1_0     0x00000000
+#define TLB_WORD1_PAR1_1     0x00000100
+#define TLB_WORD1_PAR1_2     0x00000200
+#define TLB_WORD1_PAR1_3     0x00000300
+#define TLB_WORD1_ERPN_MASK  0x0000000F
+#define TLB_WORD1_ERPN_ENCODE(n) ((((unsigned long)(n))&0x0F)<<0)
+#define TLB_WORD1_ERPN_DECODE(n) ((((unsigned long)(n))>>0)&0x0F)
+
+#define TLB_WORD2_PAR2_MASK  0xC0000000
+#define TLB_WORD2_PAR2_ENCODE(n) ((((unsigned long)(n))&0x03)<<30)
+#define TLB_WORD2_PAR2_DECODE(n) ((((unsigned long)(n))>>30)&0x03)
+#define TLB_WORD2_PAR2_0     0x00000000
+#define TLB_WORD2_PAR2_1     0x40000000
+#define TLB_WORD2_PAR2_2     0x80000000
+#define TLB_WORD2_PAR2_3     0xC0000000
+#define TLB_WORD2_U0_MASK    0x00008000
+#define TLB_WORD2_U0_ENABLE  0x00008000
+#define TLB_WORD2_U0_DISABLE 0x00000000
+#define TLB_WORD2_U1_MASK    0x00004000
+#define TLB_WORD2_U1_ENABLE  0x00004000
+#define TLB_WORD2_U1_DISABLE 0x00000000
+#define TLB_WORD2_U2_MASK    0x00002000
+#define TLB_WORD2_U2_ENABLE  0x00002000
+#define TLB_WORD2_U2_DISABLE 0x00000000
+#define TLB_WORD2_U3_MASK    0x00001000
+#define TLB_WORD2_U3_ENABLE  0x00001000
+#define TLB_WORD2_U3_DISABLE 0x00000000
+#define TLB_WORD2_W_MASK     0x00000800
+#define TLB_WORD2_W_ENABLE   0x00000800
+#define TLB_WORD2_W_DISABLE  0x00000000
+#define TLB_WORD2_I_MASK     0x00000400
+#define TLB_WORD2_I_ENABLE   0x00000400
+#define TLB_WORD2_I_DISABLE  0x00000000
+#define TLB_WORD2_M_MASK     0x00000200
+#define TLB_WORD2_M_ENABLE   0x00000200
+#define TLB_WORD2_M_DISABLE  0x00000000
+#define TLB_WORD2_G_MASK     0x00000100
+#define TLB_WORD2_G_ENABLE   0x00000100
+#define TLB_WORD2_G_DISABLE  0x00000000
+#define TLB_WORD2_E_MASK     0x00000080
+#define TLB_WORD2_E_ENABLE   0x00000080
+#define TLB_WORD2_E_DISABLE  0x00000000
+#define TLB_WORD2_UX_MASK    0x00000020
+#define TLB_WORD2_UX_ENABLE  0x00000020
+#define TLB_WORD2_UX_DISABLE 0x00000000
+#define TLB_WORD2_UW_MASK    0x00000010
+#define TLB_WORD2_UW_ENABLE  0x00000010
+#define TLB_WORD2_UW_DISABLE 0x00000000
+#define TLB_WORD2_UR_MASK    0x00000008
+#define TLB_WORD2_UR_ENABLE  0x00000008
+#define TLB_WORD2_UR_DISABLE 0x00000000
+#define TLB_WORD2_SX_MASK    0x00000004
+#define TLB_WORD2_SX_ENABLE  0x00000004
+#define TLB_WORD2_SX_DISABLE 0x00000000
+#define TLB_WORD2_SW_MASK    0x00000002
+#define TLB_WORD2_SW_ENABLE  0x00000002
+#define TLB_WORD2_SW_DISABLE 0x00000000
+#define TLB_WORD2_SR_MASK    0x00000001
+#define TLB_WORD2_SR_ENABLE  0x00000001
+#define TLB_WORD2_SR_DISABLE 0x00000000
+
 /*----------------------------------------------------------------------------+
 | Following instructions are not available in Book E mode of the GNU assembler.
 +----------------------------------------------------------------------------*/
@@ -516,11 +636,15 @@
 #define MBAR_INST 				.long 0x7c000000|\
 					(854<<1)
 
-/*----------------------------------------------------------------------------+
-| Following instruction is not available in PPC405 mode of the GNU assembler.
-+----------------------------------------------------------------------------*/
-#define TLBRE(rt,ra,ws)			.long 0x7c000000|\
-					(rt<<21)|(ra<<16)|(ws<<11)|(946<<1)
+#ifndef __ASSEMBLY__
+/* Prototypes */
+void mttlb1(unsigned long index, unsigned long value);
+void mttlb2(unsigned long index, unsigned long value);
+void mttlb3(unsigned long index, unsigned long value);
+unsigned long mftlb1(unsigned long index);
+unsigned long mftlb2(unsigned long index);
+unsigned long mftlb3(unsigned long index);
+#endif /* __ASSEMBLY__ */
 
-#endif
+#endif /* CONFIG_440 */
 #endif /* _PPC_MMU_H_ */
diff --git a/include/common.h b/include/common.h
index 982d6a8..b162dbd 100644
--- a/include/common.h
+++ b/include/common.h
@@ -187,6 +187,7 @@
 long int initdram (int);
 int	display_options (void);
 void	print_size (ulong, const char *);
+int	print_buffer (ulong addr, void* data, uint width, uint count, uint linelen);
 
 /* common/main.c */
 void	main_loop	(void);
diff --git a/include/configs/hmi1001.h b/include/configs/hmi1001.h
index cfaf153..095b5f6 100644
--- a/include/configs/hmi1001.h
+++ b/include/configs/hmi1001.h
@@ -210,6 +210,7 @@
  */
 #define CONFIG_MPC5xxx_FEC	1
 #define CONFIG_PHY_ADDR		0x00
+#define CONFIG_MII		1		/* MII PHY management		*/
 
 /*
  * GPIO configuration
diff --git a/include/configs/katmai.h b/include/configs/katmai.h
new file mode 100644
index 0000000..1606d0d
--- /dev/null
+++ b/include/configs/katmai.h
@@ -0,0 +1,429 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * (C) Copyright 2004 Paul Reynolds <PaulReynolds@lhsolutions.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
+ */
+
+/************************************************************************
+ * katmai.h - configuration for AMCC Katmai (440SPe)
+ ***********************************************************************/
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*-----------------------------------------------------------------------
+ * High Level Configuration Options
+ *----------------------------------------------------------------------*/
+#define CONFIG_KATMAI			1	/* Board is Katmai	*/
+#define CONFIG_4xx			1	/* ... PPC4xx family	*/
+#define CONFIG_440			1	/* ... PPC440 family	*/
+#define CONFIG_440SPE			1	/* Specifc SPe support	*/
+#undef	CFG_DRAM_TEST				/* Disable-takes long time */
+#define CONFIG_SYS_CLK_FREQ	33333333	/* external freq to pll	*/
+
+#define CONFIG_BOARD_EARLY_INIT_F 1	/* Call board_pre_init		*/
+#define	CONFIG_MISC_INIT_F	1	/* Use misc_init_f()		*/
+#define CONFIG_ADD_RAM_INFO	1	/* Print additional info	*/
+#undef  CONFIG_SHOW_BOOT_PROGRESS
+
+/*-----------------------------------------------------------------------
+ * Base addresses -- Note these are effective addresses where the
+ * actual resources get mapped (not physical addresses)
+ *----------------------------------------------------------------------*/
+#define CFG_MONITOR_LEN		(256 * 1024)	/* Reserve 256 kB for Mon */
+#define CFG_MALLOC_LEN		(512 * 1024)	/* Reserve 512 kB for malloc */
+
+#define CFG_SDRAM_BASE		0x00000000	/* _must_ be 0		*/
+#define CFG_FLASH_BASE		0xff000000	/* start of FLASH	*/
+#define CFG_MONITOR_BASE	TEXT_BASE
+#define CFG_PERIPHERAL_BASE	0xa0000000	/* internal peripherals	*/
+#define CFG_ISRAM_BASE		0x90000000	/* internal SRAM	*/
+
+#define CFG_PCI_MEMBASE		0x80000000	/* mapped PCI memory	*/
+#define CFG_PCI_BASE		0xd0000000	/* internal PCI regs	*/
+#define CFG_PCI_TARGBASE	CFG_PCI_MEMBASE
+
+#define CFG_PCIE_MEMBASE	0xb0000000	/* mapped PCIe memory	*/
+#define CFG_PCIE_MEMSIZE	0x01000000
+#define CFG_PCIE_BASE		0xe0000000	/* PCIe UTL regs */
+
+#define CFG_PCIE0_CFGBASE	0xc0000000
+#define CFG_PCIE0_XCFGBASE	0xc0000400
+#define CFG_PCIE1_CFGBASE	0xc0001000
+#define CFG_PCIE1_XCFGBASE	0xc0001400
+#define CFG_PCIE2_CFGBASE	0xc0002000
+#define CFG_PCIE2_XCFGBASE	0xc0002400
+
+/* System RAM mapped to PCI space */
+#define CONFIG_PCI_SYS_MEM_BUS	CFG_SDRAM_BASE
+#define CONFIG_PCI_SYS_MEM_PHYS	CFG_SDRAM_BASE
+#define CONFIG_PCI_SYS_MEM_SIZE	(1024 * 1024 * 1024)
+
+#define CFG_ACE_BASE		0xe0000000	/* Xilinx ACE controller - Compact Flash */
+
+/*-----------------------------------------------------------------------
+ * Initial RAM & stack pointer (placed in internal SRAM)
+ *----------------------------------------------------------------------*/
+#define CFG_TEMP_STACK_OCM	1
+#define CFG_OCM_DATA_ADDR	CFG_ISRAM_BASE
+#define CFG_INIT_RAM_ADDR	CFG_ISRAM_BASE	/* Initial RAM address	*/
+#define CFG_INIT_RAM_END	0x2000		/* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE	128		/* num bytes initial data */
+
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_POST_WORD_ADDR	(CFG_GBL_DATA_OFFSET - 0x4)
+#define CFG_INIT_SP_OFFSET	CFG_POST_WORD_ADDR
+
+/*-----------------------------------------------------------------------
+ * Serial Port
+ *----------------------------------------------------------------------*/
+#define CONFIG_SERIAL_MULTI	1
+#undef CONFIG_UART1_CONSOLE
+#undef CFG_EXT_SERIAL_CLOCK
+#define CONFIG_BAUDRATE		115200
+#define CFG_BAUDRATE_TABLE  \
+	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
+
+/*-----------------------------------------------------------------------
+ * DDR SDRAM
+ *----------------------------------------------------------------------*/
+#define CONFIG_SPD_EEPROM	1	/* Use SPD EEPROM for setup	*/
+#define SPD_EEPROM_ADDRESS	{0x51, 0x52}	/* SPD i2c spd addresses*/
+#define CONFIG_DDR_ECC		1	/* with ECC support		*/
+#undef  CONFIG_STRESS
+
+/*-----------------------------------------------------------------------
+ * I2C
+ *----------------------------------------------------------------------*/
+#define CONFIG_HARD_I2C		1	/* I2C with hardware support	*/
+#undef	CONFIG_SOFT_I2C			/* I2C bit-banged		*/
+#define CFG_I2C_SPEED		100000	/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		0x7F
+
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_I2C_CMD_TREE
+#define CFG_SPD_BUS_NUM		0	/* The I2C bus for SPD		*/
+
+#define IIC0_BOOTPROM_ADDR	0x50
+#define IIC0_ALT_BOOTPROM_ADDR	0x54
+
+#define CFG_I2C_MULTI_EEPROMS
+#define CFG_I2C_EEPROM_ADDR	(0x50)
+#define CFG_I2C_EEPROM_ADDR_LEN 1
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+#define CFG_EEPROM_PAGE_WRITE_BITS 3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10
+
+/* I2C RTC */
+#define CONFIG_RTC_M41T11	1
+#define CFG_RTC_BUS_NUM		1	/* The I2C bus for RTC		*/
+#define CFG_I2C_RTC_ADDR	0x68
+#define CFG_M41T11_BASE_YEAR	1900	/* play along with linux	*/
+
+/* I2C DTT */
+#define CONFIG_DTT_ADM1021	1	/* ADM1021 temp sensor support	*/
+#define CFG_DTT_BUS_NUM		1	/* The I2C bus for DTT		*/
+/*
+ * standard dtt sensor configuration - bottom bit will determine local or
+ * remote sensor of the ADM1021, the rest determines index into
+ * CFG_DTT_ADM1021 array below.
+ */
+#define CONFIG_DTT_SENSORS	{ 0, 1 }
+
+/*
+ * ADM1021 temp sensor configuration (see dtt/adm1021.c for details).
+ * there will be one entry in this array for each two (dummy) sensors in
+ * CONFIG_DTT_SENSORS.
+ *
+ * For Katmai board:
+ * - only one ADM1021
+ * - i2c addr 0x18
+ * - conversion rate 0x02 = 0.25 conversions/second
+ * - ALERT ouput disabled
+ * - local temp sensor enabled, min set to 0 deg, max set to 85 deg
+ * - remote temp sensor enabled, min set to 0 deg, max set to 85 deg
+ */
+#define CFG_DTT_ADM1021		{ { 0x18, 0x02, 0, 1, 0, 85, 1, 0, 58} }
+
+/*-----------------------------------------------------------------------
+ * Environment
+ *----------------------------------------------------------------------*/
+#define	CFG_ENV_IS_IN_FLASH	1	/* Environment uses flash	*/
+
+#define CONFIG_PREBOOT	"echo;"	\
+	"echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+	"echo"
+
+#undef	CONFIG_BOOTARGS
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"netdev=eth0\0"							\
+	"hostname=katmai\0"						\
+	"nfsargs=setenv bootargs root=/dev/nfs rw "			\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"ramargs=setenv bootargs root=/dev/ram rw\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off panic=1\0"			\
+	"addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\
+	"flash_nfs=run nfsargs addip addtty;"				\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip addtty;"				\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;"     \
+		"bootm\0"						\
+	"rootpath=/opt/eldk/ppc_4xx\0"				\
+	"bootfile=katmai/uImage\0"					\
+	"kernel_addr=fff10000\0"					\
+	"ramdisk_addr=fff20000\0"					\
+	"initrd_high=30000000\0"					\
+	"load=tftp 200000 katmai/u-boot.bin\0"				\
+	"update=protect off fffc0000 ffffffff;era fffc0000 ffffffff;"	\
+		"cp.b ${fileaddr} fffc0000 ${filesize};"		\
+		"setenv filesize;saveenv\0"				\
+	"upd=run load;run update\0"					\
+	"kozio=bootm ffc60000\0"					\
+	""
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds	*/
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_COMMANDS	       (CONFIG_CMD_DFL	| \
+				CFG_CMD_ASKENV	| \
+				CFG_CMD_EEPROM	| \
+				CFG_CMD_DATE	| \
+				CFG_CMD_DHCP	| \
+				CFG_CMD_DIAG	| \
+				CFG_CMD_DTT	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_EXT2	| \
+				CFG_CMD_FAT	| \
+				CFG_CMD_I2C	| \
+				CFG_CMD_IRQ	| \
+				CFG_CMD_MII	| \
+				CFG_CMD_NET	| \
+				CFG_CMD_NFS	| \
+				CFG_CMD_PCI	| \
+				CFG_CMD_PING	| \
+				CFG_CMD_REGINFO	| \
+				CFG_CMD_SDRAM)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define	CONFIG_IBM_EMAC4_V4	1	/* 440SPe has this EMAC version	*/
+#define CONFIG_MII		1	/* MII PHY management		*/
+#define CONFIG_PHY_ADDR		1	/* PHY address, See schematics	*/
+#define CONFIG_HAS_ETH0
+#define CONFIG_PHY_RESET        1	/* reset phy upon startup	*/
+#define CONFIG_PHY_RESET_DELAY	1000
+#define CONFIG_CIS8201_PHY	1	/* Enable 'special' RGMII mode for Cicada phy */
+#define CONFIG_PHY_GIGE		1	/* Include GbE speed/duplex detection */
+#define CFG_RX_ETH_BUFFER	32	/* Number of ethernet rx buffers & descriptors */
+
+#define CONFIG_NETCONSOLE		/* include NetConsole support	*/
+#define CONFIG_NET_MULTI		/* needed for NetConsole	*/
+
+#undef CONFIG_WATCHDOG			/* watchdog disabled		*/
+
+/*
+ * 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	0x0400000	/* memtest works on		*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM		*/
+
+#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_CMDLINE_EDITING	1	/* add command line history	*/
+#define CONFIG_LOOPW            1       /* enable loopw command         */
+#define CONFIG_MX_CYCLIC        1       /* enable mdc/mwc commands      */
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+#define CONFIG_VERSION_VARIABLE 1	/* include version env variable */
+
+#define CFG_4xx_RESET_TYPE	0x2	/* use chip reset on this board	*/
+
+/*-----------------------------------------------------------------------
+ * FLASH related
+ *----------------------------------------------------------------------*/
+#define CFG_FLASH_CFI
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_EMPTY_INFO		/* print 'E' for empty sector on flinfo */
+#define CFG_FLASH_USE_BUFFER_WRITE 1	/* use buffered writes (20x faster)	*/
+
+#define CFG_FLASH_BANKS_LIST    {CFG_FLASH_BASE}
+#define CFG_MAX_FLASH_BANKS     1		    /* number of banks	    */
+#define CFG_MAX_FLASH_SECT	1024		    /* sectors per device   */
+
+#undef	CFG_FLASH_CHECKSUM
+#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_SECT_SIZE	0x20000 /* size of one complete sector	*/
+#define CFG_ENV_ADDR		(CFG_MONITOR_BASE-CFG_ENV_SECT_SIZE)
+#define	CFG_ENV_SIZE		0x4000	/* Total Size of Environment Sector	*/
+
+/* Address and size of Redundant Environment Sector	*/
+#define CFG_ENV_ADDR_REDUND	(CFG_ENV_ADDR-CFG_ENV_SECT_SIZE)
+#define CFG_ENV_SIZE_REDUND	(CFG_ENV_SIZE)
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+/* General PCI */
+#define CONFIG_PCI			/* include pci support		*/
+#define CONFIG_PCI_PNP		1	/* do pci plug-and-play		*/
+#define CONFIG_PCI_SCAN_SHOW	1	/* show pci devices on startup	*/
+#undef CONFIG_PCI_CONFIG_HOST_BRIDGE
+
+/* Board-specific PCI */
+#define CFG_PCI_PRE_INIT	1	/* enable board pci_pre_init()	*/
+#define CFG_PCI_TARGET_INIT		/* let board init pci target    */
+#undef	CFG_PCI_MASTER_INIT
+
+#define CFG_PCI_SUBSYS_VENDORID 0x1014	/* IBM				*/
+#define CFG_PCI_SUBSYS_DEVICEID 0xcafe	/* Whatever			*/
+/* #define CFG_PCI_SUBSYS_ID	CFG_PCI_SUBSYS_DEVICEID */
+
+/*
+ *  NETWORK Support (PCI):
+ */
+/* Support for Intel 82557/82559/82559ER chips. */
+#define CONFIG_EEPRO100
+
+/*-----------------------------------------------------------------------
+ * Xilinx System ACE support
+ *----------------------------------------------------------------------*/
+#define CONFIG_SYSTEMACE	1	/* Enable SystemACE support	*/
+#define CFG_SYSTEMACE_WIDTH	16	/* Data bus width is 16		*/
+#define CFG_SYSTEMACE_BASE	CFG_ACE_BASE
+#define CONFIG_DOS_PARTITION	1
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ *----------------------------------------------------------------------*/
+
+/* Memory Bank 0 (Flash) initialization					*/
+#define CFG_EBC_PB0AP		(EBC_BXAP_BME_DISABLED      |		\
+				 EBC_BXAP_TWT_ENCODE(7)     |		\
+				 EBC_BXAP_BCE_DISABLE       |		\
+				 EBC_BXAP_BCT_2TRANS        |		\
+				 EBC_BXAP_CSN_ENCODE(0)     |		\
+				 EBC_BXAP_OEN_ENCODE(0)     |		\
+				 EBC_BXAP_WBN_ENCODE(0)     |		\
+				 EBC_BXAP_WBF_ENCODE(0)     |		\
+				 EBC_BXAP_TH_ENCODE(0)      |		\
+				 EBC_BXAP_RE_DISABLED       |		\
+				 EBC_BXAP_SOR_DELAYED       |		\
+				 EBC_BXAP_BEM_WRITEONLY     |		\
+				 EBC_BXAP_PEN_DISABLED)
+#define CFG_EBC_PB0CR		(EBC_BXCR_BAS_ENCODE(CFG_FLASH_BASE) |	\
+				 EBC_BXCR_BS_16MB                    |	\
+				 EBC_BXCR_BU_RW                      |	\
+				 EBC_BXCR_BW_16BIT)
+
+/* Memory Bank 1 (Xilinx System ACE controller) initialization		*/
+#define CFG_EBC_PB1AP		0x7F8FFE80
+#define CFG_EBC_PB1CR		(EBC_BXCR_BAS_ENCODE(CFG_ACE_BASE)  |	\
+				 EBC_BXCR_BS_1MB                    |	\
+				 EBC_BXCR_BU_RW                     |	\
+				 EBC_BXCR_BW_16BIT)
+
+/*-------------------------------------------------------------------------
+ * Initialize EBC CONFIG -
+ * Keep the Default value, but the bit PDT which has to be set to 1 ?TBC
+ * default value : 0x07C00000 - 0 0 000 1 1 1 1 1 0000 0 00000 000000000000
+ *-------------------------------------------------------------------------*/
+#define CFG_EBC_CFG		(EBC_CFG_LE_UNLOCK    |	\
+				 EBC_CFG_PTD_ENABLE   |	\
+				 EBC_CFG_RTC_16PERCLK | \
+				 EBC_CFG_ATC_PREVIOUS | \
+				 EBC_CFG_DTC_PREVIOUS | \
+				 EBC_CFG_CTC_PREVIOUS | \
+				 EBC_CFG_OEO_PREVIOUS | \
+				 EBC_CFG_EMC_DEFAULT  |	\
+				 EBC_CFG_PME_DISABLE  |	\
+				 EBC_CFG_PR_16)
+
+/*-----------------------------------------------------------------------
+ * GPIO Setup
+ *----------------------------------------------------------------------*/
+#define CFG_GPIO_PCIE_PRESENT0	17
+#define CFG_GPIO_PCIE_PRESENT1	21
+#define CFG_GPIO_PCIE_PRESENT2	23
+#define CFG_GPIO_RS232_FORCEOFF	30
+
+#define CFG_PFC0		(GPIO_VAL(CFG_GPIO_PCIE_PRESENT0) | \
+				 GPIO_VAL(CFG_GPIO_PCIE_PRESENT1) | \
+				 GPIO_VAL(CFG_GPIO_PCIE_PRESENT2) | \
+				 GPIO_VAL(CFG_GPIO_RS232_FORCEOFF))
+#define CFG_GPIO_OR		GPIO_VAL(CFG_GPIO_RS232_FORCEOFF)
+#define CFG_GPIO_TCR		GPIO_VAL(CFG_GPIO_RS232_FORCEOFF)
+#define CFG_GPIO_ODR		0
+
+/*
+ * 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_DCACHE_SIZE		8192	/* For AMCC 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
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM	0x02		/* Software reboot */
+
+#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
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/luan.h b/include/configs/luan.h
index 5c9d208..9c8769b 100644
--- a/include/configs/luan.h
+++ b/include/configs/luan.h
@@ -37,8 +37,9 @@
 #define CONFIG_440		1
 #define CONFIG_SYS_CLK_FREQ	33333333 /* external freq to pll	*/
 
-#define CONFIG_BOARD_EARLY_INIT_F 1     /* call board_early_init_f()	*/
+#define CONFIG_BOARD_EARLY_INIT_F 1	/* call board_early_init_f()	*/
 #define CONFIG_MISC_INIT_R	1	/* call misc_init_r()		*/
+#define CONFIG_ADD_RAM_INFO	1	/* Print additional info	*/
 
 /*-----------------------------------------------------------------------
  * Base addresses -- Note these are effective addresses where the
@@ -132,10 +133,9 @@
 /*-----------------------------------------------------------------------
  * DDR SDRAM
  *----------------------------------------------------------------------*/
-#undef  CONFIG_SPD_EEPROM		/* SPD EEPROM init doesn't support DDR2 */
-#define SPD_EEPROM_ADDRESS {0x52,0x53}	/* I2C SPD addresses */
-#define IIC0_DIMM0_ADDR         0x52
-#define IIC0_DIMM1_ADDR         0x53
+#define CONFIG_SPD_EEPROM	1	/* Use SPD EEPROM for setup	*/
+#define SPD_EEPROM_ADDRESS	{0x53, 0x52}	/* SPD i2c spd addresses*/
+#undef CONFIG_DDR_ECC			/* no ECC support for now	*/
 
 /*-----------------------------------------------------------------------
  * I2C
@@ -206,11 +206,6 @@
 #define CONFIG_NETCONSOLE		/* include NetConsole support	*/
 #define CONFIG_NET_MULTI		/* needed for NetConsole	*/
 
-/* Partitions */
-#define CONFIG_MAC_PARTITION
-#define CONFIG_DOS_PARTITION
-#define CONFIG_ISO_PARTITION
-
 #ifdef DEBUG
 #define CONFIG_PANIC_HANG
 #else
@@ -219,9 +214,7 @@
 
 #define CONFIG_COMMANDS	       (CONFIG_CMD_DFL		|	\
 				CFG_CMD_ASKENV		|	\
-			        CFG_CMD_CACHE		|	\
 				CFG_CMD_DHCP		|	\
-				CFG_CMD_DIAG		|	\
 				CFG_CMD_ELF		|	\
 				CFG_CMD_EEPROM		|	\
 				CFG_CMD_I2C		|	\
@@ -232,7 +225,6 @@
 				CFG_CMD_PCI		|	\
 				CFG_CMD_PING		|	\
 				CFG_CMD_REGINFO		|	\
-				CFG_CMD_SETGETDCR	|	\
 				CFG_CMD_SDRAM		|	\
 				0)
 
diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h
index f60973b..621a81c 100644
--- a/include/configs/mcc200.h
+++ b/include/configs/mcc200.h
@@ -265,6 +265,7 @@
  */
 #if !defined(CONFIG_PRS200)
 #define CONFIG_LCD		1
+#define CONFIG_PROGRESSBAR 1
 #endif
 
 #if defined(CONFIG_LCD)
diff --git a/include/configs/mecp5200.h b/include/configs/mecp5200.h
index ccb0293..0c10294 100644
--- a/include/configs/mecp5200.h
+++ b/include/configs/mecp5200.h
@@ -88,10 +88,10 @@
 /* USB */
 #if 0
 #define CONFIG_USB_OHCI
-#define ADD_USB_CMD             CFG_CMD_USB | CFG_CMD_FAT
+#define ADD_USB_CMD		CFG_CMD_USB | CFG_CMD_FAT
 #define CONFIG_USB_STORAGE
 #else
-#define ADD_USB_CMD             0
+#define ADD_USB_CMD		0
 #endif
 
 /*
@@ -100,7 +100,7 @@
 #define CONFIG_COMMANDS		(CONFIG_CMD_DFL	| \
 				 CFG_CMD_EEPROM	| \
 				 CFG_CMD_FAT	| \
-                                 CFG_CMD_EXT2   | \
+				 CFG_CMD_EXT2	| \
 				 CFG_CMD_I2C	| \
 				 CFG_CMD_IDE	| \
 				 CFG_CMD_BSP	| \
@@ -110,11 +110,11 @@
 #include <cmd_confdefs.h>
 
 #if (TEXT_BASE == 0xFF000000)		/* Boot low with 16 MB Flash */
-#   define CFG_LOWBOOT	        1
+#   define CFG_LOWBOOT		1
 #   define CFG_LOWBOOT16	1
 #endif
 #if (TEXT_BASE == 0xFF800000)		/* Boot low with  8 MB Flash */
-#   define CFG_LOWBOOT	        1
+#   define CFG_LOWBOOT		1
 #   define CFG_LOWBOOT08	1
 #endif
 
@@ -131,20 +131,20 @@
 
 #define	CONFIG_EXTRA_ENV_SETTINGS \
 	"netdev=eth0\0" \
-        "flash_vxworks0=run ata_vxworks_args;setenv loadaddr ff000000;bootvx\0" \
-        "flash_vxworks1=run ata_vxworks_args;setenv loadaddr ff200000:bootvx\0" \
-        "net_vxworks=tftp $(loadaddr) $(image);run vxworks_args;bootvx\0" \
-        "vxworks_args=setenv bootargs fec(0,0)$(host):$(image) h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script)\0" \
-        "ata_vxworks_args=setenv bootargs /ata0/vxWorks h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script) o=fec0 \0" \
-        "loadaddr=01000000\0" \
-        "serverip=192.168.2.99\0" \
-        "gatewayip=10.0.0.79\0" \
-        "user=mu\0" \
-        "target=mecp5200.esd\0" \
-        "script=mecp5200.bat\0" \
-        "image=/tftpboot/vxWorks_mecp5200\0" \
-        "ipaddr=10.0.13.196\0" \
-        "netmask=255.255.0.0\0" \
+	"flash_vxworks0=run ata_vxworks_args;setenv loadaddr ff000000;bootvx\0" \
+	"flash_vxworks1=run ata_vxworks_args;setenv loadaddr ff200000:bootvx\0" \
+	"net_vxworks=tftp $(loadaddr) $(image);run vxworks_args;bootvx\0" \
+	"vxworks_args=setenv bootargs fec(0,0)$(host):$(image) h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script)\0" \
+	"ata_vxworks_args=setenv bootargs /ata0/vxWorks h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script) o=fec0 \0" \
+	"loadaddr=01000000\0" \
+	"serverip=192.168.2.99\0" \
+	"gatewayip=10.0.0.79\0" \
+	"user=mu\0" \
+	"target=mecp5200.esd\0" \
+	"script=mecp5200.bat\0" \
+	"image=/tftpboot/vxWorks_mecp5200\0" \
+	"ipaddr=10.0.13.196\0" \
+	"netmask=255.255.0.0\0" \
 	""
 
 #define CONFIG_BOOTCOMMAND	"run flash_vxworks0"
@@ -171,12 +171,12 @@
 #define CFG_I2C_EEPROM_ADDR_LEN		2
 #define CFG_EEPROM_PAGE_WRITE_BITS	5
 #define CFG_EEPROM_PAGE_WRITE_DELAY_MS	20
-#define CFG_I2C_MULTI_EEPROMS           1
+#define CFG_I2C_MULTI_EEPROMS		1
 /*
  * Flash configuration
  */
 #define CFG_FLASH_BASE		0xFFC00000
-#define CFG_FLASH_SIZE	        0x00400000
+#define CFG_FLASH_SIZE		0x00400000
 #define CFG_ENV_ADDR		(CFG_FLASH_BASE + 0x003E0000)
 #define CFG_MAX_FLASH_BANKS	1	/* max num of memory banks      */
 #define CFG_MAX_FLASH_SECT	512
@@ -200,15 +200,15 @@
 #define CONFIG_ENV_OVERWRITE	1
 #endif
 
-#define CFG_FLASH_CFI_DRIVER    1          /* Flash is CFI conformant           */
-#define CFG_FLASH_CFI           1          /* Flash is CFI conformant           */
-#define CFG_FLASH_PROTECTION    1          /* use hardware protection           */
+#define CFG_FLASH_CFI_DRIVER	1	   /* Flash is CFI conformant		*/
+#define CFG_FLASH_CFI		1	   /* Flash is CFI conformant		*/
+#define CFG_FLASH_PROTECTION	1	   /* use hardware protection		*/
 #if 0
 #define CFG_FLASH_USE_BUFFER_WRITE 1       /* use buffered writes (20x faster)  */
 #endif
-#define CFG_FLASH_INCREMENT     0x00400000 /* size of  flash bank               */
+#define CFG_FLASH_INCREMENT	0x00400000 /* size of  flash bank		*/
 #define CFG_FLASH_BANKS_LIST  { CFG_FLASH_BASE }
-#define CFG_FLASH_EMPTY_INFO    1          /* show if bank is empty             */
+#define CFG_FLASH_EMPTY_INFO	1	   /* show if bank is empty		*/
 
 
 /*
@@ -272,7 +272,7 @@
 
 #define CFG_LOAD_ADDR		0x100000	/* default load address */
 
-#define CFG_HZ			1000	        /* decrementer freq: 1 ms ticks */
+#define CFG_HZ			1000		/* decrementer freq: 1 ms ticks */
 
 #define CFG_VXWORKS_MAC_PTR	0x00000000	/* Pass Ethernet MAC to VxWorks */
 
@@ -339,7 +339,7 @@
 /* Offset for alternate registers	*/
 #define CFG_ATA_ALT_OFFSET	(0x005C)
 
-/* Interval between registers                                                */
-#define CFG_ATA_STRIDE          4
+/* Interval between registers		*/
+#define CFG_ATA_STRIDE		4
 
 #endif /* __CONFIG_H */
diff --git a/include/configs/motionpro.h b/include/configs/motionpro.h
new file mode 100644
index 0000000..5328e8d
--- /dev/null
+++ b/include/configs/motionpro.h
@@ -0,0 +1,305 @@
+/*
+ * (C) Copyright 2003-2007
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Based on PRO Motion board config file by Andy Joseph, andy@promessdev.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 __CONFIG_H
+#define __CONFIG_H
+
+
+/*
+ * High Level Configuration Options
+ */
+
+
+/* CPU and board */
+#define CONFIG_MPC5xxx		1	/* This is an MPC5xxx CPU */
+#define CONFIG_MPC5200		1	/* More exactly a MPC5200 */
+#define CONFIG_MOTIONPRO	1	/* ... on Promess Motion-PRO board */
+
+
+/*
+ * Supported commands
+ */
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL	| \
+				CFG_CMD_ASKENV	| \
+				CFG_CMD_DHCP	| \
+				CFG_CMD_REGINFO	| \
+				CFG_CMD_IMMAP	| \
+				CFG_CMD_ELF	| \
+				CFG_CMD_MII	| \
+				CFG_CMD_BEDBUG	| \
+				CFG_CMD_NET	| \
+				CFG_CMD_PING)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_PSC_CONSOLE	1	/* console is on PSC1 */
+#define CONFIG_NETCONSOLE	1	/* network console */
+#define CONFIG_BAUDRATE		115200
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_MPC5xxx_FEC	1
+#define CONFIG_PHY_ADDR		0x2
+#define CONFIG_PHY_TYPE		0x79c874
+
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY	2	/* autoboot after 2 seconds */
+#define CONFIG_AUTOBOOT_KEYED
+#define CONFIG_AUTOBOOT_STOP_STR	"\x1b\x1b"
+#define DEBUG_BOOTKEYS		0
+#undef CONFIG_AUTOBOOT_DELAY_STR
+#undef CONFIG_BOOTARGS
+#define CONFIG_AUTOBOOT_PROMPT	"Autobooting in %d seconds, "		\
+					"press \"<Esc><Esc>\" to stop\n"
+
+#define CONFIG_ETHADDR		00:50:C2:40:10:00
+#define CONFIG_OVERWRITE_ETHADDR_ONCE	1
+#define CONFIG_VERSION_VARIABLE	1	/* include version env variable */
+
+
+/*
+ * Default environment settings
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	"sdram_test=0\0"						\
+	"netdev=eth0\0"							\
+	"hostname=motionpro\0"						\
+	"netmask=255.255.0.0\0"						\
+	"ipaddr=192.168.160.22\0"					\
+	"serverip=192.168.1.1\0"					\
+	"gatewayip=192.168.1.1\0"					\
+	"kernel_addr=200000\0"						\
+	"u-boot_addr=100000\0"						\
+	"kernel_sector=20\0"						\
+	"kernel_size=1000\0"						\
+	"console=ttyS0,115200\0"					\
+	"rootpath=/opt/eldk-4.1/ppc_6xx\0"				\
+	"bootfile=/tftpboot/motionpro/uImage\0"				\
+	"u-boot=/tftpboot/motionpro/u-boot.bin\0"			\
+	"load=tftp $(u-boot_addr) $(u-boot)\0"				\
+	"update=prot off fff00000 fff3ffff; era fff00000 fff3ffff; "	\
+		"cp.b $(u-boot_addr) fff00000 $(filesize);"		\
+		"prot on fff00000 fff3ffff\0"				\
+	"ramargs=setenv bootargs root=/dev/ram rw\0"			\
+	"addip=setenv bootargs $(bootargs) console=$(console) "		\
+		"ip=$(ipaddr):$(serverip):$(gatewayip):"		\
+		"$(netmask):$(hostname):$(netdev):off panic=1\0"	\
+	"flash_nfs=run nfsargs addip;bootm $(kernel_addr)\0"		\
+	"flash_self=run ramargs addip;bootm $(kernel_addr) "		\
+		"$(ramdisk_addr)\0"					\
+	"net_nfs=tftp $(kernel_addr) $(bootfile); run nfsargs addip; "	\
+		"bootm $(kernel_addr)\0"				\
+	"nfsargs=setenv bootargs root=/dev/nfs rw "			\
+		"nfsroot=$(serverip):$(rootpath)\0"			\
+	"fstype=ext3\0"							\
+	"fatargs=setenv bootargs init=/linuxrc rw\0"			\
+	""
+#define CONFIG_BOOTCOMMAND	"run net_nfs"
+
+
+/*
+ * do board-specific init
+ */
+#define CONFIG_BOARD_EARLY_INIT_R	1
+
+
+/*
+ * Low level configuration
+ */
+
+
+/*
+ * Clock configuration: SYS_XTALIN = 25MHz
+ */
+#define CFG_MPC5XXX_CLKIN	25000000
+
+
+/*
+ * Memory map
+ */
+/*
+ * Warning!!! with the current BestComm Task, MBAR MUST BE set to 0xf0000000.
+ * Setting MBAR to otherwise will cause system hang when using SmartDMA such
+ * as network commands.
+ */
+#define CFG_MBAR		0xf0000000
+#define CFG_SDRAM_BASE		0x00000000
+
+/*
+ * If building for running out of SDRAM, then MBAR has been set up beforehand
+ * (e.g., by the BDI). Otherwise we must specify the default boot-up value of
+ * MBAR, as given in the doccumentation.
+ */
+#if TEXT_BASE == 0x00100000
+#define CFG_DEFAULT_MBAR	0xf0000000
+#else /* TEXT_BASE != 0x00100000 */
+#define CFG_DEFAULT_MBAR	0x80000000
+#define CFG_LOWBOOT		1
+#endif /* TEXT_BASE == 0x00100000 */
+
+/* Use SRAM until RAM will be available */
+#define CFG_INIT_RAM_ADDR	MPC5XXX_SRAM
+#define CFG_INIT_RAM_END	MPC5XXX_SRAM_SIZE
+
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes 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
+
+#define CFG_MONITOR_BASE	TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#define CFG_RAMBOOT		1
+#endif
+
+#define CFG_MONITOR_LEN		(256 << 10)	/* 256 kB for Monitor */
+#define CFG_MALLOC_LEN		(128 << 10)	/* 128 kB for malloc() */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* initial mem map for Linux */
+
+
+/*
+ * Chip selects configuration
+ */
+/* Boot Chipselect */
+#define CFG_BOOTCS_START	CFG_FLASH_BASE
+#define CFG_BOOTCS_SIZE		CFG_FLASH_SIZE
+#define CFG_BOOTCS_CFG		0x03035D00
+
+/* Flash memory addressing */
+#define CFG_CS0_START		CFG_FLASH_BASE
+#define CFG_CS0_SIZE		CFG_FLASH_SIZE
+#define CFG_CS0_CFG		CFG_BOOTCS_CFG
+
+/* Dual Port SRAM -- Kollmorgen Drive memory addressing */
+#define CFG_CS1_START		0x50000000
+#define CFG_CS1_SIZE		0x10000
+#define CFG_CS1_CFG		0x05055800
+
+/* Local register access */
+#define CFG_CS2_START		0x50010000
+#define CFG_CS2_SIZE		0x10000
+#define CFG_CS2_CFG		0x05055800
+
+/* Anybus CompactCom Module memory addressing */
+#define CFG_CS3_START		0x50020000
+#define CFG_CS3_SIZE		0x10000
+#define CFG_CS3_CFG		0x05055800
+
+/* No burst and dead cycle = 2 for all CSs */
+#define CFG_CS_BURST		0x00000000
+#define CFG_CS_DEADCYCLE	0x22222222
+
+
+/*
+ * SDRAM configuration
+ */
+/* 2 x MT48LC16M16A2BG-75 IT:D, CASL 2, 32 bit data bus */
+#define SDRAM_CONFIG1		0x52222600
+#define SDRAM_CONFIG2		0x88b70000
+#define SDRAM_CONTROL		0x50570000
+#define SDRAM_MODE		0x008d0000
+
+
+/*
+ * Flash configuration
+ */
+#define CFG_FLASH_CFI		1	/* Flash is CFI conformant */
+#define CFG_FLASH_CFI_DRIVER	1
+#define CFG_FLASH_BASE		0xff000000
+#define CFG_FLASH_SIZE		0x01000000
+#define CFG_MAX_FLASH_BANKS	1	/* max num of memory banks */
+#define CFG_FLASH_BANKS_LIST	{ CFG_FLASH_BASE }
+#define CFG_MAX_FLASH_SECT	256	/* max num of sects on one chip */
+#define CONFIG_FLASH_16BIT		/* Flash is 16-bit */
+
+
+/*
+ * Environment settings
+ */
+#define CFG_ENV_IS_IN_FLASH	1
+/* This has to be a multiple of the Flash sector size */
+#define CFG_ENV_ADDR		(CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#define CFG_ENV_SIZE		0x1000
+#define CFG_ENV_SECT_SIZE	0x10000
+
+
+/*
+ * Pin multiplexing configuration
+ */
+
+/* PSC1: UART1
+ * PSC2: GPIO (default)
+ * PSC3: GPIO (default)
+ * USB: 2xUART4/5
+ * Ethernet: Ethernet 100Mbit with MD
+ * Timer: CAN2/GPIO
+ * PSC6/IRDA: GPIO (default)
+ */
+#define CFG_GPS_PORT_CONFIG	0x1105a004
+
+
+/*
+ * 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  */
+#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		0x03f00000	/* 1 ... 64 MiB in DRAM */
+
+#define CFG_LOAD_ADDR		0x200000	/* default kernel load addr */
+
+#define CFG_HZ			1000	/* decrementer freq: 1 ms ticks */
+
+
+/*
+ * Various low-level settings
+ */
+#define CFG_HID0_INIT		HID0_ICE | HID0_ICFI
+#define CFG_HID0_FINAL		HID0_ICE
+
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH  */
+#define BOOTFLAG_WARM		0x02	/* Software reboot */
+
+#define CFG_CACHELINE_SIZE	32	/* For MPC5xxx CPUs */
+
+
+/* Not needed for MPC 5xxx U-Boot, but used by tools/updater */
+#define CFG_RESET_ADDRESS	0xfff00100
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/ocotea.h b/include/configs/ocotea.h
index 0e3660b..fe4e638 100644
--- a/include/configs/ocotea.h
+++ b/include/configs/ocotea.h
@@ -148,8 +148,9 @@
 /*-----------------------------------------------------------------------
  * DDR SDRAM
  *----------------------------------------------------------------------*/
-#define CONFIG_SPD_EEPROM	1	 /* Use SPD EEPROM for setup	 */
+#define CONFIG_SPD_EEPROM	1	/* Use SPD EEPROM for setup	*/
 #define SPD_EEPROM_ADDRESS {0x53,0x52}	/* SPD i2c spd addresses	*/
+#define CONFIG_PROG_SDRAM_TLB	1	/* setup SDRAM TLB's dynamically*/
 
 /*-----------------------------------------------------------------------
  * I2C
diff --git a/include/configs/sc3.h b/include/configs/sc3.h
index b767449..f2f0598 100644
--- a/include/configs/sc3.h
+++ b/include/configs/sc3.h
@@ -115,7 +115,7 @@
 		":${hostname}:${netdev}:off panic=1\0"			\
 	"flash_nfs=run nfsargs addip;"					\
 		"bootm ${kernel_addr}\0"				\
-	"flash_nand=nand_args addip addcon;bootm ${kernel_addr}\0"	\
+	"flash_nand=run nand_args addip addcon;bootm ${kernel_addr}\0"	\
 	"net_nfs=tftp 200000 ${bootfile};run nfsargs addip;bootm\0"	\
 	"rootpath=/opt/eldk/ppc_4xx\0"					\
 	"bootfile=/tftpboot/sc3/uImage\0"				\
diff --git a/include/configs/sequoia.h b/include/configs/sequoia.h
index 098aa3f..29f3b40 100644
--- a/include/configs/sequoia.h
+++ b/include/configs/sequoia.h
@@ -391,7 +391,7 @@
 #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
 #define CFG_NAND_CS		3		/* NAND chip connected to CSx	*/
 /* Memory Bank 0 (NOR-FLASH) initialization					*/
-#define CFG_EBC_PB0AP		0x03017300
+#define CFG_EBC_PB0AP		0x03017200
 #define CFG_EBC_PB0CR		(CFG_FLASH | 0xda000)
 
 /* Memory Bank 3 (NAND-FLASH) initialization					*/
@@ -400,7 +400,7 @@
 #else
 #define CFG_NAND_CS		0		/* NAND chip connected to CSx	*/
 /* Memory Bank 3 (NOR-FLASH) initialization					*/
-#define CFG_EBC_PB3AP		0x03017300
+#define CFG_EBC_PB3AP		0x03017200
 #define CFG_EBC_PB3CR		(CFG_FLASH | 0xda000)
 
 /* Memory Bank 0 (NAND-FLASH) initialization					*/
diff --git a/include/configs/yucca.h b/include/configs/yucca.h
index 6417ed8..eb4859c 100644
--- a/include/configs/yucca.h
+++ b/include/configs/yucca.h
@@ -45,11 +45,11 @@
 #define EXTCLK_50		50000000
 #define EXTCLK_83		83333333
 
-#define	CONFIG_IBM_EMAC4_V4		1
-#define	CONFIG_MISC_INIT_F		1	/* Use misc_init_f()	*/
+#define	CONFIG_MISC_INIT_F	1	/* Use misc_init_f()		*/
+#define CONFIG_ADD_RAM_INFO	1	/* Print additional info	*/
 #undef  CONFIG_SHOW_BOOT_PROGRESS
 #undef  CONFIG_STRESS
-#undef  ENABLE_ECC
+
 /*-----------------------------------------------------------------------
  * Base addresses -- Note these are effective addresses where the
  * actual resources get mapped (not physical addresses)
@@ -118,10 +118,9 @@
 /*-----------------------------------------------------------------------
  * DDR SDRAM
  *----------------------------------------------------------------------*/
-#undef CONFIG_SPD_EEPROM		/* Use SPD EEPROM for setup	*/
-#define SPD_EEPROM_ADDRESS {0x53, 0x52}	/* SPD i2c spd addresses	*/
-#define IIC0_DIMM0_ADDR		0x53
-#define IIC0_DIMM1_ADDR		0x52
+#define CONFIG_SPD_EEPROM	1	/* Use SPD EEPROM for setup	*/
+#define SPD_EEPROM_ADDRESS	{0x53, 0x52}	/* SPD i2c spd addresses*/
+#undef CONFIG_DDR_ECC			/* no ECC support for now	*/
 
 /*-----------------------------------------------------------------------
  * I2C
@@ -211,6 +210,7 @@
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
 
+#define	CONFIG_IBM_EMAC4_V4	1
 #define CONFIG_MII		1	/* MII PHY management		*/
 #undef CONFIG_NET_MULTI
 #define CONFIG_PHY_ADDR		1	/* PHY address, See schematics	*/
diff --git a/include/i2c.h b/include/i2c.h
index a8f729a..d31c72d 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -46,6 +46,24 @@
  */
 #define I2C_RXTX_LEN	128	/* maximum tx/rx buffer length */
 
+#if defined(CONFIG_I2C_MULTI_BUS)
+#define CFG_MAX_I2C_BUS		2
+#define I2C_GET_BUS()		i2c_get_bus_num()
+#define I2C_SET_BUS(a)		i2c_set_bus_num(a)
+#else
+#define CFG_MAX_I2C_BUS		1
+#define I2C_GET_BUS()		0
+#define I2C_SET_BUS(a)
+#endif
+
+/* define the I2C bus number for RTC and DTT if not already done */
+#if !defined(CFG_RTC_BUS_NUM)
+#define CFG_RTC_BUS_NUM		0
+#endif
+#if !defined(CFG_DTT_BUS_NUM)
+#define CFG_DTT_BUS_NUM		0
+#endif
+
 /*
  * Initialization, must be called once on start up, may be called
  * repeatedly to change the speed and slave addresses.
diff --git a/include/ide.h b/include/ide.h
index dfef32f..6976a6c 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -48,8 +48,8 @@
  * Function Prototypes
  */
 
-void  ide_init  (void);
-ulong ide_read	(int device, lbaint_t blknr, ulong blkcnt, ulong *buffer);
-ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer);
+void ide_init(void);
+ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer);
+ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, void *buffer);
 
 #endif /* _IDE_H */
diff --git a/include/part.h b/include/part.h
index 318aa3c..29c0320 100644
--- a/include/part.h
+++ b/include/part.h
@@ -22,6 +22,7 @@
  */
 #ifndef _PART_H
 #define _PART_H
+
 #include <ide.h>
 
 typedef struct block_dev_desc {
@@ -43,7 +44,11 @@
 	unsigned long	(*block_read)(int dev,
 				      unsigned long start,
 				      lbaint_t blkcnt,
-				      unsigned long *buffer);
+				      void *buffer);
+	unsigned long	(*block_write)(int dev,
+				       unsigned long start,
+				       lbaint_t blkcnt,
+				       const void *buffer);
 }block_dev_desc_t;
 
 /* Interface types: */
@@ -83,6 +88,14 @@
 	uchar	type[32];	/* string type description		*/
 } disk_partition_t;
 
+/* Misc _get_dev functions */
+block_dev_desc_t* get_dev(char* ifname, int dev);
+block_dev_desc_t* ide_get_dev(int dev);
+block_dev_desc_t* scsi_get_dev(int dev);
+block_dev_desc_t* usb_stor_get_dev(int dev);
+block_dev_desc_t* mmc_get_dev(int dev);
+block_dev_desc_t* systemace_get_dev(int dev);
+
 /* disk/part.c */
 int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 void print_part (block_dev_desc_t *dev_desc);
diff --git a/include/ppc405.h b/include/ppc405.h
index e475fa5..a49912c 100644
--- a/include/ppc405.h
+++ b/include/ppc405.h
@@ -240,6 +240,7 @@
   #define pbesr0      0x21    /* periph bus error status reg 0       */
   #define pbesr1      0x22    /* periph bus error status reg 1       */
   #define epcr        0x23    /* external periph control reg         */
+#define EBC0_CFG	0x23	/* external bus configuration reg	*/
 
 #ifdef CONFIG_405EP
 /******************************************************************************
diff --git a/include/ppc440.h b/include/ppc440.h
index 91cff41..9b15c2c 100644
--- a/include/ppc440.h
+++ b/include/ppc440.h
@@ -417,7 +417,9 @@
 #define SDR0_PEGPLLSET1		0x000003A0	/* PE Pll LC Tank Setting1 */
 #define SDR0_PEGPLLSET2		0x000003A1	/* PE Pll LC Tank Setting2 */
 #define SDR0_PEGPLLSTS		0x000003A2	/* PE Pll LC Tank Status */
+#endif /* CONFIG_440SPE */
 
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 /*----------------------------------------------------------------------------+
 | SDRAM Controller
 +----------------------------------------------------------------------------*/
@@ -453,9 +455,16 @@
 /*-----------------------------------------------------------------------------+
 |  Memory Bank 0-7 configuration
 +-----------------------------------------------------------------------------*/
-#define SDRAM_RXBAS_SDBA_MASK		0xFF800000	/* Base address	*/
+#if defined(CONFIG_440SPE)
+#define SDRAM_RXBAS_SDBA_MASK		0xFFE00000	/* Base address	*/
 #define SDRAM_RXBAS_SDBA_ENCODE(n)	((((unsigned long)(n))&0xFFE00000)>>2)
 #define SDRAM_RXBAS_SDBA_DECODE(n)	((((unsigned long)(n))&0xFFE00000)<<2)
+#endif /* CONFIG_440SPE */
+#if defined(CONFIG_440SP)
+#define SDRAM_RXBAS_SDBA_MASK		0xFF800000	/* Base address	*/
+#define SDRAM_RXBAS_SDBA_ENCODE(n)	((((unsigned long)(n))&0xFF800000))
+#define SDRAM_RXBAS_SDBA_DECODE(n)	((((unsigned long)(n))&0xFF800000))
+#endif /* CONFIG_440SP */
 #define SDRAM_RXBAS_SDSZ_MASK		0x0000FFC0	/* Size		*/
 #define SDRAM_RXBAS_SDSZ_ENCODE(n)	((((unsigned long)(n))&0x3FF)<<6)
 #define SDRAM_RXBAS_SDSZ_DECODE(n)	((((unsigned long)(n))>>6)&0x3FF)
@@ -533,9 +542,12 @@
 #define SDRAM_MCSTAT_MIC_MASK		0x80000000	/* Memory init status mask	*/
 #define SDRAM_MCSTAT_MIC_NOTCOMP	0x00000000	/* Mem init not complete	*/
 #define SDRAM_MCSTAT_MIC_COMP		0x80000000	/* Mem init complete		*/
-#define SDRAM_MCSTAT_SRMS_MASK		0x80000000	/* Mem self refresh stat mask	*/
+#define SDRAM_MCSTAT_SRMS_MASK		0x40000000	/* Mem self refresh stat mask	*/
 #define SDRAM_MCSTAT_SRMS_NOT_SF	0x00000000	/* Mem not in self refresh	*/
-#define SDRAM_MCSTAT_SRMS_SF		0x80000000	/* Mem in self refresh		*/
+#define SDRAM_MCSTAT_SRMS_SF		0x40000000	/* Mem in self refresh		*/
+#define SDRAM_MCSTAT_IDLE_MASK		0x20000000	/* Mem self refresh stat mask	*/
+#define SDRAM_MCSTAT_IDLE_NOT		0x00000000	/* Mem contr not idle		*/
+#define SDRAM_MCSTAT_IDLE		0x20000000	/* Mem contr idle		*/
 
 /*-----------------------------------------------------------------------------+
 |  Memory Controller Options 1
@@ -730,6 +742,7 @@
 #define SDRAM_WRDTR_LLWP_1_CYC		0x00000000
 #define SDRAM_WRDTR_WTR_MASK		0x0E000000
 #define SDRAM_WRDTR_WTR_0_DEG		0x06000000
+#define SDRAM_WRDTR_WTR_90_DEG_ADV	0x04000000
 #define SDRAM_WRDTR_WTR_180_DEG_ADV	0x02000000
 #define SDRAM_WRDTR_WTR_270_DEG_ADV	0x00000000
 
@@ -847,6 +860,7 @@
 #define pbear		0x20	/* periph bus error addr reg		*/
 #define pbesr		0x21	/* periph bus error status reg		*/
 #define xbcfg		0x23	/* external bus configuration reg	*/
+#define EBC0_CFG	0x23	/* external bus configuration reg	*/
 #define xbcid		0x24	/* external bus core id reg		*/
 
 #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
@@ -2162,6 +2176,20 @@
 /*-----------------------------------------------------------------------------+
 |  SDR0 Bit Settings
 +-----------------------------------------------------------------------------*/
+#if defined(CONFIG_440SP)
+#define SDR0_SRST			0x0200
+
+#define SDR0_DDR0			0x00E1
+#define SDR0_DDR0_DPLLRST		0x80000000
+#define SDR0_DDR0_DDRM_MASK		0x60000000
+#define SDR0_DDR0_DDRM_DDR1		0x20000000
+#define SDR0_DDR0_DDRM_DDR2		0x40000000
+#define SDR0_DDR0_DDRM_ENCODE(n)	((((unsigned long)(n))&0x03)<<29)
+#define SDR0_DDR0_DDRM_DECODE(n)	((((unsigned long)(n))>>29)&0x03)
+#define SDR0_DDR0_TUNE_ENCODE(n)	((((unsigned long)(n))&0x2FF)<<0)
+#define SDR0_DDR0_TUNE_DECODE(n)	((((unsigned long)(n))>>0)&0x2FF)
+#endif
+
 #if defined(CONFIG_440SPE)
 #define SDR0_CP440			0x0180
 #define SDR0_CP440_ERPN_MASK		0x30000000
@@ -3185,7 +3213,8 @@
 #define GPIO0			0
 #define GPIO1			1
 
-#if defined(CONFIG_440GP) || defined(CONFIG_440GX)
+#if defined(CONFIG_440GP) || defined(CONFIG_440GX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 #define GPIO0_BASE             (CFG_PERIPHERAL_BASE+0x00000700)
 
 #define GPIO0_OR               (GPIO0_BASE+0x0)
@@ -3270,6 +3299,8 @@
 #define GPIO_IN_SEL	    0x40000000	    /* GPIO_IN value put in GPIO_ISx for the GPIO nb 0 */
 					    /* For the other GPIO number, you must shift */
 
+#define GPIO_VAL(gpio)		(0x80000000 >> (gpio))
+
 #ifndef __ASSEMBLY__
 
 typedef enum gpio_select { GPIO_SEL, GPIO_ALT1, GPIO_ALT2, GPIO_ALT3 } gpio_select_t;
@@ -3280,32 +3311,31 @@
 	gpio_select_t  alt_nb; /* Selected Alternate */
 } gpio_param_s;
 
-
 #endif /* __ASSEMBLY__ */
 
 /*
  * Macros for accessing the indirect EBC registers
  */
-#define mtebc(reg, data)	{ mtdcr(ebccfga,reg);mtdcr(ebccfgd,data); }
-#define mfebc(reg, data)	{ mtdcr(ebccfga,reg);data = mfdcr(ebccfgd); }
+#define mtebc(reg, data)	do { mtdcr(ebccfga,reg);mtdcr(ebccfgd,data); } while (0)
+#define mfebc(reg, data)	do { mtdcr(ebccfga,reg);data = mfdcr(ebccfgd); } while (0)
 
 /*
  * Macros for accessing the indirect SDRAM controller registers
  */
-#define mtsdram(reg, data)	{ mtdcr(memcfga,reg);mtdcr(memcfgd,data); }
-#define mfsdram(reg, data)	{ mtdcr(memcfga,reg);data = mfdcr(memcfgd); }
+#define mtsdram(reg, data)	do { mtdcr(memcfga,reg);mtdcr(memcfgd,data); } while (0)
+#define mfsdram(reg, data)	do { mtdcr(memcfga,reg);data = mfdcr(memcfgd); } while (0)
 
 /*
  * Macros for accessing the indirect clocking controller registers
  */
-#define mtclk(reg, data)	{ mtdcr(clkcfga,reg);mtdcr(clkcfgd,data); }
-#define mfclk(reg, data)	{ mtdcr(clkcfga,reg);data = mfdcr(clkcfgd); }
+#define mtclk(reg, data)	do { mtdcr(clkcfga,reg);mtdcr(clkcfgd,data); } while (0)
+#define mfclk(reg, data)	do { mtdcr(clkcfga,reg);data = mfdcr(clkcfgd); } while (0)
 
 /*
  * Macros for accessing the sdr controller registers
  */
-#define mtsdr(reg, data)	{ mtdcr(sdrcfga,reg);mtdcr(sdrcfgd,data); }
-#define mfsdr(reg, data)	{ mtdcr(sdrcfga,reg);data = mfdcr(sdrcfgd); }
+#define mtsdr(reg, data)	do { mtdcr(sdrcfga,reg);mtdcr(sdrcfgd,data); } while (0)
+#define mfsdr(reg, data)	do { mtdcr(sdrcfga,reg);data = mfdcr(sdrcfgd); } while (0)
 
 
 #ifndef __ASSEMBLY__
diff --git a/lib_generic/display_options.c b/lib_generic/display_options.c
index 512e898..5ddd94f 100644
--- a/lib_generic/display_options.c
+++ b/lib_generic/display_options.c
@@ -21,7 +21,10 @@
  * MA 02111-1307 USA
  */
 
+#include <config.h>
 #include <common.h>
+#include <linux/ctype.h>
+#include <asm/io.h>
 
 int display_options (void)
 {
@@ -65,3 +68,70 @@
 	}
 	printf (" %cB%s", c, s);
 }
+
+/*
+ * Print data buffer in hex and ascii form to the terminal.
+ *
+ * data reads are buffered so that each memory address is only read once.
+ * Useful when displaying the contents of volatile registers.
+ *
+ * parameters:
+ *    addr: Starting address to display at start of line
+ *    data: pointer to data buffer
+ *    width: data value width.  May be 1, 2, or 4.
+ *    count: number of values to display
+ *    linelen: Number of values to print per line; specify 0 for default length
+ */
+#define MAX_LINE_LENGTH_BYTES (64)
+#define DEFAULT_LINE_LENGTH_BYTES (16)
+int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen)
+{
+	uint8_t linebuf[MAX_LINE_LENGTH_BYTES];
+	uint32_t *uip = (void*)linebuf;
+	uint16_t *usp = (void*)linebuf;
+	uint8_t *ucp = (void*)linebuf;
+	int i;
+
+	if (linelen*width > MAX_LINE_LENGTH_BYTES)
+		linelen = MAX_LINE_LENGTH_BYTES / width;
+	if (linelen < 1)
+		linelen = DEFAULT_LINE_LENGTH_BYTES / width;
+
+	while (count) {
+		printf("%08lx:", addr);
+
+		/* check for overflow condition */
+		if (count < linelen)
+			linelen = count;
+
+		/* Copy from memory into linebuf and print hex values */
+		for (i = 0; i < linelen; i++) {
+			if (width == 4) {
+				uip[i] = *(volatile uint32_t *)data;
+				printf(" %08x", uip[i]);
+			} else if (width == 2) {
+				usp[i] = *(volatile uint16_t *)data;
+				printf(" %04x", usp[i]);
+			} else {
+				ucp[i] = *(volatile uint8_t *)data;
+				printf(" %02x", ucp[i]);
+			}
+			data += width;
+		}
+
+		/* Print data in ASCII characters */
+		puts("    ");
+		for (i = 0; i < linelen * width; i++)
+			putc(isprint(ucp[i]) && (ucp[i] < 0x80) ? ucp[i] : '.');
+		putc ('\n');
+
+		/* update references */
+		addr += linelen * width;
+		count -= linelen;
+
+		if (ctrlc())
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/nand_spl/board/amcc/sequoia/Makefile b/nand_spl/board/amcc/sequoia/Makefile
index b42da8c..510999d 100644
--- a/nand_spl/board/amcc/sequoia/Makefile
+++ b/nand_spl/board/amcc/sequoia/Makefile
@@ -30,7 +30,7 @@
 CFLAGS	+= -DCONFIG_NAND_SPL
 
 SOBJS	= start.o init.o resetvec.o
-COBJS	= nand_boot.o ndfc.o sdram.o
+COBJS	= nand_boot.o ndfc.o sdram.o speed.o
 
 SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
@@ -69,6 +69,10 @@
 	@rm -f $(obj)start.S
 	ln -s $(SRCTREE)/cpu/ppc4xx/start.S $(obj)start.S
 
+$(obj)speed.c:
+	@rm -f $(obj)speed.c
+	ln -s $(SRCTREE)/cpu/ppc4xx/speed.c $(obj)speed.c
+
 # from board directory
 $(obj)init.S:
 	@rm -f $(obj)init.S
diff --git a/post/Makefile b/post/Makefile
index 228bafc..f32af95 100644
--- a/post/Makefile
+++ b/post/Makefile
@@ -22,14 +22,10 @@
 #
 
 
-SUBDIRS = cpu
+SUBDIRS = drivers cpu lib_$(ARCH) board/$(BOARDDIR)
 
 LIB	= libpost.a
 
-AOBJS	= cache_8xx.o
-COBJS	= cache.o codec.o cpu.o dsp.o ether.o
-COBJS  += i2c.o memory.o post.o rtc.o
-COBJS  += spr.o sysmon.o tests.o uart.o
-COBJS  += usb.o watchdog.o
+COBJS	= post.o tests.o
 
 include $(TOPDIR)/post/rules.mk
diff --git a/post/board/lwmon/Makefile b/post/board/lwmon/Makefile
new file mode 100644
index 0000000..899b0dc
--- /dev/null
+++ b/post/board/lwmon/Makefile
@@ -0,0 +1,29 @@
+#
+# (C) Copyright 2002-2006
+# 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
+#
+
+
+LIB	= libpostlwmon.a
+
+COBJS	= sysmon.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/post/board/lwmon/sysmon.c b/post/board/lwmon/sysmon.c
new file mode 100644
index 0000000..f61d598
--- /dev/null
+++ b/post/board/lwmon/sysmon.c
@@ -0,0 +1,331 @@
+/*
+ * (C) Copyright 2003
+ * 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 <post.h>
+#include <common.h>
+
+#ifdef CONFIG_POST
+
+/*
+ * SYSMON test
+ *
+ * This test performs the system hardware monitoring.
+ * The test passes when all the following voltages and temperatures
+ * are within allowed ranges:
+ *
+ * Board temperature
+ * Front temperature
+ * +3.3V CPU logic
+ * +5V logic
+ * +12V PCMCIA
+ * +12V CCFL
+ * +5V standby
+ *
+ * CCFL is not enabled if temperature values are not within allowed ranges
+ *
+ * See the list off all parameters in the sysmon_table below
+ */
+
+#include <post.h>
+#include <watchdog.h>
+#include <i2c.h>
+
+#if CONFIG_POST & CFG_POST_SYSMON
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sysmon_temp_invalid = 0;
+
+/* #define DEBUG */
+
+#define	RELOC(x) if (x != NULL) x = (void *) ((ulong) (x) + gd->reloc_off)
+
+typedef struct sysmon_s sysmon_t;
+typedef struct sysmon_table_s sysmon_table_t;
+
+static void sysmon_lm87_init (sysmon_t * this);
+static void sysmon_pic_init (sysmon_t * this);
+static uint sysmon_i2c_read (sysmon_t * this, uint addr);
+static uint sysmon_i2c_read_sgn (sysmon_t * this, uint addr);
+static void sysmon_ccfl_disable (sysmon_table_t * this);
+static void sysmon_ccfl_enable (sysmon_table_t * this);
+
+struct sysmon_s
+{
+	uchar	chip;
+	void	(*init)(sysmon_t *);
+	uint	(*read)(sysmon_t *, uint);
+};
+
+static sysmon_t sysmon_lm87 =
+	{CFG_I2C_SYSMON_ADDR, sysmon_lm87_init, sysmon_i2c_read};
+static sysmon_t sysmon_lm87_sgn =
+	{CFG_I2C_SYSMON_ADDR, sysmon_lm87_init, sysmon_i2c_read_sgn};
+static sysmon_t sysmon_pic =
+	{CFG_I2C_PICIO_ADDR, sysmon_pic_init, sysmon_i2c_read};
+
+static sysmon_t * sysmon_list[] =
+{
+	&sysmon_lm87,
+	&sysmon_lm87_sgn,
+	&sysmon_pic,
+	NULL
+};
+
+struct sysmon_table_s
+{
+	char *		name;
+	char *		unit_name;
+	sysmon_t *	sysmon;
+	void		(*exec_before)(sysmon_table_t *);
+	void		(*exec_after)(sysmon_table_t *);
+
+	int		unit_precision;
+	int		unit_div;
+	int		unit_min;
+	int		unit_max;
+	uint		val_mask;
+	uint		val_min;
+	uint		val_max;
+	int		val_valid;
+	uint		val_min_alt;
+	uint		val_max_alt;
+	int		val_valid_alt;
+	uint		addr;
+};
+
+static sysmon_table_t sysmon_table[] =
+{
+    {"Board temperature", " C", &sysmon_lm87_sgn, NULL, sysmon_ccfl_disable,
+     1, 1, -128, 127, 0xFF, 0x58, 0xD5, 0, 0x6C, 0xC6, 0, 0x27},
+
+    {"Front temperature", " C", &sysmon_lm87, NULL, sysmon_ccfl_disable,
+     1, 100, -27316, 8984, 0xFF, 0xA4, 0xFC, 0, 0xB2, 0xF1, 0, 0x29},
+
+    {"+3.3V CPU logic", "V", &sysmon_lm87, NULL, NULL,
+     100, 1000, 0, 4386, 0xFF, 0xB6, 0xC9, 0, 0xB6, 0xC9, 0, 0x22},
+
+    {"+ 5 V logic", "V", &sysmon_lm87, NULL, NULL,
+     100, 1000, 0, 6630, 0xFF, 0xB6, 0xCA, 0, 0xB6, 0xCA, 0, 0x23},
+
+    {"+12 V PCMCIA", "V", &sysmon_lm87, NULL, NULL,
+     100, 1000, 0, 15460, 0xFF, 0xBC, 0xD0, 0, 0xBC, 0xD0, 0, 0x21},
+
+    {"+12 V CCFL", "V", &sysmon_lm87, NULL, sysmon_ccfl_enable,
+     100, 1000, 0, 15900, 0xFF, 0xB6, 0xCA, 0, 0xB6, 0xCA, 0, 0x24},
+
+    {"+ 5 V standby", "V", &sysmon_pic, NULL, NULL,
+     100, 1000, 0, 6040, 0xFF, 0xC8, 0xDE, 0, 0xC8, 0xDE, 0, 0x7C},
+};
+static int sysmon_table_size = sizeof(sysmon_table) / sizeof(sysmon_table[0]);
+
+static int conversion_done = 0;
+
+
+int sysmon_init_f (void)
+{
+	sysmon_t ** l;
+	ulong reg;
+
+	/* Power on CCFL, PCMCIA */
+	reg = pic_read  (0x60);
+	reg |= 0x09;
+	pic_write (0x60, reg);
+
+	for (l = sysmon_list; *l; l++) {
+		(*l)->init(*l);
+	}
+
+	return 0;
+}
+
+void sysmon_reloc (void)
+{
+	sysmon_t ** l;
+	sysmon_table_t * t;
+
+	for (l = sysmon_list; *l; l++) {
+		RELOC(*l);
+		RELOC((*l)->init);
+		RELOC((*l)->read);
+	}
+
+	for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++) {
+		RELOC(t->exec_before);
+		RELOC(t->exec_after);
+		RELOC(t->sysmon);
+	}
+}
+
+static char *sysmon_unit_value (sysmon_table_t *s, uint val)
+{
+	static char buf[32];
+	int unit_val =
+	    s->unit_min + (s->unit_max - s->unit_min) * val / s->val_mask;
+	char *p, sign;
+	int dec, frac;
+
+	if (val == -1) {
+		return "I/O ERROR";
+	}
+
+	if (unit_val < 0) {
+		sign = '-';
+		unit_val = -unit_val;
+	} else {
+		sign = '+';
+	}
+
+	p = buf + sprintf(buf, "%c%2d", sign, unit_val / s->unit_div);
+
+
+	frac = unit_val % s->unit_div;
+
+	frac /= (s->unit_div / s->unit_precision);
+
+	dec = s->unit_precision;
+
+	if (dec != 1) {
+		*p++ = '.';
+	}
+	for (dec /= 10; dec != 0; dec /= 10) {
+		*p++ = '0' + (frac / dec) % 10;
+	}
+	strcpy(p, s->unit_name);
+
+	return buf;
+}
+
+static void sysmon_lm87_init (sysmon_t * this)
+{
+	uchar val;
+
+	/* Detect LM87 chip */
+	if (i2c_read(this->chip, 0x40, 1, &val, 1) || (val & 0x80) != 0 ||
+	    i2c_read(this->chip, 0x3E, 1, &val, 1) || val != 0x02) {
+		printf("Error: LM87 not found at 0x%02X\n", this->chip);
+		return;
+	}
+
+	/* Configure pins 5,6 as AIN */
+	val = 0x03;
+	if (i2c_write(this->chip, 0x16, 1, &val, 1)) {
+		printf("Error: can't write LM87 config register\n");
+		return;
+	}
+
+	/* Start monitoring */
+	val = 0x01;
+	if (i2c_write(this->chip, 0x40, 1, &val, 1)) {
+		printf("Error: can't write LM87 config register\n");
+		return;
+	}
+}
+
+static void sysmon_pic_init (sysmon_t * this)
+{
+}
+
+static uint sysmon_i2c_read (sysmon_t * this, uint addr)
+{
+	uchar val;
+	uint res = i2c_read(this->chip, addr, 1, &val, 1);
+
+	return res == 0 ? val : -1;
+}
+
+static uint sysmon_i2c_read_sgn (sysmon_t * this, uint addr)
+{
+	uchar val;
+	return i2c_read(this->chip, addr, 1, &val, 1) == 0 ?
+		128 + (signed char)val : -1;
+}
+
+static void sysmon_ccfl_disable (sysmon_table_t * this)
+{
+	if (!this->val_valid_alt) {
+		sysmon_temp_invalid = 1;
+	}
+}
+
+static void sysmon_ccfl_enable (sysmon_table_t * this)
+{
+	ulong reg;
+
+	if (!sysmon_temp_invalid) {
+		reg = pic_read  (0x60);
+		reg |= 0x06;
+		pic_write (0x60, reg);
+	}
+}
+
+int sysmon_post_test (int flags)
+{
+	int res = 0;
+	sysmon_table_t * t;
+	uint val;
+
+	/*
+	 * The A/D conversion on the LM87 sensor takes 300 ms.
+	 */
+	if (! conversion_done) {
+		while (post_time_ms(gd->post_init_f_time) < 300) WATCHDOG_RESET ();
+		conversion_done = 1;
+	}
+
+	for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++) {
+		if (t->exec_before) {
+			t->exec_before(t);
+		}
+
+		val = t->sysmon->read(t->sysmon, t->addr);
+		if (val != -1) {
+			t->val_valid = val >= t->val_min && val <= t->val_max;
+			t->val_valid_alt = val >= t->val_min_alt && val <= t->val_max_alt;
+		} else {
+			t->val_valid = 0;
+			t->val_valid_alt = 0;
+		}
+
+		if (t->exec_after) {
+			t->exec_after(t);
+		}
+
+		if ((!t->val_valid) || (flags & POST_MANUAL)) {
+			printf("%-17s = %-10s ", t->name, sysmon_unit_value(t, val));
+			printf("allowed range");
+			printf(" %-8s ..", sysmon_unit_value(t, t->val_min));
+			printf(" %-8s", sysmon_unit_value(t, t->val_max));
+			printf("     %s\n", t->val_valid ? "OK" : "FAIL");
+		}
+
+		if (!t->val_valid) {
+			res = -1;
+		}
+	}
+
+	return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_SYSMON */
+#endif /* CONFIG_POST */
diff --git a/post/board/netta/Makefile b/post/board/netta/Makefile
new file mode 100644
index 0000000..60c7790
--- /dev/null
+++ b/post/board/netta/Makefile
@@ -0,0 +1,29 @@
+#
+# (C) Copyright 2002-2006
+# 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
+#
+
+
+LIB	= libpostnetta.a
+
+COBJS	= codec.o dsp.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/post/board/netta/codec.c b/post/board/netta/codec.c
new file mode 100644
index 0000000..e881752
--- /dev/null
+++ b/post/board/netta/codec.c
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2004
+ * Pantelis Antoniou, Intracom S.A. , panto@intracom.gr
+ *
+ * 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>
+
+/*
+ * CODEC test
+ *
+ * This test verifies the connection and performs a memory test
+ * on any connected codec(s). The meat of the work is done
+ * in the board specific function.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_CODEC
+
+extern int board_post_codec(int flags);
+
+int codec_post_test (int flags)
+{
+	return board_post_codec(flags);
+}
+
+#endif /* CONFIG_POST & CFG_POST_CODEC */
+#endif /* CONFIG_POST */
diff --git a/post/board/netta/dsp.c b/post/board/netta/dsp.c
new file mode 100644
index 0000000..63531a2
--- /dev/null
+++ b/post/board/netta/dsp.c
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2004
+ * Pantelis Antoniou, Intracom S.A. , panto@intracom.gr
+ *
+ * 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>
+
+/*
+ * DSP test
+ *
+ * This test verifies the connection and performs a memory test
+ * on any connected DSP(s). The meat of the work is done
+ * in the board specific function.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_DSP
+
+extern int board_post_dsp(int flags);
+
+int dsp_post_test (int flags)
+{
+	return board_post_dsp(flags);
+}
+
+#endif /* CONFIG_POST & CFG_POST_DSP */
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/Makefile b/post/cpu/mpc8xx/Makefile
new file mode 100644
index 0000000..9dd3f0f
--- /dev/null
+++ b/post/cpu/mpc8xx/Makefile
@@ -0,0 +1,29 @@
+#
+# (C) Copyright 2002-2007
+# 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
+#
+
+LIB	= libpostmpc8xx.a
+
+AOBJS	= cache_8xx.o
+COBJS	= ether.o spr.o uart.o usb.o watchdog.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/post/cpu/mpc8xx/cache_8xx.S b/post/cpu/mpc8xx/cache_8xx.S
new file mode 100644
index 0000000..2d41b55
--- /dev/null
+++ b/post/cpu/mpc8xx/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_MPC862)
+
+#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 */
+#endif /* CONFIG_POST & CFG_POST_CACHE */
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/ether.c b/post/cpu/mpc8xx/ether.c
new file mode 100644
index 0000000..8c87b59
--- /dev/null
+++ b/post/cpu/mpc8xx/ether.c
@@ -0,0 +1,631 @@
+/*
+ * (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 CONFIG_POST & CFG_POST_ETHER
+#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>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#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);
+	void (*halt) (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" };
+
+/* 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)
+{
+	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) || defined(CONFIG_MPC86xADS)
+	/* The FADS860T and MPC86xADS don'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 void scc_halt (int scc_index)
+{
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+	immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
+			~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+	immr->im_ioport.iop_pcso  &=  ~(PC_ENET_CLSN | PC_ENET_RENA);
+}
+
+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:
+
+	ctlr_proc[ctlr].halt (index);
+
+	/*
+	 * 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;
+
+	ctlr_proc[CTLR_SCC].init = scc_init;
+	ctlr_proc[CTLR_SCC].halt = scc_halt;
+	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;
+		}
+	}
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+	serial_reinit_all ();
+#endif
+	return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_ETHER */
+
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/spr.c b/post/cpu/mpc8xx/spr.c
new file mode 100644
index 0000000..330b977
--- /dev/null
+++ b/post/cpu/mpc8xx/spr.c
@@ -0,0 +1,152 @@
+/*
+ * (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>
+
+/*
+ * SPR test
+ *
+ * The test checks the contents of Special Purpose Registers (SPR) listed
+ * in the spr_test_list array below.
+ * Each SPR value is read using mfspr instruction, some bits are masked
+ * according to the table and the resulting value is compared to the
+ * corresponding table value.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_SPR
+
+static struct
+{
+    int number;
+    char * name;
+    unsigned long mask;
+    unsigned long value;
+} spr_test_list [] = {
+	/* Standard Special-Purpose Registers */
+
+	{1,	"XER",		0x00000000,	0x00000000},
+	{8,	"LR",		0x00000000,	0x00000000},
+	{9,	"CTR",		0x00000000,	0x00000000},
+	{18,	"DSISR",	0x00000000,	0x00000000},
+	{19,	"DAR",		0x00000000,	0x00000000},
+	{22,	"DEC",		0x00000000,	0x00000000},
+	{26,	"SRR0",		0x00000000,	0x00000000},
+	{27,	"SRR1",		0x00000000,	0x00000000},
+	{272,	"SPRG0",	0x00000000,	0x00000000},
+	{273,	"SPRG1",	0x00000000,	0x00000000},
+	{274,	"SPRG2",	0x00000000,	0x00000000},
+	{275,	"SPRG3",	0x00000000,	0x00000000},
+	{287,	"PVR",		0xFFFF0000,	0x00500000},
+
+	/* Additional Special-Purpose Registers */
+
+	{144,	"CMPA",		0x00000000,	0x00000000},
+	{145,	"CMPB",		0x00000000,	0x00000000},
+	{146,	"CMPC",		0x00000000,	0x00000000},
+	{147,	"CMPD",		0x00000000,	0x00000000},
+	{148,	"ICR",		0xFFFFFFFF,	0x00000000},
+	{149,	"DER",		0x00000000,	0x00000000},
+	{150,	"COUNTA",	0xFFFFFFFF,	0x00000000},
+	{151,	"COUNTB",	0xFFFFFFFF,	0x00000000},
+	{152,	"CMPE",		0x00000000,	0x00000000},
+	{153,	"CMPF",		0x00000000,	0x00000000},
+	{154,	"CMPG",		0x00000000,	0x00000000},
+	{155,	"CMPH",		0x00000000,	0x00000000},
+	{156,	"LCTRL1",	0xFFFFFFFF,	0x00000000},
+	{157,	"LCTRL2",	0xFFFFFFFF,	0x00000000},
+	{158,	"ICTRL",	0xFFFFFFFF,	0x00000007},
+	{159,	"BAR",		0x00000000,	0x00000000},
+	{630,	"DPDR",		0x00000000,	0x00000000},
+	{631,	"DPIR",		0x00000000,	0x00000000},
+	{638,	"IMMR",		0xFFFF0000,	CFG_IMMR  },
+	{560,	"IC_CST",	0x8E380000,	0x00000000},
+	{561,	"IC_ADR",	0x00000000,	0x00000000},
+	{562,	"IC_DAT",	0x00000000,	0x00000000},
+	{568,	"DC_CST",	0xEF380000,	0x00000000},
+	{569,	"DC_ADR",	0x00000000,	0x00000000},
+	{570,	"DC_DAT",	0x00000000,	0x00000000},
+	{784,	"MI_CTR",	0xFFFFFFFF,	0x00000000},
+	{786,	"MI_AP",	0x00000000,	0x00000000},
+	{787,	"MI_EPN",	0x00000000,	0x00000000},
+	{789,	"MI_TWC",	0xFFFFFE02,	0x00000000},
+	{790,	"MI_RPN",	0x00000000,	0x00000000},
+	{816,	"MI_DBCAM",	0x00000000,	0x00000000},
+	{817,	"MI_DBRAM0",	0x00000000,	0x00000000},
+	{818,	"MI_DBRAM1",	0x00000000,	0x00000000},
+	{792,	"MD_CTR",	0xFFFFFFFF,	0x04000000},
+	{793,	"M_CASID",	0xFFFFFFF0,	0x00000000},
+	{794,	"MD_AP",	0x00000000,	0x00000000},
+	{795,	"MD_EPN",	0x00000000,	0x00000000},
+	{796,	"M_TWB",	0x00000003,	0x00000000},
+	{797,	"MD_TWC",	0x00000003,	0x00000000},
+	{798,	"MD_RPN",	0x00000000,	0x00000000},
+	{799,	"M_TW",		0x00000000,	0x00000000},
+	{824,	"MD_DBCAM",	0x00000000,	0x00000000},
+	{825,	"MD_DBRAM0",	0x00000000,	0x00000000},
+	{826,	"MD_DBRAM1",	0x00000000,	0x00000000},
+};
+
+static int spr_test_list_size =
+		sizeof (spr_test_list) / sizeof (spr_test_list[0]);
+
+int spr_post_test (int flags)
+{
+	int ret = 0;
+	int ic = icache_status ();
+	int i;
+
+	unsigned long code[] = {
+		0x7c6002a6,				/* mfspr r3,SPR */
+		0x4e800020				/* blr          */
+	};
+	unsigned long (*get_spr) (void) = (void *) code;
+
+	if (ic)
+		icache_disable ();
+
+	for (i = 0; i < spr_test_list_size; i++) {
+		int num = spr_test_list[i].number;
+
+		/* mfspr r3,num */
+		code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6);
+
+		if ((get_spr () & spr_test_list[i].mask) !=
+			(spr_test_list[i].value & spr_test_list[i].mask)) {
+			post_log ("The value of %s special register "
+				  "is incorrect: 0x%08X\n",
+					spr_test_list[i].name, get_spr ());
+			ret = -1;
+		}
+	}
+
+	if (ic)
+		icache_enable ();
+
+	return ret;
+}
+#endif /* CONFIG_POST & CFG_POST_SPR */
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/uart.c b/post/cpu/mpc8xx/uart.c
new file mode 100644
index 0000000..fd97e38
--- /dev/null
+++ b/post/cpu/mpc8xx/uart.c
@@ -0,0 +1,560 @@
+/*
+ * (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>
+
+/*
+ * UART test
+ *
+ * The Serial Management Controllers (SMC) and the Serial Communication
+ * Controllers (SCC) listed in ctlr_list array below are tested in
+ * the loopback UART mode.
+ * The controllers are configured accordingly and several characters
+ * 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 CONFIG_POST & CFG_POST_UART
+#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 <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CTLR_SMC 0
+#define CTLR_SCC 1
+
+/* The list of controllers to test */
+#if defined(CONFIG_MPC823)
+static int ctlr_list[][2] =
+		{ {CTLR_SMC, 0}, {CTLR_SMC, 1}, {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);
+	void (*halt) (int index);
+	void (*putc) (int index, const char c);
+	int (*getc) (int index);
+} ctlr_proc[2];
+
+static char *ctlr_name[2] = { "SMC", "SCC" };
+
+static int proff_smc[] = { PROFF_SMC1, PROFF_SMC2 };
+static int proff_scc[] =
+		{ PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
+
+/*
+ * SMC callbacks
+ */
+
+static void smc_init (int smc_index)
+{
+	static int cpm_cr_ch[] = { CPM_CR_CH_SMC1, CPM_CR_CH_SMC2 };
+
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile smc_t *sp;
+	volatile smc_uart_t *up;
+	volatile cbd_t *tbdf, *rbdf;
+	volatile cpm8xx_t *cp = &(im->im_cpm);
+	uint dpaddr;
+
+	/* initialize pointers to SMC */
+
+	sp = (smc_t *) & (cp->cp_smc[smc_index]);
+	up = (smc_uart_t *) & cp->cp_dparam[proff_smc[smc_index]];
+
+	/* Disable transmitter/receiver.
+	 */
+	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+	/* Enable SDMA.
+	 */
+	im->im_siu_conf.sc_sdcr = 1;
+
+	/* clear error conditions */
+#ifdef	CFG_SDSR
+	im->im_sdma.sdma_sdsr = CFG_SDSR;
+#else
+	im->im_sdma.sdma_sdsr = 0x83;
+#endif
+
+	/* clear SDMA interrupt mask */
+#ifdef	CFG_SDMR
+	im->im_sdma.sdma_sdmr = CFG_SDMR;
+#else
+	im->im_sdma.sdma_sdmr = 0x00;
+#endif
+
+#if defined(CONFIG_FADS)
+	/* Enable RS232 */
+	*((uint *) BCSR1) &=
+			~(smc_index == 1 ? BCSR1_RS232EN_1 : BCSR1_RS232EN_2);
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+	/* Enable Monitor Port Transceiver */
+	*((uchar *) BCSR0) |= BCSR0_ENMONXCVR;
+#endif
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+
+#ifdef CFG_ALLOC_DPRAM
+	dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
+#else
+	dpaddr = CPM_POST_BASE;
+#endif
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	 * For now, this address seems OK, but it may have to
+	 * change with newer versions of the firmware.
+	 * damm: allocating space after the two buffers for rx/tx data
+	 */
+
+	rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
+	rbdf->cbd_bufaddr = (uint) (rbdf + 2);
+	rbdf->cbd_sc = 0;
+	tbdf = rbdf + 1;
+	tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
+	tbdf->cbd_sc = 0;
+
+	/* Set up the uart parameters in the parameter ram.
+	 */
+	up->smc_rbase = dpaddr;
+	up->smc_tbase = dpaddr + sizeof (cbd_t);
+	up->smc_rfcr = SMC_EB;
+	up->smc_tfcr = SMC_EB;
+
+#if defined(CONFIG_MBX)
+	board_serial_init ();
+#endif
+
+	/* Set UART mode, 8 bit, no parity, one stop.
+	 * Enable receive and transmit.
+	 * Set local loopback mode.
+	 */
+	sp->smc_smcmr = smcr_mk_clen (9) | SMCMR_SM_UART | (ushort) 0x0004;
+
+	/* Mask all interrupts and remove anything pending.
+	 */
+	sp->smc_smcm = 0;
+	sp->smc_smce = 0xff;
+
+	/* Set up the baud rate generator.
+	 */
+	cp->cp_simode = 0x00000000;
+
+	cp->cp_brgc1 =
+			(((gd->cpu_clk / 16 / gd->baudrate) -
+			  1) << 1) | CPM_BRG_EN;
+
+	/* Make the first buffer the only buffer.
+	 */
+	tbdf->cbd_sc |= BD_SC_WRAP;
+	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Single character receive.
+	 */
+	up->smc_mrblr = 1;
+	up->smc_maxidl = 0;
+
+	/* Initialize Tx/Rx parameters.
+	 */
+
+	while (cp->cp_cpcr & CPM_CR_FLG)	/* wait if cp is busy */
+		;
+
+	cp->cp_cpcr =
+			mk_cr_cmd (cpm_cr_ch[smc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+	while (cp->cp_cpcr & CPM_CR_FLG)	/* wait if cp is busy */
+		;
+
+	/* Enable transmitter/receiver.
+	 */
+	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+}
+
+static void smc_halt(int smc_index)
+{
+}
+
+static void smc_putc (int smc_index, const char c)
+{
+	volatile cbd_t *tbdf;
+	volatile char *buf;
+	volatile smc_uart_t *up;
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile cpm8xx_t *cpmp = &(im->im_cpm);
+
+	up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
+
+	tbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_tbase];
+
+	/* Wait for last character to go.
+	 */
+
+	buf = (char *) tbdf->cbd_bufaddr;
+#if 0
+	__asm__ ("eieio");
+	while (tbdf->cbd_sc & BD_SC_READY)
+		__asm__ ("eieio");
+#endif
+
+	*buf = c;
+	tbdf->cbd_datlen = 1;
+	tbdf->cbd_sc |= BD_SC_READY;
+	__asm__ ("eieio");
+#if 1
+	while (tbdf->cbd_sc & BD_SC_READY)
+		__asm__ ("eieio");
+#endif
+}
+
+static int smc_getc (int smc_index)
+{
+	volatile cbd_t *rbdf;
+	volatile unsigned char *buf;
+	volatile smc_uart_t *up;
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile cpm8xx_t *cpmp = &(im->im_cpm);
+	unsigned char c;
+	int i;
+
+	up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
+
+	rbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_rbase];
+
+	/* Wait for character to show up.
+	 */
+	buf = (unsigned char *) rbdf->cbd_bufaddr;
+#if 0
+	while (rbdf->cbd_sc & BD_SC_EMPTY);
+#else
+	for (i = 100; i > 0; i--) {
+		if (!(rbdf->cbd_sc & BD_SC_EMPTY))
+			break;
+		udelay (1000);
+	}
+
+	if (i == 0)
+		return -1;
+#endif
+	c = *buf;
+	rbdf->cbd_sc |= BD_SC_EMPTY;
+
+	return (c);
+}
+
+  /*
+   * SCC callbacks
+   */
+
+static void scc_init (int scc_index)
+{
+	static int cpm_cr_ch[] = {
+		CPM_CR_CH_SCC1,
+		CPM_CR_CH_SCC2,
+		CPM_CR_CH_SCC3,
+		CPM_CR_CH_SCC4,
+	};
+
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile scc_t *sp;
+	volatile scc_uart_t *up;
+	volatile cbd_t *tbdf, *rbdf;
+	volatile cpm8xx_t *cp = &(im->im_cpm);
+	uint dpaddr;
+
+	/* initialize pointers to SCC */
+
+	sp = (scc_t *) & (cp->cp_scc[scc_index]);
+	up = (scc_uart_t *) & cp->cp_dparam[proff_scc[scc_index]];
+
+	/* Disable transmitter/receiver.
+	 */
+	sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	 */
+
+#ifdef CFG_ALLOC_DPRAM
+	dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
+#else
+	dpaddr = CPM_POST_BASE;
+#endif
+
+	/* Enable SDMA.
+	 */
+	im->im_siu_conf.sc_sdcr = 0x0001;
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+
+	rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
+	rbdf->cbd_bufaddr = (uint) (rbdf + 2);
+	rbdf->cbd_sc = 0;
+	tbdf = rbdf + 1;
+	tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
+	tbdf->cbd_sc = 0;
+
+	/* Set up the baud rate generator.
+	 */
+	cp->cp_sicr &= ~(0x000000FF << (8 * scc_index));
+	/* no |= needed, since BRG1 is 000 */
+
+	cp->cp_brgc1 =
+			(((gd->cpu_clk / 16 / gd->baudrate) -
+			  1) << 1) | CPM_BRG_EN;
+
+	/* Set up the uart parameters in the parameter ram.
+	 */
+	up->scc_genscc.scc_rbase = dpaddr;
+	up->scc_genscc.scc_tbase = dpaddr + sizeof (cbd_t);
+
+	/* Initialize Tx/Rx parameters.
+	 */
+	while (cp->cp_cpcr & CPM_CR_FLG)	/* wait if cp is busy */
+		;
+	cp->cp_cpcr =
+			mk_cr_cmd (cpm_cr_ch[scc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+	while (cp->cp_cpcr & CPM_CR_FLG)	/* wait if cp is busy */
+		;
+
+	up->scc_genscc.scc_rfcr = SCC_EB | 0x05;
+	up->scc_genscc.scc_tfcr = SCC_EB | 0x05;
+
+	up->scc_genscc.scc_mrblr = 1;	/* Single character receive */
+	up->scc_maxidl = 0;		/* disable max idle */
+	up->scc_brkcr = 1;		/* send one break character on stop TX */
+	up->scc_parec = 0;
+	up->scc_frmec = 0;
+	up->scc_nosec = 0;
+	up->scc_brkec = 0;
+	up->scc_uaddr1 = 0;
+	up->scc_uaddr2 = 0;
+	up->scc_toseq = 0;
+	up->scc_char1 = 0x8000;
+	up->scc_char2 = 0x8000;
+	up->scc_char3 = 0x8000;
+	up->scc_char4 = 0x8000;
+	up->scc_char5 = 0x8000;
+	up->scc_char6 = 0x8000;
+	up->scc_char7 = 0x8000;
+	up->scc_char8 = 0x8000;
+	up->scc_rccm = 0xc0ff;
+
+	/* Set low latency / small fifo.
+	 */
+	sp->scc_gsmrh = SCC_GSMRH_RFW;
+
+	/* Set UART mode
+	 */
+	sp->scc_gsmrl &= ~0xF;
+	sp->scc_gsmrl |= SCC_GSMRL_MODE_UART;
+
+	/* Set local loopback mode.
+	 */
+	sp->scc_gsmrl &= ~SCC_GSMRL_DIAG_LE;
+	sp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;
+
+	/* Set clock divider 16 on Tx and Rx
+	 */
+	sp->scc_gsmrl |= (SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+	sp->scc_psmr |= SCU_PSMR_CL;
+
+	/* Mask all interrupts and remove anything pending.
+	 */
+	sp->scc_sccm = 0;
+	sp->scc_scce = 0xffff;
+	sp->scc_dsr = 0x7e7e;
+	sp->scc_psmr = 0x3000;
+
+	/* Make the first buffer the only buffer.
+	 */
+	tbdf->cbd_sc |= BD_SC_WRAP;
+	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Enable transmitter/receiver.
+	 */
+	sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+}
+
+static void scc_halt(int scc_index)
+{
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile cpm8xx_t *cp = &(im->im_cpm);
+	volatile scc_t *sp = (scc_t *) & (cp->cp_scc[scc_index]);
+
+	sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT | SCC_GSMRL_DIAG_LE);
+}
+
+static void scc_putc (int scc_index, const char c)
+{
+	volatile cbd_t *tbdf;
+	volatile char *buf;
+	volatile scc_uart_t *up;
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile cpm8xx_t *cpmp = &(im->im_cpm);
+
+	up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
+
+	tbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_tbase];
+
+	/* Wait for last character to go.
+	 */
+
+	buf = (char *) tbdf->cbd_bufaddr;
+#if 0
+	__asm__ ("eieio");
+	while (tbdf->cbd_sc & BD_SC_READY)
+		__asm__ ("eieio");
+#endif
+
+	*buf = c;
+	tbdf->cbd_datlen = 1;
+	tbdf->cbd_sc |= BD_SC_READY;
+	__asm__ ("eieio");
+#if 1
+	while (tbdf->cbd_sc & BD_SC_READY)
+		__asm__ ("eieio");
+#endif
+}
+
+static int scc_getc (int scc_index)
+{
+	volatile cbd_t *rbdf;
+	volatile unsigned char *buf;
+	volatile scc_uart_t *up;
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile cpm8xx_t *cpmp = &(im->im_cpm);
+	unsigned char c;
+	int i;
+
+	up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
+
+	rbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
+
+	/* Wait for character to show up.
+	 */
+	buf = (unsigned char *) rbdf->cbd_bufaddr;
+#if 0
+	while (rbdf->cbd_sc & BD_SC_EMPTY);
+#else
+	for (i = 100; i > 0; i--) {
+		if (!(rbdf->cbd_sc & BD_SC_EMPTY))
+			break;
+		udelay (1000);
+	}
+
+	if (i == 0)
+		return -1;
+#endif
+	c = *buf;
+	rbdf->cbd_sc |= BD_SC_EMPTY;
+
+	return (c);
+}
+
+  /*
+   * Test routines
+   */
+
+static int test_ctlr (int ctlr, int index)
+{
+	int res = -1;
+	char test_str[] = "*** UART Test String ***\r\n";
+	int i;
+
+	ctlr_proc[ctlr].init (index);
+
+	for (i = 0; i < sizeof (test_str) - 1; i++) {
+		ctlr_proc[ctlr].putc (index, test_str[i]);
+		if (ctlr_proc[ctlr].getc (index) != test_str[i])
+			goto Done;
+	}
+
+	res = 0;
+
+Done:
+	ctlr_proc[ctlr].halt (index);
+
+	if (res != 0) {
+		post_log ("uart %s%d test failed\n",
+				ctlr_name[ctlr], index + 1);
+	}
+
+	return res;
+}
+
+int uart_post_test (int flags)
+{
+	int res = 0;
+	int i;
+
+	ctlr_proc[CTLR_SMC].init = smc_init;
+	ctlr_proc[CTLR_SMC].halt = smc_halt;
+	ctlr_proc[CTLR_SMC].putc = smc_putc;
+	ctlr_proc[CTLR_SMC].getc = smc_getc;
+
+	ctlr_proc[CTLR_SCC].init = scc_init;
+	ctlr_proc[CTLR_SCC].halt = scc_halt;
+	ctlr_proc[CTLR_SCC].putc = scc_putc;
+	ctlr_proc[CTLR_SCC].getc = scc_getc;
+
+	for (i = 0; i < CTRL_LIST_SIZE; i++) {
+		if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
+			res = -1;
+		}
+	}
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+	serial_reinit_all ();
+#endif
+
+	return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_UART */
+
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/usb.c b/post/cpu/mpc8xx/usb.c
new file mode 100644
index 0000000..0c74cfa
--- /dev/null
+++ b/post/cpu/mpc8xx/usb.c
@@ -0,0 +1,269 @@
+/*
+ * (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>
+
+/*
+ * USB test
+ *
+ * The USB controller is tested in the local loopback mode.
+ * It is configured so that endpoint 0 operates as host and endpoint 1
+ * operates as function endpoint. After that an IN token transaction
+ * is performed.
+ * Refer to MPC850 User Manual, Section 32.11.1 USB Host Controller
+ * Initialization Example.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_USB
+
+#include <commproc.h>
+#include <command.h>
+
+#define TOUT_LOOP 100
+
+#define	PROFF_USB		((uint)0x0000)
+
+#define CPM_USB_EP0_BASE	0x0a00
+#define CPM_USB_EP1_BASE	0x0a20
+
+#define CPM_USB_DT0_BASE	0x0a80
+#define CPM_USB_DT1_BASE	0x0a90
+#define CPM_USB_DR0_BASE	0x0aa0
+#define CPM_USB_DR1_BASE	0x0ab0
+
+#define CPM_USB_RX0_BASE	0x0b00
+#define CPM_USB_RX1_BASE	0x0b08
+#define CPM_USB_TX0_BASE	0x0b20
+#define CPM_USB_TX1_BASE	0x0b28
+
+#define USB_EXPECT(x)		if (!(x)) goto Done;
+
+typedef struct usb_param {
+	ushort ep0ptr;
+	ushort ep1ptr;
+	ushort ep2ptr;
+	ushort ep3ptr;
+	uint rstate;
+	uint rptr;
+	ushort frame_n;
+	ushort rbcnt;
+	ushort rtemp;
+} usb_param_t;
+
+typedef struct usb_param_block {
+	ushort rbase;
+	ushort tbase;
+	uchar rfcr;
+	uchar tfcr;
+	ushort mrblr;
+	ushort rbptr;
+	ushort tbptr;
+	uint tstate;
+	uint tptr;
+	ushort tcrc;
+	ushort tbcnt;
+	uint res[2];
+} usb_param_block_t;
+
+typedef struct usb {
+	uchar usmod;
+	uchar usadr;
+	uchar uscom;
+	uchar res1;
+	ushort usep[4];
+	uchar res2[4];
+	ushort usber;
+	uchar res3[2];
+	ushort usbmr;
+	uchar res4;
+	uchar usbs;
+	uchar res5[8];
+} usb_t;
+
+int usb_post_test (int flags)
+{
+	int res = -1;
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	volatile cpm8xx_t *cp = &(im->im_cpm);
+	volatile usb_param_t *pram_ptr;
+	uint dpram;
+	ushort DPRAM;
+	volatile cbd_t *tx;
+	volatile cbd_t *rx;
+	volatile usb_t *usbr;
+	volatile usb_param_block_t *ep0;
+	volatile usb_param_block_t *ep1;
+	int j;
+
+	pram_ptr = (usb_param_t *) & (im->im_cpm.cp_dparam[PROFF_USB]);
+	dpram = (uint) im->im_cpm.cp_dpmem;
+	DPRAM = dpram;
+	tx = (cbd_t *) (dpram + CPM_USB_TX0_BASE);
+	rx = (cbd_t *) (dpram + CPM_USB_RX0_BASE);
+	ep0 = (usb_param_block_t *) (dpram + CPM_USB_EP0_BASE);
+	ep1 = (usb_param_block_t *) (dpram + CPM_USB_EP1_BASE);
+	usbr = (usb_t *) & (im->im_cpm.cp_scc[0]);
+
+	/* 01 */
+	im->im_ioport.iop_padir &= ~(ushort) 0x0200;
+	im->im_ioport.iop_papar |= (ushort) 0x0200;
+
+	cp->cp_sicr &= ~0x000000FF;
+	cp->cp_sicr |= 0x00000018;
+
+	cp->cp_brgc4 = 0x00010001;
+
+	/* 02 */
+	im->im_ioport.iop_padir &= ~(ushort) 0x0002;
+	im->im_ioport.iop_padir &= ~(ushort) 0x0001;
+
+	im->im_ioport.iop_papar |= (ushort) 0x0002;
+	im->im_ioport.iop_papar |= (ushort) 0x0001;
+
+	/* 03 */
+	im->im_ioport.iop_pcdir &= ~(ushort) 0x0020;
+	im->im_ioport.iop_pcdir &= ~(ushort) 0x0010;
+
+	im->im_ioport.iop_pcpar &= ~(ushort) 0x0020;
+	im->im_ioport.iop_pcpar &= ~(ushort) 0x0010;
+
+	im->im_ioport.iop_pcso |= (ushort) 0x0020;
+	im->im_ioport.iop_pcso |= (ushort) 0x0010;
+
+	/* 04 */
+	im->im_ioport.iop_pcdir |= (ushort) 0x0200;
+	im->im_ioport.iop_pcdir |= (ushort) 0x0100;
+
+	im->im_ioport.iop_pcpar |= (ushort) 0x0200;
+	im->im_ioport.iop_pcpar |= (ushort) 0x0100;
+
+	/* 05 */
+	pram_ptr->frame_n = 0;
+
+	/* 06 */
+	pram_ptr->ep0ptr = DPRAM + CPM_USB_EP0_BASE;
+	pram_ptr->ep1ptr = DPRAM + CPM_USB_EP1_BASE;
+
+	/* 07-10 */
+	tx[0].cbd_sc = 0xB800;
+	tx[0].cbd_datlen = 3;
+	tx[0].cbd_bufaddr = dpram + CPM_USB_DT0_BASE;
+
+	tx[1].cbd_sc = 0xBC80;
+	tx[1].cbd_datlen = 3;
+	tx[1].cbd_bufaddr = dpram + CPM_USB_DT1_BASE;
+
+	rx[0].cbd_sc = 0xA000;
+	rx[0].cbd_datlen = 0;
+	rx[0].cbd_bufaddr = dpram + CPM_USB_DR0_BASE;
+
+	rx[1].cbd_sc = 0xA000;
+	rx[1].cbd_datlen = 0;
+	rx[1].cbd_bufaddr = dpram + CPM_USB_DR1_BASE;
+
+	/* 11-12 */
+	*(volatile int *) (dpram + CPM_USB_DT0_BASE) = 0x69856000;
+	*(volatile int *) (dpram + CPM_USB_DT1_BASE) = 0xABCD1234;
+
+	*(volatile int *) (dpram + CPM_USB_DR0_BASE) = 0;
+	*(volatile int *) (dpram + CPM_USB_DR1_BASE) = 0;
+
+	/* 13-16 */
+	ep0->rbase = DPRAM + CPM_USB_RX0_BASE;
+	ep0->tbase = DPRAM + CPM_USB_TX0_BASE;
+	ep0->rfcr = 0x18;
+	ep0->tfcr = 0x18;
+	ep0->mrblr = 0x100;
+	ep0->rbptr = DPRAM + CPM_USB_RX0_BASE;
+	ep0->tbptr = DPRAM + CPM_USB_TX0_BASE;
+	ep0->tstate = 0;
+
+	/* 17-20 */
+	ep1->rbase = DPRAM + CPM_USB_RX1_BASE;
+	ep1->tbase = DPRAM + CPM_USB_TX1_BASE;
+	ep1->rfcr = 0x18;
+	ep1->tfcr = 0x18;
+	ep1->mrblr = 0x100;
+	ep1->rbptr = DPRAM + CPM_USB_RX1_BASE;
+	ep1->tbptr = DPRAM + CPM_USB_TX1_BASE;
+	ep1->tstate = 0;
+
+	/* 21-24 */
+	usbr->usep[0] = 0x0000;
+	usbr->usep[1] = 0x1100;
+	usbr->usep[2] = 0x2200;
+	usbr->usep[3] = 0x3300;
+
+	/* 25 */
+	usbr->usmod = 0x06;
+
+	/* 26 */
+	usbr->usadr = 0x05;
+
+	/* 27 */
+	usbr->uscom = 0;
+
+	/* 28 */
+	usbr->usmod |= 0x01;
+	udelay (1);
+
+	/* 29-30 */
+	usbr->uscom = 0x80;
+	usbr->uscom = 0x81;
+
+	/* Wait for the data packet to be transmitted */
+	for (j = 0; j < TOUT_LOOP; j++) {
+		if (tx[1].cbd_sc & (ushort) 0x8000)
+			udelay (1);
+		else
+			break;
+	}
+
+	USB_EXPECT (j < TOUT_LOOP);
+
+	USB_EXPECT (tx[0].cbd_sc == 0x3800);
+	USB_EXPECT (tx[0].cbd_datlen == 3);
+
+	USB_EXPECT (tx[1].cbd_sc == 0x3C80);
+	USB_EXPECT (tx[1].cbd_datlen == 3);
+
+	USB_EXPECT (rx[0].cbd_sc == 0x2C00);
+	USB_EXPECT (rx[0].cbd_datlen == 5);
+
+	USB_EXPECT (*(volatile int *) (dpram + CPM_USB_DR0_BASE) ==
+				0xABCD122B);
+	USB_EXPECT (*(volatile char *) (dpram + CPM_USB_DR0_BASE + 4) == 0x42);
+
+	res = 0;
+  Done:
+
+	return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_USB */
+
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/watchdog.c b/post/cpu/mpc8xx/watchdog.c
new file mode 100644
index 0000000..48c4282
--- /dev/null
+++ b/post/cpu/mpc8xx/watchdog.c
@@ -0,0 +1,78 @@
+/*
+ * (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>
+
+/*
+ * Watchdog test
+ *
+ * The test verifies the watchdog timer operation.
+ * On the first iteration, the test routine disables interrupts and
+ * makes a 10-second delay. If the system does not reboot during this delay,
+ * the watchdog timer is not operational and the test fails. If the system
+ * reboots, on the second iteration the test routine reports a success.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_WATCHDOG
+
+static ulong gettbl (void)
+{
+	ulong r;
+
+  asm ("mftbl %0":"=r" (r));
+
+	return r;
+}
+
+int watchdog_post_test (int flags)
+{
+	if (flags & POST_REBOOT) {
+		/* Test passed */
+
+		return 0;
+	} else {
+		/* 10-second delay */
+		int ints = disable_interrupts ();
+		ulong base = gettbl ();
+		ulong clk = get_tbclk ();
+
+		while ((gettbl () - base) / 10 < clk);
+
+		if (ints)
+			enable_interrupts ();
+
+		/*
+		 * If we have reached this point, the watchdog timer
+		 * does not work
+		 */
+		return -1;
+	}
+}
+
+#endif /* CONFIG_POST & CFG_POST_WATCHDOG */
+#endif /* CONFIG_POST */
diff --git a/post/drivers/Makefile b/post/drivers/Makefile
new file mode 100644
index 0000000..068fa98
--- /dev/null
+++ b/post/drivers/Makefile
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2002-2006
+# 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
+#
+
+
+SUBDIRS =
+
+LIB	= libpostdrivers.a
+
+COBJS	= cache.o i2c.o memory.o rtc.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/post/drivers/cache.c b/post/drivers/cache.c
new file mode 100644
index 0000000..501465c
--- /dev/null
+++ b/post/drivers/cache.c
@@ -0,0 +1,81 @@
+/*
+ * (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>
+
+/* Cache test
+ *
+ * This test verifies the CPU data and instruction cache using
+ * several test scenarios.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_CACHE
+
+#define CACHE_POST_SIZE	1024
+
+extern int cache_post_test1 (char *, unsigned int);
+extern int cache_post_test2 (char *, unsigned int);
+extern int cache_post_test3 (char *, unsigned int);
+extern int cache_post_test4 (char *, unsigned int);
+extern int cache_post_test5 (void);
+extern int cache_post_test6 (void);
+
+int cache_post_test (int flags)
+{
+	int ints = disable_interrupts ();
+	int res = 0;
+	static char ta[CACHE_POST_SIZE + 0xf];
+	char *testarea = (char *) (((unsigned long) ta + 0xf) & ~0xf);
+
+	WATCHDOG_RESET ();
+	if (res == 0)
+		res = cache_post_test1 (testarea, CACHE_POST_SIZE);
+	WATCHDOG_RESET ();
+	if (res == 0)
+		res = cache_post_test2 (testarea, CACHE_POST_SIZE);
+	WATCHDOG_RESET ();
+	if (res == 0)
+		res = cache_post_test3 (testarea, CACHE_POST_SIZE);
+	WATCHDOG_RESET ();
+	if (res == 0)
+		res = cache_post_test4 (testarea, CACHE_POST_SIZE);
+	WATCHDOG_RESET ();
+	if (res == 0)
+		res = cache_post_test5 ();
+	WATCHDOG_RESET ();
+	if (res == 0)
+		res = cache_post_test6 ();
+
+	WATCHDOG_RESET ();
+	if (ints)
+		enable_interrupts ();
+	return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_CACHE */
+#endif /* CONFIG_POST */
diff --git a/post/drivers/i2c.c b/post/drivers/i2c.c
new file mode 100644
index 0000000..1b2e644
--- /dev/null
+++ b/post/drivers/i2c.c
@@ -0,0 +1,94 @@
+/*
+ * (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>
+
+#ifdef CONFIG_POST
+
+/*
+ * I2C test
+ *
+ * For verifying the I2C bus, a full I2C bus scanning is performed.
+ *
+ * #ifdef I2C_ADDR_LIST
+ *   The test is considered as passed if all the devices and
+ *   only the devices in the list are found.
+ * #else [ ! I2C_ADDR_LIST ]
+ *   The test is considered as passed if any I2C device is found.
+ * #endif
+ */
+
+#include <post.h>
+#include <i2c.h>
+
+#if CONFIG_POST & CFG_POST_I2C
+
+int i2c_post_test (int flags)
+{
+	unsigned int i;
+	unsigned int good = 0;
+#ifdef I2C_ADDR_LIST
+	unsigned int bad  = 0;
+	int j;
+	unsigned char i2c_addr_list[] = I2C_ADDR_LIST;
+	unsigned char i2c_miss_list[] = I2C_ADDR_LIST;
+#endif
+
+	for (i = 0; i < 128; i++) {
+		if (i2c_probe (i) == 0) {
+#ifndef	I2C_ADDR_LIST
+			good++;
+#else	/* I2C_ADDR_LIST */
+			for (j=0; j<sizeof(i2c_addr_list); ++j) {
+				if (i == i2c_addr_list[j]) {
+					good++;
+					i2c_miss_list[j] = 0xFF;
+					break;
+				}
+			}
+			if (j == sizeof(i2c_addr_list)) {
+				bad++;
+				post_log ("I2C: addr %02X not expected\n",
+						i);
+			}
+#endif	/* I2C_ADDR_LIST */
+		}
+	}
+
+#ifndef	I2C_ADDR_LIST
+	return good > 0 ? 0 : -1;
+#else	/* I2C_ADDR_LIST */
+	if (good != sizeof(i2c_addr_list)) {
+		for (j=0; j<sizeof(i2c_miss_list); ++j) {
+			if (i2c_miss_list[j] != 0xFF) {
+				post_log ("I2C: addr %02X did not respond\n",
+						i2c_miss_list[j]);
+			}
+		}
+	}
+	return ((good == sizeof(i2c_addr_list)) && (bad == 0)) ? 0 : -1;
+#endif
+}
+
+#endif /* CONFIG_POST & CFG_POST_I2C */
+#endif /* CONFIG_POST */
diff --git a/post/drivers/memory.c b/post/drivers/memory.c
new file mode 100644
index 0000000..a2c088b
--- /dev/null
+++ b/post/drivers/memory.c
@@ -0,0 +1,483 @@
+/*
+ * (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 slow-test mode, it verifies
+ * the whole RAM.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_MEMORY
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * 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[] = {
+	0xaaaaaaaaaaaaaaaaULL,
+	0xccccccccccccccccULL,
+	0xf0f0f0f0f0f0f0f0ULL,
+	0xff00ff00ff00ff00ULL,
+	0xffff0000ffff0000ULL,
+	0xffffffff00000000ULL,
+	0x00000000ffffffffULL,
+	0x0000ffff0000ffffULL,
+	0x00ff00ff00ff00ffULL,
+	0x0f0f0f0f0f0f0f0fULL,
+	0x3333333333333333ULL,
+	0x5555555555555555ULL
+};
+const unsigned long long otherpattern = 0x0123456789abcdefULL;
+
+
+static int memory_post_dataline(unsigned long long * pmem)
+{
+	unsigned long long temp64 = 0;
+	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 = (ulong *)((ulong)base + size);	/* pointer arith! */
+	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 ((unsigned long long *)start);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_addrline ((ulong *)start, (ulong *)start, size);
+	WATCHDOG_RESET ();
+	if (ret == 0)
+		ret = memory_post_addrline ((ulong *)(start + size - 8),
+					    (ulong *)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;
+	bd_t *bd = gd->bd;
+	unsigned long memsize = (bd->bi_memsize >= 256 << 20 ?
+				 256 << 20 : bd->bi_memsize) - (1 << 20);
+
+
+	if (flags & POST_SLOWTEST) {
+		ret = memory_post_tests (CFG_SDRAM_BASE, memsize);
+	} else {			/* POST_NORMAL */
+
+		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/post/drivers/rtc.c b/post/drivers/rtc.c
new file mode 100644
index 0000000..7d4f9b8
--- /dev/null
+++ b/post/drivers/rtc.c
@@ -0,0 +1,183 @@
+/*
+ * (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>
+
+/*
+ * RTC test
+ *
+ * The Real Time Clock (RTC) operation is verified by this test.
+ * The following features are verified:
+ *   o) Time uniformity
+ *      This is verified by reading RTC in polling within
+ *      a short period of time.
+ *   o) Passing month boundaries
+ *      This is checked by setting RTC to a second before
+ *      a month boundary and reading it after its passing the
+ *      boundary. The test is performed for both leap- and
+ *      nonleap-years.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <rtc.h>
+
+#if CONFIG_POST & CFG_POST_RTC
+
+static int rtc_post_skip (ulong * diff)
+{
+	struct rtc_time tm1;
+	struct rtc_time tm2;
+	ulong start1;
+	ulong start2;
+
+	rtc_get (&tm1);
+	start1 = get_timer (0);
+
+	while (1) {
+		rtc_get (&tm2);
+		start2 = get_timer (0);
+		if (tm1.tm_sec != tm2.tm_sec)
+			break;
+		if (start2 - start1 > 1500)
+			break;
+	}
+
+	if (tm1.tm_sec != tm2.tm_sec) {
+		*diff = start2 - start1;
+
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+static void rtc_post_restore (struct rtc_time *tm, unsigned int sec)
+{
+	time_t t = mktime (tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
+					   tm->tm_min, tm->tm_sec) + sec;
+	struct rtc_time ntm;
+
+	to_tm (t, &ntm);
+
+	rtc_set (&ntm);
+}
+
+int rtc_post_test (int flags)
+{
+	ulong diff;
+	unsigned int i;
+	struct rtc_time svtm;
+	static unsigned int daysnl[] =
+			{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+	static unsigned int daysl[] =
+			{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+	unsigned int ynl = 1999;
+	unsigned int yl = 2000;
+	unsigned int skipped = 0;
+
+	/* Time uniformity */
+	if (rtc_post_skip (&diff) != 0) {
+		post_log ("Timeout while waiting for a new second !\n");
+
+		return -1;
+	}
+
+	for (i = 0; i < 5; i++) {
+		if (rtc_post_skip (&diff) != 0) {
+			post_log ("Timeout while waiting for a new second !\n");
+
+			return -1;
+		}
+
+		if (diff < 950 || diff > 1050) {
+			post_log ("Invalid second duration !\n");
+
+			return -1;
+		}
+	}
+
+	/* Passing month boundaries */
+
+	if (rtc_post_skip (&diff) != 0) {
+		post_log ("Timeout while waiting for a new second !\n");
+
+		return -1;
+	}
+	rtc_get (&svtm);
+
+	for (i = 0; i < 12; i++) {
+		time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59);
+		struct rtc_time tm;
+
+		to_tm (t, &tm);
+		rtc_set (&tm);
+
+		skipped++;
+		if (rtc_post_skip (&diff) != 0) {
+			rtc_post_restore (&svtm, skipped);
+			post_log ("Timeout while waiting for a new second !\n");
+
+			return -1;
+		}
+
+		rtc_get (&tm);
+		if (tm.tm_mon == i + 1) {
+			rtc_post_restore (&svtm, skipped);
+			post_log ("Month %d boundary is not passed !\n", i + 1);
+
+			return -1;
+		}
+	}
+
+	for (i = 0; i < 12; i++) {
+		time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59);
+		struct rtc_time tm;
+
+		to_tm (t, &tm);
+		rtc_set (&tm);
+
+		skipped++;
+		if (rtc_post_skip (&diff) != 0) {
+			rtc_post_restore (&svtm, skipped);
+			post_log ("Timeout while waiting for a new second !\n");
+
+			return -1;
+		}
+
+		rtc_get (&tm);
+		if (tm.tm_mon == i + 1) {
+			rtc_post_restore (&svtm, skipped);
+			post_log ("Month %d boundary is not passed !\n", i + 1);
+
+			return -1;
+		}
+	}
+	rtc_post_restore (&svtm, skipped);
+
+	return 0;
+}
+
+#endif /* CONFIG_POST & CFG_POST_RTC */
+#endif /* CONFIG_POST */
diff --git a/post/lib_ppc/Makefile b/post/lib_ppc/Makefile
new file mode 100644
index 0000000..14354a0
--- /dev/null
+++ b/post/lib_ppc/Makefile
@@ -0,0 +1,32 @@
+#
+# (C) Copyright 2002-2006
+# 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
+#
+
+
+LIB	= libpostppc.a
+
+AOBJS	= asm.o
+COBJS	= cpu.o cmp.o cmpi.o two.o twox.o three.o threex.o
+COBJS   += threei.o andi.o srawi.o rlwnm.o rlwinm.o rlwimi.o
+COBJS	+= store.o load.o cr.o b.o multi.o string.o complex.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/post/lib_ppc/andi.c b/post/lib_ppc/andi.c
new file mode 100644
index 0000000..7ddf2ab
--- /dev/null
+++ b/post/lib_ppc/andi.c
@@ -0,0 +1,123 @@
+/*
+ * (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
+ * Logic instructions:		andi., andis.
+ *
+ * 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_andi_s
+{
+    ulong cmd;
+    ulong op1;
+    ushort op2;
+    ulong res;
+} cpu_post_andi_table[] =
+{
+    {
+    	OP_ANDI_,
+	0x80008000,
+	0xffff,
+	0x00008000
+    },
+    {
+    	OP_ANDIS_,
+	0x80008000,
+	0xffff,
+	0x80000000
+    },
+};
+static unsigned int cpu_post_andi_size =
+    sizeof (cpu_post_andi_table) / sizeof (struct cpu_post_andi_s);
+
+int cpu_post_test_andi (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_andi_size && ret == 0; i++)
+    {
+	struct cpu_post_andi_s *test = cpu_post_andi_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 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_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;
+
+	    cpu_post_exec_21 (codecr, & cr, & res, test->op1);
+
+	    ret = res == test->res &&
+		  (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    if (ret != 0)
+	    {
+	        post_log ("Error at andi test %d !\n", i);
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/asm.S b/post/lib_ppc/asm.S
new file mode 100644
index 0000000..a0815a4
--- /dev/null
+++ b/post/lib_ppc/asm.S
@@ -0,0 +1,346 @@
+/*
+ *  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
+
+#include <post.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+
+#if CONFIG_POST & CFG_POST_CPU
+
+/* void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2); */
+	.global	cpu_post_exec_02
+cpu_post_exec_02:
+	mflr	r0
+	stwu	r0, -4(r1)
+
+	subi	r1, r1, 104
+	stmw	r6, 0(r1)
+
+	mtlr	r3
+	mr	r3, r4
+	mr	r4, r5
+	blrl
+
+	lmw	r6, 0(r1)
+	addi	r1, r1, 104
+
+	lwz	r0, 0(r1)
+	addi	r1, r1, 4
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_04 (ulong *code, ulong op1, ulong op2, ulong op3, ulong op4); */
+	.global	cpu_post_exec_04
+cpu_post_exec_04:
+	mflr	r0
+	stwu	r0, -4(r1)
+
+	subi	r1, r1, 96
+	stmw	r8, 0(r1)
+
+	mtlr	r3
+	mr	r3, r4
+	mr	r4, r5
+	mr	r5, r6
+	mtxer	r7
+	blrl
+
+	lmw	r8, 0(r1)
+	addi	r1, r1, 96
+
+	lwz	r0, 0(r1)
+	addi	r1, r1, 4
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2); */
+	.global	cpu_post_exec_12
+cpu_post_exec_12:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+
+	mtlr	r3
+	mr	r3, r5
+	mr	r4, r6
+	blrl
+
+	lwz	r4, 0(r1)
+	stw	r3, 0(r4)
+
+	lwz	r0, 4(r1)
+	addi	r1, r1, 8
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1); */
+	.global	cpu_post_exec_11
+cpu_post_exec_11:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+
+	mtlr	r3
+	mr	r3, r5
+	blrl
+
+	lwz	r4, 0(r1)
+	stw	r3, 0(r4)
+
+	lwz	r0, 4(r1)
+	addi	r1, r1, 8
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1); */
+	.global	cpu_post_exec_21
+cpu_post_exec_21:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+	stwu	r5, -4(r1)
+
+	li	r0, 0
+	mtxer	r0
+	lwz	r0, 0(r4)
+	mtcr	r0
+
+	mtlr	r3
+	mr	r3, r6
+	blrl
+
+	mfcr	r0
+	lwz	r4, 4(r1)
+	stw	r0, 0(r4)
+	lwz	r4, 0(r1)
+	stw	r3, 0(r4)
+
+	lwz	r0, 8(r1)
+	addi	r1, r1, 12
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+    ulong op2); */
+	.global	cpu_post_exec_22
+cpu_post_exec_22:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+	stwu	r5, -4(r1)
+
+	li	r0, 0
+	mtxer	r0
+	lwz	r0, 0(r4)
+	mtcr	r0
+
+	mtlr	r3
+	mr	r3, r6
+	mr	r4, r7
+	blrl
+
+	mfcr	r0
+	lwz	r4, 4(r1)
+	stw	r0, 0(r4)
+	lwz	r4, 0(r1)
+	stw	r3, 0(r4)
+
+	lwz	r0, 8(r1)
+	addi	r1, r1, 12
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_12w (ulong *code, ulong *op1, ulong op2, ulong op3); */
+	.global	cpu_post_exec_12w
+cpu_post_exec_12w:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+
+	mtlr	r3
+	lwz	r3, 0(r4)
+	mr	r4, r5
+	mr	r5, r6
+	blrl
+
+	lwz	r4, 0(r1)
+	stw	r3, 0(r4)
+
+	lwz	r0, 4(r1)
+	addi	r1, r1, 8
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2); */
+	.global	cpu_post_exec_11w
+cpu_post_exec_11w:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+
+	mtlr	r3
+	lwz	r3, 0(r4)
+	mr	r4, r5
+	blrl
+
+	lwz	r4, 0(r1)
+	stw	r3, 0(r4)
+
+	lwz	r0, 4(r1)
+	addi	r1, r1, 8
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_22w (ulong *code, ulong *op1, ulong op2, ulong *op3); */
+	.global	cpu_post_exec_22w
+cpu_post_exec_22w:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+	stwu	r6, -4(r1)
+
+	mtlr	r3
+	lwz	r3, 0(r4)
+	mr	r4, r5
+	blrl
+
+	lwz	r4, 4(r1)
+	stw	r3, 0(r4)
+	lwz	r4, 0(r1)
+	stw	r5, 0(r4)
+
+	lwz	r0, 8(r1)
+	addi	r1, r1, 12
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_21w (ulong *code, ulong *op1, ulong *op2); */
+	.global	cpu_post_exec_21w
+cpu_post_exec_21w:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+	stwu	r5, -4(r1)
+
+	mtlr	r3
+	lwz	r3, 0(r4)
+	blrl
+
+	lwz	r5, 4(r1)
+	stw	r3, 0(r5)
+	lwz	r5, 0(r1)
+	stw	r4, 0(r5)
+
+	lwz	r0, 8(r1)
+	addi	r1, r1, 12
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3); */
+	.global	cpu_post_exec_21x
+cpu_post_exec_21x:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+	stwu	r5, -4(r1)
+
+	mtlr	r3
+	mr	r3, r6
+	blrl
+
+	lwz	r5, 4(r1)
+	stw	r3, 0(r5)
+	lwz	r5, 0(r1)
+	stw	r4, 0(r5)
+
+	lwz	r0, 8(r1)
+	addi	r1, r1, 12
+	mtlr	r0
+	blr
+
+/* void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
+    ulong cr); */
+	.global	cpu_post_exec_31
+cpu_post_exec_31:
+	mflr	r0
+	stwu	r0, -4(r1)
+	stwu	r4, -4(r1)
+	stwu	r5, -4(r1)
+	stwu	r6, -4(r1)
+
+	mtlr	r3
+	lwz	r3, 0(r4)
+	lwz	r4, 0(r5)
+	mr	r6, r7
+	blrl
+
+	lwz	r7, 8(r1)
+	stw	r3, 0(r7)
+	lwz	r7, 4(r1)
+	stw	r4, 0(r7)
+	lwz	r7, 0(r1)
+	stw	r5, 0(r7)
+
+	lwz	r0, 12(r1)
+	addi	r1, r1, 16
+	mtlr	r0
+	blr
+
+/* int cpu_post_complex_1_asm (int a1, int a2, int a3, int a4, int n); */
+	.global	cpu_post_complex_1_asm
+cpu_post_complex_1_asm:
+	li	r9,0
+	cmpw	r9,r7
+	bge	cpu_post_complex_1_done
+	mtctr	r7
+cpu_post_complex_1_loop:
+	mullw	r0,r3,r4
+	subf	r0,r5,r0
+	divw	r0,r0,r6
+	add	r9,r9,r0
+	bdnz	cpu_post_complex_1_loop
+cpu_post_complex_1_done:
+	mr	r3,r9
+	blr
+
+/* int cpu_post_complex_2_asm (int x, int n); */
+	.global	cpu_post_complex_2_asm
+cpu_post_complex_2_asm:
+	mr.	r0,r4
+	mtctr	r0
+	mr	r0,r3
+	li	r3,1
+	li	r4,1
+	blelr
+cpu_post_complex_2_loop:
+	mullw	r3,r3,r0
+	add	r3,r3,r4
+	bdnz	cpu_post_complex_2_loop
+blr
+
+#endif
+#endif
diff --git a/post/lib_ppc/b.c b/post/lib_ppc/b.c
new file mode 100644
index 0000000..b4b17c8
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/cmp.c b/post/lib_ppc/cmp.c
new file mode 100644
index 0000000..789a24c
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/cmpi.c b/post/lib_ppc/cmpi.c
new file mode 100644
index 0000000..e0c2aaf
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/complex.c b/post/lib_ppc/complex.c
new file mode 100644
index 0000000..033584b
--- /dev/null
+++ b/post/lib_ppc/complex.c
@@ -0,0 +1,126 @@
+/*
+ * (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
+ * Complex calculations
+ *
+ * The calculations in this test are just a combination of simpler
+ * calculations, but probably under different timing conditions, etc.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern int cpu_post_complex_1_asm (int a1, int a2, int a3, int a4, int n);
+extern int cpu_post_complex_2_asm (int x, int n);
+
+  /*
+   *     n
+   *	SUM (a1 * a2 - a3) / a4 = n * result
+   *    i=1
+   */
+static int cpu_post_test_complex_1 (void)
+{
+    int a1 = 666;
+    int a2 = 667;
+    int a3 = 668;
+    int a4 = 66;
+    int n = 100;
+    int result = 6720; /* (a1 * a2 - a3) / a4 */
+
+    if (cpu_post_complex_1_asm(a1, a2, a3, a4, n) != n * result)
+    {
+	return -1;
+    }
+
+    return 0;
+}
+
+  /*	(1 + x + x^2 + ... + x^n) * (1 - x) = 1 - x^(n+1)
+   */
+static int cpu_post_test_complex_2 (void)
+{
+    int ret = -1;
+    int x;
+    int n;
+    int k;
+    int left;
+    int right;
+
+    for (x = -8; x <= 8; x ++)
+    {
+	n = 9;
+
+	left = cpu_post_complex_2_asm(x, n);
+	left *= 1 - x;
+
+	right = 1;
+	for (k = 0; k <= n; k ++)
+	{
+	    right *= x;
+	}
+	right = 1 - right;
+
+	if (left != right)
+	{
+	    goto Done;
+	}
+    }
+
+    ret = 0;
+    Done:
+
+    return ret;
+}
+
+int cpu_post_test_complex (void)
+{
+    int ret = 0;
+
+    if (ret == 0)
+    {
+	ret = cpu_post_test_complex_1();
+    }
+
+    if (ret == 0)
+    {
+	ret = cpu_post_test_complex_2();
+    }
+
+    if (ret != 0)
+    {
+	post_log ("Error at complex test !\n");
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/cpu.c b/post/lib_ppc/cpu.c
new file mode 100644
index 0000000..1f2ded2
--- /dev/null
+++ b/post/lib_ppc/cpu.c
@@ -0,0 +1,139 @@
+/*
+ * (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;
+
+	WATCHDOG_RESET();
+	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 ();
+	WATCHDOG_RESET();
+	if (ret == 0)
+		ret = cpu_post_test_three ();
+	if (ret == 0)
+		ret = cpu_post_test_threex ();
+	if (ret == 0)
+		ret = cpu_post_test_threei ();
+	if (ret == 0)
+		ret = cpu_post_test_andi ();
+	WATCHDOG_RESET();
+	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 ();
+	WATCHDOG_RESET();
+	if (ret == 0)
+		ret = cpu_post_test_store ();
+	if (ret == 0)
+		ret = cpu_post_test_load ();
+	if (ret == 0)
+		ret = cpu_post_test_cr ();
+	if (ret == 0)
+		ret = cpu_post_test_b ();
+	WATCHDOG_RESET();
+	if (ret == 0)
+		ret = cpu_post_test_multi ();
+	WATCHDOG_RESET();
+	if (ret == 0)
+		ret = cpu_post_test_string ();
+	if (ret == 0)
+		ret = cpu_post_test_complex ();
+	WATCHDOG_RESET();
+
+	if (ic)
+		icache_enable ();
+
+	WATCHDOG_RESET();
+
+	return ret;
+}
+
+#endif /* CONFIG_POST & CFG_POST_CPU */
+#endif /* CONFIG_POST */
diff --git a/post/lib_ppc/cpu_asm.h b/post/lib_ppc/cpu_asm.h
new file mode 100644
index 0000000..1cbaf41
--- /dev/null
+++ b/post/lib_ppc/cpu_asm.h
@@ -0,0 +1,224 @@
+/*
+ * (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 _CPU_ASM_H
+#define _CPU_ASM_H
+
+#define BIT_C				0x00000001
+
+#define OP_BLR				0x4e800020
+#define OP_EXTSB			0x7c000774
+#define OP_EXTSH			0x7c000734
+#define OP_NEG				0x7c0000d0
+#define OP_CNTLZW			0x7c000034
+#define OP_ADD				0x7c000214
+#define OP_ADDC				0x7c000014
+#define OP_ADDME			0x7c0001d4
+#define OP_ADDZE			0x7c000194
+#define OP_ADDE				0x7c000114
+#define OP_ADDI				0x38000000
+#define OP_SUBF				0x7c000050
+#define OP_SUBFC			0x7c000010
+#define OP_SUBFE			0x7c000110
+#define OP_SUBFME			0x7c0001d0
+#define OP_SUBFZE			0x7c000190
+#define OP_MFCR				0x7c000026
+#define OP_MTCR				0x7c0ff120
+#define OP_MFXER			0x7c0102a6
+#define OP_MTXER			0x7c0103a6
+#define OP_MCRXR			0x7c000400
+#define OP_MCRF				0x4c000000
+#define OP_CRAND			0x4c000202
+#define OP_CRANDC			0x4c000102
+#define OP_CROR				0x4c000382
+#define OP_CRORC			0x4c000342
+#define OP_CRXOR			0x4c000182
+#define OP_CRNAND			0x4c0001c2
+#define OP_CRNOR			0x4c000042
+#define OP_CREQV			0x4c000242
+#define OP_CMPW				0x7c000000
+#define OP_CMPLW			0x7c000040
+#define OP_CMPWI			0x2c000000
+#define OP_CMPLWI			0x28000000
+#define OP_MULLW			0x7c0001d6
+#define OP_MULHW			0x7c000096
+#define OP_MULHWU			0x7c000016
+#define OP_DIVW				0x7c0003d6
+#define OP_DIVWU			0x7c000396
+#define OP_OR				0x7c000378
+#define OP_ORC				0x7c000338
+#define OP_XOR				0x7c000278
+#define OP_NAND				0x7c0003b8
+#define OP_NOR				0x7c0000f8
+#define OP_EQV				0x7c000238
+#define OP_SLW				0x7c000030
+#define OP_SRW				0x7c000430
+#define OP_SRAW				0x7c000630
+#define OP_ORI				0x60000000
+#define OP_ORIS				0x64000000
+#define OP_XORI				0x68000000
+#define OP_XORIS			0x6c000000
+#define OP_ANDI_			0x70000000
+#define OP_ANDIS_			0x74000000
+#define OP_SRAWI			0x7c000670
+#define OP_RLWINM			0x54000000
+#define OP_RLWNM			0x5c000000
+#define OP_RLWIMI			0x50000000
+#define OP_LWZ				0x80000000
+#define OP_LHZ				0xa0000000
+#define OP_LHA				0xa8000000
+#define OP_LBZ				0x88000000
+#define OP_LWZU				0x84000000
+#define OP_LHZU				0xa4000000
+#define OP_LHAU				0xac000000
+#define OP_LBZU				0x8c000000
+#define OP_LWZX				0x7c00002e
+#define OP_LHZX				0x7c00022e
+#define OP_LHAX				0x7c0002ae
+#define OP_LBZX				0x7c0000ae
+#define OP_LWZUX			0x7c00006e
+#define OP_LHZUX			0x7c00026e
+#define OP_LHAUX			0x7c0002ee
+#define OP_LBZUX			0x7c0000ee
+#define OP_STW				0x90000000
+#define OP_STH				0xb0000000
+#define OP_STB				0x98000000
+#define OP_STWU				0x94000000
+#define OP_STHU				0xb4000000
+#define OP_STBU				0x9c000000
+#define OP_STWX				0x7c00012e
+#define OP_STHX				0x7c00032e
+#define OP_STBX				0x7c0001ae
+#define OP_STWUX			0x7c00016e
+#define OP_STHUX			0x7c00036e
+#define OP_STBUX			0x7c0001ee
+#define OP_B				0x48000000
+#define OP_BL				0x48000001
+#define OP_BC				0x40000000
+#define OP_BCL				0x40000001
+#define OP_MTLR				0x7c0803a6
+#define OP_MFLR				0x7c0802a6
+#define OP_MTCTR			0x7c0903a6
+#define OP_MFCTR			0x7c0902a6
+#define OP_LMW				0xb8000000
+#define OP_STMW				0xbc000000
+#define OP_LSWI				0x7c0004aa
+#define OP_LSWX				0x7c00042a
+#define OP_STSWI			0x7c0005aa
+#define OP_STSWX			0x7c00052a
+
+#define ASM_0(opcode)			(opcode)
+#define ASM_1(opcode, rd)		((opcode) +		\
+	                                 ((rd) << 21))
+#define ASM_1C(opcode, cr)		((opcode) +		\
+	                                 ((cr) << 23))
+#define ASM_11(opcode, rd, rs)		((opcode) +		\
+	                                 ((rd) << 21) +		\
+					 ((rs) << 16))
+#define ASM_11C(opcode, cd, cs)		((opcode) +		\
+	                                 ((cd) << 23) +		\
+					 ((cs) << 18))
+#define ASM_11X(opcode, rd, rs)		((opcode) +		\
+	                                 ((rs) << 21) +		\
+					 ((rd) << 16))
+#define ASM_11I(opcode, rd, rs, simm)	((opcode) +		\
+	                                 ((rd) << 21) +		\
+					 ((rs) << 16) +		\
+					 ((simm) & 0xffff))
+#define ASM_11IF(opcode, rd, rs, simm)	((opcode) +		\
+	                                 ((rd) << 21) +		\
+					 ((rs) << 16) +		\
+					 ((simm) << 11))
+#define ASM_11S(opcode, rd, rs, sh)	((opcode) +		\
+	                                 ((rs) << 21) +		\
+					 ((rd) << 16) +		\
+					 ((sh) << 11))
+#define ASM_11IX(opcode, rd, rs, imm)	((opcode) +		\
+	                                 ((rs) << 21) +		\
+					 ((rd) << 16) +		\
+					 ((imm) & 0xffff))
+#define ASM_12(opcode, rd, rs1, rs2)	((opcode) +		\
+	                                 ((rd) << 21) +		\
+					 ((rs1) << 16) +	\
+					 ((rs2) << 11))
+#define ASM_12F(opcode, fd, fs1, fs2)	((opcode) +		\
+	                                 ((fd) << 21) +		\
+					 ((fs1) << 16) +	\
+					 ((fs2) << 11))
+#define ASM_12X(opcode, rd, rs1, rs2)	((opcode) +		\
+	                                 ((rs1) << 21) +	\
+					 ((rd) << 16) +		\
+					 ((rs2) << 11))
+#define ASM_2C(opcode, cr, rs1, rs2)	((opcode) +		\
+	                                 ((cr) << 23) +		\
+					 ((rs1) << 16) +	\
+					 ((rs2) << 11))
+#define ASM_1IC(opcode, cr, rs, imm)	((opcode) +		\
+	                                 ((cr) << 23) +		\
+					 ((rs) << 16) +		\
+					 ((imm) & 0xffff))
+#define ASM_122(opcode, rd, rs1, rs2, imm1, imm2)		\
+					((opcode) +		\
+	                                 ((rs1) << 21) +	\
+					 ((rd) << 16) +		\
+					 ((rs2) << 11) +	\
+					 ((imm1) << 6) +	\
+					 ((imm2) << 1))
+#define ASM_113(opcode, rd, rs, imm1, imm2, imm3)		\
+					((opcode) +		\
+	                                 ((rs) << 21) +		\
+					 ((rd) << 16) +		\
+					 ((imm1) << 11) +	\
+					 ((imm2) << 6) +	\
+					 ((imm3) << 1))
+#define ASM_1O(opcode, off)		((opcode) + (off))
+#define ASM_3O(opcode, bo, bi, off)	((opcode) + 		\
+					 ((bo) << 21) +		\
+					 ((bi) << 16) +		\
+					 (off))
+
+#define ASM_ADDI(rd, rs, simm)		ASM_11I(OP_ADDI, rd, rs, simm)
+#define ASM_BLR				ASM_0(OP_BLR)
+#define ASM_STW(rd, rs, simm)		ASM_11I(OP_STW, rd, rs, simm)
+#define ASM_LWZ(rd, rs, simm)		ASM_11I(OP_LWZ, rd, rs, simm)
+#define ASM_MFCR(rd)			ASM_1(OP_MFCR, rd)
+#define ASM_MTCR(rd)			ASM_1(OP_MTCR, rd)
+#define ASM_MFXER(rd)			ASM_1(OP_MFXER, rd)
+#define ASM_MTXER(rd)			ASM_1(OP_MTXER, rd)
+#define ASM_MFCTR(rd)			ASM_1(OP_MFCTR, rd)
+#define ASM_MTCTR(rd)			ASM_1(OP_MTCTR, rd)
+#define ASM_MCRXR(cr)			ASM_1C(OP_MCRXR, cr)
+#define ASM_MCRF(cd, cs)		ASM_11C(OP_MCRF, cd, cs)
+#define ASM_B(off)			ASM_1O(OP_B, off)
+#define ASM_BL(off)			ASM_1O(OP_BL, off)
+#define ASM_MFLR(rd)			ASM_1(OP_MFLR, rd)
+#define ASM_MTLR(rd)			ASM_1(OP_MTLR, rd)
+#define ASM_LI(rd, imm)			ASM_ADDI(rd, 0, imm)
+#define ASM_LMW(rd, rs, simm)		ASM_11I(OP_LMW, rd, rs, simm)
+#define ASM_STMW(rd, rs, simm)		ASM_11I(OP_STMW, rd, rs, simm)
+#define ASM_LSWI(rd, rs, simm)		ASM_11IF(OP_LSWI, rd, rs, simm)
+#define ASM_LSWX(rd, rs1, rs2)		ASM_12(OP_LSWX, rd, rs1, rs2)
+#define ASM_STSWI(rd, rs, simm)		ASM_11IF(OP_STSWI, rd, rs, simm)
+#define ASM_STSWX(rd, rs1, rs2)		ASM_12(OP_STSWX, rd, rs1, rs2)
+
+
+#endif /* _CPU_ASM_H */
diff --git a/post/lib_ppc/cr.c b/post/lib_ppc/cr.c
new file mode 100644
index 0000000..da6ef37
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/load.c b/post/lib_ppc/load.c
new file mode 100644
index 0000000..393c568
--- /dev/null
+++ b/post/lib_ppc/load.c
@@ -0,0 +1,255 @@
+/*
+ * (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
+ * Load instructions:		lbz(x)(u), lhz(x)(u), lha(x)(u), lwz(x)(u)
+ *
+ * All operations are performed on a 16-byte array. The array
+ * is 4-byte aligned. The base register points to offset 8.
+ * The immediate offset (index register) ranges in [-8 ... +7].
+ * The test cases are composed so that they do not
+ * cause alignment exceptions.
+ * The test contains a pre-built table describing all test cases.
+ * The table entry contains:
+ * the instruction opcode, the array contents, the value of the index
+ * register and the expected value of the destination register.
+ * After executing the instruction, the test verifies the
+ * value of the destination register and the value of the base
+ * register (it must change for "load with update" instructions).
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22w (ulong *code, ulong *op1, ulong op2, ulong *op3);
+extern void cpu_post_exec_21w (ulong *code, ulong *op1, ulong *op2);
+
+static struct cpu_post_load_s
+{
+    ulong cmd;
+    uint width;
+    int update;
+    int index;
+    ulong offset;
+} cpu_post_load_table[] =
+{
+    {
+	OP_LWZ,
+	4,
+	0,
+	0,
+	4
+    },
+    {
+	OP_LHA,
+	3,
+	0,
+	0,
+	2
+    },
+    {
+	OP_LHZ,
+	2,
+	0,
+	0,
+	2
+    },
+    {
+	OP_LBZ,
+	1,
+	0,
+	0,
+	1
+    },
+    {
+	OP_LWZU,
+	4,
+	1,
+	0,
+	4
+    },
+    {
+	OP_LHAU,
+	3,
+	1,
+	0,
+	2
+    },
+    {
+	OP_LHZU,
+	2,
+	1,
+	0,
+	2
+    },
+    {
+	OP_LBZU,
+	1,
+	1,
+	0,
+	1
+    },
+    {
+	OP_LWZX,
+	4,
+	0,
+	1,
+	4
+    },
+    {
+	OP_LHAX,
+	3,
+	0,
+	1,
+	2
+    },
+    {
+	OP_LHZX,
+	2,
+	0,
+	1,
+	2
+    },
+    {
+	OP_LBZX,
+	1,
+	0,
+	1,
+	1
+    },
+    {
+	OP_LWZUX,
+	4,
+	1,
+	1,
+	4
+    },
+    {
+	OP_LHAUX,
+	3,
+	1,
+	1,
+	2
+    },
+    {
+	OP_LHZUX,
+	2,
+	1,
+	1,
+	2
+    },
+    {
+	OP_LBZUX,
+	1,
+	1,
+	1,
+	1
+    },
+};
+static unsigned int cpu_post_load_size =
+    sizeof (cpu_post_load_table) / sizeof (struct cpu_post_load_s);
+
+int cpu_post_test_load (void)
+{
+    int ret = 0;
+    unsigned int i;
+
+    for (i = 0; i < cpu_post_load_size && ret == 0; i++)
+    {
+	struct cpu_post_load_s *test = cpu_post_load_table + i;
+	uchar data[16] =
+	{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+	ulong base0 = (ulong) (data + 8);
+	ulong base = base0;
+	ulong value;
+
+	if (test->index)
+	{
+	    ulong code[] =
+	    {
+		ASM_12(test->cmd, 5, 3, 4),
+		ASM_BLR,
+	    };
+
+	    cpu_post_exec_22w (code, &base, test->offset, &value);
+	}
+	else
+	{
+	    ulong code[] =
+	    {
+		ASM_11I(test->cmd, 4, 3, test->offset),
+		ASM_BLR,
+	    };
+
+	    cpu_post_exec_21w (code, &base, &value);
+	}
+
+	if (ret == 0)
+	{
+	   if (test->update)
+	       ret = base == base0 + test->offset ? 0 : -1;
+	   else
+	       ret = base == base0 ? 0 : -1;
+	}
+
+	if (ret == 0)
+	{
+	    switch (test->width)
+	    {
+	    case 1:
+		ret = *(uchar *)(base0 + test->offset) == value ?
+		      0 : -1;
+		break;
+	    case 2:
+		ret = *(ushort *)(base0 + test->offset) == value ?
+		      0 : -1;
+		break;
+	    case 3:
+		ret = *(short *)(base0 + test->offset) == value ?
+		      0 : -1;
+		break;
+	    case 4:
+		ret = *(ulong *)(base0 + test->offset) == value ?
+		      0 : -1;
+		break;
+	    }
+	}
+
+	if (ret != 0)
+	{
+	    post_log ("Error at load test %d !\n", i);
+	}
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/multi.c b/post/lib_ppc/multi.c
new file mode 100644
index 0000000..8724384
--- /dev/null
+++ b/post/lib_ppc/multi.c
@@ -0,0 +1,81 @@
+/*
+ * (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
+ * Load/store multiple word instructions:	lmw, stmw
+ *
+ * 26 consecutive words are loaded from a source memory buffer
+ * into GPRs r6 through r31. After that, 26 consecutive words are stored
+ * from the GPRs r6 through r31 into a target memory buffer. The contents
+ * of the source and target buffers are then compared.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2);
+
+int cpu_post_test_multi (void)
+{
+    int ret = 0;
+    unsigned int i;
+
+    if (ret == 0)
+    {
+	ulong src [26], dst [26];
+
+	ulong code[] =
+	{
+	    ASM_LMW(5, 3, 0),
+	    ASM_STMW(5, 4, 0),
+	    ASM_BLR,
+	};
+
+	for (i = 0; i < sizeof(src) / sizeof(src[0]); i ++)
+	{
+	    src[i] = i;
+	    dst[i] = 0;
+	}
+
+	cpu_post_exec_02(code, (ulong)src, (ulong)dst);
+
+	ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
+    }
+
+    if (ret != 0)
+    {
+	post_log ("Error at multi test !\n");
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/rlwimi.c b/post/lib_ppc/rlwimi.c
new file mode 100644
index 0000000..f65f79a
--- /dev/null
+++ b/post/lib_ppc/rlwimi.c
@@ -0,0 +1,162 @@
+/*
+ * (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
+ * Shift instructions:		rlwimi
+ *
+ * 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_rlwimi_s
+{
+    ulong cmd;
+    ulong op0;
+    ulong op1;
+    uchar op2;
+    uchar mb;
+    uchar me;
+    ulong res;
+} cpu_post_rlwimi_table[] =
+{
+    {
+    	OP_RLWIMI,
+	0xff00ffff,
+	0x0000aa00,
+	8,
+	8,
+	15,
+	0xffaaffff
+    },
+};
+static unsigned int cpu_post_rlwimi_size =
+    sizeof (cpu_post_rlwimi_table) / sizeof (struct cpu_post_rlwimi_s);
+
+int cpu_post_test_rlwimi (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_rlwimi_size && ret == 0; i++)
+    {
+	struct cpu_post_rlwimi_s *test = cpu_post_rlwimi_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, -20),
+		ASM_STW(3, stk, 8),
+		ASM_STW(4, stk, 12),
+		ASM_STW(reg0, stk, 4),
+		ASM_STW(reg1, stk, 0),
+		ASM_LWZ(reg1, stk, 8),
+		ASM_LWZ(reg0, stk, 12),
+		ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me),
+		ASM_STW(reg1, stk, 8),
+		ASM_LWZ(reg1, stk, 0),
+		ASM_LWZ(reg0, stk, 4),
+		ASM_LWZ(3, stk, 8),
+		ASM_ADDI(1, stk, 20),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+    	    unsigned long codecr[] =
+	    {
+		ASM_STW(stk, 1, -4),
+		ASM_ADDI(stk, 1, -20),
+		ASM_STW(3, stk, 8),
+		ASM_STW(4, stk, 12),
+		ASM_STW(reg0, stk, 4),
+		ASM_STW(reg1, stk, 0),
+		ASM_LWZ(reg1, stk, 8),
+		ASM_LWZ(reg0, stk, 12),
+		ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me) |
+		    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, 20),
+		ASM_LWZ(stk, 1, -4),
+		ASM_BLR,
+	    };
+	    ulong res;
+	    ulong cr;
+
+	    if (ret == 0)
+	    {
+ 	    	cr = 0;
+	    	cpu_post_exec_22 (code, & cr, & res, test->op0, test->op1);
+
+	    	ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at rlwimi test %d !\n", i);
+	    	}
+	    }
+
+	    if (ret == 0)
+	    {
+	    	cpu_post_exec_22 (codecr, & cr, & res, test->op0, test->op1);
+
+	    	ret = res == test->res &&
+		      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at rlwimi test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/rlwinm.c b/post/lib_ppc/rlwinm.c
new file mode 100644
index 0000000..e240c41
--- /dev/null
+++ b/post/lib_ppc/rlwinm.c
@@ -0,0 +1,155 @@
+/*
+ * (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
+ * Shift instructions:		rlwinm
+ *
+ * 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_rlwinm_s
+{
+    ulong cmd;
+    ulong op1;
+    uchar op2;
+    uchar mb;
+    uchar me;
+    ulong res;
+} cpu_post_rlwinm_table[] =
+{
+   {
+   	OP_RLWINM,
+	0xffff0000,
+	24,
+	16,
+	23,
+	0x0000ff00
+   },
+};
+static unsigned int cpu_post_rlwinm_size =
+    sizeof (cpu_post_rlwinm_table) / sizeof (struct cpu_post_rlwinm_s);
+
+int cpu_post_test_rlwinm (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_rlwinm_size && ret == 0; i++)
+    {
+	struct cpu_post_rlwinm_s *test = cpu_post_rlwinm_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_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me),
+		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_113(test->cmd, reg1, reg0, test->op2, test->mb,
+		    test->me) | 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->op1);
+
+	    	ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at rlwinm test %d !\n", i);
+	    	}
+	    }
+
+	    if (ret == 0)
+	    {
+	    	cpu_post_exec_21 (codecr, & cr, & res, test->op1);
+
+	    	ret = res == test->res &&
+		      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at rlwinm test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/rlwnm.c b/post/lib_ppc/rlwnm.c
new file mode 100644
index 0000000..523cf4d
--- /dev/null
+++ b/post/lib_ppc/rlwnm.c
@@ -0,0 +1,165 @@
+/*
+ * (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
+ * Shift instructions:		rlwnm
+ *
+ * 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_rlwnm_s
+{
+    ulong cmd;
+    ulong op1;
+    ulong op2;
+    uchar mb;
+    uchar me;
+    ulong res;
+} cpu_post_rlwnm_table[] =
+{
+   {
+   	OP_RLWNM,
+	0xffff0000,
+	24,
+	16,
+	23,
+	0x0000ff00
+   },
+};
+static unsigned int cpu_post_rlwnm_size =
+    sizeof (cpu_post_rlwnm_table) / sizeof (struct cpu_post_rlwnm_s);
+
+int cpu_post_test_rlwnm (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_rlwnm_size && ret == 0; i++)
+    {
+	struct cpu_post_rlwnm_s *test = cpu_post_rlwnm_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_122(test->cmd, reg2, reg1, reg0, test->mb, test->me),
+		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_122(test->cmd, reg2, reg1, reg0, test->mb, test->me) |
+		    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 rlwnm 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 rlwnm test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/srawi.c b/post/lib_ppc/srawi.c
new file mode 100644
index 0000000..91c82c9
--- /dev/null
+++ b/post/lib_ppc/srawi.c
@@ -0,0 +1,156 @@
+/*
+ * (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
+ * Shift instructions:		srawi
+ *
+ * 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_srawi_s
+{
+    ulong cmd;
+    ulong op1;
+    uchar op2;
+    ulong res;
+} cpu_post_srawi_table[] =
+{
+    {
+    	OP_SRAWI,
+	0x8000,
+	3,
+	0x1000
+    },
+    {
+    	OP_SRAWI,
+	0x80000000,
+	3,
+	0xf0000000
+    },
+};
+static unsigned int cpu_post_srawi_size =
+    sizeof (cpu_post_srawi_table) / sizeof (struct cpu_post_srawi_s);
+
+int cpu_post_test_srawi (void)
+{
+    int ret = 0;
+    unsigned int i, reg;
+    int flag = disable_interrupts();
+
+    for (i = 0; i < cpu_post_srawi_size && ret == 0; i++)
+    {
+	struct cpu_post_srawi_s *test = cpu_post_srawi_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_11S(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,
+	    };
+    	    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_11S(test->cmd, reg1, reg0, test->op2) | 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->op1);
+
+	    	ret = res == test->res && cr == 0 ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at srawi test %d !\n", i);
+	    	}
+	    }
+
+	    if (ret == 0)
+	    {
+	    	cpu_post_exec_21 (codecr, & cr, & res, test->op1);
+
+	    	ret = res == test->res &&
+		      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+	    	if (ret != 0)
+	    	{
+	            post_log ("Error at srawi test %d !\n", i);
+	        }
+	    }
+	}
+    }
+
+    if (flag)
+    	enable_interrupts();
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/store.c b/post/lib_ppc/store.c
new file mode 100644
index 0000000..f495bf2
--- /dev/null
+++ b/post/lib_ppc/store.c
@@ -0,0 +1,235 @@
+/*
+ * (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
+ * Store instructions:		stb(x)(u), sth(x)(u), stw(x)(u)
+ *
+ * All operations are performed on a 16-byte array. The array
+ * is 4-byte aligned. The base register points to offset 8.
+ * The immediate offset (index register) ranges in [-8 ... +7].
+ * The test cases are composed so that they do not
+ * cause alignment exceptions.
+ * The test contains a pre-built table describing all test cases.
+ * The table entry contains:
+ * the instruction opcode, the value of the index register and
+ * the value of the source register. After executing the
+ * instruction, the test verifies the contents of the array
+ * and the value of the base register (it must change for "store
+ * with update" instructions).
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_12w (ulong *code, ulong *op1, ulong op2, ulong op3);
+extern void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2);
+
+static struct cpu_post_store_s
+{
+    ulong cmd;
+    uint width;
+    int update;
+    int index;
+    ulong offset;
+    ulong value;
+} cpu_post_store_table[] =
+{
+    {
+	OP_STW,
+	4,
+	0,
+	0,
+	-4,
+	0xff00ff00
+    },
+    {
+	OP_STH,
+	2,
+	0,
+	0,
+	-2,
+	0xff00
+    },
+    {
+	OP_STB,
+	1,
+	0,
+	0,
+	-1,
+	0xff
+    },
+    {
+	OP_STWU,
+	4,
+	1,
+	0,
+	-4,
+	0xff00ff00
+    },
+    {
+	OP_STHU,
+	2,
+	1,
+	0,
+	-2,
+	0xff00
+    },
+    {
+	OP_STBU,
+	1,
+	1,
+	0,
+	-1,
+	0xff
+    },
+    {
+	OP_STWX,
+	4,
+	0,
+	1,
+	-4,
+	0xff00ff00
+    },
+    {
+	OP_STHX,
+	2,
+	0,
+	1,
+	-2,
+	0xff00
+    },
+    {
+	OP_STBX,
+	1,
+	0,
+	1,
+	-1,
+	0xff
+    },
+    {
+	OP_STWUX,
+	4,
+	1,
+	1,
+	-4,
+	0xff00ff00
+    },
+    {
+	OP_STHUX,
+	2,
+	1,
+	1,
+	-2,
+	0xff00
+    },
+    {
+	OP_STBUX,
+	1,
+	1,
+	1,
+	-1,
+	0xff
+    },
+};
+static unsigned int cpu_post_store_size =
+    sizeof (cpu_post_store_table) / sizeof (struct cpu_post_store_s);
+
+int cpu_post_test_store (void)
+{
+    int ret = 0;
+    unsigned int i;
+
+    for (i = 0; i < cpu_post_store_size && ret == 0; i++)
+    {
+	struct cpu_post_store_s *test = cpu_post_store_table + i;
+	uchar data[16] =
+	{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+	ulong base0 = (ulong) (data + 8);
+	ulong base = base0;
+
+	if (test->index)
+	{
+	    ulong code[] =
+	    {
+		ASM_12(test->cmd, 5, 3, 4),
+		ASM_BLR,
+	    };
+
+	    cpu_post_exec_12w (code, &base, test->offset, test->value);
+	}
+	else
+	{
+	    ulong code[] =
+	    {
+		ASM_11I(test->cmd, 4, 3, test->offset),
+		ASM_BLR,
+	    };
+
+	    cpu_post_exec_11w (code, &base, test->value);
+	}
+
+	if (ret == 0)
+	{
+	   if (test->update)
+	       ret = base == base0 + test->offset ? 0 : -1;
+	   else
+	       ret = base == base0 ? 0 : -1;
+	}
+
+	if (ret == 0)
+	{
+	    switch (test->width)
+	    {
+	    case 1:
+		ret = *(uchar *)(base0 + test->offset) == test->value ?
+		      0 : -1;
+		break;
+	    case 2:
+		ret = *(ushort *)(base0 + test->offset) == test->value ?
+		      0 : -1;
+		break;
+	    case 4:
+		ret = *(ulong *)(base0 + test->offset) == test->value ?
+		      0 : -1;
+		break;
+	    }
+	}
+
+	if (ret != 0)
+	{
+	    post_log ("Error at store test %d !\n", i);
+	}
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/string.c b/post/lib_ppc/string.c
new file mode 100644
index 0000000..bd83bd1
--- /dev/null
+++ b/post/lib_ppc/string.c
@@ -0,0 +1,106 @@
+/*
+ * (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
+ * Load/store string instructions:	lswi, stswi, lswx, stswx
+ *
+ * Several consecutive bytes from a source memory buffer are loaded
+ * left to right into GPRs. After that, the bytes are stored
+ * from the GPRs into a target memory buffer. The contents
+ * of the source and target buffers are then compared.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2);
+extern void cpu_post_exec_04 (ulong *code, ulong op1, ulong op2, ulong op3,
+    ulong op4);
+
+#include <bedbug/regs.h>
+int cpu_post_test_string (void)
+{
+    int ret = 0;
+    unsigned int i;
+
+    if (ret == 0)
+    {
+	char src [31], dst [31];
+
+	ulong code[] =
+	{
+	    ASM_LSWI(5, 3, 31),
+	    ASM_STSWI(5, 4, 31),
+	    ASM_BLR,
+	};
+
+	for (i = 0; i < sizeof(src); i ++)
+	{
+	    src[i] = (char) i;
+	    dst[i] = 0;
+	}
+
+	cpu_post_exec_02(code, (ulong)src, (ulong)dst);
+
+	ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
+    }
+
+    if (ret == 0)
+    {
+	char src [95], dst [95];
+
+	ulong code[] =
+	{
+	    ASM_LSWX(8, 3, 5),
+	    ASM_STSWX(8, 4, 5),
+	    ASM_BLR,
+	};
+
+	for (i = 0; i < sizeof(src); i ++)
+	{
+	    src[i] = (char) i;
+	    dst[i] = 0;
+	}
+
+	cpu_post_exec_04(code, (ulong)src, (ulong)dst, 0, sizeof(src));
+
+	ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
+    }
+
+    if (ret != 0)
+    {
+	post_log ("Error at string test !\n");
+    }
+
+    return ret;
+}
+
+#endif
+#endif
diff --git a/post/lib_ppc/three.c b/post/lib_ppc/three.c
new file mode 100644
index 0000000..c2d7476
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/threei.c b/post/lib_ppc/threei.c
new file mode 100644
index 0000000..79f0178
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/threex.c b/post/lib_ppc/threex.c
new file mode 100644
index 0000000..2c72063
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/two.c b/post/lib_ppc/two.c
new file mode 100644
index 0000000..cfbac5e
--- /dev/null
+++ b/post/lib_ppc/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/lib_ppc/twox.c b/post/lib_ppc/twox.c
new file mode 100644
index 0000000..48d9954
--- /dev/null
+++ b/post/lib_ppc/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/post.c b/post/post.c
index e1066da..ac41990 100644
--- a/post/post.c
+++ b/post/post.c
@@ -430,6 +430,7 @@
 #ifdef CONFIG_PPC
 	return (unsigned long)get_ticks () / (get_tbclk () / CFG_HZ) - base;
 #else
+#warning "Not implemented yet"
 	return 0; /* Not implemented yet */
 #endif
 }