Merge with /home/wd/git/u-boot/custodian/u-boot-mpc83xx
diff --git a/CHANGELOG b/CHANGELOG
index 6e26105..02b3664 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,172 @@
+commit 00cdb4ce5e1b42248e7e6522ad0da3421b988afa
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Mar 8 10:13:16 2007 +0100
+
+    [PATCH] Update AMCC Luan 440SP eval board support
+
+    The AMCC Luan now uses the common 440SP(e) DDR SPD code for DDR
+    inititializition. This includes DDR auto calibration and support
+    for different DIMM modules, instead of the fixed setup used in
+    the earlier version.
+
+    This patch also enables the cache in FLASH for the startup
+    phase of U-Boot (while running from FLASH). After relocating to
+    SDRAM the cache is disabled again. This will speed up the boot
+    process, especially the SDRAM setup, since there are some loops
+    for memory testing (auto calibration).
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 2f5df47351910a2936c7741cf111855829200943
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Mar 8 10:10:18 2007 +0100
+
+    [PATCH] Update AMCC Yucca 440SPe eval board support
+
+    The AMCC Yucca now uses the common 440SP(e) DDR SPD code for DDR
+    inititializition. This includes DDR auto calibration and support
+    for different DIMM modules, instead of the fixed setup used in
+    the earlier version.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 2721a68a9ea91f1e494649ce68b2577261f578e2
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Mar 8 10:07:18 2007 +0100
+
+    ppc4xx: Small AMCC Katmai 440SPe update
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit df294497479b1dca6dd86318b2a912f72fede0df
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Mar 8 10:06:09 2007 +0100
+
+    ppc4xx: Update 440SP/440SPe DDR SPD setup code to support 440SP
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit fa1aef15bcd47736687be1af544506e90fba545d
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Mar 7 16:43:00 2007 +0100
+
+    [PATCH] Use dynamic SDRAM TLB setup on AMCC Ocotea eval board
+
+    Define CONFIG_PROG_SDRAM_TLB so that the TLB entries for the
+    DDR memory are dynamically programmed matching the total size
+    of the equipped memory (DIMM modules).
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit e2ebe696818939e2b974628be9c921ea3fe9de13
+Author: Stefan Roese <sr@denx.de>
+Date:	Wed Mar 7 16:39:36 2007 +0100
+
+    [PATCH] Fix AMCC 44x SPD SDRAM init code to support 2 DIMM's
+
+    This patch fixes a problem that occurs when 2 DIMM's are
+    used. This problem was first spotted and fixed by Gerald Jackson
+    <gerald.jackson@reaonixsecurity.com> but this patch fixes the
+    problem in a little more clever way.
+
+    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.
+
+    As this feature is new to the "old" 44x SPD DDR driver, it
+    has to be enabled via the CONFIG_PROG_SDRAM_TLB define.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 39218433983417b9df087976a79e3f80dd5e83d6
+Author: Wolfgang Denk <wd@denx.de>
+Date:	Wed Mar 7 16:33:44 2007 +0100
+
+    UC101: fix compiler warnings
+
+commit 8d7e2732221bc2d64df14f700c64c23e0a4c3dce
+Author: Wolfgang Denk <wd@pollux.denx.de>
+Date:	Wed Mar 7 16:19:46 2007 +0100
+
+    HMI1001: fix build error, cleanup compiler warnings.
+
+commit ad5bb451ade552c44bef9119d907929ebc2c126f
+Author: Wolfgang Denk <wd@pollux.denx.de>
+Date:	Tue Mar 6 18:08:43 2007 +0100
+
+    Restructure POST directory to support of other CPUs, boards, etc.
+
+commit a5284efd125967675b2e9c6ef7b95832268ad360
+Author: Wolfgang Denk <wd@pollux.denx.de>
+Date:	Tue Mar 6 18:01:47 2007 +0100
+
+    Fix HOSTARCH handling.
+    Patch by Mike Frysinger, Mar 05 2007
+
+commit 07b7b0037aac5102939917d7cbe561b5c0d5aa44
+Author: Stefan Roese <sr@denx.de>
+Date:	Tue Mar 6 07:47:04 2007 +0100
+
+    [PATCH] Speed optimization of AMCC Sequoia/Rainier DDR2 setup
+
+    As provided by the AMCC applications team, this patch optimizes the
+    DDR2 setup for 166MHz bus speed. The values provided are also save
+    to use on a "normal" 133MHz PLB bus system. Only the refresh counter
+    setup has to be adjusted as done in this patch.
+
+    For this the NAND booting version had to include the "speed.c" file
+    from the cpu/ppc4xx directory. With this addition the NAND SPL image
+    will just fit into the 4kbytes of program space. gcc version 4.x as
+    provided with ELDK 4.x is needed to generate this optimized code.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit ba58e4c9a9a917ce795dd16d4ec8d515f9f7aa35
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Mar 1 21:11:36 2007 +0100
+
+    [PATCH] Update AMCC Katmai 440SPe eval board support
+
+    This patch updates the recently added Katmai board support. The biggest
+    change is the support of ECC DIMM modules in the 440SP(e) SPD DDR2
+    driver.
+
+    Please note, that still some problems are left with some memory
+    configurations. See the driver for more details.
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 8c12045a3b06c5b6675d3fe02fbc9f545988129a
+Author: Stefan Roese <sr@denx.de>
+Date:	Thu Mar 1 07:03:25 2007 +0100
+
+    [PATCH] I2C: Add missing default CFG_RTC_BUS_NUM & CFG_DTT_BUS_NUM
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit ccbc7036648e465697ca298ba51e0e76dda352a0
+Author: Wolfgang Denk <wd@pollux.denx.de>
+Date:	Wed Feb 28 01:28:53 2007 +0100
+
+    SC3: fix typo in default environment
+
+commit e344568b1b46af85ec32d815586f91bc115d6223
+Author: Sergei Poselenov <sposelenov@emcraft.com>
+Date:	Tue Feb 27 20:15:30 2007 +0300
+
+    MCC200: Fixes for update procedure
+
+    - fix logic error in image type handling
+    - make sure file system images (cramfs etc.) get stored in flash
+      with image header stripped so they can be mounted through MTD
+
+commit 743571145b37182757d4e688a77860b36ee77573
+Author: Wolfgang Denk <wd@pollux.denx.de>
+Date:	Tue Feb 27 14:26:04 2007 +0100
+
+    Minor code cleanup.
+
 commit 638dd1458bbdc2a55d4b9e25c5c4e1f838a5dc72
 Author: Sergei Poselenov <sposelenov@emcraft.com>
 Date:	Tue Feb 27 12:40:16 2007 +0300
@@ -293,6 +462,14 @@
 
     Signed-off-by: Stefan Roese <sr@denx.de>
 
+commit 2605e90bf676d48123afe5719a846d2b52b24aac
+Author: Heiko Schocher <hs@pollux.denx.de>
+Date:	Fri Feb 16 07:57:42 2007 +0100
+
+    [PATCH] Added support for the jupiter board.
+
+    Signed-off-by: Heiko Schocher <hs@denx.de>
+
 commit 497d012e5be0194e1084073d0081eb1a844796b2
 Author: Gary Jennejohn <garyj@pollux.denx.de>
 Date:	Mon Feb 12 13:11:50 2007 +0100
diff --git a/Makefile b/Makefile
index 47008ee..29180f3 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)
@@ -411,6 +412,9 @@
 		}
 	@$(MKCONFIG) -a IceCube ppc mpc5xxx icecube
 
+jupiter_config:         unconfig
+	@$(MKCONFIG) jupiter ppc mpc5xxx jupiter
+
 v38b_config: unconfig
 	@./mkconfig -a v38b ppc mpc5xxx v38b
 
diff --git a/board/amcc/katmai/init.S b/board/amcc/katmai/init.S
index f5900bc..6b024ee 100644
--- a/board/amcc/katmai/init.S
+++ b/board/amcc/katmai/init.S
@@ -46,6 +46,11 @@
 	.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)
 
 	/*
@@ -81,6 +86,11 @@
 	.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)
 
 	/*
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
-
-    /* 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 )
+	/* 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)
+
+	/*
+	 * 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)
 
-	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)
+	/*
+	 * 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/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/jupiter/Makefile b/board/jupiter/Makefile
new file mode 100644
index 0000000..aed3af0
--- /dev/null
+++ b/board/jupiter/Makefile
@@ -0,0 +1,51 @@
+
+#
+# (C) Copyright 2003-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
+#
+
+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/jupiter/config.mk b/board/jupiter/config.mk
new file mode 100644
index 0000000..5f4da96
--- /dev/null
+++ b/board/jupiter/config.mk
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2007
+# Heiko Schocher, DENX Software Engineering, hs@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
+#
+
+#
+# Jupiter board:
+#
+#	Valid values for TEXT_BASE are:
+#
+#	0xFFF00000   boot high (standard configuration)
+#	0x00100000   boot from RAM (for testing only)
+#
+
+ifndef TEXT_BASE
+## Standard: boot high
+TEXT_BASE = 0xFFF00000
+## For testing: boot from RAM
+# TEXT_BASE = 0x00100000
+endif
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
+#PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -DDEBUG -I$(TOPDIR)/board
diff --git a/board/jupiter/jupiter.c b/board/jupiter/jupiter.c
new file mode 100644
index 0000000..04fda4a
--- /dev/null
+++ b/board/jupiter/jupiter.c
@@ -0,0 +1,317 @@
+/*
+ * (C) Copyright 2007
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc5xxx.h>
+#include <pci.h>
+#include <asm/processor.h>
+
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+
+#define SDRAM_DDR	0
+#if 1
+/* Settings Icecube */
+#define SDRAM_MODE	0x00CD0000
+#define SDRAM_CONTROL	0x504F0000
+#define SDRAM_CONFIG1	0xD2322800
+#define SDRAM_CONFIG2	0x8AD70000
+#else
+/*Settings Jupiter UB 1.0.0 */
+#define SDRAM_MODE	0x008D0000
+#define SDRAM_CONTROL	0xD04F0000
+#define SDRAM_CONFIG1	0xf7277f00
+#define SDRAM_CONFIG2	0x88b70004
+#endif
+
+#ifndef CFG_RAMBOOT
+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;
+	__asm__ volatile ("sync");
+
+	/* precharge all banks */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
+	__asm__ volatile ("sync");
+
+#if SDRAM_DDR
+	/* set mode register: extended mode */
+	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
+	__asm__ volatile ("sync");
+
+	/* set mode register: reset DLL */
+	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
+	__asm__ volatile ("sync");
+#endif
+
+	/* precharge all banks */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
+	__asm__ volatile ("sync");
+
+	/* auto refresh */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
+	__asm__ volatile ("sync");
+
+	/* set mode register */
+	*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
+	__asm__ volatile ("sync");
+
+	/* normal operation */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
+	__asm__ volatile ("sync");
+}
+#endif
+
+/*
+ * ATTENTION: Although partially referenced initdram does NOT make real use
+ *            use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
+ *            is something else than 0x00000000.
+ */
+
+long int initdram (int board_type)
+{
+	ulong dramsize = 0;
+	ulong dramsize2 = 0;
+	uint svr, pvr;
+
+#ifndef CFG_RAMBOOT
+	ulong test1, test2;
+
+	/* setup SDRAM chip selects */
+	*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
+	*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
+	__asm__ volatile ("sync");
+
+	/* setup config registers */
+	*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
+	*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
+	__asm__ volatile ("sync");
+
+#if SDRAM_DDR
+	/* set tap delay */
+	*(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
+	__asm__ volatile ("sync");
+#endif
+
+	/* find RAM size using SDRAM CS0 only */
+	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 */
+	*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
+
+	/* find RAM size using SDRAM CS1 only */
+	if (!dramsize)
+		sdram_start(0);
+	test2 = test1 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000);
+	if (!dramsize) {
+		sdram_start(1);
+		test2 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000);
+	}
+	if (test1 > test2) {
+		sdram_start(0);
+		dramsize2 = test1;
+	} else {
+		dramsize2 = test2;
+	}
+
+	/* memory smaller than 1MB is impossible */
+	if (dramsize2 < (1 << 20)) {
+		dramsize2 = 0;
+	}
+
+	/* set SDRAM CS1 size according to the amount of RAM found */
+	if (dramsize2 > 0) {
+		*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
+			| (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
+	} else {
+		*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
+	}
+
+#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;
+	}
+
+	/* retrieve size of memory connected to SDRAM CS1 */
+	dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
+	if (dramsize2 >= 0x13) {
+		dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
+	} else {
+		dramsize2 = 0;
+	}
+
+#endif /* CFG_RAMBOOT */
+
+	/*
+	 * On MPC5200B we need to set the special configuration delay in the
+	 * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
+	 * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
+	 *
+	 * "The SDelay should be written to a value of 0x00000004. It is
+	 * required to account for changes caused by normal wafer processing
+	 * parameters."
+	 */
+	svr = get_svr();
+	pvr = get_pvr();
+	if ((SVR_MJREV(svr) >= 2) &&
+	    (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
+
+		*(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
+		__asm__ volatile ("sync");
+	}
+
+	return dramsize + dramsize2;
+}
+
+int checkboard (void)
+{
+	puts ("Board: Sauter (Jupiter)\n");
+	return 0;
+}
+
+void flash_preinit(void)
+{
+	/*
+	 * Now, when we are in RAM, enable flash write
+	 * access for detection process.
+	 * Note that CS_BOOT cannot be cleared when
+	 * executing in flash.
+	 */
+#if defined(CONFIG_MGT5100)
+	*(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
+	*(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
+#endif
+	*(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+}
+
+int board_early_init_r (void)
+{
+	flash_preinit ();
+	return 0;
+}
+
+void flash_afterinit(ulong size)
+{
+	if (size == 0x1000000) { /* adjust mapping */
+		*(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START =
+			START_REG(CFG_BOOTCS_START | size);
+		*(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP =
+			STOP_REG(CFG_BOOTCS_START | size, size);
+	}
+#if defined(CONFIG_MPC5200)
+	*(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
+	*(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
+#endif
+}
+
+int update_flash_size (int flash_size)
+{
+	flash_afterinit (flash_size);
+	return 0;
+}
+
+int board_early_init_f (void)
+{
+	*(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+	return 0;
+}
+
+#ifdef	CONFIG_PCI
+static struct pci_controller hose;
+
+extern void pci_mpc5xxx_init(struct pci_controller *);
+
+void pci_init_board(void)
+{
+	pci_mpc5xxx_init(&hose);
+}
+#endif
+
+#if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET)
+
+void init_ide_reset (void)
+{
+	debug ("init_ide_reset\n");
+
+	/* Configure PSC1_4 as GPIO output for ATA reset */
+	*(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
+	*(vu_long *) MPC5XXX_WU_GPIO_DIR    |= GPIO_PSC1_4;
+	/* Deassert reset */
+	*(vu_long *) MPC5XXX_WU_GPIO_DATA_O   |= GPIO_PSC1_4;
+}
+
+void ide_set_reset (int idereset)
+{
+	debug ("ide_reset(%d)\n", idereset);
+
+	if (idereset) {
+		*(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
+		/* Make a delay. MPC5200 spec says 25 usec min */
+		udelay(500000);
+	} else {
+		*(vu_long *) MPC5XXX_WU_GPIO_DATA_O |=  GPIO_PSC1_4;
+	}
+}
+#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+	ft_cpu_setup(blob, bd);
+}
+#endif
diff --git a/board/jupiter/u-boot.lds b/board/jupiter/u-boot.lds
new file mode 100644
index 0000000..f23432e
--- /dev/null
+++ b/board/jupiter/u-boot.lds
@@ -0,0 +1,125 @@
+/*
+ * (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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/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/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/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c
index e639234..13a3870 100644
--- a/cpu/mpc5xxx/fec.c
+++ b/cpu/mpc5xxx/fec.c
@@ -878,12 +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_MCC200)  || defined(CONFIG_MOTIONPRO)	|| \
-    defined(CONFIG_O2DNT)   || defined(CONFIG_PM520)	|| \
-    defined(CONFIG_TOP5200) || defined(CONFIG_TQM5200)	|| \
-    defined(CONFIG_UC101)   || defined(CONFIG_V38B)
+#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/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
index 32d44db..10b4c18 100644
--- a/cpu/ppc4xx/44x_spd_ddr.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -46,6 +46,7 @@
 #include <asm/processor.h>
 #include <i2c.h>
 #include <ppc4xx.h>
+#include <asm/mmu.h>
 
 #if defined(CONFIG_SPD_EEPROM) &&					\
 	(defined(CONFIG_440GP) || defined(CONFIG_440GX) ||		\
@@ -229,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},
@@ -259,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);
 
@@ -377,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)
 	 */
@@ -1330,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;
+ 			}
 		}
 	}
 
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 35b2315..83c9911 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -168,8 +168,8 @@
 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);
+			 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);
@@ -185,9 +185,10 @@
 static void program_initplr(unsigned long *dimm_populated,
 			    unsigned char *iic0_dimm_addr,
 			    unsigned long num_dimm_banks,
-                            ddr_cas_id_t selected_cas,
+			    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,
@@ -195,6 +196,7 @@
 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);
@@ -255,15 +257,6 @@
 	}
 }
 
-static void wait_ddr_idle(void)
-{
-	u32 val;
-
-	do {
-		mfsdram(SDRAM_MCSTAT, val);
-	} while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
-}
-
 static unsigned char spd_read(uchar chip, uint addr)
 {
 	unsigned char data[2];
@@ -491,7 +484,7 @@
 		(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_75OHM | SDRAM_MEMODE_DQS_ENABLE));
+		 | SDRAM_MEMODE_RTT_150OHM | SDRAM_MEMODE_DQS_ENABLE));
 
 	/*------------------------------------------------------------------
 	 * Program Initialization preload registers.
@@ -537,10 +530,12 @@
 	 *-----------------------------------------------------------------*/
 	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();
@@ -702,7 +697,7 @@
 	 *-----------------------------------------------------------------*/
 	get_sys_info(&board_cfg);
 
-	mfsdr(sdr_ddr0, sdr_ddrpll);
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
 	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
 
 	/*
@@ -877,7 +872,11 @@
 	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;
@@ -1149,7 +1148,7 @@
 static void program_initplr(unsigned long *dimm_populated,
 			    unsigned char *iic0_dimm_addr,
 			    unsigned long num_dimm_banks,
-                            ddr_cas_id_t selected_cas,
+			    ddr_cas_id_t selected_cas,
 			    int write_recovery)
 {
 	u32 cas = 0;
@@ -1314,7 +1313,7 @@
 	 *-----------------------------------------------------------------*/
 	get_sys_info(&board_cfg);
 
-	mfsdr(sdr_ddr0, sdr_ddrpll);
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
 	sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1);
 
 	/*------------------------------------------------------------------
@@ -1463,11 +1462,12 @@
 	mfsdram(SDRAM_MMODE, mmode);
 	mmode = mmode & ~(SDRAM_MMODE_WR_MASK | SDRAM_MMODE_DCL_MASK);
 
-	cycle_2_0_clk = MULDIV64(ONE_BILLION, 100, max_2_0_tcyc_ns_x_100);
-	cycle_2_5_clk = MULDIV64(ONE_BILLION, 100, max_2_5_tcyc_ns_x_100);
-	cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100);
-	cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100);
-	cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100);
+	/* 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)) {
@@ -1498,7 +1498,11 @@
 		} 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\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();
 		}
 	}
@@ -1575,7 +1579,7 @@
 	/*------------------------------------------------------------------
 	 * Set the SDRAM Refresh Timing Register, SDRAM_RTR
 	 *-----------------------------------------------------------------*/
-	mfsdr(sdr_ddr0, sdr_ddrpll);
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
 	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
 
 	max_refresh_rate = 0;
@@ -1661,7 +1665,7 @@
 	 *-----------------------------------------------------------------*/
 	get_sys_info(&board_cfg);
 
-	mfsdr(sdr_ddr0, sdr_ddrpll);
+	mfsdr(SDR0_DDR0, sdr_ddrpll);
 	sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
 
 	/*------------------------------------------------------------------
@@ -2069,7 +2073,7 @@
 			 * Set the sizes
 			 *-----------------------------------------------------------------*/
 			baseadd_size = 0;
-			rank_size_bytes = 1024 * 1024 * rank_size_id;
+			rank_size_bytes = 4 * 1024 * 1024 * rank_size_id;
 			switch (rank_size_id) {
 			case 0x02:
 				baseadd_size |= SDRAM_RXBAS_SDSZ_8;
@@ -2106,8 +2110,8 @@
 
 			for (i = 0; i < num_ranks; i++)	{
 				mtdcr_any(rank_reg+i+dimm_num+bank_0_populated,
-					  (rank_base_addr & SDRAM_RXBAS_SDBA_MASK) |
-					  baseadd_size);
+					  (SDRAM_RXBAS_SDBA_ENCODE(rank_base_addr) |
+					   baseadd_size));
 				rank_base_addr += rank_size_bytes;
 			}
 		}
@@ -2130,9 +2134,10 @@
 		ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val));
 	}
 
-	return(ecc);
+	return ecc;
 }
 
+#ifdef CONFIG_DDR_ECC
 /*-----------------------------------------------------------------------------+
  * program_ecc.
  *-----------------------------------------------------------------------------*/
@@ -2208,6 +2213,15 @@
 }
 #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.
  *-----------------------------------------------------------------------------*/
@@ -2276,6 +2290,7 @@
 #endif
 	}
 }
+#endif
 
 /*-----------------------------------------------------------------------------+
  * program_DQS_calibration.
@@ -2531,7 +2546,6 @@
 		}
 	}		/* for rffd */
 
-
 	/*------------------------------------------------------------------
 	 * Set the average RFFD value
 	 *-----------------------------------------------------------------*/
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 24b30df..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.
@@ -1916,43 +1916,43 @@
 /*----------------------------------------------------------------------------+
 | 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
+	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)
+	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
+	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
+	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)
+	addi    r3,r3,-32
+	bdnz    ..ag
+	sync
+	mtmsr   r9
+	blr
+	function_epilog(dflush)
 #endif /* CONFIG_440 */
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/jupiter.h b/include/configs/jupiter.h
new file mode 100644
index 0000000..48056a3
--- /dev/null
+++ b/include/configs/jupiter.h
@@ -0,0 +1,277 @@
+/*
+ * (C) Copyright 2007
+ * Heiko Schocher, DENX Software Engineering, hs@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 __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC5xxx		1	/* This is an MPC5xxx CPU */
+#define CONFIG_MPC5200		1	/* especially an MPC5200 */
+#define CONFIG_JUPITER		1	/* ... on Jupiter board */
+
+#define CFG_MPC5XXX_CLKIN	33000000 /* ... running at 33.000000MHz */
+
+#define CONFIG_BOARD_EARLY_INIT_R	1
+#define CONFIG_BOARD_EARLY_INIT_F	1
+
+#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH  */
+#define BOOTFLAG_WARM		0x02	/* Software reboot	     */
+
+#define CFG_CACHELINE_SIZE	32	/* For MPC5xxx CPUs */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */
+#endif
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_PSC_CONSOLE	1	/* console is on PSC1 */
+#define CONFIG_BAUDRATE		115200	/* ... at 115200 bps */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/*
+ * PCI Mapping:
+ * 0x40000000 - 0x4fffffff - PCI Memory
+ * 0x50000000 - 0x50ffffff - PCI IO Space
+ */
+/*#define CONFIG_PCI		*/
+
+#if defined(CONFIG_PCI)
+#define CONFIG_PCI_PNP		1
+#define CONFIG_PCI_SCAN_SHOW	1
+
+#define CONFIG_PCI_MEM_BUS	0x40000000
+#define CONFIG_PCI_MEM_PHYS	CONFIG_PCI_MEM_BUS
+#define CONFIG_PCI_MEM_SIZE	0x10000000
+
+#define CONFIG_PCI_IO_BUS	0x50000000
+#define CONFIG_PCI_IO_PHYS	CONFIG_PCI_IO_BUS
+#define CONFIG_PCI_IO_SIZE	0x01000000
+#define ADD_PCI_CMD 		CFG_CMD_PCI
+#endif
+
+#define CFG_XLB_PIPELINING	1
+
+#define CONFIG_NET_MULTI	1
+#define CONFIG_MII		1
+#define CFG_RX_ETH_BUFFER	8  /* use 8 rx buffer on eepro100  */
+
+/* Partitions */
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+#define CONFIG_ISO_PARTITION
+
+#define	CONFIG_TIMESTAMP		/* Print image info with timestamp */
+
+/*
+ * Supported commands
+ */
+#define CONFIG_COMMANDS	       (CONFIG_CMD_DFL	| \
+				CFG_CMD_NFS	| \
+				CFG_CMD_SNTP)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds */
+
+#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"							\
+	"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"			\
+	"flash_nfs=run nfsargs addip;"					\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip;"					\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"net_nfs=tftp 200000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"rootpath=/opt/eldk/ppc_82xx\0"					\
+	"bootfile=/tftpboot/jupiter/uImage\0"				\
+	""
+
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+/*
+ * IPB Bus clocking configuration.
+ */
+#undef CFG_IPBSPEED_133   	/* define for 133MHz speed */
+
+#if 0
+/* pass open firmware flat tree */
+#define CONFIG_OF_FLAT_TREE	1
+#define CONFIG_OF_BOARD_SETUP	1
+
+/* maximum size of the flat tree (8K) */
+#define OF_FLAT_TREE_MAX_SIZE	8192
+
+#define OF_CPU			"PowerPC,5200@0"
+#define OF_SOC			"soc5200@f0000000"
+#define OF_TBCLK		(bd->bi_busfreq / 8)
+#define OF_STDOUT_PATH		"/soc5200@f0000000/serial@2000"
+#endif
+
+#if 0
+/*
+ * I2C configuration
+ */
+#define CONFIG_HARD_I2C		1	/* I2C with hardware support */
+#define CFG_I2C_MODULE		2	/* Select I2C module #1 or #2 */
+
+#define CFG_I2C_SPEED		100000 /* 100 kHz */
+#define CFG_I2C_SLAVE		0x7F
+
+/*
+ * EEPROM configuration
+ */
+#define CFG_I2C_EEPROM_ADDR		0x50	/* 1010000x */
+#define CFG_I2C_EEPROM_ADDR_LEN		1
+#define CFG_EEPROM_PAGE_WRITE_BITS	3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	70
+#endif
+
+/*
+ * Flash configuration
+ */
+#define CFG_FLASH_BASE		0xFF000000
+#define CFG_FLASH_SIZE		0x01000000
+
+#define CFG_MAX_FLASH_SECT	128	/* max num of sects on one chip */
+
+#define CFG_ENV_ADDR		(TEXT_BASE + 0x40000) /* third sector */
+
+#define CFG_FLASH_ERASE_TOUT	240000	/* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT	500	/* Flash Write Timeout (in ms)  */
+
+#define CFG_MAX_FLASH_BANKS	1	/* max num of flash banks */
+
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#define CFG_FLASH_EMPTY_INFO
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
+#define CFG_UPDATE_FLASH_SIZE	1
+#define CFG_FLASH_USE_BUFFER_WRITE	1
+
+/*
+ * Environment settings
+ */
+#define CFG_ENV_IS_IN_FLASH	1
+#define CFG_ENV_SIZE		0x20000
+#define CFG_ENV_SECT_SIZE	0x20000
+#define CONFIG_ENV_OVERWRITE	1
+
+/*
+ * Memory map
+ */
+#define CFG_MBAR		0xF0000000
+#define CFG_SDRAM_BASE		0x00000000
+#define CFG_DEFAULT_MBAR	0x80000000
+
+/* Use SRAM until RAM will be available */
+#define CFG_INIT_RAM_ADDR	MPC5XXX_SRAM
+#define CFG_INIT_RAM_END	MPC5XXX_SRAM_SIZE	/* End of used area in DPRAM */
+
+
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET	CFG_GBL_DATA_OFFSET
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT		1
+#endif
+
+#define CFG_MONITOR_LEN		(192 << 10)	/* Reserve 192 kB for Monitor	*/
+#define CFG_MALLOC_LEN		(128 << 10)	/* Reserve 128 kB for malloc()	*/
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_MPC5xxx_FEC	1
+/*
+ * Define CONFIG_FEC_10MBIT to force FEC at 10Mb
+ */
+/* #define CONFIG_FEC_10MBIT 1 */
+#define CONFIG_PHY_ADDR		0x00
+
+/*
+ * GPIO configuration
+ */
+#define CFG_GPS_PORT_CONFIG	0x10000004
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP			/* undef to save memory	    */
+#define CFG_PROMPT		"=> "	/* Monitor Command Prompt   */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE		1024	/* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE		256	/* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS		16		/* max number of command args	*/
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+
+#define CFG_MEMTEST_START	0x00100000	/* memtest works on */
+#define CFG_MEMTEST_END		0x00f00000	/* 1 ... 15 MB in DRAM	*/
+#define CFG_ALT_MEMTEST		1
+
+#define CFG_LOAD_ADDR		0x200000	/* default load address */
+
+#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 CFG_BOOTCS_START	CFG_FLASH_BASE
+#define CFG_BOOTCS_SIZE		CFG_FLASH_SIZE
+#define CFG_BOOTCS_CFG		0x00047801
+#define CFG_CS0_START		CFG_FLASH_BASE
+#define CFG_CS0_SIZE		CFG_FLASH_SIZE
+
+#define CFG_CS_BURST		0x00000000
+#define CFG_CS_DEADCYCLE	0x33333333
+
+#define CFG_RESET_ADDRESS	0xff000000
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/katmai.h b/include/configs/katmai.h
index f350155..1606d0d 100644
--- a/include/configs/katmai.h
+++ b/include/configs/katmai.h
@@ -108,6 +108,7 @@
  *----------------------------------------------------------------------*/
 #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
 
 /*-----------------------------------------------------------------------
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/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/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/ppc440.h b/include/ppc440.h
index 1c7f11c..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)
@@ -2167,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
@@ -3293,26 +3316,26 @@
 /*
  * 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/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
 }