Merge with /home/wd/git/u-boot/master
diff --git a/cpu/74xx_7xx/Makefile b/cpu/74xx_7xx/Makefile
index 0e10d3a..fe905f3 100644
--- a/cpu/74xx_7xx/Makefile
+++ b/cpu/74xx_7xx/Makefile
@@ -1,4 +1,7 @@
 #
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
 # (C) Copyright 2001
 # Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
 #
@@ -23,22 +26,26 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-ASOBJS	= cache.o kgdb.o io.o
-OBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o
+SOBJS	= cache.o kgdb.o io.o
+COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o
 
-all:	.depend $(START) $(ASOBJS) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(ASOBJS) $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm1136/Makefile b/cpu/arm1136/Makefile
index 203278e..d5ac7d3 100644
--- a/cpu/arm1136/Makefile
+++ b/cpu/arm1136/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= interrupts.o cpu.o
+COBJS	= interrupts.o cpu.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm720t/Makefile b/cpu/arm720t/Makefile
index f273d92..c97f329 100644
--- a/cpu/arm720t/Makefile
+++ b/cpu/arm720t/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= serial.o serial_netarm.o interrupts.o cpu.o
+COBJS	= serial.o serial_netarm.o interrupts.o cpu.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm920t/Makefile b/cpu/arm920t/Makefile
index 8f256e9..e02bc6a 100644
--- a/cpu/arm920t/Makefile
+++ b/cpu/arm920t/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= cpu.o interrupts.o
+COBJS	= cpu.o interrupts.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm920t/at91rm9200/Makefile b/cpu/arm920t/at91rm9200/Makefile
index f9fccbc..eaabad2 100644
--- a/cpu/arm920t/at91rm9200/Makefile
+++ b/cpu/arm920t/at91rm9200/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,22 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(SOC).a
+LIB	= $(obj)lib$(SOC).a
 
-OBJS	= bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
+COBJS	= bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
 	  lxt972.o serial.o usb.o
 SOBJS	= lowlevel_init.o
 
-all:	.depend $(LIB)
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
-$(LIB):	$(OBJS) $(SOBJS)
-	$(AR) crv $@ $(OBJS) $(SOBJS)
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm920t/imx/Makefile b/cpu/arm920t/imx/Makefile
index 8865f82..9207ec1 100644
--- a/cpu/arm920t/imx/Makefile
+++ b/cpu/arm920t/imx/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,20 +23,23 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(SOC).a
+LIB	= $(obj)lib$(SOC).a
 
-OBJS	= generic.o interrupts.o serial.o speed.o
+COBJS	= generic.o interrupts.o serial.o speed.o
 
-all:	.depend $(LIB)
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all:	$(obj).depend $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm920t/ks8695/Makefile b/cpu/arm920t/ks8695/Makefile
index ac49060..7db9473 100644
--- a/cpu/arm920t/ks8695/Makefile
+++ b/cpu/arm920t/ks8695/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,24 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(SOC).a
+LIB	= $(obj)lib$(SOC).a
 
-OBJS	= interrupts.o serial.o
+COBJS	= interrupts.o serial.o
 SOBJS	= lowlevel_init.o
 
-all:	.depend $(LIB)
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
-$(LIB):	$(OBJS) $(SOBJS)
-	$(AR) crv $@ $(OBJS) $(SOBJS)
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile
index f81f84d..0ff36c5 100644
--- a/cpu/arm920t/s3c24x0/Makefile
+++ b/cpu/arm920t/s3c24x0/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,24 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(SOC).a
+LIB	= $(obj)lib$(SOC).a
 
-OBJS	= i2c.o interrupts.o serial.o speed.o \
+COBJS	= i2c.o interrupts.o serial.o speed.o \
 	  usb.o
 
-all:	.depend $(LIB)
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all:	$(obj).depend $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm925t/Makefile b/cpu/arm925t/Makefile
index a1db818..0d4912c 100644
--- a/cpu/arm925t/Makefile
+++ b/cpu/arm925t/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= interrupts.o cpu.o omap925.o
+COBJS	= interrupts.o cpu.o omap925.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm925t/omap925.c b/cpu/arm925t/omap925.c
index ae62656..65dab9f 100644
--- a/cpu/arm925t/omap925.c
+++ b/cpu/arm925t/omap925.c
@@ -25,40 +25,6 @@
 #include <command.h>
 #include <arm925t.h>
 
-ushort gpioreserved;
-
-void gpioreserve(ushort mask)
-{
-	gpioreserved |= mask;
-}
-
-void gpiosetdir(ushort mask, ushort in)
-{
-	*(ushort *)GPIO_DIR_CONTROL_REG = (*(ushort *)GPIO_DIR_CONTROL_REG & ~mask) | (in & mask);
-}
-
-
-void gpiosetout(ushort mask, ushort out)
-{
-	ushort *r_ptr, r_val;
-
-	r_ptr = (ushort *)GPIO_DATA_OUTPUT_REG;	/* set pointer */
-	r_val = *r_ptr & ~mask;		/* get previous val, clear bits we want to change */
-	r_val |= (out & mask);		/* set specified bits in value + plus origional ones */
-	*r_ptr = r_val;			/* write it out */
-/*
- * gcc screwed this one up :(.
- *
- * *(ushort *)GPIO_DATA_OUTPUT_REG = (*(ushort *)GPIO_DATA_OUTPUT_REG & ~mask) | (out & mask);
- */
-
-}
-
-void gpioinit(void)
-{
-}
-
-
 #define MIF_CONFIG_REG 0xFFFECC0C
 #define FLASH_GLOBAL_CTRL_NWP 1
 
diff --git a/cpu/arm926ejs/Makefile b/cpu/arm926ejs/Makefile
index 060fd20..0facce4 100644
--- a/cpu/arm926ejs/Makefile
+++ b/cpu/arm926ejs/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= interrupts.o cpu.o cpuinfo.o
+COBJS	= interrupts.o cpu.o cpuinfo.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm926ejs/omap/Makefile b/cpu/arm926ejs/omap/Makefile
index f9d3378..c335d5c 100644
--- a/cpu/arm926ejs/omap/Makefile
+++ b/cpu/arm926ejs/omap/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(SOC).a
+LIB	= $(obj)lib$(SOC).a
 
-OBJS	= timer.o
+COBJS	= timer.o
 SOBJS	= reset.o
 
-all:	.depend $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
 
-$(LIB):	$(OBJS) $(SOBJS)
-	$(AR) crv $@ $(OBJS) $(SOBJS)
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm926ejs/versatile/Makefile b/cpu/arm926ejs/versatile/Makefile
index f9d3378..c335d5c 100644
--- a/cpu/arm926ejs/versatile/Makefile
+++ b/cpu/arm926ejs/versatile/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(SOC).a
+LIB	= $(obj)lib$(SOC).a
 
-OBJS	= timer.o
+COBJS	= timer.o
 SOBJS	= reset.o
 
-all:	.depend $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
 
-$(LIB):	$(OBJS) $(SOBJS)
-	$(AR) crv $@ $(OBJS) $(SOBJS)
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm946es/Makefile b/cpu/arm946es/Makefile
index 203278e..d5ac7d3 100644
--- a/cpu/arm946es/Makefile
+++ b/cpu/arm946es/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= interrupts.o cpu.o
+COBJS	= interrupts.o cpu.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/arm_intcm/Makefile b/cpu/arm_intcm/Makefile
index 203278e..d5ac7d3 100644
--- a/cpu/arm_intcm/Makefile
+++ b/cpu/arm_intcm/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= interrupts.o cpu.o
+COBJS	= interrupts.o cpu.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
new file mode 100644
index 0000000..f62ec8b
--- /dev/null
+++ b/cpu/at32ap/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2005-2006 Atmel Corporation.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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$(CPU).a
+
+START	:= start.o
+SOBJS	:= entry.o
+COBJS	:= cpu.o hsdramc.o exception.o cache.o
+COBJS	+= interrupts.o device.o pm.o pio.o
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+	$(AR) $(ARFLAGS) $@ $^
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/at32ap/at32ap7000/Makefile b/cpu/at32ap/at32ap7000/Makefile
new file mode 100644
index 0000000..2ed74d2
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2005-2006 Atmel Corporation
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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$(SOC).a
+
+COBJS	:= hebi.o devices.o
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+	$(AR) $(ARFLAGS) $@ $^
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/at32ap/at32ap7000/devices.c b/cpu/at32ap/at32ap7000/devices.c
new file mode 100644
index 0000000..8b216e9
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/devices.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "../sm.h"
+
+#define ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0]))
+
+const struct clock_domain chip_clock[] = {
+	[CLOCK_CPU] = {
+		.reg	= SM_PM_CPU_MASK,
+		.id	= CLOCK_CPU,
+		.bridge	= NO_DEVICE,
+	},
+	[CLOCK_HSB] = {
+		.reg	= SM_PM_HSB_MASK,
+		.id	= CLOCK_HSB,
+		.bridge	= NO_DEVICE,
+	},
+	[CLOCK_PBA] = {
+		.reg	= SM_PM_PBA_MASK,
+		.id	= CLOCK_PBA,
+		.bridge	= DEVICE_PBA_BRIDGE,
+	},
+	[CLOCK_PBB] = {
+		.reg	= SM_PM_PBB_MASK,
+		.id	= CLOCK_PBB,
+		.bridge	= DEVICE_PBB_BRIDGE,
+	},
+};
+
+static const struct resource hebi_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 0 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 13 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 14 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 27, DEVICE_PIOE, GPIO_FUNC_A, 0 },
+		},
+	},
+};
+static const struct resource pba_bridge_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 1 },
+		}
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			/* HSB-HSB Bridge */
+			.clock	= { CLOCK_HSB, 4 },
+		},
+	},
+};
+static const struct resource pbb_bridge_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 2 },
+		},
+	},
+};
+static const struct resource hramc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 3 },
+		},
+	},
+};
+static const struct resource pioa_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 10 },
+		},
+	},
+};
+static const struct resource piob_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 11 },
+		},
+	},
+};
+static const struct resource pioc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 12 },
+		},
+	},
+};
+static const struct resource piod_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 13 },
+		},
+	},
+};
+static const struct resource pioe_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 14 },
+		},
+	},
+};
+static const struct resource sm_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 0 },
+		},
+	},
+};
+static const struct resource intc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock = { CLOCK_PBB, 1 },
+		},
+	},
+};
+static const struct resource hmatrix_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock = { CLOCK_PBB, 2 },
+		},
+	},
+};
+#if defined(CFG_HPDC)
+static const struct resource hpdc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 16 },
+		},
+	},
+};
+#endif
+#if defined(CFG_MACB0)
+static const struct resource macb0_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 8 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 6 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 19, DEVICE_PIOC, GPIO_FUNC_A, 0 },
+		},
+	},
+};
+#endif
+#if defined(CFG_MACB1)
+static const struct resource macb1_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 9 },
+		},
+	}, {
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 7 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 12, DEVICE_PIOC, GPIO_FUNC_B, 19 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio	= { 14, DEVICE_PIOD, GPIO_FUNC_B, 2 },
+		},
+	},
+};
+#endif
+#if defined(CFG_LCDC)
+static const struct resource lcdc_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 7 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART0)
+static const struct resource usart0_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 3 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_B, 8 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART1)
+static const struct resource usart1_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 4 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_A, 17 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART2)
+static const struct resource usart2_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 5 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 26 },
+		},
+	},
+};
+#endif
+#if defined(CFG_USART3)
+static const struct resource usart3_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBA, 6 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 17 },
+		},
+	},
+};
+#endif
+#if defined(CFG_MMCI)
+static const struct resource mmci_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_PBB, 9 },
+		},
+	}, {
+		.type	= RESOURCE_GPIO,
+		.u	= {
+			.gpio = { 6, DEVICE_PIOA, GPIO_FUNC_A, 10 },
+		},
+	},
+};
+#endif
+#if defined(CFG_DMAC)
+static const struct resource dmac_resource[] = {
+	{
+		.type	= RESOURCE_CLOCK,
+		.u	= {
+			.clock	= { CLOCK_HSB, 10 },
+		},
+	},
+};
+#endif
+
+const struct device chip_device[] = {
+	[DEVICE_HEBI] = {
+		.regs		= (void *)HSMC_BASE,
+		.nr_resources	= ARRAY_SIZE(hebi_resource),
+		.resource	= hebi_resource,
+	},
+	[DEVICE_PBA_BRIDGE] = {
+		.nr_resources	= ARRAY_SIZE(pba_bridge_resource),
+		.resource	= pba_bridge_resource,
+	},
+	[DEVICE_PBB_BRIDGE] = {
+		.nr_resources	= ARRAY_SIZE(pbb_bridge_resource),
+		.resource	= pbb_bridge_resource,
+	},
+	[DEVICE_HRAMC] = {
+		.nr_resources	= ARRAY_SIZE(hramc_resource),
+		.resource	= hramc_resource,
+	},
+	[DEVICE_PIOA] = {
+		.regs		= (void *)PIOA_BASE,
+		.nr_resources	= ARRAY_SIZE(pioa_resource),
+		.resource	= pioa_resource,
+	},
+	[DEVICE_PIOB] = {
+		.regs		= (void *)PIOB_BASE,
+		.nr_resources	= ARRAY_SIZE(piob_resource),
+		.resource	= piob_resource,
+	},
+	[DEVICE_PIOC] = {
+		.regs		= (void *)PIOC_BASE,
+		.nr_resources	= ARRAY_SIZE(pioc_resource),
+		.resource	= pioc_resource,
+	},
+	[DEVICE_PIOD] = {
+		.regs		= (void *)PIOD_BASE,
+		.nr_resources	= ARRAY_SIZE(piod_resource),
+		.resource	= piod_resource,
+	},
+	[DEVICE_PIOE] = {
+		.regs		= (void *)PIOE_BASE,
+		.nr_resources	= ARRAY_SIZE(pioe_resource),
+		.resource	= pioe_resource,
+	},
+	[DEVICE_SM] = {
+		.regs		= (void *)SM_BASE,
+		.nr_resources	= ARRAY_SIZE(sm_resource),
+		.resource	= sm_resource,
+	},
+	[DEVICE_INTC] = {
+		.regs		= (void *)INTC_BASE,
+		.nr_resources	= ARRAY_SIZE(intc_resource),
+		.resource	= intc_resource,
+	},
+	[DEVICE_HMATRIX] = {
+		.regs		= (void *)HMATRIX_BASE,
+		.nr_resources	= ARRAY_SIZE(hmatrix_resource),
+		.resource	= hmatrix_resource,
+	},
+#if defined(CFG_HPDC)
+	[DEVICE_HPDC] = {
+		.nr_resources	= ARRAY_SIZE(hpdc_resource),
+		.resource	= hpdc_resource,
+	},
+#endif
+#if defined(CFG_MACB0)
+	[DEVICE_MACB0] = {
+		.regs		= (void *)MACB0_BASE,
+		.nr_resources	= ARRAY_SIZE(macb0_resource),
+		.resource	= macb0_resource,
+	},
+#endif
+#if defined(CFG_MACB1)
+	[DEVICE_MACB1] = {
+		.regs		= (void *)MACB1_BASE,
+		.nr_resources	= ARRAY_SIZE(macb1_resource),
+		.resource	= macb1_resource,
+	},
+#endif
+#if defined(CFG_LCDC)
+	[DEVICE_LCDC] = {
+		.nr_resources	= ARRAY_SIZE(lcdc_resource),
+		.resource	= lcdc_resource,
+	},
+#endif
+#if defined(CFG_USART0)
+	[DEVICE_USART0] = {
+		.regs		= (void *)USART0_BASE,
+		.nr_resources	= ARRAY_SIZE(usart0_resource),
+		.resource	= usart0_resource,
+	},
+#endif
+#if defined(CFG_USART1)
+	[DEVICE_USART1] = {
+		.regs		= (void *)USART1_BASE,
+		.nr_resources	= ARRAY_SIZE(usart1_resource),
+		.resource	= usart1_resource,
+	},
+#endif
+#if defined(CFG_USART2)
+	[DEVICE_USART2] = {
+		.regs		= (void *)USART2_BASE,
+		.nr_resources	= ARRAY_SIZE(usart2_resource),
+		.resource	= usart2_resource,
+	},
+#endif
+#if defined(CFG_USART3)
+	[DEVICE_USART3] = {
+		.regs		= (void *)USART3_BASE,
+		.nr_resources	= ARRAY_SIZE(usart3_resource),
+		.resource	= usart3_resource,
+	},
+#endif
+#if defined(CFG_MMCI)
+	[DEVICE_MMCI] = {
+		.regs		= (void *)MMCI_BASE,
+		.nr_resources	= ARRAY_SIZE(mmci_resource),
+		.resource	= mmci_resource,
+	},
+#endif
+#if defined(CFG_DMAC)
+	[DEVICE_DMAC] = {
+		.regs		= (void *)DMAC_BASE,
+		.nr_resources	= ARRAY_SIZE(dmac_resource),
+		.resource	= dmac_resource,
+	},
+#endif
+};
diff --git a/cpu/at32ap/at32ap7000/hebi.c b/cpu/at32ap/at32ap7000/hebi.c
new file mode 100644
index 0000000..3b32adf
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/hebi.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/hmatrix2.h>
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+void cpu_enable_sdram(void)
+{
+	const struct device *hmatrix;
+
+	hmatrix = get_device(DEVICE_HMATRIX);
+
+	/* Set the SDRAM_ENABLE bit in the HEBI SFR */
+	hmatrix2_writel(hmatrix, SFR4, 1 << 1);
+}
diff --git a/cpu/at32ap/cache.c b/cpu/at32ap/cache.c
new file mode 100644
index 0000000..41fb5aa
--- /dev/null
+++ b/cpu/at32ap/cache.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#include <asm/cacheflush.h>
+
+void dcache_clean_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_DCACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		dcache_clean_line((void *)v);
+
+	sync_write_buffer();
+}
+
+void dcache_invalidate_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_DCACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		dcache_invalidate_line((void *)v);
+}
+
+void dcache_flush_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_DCACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		dcache_flush_line((void *)v);
+
+	sync_write_buffer();
+}
+
+void icache_invalidate_range(volatile void *start, size_t size)
+{
+	unsigned long v, begin, end, linesz;
+
+	linesz = CFG_ICACHE_LINESZ;
+
+	/* You asked for it, you got it */
+	begin = (unsigned long)start & ~(linesz - 1);
+	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+	for (v = begin; v < end; v += linesz)
+		icache_invalidate_line((void *)v);
+}
+
+/*
+ * This is called after loading something into memory.  We need to
+ * make sure that everything that was loaded is actually written to
+ * RAM, and that the icache will look for it. Cleaning the dcache and
+ * invalidating the icache will do the trick.
+ */
+void  flush_cache (unsigned long start_addr, unsigned long size)
+{
+	dcache_clean_range((void *)start_addr, size);
+	icache_invalidate_range((void *)start_addr, size);
+}
diff --git a/cpu/at32ap/config.mk b/cpu/at32ap/config.mk
new file mode 100644
index 0000000..1c12169
--- /dev/null
+++ b/cpu/at32ap/config.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2005-2006 Atmel Corporation
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+PLATFORM_RELFLAGS       += -mcpu=ap7000
diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c
new file mode 100644
index 0000000..37e3ea0
--- /dev/null
+++ b/cpu/at32ap/cpu.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <command.h>
+
+#include <asm/io.h>
+#include <asm/sections.h>
+#include <asm/sysreg.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "hsmc3.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int cpu_init(void)
+{
+	const struct device *hebi;
+	extern void _evba(void);
+	char *p;
+
+	gd->cpu_hz = CFG_OSC0_HZ;
+
+	/* fff03400: 00010001 04030402 00050005 10011103 */
+	hebi = get_device(DEVICE_HEBI);
+	hsmc3_writel(hebi, MODE0, 0x00031103);
+	hsmc3_writel(hebi, CYCLE0, 0x000c000d);
+	hsmc3_writel(hebi, PULSE0, 0x0b0a0906);
+	hsmc3_writel(hebi, SETUP0, 0x00010002);
+
+	pm_init();
+
+	sysreg_write(EVBA, (unsigned long)&_evba);
+	asm volatile("csrf	%0" : : "i"(SYSREG_EM_OFFSET));
+	gd->console_uart = get_device(CFG_CONSOLE_UART_DEV);
+
+	/* Lock everything that mess with the flash in the icache */
+	for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ);
+	     p += CFG_ICACHE_LINESZ)
+		asm volatile("cache %0, 0x02" : "=m"(*p) :: "memory");
+
+	return 0;
+}
+
+void prepare_to_boot(void)
+{
+	/* Flush both caches and the write buffer */
+	asm volatile("cache  %0[4], 010\n\t"
+		     "cache  %0[0], 000\n\t"
+		     "sync   0" : : "r"(0) : "memory");
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	/* This will reset the CPU core, caches, MMU and all internal busses */
+	__builtin_mtdr(8, 1 << 13);	/* set DC:DBE */
+	__builtin_mtdr(8, 1 << 30);	/* set DC:RES */
+
+	/* Flush the pipeline before we declare it a failure */
+	asm volatile("sub   pc, pc, -4");
+
+	return -1;
+}
diff --git a/cpu/at32ap/device.c b/cpu/at32ap/device.c
new file mode 100644
index 0000000..89914b6
--- /dev/null
+++ b/cpu/at32ap/device.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/arch/platform.h>
+
+#include "sm.h"
+
+struct device_state {
+	int refcount;
+};
+
+static struct device_state device_state[NR_DEVICES];
+
+static int claim_resource(const struct resource *res)
+{
+	int ret = 0;
+
+	switch (res->type) {
+	case RESOURCE_GPIO:
+		ret = gpio_set_func(res->u.gpio.gpio_dev,
+				    res->u.gpio.start,
+				    res->u.gpio.nr_pins,
+				    res->u.gpio.func);
+		break;
+	case RESOURCE_CLOCK:
+		ret = pm_enable_clock(res->u.clock.id, res->u.clock.index);
+		break;
+	}
+
+	return ret;
+}
+
+static void free_resource(const struct resource *res)
+{
+	switch (res->type) {
+	case RESOURCE_GPIO:
+		gpio_free(res->u.gpio.gpio_dev, res->u.gpio.start,
+			  res->u.gpio.nr_pins);
+		break;
+	case RESOURCE_CLOCK:
+		pm_disable_clock(res->u.clock.id, res->u.clock.index);
+		break;
+	}
+}
+
+static int init_dev(const struct device *dev)
+{
+	unsigned int i;
+	int ret = 0;
+
+	for (i = 0; i < dev->nr_resources; i++) {
+		ret = claim_resource(&dev->resource[i]);
+		if (ret)
+			goto cleanup;
+	}
+
+	return 0;
+
+cleanup:
+	while (i--)
+		free_resource(&dev->resource[i]);
+
+	return ret;
+}
+
+const struct device *get_device(enum device_id devid)
+{
+	struct device_state *devstate;
+	const struct device *dev;
+	unsigned long flags;
+	int initialized = 0;
+	int ret = 0;
+
+	devstate = &device_state[devid];
+	dev = &chip_device[devid];
+
+	flags = disable_interrupts();
+	if (devstate->refcount++)
+		initialized = 1;
+	if (flags)
+		enable_interrupts();
+
+	if (!initialized)
+		ret = init_dev(dev);
+
+	return ret ? NULL : dev;
+}
+
+void put_device(const struct device *dev)
+{
+	struct device_state *devstate;
+	unsigned long devid, flags;
+
+	devid = (unsigned long)(dev - chip_device) / sizeof(struct device);
+	devstate = &device_state[devid];
+
+	flags = disable_interrupts();
+	devstate--;
+	if (!devstate) {
+		unsigned int i;
+		for (i = 0; i < dev->nr_resources; i++)
+			free_resource(&dev->resource[i]);
+	}
+	if (flags)
+		enable_interrupts();
+}
diff --git a/cpu/at32ap/entry.S b/cpu/at32ap/entry.S
new file mode 100644
index 0000000..b52d798
--- /dev/null
+++ b/cpu/at32ap/entry.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <asm/sysreg.h>
+#include <asm/ptrace.h>
+
+	.section .text.exception,"ax"
+	.global	_evba
+	.type	_evba,@function
+	.align	10
+_evba:
+	.irp	x,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
+	.align	2
+	rjmp	unknown_exception
+	.endr
+
+	.global	timer_interrupt_handler
+	.type	timer_interrupt_handler,@function
+	.align	2
+timer_interrupt_handler:
+	/*
+	 * Increment timer_overflow and re-write COMPARE with 0xffffffff.
+	 *
+	 * We're running at interrupt level 3, so we don't need to save
+	 * r8-r12 or lr to the stack.
+	 */
+	mov	r8, lo(timer_overflow)
+	orh	r8, hi(timer_overflow)
+	ld.w	r9, r8[0]
+	mov	r10, -1
+	mtsr	SYSREG_COMPARE, r10
+	sub	r9, -1
+	st.w	r8[0], r9
+	rete
+
+	.type	unknown_exception, @function
+unknown_exception:
+	pushm	r0-r12
+	sub	r8, sp, REG_R12 - REG_R0 - 4
+	mov	r9, lr
+	mfsr	r10, SYSREG_RAR_EX
+	mfsr	r11, SYSREG_RSR_EX
+	pushm	r8-r11
+	mfsr	r12, SYSREG_ECR
+	mov	r11, sp
+	rcall	do_unknown_exception
+1:	rjmp	1b
diff --git a/cpu/at32ap/exception.c b/cpu/at32ap/exception.c
new file mode 100644
index 0000000..4123c44
--- /dev/null
+++ b/cpu/at32ap/exception.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/sysreg.h>
+#include <asm/ptrace.h>
+
+static const char * const cpu_modes[8] = {
+	"Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
+	"Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
+};
+
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+{
+	unsigned long p;
+	int i;
+
+	printf("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+
+	for (p = bottom & ~31; p < top; ) {
+		printf("%04lx: ", p & 0xffff);
+
+		for (i = 0; i < 8; i++, p += 4) {
+			unsigned int val;
+
+			if (p < bottom || p >= top)
+				printf("         ");
+			else {
+				val = *(unsigned long *)p;
+				printf("%08x ", val);
+			}
+		}
+		printf("\n");
+	}
+}
+
+void do_unknown_exception(unsigned int ecr, struct pt_regs *regs)
+{
+	unsigned int mode;
+
+	printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc);
+
+	switch (ecr) {
+	case ECR_BUS_ERROR_WRITE:
+	case ECR_BUS_ERROR_READ:
+		printf("Bus error at address 0x%08lx\n",
+		       sysreg_read(BEAR));
+		break;
+	case ECR_TLB_MULTIPLE:
+	case ECR_ADDR_ALIGN_X:
+	case ECR_PROTECTION_X:
+	case ECR_ADDR_ALIGN_R:
+	case ECR_ADDR_ALIGN_W:
+	case ECR_PROTECTION_R:
+	case ECR_PROTECTION_W:
+	case ECR_DTLB_MODIFIED:
+	case ECR_TLB_MISS_X:
+	case ECR_TLB_MISS_R:
+	case ECR_TLB_MISS_W:
+		printf("MMU exception at address 0x%08lx\n",
+		       sysreg_read(TLBEAR));
+		break;
+	}
+
+	printf("   pc: %08lx    lr: %08lx    sp: %08lx   r12: %08lx\n",
+	       regs->pc, regs->lr, regs->sp, regs->r12);
+	printf("  r11: %08lx   r10: %08lx    r9: %08lx    r8: %08lx\n",
+	       regs->r11, regs->r10, regs->r9, regs->r8);
+	printf("   r7: %08lx    r6: %08lx    r5: %08lx    r4: %08lx\n",
+	       regs->r7, regs->r6, regs->r5, regs->r4);
+	printf("   r3: %08lx    r2: %08lx    r1: %08lx    r0: %08lx\n",
+	       regs->r3, regs->r2, regs->r1, regs->r0);
+	printf("Flags: %c%c%c%c%c\n",
+	       regs->sr & SR_Q ? 'Q' : 'q',
+	       regs->sr & SR_V ? 'V' : 'v',
+	       regs->sr & SR_N ? 'N' : 'n',
+	       regs->sr & SR_Z ? 'Z' : 'z',
+	       regs->sr & SR_C ? 'C' : 'c');
+	printf("Mode bits: %c%c%c%c%c%c%c%c%c\n",
+	       regs->sr & SR_H ? 'H' : 'h',
+	       regs->sr & SR_R ? 'R' : 'r',
+	       regs->sr & SR_J ? 'J' : 'j',
+	       regs->sr & SR_EM ? 'E' : 'e',
+	       regs->sr & SR_I3M ? '3' : '.',
+	       regs->sr & SR_I2M ? '2' : '.',
+	       regs->sr & SR_I1M ? '1' : '.',
+	       regs->sr & SR_I0M ? '0' : '.',
+	       regs->sr & SR_GM ? 'G' : 'g');
+	mode = (regs->sr >> SYSREG_M0_OFFSET) & 7;
+	printf("CPU Mode: %s\n", cpu_modes[mode]);
+
+	/* Avoid exception loops */
+	if (regs->sp >= CFG_INIT_SP_ADDR
+	    || regs->sp < (CFG_INIT_SP_ADDR - CONFIG_STACKSIZE))
+		printf("\nStack pointer seems bogus, won't do stack dump\n");
+	else
+		dump_mem("\nStack: ", regs->sp, CFG_INIT_SP_ADDR);
+
+	panic("Unhandled exception\n");
+}
diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c
new file mode 100644
index 0000000..f36da35
--- /dev/null
+++ b/cpu/at32ap/hsdramc.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 CFG_HSDRAMC
+#include <asm/io.h>
+#include <asm/sdram.h>
+
+#include <asm/arch/platform.h>
+
+#include "hsdramc1.h"
+
+struct hsdramc {
+	const struct device *hebi;
+	void *regs;
+};
+
+static struct hsdramc hsdramc;
+
+unsigned long sdram_init(const struct sdram_info *info)
+{
+	unsigned long *sdram = (unsigned long *)uncached(info->phys_addr);
+	unsigned long sdram_size;
+	unsigned long tmp;
+	unsigned long bus_hz;
+	unsigned int i;
+
+	hsdramc.hebi = get_device(DEVICE_HEBI);
+	if (!hsdramc.hebi)
+		return 0;
+
+	/* FIXME: Both of these lines are complete hacks */
+	hsdramc.regs = hsdramc.hebi->regs + 0x400;
+	bus_hz = pm_get_clock_freq(hsdramc.hebi->resource[0].u.clock.id);
+
+	cpu_enable_sdram();
+
+	tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
+	       | HSDRAMC1_BF(NR, info->row_bits - 11)
+	       | HSDRAMC1_BF(NB, info->bank_bits - 1)
+	       | HSDRAMC1_BF(CAS, info->cas)
+	       | HSDRAMC1_BF(TWR, info->twr)
+	       | HSDRAMC1_BF(TRC, info->trc)
+	       | HSDRAMC1_BF(TRP, info->trp)
+	       | HSDRAMC1_BF(TRCD, info->trcd)
+	       | HSDRAMC1_BF(TRAS, info->tras)
+	       | HSDRAMC1_BF(TXSR, info->txsr));
+
+#ifdef CFG_SDRAM_16BIT
+	tmp |= HSDRAMC1_BIT(DBW);
+	sdram_size = 1 << (info->row_bits + info->col_bits
+			   + info->bank_bits + 1);
+#else
+	sdram_size = 1 << (info->row_bits + info->col_bits
+			   + info->bank_bits + 2);
+#endif
+
+	hsdramc1_writel(&hsdramc, CR, tmp);
+
+	/*
+	 * Initialization sequence for SDRAM, from the data sheet:
+	 *
+	 * 1. A minimum pause of 200 us is provided to precede any
+	 *    signal toggle.
+	 */
+	udelay(200);
+
+	/*
+	 * 2. A Precharge All command is issued to the SDRAM
+	 */
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
+	hsdramc1_readl(&hsdramc, MR);
+	writel(0, sdram);
+
+	/*
+	 * 3. Eight auto-refresh (CBR) cycles are provided
+	 */
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_AUTO_REFRESH);
+	hsdramc1_readl(&hsdramc, MR);
+	for (i = 0; i < 8; i++)
+		writel(0, sdram);
+
+	/*
+	 * 4. A mode register set (MRS) cycle is issued to program
+	 *    SDRAM parameters, in particular CAS latency and burst
+	 *    length.
+	 *
+	 * CAS from info struct, burst length 1, serial burst type
+	 */
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_LOAD_MODE);
+	hsdramc1_readl(&hsdramc, MR);
+	writel(0, sdram + (info->cas << 4));
+
+	/*
+	 * 5. A Normal Mode command is provided, 3 clocks after tMRD
+	 *    is met.
+	 *
+	 * From the timing diagram, it looks like tMRD is 3
+	 * cycles...try a dummy read from the peripheral bus.
+	 */
+	hsdramc1_readl(&hsdramc, MR);
+	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_NORMAL);
+	hsdramc1_readl(&hsdramc, MR);
+	writel(0, sdram);
+
+	/*
+	 * 6. Write refresh rate into SDRAMC refresh timer count
+	 *    register (refresh rate = timing between refresh cycles).
+	 *
+	 * 15.6 us is a typical value for a burst of length one
+	 */
+	hsdramc1_writel(&hsdramc, TR, (156 * (bus_hz / 1000)) / 10000);
+
+	printf("SDRAM: %u MB at address 0x%08lx\n",
+	       sdram_size >> 20, info->phys_addr);
+
+	printf("Testing SDRAM...");
+	for (i = 0; i < sdram_size / 4; i++)
+		sdram[i] = i;
+
+	for (i = 0; i < sdram_size / 4; i++) {
+		tmp = sdram[i];
+		if (tmp != i) {
+			printf("FAILED at address 0x%08lx\n",
+			       info->phys_addr + i * 4);
+			printf("SDRAM: read 0x%lx, expected 0x%lx\n", tmp, i);
+			return 0;
+		}
+	}
+
+	puts("OK\n");
+
+	return sdram_size;
+}
+
+#endif /* CFG_HSDRAMC */
diff --git a/cpu/at32ap/hsdramc1.h b/cpu/at32ap/hsdramc1.h
new file mode 100644
index 0000000..ce229bc
--- /dev/null
+++ b/cpu/at32ap/hsdramc1.h
@@ -0,0 +1,143 @@
+/*
+ * Register definitions for SDRAM Controller
+ */
+#ifndef __ASM_AVR32_HSDRAMC1_H__
+#define __ASM_AVR32_HSDRAMC1_H__
+
+/* HSDRAMC1 register offsets */
+#define HSDRAMC1_MR				0x0000
+#define HSDRAMC1_TR				0x0004
+#define HSDRAMC1_CR				0x0008
+#define HSDRAMC1_HSR				0x000c
+#define HSDRAMC1_LPR				0x0010
+#define HSDRAMC1_IER				0x0014
+#define HSDRAMC1_IDR				0x0018
+#define HSDRAMC1_IMR				0x001c
+#define HSDRAMC1_ISR				0x0020
+#define HSDRAMC1_MDR				0x0024
+#define HSDRAMC1_VERSION			0x00fc
+
+/* Bitfields in MR */
+#define HSDRAMC1_MODE_OFFSET			0
+#define HSDRAMC1_MODE_SIZE			3
+
+/* Bitfields in TR */
+#define HSDRAMC1_COUNT_OFFSET			0
+#define HSDRAMC1_COUNT_SIZE			12
+
+/* Bitfields in CR */
+#define HSDRAMC1_NC_OFFSET			0
+#define HSDRAMC1_NC_SIZE			2
+#define HSDRAMC1_NR_OFFSET			2
+#define HSDRAMC1_NR_SIZE			2
+#define HSDRAMC1_NB_OFFSET			4
+#define HSDRAMC1_NB_SIZE			1
+#define HSDRAMC1_CAS_OFFSET			5
+#define HSDRAMC1_CAS_SIZE			2
+#define HSDRAMC1_DBW_OFFSET			7
+#define HSDRAMC1_DBW_SIZE			1
+#define HSDRAMC1_TWR_OFFSET			8
+#define HSDRAMC1_TWR_SIZE			4
+#define HSDRAMC1_TRC_OFFSET			12
+#define HSDRAMC1_TRC_SIZE			4
+#define HSDRAMC1_TRP_OFFSET			16
+#define HSDRAMC1_TRP_SIZE			4
+#define HSDRAMC1_TRCD_OFFSET			20
+#define HSDRAMC1_TRCD_SIZE			4
+#define HSDRAMC1_TRAS_OFFSET			24
+#define HSDRAMC1_TRAS_SIZE			4
+#define HSDRAMC1_TXSR_OFFSET			28
+#define HSDRAMC1_TXSR_SIZE			4
+
+/* Bitfields in HSR */
+#define HSDRAMC1_DA_OFFSET			0
+#define HSDRAMC1_DA_SIZE			1
+
+/* Bitfields in LPR */
+#define HSDRAMC1_LPCB_OFFSET			0
+#define HSDRAMC1_LPCB_SIZE			2
+#define HSDRAMC1_PASR_OFFSET			4
+#define HSDRAMC1_PASR_SIZE			3
+#define HSDRAMC1_TCSR_OFFSET			8
+#define HSDRAMC1_TCSR_SIZE			2
+#define HSDRAMC1_DS_OFFSET			10
+#define HSDRAMC1_DS_SIZE			2
+#define HSDRAMC1_TIMEOUT_OFFSET			12
+#define HSDRAMC1_TIMEOUT_SIZE			2
+
+/* Bitfields in IDR */
+#define HSDRAMC1_RES_OFFSET			0
+#define HSDRAMC1_RES_SIZE			1
+
+/* Bitfields in MDR */
+#define HSDRAMC1_MD_OFFSET			0
+#define HSDRAMC1_MD_SIZE			2
+
+/* Bitfields in VERSION */
+#define HSDRAMC1_VERSION_OFFSET			0
+#define HSDRAMC1_VERSION_SIZE			12
+#define HSDRAMC1_MFN_OFFSET			16
+#define HSDRAMC1_MFN_SIZE			3
+
+/* Constants for MODE */
+#define HSDRAMC1_MODE_NORMAL			0
+#define HSDRAMC1_MODE_NOP			1
+#define HSDRAMC1_MODE_BANKS_PRECHARGE		2
+#define HSDRAMC1_MODE_LOAD_MODE			3
+#define HSDRAMC1_MODE_AUTO_REFRESH		4
+#define HSDRAMC1_MODE_EXT_LOAD_MODE		5
+#define HSDRAMC1_MODE_POWER_DOWN		6
+
+/* Constants for NC */
+#define HSDRAMC1_NC_8_COLUMN_BITS		0
+#define HSDRAMC1_NC_9_COLUMN_BITS		1
+#define HSDRAMC1_NC_10_COLUMN_BITS		2
+#define HSDRAMC1_NC_11_COLUMN_BITS		3
+
+/* Constants for NR */
+#define HSDRAMC1_NR_11_ROW_BITS			0
+#define HSDRAMC1_NR_12_ROW_BITS			1
+#define HSDRAMC1_NR_13_ROW_BITS			2
+
+/* Constants for NB */
+#define HSDRAMC1_NB_TWO_BANKS			0
+#define HSDRAMC1_NB_FOUR_BANKS			1
+
+/* Constants for CAS */
+#define HSDRAMC1_CAS_ONE_CYCLE			1
+#define HSDRAMC1_CAS_TWO_CYCLES			2
+
+/* Constants for DBW */
+#define HSDRAMC1_DBW_32_BITS			0
+#define HSDRAMC1_DBW_16_BITS			1
+
+/* Constants for TIMEOUT */
+#define HSDRAMC1_TIMEOUT_AFTER_END		0
+#define HSDRAMC1_TIMEOUT_64_CYC_AFTER_END	1
+#define HSDRAMC1_TIMEOUT_128_CYC_AFTER_END	2
+
+/* Constants for MD */
+#define HSDRAMC1_MD_SDRAM			0
+#define HSDRAMC1_MD_LOW_POWER_SDRAM		1
+
+/* Bit manipulation macros */
+#define HSDRAMC1_BIT(name)					\
+	(1 << HSDRAMC1_##name##_OFFSET)
+#define HSDRAMC1_BF(name,value)					\
+	(((value) & ((1 << HSDRAMC1_##name##_SIZE) - 1))	\
+	 << HSDRAMC1_##name##_OFFSET)
+#define HSDRAMC1_BFEXT(name,value)				\
+	(((value) >> HSDRAMC1_##name##_OFFSET)			\
+	 & ((1 << HSDRAMC1_##name##_SIZE) - 1))
+#define HSDRAMC1_BFINS(name,value,old)				\
+	(((old) & ~(((1 << HSDRAMC1_##name##_SIZE) - 1)		\
+		    << HSDRAMC1_##name##_OFFSET))		\
+	 | HSDRAMC1_BF(name,value))
+
+/* Register access macros */
+#define hsdramc1_readl(port,reg)				\
+	readl((port)->regs + HSDRAMC1_##reg)
+#define hsdramc1_writel(port,reg,value)				\
+	writel((value), (port)->regs + HSDRAMC1_##reg)
+
+#endif /* __ASM_AVR32_HSDRAMC1_H__ */
diff --git a/cpu/at32ap/hsmc3.h b/cpu/at32ap/hsmc3.h
new file mode 100644
index 0000000..ec78cee
--- /dev/null
+++ b/cpu/at32ap/hsmc3.h
@@ -0,0 +1,126 @@
+/*
+ * Register definitions for Static Memory Controller
+ */
+#ifndef __CPU_AT32AP_HSMC3_H__
+#define __CPU_AT32AP_HSMC3_H__
+
+/* HSMC3 register offsets */
+#define HSMC3_SETUP0				0x0000
+#define HSMC3_PULSE0				0x0004
+#define HSMC3_CYCLE0				0x0008
+#define HSMC3_MODE0				0x000c
+#define HSMC3_SETUP1				0x0010
+#define HSMC3_PULSE1				0x0014
+#define HSMC3_CYCLE1				0x0018
+#define HSMC3_MODE1				0x001c
+#define HSMC3_SETUP2				0x0020
+#define HSMC3_PULSE2				0x0024
+#define HSMC3_CYCLE2				0x0028
+#define HSMC3_MODE2				0x002c
+#define HSMC3_SETUP3				0x0030
+#define HSMC3_PULSE3				0x0034
+#define HSMC3_CYCLE3				0x0038
+#define HSMC3_MODE3				0x003c
+#define HSMC3_SETUP4				0x0040
+#define HSMC3_PULSE4				0x0044
+#define HSMC3_CYCLE4				0x0048
+#define HSMC3_MODE4				0x004c
+#define HSMC3_SETUP5				0x0050
+#define HSMC3_PULSE5				0x0054
+#define HSMC3_CYCLE5				0x0058
+#define HSMC3_MODE5				0x005c
+
+/* Bitfields in SETUP0 */
+#define HSMC3_NWE_SETUP_OFFSET			0
+#define HSMC3_NWE_SETUP_SIZE			6
+#define HSMC3_NCS_WR_SETUP_OFFSET		8
+#define HSMC3_NCS_WR_SETUP_SIZE			6
+#define HSMC3_NRD_SETUP_OFFSET			16
+#define HSMC3_NRD_SETUP_SIZE			6
+#define HSMC3_NCS_RD_SETUP_OFFSET		24
+#define HSMC3_NCS_RD_SETUP_SIZE			6
+
+/* Bitfields in PULSE0 */
+#define HSMC3_NWE_PULSE_OFFSET			0
+#define HSMC3_NWE_PULSE_SIZE			7
+#define HSMC3_NCS_WR_PULSE_OFFSET		8
+#define HSMC3_NCS_WR_PULSE_SIZE			7
+#define HSMC3_NRD_PULSE_OFFSET			16
+#define HSMC3_NRD_PULSE_SIZE			7
+#define HSMC3_NCS_RD_PULSE_OFFSET		24
+#define HSMC3_NCS_RD_PULSE_SIZE			7
+
+/* Bitfields in CYCLE0 */
+#define HSMC3_NWE_CYCLE_OFFSET			0
+#define HSMC3_NWE_CYCLE_SIZE			9
+#define HSMC3_NRD_CYCLE_OFFSET			16
+#define HSMC3_NRD_CYCLE_SIZE			9
+
+/* Bitfields in MODE0 */
+#define HSMC3_READ_MODE_OFFSET			0
+#define HSMC3_READ_MODE_SIZE			1
+#define HSMC3_WRITE_MODE_OFFSET			1
+#define HSMC3_WRITE_MODE_SIZE			1
+#define HSMC3_EXNW_MODE_OFFSET			4
+#define HSMC3_EXNW_MODE_SIZE			2
+#define HSMC3_BAT_OFFSET			8
+#define HSMC3_BAT_SIZE				1
+#define HSMC3_DBW_OFFSET			12
+#define HSMC3_DBW_SIZE				2
+#define HSMC3_TDF_CYCLES_OFFSET			16
+#define HSMC3_TDF_CYCLES_SIZE			4
+#define HSMC3_TDF_MODE_OFFSET			20
+#define HSMC3_TDF_MODE_SIZE			1
+#define HSMC3_PMEN_OFFSET			24
+#define HSMC3_PMEN_SIZE				1
+#define HSMC3_PS_OFFSET				28
+#define HSMC3_PS_SIZE				2
+
+/* Bitfields in MODE1 */
+#define HSMC3_PD_OFFSET				28
+#define HSMC3_PD_SIZE				2
+
+/* Constants for READ_MODE */
+#define HSMC3_READ_MODE_NCS_CONTROLLED		0
+#define HSMC3_READ_MODE_NRD_CONTROLLED		1
+
+/* Constants for WRITE_MODE */
+#define HSMC3_WRITE_MODE_NCS_CONTROLLED		0
+#define HSMC3_WRITE_MODE_NWE_CONTROLLED		1
+
+/* Constants for EXNW_MODE */
+#define HSMC3_EXNW_MODE_DISABLED		0
+#define HSMC3_EXNW_MODE_RESERVED		1
+#define HSMC3_EXNW_MODE_FROZEN			2
+#define HSMC3_EXNW_MODE_READY			3
+
+/* Constants for BAT */
+#define HSMC3_BAT_BYTE_SELECT			0
+#define HSMC3_BAT_BYTE_WRITE			1
+
+/* Constants for DBW */
+#define HSMC3_DBW_8_BITS			0
+#define HSMC3_DBW_16_BITS			1
+#define HSMC3_DBW_32_BITS			2
+
+/* Bit manipulation macros */
+#define HSMC3_BIT(name)						\
+	(1 << HSMC3_##name##_OFFSET)
+#define HSMC3_BF(name,value)					\
+	(((value) & ((1 << HSMC3_##name##_SIZE) - 1))		\
+	 << HSMC3_##name##_OFFSET)
+#define HSMC3_BFEXT(name,value)					\
+	(((value) >> HSMC3_##name##_OFFSET)			\
+	 & ((1 << HSMC3_##name##_SIZE) - 1))
+#define HSMC3_BFINS(name,value,old)\
+	(((old) & ~(((1 << HSMC3_##name##_SIZE) - 1)		\
+		    << HSMC3_##name##_OFFSET))			\
+	 | HSMC3_BF(name,value))
+
+/* Register access macros */
+#define hsmc3_readl(port,reg)					\
+	readl((port)->regs + HSMC3_##reg)
+#define hsmc3_writel(port,reg,value)				\
+	writel((value), (port)->regs + HSMC3_##reg)
+
+#endif /* __CPU_AT32AP_HSMC3_H__ */
diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c
new file mode 100644
index 0000000..d720cfa
--- /dev/null
+++ b/cpu/at32ap/interrupts.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/div64.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/sysreg.h>
+
+#include <asm/arch/platform.h>
+
+#define HANDLER_MASK	0x00ffffff
+#define INTLEV_SHIFT	30
+#define INTLEV_MASK	0x00000003
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Incremented whenever COUNT reaches 0xffffffff by timer_interrupt_handler */
+volatile unsigned long timer_overflow;
+
+/*
+ * Instead of dividing by get_tbclk(), multiply by this constant and
+ * right-shift the result by 32 bits.
+ */
+static unsigned long tb_factor;
+
+static const struct device *intc_dev;
+
+unsigned long get_tbclk(void)
+{
+	return gd->cpu_hz;
+}
+
+unsigned long long get_ticks(void)
+{
+	unsigned long lo, hi_now, hi_prev;
+
+	do {
+		hi_prev = timer_overflow;
+		lo = sysreg_read(COUNT);
+		hi_now = timer_overflow;
+	} while (hi_prev != hi_now);
+
+	return ((unsigned long long)hi_now << 32) | lo;
+}
+
+void reset_timer(void)
+{
+	sysreg_write(COUNT, 0);
+	cpu_sync_pipeline();	/* process any pending interrupts */
+	timer_overflow = 0;
+}
+
+unsigned long get_timer(unsigned long base)
+{
+	u64 now = get_ticks();
+
+	now *= tb_factor;
+	return (unsigned long)(now >> 32) - base;
+}
+
+void set_timer(unsigned long t)
+{
+	unsigned long long ticks = t;
+	unsigned long lo, hi, hi_new;
+
+	ticks = (ticks * get_tbclk()) / CFG_HZ;
+	hi = ticks >> 32;
+	lo = ticks & 0xffffffffUL;
+
+	do {
+		timer_overflow = hi;
+		sysreg_write(COUNT, lo);
+		hi_new = timer_overflow;
+	} while (hi_new != hi);
+}
+
+/*
+ * For short delays only. It will overflow after a few seconds.
+ */
+void udelay(unsigned long usec)
+{
+	unsigned long now, end;
+
+	now = sysreg_read(COUNT);
+
+	end = ((usec * (get_tbclk() / 10000)) + 50) / 100;
+	end += now;
+
+	while (now > end)
+		now = sysreg_read(COUNT);
+
+	while (now < end)
+		now = sysreg_read(COUNT);
+}
+
+static int set_interrupt_handler(unsigned int nr, void (*handler)(void),
+				 unsigned int priority)
+{
+	unsigned long intpr;
+	unsigned long handler_addr = (unsigned long)handler;
+
+	if ((handler_addr & HANDLER_MASK) != handler_addr
+	    || (priority & INTLEV_MASK) != priority)
+		return -EINVAL;
+
+	intpr = (handler_addr & HANDLER_MASK);
+	intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT;
+	writel(intpr, intc_dev->regs + 4 * nr);
+
+	return 0;
+}
+
+void timer_init(void)
+{
+	extern void timer_interrupt_handler(void);
+	u64 tmp;
+
+	sysreg_write(COUNT, 0);
+
+	tmp = (u64)CFG_HZ << 32;
+	tmp += gd->cpu_hz / 2;
+	do_div(tmp, gd->cpu_hz);
+	tb_factor = (u32)tmp;
+
+	intc_dev = get_device(DEVICE_INTC);
+
+	if (!intc_dev
+	    || set_interrupt_handler(0, &timer_interrupt_handler, 3))
+		return;
+
+	/* For all practical purposes, this gives us an overflow interrupt */
+	sysreg_write(COMPARE, 0xffffffff);
+}
diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c
new file mode 100644
index 0000000..8b6c3a3
--- /dev/null
+++ b/cpu/at32ap/pio.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+#include "pio2.h"
+
+struct pio_state {
+	const struct device *dev;
+	u32 alloc_mask;
+};
+
+static struct pio_state pio_state[CFG_NR_PIOS];
+
+int gpio_set_func(enum device_id gpio_devid, unsigned int start,
+		  unsigned int nr_pins, enum gpio_func func)
+{
+	const struct device *gpio;
+	struct pio_state *state;
+	u32 mask;
+
+	state = &pio_state[gpio_devid - DEVICE_PIOA];
+
+	gpio = get_device(gpio_devid);
+	if (!gpio)
+		return -EBUSY;
+
+	state->dev = gpio;
+	mask = ((1 << nr_pins) - 1) << start;
+
+	if (mask & state->alloc_mask) {
+		put_device(gpio);
+		return -EBUSY;
+	}
+	state->alloc_mask |= mask;
+
+	switch (func) {
+	case GPIO_FUNC_GPIO:
+		/* TODO */
+		return -EINVAL;
+	case GPIO_FUNC_A:
+		pio2_writel(gpio, ASR, mask);
+		pio2_writel(gpio, PDR, mask);
+		pio2_writel(gpio, PUDR, mask);
+		break;
+	case GPIO_FUNC_B:
+		pio2_writel(gpio, BSR, mask);
+		pio2_writel(gpio, PDR, mask);
+		pio2_writel(gpio, PUDR, mask);
+		break;
+	}
+
+	return 0;
+}
+
+void gpio_free(enum device_id gpio_devid, unsigned int start,
+	       unsigned int nr_pins)
+{
+	const struct device *gpio;
+	struct pio_state *state;
+	u32 mask;
+
+	state = &pio_state[gpio_devid - DEVICE_PIOA];
+	gpio = state->dev;
+	mask = ((1 << nr_pins) - 1) << start;
+
+	pio2_writel(gpio, ODR, mask);
+	pio2_writel(gpio, PER, mask);
+
+	state->alloc_mask &= ~mask;
+	put_device(gpio);
+}
diff --git a/cpu/at32ap/pio2.h b/cpu/at32ap/pio2.h
new file mode 100644
index 0000000..6b79de3
--- /dev/null
+++ b/cpu/at32ap/pio2.h
@@ -0,0 +1,44 @@
+/*
+ * Register definitions for Parallel Input/Output Controller
+ */
+#ifndef __CPU_AT32AP_PIO2_H__
+#define __CPU_AT32AP_PIO2_H__
+
+/* PIO2 register offsets */
+#define PIO2_PER				0x0000
+#define PIO2_PDR				0x0004
+#define PIO2_PSR				0x0008
+#define PIO2_OER				0x0010
+#define PIO2_ODR				0x0014
+#define PIO2_OSR				0x0018
+#define PIO2_IFER				0x0020
+#define PIO2_IFDR				0x0024
+#define PIO2_ISFR				0x0028
+#define PIO2_SODR				0x0030
+#define PIO2_CODR				0x0034
+#define PIO2_ODSR				0x0038
+#define PIO2_PDSR				0x003c
+#define PIO2_IER				0x0040
+#define PIO2_IDR				0x0044
+#define PIO2_IMR				0x0048
+#define PIO2_ISR				0x004c
+#define PIO2_MDER				0x0050
+#define PIO2_MDDR				0x0054
+#define PIO2_MDSR				0x0058
+#define PIO2_PUDR				0x0060
+#define PIO2_PUER				0x0064
+#define PIO2_PUSR				0x0068
+#define PIO2_ASR				0x0070
+#define PIO2_BSR				0x0074
+#define PIO2_ABSR				0x0078
+#define PIO2_OWER				0x00a0
+#define PIO2_OWDR				0x00a4
+#define PIO2_OWSR				0x00a8
+
+/* Register access macros */
+#define pio2_readl(port,reg)				\
+	readl((port)->regs + PIO2_##reg)
+#define pio2_writel(port,reg,value)			\
+	writel((value), (port)->regs + PIO2_##reg)
+
+#endif /* __CPU_AT32AP_PIO2_H__ */
diff --git a/cpu/at32ap/pm.c b/cpu/at32ap/pm.c
new file mode 100644
index 0000000..01ac325
--- /dev/null
+++ b/cpu/at32ap/pm.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 CFG_POWER_MANAGER
+#include <asm/errno.h>
+#include <asm/io.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "sm.h"
+
+/* Sanity checks */
+#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB)		\
+	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA)	\
+	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
+# error Constraint fCPU >= fHSB >= fPB{A,B} violated
+#endif
+#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
+# error Invalid PLL multiplier and/or divider
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clock_domain_state {
+	const struct device *bridge;
+	unsigned long freq;
+	u32 mask;
+};
+static struct clock_domain_state ckd_state[NR_CLOCK_DOMAINS];
+
+int pm_enable_clock(enum clock_domain_id id, unsigned int index)
+{
+	const struct clock_domain *ckd = &chip_clock[id];
+	struct clock_domain_state *state = &ckd_state[id];
+
+	if (ckd->bridge != NO_DEVICE) {
+		state->bridge = get_device(ckd->bridge);
+		if (!state->bridge)
+			return -EBUSY;
+	}
+
+	state->mask |= 1 << index;
+	if (gd->sm)
+		writel(state->mask, gd->sm->regs + ckd->reg);
+
+	return 0;
+}
+
+void pm_disable_clock(enum clock_domain_id id, unsigned int index)
+{
+	const struct clock_domain *ckd = &chip_clock[id];
+	struct clock_domain_state *state = &ckd_state[id];
+
+	state->mask &= ~(1 << index);
+	if (gd->sm)
+		writel(state->mask, gd->sm->regs + ckd->reg);
+
+	if (ckd->bridge)
+		put_device(state->bridge);
+}
+
+unsigned long pm_get_clock_freq(enum clock_domain_id domain)
+{
+	return ckd_state[domain].freq;
+}
+
+void pm_init(void)
+{
+	uint32_t cksel = 0;
+	unsigned long main_clock;
+
+	/* Make sure we don't disable any device we're already using */
+	get_device(DEVICE_HRAMC);
+	get_device(DEVICE_HEBI);
+
+	/* Enable the PICO as well */
+	ckd_state[CLOCK_CPU].mask |= 1;
+
+	gd->sm = get_device(DEVICE_SM);
+	if (!gd->sm)
+		panic("Unable to claim system manager device!\n");
+
+	/* Disable any devices that haven't been explicitly claimed */
+	sm_writel(gd->sm, PM_PBB_MASK, ckd_state[CLOCK_PBB].mask);
+	sm_writel(gd->sm, PM_PBA_MASK, ckd_state[CLOCK_PBA].mask);
+	sm_writel(gd->sm, PM_HSB_MASK, ckd_state[CLOCK_HSB].mask);
+	sm_writel(gd->sm, PM_CPU_MASK, ckd_state[CLOCK_CPU].mask);
+
+#ifdef CONFIG_PLL
+	/* Initialize the PLL */
+	main_clock = (CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL;
+
+	sm_writel(gd->sm, PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES)
+				    | SM_BF(PLLMUL, CFG_PLL0_MUL - 1)
+				    | SM_BF(PLLDIV, CFG_PLL0_DIV - 1)
+				    | SM_BF(PLLOPT, CFG_PLL0_OPT)
+				    | SM_BF(PLLOSC, 0)
+				    | SM_BIT(PLLEN)));
+
+	/* Wait for lock */
+	while (!(sm_readl(gd->sm, PM_ISR) & SM_BIT(LOCK0))) ;
+#else
+	main_clock = CFG_OSC0_HZ;
+#endif
+
+	/* Set up clocks for the CPU and all peripheral buses */
+	if (CFG_CLKDIV_CPU) {
+		cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1);
+		ckd_state[CLOCK_CPU].freq = main_clock / (1 << CFG_CLKDIV_CPU);
+	} else {
+		ckd_state[CLOCK_CPU].freq = main_clock;
+	}
+	if (CFG_CLKDIV_HSB) {
+		cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1);
+		ckd_state[CLOCK_HSB].freq = main_clock / (1 << CFG_CLKDIV_HSB);
+	} else {
+		ckd_state[CLOCK_HSB].freq = main_clock;
+	}
+	if (CFG_CLKDIV_PBA) {
+		cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1);
+		ckd_state[CLOCK_PBA].freq = main_clock / (1 << CFG_CLKDIV_PBA);
+	} else {
+		ckd_state[CLOCK_PBA].freq = main_clock;
+	}
+	if (CFG_CLKDIV_PBB) {
+		cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1);
+		ckd_state[CLOCK_PBB].freq = main_clock / (1 << CFG_CLKDIV_PBB);
+	} else {
+		ckd_state[CLOCK_PBB].freq = main_clock;
+	}
+	sm_writel(gd->sm, PM_CKSEL, cksel);
+
+	/* CFG_HZ currently depends on cpu_hz */
+	gd->cpu_hz = ckd_state[CLOCK_CPU].freq;
+
+#ifdef CONFIG_PLL
+	/* Use PLL0 as main clock */
+	sm_writel(gd->sm, PM_MCCTRL, SM_BIT(PLLSEL));
+#endif
+}
+
+#endif /* CFG_POWER_MANAGER */
diff --git a/cpu/at32ap/sm.h b/cpu/at32ap/sm.h
new file mode 100644
index 0000000..ce81ef0
--- /dev/null
+++ b/cpu/at32ap/sm.h
@@ -0,0 +1,204 @@
+/*
+ * Register definitions for System Manager
+ */
+#ifndef __CPU_AT32AP_SM_H__
+#define __CPU_AT32AP_SM_H__
+
+/* SM register offsets */
+#define SM_PM_MCCTRL				0x0000
+#define SM_PM_CKSEL				0x0004
+#define SM_PM_CPU_MASK				0x0008
+#define SM_PM_HSB_MASK				0x000c
+#define SM_PM_PBA_MASK				0x0010
+#define SM_PM_PBB_MASK				0x0014
+#define SM_PM_PLL0				0x0020
+#define SM_PM_PLL1				0x0024
+#define SM_PM_VCTRL				0x0030
+#define SM_PM_VMREF				0x0034
+#define SM_PM_VMV				0x0038
+#define SM_PM_IER				0x0040
+#define SM_PM_IDR				0x0044
+#define SM_PM_IMR				0x0048
+#define SM_PM_ISR				0x004c
+#define SM_PM_ICR				0x0050
+#define SM_PM_GCCTRL				0x0060
+#define SM_RTC_CTRL				0x0080
+#define SM_RTC_VAL				0x0084
+#define SM_RTC_TOP				0x0088
+#define SM_RTC_IER				0x0090
+#define SM_RTC_IDR				0x0094
+#define SM_RTC_IMR				0x0098
+#define SM_RTC_ISR				0x009c
+#define SM_RTC_ICR				0x00a0
+#define SM_WDT_CTRL				0x00b0
+#define SM_WDT_CLR				0x00b4
+#define SM_WDT_EXT				0x00b8
+#define SM_RC_RCAUSE				0x00c0
+#define SM_EIM_IER				0x0100
+#define SM_EIM_IDR				0x0104
+#define SM_EIM_IMR				0x0108
+#define SM_EIM_ISR				0x010c
+#define SM_EIM_ICR				0x0110
+#define SM_EIM_MODE				0x0114
+#define SM_EIM_EDGE				0x0118
+#define SM_EIM_LEVEL				0x011c
+#define SM_EIM_TEST				0x0120
+#define SM_EIM_NMIC				0x0124
+
+/* Bitfields in PM_CKSEL */
+#define SM_CPUSEL_OFFSET			0
+#define SM_CPUSEL_SIZE				3
+#define SM_CPUDIV_OFFSET			7
+#define SM_CPUDIV_SIZE				1
+#define SM_HSBSEL_OFFSET			8
+#define SM_HSBSEL_SIZE				3
+#define SM_HSBDIV_OFFSET			15
+#define SM_HSBDIV_SIZE				1
+#define SM_PBASEL_OFFSET			16
+#define SM_PBASEL_SIZE				3
+#define SM_PBADIV_OFFSET			23
+#define SM_PBADIV_SIZE				1
+#define SM_PBBSEL_OFFSET			24
+#define SM_PBBSEL_SIZE				3
+#define SM_PBBDIV_OFFSET			31
+#define SM_PBBDIV_SIZE				1
+
+/* Bitfields in PM_PLL0 */
+#define SM_PLLEN_OFFSET				0
+#define SM_PLLEN_SIZE				1
+#define SM_PLLOSC_OFFSET			1
+#define SM_PLLOSC_SIZE				1
+#define SM_PLLOPT_OFFSET			2
+#define SM_PLLOPT_SIZE				3
+#define SM_PLLDIV_OFFSET			8
+#define SM_PLLDIV_SIZE				8
+#define SM_PLLMUL_OFFSET			16
+#define SM_PLLMUL_SIZE				8
+#define SM_PLLCOUNT_OFFSET			24
+#define SM_PLLCOUNT_SIZE			6
+#define SM_PLLTEST_OFFSET			31
+#define SM_PLLTEST_SIZE				1
+
+/* Bitfields in PM_VCTRL */
+#define SM_VAUTO_OFFSET				0
+#define SM_VAUTO_SIZE				1
+#define SM_PM_VCTRL_VAL_OFFSET			8
+#define SM_PM_VCTRL_VAL_SIZE			7
+
+/* Bitfields in PM_VMREF */
+#define SM_REFSEL_OFFSET			0
+#define SM_REFSEL_SIZE				4
+
+/* Bitfields in PM_VMV */
+#define SM_PM_VMV_VAL_OFFSET			0
+#define SM_PM_VMV_VAL_SIZE			8
+
+/* Bitfields in PM_ICR */
+#define SM_LOCK0_OFFSET				0
+#define SM_LOCK0_SIZE				1
+#define SM_LOCK1_OFFSET				1
+#define SM_LOCK1_SIZE				1
+#define SM_WAKE_OFFSET				2
+#define SM_WAKE_SIZE				1
+#define SM_VOK_OFFSET				3
+#define SM_VOK_SIZE				1
+#define SM_VMRDY_OFFSET				4
+#define SM_VMRDY_SIZE				1
+#define SM_CKRDY_OFFSET				5
+#define SM_CKRDY_SIZE				1
+
+/* Bitfields in PM_GCCTRL */
+#define SM_OSCSEL_OFFSET			0
+#define SM_OSCSEL_SIZE				1
+#define SM_PLLSEL_OFFSET			1
+#define SM_PLLSEL_SIZE				1
+#define SM_CEN_OFFSET				2
+#define SM_CEN_SIZE				1
+#define SM_CPC_OFFSET				3
+#define SM_CPC_SIZE				1
+#define SM_DIVEN_OFFSET				4
+#define SM_DIVEN_SIZE				1
+#define SM_DIV_OFFSET				8
+#define SM_DIV_SIZE				8
+
+/* Bitfields in RTC_CTRL */
+#define SM_PCLR_OFFSET				1
+#define SM_PCLR_SIZE				1
+#define SM_TOPEN_OFFSET				2
+#define SM_TOPEN_SIZE				1
+#define SM_CLKEN_OFFSET				3
+#define SM_CLKEN_SIZE				1
+#define SM_PSEL_OFFSET				8
+#define SM_PSEL_SIZE				16
+
+/* Bitfields in RTC_VAL */
+#define SM_RTC_VAL_VAL_OFFSET			0
+#define SM_RTC_VAL_VAL_SIZE			31
+
+/* Bitfields in RTC_TOP */
+#define SM_RTC_TOP_VAL_OFFSET			0
+#define SM_RTC_TOP_VAL_SIZE			32
+
+/* Bitfields in RTC_ICR */
+#define SM_TOPI_OFFSET				0
+#define SM_TOPI_SIZE				1
+
+/* Bitfields in WDT_CTRL */
+#define SM_KEY_OFFSET				24
+#define SM_KEY_SIZE				8
+
+/* Bitfields in RC_RCAUSE */
+#define SM_POR_OFFSET				0
+#define SM_POR_SIZE				1
+#define SM_BOD_OFFSET				1
+#define SM_BOD_SIZE				1
+#define SM_EXT_OFFSET				2
+#define SM_EXT_SIZE				1
+#define SM_WDT_OFFSET				3
+#define SM_WDT_SIZE				1
+#define SM_NTAE_OFFSET				4
+#define SM_NTAE_SIZE				1
+#define SM_SERP_OFFSET				5
+#define SM_SERP_SIZE				1
+
+/* Bitfields in EIM_EDGE */
+#define SM_INT0_OFFSET				0
+#define SM_INT0_SIZE				1
+#define SM_INT1_OFFSET				1
+#define SM_INT1_SIZE				1
+#define SM_INT2_OFFSET				2
+#define SM_INT2_SIZE				1
+#define SM_INT3_OFFSET				3
+#define SM_INT3_SIZE				1
+
+/* Bitfields in EIM_LEVEL */
+
+/* Bitfields in EIM_TEST */
+#define SM_TESTEN_OFFSET			31
+#define SM_TESTEN_SIZE				1
+
+/* Bitfields in EIM_NMIC */
+#define SM_EN_OFFSET				0
+#define SM_EN_SIZE				1
+
+/* Bit manipulation macros */
+#define SM_BIT(name)					\
+	(1 << SM_##name##_OFFSET)
+#define SM_BF(name,value)				\
+	(((value) & ((1 << SM_##name##_SIZE) - 1))	\
+	 << SM_##name##_OFFSET)
+#define SM_BFEXT(name,value)				\
+	(((value) >> SM_##name##_OFFSET)		\
+	 & ((1 << SM_##name##_SIZE) - 1))
+#define SM_BFINS(name,value,old)			\
+	(((old) & ~(((1 << SM_##name##_SIZE) - 1)	\
+		    << SM_##name##_OFFSET))		\
+	 | SM_BF(name,value))
+
+/* Register access macros */
+#define sm_readl(port,reg)				\
+	readl((port)->regs + SM_##reg)
+#define sm_writel(port,reg,value)			\
+	writel((value), (port)->regs + SM_##reg)
+
+#endif /* __CPU_AT32AP_SM_H__ */
diff --git a/cpu/at32ap/start.S b/cpu/at32ap/start.S
new file mode 100644
index 0000000..79ee33b
--- /dev/null
+++ b/cpu/at32ap/start.S
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <config.h>
+#include <asm/sysreg.h>
+
+#ifndef PART_SPECIFIC_BOOTSTRAP
+# define PART_SPECIFIC_BOOTSTRAP
+#endif
+
+#define SYSREG_MMUCR_I_OFFSET	2
+#define SYSREG_MMUCR_S_OFFSET	4
+
+#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
+#define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE)		\
+		    | SYSREG_BIT(FE) | SYSREG_BIT(RE)		\
+		    | SYSREG_BIT(IBE) | SYSREG_BIT(IEE))
+
+	.text
+	.global	_start
+_start:
+	PART_SPECIFIC_BOOTSTRAP
+
+	/* Reset the Status Register */
+	mov	r0, lo(SR_INIT)
+	orh	r0, hi(SR_INIT)
+	mtsr	SYSREG_SR, r0
+
+	/* Reset CPUCR and invalidate the BTB */
+	mov	r2, CPUCR_INIT
+	mtsr	SYSREG_CPUCR, r2
+
+	/* Flush the caches */
+	mov	r1, 0
+	cache	r1[4], 8
+	cache	r1[0], 0
+	sync	0
+
+	/* Reset the MMU to default settings */
+	mov	r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
+	mtsr	SYSREG_MMUCR, r0
+
+	/* Internal RAM should not need any initialization.  We might
+	   have to initialize external RAM here if the part doesn't
+	   have internal RAM (or we may use the data cache) */
+
+	/* Jump to cacheable segment */
+	lddpc	pc, 1f
+
+	.align	2
+1:	.long	2f
+
+2:	lddpc	sp, sp_init
+
+	/*
+	 * Relocate the data section and initialize .bss.  Everything
+	 * is guaranteed to be at least doubleword aligned by the
+	 * linker script.
+	 */
+	lddpc	r12, .Ldata_vma
+	lddpc	r11, .Ldata_lma
+	lddpc	r10, .Ldata_end
+	sub	r10, r12
+4:	ld.d	r8, r11++
+	sub	r10, 8
+	st.d	r12++, r8
+	brne	4b
+
+	mov	r8, 0
+	mov	r9, 0
+	lddpc	r10, .Lbss_end
+	sub	r10, r12
+4:	sub	r10, 8
+	st.d	r12++, r8
+	brne	4b
+
+	/* Initialize the GOT pointer */
+	lddpc	r6, got_init
+3:	rsub	r6, pc
+	ld.w	pc, r6[start_u_boot@got]
+
+	.align	2
+	.type	sp_init,@object
+sp_init:
+	.long	CFG_INIT_SP_ADDR
+got_init:
+	.long	3b - _GLOBAL_OFFSET_TABLE_
+.Ldata_lma:
+	.long	__data_lma
+.Ldata_vma:
+	.long	_data
+.Ldata_end:
+	.long	_edata
+.Lbss_end:
+	.long	_end
diff --git a/cpu/bf533/Makefile b/cpu/bf533/Makefile
index c63a8f6..9f4a0d8 100644
--- a/cpu/bf533/Makefile
+++ b/cpu/bf533/Makefile
@@ -2,7 +2,7 @@
 #
 # Copyright (c) 2005 blackfin.uclinux.org
 #
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -26,21 +26,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o start1.o interrupt.o cache.o cplbhdlr.o cplbmgr.o flush.o
-OBJS	= cpu.o traps.o ints.o serial.o interrupts.o
+COBJS	= cpu.o traps.o ints.o serial.o interrupts.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile
index c44412a..50534b6 100644
--- a/cpu/i386/Makefile
+++ b/cpu/i386/Makefile
@@ -1,4 +1,7 @@
 #
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
 # (C) Copyright 2002
 # Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
 #
@@ -23,22 +26,26 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o start16.o reset.o
 COBJS	= serial.o interrupts.o cpu.o timer.o sc520.o
-AOBJS	= sc520_asm.o
+SOBJS	= sc520_asm.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
 
-$(LIB):	$(COBJS) $(AOBJS)
-	$(AR) crv $@ $(COBJS) $(AOBJS)
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(COBJS:.o=.c) $(AOBJS:.o=.S)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(COBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/i386/sc520.c b/cpu/i386/sc520.c
index c83f0bb..d0a7341 100644
--- a/cpu/i386/sc520.c
+++ b/cpu/i386/sc520.c
@@ -31,7 +31,9 @@
 #include <common.h>
 #include <config.h>
 #include <pci.h>
+#ifdef CONFIG_SC520_SSI
 #include <ssi.h>
+#endif
 #include <asm/io.h>
 #include <asm/pci.h>
 #include <asm/ic/sc520.h>
@@ -143,7 +145,15 @@
 
 	u32 dram_present=0;
 	u32 dram_ctrl;
-
+#ifdef CFG_SDRAM_DRCTMCTL
+	/* these memory control registers are set up in the assember part,
+	 * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
+	 * after we are running a stack in RAM, we have troubles.  Besides,
+	 * these refresh and delay values are better ? simply specified
+	 * outright in the include/configs/{cfg} file since the HW designer
+	 * simply dictates it.
+	 */
+#else
 	int val;
 
 	int cas_precharge_delay = CFG_SDRAM_PRECHARGE_DELAY;
@@ -162,6 +172,7 @@
 	} else {
 		val = 3;  /* 62.4us */
 	}
+
 	write_mmcr_byte(SC520_DRCCTL, (read_mmcr_byte(SC520_DRCCTL) & 0xcf) | (val<<4));
 
 	val = read_mmcr_byte(SC520_DRCTMCTL);
@@ -181,13 +192,12 @@
 		val |= 1;
 	}
 	write_mmcr_byte(SC520_DRCTMCTL, val);
-
+#endif
 
 	/* We read-back the configuration of the dram
 	 * controller that the assembly code wrote */
 	dram_ctrl = read_mmcr_long(SC520_DRCBENDADR);
 
-
 	bd->bi_dram[0].start = 0;
 	if (dram_ctrl & 0x80) {
 		/* bank 0 enabled */
@@ -274,7 +284,7 @@
 {
 	int i;
 
-# if 0
+# if 1
 	printf("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq);
 #endif
 	if (irq < 0 || irq > 15) {
diff --git a/cpu/i386/sc520_asm.S b/cpu/i386/sc520_asm.S
index 80464fa..8fc713d 100644
--- a/cpu/i386/sc520_asm.S
+++ b/cpu/i386/sc520_asm.S
@@ -113,6 +113,7 @@
 .equ            DRCCFG,     0x0fffef014   /* DRAM bank configuration register */
 .equ            DRCBENDADR, 0x0fffef018   /* DRAM bank ending address register */
 .equ            ECCCTL,     0x0fffef020   /* DRAM ECC control register */
+.equ            ECCINT,     0x0fffefd18   /* DRAM ECC nmi-INT mapping */
 .equ            DBCTL,      0x0fffef040   /* DRAM buffer control register */
 
 .equ            CACHELINESZ, 0x00000010   /* size of our cache line (read buffer) */
@@ -459,6 +460,12 @@
 	incl    %edi
 	loop    cleanuplp
 
+#if defined CFG_SDRAM_DRCTMCTL
+	/* just have your hardware desinger _GIVE_ you what you need here! */
+	movl    $DRCTMCTL, %edi
+	movb    $CFG_SDRAM_DRCTMCTL,%al
+	movb    (%edi), %al
+#else
 #if defined(CFG_SDRAM_CAS_LATENCY_2T) || defined(CFG_SDRAM_CAS_LATENCY_3T)
 	/* set the CAS latency now since it is hard to do
 	 * when we run from the RAM */
@@ -472,6 +479,7 @@
 #endif
 	movb    %al, (%edi)
 #endif
+#endif
 	movl    $DRCCTL, %edi            /* DRAM Control register */
 	movb    $0x3,%al                 /* Load mode register cmd */
 	movb     %al, (%edi)
@@ -528,9 +536,49 @@
 	shll	$22, %eax
 	movl	%eax, %ebx
 
-done:	movl	%ebx, %eax
 
-	jmp	*%ebp
+done:
+	movl	%ebx, %eax
 
+#if CFG_SDRAM_ECC_ENABLE
+	/* A nominal memory test: just a byte at each address line */
+	movl    %eax, %ecx
+	shrl    $0x1, %ecx
+	movl	$0x1, %edi
+memtest0:
+	movb	$0xa5, (%edi)
+	cmpb    $0xa5, (%edi)
+	jne	out
+	shrl	$1, %ecx
+	andl	%ecx,%ecx
+	jz	set_ecc
+	shll	$1, %edi
+	jmp	memtest0
+
+set_ecc:
+	/* clear all ram with a memset */
+	movl	%eax, %ecx
+	xorl	%esi, %esi
+	xorl	%edi, %edi
+	xorl	%eax, %eax
+	shrl	$2, %ecx
+	cld
+	rep 	stosl
+			/* enable read, write buffers */
+	movb    $0x11, %al
+	movl    $DBCTL, %edi
+	movb    %al, (%edi)
+			/* enable NMI mapping for ECC */
+	movl    $ECCINT, %edi
+	mov	$0x10, %al
+	movb    %al, (%edi)
+			/* Turn on ECC */
+	movl    $ECCCTL, %edi
+	mov	$0x05, %al
+	movb    %al, (%edi)
+#endif
+out:
+	movl	%ebx, %eax
+	jmp	*%ebp
 
 #endif /* CONFIG_SC520 */
diff --git a/cpu/ixp/Makefile b/cpu/ixp/Makefile
index ba2e589..e1fb327 100644
--- a/cpu/ixp/Makefile
+++ b/cpu/ixp/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000, 2002
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= serial.o interrupts.o cpu.o timer.o pci.o
+COBJS	= serial.o interrupts.o cpu.o timer.o pci.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/ixp/npe/Makefile b/cpu/ixp/npe/Makefile
index 937de9d..4de34fd 100644
--- a/cpu/ixp/npe/Makefile
+++ b/cpu/ixp/npe/Makefile
@@ -23,11 +23,13 @@
 
 include $(TOPDIR)/config.mk
 
-LIB := libnpe.a
+LIB := $(obj)libnpe.a
 
-CFLAGS  += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB
+LOCAL_CFLAGS  += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB
+CFLAGS  += $(LOCAL_CFLAGS)
+HOST_CFLAGS  += $(LOCAL_CFLAGS)
 
-OBJS := npe.o \
+COBJS := npe.o \
 	miiphy.o \
 	IxOsalBufferMgt.o \
 	IxOsalIoMem.o \
@@ -78,14 +80,21 @@
 	IxNpeMhSolicitedCbMgr.o \
 	IxNpeMhUnsolicitedCbMgr.o
 
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
 all:	$(LIB)
 
-$(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/lh7a40x/Makefile b/cpu/lh7a40x/Makefile
index b45bd6a..bac2a64 100644
--- a/cpu/lh7a40x/Makefile
+++ b/cpu/lh7a40x/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= cpu.o speed.o interrupts.o serial.o
+COBJS	= cpu.o speed.o interrupts.o serial.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mcf52x2/Makefile b/cpu/mcf52x2/Makefile
index 879deb7..70d57cf 100644
--- a/cpu/mcf52x2/Makefile
+++ b/cpu/mcf52x2/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -25,21 +25,25 @@
 
 # CFLAGS += -DET_DEBUG
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	=
-OBJS	= serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
+COBJS	= serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mcf52x2/fec.c b/cpu/mcf52x2/fec.c
index 6db6214..b6540b5 100644
--- a/cpu/mcf52x2/fec.c
+++ b/cpu/mcf52x2/fec.c
@@ -267,6 +267,7 @@
 	fecp->fec_hash_table_high = 0;
 	fecp->fec_hash_table_low = 0;
 #endif
+#endif
 
 	/* Set maximum receive buffer size.
 	 */
diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S
index 8a83ca5..f1f4077 100644
--- a/cpu/mcf52x2/start.S
+++ b/cpu/mcf52x2/start.S
@@ -140,6 +140,7 @@
 	move.l	#(CFG_MBAR + 1), %d0		/* set IPSBAR address + valid flag */
 	move.l	%d0, 0x40000000
 
+#if defined(CONFIG_M5282)
 	/* Initialize RAMBAR1: locate SRAM and validate it */
 	move.l	#(CFG_INIT_RAM_ADDR + 0x21), %d0
 	movec	%d0, %RAMBAR1
@@ -171,6 +172,7 @@
 #endif /* (TEXT_BASE == CFG_INT_FLASH_BASE) */
 
 #endif
+#endif
 	/* if we come from a pre-loader we have no exception table and
 	 * therefore no VBR to set
 	 */
diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile
index 610043e..fd54425 100644
--- a/cpu/microblaze/Makefile
+++ b/cpu/microblaze/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= cpu.o interrupts.o
+COBJS	= cpu.o interrupts.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
-	$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mips/Makefile b/cpu/mips/Makefile
index c8b30c7..92dcc16 100644
--- a/cpu/mips/Makefile
+++ b/cpu/mips/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
+COBJS	= asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
 	  cpu.o interrupts.o incaip_clock.o
 SOBJS	= incaip_wdt.o cache.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
 
-$(LIB):	$(OBJS) $(SOBJS)
-	$(AR) crv $@ $(OBJS) $(SOBJS)
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc5xx/Makefile b/cpu/mpc5xx/Makefile
index b787b61..8aab018 100644
--- a/cpu/mpc5xx/Makefile
+++ b/cpu/mpc5xx/Makefile
@@ -1,4 +1,7 @@
 #
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
 # (C) Copyright 2003
 # Martin Winistoerfer, martinwinistoerfer@gmx.ch.
 #
@@ -32,21 +35,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
-START	= start.S
-OBJS	= serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o spi.o
+START	= start.o
+COBJS	= serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o spi.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S)  $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc5xxx/Makefile b/cpu/mpc5xxx/Makefile
index a97b625..235adb7 100644
--- a/cpu/mpc5xxx/Makefile
+++ b/cpu/mpc5xxx/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-ASOBJS	= io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
-OBJS	= i2c.o traps.o cpu.o cpu_init.o fec.o ide.o interrupts.o \
+SOBJS	= io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
+COBJS	= i2c.o traps.o cpu.o cpu_init.o fec.o ide.o interrupts.o \
 	  loadtask.o pci_mpc5200.o serial.o speed.o usb_ohci.o
 
-all:	.depend $(START) $(ASOBJS) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(ASOBJS) $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c
index 19737ce..37fe3e7 100644
--- a/cpu/mpc5xxx/fec.c
+++ b/cpu/mpc5xxx/fec.c
@@ -882,7 +882,7 @@
     defined(CONFIG_ICECUBE) || defined(CONFIG_INKA4X0)	|| \
     defined(CONFIG_MCC200)  || defined(CONFIG_O2DNT)	|| \
     defined(CONFIG_PM520)   || defined(CONFIG_TOP5200)	|| \
-    defined(CONFIG_TQM5200)
+    defined(CONFIG_TQM5200) || defined(CONFIG_V38B)
 # ifndef CONFIG_FEC_10MBIT
 	fec->xcv_type = MII100;
 # else
diff --git a/cpu/mpc5xxx/interrupts.c b/cpu/mpc5xxx/interrupts.c
index 7bacecd..beeb222 100644
--- a/cpu/mpc5xxx/interrupts.c
+++ b/cpu/mpc5xxx/interrupts.c
@@ -1,4 +1,7 @@
 /*
+ * (C) Copyright 2006
+ * Detlev Zundel, DENX Software Engineering, dzu@denx.de
+ *
  * (C) Copyright -2003
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
@@ -24,18 +27,212 @@
  * MA 02111-1307 USA
  */
 
-/*
- * interrupts.c - just enough support for the decrementer/timer
+/* this section was ripped out of arch/ppc/syslib/mpc52xx_pic.c in the
+ * Linux 2.6 source with the following copyright.
+ *
+ * Based on (well, mostly copied from) the code from the 2.4 kernel by
+ * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
+ *
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Montavista Software, Inc
  */
 
 #include <common.h>
 #include <asm/processor.h>
+#include <asm/io.h>
 #include <command.h>
 
+struct irq_action {
+	interrupt_handler_t *handler;
+	void *arg;
+	ulong count;
+};
+
+static struct irq_action irq_handlers[NR_IRQS];
+
+static struct mpc5xxx_intr *intr;
+static struct mpc5xxx_sdma *sdma;
+
+static void mpc5xxx_ic_disable(unsigned int irq)
+{
+	u32 val;
+
+	if (irq == MPC5XXX_IRQ0) {
+		val = in_be32(&intr->ctrl);
+		val &= ~(1 << 11);
+		out_be32(&intr->ctrl, val);
+	} else if (irq < MPC5XXX_IRQ1) {
+		BUG();
+	} else if (irq <= MPC5XXX_IRQ3) {
+		val = in_be32(&intr->ctrl);
+		val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1)));
+		out_be32(&intr->ctrl, val);
+	} else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
+		val = in_be32(&intr->main_mask);
+		val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE));
+		out_be32(&intr->main_mask, val);
+	} else if (irq < MPC5XXX_PERP_IRQ_BASE) {
+		val = in_be32(&sdma->IntMask);
+		val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE);
+		out_be32(&sdma->IntMask, val);
+	} else {
+		val = in_be32(&intr->per_mask);
+		val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE));
+		out_be32(&intr->per_mask, val);
+	}
+}
+
+static void mpc5xxx_ic_enable(unsigned int irq)
+{
+	u32 val;
+
+	if (irq == MPC5XXX_IRQ0) {
+		val = in_be32(&intr->ctrl);
+		val |= 1 << 11;
+		out_be32(&intr->ctrl, val);
+	} else if (irq < MPC5XXX_IRQ1) {
+		BUG();
+	} else if (irq <= MPC5XXX_IRQ3) {
+		val = in_be32(&intr->ctrl);
+		val |= 1 << (10 - (irq - MPC5XXX_IRQ1));
+		out_be32(&intr->ctrl, val);
+	} else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
+		val = in_be32(&intr->main_mask);
+		val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)));
+		out_be32(&intr->main_mask, val);
+	} else if (irq < MPC5XXX_PERP_IRQ_BASE) {
+		val = in_be32(&sdma->IntMask);
+		val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
+		out_be32(&sdma->IntMask, val);
+	} else {
+		val = in_be32(&intr->per_mask);
+		val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)));
+		out_be32(&intr->per_mask, val);
+	}
+}
+
+static void mpc5xxx_ic_ack(unsigned int irq)
+{
+	u32 val;
+
+	/*
+	 * Only some irqs are reset here, others in interrupting hardware.
+	 */
+
+	switch (irq) {
+	case MPC5XXX_IRQ0:
+		val = in_be32(&intr->ctrl);
+		val |= 0x08000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	case MPC5XXX_CCS_IRQ:
+		val = in_be32(&intr->enc_status);
+		val |= 0x00000400;
+		out_be32(&intr->enc_status, val);
+		break;
+	case MPC5XXX_IRQ1:
+		val = in_be32(&intr->ctrl);
+		val |= 0x04000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	case MPC5XXX_IRQ2:
+		val = in_be32(&intr->ctrl);
+		val |= 0x02000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	case MPC5XXX_IRQ3:
+		val = in_be32(&intr->ctrl);
+		val |= 0x01000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	default:
+		if (irq >= MPC5XXX_SDMA_IRQ_BASE
+		    && irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) {
+			out_be32(&sdma->IntPend,
+				 1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
+		}
+		break;
+	}
+}
+
+static void mpc5xxx_ic_disable_and_ack(unsigned int irq)
+{
+	mpc5xxx_ic_disable(irq);
+	mpc5xxx_ic_ack(irq);
+}
+
-int interrupt_init_cpu (ulong *decrementer_count)
+static void mpc5xxx_ic_end(unsigned int irq)
+{
+	mpc5xxx_ic_enable(irq);
+}
+
+void mpc5xxx_init_irq(void)
+{
+	u32 intr_ctrl;
+
+	/* Remap the necessary zones */
+	intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
+	sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA);
+
+	/* Disable all interrupt sources. */
+	out_be32(&sdma->IntPend, 0xffffffff);	/* 1 means clear pending */
+	out_be32(&sdma->IntMask, 0xffffffff);	/* 1 means disabled */
+	out_be32(&intr->per_mask, 0x7ffffc00);	/* 1 means disabled */
+	out_be32(&intr->main_mask, 0x00010fff);	/* 1 means disabled */
+	intr_ctrl = in_be32(&intr->ctrl);
+	intr_ctrl |= 0x0f000000 |	/* clear IRQ 0-3 */
+	    0x00ff0000 |	/* IRQ 0-3 level sensitive low active */
+	    0x00001000 |	/* MEE master external enable */
+	    0x00000000 |	/* 0 means disable IRQ 0-3 */
+	    0x00000001;		/* CEb route critical normally */
+	out_be32(&intr->ctrl, intr_ctrl);
+
+	/* Zero a bunch of the priority settings.  */
+	out_be32(&intr->per_pri1, 0);
+	out_be32(&intr->per_pri2, 0);
+	out_be32(&intr->per_pri3, 0);
+	out_be32(&intr->main_pri1, 0);
+	out_be32(&intr->main_pri2, 0);
+}
+
+int mpc5xxx_get_irq(struct pt_regs *regs)
+{
+	u32 status;
+	int irq = -1;
+
+	status = in_be32(&intr->enc_status);
+
+	if (status & 0x00000400) {	/* critical */
+		irq = (status >> 8) & 0x3;
+		if (irq == 2)	/* high priority peripheral */
+			goto peripheral;
+		irq += MPC5XXX_CRIT_IRQ_BASE;
+	} else if (status & 0x00200000) {	/* main */
+		irq = (status >> 16) & 0x1f;
+		if (irq == 4)	/* low priority peripheral */
+			goto peripheral;
+		irq += MPC5XXX_MAIN_IRQ_BASE;
+	} else if (status & 0x20000000) {	/* peripheral */
+	      peripheral:
+		irq = (status >> 24) & 0x1f;
+		if (irq == 0) {	/* bestcomm */
+			status = in_be32(&sdma->IntPend);
+			irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1;
+		} else
+			irq += MPC5XXX_PERP_IRQ_BASE;
+	}
+
+	return irq;
+}
+
+/****************************************************************************/
+
+int interrupt_init_cpu(ulong * decrementer_count)
 {
 	*decrementer_count = get_tbclk() / CFG_HZ;
 
+	mpc5xxx_init_irq();
+
 	return (0);
 }
 
@@ -44,14 +241,32 @@
 /*
  * Handle external interrupts
  */
-void
-external_interrupt(struct pt_regs *regs)
+void external_interrupt(struct pt_regs *regs)
 {
-	puts("external_interrupt (oops!)\n");
+	int irq, unmask = 1;
+
+	irq = mpc5xxx_get_irq(regs);
+
+	mpc5xxx_ic_disable_and_ack(irq);
+
+	enable_interrupts();
+
+	if (irq_handlers[irq].handler != NULL)
+		(*irq_handlers[irq].handler) (irq_handlers[irq].arg);
+	else {
+		printf("\nBogus External Interrupt IRQ %d\n", irq);
+		/*
+		 * turn off the bogus interrupt, otherwise it
+		 * might repeat forever
+		 */
+		unmask = 0;
+	}
+
+	if (unmask)
+		mpc5xxx_ic_end(irq);
 }
 
-void
-timer_interrupt_cpu (struct pt_regs *regs)
+void timer_interrupt_cpu(struct pt_regs *regs)
 {
 	/* nothing to do here */
 	return;
@@ -63,22 +278,69 @@
  * Install and free a interrupt handler.
  */
 
-void
-irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
 {
+	if (irq < 0 || irq >= NR_IRQS) {
+		printf("irq_install_handler: bad irq number %d\n", irq);
+		return;
+	}
 
+	if (irq_handlers[irq].handler != NULL)
+		printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
+		       (ulong) handler, (ulong) irq_handlers[irq].handler);
+
+	irq_handlers[irq].handler = handler;
+	irq_handlers[irq].arg = arg;
+
+	mpc5xxx_ic_enable(irq);
 }
 
-void
-irq_free_handler(int vec)
+void irq_free_handler(int irq)
 {
+	if (irq < 0 || irq >= NR_IRQS) {
+		printf("irq_free_handler: bad irq number %d\n", irq);
+		return;
+	}
 
+	mpc5xxx_ic_disable(irq);
+
+	irq_handlers[irq].handler = NULL;
+	irq_handlers[irq].arg = NULL;
 }
 
 /****************************************************************************/
 
-void
-do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
+void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
 {
-	puts("IRQ related functions are unimplemented currently.\n");
+	int irq, re_enable;
+	u32 intr_ctrl;
+	char *irq_config[] = { "level sensitive, active high",
+		"edge sensitive, rising active edge",
+		"edge sensitive, falling active edge",
+		"level sensitive, active low"
+	};
+
+	re_enable = disable_interrupts();
+
+	intr_ctrl = in_be32(&intr->ctrl);
+	printf("Interrupt configuration:\n");
+
+	for (irq = 0; irq <= 3; irq++) {
+		printf("IRQ%d: %s\n", irq,
+		       irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]);
+	}
+
+	puts("\nInterrupt-Information:\n" "Nr  Routine   Arg       Count\n");
+
+	for (irq = 0; irq < NR_IRQS; irq++)
+		if (irq_handlers[irq].handler != NULL)
+			printf("%02d  %08lx  %08lx  %ld\n", irq,
+			       (ulong) irq_handlers[irq].handler,
+			       (ulong) irq_handlers[irq].arg,
+			       irq_handlers[irq].count);
+
+	if (re_enable)
+		enable_interrupts();
 }
+#endif
diff --git a/cpu/mpc5xxx/serial.c b/cpu/mpc5xxx/serial.c
index 6cb523d..430d63f 100644
--- a/cpu/mpc5xxx/serial.c
+++ b/cpu/mpc5xxx/serial.c
@@ -166,6 +166,25 @@
 }
 
 #if defined(CONFIG_SERIAL_MULTI)
+void serial_putc_raw_dev(unsigned long dev_base, const char c)
+#else
+void serial_putc_raw(const char c)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+	/* Wait for last character to go. */
+	while (!(psc->psc_status & PSC_SR_TXEMP))
+		;
+
+	psc->psc_buffer_8 = c;
+}
+
+
+#if defined(CONFIG_SERIAL_MULTI)
 void serial_puts_dev (unsigned long dev_base, const char *s)
 #else
 void serial_puts (const char *s)
@@ -240,6 +259,43 @@
 }
 
 #if defined(CONFIG_SERIAL_MULTI)
+void serial_setrts_dev (unsigned long dev_base, int s)
+#else
+void serial_setrts(int s)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+
+	if (s) {
+		/* Assert RTS (become LOW) */
+		psc->op1 = 0x1;
+	}
+	else {
+		/* Negate RTS (become HIGH) */
+		psc->op0 = 0x1;
+	}
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_getcts_dev (unsigned long dev_base)
+#else
+int serial_getcts(void)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+
+	return (psc->ip & 0x1) ? 0 : 1;
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
 int serial0_init(void)
 {
 	return (serial_init_dev(PSC_BASE));
diff --git a/cpu/mpc8220/Makefile b/cpu/mpc8220/Makefile
index 7c9b6c9..b4fad28 100644
--- a/cpu/mpc8220/Makefile
+++ b/cpu/mpc8220/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,24 +23,28 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-ASOBJS	= io.o fec_dma_tasks.o
-OBJS	= cpu.o cpu_init.o dramSetup.o fec.o i2c.o \
+SOBJS	= io.o fec_dma_tasks.o
+COBJS	= cpu.o cpu_init.o dramSetup.o fec.o i2c.o \
 	  interrupts.o loadtask.o speed.o \
 	  traps.o uart.o pci.o
 
-all:	.depend $(START) $(ASOBJS) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(ASOBJS) $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc8220/pci.c b/cpu/mpc8220/pci.c
index ca4a04d..4ef214e 100644
--- a/cpu/mpc8220/pci.c
+++ b/cpu/mpc8220/pci.c
@@ -170,7 +170,7 @@
 	hose->region_count = 3;
 
 	hose->cfg_addr = &(xcpci->cfg_adr);
-	hose->cfg_data = CONFIG_PCI_CFG_BUS;
+	hose->cfg_data = (volatile unsigned char *)CONFIG_PCI_CFG_BUS;
 
 	pci_set_ops(hose,
 		mpc8220_pci_read_config_byte,
diff --git a/cpu/mpc824x/Makefile b/cpu/mpc824x/Makefile
index df0d64e..f249dd7 100644
--- a/cpu/mpc824x/Makefile
+++ b/cpu/mpc824x/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -22,26 +22,35 @@
 #
 
 include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)drivers/epic)
+$(shell mkdir -p $(obj)drivers/i2c)
+endif
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
-START	= start.S
-OBJS	= traps.o cpu.o cpu_init.o interrupts.o speed.o \
-	  drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o
+START	= start.o
+COBJS	= traps.o cpu.o cpu_init.o interrupts.o speed.o \
+	  drivers/epic/epic1.o drivers/i2c/i2c.o pci.o
+COBJS_LN = bedbug_603e.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) $(addprefix $(obj),$(COBJS_LN:.o=.c))
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS_LN))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
-bedbug_603e.c:
-	ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c
+$(obj)bedbug_603e.c:
+	ln -s $(src)../mpc8260/bedbug_603e.c $(obj)bedbug_603e.c
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S)  $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc824x/drivers/dma/Makefile b/cpu/mpc824x/drivers/dma/Makefile
deleted file mode 100644
index 59e2fac..0000000
--- a/cpu/mpc824x/drivers/dma/Makefile
+++ /dev/null
@@ -1,83 +0,0 @@
-##########################################################################
-#
-#       Copyright Motorola, Inc. 1997
-#       ALL RIGHTS RESERVED
-#
-#       You are hereby granted a copyright license to use, modify, and
-#       distribute the SOFTWARE so long as this entire notice is retained
-#       without alteration in any modified and/or redistributed versions,
-#       and that such modified versions are clearly identified as such.
-#       No licenses are granted by implication, estoppel or otherwise under
-#       any patents or trademarks of Motorola, Inc.
-#
-#       The SOFTWARE is provided on an "AS IS" basis and without warranty.
-#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-#       INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libdma.a
-
-DEBUG   = -DDMADBG
-LST     = -Hanno -S
-OPTIM   =
-CC      = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP    = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT   = -big_si -c
-ASDEBUG = -l -fm
-AS      = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT	=  -Bbase=0 -q -r -Qn
-LKCMD   =
-LINK    =  /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL     = rm
-COPY    = cp
-LIST    = ls
-
-OBJECTS = dma1.o dma2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
-	$(LINK) $(OBJECTS) -o $@
-
-objects: dma1.o
-
-clean:
-	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
-#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
-	$(CCobj) $<
-
-.c.s:
-	$(CCobj) $(LST) $<
-
-dma1.o: dma_export.h dma.h dma1.c
-
-dma2.o: dma.h dma2.s
diff --git a/cpu/mpc824x/drivers/dma/Makefile_pc b/cpu/mpc824x/drivers/dma/Makefile_pc
deleted file mode 100644
index 8df2a3c..0000000
--- a/cpu/mpc824x/drivers/dma/Makefile_pc
+++ /dev/null
@@ -1,89 +0,0 @@
-##########################################################################
-#
-#   makefile_pc  for use with mksnt tools   drivers/dma
-#
-#       Copyright Motorola, Inc. 1997
-#       ALL RIGHTS RESERVED
-#
-#       You are hereby granted a copyright license to use, modify, and
-#       distribute the SOFTWARE so long as this entire notice is retained
-#       without alteration in any modified and/or redistributed versions,
-#       and that such modified versions are clearly identified as such.
-#       No licenses are granted by implication, estoppel or otherwise under
-#       any patents or trademarks of Motorola, Inc.
-#
-#       The SOFTWARE is provided on an "AS IS" basis and without warranty.
-#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-#       INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libdma.a
-
-DEBUG   = -DDMADBG
-LST     = -Hanno -S
-OPTIM   =
-CC      = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP    = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT   = -big_si -c
-ASDEBUG = -l -fm
-AS      = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT	=  -Bbase=0 -q -r -Qn
-LKCMD   =
-LINK    = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL     = rm
-COPY    = cp
-LIST    = ls
-
-OBJECTS = dma1.o dma2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
-	$(LINK) $(OBJECTS) -o $@
-
-objects: dma1.o
-
-clean:
-	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
-#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
-	$(CCobj) $<
-
-.c.s:
-	$(CCobj) $(LST) $<
-
-dma1.o: dma_export.h dma.h dma1.c
-	$(CCobj) $<
-
-dma2.o: dma.h dma2.s
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
diff --git a/cpu/mpc824x/drivers/dma/README b/cpu/mpc824x/drivers/dma/README
deleted file mode 100644
index 06f4bc0..0000000
--- a/cpu/mpc824x/drivers/dma/README
+++ /dev/null
@@ -1,100 +0,0 @@
-CONTENT:
-
-   dma.h
-   dma1.c
-   dma2.s
-
-WHAT ARE THESE FILES:
-
-These files contain MPC8240 (Kahlua) DMA controller
-driver routines. The driver routines are not
-written for any specific operating system.
-They serves the purpose of code sample, and
-jump-start for using the MPC8240 DMA controller.
-
-For the reason of correctness of C language
-syntax, these files are compiled by Metaware
-C compiler and assembler.
-
-ENDIAN NOTATION:
-
-The algorithm is designed for big-endian mode,
-software is responsible for byte swapping.
-
-USAGE:
-
-1. The host system that is running on MPC8240
-   or using MPC8240 as I/O device shall link
-   the files listed here. The memory location
-   of driver routines shall take into account of
-   that driver routines need to run in supervisor
-   mode and they process DMA controller interrupt.
-
-2. The host system is responsible for configuring
-   the MPC8240 including Embedded Utilities Memory
-   Block. Since the DMA controller on MPC8240 can
-   be accessed by either local 603e core or the host
-   that MPC8240 serves as I/O processor through host
-   PCI configuration, it is important that the local
-   processor uses EUMBBAR to access its local DMA
-   controller while the PCI master uses I/O
-   processor's PCSRBAR to access the DMA controller
-   on I/O device.
-
-   To qualify whether is EUMBBAR or PCSRBAR, one
-   additional parameter is requied from the host
-   system, LOCAL or REMOTE so that the base value
-   can be correctly interpreted.
-
-3. If the host system is also using the EPIC unit
-   on MPC8240, the system can register the
-   DMA_ISR with the EPIC including other
-   desired resources.
-
-   If the host system does not using the EPIC unit
-   on MPC8240, DMA_ISR function can be called for
-   each desired time interval.
-
-   In both cases, the host system is free to
-   provide its own interrupt service routine.
-
-4. To start a direct mode DMA transaction,
-   use DMA_Bld_Curr with the start parameter
-   set to 1.
-
-   To start a chaining mode DMA transaction,
-   the application shall build descriptors
-   in memory first, next, use DMA_Bld_Desp
-   with the start parameter set to 1.
-
-5. DMA_Start function clears, then sets the CS
-   bit of DMA mode register.
-
-   DMA_Halt function clears the CS bit of DMA
-   mode register.
-
-   These functions can be used to start and
-   halt the DMA transaction.
-
-   If the chaining descriptors has been
-   modified since the last time a DMA
-   transaction started, use DMA_Chn_Cnt
-   function to let DMA controller process
-   the modified descriptor chain without
-   stopping or disturbing the current DMA
-   transaction.
-
-   It is the host system's responsibility of
-   setting up the correct DMA transfer mode
-   and pass the correct memory address parameters.
-
-6. It is the host system's responsibility of
-   queueing the DMA I/O request. The host
-   system can call the DMA_ISR with its own
-   desired interrupt service subroutines to
-   handle each individual interrupt and queued
-   DMA I/O requests.
-
-7. The DMA driver routines contains a set
-   of utilities, Set and Get, for host system
-   to query and modify the desired DMA registers.
diff --git a/cpu/mpc824x/drivers/dma/dma.h b/cpu/mpc824x/drivers/dma/dma.h
deleted file mode 100644
index a21be74..0000000
--- a/cpu/mpc824x/drivers/dma/dma.h
+++ /dev/null
@@ -1,326 +0,0 @@
-#ifndef DMA_H
-#define DMA_H
-/*******************************************************
- *
- * copyright @ Motorola 1999
- *
- *******************************************************/
-#define NUM_DMA_REG   7
-#define DMA_MR_REG    0
-#define DMA_SR_REG    1
-#define DMA_CDAR_REG  2
-#define DMA_SAR_REG   3
-#define DMA_DAR_REG   4
-#define DMA_BCR_REG   5
-#define DMA_NDAR_REG  6
-
-typedef enum _dmastatus
-{
-	DMASUCCESS = 0x1000,
-	DMALMERROR,
-	DMAPERROR,
-	DMACHNBUSY,
-	DMAEOSINT,
-	DMAEOCAINT,
-	DMAINVALID,
-	DMANOEVENT,
-} DMAStatus;
-
-typedef enum _location
-{
-	LOCAL = 0,     /* local processor accesses on board DMA,
-			          local processor's eumbbar is required */
-	REMOTE = 1,    /* PCI master accesses DMA on I/O board,
-			          I/O processor's pcsrbar is required */
-} LOCATION;
-
-typedef enum dma_mr_bit
-{
-	IRQS    = 0x00080000,
-    PDE     = 0x00040000,
-	DAHTS   = 0x00030000,
-	SAHTS   = 0x0000c000,
-	DAHE    = 0x00002000,
-	SAHE    = 0x00001000,
-	PRC     = 0x00000c00,
-	EIE     = 0x00000080,
-	EOTIE   = 0x00000040,
-	DL      = 0x00000008,
-	CTM     = 0x00000004,
-	CC      = 0x00000002,
-	CS      = 0x00000001,
-} DMA_MR_BIT;
-
-typedef enum dma_sr_bit
-{
-	LME     = 0x00000080,
-	PE      = 0x00000010,
-	CB      = 0x00000004,
-	EOSI    = 0x00000002,
-	EOCAI   = 0x00000001,
-} DMA_SR_BIT;
-
-/* structure for DMA Mode Register */
-typedef struct _dma_mr
-{
-	unsigned int  reserved0 : 12;
-	unsigned int  irqs      : 1;
-	unsigned int  pde       : 1;
-	unsigned int  dahts     : 2;
-    unsigned int  sahts     : 2;
-	unsigned int  dahe      : 1;
-	unsigned int  sahe      : 1;
-	unsigned int  prc       : 2;
-	unsigned int  reserved1 : 1;
-	unsigned int  eie       : 1;
-	unsigned int  eotie     : 1;
-	unsigned int  reserved2 : 3;
-	unsigned int  dl        : 1;
-	unsigned int  ctm       : 1;
-	/* if chaining mode is enabled, any time, user can modify the
-	 * descriptor and does not need to halt the current DMA transaction.
-	 * Set CC bit, enable DMA to process the modified descriptors
-	 * Hardware will clear this bit each time, DMA starts.
-	 */
-	unsigned int  cc        : 1;
-	/* cs bit has dua role, halt the current DMA transaction and
-	 * (re)start DMA transaction. In chaining mode, if the descriptor
-	 * needs modification, cs bit shall be used not the cc bit.
-	 * Hardware will not set/clear this bit each time DMA transaction
-	 * stops or starts. Software shall do it.
-	 *
-	 * cs bit shall not be used to halt chaining DMA transaction for
-	 * modifying the descriptor. That is the role of CC bit.
-	 */
-	unsigned int  cs        : 1;
-} DMA_MR;
-
-/* structure for DMA Status register */
-typedef struct _dma_sr
-{
-	unsigned int  reserved0 : 24;
-	unsigned int  lme       : 1;
-	unsigned int  reserved1 : 2;
-	unsigned int  pe        : 1;
-	unsigned int  reserved2 : 1;
-	unsigned int  cb        : 1;
-	unsigned int  eosi      : 1;
-	unsigned int  eocai     : 1;
-} DMA_SR;
-
-/* structure for DMA current descriptor address register */
-typedef struct _dma_cdar
-{
-	unsigned int  cda    : 27;
-	unsigned int snen    : 1;
-	unsigned int eosie   : 1;
-	unsigned int ctt     : 2;
-	unsigned int eotd    : 1;
-} DMA_CDAR;
-
-/* structure for DMA byte count register */
-typedef struct _dma_bcr
-{
-	unsigned int reserved : 6;
-	unsigned int  bcr      : 26;
-} DMA_BCR;
-
-/* structure for DMA Next Descriptor Address register */
-typedef struct _dma_ndar
-{
-	unsigned int nda    : 27;
-	unsigned int ndsnen : 1;
-	unsigned int ndeosie: 1;
-	unsigned int ndctt  : 2;
-	unsigned int eotd   : 1;
-} DMA_NDAR;
-
-/* structure for DMA current transaction info */
-typedef struct _dma_curr
-{
-	unsigned int src_addr;
-	unsigned int dest_addr;
-	unsigned int byte_cnt;
-} DMA_CURR;
-
-/************************* Kernel API********************
- * Kernel APIs are used to interface with O.S. kernel.
- * They are the functions required by O.S. kernel to
- * provide I/O service.
- ********************************************************/
-
-/**************DMA Device Control Functions ********/
-
-/**
- * Note:
- *
- * In all following functions, the host (KAHLUA) processor has a
- * choice of accessing on board local DMA (LOCAL),
- * or DMA on a distributed KAHLUA (REMOTE). In either case,
- * the caller shall pass the configured embedded utility memory
- * block base address relative to the DMA. If LOCAL DMA is used,
- * this parameter shall be EUMBBAR, if REMOTE is used, the
- * parameter shall be the corresponding PCSRBAR.
- **/
-
-/**************************************************************
- * function: DMA_Get_Stat
- *
- * description: return the content of status register of
- *              the given DMA channel
- *              if error, return DMAINVALID. Otherwise return
- *              DMASUCCESS.
- *
- **************************************************************/
-static DMAStatus DMA_Get_Stat( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_SR * );
-
-/**************************************************************
- * function: DMA_Get_Mode
- *
- * description: return the content of mode register of the
- *              given DMA channel
- *              if error, return DMAINVALID. Otherwise return DMASUCCESS.
- *
- **************************************************************/
-static DMAStatus DMA_Get_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR * );
-
-/**************************************************************
- * function: DMA_Set_Mode
- *
- * description: Set a new mode to a given DMA channel
- *              return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: It is not a good idea of changing the DMA mode during
- *       the middle of a transaction.
- **************************************************************/
-static DMAStatus DMA_Set_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR mode );
-
-/*************************************************************
- * function: DMA_ISR
- *
- * description: DMA interrupt service routine
- *              return DMAStatus based on the status
- *
- *************************************************************/
-static DMAStatus    DMA_ISR( unsigned int eumbbar,
-							 unsigned int channel,
-						     DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
-					         DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
-					         DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
-					         DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ));
-
-static DMAStatus dma_error_func( unsigned int, unsigned int, DMAStatus );
-
-/********************* DMA I/O function ********************/
-
-/************************************************************
- * function: DMA_Start
- *
- * description: start a given DMA channel transaction
- *              return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: this function will clear DMA_MR(CC) first, then
- *       set DMA_MR(CC).
- ***********************************************************/
-static DMAStatus DMA_Start( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/***********************************************************
- * function: DMA_Halt
- *
- * description: halt the current dma transaction on the specified
- *              channel.
- *              return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: if the specified DMA channel is idle, nothing happens
- *************************************************************/
-static DMAStatus DMA_Halt( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/*************************************************************
- * function: DMA_Chn_Cnt
- *
- * description: set the DMA_MR(CC) bit for a given channel
- *              that is in chaining mode.
- *              return DMASUCCESS if successfule, otherwise return DMACHNINVALID
- *
- * note: if the given channel is not in chaining mode, nothing
- *       happen.
- *
- *************************************************************/
-static DMAStatus DMA_Chn_Cnt( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/*********************** App. API ***************************
- * App. API are the APIs Kernel provides for the application
- * level program
- ************************************************************/
-/**************************************************************
- * function: DMA_Bld_Curr
- *
- * description: set current src, dest, byte count registers
- *              according to the desp for a given channel
- *
- *              if the given channel is busy,  no change made,
- *              return DMACHNBUSY.
- *
- *              otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static DMAStatus DMA_Bld_Curr( LOCATION,
-								  unsigned int eumbbar,
-								  unsigned int channel,
-							      DMA_CURR     desp );
-
-/**************************************************************
- * function: DMA_Poke_Curr
- *
- * description: poke the current src, dest, byte count registers
- *              for a given channel.
- *
- *              return DMASUCCESS if no error otherwise return DMACHNERROR
- *
- * note:        Due to the undeterministic parallelism, in chaining
- *              mode, the value returned by this function shall
- *              be taken as reference when the query is made rather
- *              than the absolute snapshot when the value is returned.
- **************************************************************/
-static DMAStatus DMA_Poke_Curr( LOCATION,
-							   unsigned int eumbbar,
-							   unsigned int channel,
-						       DMA_CURR*    desp );
-
-/**************************************************************
- * function: DMA_Bld_Desp
- *
- * description: set current descriptor address register
- *              according to the desp for a given channel
- *
- *              if the given channel is busy return DMACHNBUSY
- *              and no change made, otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static DMAStatus DMA_Bld_Desp( LOCATION host,
-					          unsigned int eumbbar,
-					          unsigned int channel,
-					          DMA_CDAR     desp );
-
-/**************************************************************
- * function: DMA_Poke_Desp
- *
- * description: poke the current descriptor address register
- *              for a given channel
- *
- *              return DMASUCCESS if no error otherwise return
- *              DMAINVALID
- *
- * note: Due to the undeterministic parallellism of DMA operation,
- *       the value returned by this function shall be taken as
- *       the most recently used descriptor when the last time
- *       DMA starts a chaining mode operation.
- **************************************************************/
-static DMAStatus DMA_Poke_Desp( LOCATION,
-							   unsigned int eumbbar,
-							   unsigned int channel,
-						       DMA_CDAR     *desp );
-
-#endif
diff --git a/cpu/mpc824x/drivers/dma/dma1.c b/cpu/mpc824x/drivers/dma/dma1.c
deleted file mode 100644
index 9c85267..0000000
--- a/cpu/mpc824x/drivers/dma/dma1.c
+++ /dev/null
@@ -1,801 +0,0 @@
-/************************************************************
- *
- * copyright @ Motorola, 1999
- *
- * App. API
- *
- * App. API are the APIs Kernel provides for the application
- * level program
- *
- ************************************************************/
-#include "dma_export.h"
-#include "dma.h"
-
-/* Define a macro to use an optional application-layer print function, if
- * one was passed to the library during initialization.  If there was no
- * function pointer passed, this protects against referencing a NULL pointer.
- * Also define The global variable that holds the passed pointer.
- */
-#define PRINT if ( app_print ) app_print
-static int (*app_print)(char *,...);
-
-/* Set by call to get_eumbbar during DMA_Initialize.
- * This could be globally available to the library, but there is
- * an advantage to passing it as a parameter: it is already in a register
- * and doesn't have to be loaded from memory.  Also, that is the way the
- * library was already implemented and I don't want to change it without
- * a more detailed analysis.
- * It is being set as a global variable during initialization to hide it from
- * the DINK application layer, because it is Kahlua-specific.  I think that
- * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
- * a Kahlua-specific library dealing with the embedded utilities memory block.
- * Right now, get_eumbbar is defined in dink32/kahlua.s.  The other two are
- * defined in dink32/drivers/i2c/i2c2.s, drivers/dma/dma2.s, etc.
- */
-static unsigned int Global_eumbbar = 0;
-extern unsigned int get_eumbbar();
-
-
-extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
-#pragma Alias( load_runtime_reg, "load_runtime_reg" );
-
-extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
-#pragma Alias( store_runtime_reg, "store_runtime_reg" );
-
-unsigned int dma_reg_tb[][14] = {
-	/* local DMA registers */
-	{
-      /* DMA_0_MR   */  0x00001100,
-      /* DMA_0_SR   */  0x00001104,
-      /* DMA_0_CDAR */  0x00001108,
-      /* DMA_0_SAR  */  0x00001110,
-      /* DMA_0_DAR  */  0x00001118,
-      /* DMA_0_BCR  */  0x00001120,
-      /* DMA_0_NDAR */  0x00001124,
-      /* DMA_1_MR   */  0x00001200,
-      /* DMA_1_SR   */  0x00001204,
-      /* DMA_1_CDAR */  0x00001208,
-      /* DMA_1_SAR  */  0x00001210,
-      /* DMA_1_DAR  */  0x00001218,
-      /* DMA_1_BCR  */  0x00001220,
-      /* DMA_1_NDAR */  0x00001224,
-	},
-	/* remote DMA registers */
-	{
-      /* DMA_0_MR   */  0x00000100,
-      /* DMA_0_SR   */  0x00000104,
-      /* DMA_0_CDAR */  0x00000108,
-      /* DMA_0_SAR  */  0x00000110,
-      /* DMA_0_DAR  */  0x00000118,
-      /* DMA_0_BCR  */  0x00000120,
-      /* DMA_0_NDAR */  0x00000124,
-      /* DMA_1_MR   */  0x00000200,
-      /* DMA_1_SR   */  0x00000204,
-      /* DMA_1_CDAR */  0x00000208,
-      /* DMA_1_SAR  */  0x00000210,
-      /* DMA_1_DAR  */  0x00000218,
-      /* DMA_1_BCR  */  0x00000220,
-      /* DMA_1_NDAR */  0x00000224,
-	},
-};
-
-/* API functions */
-
-/*  Initialize DMA unit with the following:
- *  optional pointer to application layer print function
- *
- *  These parameters may be added:
- *  ???
- *  Interrupt enables, modes, etc. are set for each transfer.
- *
- *  This function must be called before DMA unit can be used.
- */
-extern
-DMA_Status DMA_Initialize( int (*p)(char *,...))
-{
-  DMAStatus status;
-  /* establish the pointer, if there is one, to the application's "printf" */
-  app_print = p;
-
-  /* If this is the first call, get the embedded utilities memory block
-   * base address.  I'm not sure what to do about error handling here:
-   * if a non-zero value is returned, accept it.
-   */
-  if ( Global_eumbbar == 0)
-     Global_eumbbar = get_eumbbar();
-  if ( Global_eumbbar == 0)
-  {
-    PRINT( "DMA_Initialize: can't find EUMBBAR\n" );
-    return DMA_ERROR;
-  }
-
-  return DMA_SUCCESS;
-}
-
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters.  The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
-				       DMA_TRANSFER_TYPE type,
-				       unsigned int source,
-				       unsigned int dest,
-				       unsigned int len,
-				       DMA_CHANNEL channel,
-				       DMA_SNOOP_MODE snoop)
-{
-    DMA_MR md;
-    DMA_CDAR cdar;
-    /* it's inappropriate for curr to be a struct, but I'll leave it */
-    DMA_CURR curr;
-
-    DMAStatus stat;
-
-	/* The rest of this code was moved from device.c test_dma to here.
-	 * It needs to be cleaned up and validated, but at least it is removed
-	 * from the application and API.  Most of the mode is left hard coded.
-	 * This should be changed after the final API is defined and the user
-	 * application has a way to control the transfer.
-	 *
-	 */
-
-	if ( DMA_Get_Mode( LOCAL, Global_eumbbar, channel, &md ) != DMASUCCESS )
-	{
-		return DMA_ERROR;
-	}
-
-	md.irqs = int_steer;
-	md.pde = 0;
-	md.dahts = 3; /* 8 - byte */
-	md.sahts = 3; /* 8 - byte */
-	md.dahe = 0;
-	md.sahe = 0;
-	md.prc = 0;
-	/* if steering interrupts to local processor, use polling mode */
-	if ( int_steer == DMA_INT_STEER_PCI )
-	{
-		md.eie = 1;
-		md.eotie = 1;
-	} else {
-		md.eie = 0;
-		md.eotie = 0;
-	}
-	md.dl = 0;
-	md.ctm = 1;   /* direct mode */
-    md.cc = 0;
-
-	/* validate the length range */
-	if (len > 0x3ffffff )
-	{
-		PRINT( "dev DMA: length of transfer too large: %d\n", len );
-		return DMA_ERROR;
-	}
-
-	/* inappropriate to use a struct, but leave as is for now */
-	curr.src_addr = source;
-	curr.dest_addr = dest;
-	curr.byte_cnt = len;
-
-	(void)DMA_Poke_Desp( LOCAL, Global_eumbbar, channel, &cdar );
-	cdar.snen = snoop;
-	cdar.ctt = type;
-
-	if ( ( stat = DMA_Bld_Desp( LOCAL, Global_eumbbar, channel, cdar ))
-			!= DMASUCCESS ||
-		 ( stat = DMA_Bld_Curr( LOCAL, Global_eumbbar, channel, curr ))
-			!= DMASUCCESS ||
-	     ( stat = DMA_Set_Mode( LOCAL, Global_eumbbar, channel, md ))
-			!= DMASUCCESS ||
-		 ( stat = DMA_Start( LOCAL, Global_eumbbar, channel ))
-			!= DMASUCCESS )
-	{
-		if ( stat == DMACHNBUSY )
-		{
-			PRINT( "dev DMA: channel %d busy.\n", channel );
-		}
-		else
-		{
-			PRINT( "dev DMA: invalid channel request.\n", channel );
-		}
-
-		return DMA_ERROR;
-	}
-
-/* Since we are interested at the DMA performace right now,
-   we are going to do as less as possible to burden the
-   603e core.
-
-   if you have epic enabled or don't care the return from
-   DMA operation, you can just return SUCCESS.
-
-   if you don't have epic enabled and care the DMA result,
-   you can use the polling method below.
-
-   Note: I'll attempt to activate the code for handling polling.
- */
-
-#if 0
-	/* if steering interrupt to local processor, let it handle results */
-	if ( int_steer == DMA_INT_STEER_LOCAL )
-	{
-	    return DMA_SUCCESS;
-	}
-
-	/* polling since interrupt goes to PCI */
-	do
-	{
-		stat = DMA_ISR( Global_eumbbar, channel, dma_error_func,
-			dma_error_func, dma_error_func, dma_error_func );
-	}
-	while ( stat == DMANOEVENT );
-#endif
-
-    return DMA_SUCCESS;
-}
-
-/* DMA library internal functions */
-
-/**
- * Note:
- *
- * In all following functions, the host (KAHLUA) processor has a
- * choice of accessing on board local DMA (LOCAL),
- * or DMA on a distributed KAHLUA (REMOTE). In either case,
- * the caller shall pass the configured embedded utility memory
- * block base address relative to the DMA. If LOCAL DMA is used,
- * this parameter shall be EUMBBAR, if REMOTE is used, the
- * parameter shall be the corresponding PCSRBAR.
- **/
-
-/**************************************************************
- * function: DMA_Get_Stat
- *
- * description: return the content of status register of
- *              the given DMA channel
- *
- *              if error, reserved0 field all 1s.
- **************************************************************/
-static
-DMAStatus DMA_Get_Stat( LOCATION host, unsigned int eumbbar, unsigned int channel, DMA_SR *stat )
-{
-    unsigned int tmp;
-
-   if ( channel != 0 && channel != 1 || stat == 0 )
-   {
-       return DMAINVALID;
-   }
-
-    tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG] );
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) stat = 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG], tmp );
-#endif
-
-	 stat->reserved0 = ( tmp & 0xffffff00 ) >> 8;
-	 stat->lme       = ( tmp & 0x00000080 ) >> 7;
-	 stat->reserved1 = ( tmp & 0x00000060 ) >> 5;
-	 stat->pe        = ( tmp & 0x00000010 ) >> 4;
-	 stat->reserved2 = ( tmp & 0x00000008 ) >> 3;
-	 stat->cb        = ( tmp & 0x00000004 ) >> 2;
-	 stat->eosi      = ( tmp & 0x00000002 ) >> 1;
-	 stat->eocai     = ( tmp & 0x00000001 );
-
-   return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Get_Mode
- *
- * description: return the content of mode register of the
- *              given DMA channel
- *
- *              if error, return DMAINVALID, otherwise return
- *              DMASUCCESS
- **************************************************************/
-static
-DMAStatus DMA_Get_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR *mode )
-{
-    unsigned int tmp;
-   if ( channel != 0 && channel != 1 || mode == 0 )
-   {
-     return DMAINVALID;
-   }
-
-    tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG] );
-
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) mode = 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG], tmp );
-#endif
-
-	 mode->reserved0 = (tmp & 0xfff00000) >> 20;
-	 mode->irqs      = (tmp & 0x00080000) >> 19;
-	 mode->pde       = (tmp & 0x00040000) >> 18;
-	 mode->dahts     = (tmp & 0x00030000) >> 16;
-     mode->sahts     = (tmp & 0x0000c000) >> 14;
-	 mode->dahe      = (tmp & 0x00002000) >> 13;
-	 mode->sahe      = (tmp & 0x00001000) >> 12;
-	 mode->prc       = (tmp & 0x00000c00) >> 10;
-	 mode->reserved1 = (tmp & 0x00000200) >> 9;
-	 mode->eie       = (tmp & 0x00000100) >> 8;
-	 mode->eotie     = (tmp & 0x00000080) >> 7;
-	 mode->reserved2 = (tmp & 0x00000070) >> 4;
-	 mode->dl        = (tmp & 0x00000008) >> 3;
-	 mode->ctm       = (tmp & 0x00000004) >> 2;
-	 mode->cc        = (tmp & 0x00000002) >> 1;
-	 mode->cs        = (tmp & 0x00000001);
-
-   return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Set_Mode
- *
- * description: Set a new mode to a given DMA channel
- *
- * note: It is not a good idea of changing the DMA mode during
- *       the middle of a transaction.
- **************************************************************/
-static
-DMAStatus DMA_Set_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR mode )
-{
-    unsigned int tmp;
-   if ( channel != 0 && channel != 1 )
-   {
-	   return DMAINVALID;
-   }
-
-   tmp = ( mode.reserved0 & 0xfff ) << 20;
-   tmp |= ( ( mode.irqs  & 0x1 ) << 19);
-   tmp |= ( ( mode.pde   & 0x1 ) << 18 );
-   tmp |= ( ( mode.dahts & 0x3 ) << 16 );
-   tmp |= ( ( mode.sahts & 0x3 ) << 14 );
-   tmp |= ( ( mode.dahe  & 0x1 ) << 13 );
-   tmp |= ( ( mode.sahe  & 0x1 ) << 12 );
-   tmp |= ( ( mode.prc   & 0x3 ) << 10 );
-   tmp |= ( ( mode.reserved1 & 0x1 ) << 9 );
-   tmp |= ( ( mode.eie   & 0x1 ) << 8 );
-   tmp |= ( ( mode.eotie & 0x1 ) << 7 );
-   tmp |= ( ( mode.reserved2 & 0x7 ) << 4 );
-   tmp |= ( ( mode.dl    & 0x1 ) << 3 );
-   tmp |= ( ( mode.ctm   & 0x1 ) << 2 );
-   tmp |= ( ( mode.cc    & 0x1 ) << 1 ) ;
-   tmp |= ( mode.cs    & 0x1 );
-
-   store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], tmp );
-   return DMASUCCESS;
-}
-
-/************************************************************
- * function: DMA_Start
- *
- * description: start a given DMA channel transaction
- *              return DMASUCCESS if success otherwise return
- *              DMAStatus value
- *
- * note: this function will clear DMA_MR(CC) first, then
- *       set DMA_MR(CC).
- ***********************************************************/
-static
-DMAStatus DMA_Start( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
-   DMA_SR stat;
-   unsigned int mode;
-
-   if ( channel != 0 && channel != 1 )
-   {
-	   return DMAINVALID;
-   }
-
-   if ( DMA_Get_Stat( host, eumbbar, channel, &stat ) != DMASUCCESS )
-   {
-		   return DMAINVALID;
-   }
-
-   if ( stat.cb == 1 )
-   {
-	   /* DMA is not free */
-	   return DMACHNBUSY;
-   }
-
-   mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG] );
-   /* clear DMA_MR(CS) */
-   mode &= 0xfffffffe;
-   store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
-
-   /* set DMA_MR(CS) */
-   mode |= CS;
-   store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
-   return DMASUCCESS;
-}
-
-/***********************************************************
- * function: DMA_Halt
- *
- * description: halt the current dma transaction on the specified
- *              channel.
- *              return DMASUCCESS if success otherwise return DMAINVALID
- *
- * note: if the specified DMA channel is idle, nothing happens
- *************************************************************/
-static
-DMAStatus DMA_Halt( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
-   unsigned int mode;
-   if ( channel != 0 && channel != 1 )
-   {
-	   return DMAINVALID;
-   }
-
-   mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG]);
-
-   /* clear DMA_MR(CS) */
-   mode &= 0xfffffffe;
-   store_runtime_reg(eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
-   return DMASUCCESS;
-}
-
-/*************************************************************
- * function: DMA_Chn_Cnt
- *
- * description: set the DMA_MR(CC) bit for a given channel
- *              that is in chaining mode.
- *              return DMASUCCESS if successfule, otherwise return
- *              DMAINVALID.
- *
- * note: if the given channel is not in chaining mode, nothing
- *       happen.
- *
- *************************************************************/
-static
-DMAStatus DMA_Chn_Cnt( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
-	DMA_MR mode;
-	if ( channel != 0 && channel != 1 )
-	{
-		return DMAINVALID;
-	}
-
-	if ( DMA_Get_Mode( host, eumbbar, channel, &mode ) != DMASUCCESS )
-	{
-			return DMAINVALID;
-	}
-
-	if ( mode.ctm == 0 )
-	{
-		/* either illegal mode or not chaining mode */
-		return DMAINVALID;
-	}
-
-	mode.cc = 1;
-	return DMA_Set_Mode( host, eumbbar, channel, mode );
-}
-
-/**************************************************************
- * function: DMA_Bld_Desp
- *
- * description: set current descriptor address register
- *              according to the desp for a given channel
- *
- *              if the given channel is busy return DMACHNBUSY
- *              and no change made, otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static
-DMAStatus DMA_Bld_Desp( LOCATION host,
-						   unsigned int eumbbar,
-						   unsigned int channel,
-						   DMA_CDAR     desp )
-{
-	DMA_SR status;
-	unsigned int temp;
-
-	if ( channel != 0 && channel != 1 )
-	{
-		/* channel number out of range */
-		return DMAINVALID;
-	}
-
-	if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
-	{
-			return DMAINVALID;
-	}
-
-	if ( status.cb == 1 )
-	{
-		/* channel busy */
-		return DMACHNBUSY;
-	}
-
-	temp = ( desp.cda & 0x7ffffff ) << 5;
-	temp |= (( desp.snen & 0x1 ) << 4 );
-	temp |= (( desp.eosie & 0x1 ) << 3 );
-	temp |= (( desp.ctt   & 0x3 ) << 1 );
-    temp |= ( desp.eotd  & 0x1 );
-
-    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
-
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) cdar := 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
-#endif
-
-	return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Poke_Desp
- *
- * description: poke the current descriptor address register
- *              for a given channel
- *
- *              return DMASUCCESS if no error
- *
- * note: Due to the undeterministic parallellism of DMA operation,
- *       the value returned by this function shall be taken as
- *       the most recently used descriptor when the last time
- *       DMA starts a chaining mode operation.
- **************************************************************/
-static
-DMAStatus DMA_Poke_Desp( LOCATION host,
-						    unsigned int eumbbar,
-						    unsigned int channel,
-						    DMA_CDAR     *desp )
-{
-	unsigned int cdar;
-	if ( channel != 0 && channel != 1 || desp == 0 )
-	{
-			return DMAINVALID;
-	}
-
-    cdar = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG] );
-
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) cdar : 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], cdar );
-#endif
-
-
-	desp->cda   = ( cdar & 0xffffffe0 ) >> 5;
-	desp->snen  = ( cdar & 0x00000010 ) >> 4;
-	desp->eosie = ( cdar & 0x00000008 ) >> 3;
-	desp->ctt   = ( cdar & 0x00000006 ) >> 1;
-	desp->eotd  = ( cdar & 0x00000001 );
-
-	return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Bld_Curr
- *
- * description: set current src, dest, byte count registers
- *              according to the desp for a given channel
- *              return DMASUCCESS if no error.
- *
- * note:
- **************************************************************/
-static
-DMAStatus DMA_Bld_Curr( LOCATION host,
-					   unsigned int eumbbar,
-					   unsigned int channel,
-					   DMA_CURR     desp )
-{
-	DMA_SR status;
-	if ( channel != 0 && channel != 1 )
-	{
-		/* channel number out of range */
-		return DMAINVALID;
-	}
-
-	if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
-	{
-		 return DMAINVALID;
-	}
-
-	if ( status.cb == 1  )
-	{
-		/* channel busy */
-		return DMACHNBUSY;
-	}
-
-	desp.byte_cnt &= 0x03ffffff; /* upper 6-bits are 0s */
-
-    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG], desp.src_addr );
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) src := 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.src_addr );
-#endif
-
-    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG], desp.dest_addr );
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) dest := 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.dest_addr );
-#endif
-
-    store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG], desp.byte_cnt );
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) count := 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.byte_cnt );
-#endif
-
-
-	return DMASUCCESS;
-
-}
-
-/**************************************************************
- * function: DMA_Poke_Curr
- *
- * description: poke the current src, dest, byte count registers
- *              for a given channel.
- *
- *              return DMASUCCESS if no error
- *
- * note:        Due to the undeterministic parallelism, in chaining
- *              mode, the value returned by this function shall
- *              be taken as reference when the query is made rather
- *              than the absolute snapshot when the value is returned.
- **************************************************************/
-static
-DMAStatus DMA_Poke_Curr( LOCATION host,
-					    unsigned int eumbbar,
-					    unsigned int channel,
-					    DMA_CURR*    desp )
-{
-	if ( channel != 0 && channel != 1 || desp == 0 )
-	{
-			return DMAINVALID;
-	}
-
-	desp->src_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG] );
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) src : 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->src_addr );
-#endif
-
-	desp->dest_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG] );
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) dest : 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->dest_addr );
-#endif
-
-    desp->byte_cnt = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG] );
-#ifdef DMADBG0
-   PRINT( "%s(%d): %s DMA %d (0x%08x) count : 0x%08x\n", __FILE__, __LINE__,
-		  ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->byte_cnt );
-#endif
-
-
-	return DMASUCCESS;
-}
-
-/*****************************************************************
- * function: dma_error_func
- *
- * description: display the error information
- *
- * note: This seems like a highly convoluted way to handle messages,
- * but I'll leave it as it was in device.c when I moved it into the
- * DMA library source.
- ****************************************************************/
-static
-DMAStatus dma_error_func( unsigned int eumbbar, unsigned int chn, DMAStatus err)
-{
-	unsigned char *msg[] =
-		{
-			"Local Memory Error",
-			"PCI Error",
-			"Channel Busy",
-			"End-of-Segment Interrupt",
-			"End-of-Chain/Direct Interrupt",
-		};
-
-	   if ( err >= DMALMERROR && err <= DMAEOCAINT )
-	   {
-	     PRINT( "DMA Status: channel %d  %s\n", chn, msg[err-DMASUCCESS-1] );
-	   }
-
-	   return err;
-
-}
-
-/*************************************************************
- * function: DMA_ISR
- *
- * description: DMA interrupt service routine
- *              return DMAStatus value based on
- *              the status
- *
- *************************************************************/
-static
-DMAStatus DMA_ISR( unsigned int eumbbar,
-				  unsigned int channel,
-				  DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
-				  DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
-				  DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
-				  DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ))
-{
-
-	DMA_SR stat;
-	DMAStatus rval = DMANOEVENT;
-    unsigned int temp;
-
-	if ( channel != 0 && channel != 1 )
-	{
-		return DMAINVALID;
-	}
-
-	if ( DMA_Get_Stat( LOCAL, eumbbar, channel, &stat ) != DMASUCCESS )
-	{
-			return DMAINVALID;
-	}
-
-	if ( stat.lme == 1 )
-	{
-		/* local memory error */
-		rval = DMALMERROR;
-		if ( lme_func != 0 )
-		{
-		  rval = (*lme_func)(eumbbar, channel, DMALMERROR );
-	    }
-
-	}
-	else if ( stat.pe == 1 )
-	{
-	/* PCI error */
-		rval = DMAPERROR;
-		if ( pe_func != 0 )
-		{
-		  rval = (*pe_func)(eumbbar, channel, DMAPERROR );
-	    }
-
-	}
-	else if ( stat.eosi == 1 )
-	{
-		/* end-of-segment interrupt */
-		rval = DMAEOSINT;
-		if ( eosi_func != 0 )
-		{
-		  rval = (*eosi_func)(eumbbar, channel, DMAEOSINT );
-	    }
-	}
-	else
-	{
-		/* End-of-chain/direct interrupt */
-		rval = DMAEOCAINT;
-		if ( eocai_func != 0 )
-		{
-		  rval = (*eocai_func)(eumbbar, channel, DMAEOCAINT );
-	    }
-	}
-
-    temp = ( stat.reserved0 & 0xffffff ) << 8;
-	temp |= ( ( stat.lme       & 0x1 ) << 7 );  /* write one to clear */
-	temp |= ( ( stat.reserved1 & 0x3 ) << 5 );
-    temp |= ( ( stat.pe        & 0x1 ) << 4 );  /* write one to clear */
-    temp |= ( ( stat.reserved2 & 0x1 ) << 3 );
-	temp |= ( ( stat.cb        & 0x1 ) << 2 );  /* write one to clear */
-    temp |= ( ( stat.eosi      & 0x1 ) << 1 );  /* write one to clear */
-    temp |= ( stat.eocai & 0x1 );               /* write one to clear */
-
-    store_runtime_reg( eumbbar, dma_reg_tb[LOCAL][channel*NUM_DMA_REG + DMA_SR_REG], temp );
-
-#ifdef DMADBG0
-	PRINT( "%s(%d): DMA channel %d SR := 0x%08x\n", __FILE__, __LINE__, channel, temp );
-#endif
-
-	return rval;
-}
diff --git a/cpu/mpc824x/drivers/dma/dma2.S b/cpu/mpc824x/drivers/dma/dma2.S
deleted file mode 100644
index ccbc226..0000000
--- a/cpu/mpc824x/drivers/dma/dma2.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-/**********************************************************
- * function: load_runtime_reg
- *
- * input:  r3 - value of eumbbar
- *         r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
-	.text
-	.align 2
-	.global load_runtime_reg
-
-load_runtime_reg:
-
-	lwbrx	r3,r4,r3
-	sync
-
-	bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- *        r4 - register offset in embedded utility space
- *        r5 - new value to be stored
- *
- ****************************************************************/
-	.text
-	.align 2
-	.global store_runtime_reg
-store_runtime_reg:
-
-	stwbrx r5,  r4, r3
-	sync
-
-	bclr   20,0
diff --git a/cpu/mpc824x/drivers/dma/dma_export.h b/cpu/mpc824x/drivers/dma/dma_export.h
deleted file mode 100644
index 471e488..0000000
--- a/cpu/mpc824x/drivers/dma/dma_export.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef DMA_EXPORT_H
-#define DMA_EXPORT_H
-
-/****************************************************
- * $Id:
- *
- * Copyright Motorola 1999
- *
- * $Log:
- *
- ****************************************************/
-
-/* These are the defined return values for the DMA_* functions.
- * Any non-zero value indicates failure.  Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _dma_status
-{
- DMA_SUCCESS     = 0,
- DMA_ERROR,
-} DMA_Status;
-
-/* These are the defined channel transfer types.  */
-typedef enum _dma_transfer_types
-{
-	DMA_M2M =  0,	/* local memory to local memory */
-	DMA_M2P =  1,	/* local memory to PCI */
-	DMA_P2M =  2,	/* PCI to local memory */
-	DMA_P2P =  3,	/* PCI to PCI */
-} DMA_TRANSFER_TYPE;
-
-typedef enum _dma_interrupt_steer
-{
-	DMA_INT_STEER_LOCAL =  0, /* steer DMA int to local processor */
-	DMA_INT_STEER_PCI = 1,    /* steer DMA int to PCI bus through INTA_ */
-} DMA_INTERRUPT_STEER;
-
-typedef enum _dma_channel
-{
-	DMA_CHN_0 =  0, /* kahlua has two dma channels: 0 and 1 */
-	DMA_CHN_1 =  1,
-} DMA_CHANNEL;
-
-typedef enum _dma_snoop_mode
-{
-	DMA_SNOOP_DISABLE =  0,
-	DMA_SNOOP_ENABLE = 1,
-} DMA_SNOOP_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by DMA driver.
- * This is a "generic" DMA interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- *       byte. In our API, we currently transfer whatever
- *       we are given - Big/Little Endian.  This could
- *       become part of the DMA config, though.
- **************************************************/
-
-
-/*  Initialize DMA unit with the following:
- *  optional pointer to application layer print function
- *
- *  These parameters may be added:
- *  ???
- *  Interrupt enables, modes, etc. are set for each transfer.
- *
- *  This function must be called before DMA unit can be used.
- */
-extern DMA_Status DMA_Initialize(
-	int (*app_print_function)(char *,...)); /* pointer to optional "printf"
-						 * provided by application
-						 */
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters.  The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
-				       DMA_TRANSFER_TYPE type,
-				       unsigned int source,
-				       unsigned int dest,
-				       unsigned int len,
-				       DMA_CHANNEL channel,
-				       DMA_SNOOP_MODE snoop);
-#endif
diff --git a/cpu/mpc824x/drivers/dma_export.h b/cpu/mpc824x/drivers/dma_export.h
deleted file mode 100644
index 471e488..0000000
--- a/cpu/mpc824x/drivers/dma_export.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef DMA_EXPORT_H
-#define DMA_EXPORT_H
-
-/****************************************************
- * $Id:
- *
- * Copyright Motorola 1999
- *
- * $Log:
- *
- ****************************************************/
-
-/* These are the defined return values for the DMA_* functions.
- * Any non-zero value indicates failure.  Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _dma_status
-{
- DMA_SUCCESS     = 0,
- DMA_ERROR,
-} DMA_Status;
-
-/* These are the defined channel transfer types.  */
-typedef enum _dma_transfer_types
-{
-	DMA_M2M =  0,	/* local memory to local memory */
-	DMA_M2P =  1,	/* local memory to PCI */
-	DMA_P2M =  2,	/* PCI to local memory */
-	DMA_P2P =  3,	/* PCI to PCI */
-} DMA_TRANSFER_TYPE;
-
-typedef enum _dma_interrupt_steer
-{
-	DMA_INT_STEER_LOCAL =  0, /* steer DMA int to local processor */
-	DMA_INT_STEER_PCI = 1,    /* steer DMA int to PCI bus through INTA_ */
-} DMA_INTERRUPT_STEER;
-
-typedef enum _dma_channel
-{
-	DMA_CHN_0 =  0, /* kahlua has two dma channels: 0 and 1 */
-	DMA_CHN_1 =  1,
-} DMA_CHANNEL;
-
-typedef enum _dma_snoop_mode
-{
-	DMA_SNOOP_DISABLE =  0,
-	DMA_SNOOP_ENABLE = 1,
-} DMA_SNOOP_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by DMA driver.
- * This is a "generic" DMA interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- *       byte. In our API, we currently transfer whatever
- *       we are given - Big/Little Endian.  This could
- *       become part of the DMA config, though.
- **************************************************/
-
-
-/*  Initialize DMA unit with the following:
- *  optional pointer to application layer print function
- *
- *  These parameters may be added:
- *  ???
- *  Interrupt enables, modes, etc. are set for each transfer.
- *
- *  This function must be called before DMA unit can be used.
- */
-extern DMA_Status DMA_Initialize(
-	int (*app_print_function)(char *,...)); /* pointer to optional "printf"
-						 * provided by application
-						 */
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters.  The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
-				       DMA_TRANSFER_TYPE type,
-				       unsigned int source,
-				       unsigned int dest,
-				       unsigned int len,
-				       DMA_CHANNEL channel,
-				       DMA_SNOOP_MODE snoop);
-#endif
diff --git a/cpu/mpc824x/drivers/i2o.h b/cpu/mpc824x/drivers/i2o.h
deleted file mode 100644
index c47253d..0000000
--- a/cpu/mpc824x/drivers/i2o.h
+++ /dev/null
@@ -1,344 +0,0 @@
-#ifndef I2O_H
-#define I2O_H
-/*********************************************************
- *
- * copyright @ Motorola, 1999
- *********************************************************/
-
-#define I2O_REG_OFFSET 0x0004
-
-#define PCI_CFG_CLA    0x0B
-#define PCI_CFG_SCL    0x0A
-#define PCI_CFG_PIC    0x09
-
-#define I2O_IMR0 0x0050
-#define I2O_IMR1 0x0054
-#define I2O_OMR0 0x0058
-#define I2O_OMR1 0x005C
-
-#define I2O_ODBR 0x0060
-#define I2O_IDBR 0x0068
-
-#define I2O_OMISR  0x0030
-#define I2O_OMIMR  0x0034
-#define I2O_IMISR  0x0100
-#define I2O_IMIMR  0x0104
-
-/* accessable to PCI master but local processor */
-#define I2O_IFQPR  0x0040
-#define I2O_OFQPR  0x0044
-
-/* accessable to local processor */
-#define I2O_IFHPR  0x0120
-#define I2O_IFTPR  0x0128
-#define I2O_IPHPR  0x0130
-#define I2O_IPTPR  0x0138
-#define I2O_OFHPR  0x0140
-#define I2O_OFTPR  0x0148
-#define I2O_OPHPR  0x0150
-#define I2O_OPTPR  0x0158
-#define I2O_MUCR   0x0164
-#define I2O_QBAR   0x0170
-
-#define I2O_NUM_MSG 2
-
-typedef enum _i2o_status
-{
-	I2OSUCCESS = 0,
-	I2OINVALID,
-	I2OMSGINVALID,
-	I2ODBINVALID,
-	I2OQUEINVALID,
-	I2OQUEEMPTY,
-	I2OQUEFULL,
-	I2ONOEVENT,
-} I2OSTATUS;
-
-typedef enum _queue_size
-{
-    QSIZE_4K = 0x02,
-    QSIZE_8K = 0x04,
-    QSIZE_16K = 0x08,
-    QSIZE_32K = 0x10,
-    QSIZe_64K = 0x20,
-} QUEUE_SIZE;
-
-typedef enum _location
-{
-    LOCAL = 0,     /* used by local processor to access its own on board device,
-		      local processor's eumbbar is required */
-    REMOTE,        /* used by PCI master to access the devices on its PCI device,
-		      device's pcsrbar is required */
-} LOCATION;
-
-/* door bell */
-typedef enum _i2o_in_db
-{
-  IN_DB = 1,
-  MC,         /* machine check */
-} I2O_IN_DB;
-
-/* I2O PCI configuration identification */
-typedef struct _i2o_iop
-{
-	unsigned int base_class : 8;
-	unsigned int sub_class  : 8;
-	unsigned int prg_code   : 8;
-} I2OIOP;
-
-/* I2O Outbound Message Interrupt Status Register */
-typedef struct _i2o_om_stat
-{
-	unsigned int rsvd0 : 26;
-	unsigned int opqi  : 1;
-	unsigned int rsvd1 : 1;
-	unsigned int odi   : 1;
-	unsigned int rsvd2 : 1;
-	unsigned int om1i  : 1;
-	unsigned int om0i  : 1;
-} I2OOMSTAT;
-
-/* I2O inbound Message Interrupt Status Register */
-typedef struct _i2o_im_stat
-{
-	unsigned int rsvd0 : 23;
-	unsigned int ofoi  : 1;
-	unsigned int ipoi  : 1;
-	unsigned int rsvd1 : 1;
-	unsigned int ipqi  : 1;
-	unsigned int mci   : 1;
-	unsigned int idi   : 1;
-	unsigned int rsvd2 : 1;
-	unsigned int im1i  : 1;
-	unsigned int im0i  : 1;
-} I2OIMSTAT;
-
-/**
- Enable the interrupt associated with in/out bound msg
-
- Inbound message interrupt generated by PCI master and serviced by local processor
- local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
-
- Outbound message interrupt generated by local processor and serviced by PCI master
- PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
- **/
-extern I2OSTATUS I2OMsgEnable( LOCATION,            /*  REMOTE/LOCAL   */
-			       unsigned int base,   /* pcsrbar/eumbbar */
-			       unsigned char n );   /* b'1' - msg 0
-									     * b'10'- msg 1
-									     * b'11'- both
-									     */
-
-/**
- Disable the interrupt associated with in/out bound msg
-
- local processor needs to disable its inbound interrupts it is not interested (LOCAL)
-
- PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
- **/
-extern I2OSTATUS I2OMsgDisable( LOCATION,          /*  REMOTE/LOCAL   */
-				unsigned int base, /* pcsrbar/eumbbar */
-				unsigned char n ); /* b'1' - msg 0
-									    * b'10'- msg 1
-									    * b'11'- both
-									    */
-
-/**
- Read the msg register either from local inbound msg 0/1,
- or an outbound msg 0/1 of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outbound msg of the device is read.
- Otherwise local inbound msg is read.
- **/
-extern I2OSTATUS I2OMsgGet ( LOCATION,                 /* REMOTE/LOCAL */
-			     unsigned int base,        /*pcsrbar/eumbbar */
-			     unsigned int n,           /* 0 or 1 */
-			     unsigned int *msg );
-
-/**
- Write to nth Msg register either on local outbound msg 0/1,
- or aninbound msg 0/1 of devices
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, inbound msg on the device is written.
- Otherwise local outbound msg is written.
- **/
-extern I2OSTATUS I2OMsgPost( LOCATION,                 /* REMOTE/LOCAL */
-				unsigned int base,        /*pcsrbar/eumbbar */
-				unsigned int n,           /* 0 or 1 */
-				unsigned int msg );
-
-/**
- Enable the In/Out DoorBell Interrupt
-
- InDoorBell interrupt is generated by PCI master and serviced by local processor
- local processor needs to enable its inbound doorbell interrupts it wants to handle
-
- OutDoorbell interrupt is generated by local processor and serviced by PCI master
- PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
- **/
-extern I2OSTATUS I2ODBEnable( LOCATION,            /*  REMOTE/LOCAL   */
-			      unsigned int base,   /* pcsrbar/eumbbar */
-			      unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Disable the In/Out DoorBell Interrupt
-
- local processor needs to disable its inbound doorbell interrupts it is not interested
-
- PCI master needs to disable outbound doorbell interrupts of devices it is not interested
-
- **/
-extern I2OSTATUS I2ODBDisable( LOCATION,              /*  REMOTE/LOCAL   */
-			       unsigned int base,     /* pcsrbar/eumbbar */
-			       unsigned int in_db );  /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Read a local indoorbell register, or an outdoorbell of devices.
- Reading a doorbell register, the register will be cleared.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outdoorbell register on the device is read.
- Otherwise local in doorbell is read
- **/
-extern unsigned int I2ODBGet( LOCATION,             /*  REMOTE/LOCAL   */
-			      unsigned int base);   /* pcsrbar/eumbbar */
-
-/**
- Write to a local outdoorbell register, or an indoorbell register of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, in doorbell register on the device is written.
- Otherwise local out doorbell is written
- **/
-extern void I2ODBPost( LOCATION,                 /*  REMOTE/LOCAL   */
-		       unsigned int base,        /* pcsrbar/eumbbar */
-		       unsigned int msg );       /*   in   / out    */
-
-/**
- Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
- the register will be cleared.
-
- The outbound interrupt status is AND with the outbound
- interrupt mask. The result is returned.
-
- PCI master must pass the pcsrbar to the function.
- **/
-extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
-
-/**
- Read the inbound msg unit interrupt status. Reading an interrupt status register,
- the register will be cleared.
-
- The inbound interrupt status is AND with the inbound
- interrupt mask. The result is returned.
-
- Local process must pass its eumbbar to the function.
-**/
-extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
-
-/**
- Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
- MUCR.
- **/
-extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
-					      QUEUE_SIZE,
-					      unsigned int qba);/* queue base address that must be aligned at 1M */
-/**
- Enable the circular queue
- **/
-extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue
- **/
-extern void I2OFIFODisable( unsigned int eumbbar );
-
-/**
- Enable the circular queue interrupt
- PCI master enables outbound FIFO interrupt of device
- Device enables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntEnable( LOCATION, unsigned int base  );
-
-/**
- Disable the circular queue interrupt
- PCI master disables outbound FIFO interrupt of device
- Device disables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
-
-/**
- Enable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
-
-/**
- Allocate a free msg frame from free FIFO.
-
- PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
- while local processor allocates a free msg frame from outbound free queue(OFTPR)
-
- Unless both free queues are initialized, allocating a free MF will return 0xffffffff
- **/
-extern I2OSTATUS I2OFIFOAlloc( LOCATION,
-					       unsigned int base,
-					       void         **pMsg);
-/**
- Free a used msg frame back to free queue
- PCI Master frees a MFA through outbound queue port of device(OFQPR)
- while local processor frees a MFA into its inbound free queue(IFHPR)
-
- Used msg frame does not need to be recycled in the order they
- read
-
- This function has to be called by PCI master to initialize Inbound free queue
- and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
- **/
-extern I2OSTATUS I2OFIFOFree( LOCATION,
-					  unsigned int base,
-					  void        *pMsg );
-
-/**
- Post a msg into FIFO
- PCI Master posts a msg through inbound queue port of device(IFQPR)
- while local processor post a msg into its outbound post queue(OPHPR)
-
- The total number of msg must be less than the max size of the queue
- Otherwise queue overflow interrupt will assert.
- **/
-extern I2OSTATUS I2OFIFOPost( LOCATION,
-				      unsigned int base,
-				      void         *pMsg );
-
-/**
- Read a msg from FIFO
- PCI Master reads a msg through outbound queue port of device(OFQPR)
- while local processor reads a msg from its inbound post queue(IPTPR)
- **/
-extern I2OSTATUS I2OFIFOGet( LOCATION,
-					  unsigned int base,
-							  void     **pMsg );
-
-/**
- Get the I2O PCI configuration identification register
- **/
-extern I2OSTATUS I2OPCIConfigGet( LOCATION,
-					   unsigned int base,
-							   I2OIOP *);
-
-#endif
diff --git a/cpu/mpc824x/drivers/i2o/Makefile b/cpu/mpc824x/drivers/i2o/Makefile
deleted file mode 100644
index 3f5ca26..0000000
--- a/cpu/mpc824x/drivers/i2o/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-##########################################################################
-#
-#       Copyright Motorola, Inc. 1997
-#       ALL RIGHTS RESERVED
-#
-#       You are hereby granted a copyright license to use, modify, and
-#       distribute the SOFTWARE so long as this entire notice is retained
-#       without alteration in any modified and/or redistributed versions,
-#       and that such modified versions are clearly identified as such.
-#       No licenses are granted by implication, estoppel or otherwise under
-#       any patents or trademarks of Motorola, Inc.
-#
-#       The SOFTWARE is provided on an "AS IS" basis and without warranty.
-#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-#       INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2o.a
-
-#DEBUG  = -g
-DEBUG   =
-LST     = -Hanno -S
-OPTIM   =
-CC      = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP    = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT   = -big_si -c
-ASDEBUG  = -l -fm
-AS      = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT	=  -Bbase=0 -Qn -q -r
-LKCMD    =
-LINK    =  /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL     = rm
-COPY    = cp
-LIST    = ls
-
-OBJECTS = i2o1.o i2o2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
-	$(LINK) $(OBJECTS) -o $@
-
-objects: i2o1.o
-
-clean:
-	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
-#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
-	$(CCobj) $<
-
-.c.s:
-	$(CCobj) $(LST) $<
-
-i2o1.o: i2o.h i2o1.c
-
-i2o2.o: i2o.h i2o2.s
diff --git a/cpu/mpc824x/drivers/i2o/Makefile_pc b/cpu/mpc824x/drivers/i2o/Makefile_pc
deleted file mode 100644
index 6867f58..0000000
--- a/cpu/mpc824x/drivers/i2o/Makefile_pc
+++ /dev/null
@@ -1,90 +0,0 @@
-##########################################################################
-#
-#      makefile_pc for use with PC mksnt tools   dink32/drivers/i2o
-#
-#       Copyright Motorola, Inc. 1997
-#       ALL RIGHTS RESERVED
-#
-#       You are hereby granted a copyright license to use, modify, and
-#       distribute the SOFTWARE so long as this entire notice is retained
-#       without alteration in any modified and/or redistributed versions,
-#       and that such modified versions are clearly identified as such.
-#       No licenses are granted by implication, estoppel or otherwise under
-#       any patents or trademarks of Motorola, Inc.
-#
-#       The SOFTWARE is provided on an "AS IS" basis and without warranty.
-#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-#       INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2o.a
-
-#DEBUG  = -g
-DEBUG   =
-LST     = -Hanno -S
-OPTIM   =
-CC      = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP    = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT   = -big_si -c
-ASDEBUG  = -l -fm
-AS      = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT	=  -Bbase=0 -Qn -q -r
-LKCMD    =
-LINK    = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL     = rm
-COPY    = cp
-LIST    = ls
-
-OBJECTS = i2o1.o i2o2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
-	$(LINK) $(OBJECTS) -o $@
-
-objects: i2o1.o
-
-clean:
-	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
-#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
-	$(CCobj) $<
-
-.c.s:
-	$(CCobj) $(LST) $<
-
-i2o1.o: i2o.h i2o1.c
-	$(CCobj) $<
-
-i2o2.o: i2o.h i2o2.s
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
diff --git a/cpu/mpc824x/drivers/i2o/i2o.h b/cpu/mpc824x/drivers/i2o/i2o.h
deleted file mode 100644
index 71572b2..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o.h
+++ /dev/null
@@ -1,345 +0,0 @@
-#ifndef I2O_H
-#define I2O_H
-/*********************************************************
- *
- * copyright @ Motorola, 1999
- *
- *********************************************************/
-
-#define I2O_REG_OFFSET 0x0004
-
-#define PCI_CFG_CLA    0x0B
-#define PCI_CFG_SCL    0x0A
-#define PCI_CFG_PIC    0x09
-
-#define I2O_IMR0 0x0050
-#define I2O_IMR1 0x0054
-#define I2O_OMR0 0x0058
-#define I2O_OMR1 0x005C
-
-#define I2O_ODBR 0x0060
-#define I2O_IDBR 0x0068
-
-#define I2O_OMISR  0x0030
-#define I2O_OMIMR  0x0034
-#define I2O_IMISR  0x0100
-#define I2O_IMIMR  0x0104
-
-/* accessable to PCI master but local processor */
-#define I2O_IFQPR  0x0040
-#define I2O_OFQPR  0x0044
-
-/* accessable to local processor */
-#define I2O_IFHPR  0x0120
-#define I2O_IFTPR  0x0128
-#define I2O_IPHPR  0x0130
-#define I2O_IPTPR  0x0138
-#define I2O_OFHPR  0x0140
-#define I2O_OFTPR  0x0148
-#define I2O_OPHPR  0x0150
-#define I2O_OPTPR  0x0158
-#define I2O_MUCR   0x0164
-#define I2O_QBAR   0x0170
-
-#define I2O_NUM_MSG 2
-
-typedef enum _i2o_status
-{
-	I2OSUCCESS = 0,
-	I2OINVALID,
-	I2OMSGINVALID,
-	I2ODBINVALID,
-	I2OQUEINVALID,
-	I2OQUEEMPTY,
-	I2OQUEFULL,
-	I2ONOEVENT,
-} I2OSTATUS;
-
-typedef enum _queue_size
-{
-    QSIZE_4K = 0x02,
-    QSIZE_8K = 0x04,
-    QSIZE_16K = 0x08,
-    QSIZE_32K = 0x10,
-    QSIZe_64K = 0x20,
-} QUEUE_SIZE;
-
-typedef enum _location
-{
-    LOCAL = 0,     /* used by local processor to access its own on board device,
-		      local processor's eumbbar is required */
-    REMOTE,        /* used by PCI master to access the devices on its PCI device,
-		      device's pcsrbar is required */
-} LOCATION;
-
-/* door bell */
-typedef enum _i2o_in_db
-{
-  IN_DB = 1,
-  MC,         /* machine check */
-} I2O_IN_DB;
-
-/* I2O PCI configuration identification */
-typedef struct _i2o_iop
-{
-	unsigned int base_class : 8;
-	unsigned int sub_class  : 8;
-	unsigned int prg_code   : 8;
-} I2OIOP;
-
-/* I2O Outbound Message Interrupt Status Register */
-typedef struct _i2o_om_stat
-{
-	unsigned int rsvd0 : 26;
-	unsigned int opqi  : 1;
-	unsigned int rsvd1 : 1;
-	unsigned int odi   : 1;
-	unsigned int rsvd2 : 1;
-	unsigned int om1i  : 1;
-	unsigned int om0i  : 1;
-} I2OOMSTAT;
-
-/* I2O inbound Message Interrupt Status Register */
-typedef struct _i2o_im_stat
-{
-	unsigned int rsvd0 : 23;
-	unsigned int ofoi  : 1;
-	unsigned int ipoi  : 1;
-	unsigned int rsvd1 : 1;
-	unsigned int ipqi  : 1;
-	unsigned int mci   : 1;
-	unsigned int idi   : 1;
-	unsigned int rsvd2 : 1;
-	unsigned int im1i  : 1;
-	unsigned int im0i  : 1;
-} I2OIMSTAT;
-
-/**
- Enable the interrupt associated with in/out bound msg
-
- Inbound message interrupt generated by PCI master and serviced by local processor
- local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
-
- Outbound message interrupt generated by local processor and serviced by PCI master
- PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
- **/
-extern I2OSTATUS I2OMsgEnable( LOCATION,            /*  REMOTE/LOCAL   */
-			       unsigned int base,   /* pcsrbar/eumbbar */
-			       unsigned char n );   /* b'1' - msg 0
-									     * b'10'- msg 1
-									     * b'11'- both
-									     */
-
-/**
- Disable the interrupt associated with in/out bound msg
-
- local processor needs to disable its inbound interrupts it is not interested (LOCAL)
-
- PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
- **/
-extern I2OSTATUS I2OMsgDisable( LOCATION,          /*  REMOTE/LOCAL   */
-				unsigned int base, /* pcsrbar/eumbbar */
-				unsigned char n ); /* b'1' - msg 0
-									    * b'10'- msg 1
-									    * b'11'- both
-									    */
-
-/**
- Read the msg register either from local inbound msg 0/1,
- or an outbound msg 0/1 of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outbound msg of the device is read.
- Otherwise local inbound msg is read.
- **/
-extern I2OSTATUS I2OMsgGet ( LOCATION,                 /* REMOTE/LOCAL */
-			     unsigned int base,        /*pcsrbar/eumbbar */
-			     unsigned int n,           /* 0 or 1 */
-			     unsigned int *msg );
-
-/**
- Write to nth Msg register either on local outbound msg 0/1,
- or aninbound msg 0/1 of devices
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, inbound msg on the device is written.
- Otherwise local outbound msg is written.
- **/
-extern I2OSTATUS I2OMsgPost( LOCATION,                 /* REMOTE/LOCAL */
-				unsigned int base,        /*pcsrbar/eumbbar */
-				unsigned int n,           /* 0 or 1 */
-				unsigned int msg );
-
-/**
- Enable the In/Out DoorBell Interrupt
-
- InDoorBell interrupt is generated by PCI master and serviced by local processor
- local processor needs to enable its inbound doorbell interrupts it wants to handle
-
- OutDoorbell interrupt is generated by local processor and serviced by PCI master
- PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
- **/
-extern I2OSTATUS I2ODBEnable( LOCATION,            /*  REMOTE/LOCAL   */
-			      unsigned int base,   /* pcsrbar/eumbbar */
-			      unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Disable the In/Out DoorBell Interrupt
-
- local processor needs to disable its inbound doorbell interrupts it is not interested
-
- PCI master needs to disable outbound doorbell interrupts of devices it is not interested
-
- **/
-extern I2OSTATUS I2ODBDisable( LOCATION,              /*  REMOTE/LOCAL   */
-			       unsigned int base,     /* pcsrbar/eumbbar */
-			       unsigned int in_db );  /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Read a local indoorbell register, or an outdoorbell of devices.
- Reading a doorbell register, the register will be cleared.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outdoorbell register on the device is read.
- Otherwise local in doorbell is read
- **/
-extern unsigned int I2ODBGet( LOCATION,             /*  REMOTE/LOCAL   */
-			      unsigned int base);   /* pcsrbar/eumbbar */
-
-/**
- Write to a local outdoorbell register, or an indoorbell register of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, in doorbell register on the device is written.
- Otherwise local out doorbell is written
- **/
-extern void I2ODBPost( LOCATION,                 /*  REMOTE/LOCAL   */
-		       unsigned int base,        /* pcsrbar/eumbbar */
-		       unsigned int msg );       /*   in   / out    */
-
-/**
- Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
- the register will be cleared.
-
- The outbound interrupt status is AND with the outbound
- interrupt mask. The result is returned.
-
- PCI master must pass the pcsrbar to the function.
- **/
-extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
-
-/**
- Read the inbound msg unit interrupt status. Reading an interrupt status register,
- the register will be cleared.
-
- The inbound interrupt status is AND with the inbound
- interrupt mask. The result is returned.
-
- Local process must pass its eumbbar to the function.
-**/
-extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
-
-/**
- Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
- MUCR.
- **/
-extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
-					      QUEUE_SIZE,
-					      unsigned int qba);/* queue base address that must be aligned at 1M */
-/**
- Enable the circular queue
- **/
-extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue
- **/
-extern void I2OFIFODisable( unsigned int eumbbar );
-
-/**
- Enable the circular queue interrupt
- PCI master enables outbound FIFO interrupt of device
- Device enables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntEnable( LOCATION, unsigned int base  );
-
-/**
- Disable the circular queue interrupt
- PCI master disables outbound FIFO interrupt of device
- Device disables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
-
-/**
- Enable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
-
-/**
- Allocate a free msg frame from free FIFO.
-
- PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
- while local processor allocates a free msg frame from outbound free queue(OFTPR)
-
- Unless both free queues are initialized, allocating a free MF will return 0xffffffff
- **/
-extern I2OSTATUS I2OFIFOAlloc( LOCATION,
-					       unsigned int base,
-					       void         **pMsg);
-/**
- Free a used msg frame back to free queue
- PCI Master frees a MFA through outbound queue port of device(OFQPR)
- while local processor frees a MFA into its inbound free queue(IFHPR)
-
- Used msg frame does not need to be recycled in the order they
- read
-
- This function has to be called by PCI master to initialize Inbound free queue
- and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
- **/
-extern I2OSTATUS I2OFIFOFree( LOCATION,
-					  unsigned int base,
-					  void        *pMsg );
-
-/**
- Post a msg into FIFO
- PCI Master posts a msg through inbound queue port of device(IFQPR)
- while local processor post a msg into its outbound post queue(OPHPR)
-
- The total number of msg must be less than the max size of the queue
- Otherwise queue overflow interrupt will assert.
- **/
-extern I2OSTATUS I2OFIFOPost( LOCATION,
-				      unsigned int base,
-				      void         *pMsg );
-
-/**
- Read a msg from FIFO
- PCI Master reads a msg through outbound queue port of device(OFQPR)
- while local processor reads a msg from its inbound post queue(IPTPR)
- **/
-extern I2OSTATUS I2OFIFOGet( LOCATION,
-					  unsigned int base,
-							  void     **pMsg );
-
-/**
- Get the I2O PCI configuration identification register
- **/
-extern I2OSTATUS I2OPCIConfigGet( LOCATION,
-					   unsigned int base,
-							   I2OIOP *);
-
-#endif
diff --git a/cpu/mpc824x/drivers/i2o/i2o1.c b/cpu/mpc824x/drivers/i2o/i2o1.c
deleted file mode 100644
index f058151..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o1.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*********************************************************
- * $Id
- *
- * copyright @ Motorola, 1999
- *********************************************************/
-#include "i2o.h"
-
-extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
-#pragma Alias( load_runtime_reg, "load_runtime_reg" );
-
-extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
-#pragma Alias( store_runtime_reg, "store_runtime_reg" );
-
-typedef struct _fifo_stat
-{
-    QUEUE_SIZE   qsz;
-    unsigned int qba;
-} FIFOSTAT;
-
-FIFOSTAT fifo_stat = { QSIZE_4K, 0xffffffff };
-
-/**********************************************************************************
- * function: I2OMsgEnable
- *
- * description: Enable the interrupt associated with in/out bound msg
- *              return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- *              All previously enabled interrupts are preserved.
- * note:
- * Inbound message interrupt generated by PCI master and serviced by local processor
- * Outbound message interrupt generated by local processor and serviced by PCI master
- *
- * local processor needs to enable its inbound interrupts it wants to handle(LOCAL)
- * PCI master needs to enable the outbound interrupts of devices it wants to handle(REMOTE)
- ************************************************************************************/
-I2OSTATUS I2OMsgEnable ( LOCATION loc,        /*  REMOTE/LOCAL   */
-			 unsigned int base,   /* pcsrbar/eumbbar */
-			 unsigned char n )    /* b'1' - msg 0
-					       * b'10'- msg 1
-					       * b'11'- both
-					       */
-{
-    unsigned int reg, val;
-    if ( ( n & 0x3 ) == 0 )
-    {
-	/* neither msg 0, nor msg 1 */
-	return I2OMSGINVALID;
-    }
-
-    n = (~n) & 0x3;
-    /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
-     *            LOCAL  : enable local inbound message, eumbbar as base
-     */
-    reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
-    val = load_runtime_reg( base, reg );
-
-    val &= 0xfffffffc; /* masked out the msg interrupt bits */
-    val |= n;          /* LSB are the one we want */
-    store_runtime_reg( base, reg, val );
-
-    return I2OSUCCESS;
-}
-
-/*********************************************************************************
- * function: I2OMsgDisable
- *
- * description: Disable the interrupt associated with in/out bound msg
- *              Other previously enabled interrupts are preserved.
- *              return I2OSUCCESS if no error otherwise return I2OMSGINVALID
- *
- * note:
- *  local processor needs to disable its inbound interrupts it is not interested(LOCAL)
- *  PCI master needs to disable outbound interrupts of devices it is not interested(REMOTE)
- *********************************************************************************/
-I2OSTATUS I2OMsgDisable( LOCATION loc,      /*  REMOTE/LOCAL   */
-			 unsigned int base, /* pcsrbar/eumbbar */
-			 unsigned char n )  /* b'1' - msg 0
-					     * b'10'- msg 1
-					     * b'11'- both
-					     */
-{
-    unsigned int reg, val;
-
-    if ( ( n & 0x3 ) == 0 )
-    {
-	/* neither msg 0, nor msg 1 */
-	return I2OMSGINVALID;
-    }
-
-    /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
-     *            LOCAL  : disable local inbound message interrupt, eumbbar as base
-     */
-    reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
-    val = load_runtime_reg( base, reg );
-
-    val &= 0xfffffffc; /* masked out the msg interrupt bits */
-    val |= ( n & 0x3 );
-    store_runtime_reg( base, reg, val );
-
-    return I2OSUCCESS;
-
-}
-
-/**************************************************************************
- * function: I2OMsgGet
- *
- * description: Local processor reads the nth Msg register from its inbound msg,
- *              or a PCI Master reads nth outbound msg from device
- *
- *              return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
- * If it is remote, outbound msg on the device is read; otherwise local inbound msg is read
- *************************************************************************/
-I2OSTATUS I2OMsgGet ( LOCATION loc,             /* REMOTE/LOCAL */
-			 unsigned int base,        /*pcsrbar/eumbbar */
-			 unsigned int n,           /* 0 or 1 */
-			 unsigned int *msg )
-{
-    if ( n >= I2O_NUM_MSG || msg == 0 )
-    {
-	return I2OMSGINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* read the outbound msg of the device, pcsrbar as base */
-	*msg = load_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET );
-    }
-    else
-    {
-	/* read the inbound msg sent by PCI master, eumbbar as base */
-	*msg = load_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET );
-    }
-
-    return I2OSUCCESS;
-}
-
-/***************************************************************
- * function: I2OMsgPost
- *
- * description: Kahlua  writes to its nth outbound msg register
- *              PCI master writes to nth inbound msg register of device
- *
- *              return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
- *
- * If it is remote, inbound msg on the device is written; otherwise local outbound msg is written
- ***************************************************************/
-I2OSTATUS I2OMsgPost( LOCATION loc,             /* REMOTE/LOCAL */
-		      unsigned int base,        /*pcsrbar/eumbbar */
-		      unsigned int n,           /* 0 or 1 */
-		      unsigned int msg )
-{
-    if ( n >= I2O_NUM_MSG )
-    {
-	return I2OMSGINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* write to the inbound msg register of the device, pcsrbar as base  */
-	store_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET, msg );
-    }
-    else
-    {
-	/* write to the outbound msg register for PCI master to read, eumbbar as base */
-	store_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET, msg );
-    }
-
-    return I2OSUCCESS;
-}
-
-/***********************************************************************
- * function: I2ODBEnable
- *
- * description: Local processor enables it's inbound doorbell interrupt
- *              PCI master enables outbound doorbell interrupt of devices
- *              Other previously enabled interrupts are preserved.
- *              Return I2OSUCCESS if no error otherwise return I2ODBINVALID
- *
- * note:
- * In DoorBell interrupt is generated by PCI master and serviced by local processor
- * Out Doorbell interrupt is generated by local processor and serviced by PCI master
- *
- * Out Doorbell interrupt is generated by local processor and serviced by PCI master
- * PCI master needs to enable the outbound doorbell interrupts of device it wants to handle
- **********************************************************************/
-I2OSTATUS I2ODBEnable( LOCATION loc,        /*  REMOTE/LOCAL   */
-		  unsigned int base,   /* pcsrbar/eumbbar */
-		  unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-{
-
-    /* LOCATION - REMOTE : PCI master initializes outbound doorbell message of device
-     *            LOCAL  : Kahlua initializes its inbound doorbell message
-     */
-    unsigned int val;
-
-    if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
-    {
-	return I2ODBINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* pcsrbar is base */
-	val = load_runtime_reg( base, I2O_OMIMR );
-	val &= 0xfffffff7;
-	store_runtime_reg( base, I2O_OMIMR , val );
-    }
-    else
-    {
-	/* eumbbar is base */
-	val = load_runtime_reg( base, I2O_IMIMR);
-	in_db = ( (~in_db) & 0x3 ) << 3;
-	val = ( val & 0xffffffe7) | in_db;
-	store_runtime_reg( base,  I2O_IMIMR, val );
-    }
-
-    return I2OSUCCESS;
-}
-
-/**********************************************************************************
- * function: I2ODBDisable
- *
- * description: local processor disables its inbound DoorBell Interrupt
- *              PCI master disables outbound DoorBell interrupt of device
- *              Other previously enabled interrupts are preserved.
- *              return I2OSUCCESS if no error.Otherwise return I2ODBINVALID
- *
- * note:
- * local processor needs to disable its inbound doorbell interrupts it is not interested
- *
- * PCI master needs to disable outbound doorbell interrupts of device it is not interested
- ************************************************************************************/
-I2OSTATUS I2ODBDisable( LOCATION loc,          /*  REMOTE/LOCAL   */
-			unsigned int base,     /* pcsrbar/eumbbar */
-			unsigned int in_db )   /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-{
-    /* LOCATION - REMOTE : handle device's out bound message initialization
-     *            LOCAL  : handle local in bound message initialization
-     */
-    unsigned int val;
-
-    if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
-    {
-	    return I2ODBINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* pcsrbar is the base */
-	val = load_runtime_reg( base, I2O_OMIMR );
-	val |= 0x8;
-	store_runtime_reg( base, I2O_OMIMR, val );
-    }
-    else
-    {
-	    val = load_runtime_reg( base, I2O_IMIMR);
-	    in_db = ( in_db & 0x3 ) << 3;
-	    val |= in_db;
-	    store_runtime_reg( base, I2O_IMIMR, val );
-    }
-
-    return I2OSUCCESS;
-}
-
-/**********************************************************************************
- * function: I2ODBGet
- *
- * description: Local processor reads its in doorbell register,
- *              PCI master reads the outdoorbell register of device.
- *              After a doorbell register is read, the whole register will be cleared.
- *              Otherwise, HW keeps generating interrupt.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function.
- * Otherwise eumbbar is passed.
- *
- * If it is remote, out doorbell register on the device is read.
- * Otherwise local in doorbell is read
- *
- * If the register is not cleared by write to it, any remaining bit of b'1's
- * will cause interrupt pending.
- *********************************************************************************/
-unsigned int I2ODBGet( LOCATION loc,         /*  REMOTE/LOCAL   */
-		       unsigned int base)    /* pcsrbar/eumbbar */
-{
-    unsigned int msg, val;
-
-    if ( loc == REMOTE )
-    {
-	/* read outbound doorbell register of device, pcsrbar is the base */
-	val = load_runtime_reg( base, I2O_ODBR );
-	msg = val & 0xe0000000;
-	store_runtime_reg( base, I2O_ODBR, val ); /* clear the register */
-    }
-    else
-    {
-	/* read the inbound doorbell register, eumbbar is the base */
-	val = load_runtime_reg( base, I2O_IDBR );
-	store_runtime_reg( base, I2O_IDBR, val ); /* clear the register */
-	msg = val;
-    }
-
-    return msg;
-}
-
-/**********************************************************************
- * function: I2ODBPost
- *
- * description: local processor writes to a outbound doorbell register,
- *              PCI master writes to the inbound doorbell register of device
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function.
- * Otherwise eumbbar is passed.
- *
- * If it is remote, in doorbell register on the device is written.
- * Otherwise local out doorbell is written
- *********************************************************************/
-void I2ODBPost( LOCATION loc,             /*  REMOTE/LOCAL   */
-		unsigned int base,        /* pcsrbar/eumbbar */
-		unsigned int msg )        /*   in   / out    */
-{
-    if ( loc == REMOTE )
-    {
-	/* write to inbound doorbell register of device, pcsrbar is the base */
-	store_runtime_reg( base, I2O_IDBR, msg );
-    }
-    else
-    {
-	/* write to local outbound doorbell register, eumbbar is the base */
-	store_runtime_reg( base, I2O_ODBR, msg & 0x1fffffff );
-    }
-
-}
-
-/********************************************************************
- * function: I2OOutMsgStatGet
- *
- * description: PCI master reads device's outbound msg unit interrupt status.
- *              Reading an interrupt status register,
- *              the register will be cleared.
- *
- *              The value of the status register is AND with the outbound
- *              interrupt mask and result is returned.
- *
- * note:
- * pcsrbar must be passed to the function.
- ********************************************************************/
-I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT *val )
-{
-    unsigned int stat;
-    unsigned int mask;
-
-    if ( val == 0 )
-    {
-	    return I2OINVALID;
-    }
-
-    /* read device's outbound status */
-    stat = load_runtime_reg( pcsrbar, I2O_OMISR );
-    mask = load_runtime_reg( pcsrbar, I2O_OMIMR );
-    store_runtime_reg( pcsrbar, I2O_OMISR, stat & 0xffffffd7);
-
-    stat &= mask;
-    val->rsvd0 = ( stat & 0xffffffc0 ) >> 6;
-    val->opqi  = ( stat & 0x00000020 ) >> 5;
-    val->rsvd1 = ( stat & 0x00000010 ) >> 4;
-    val->odi   = ( stat & 0x00000008 ) >> 3;
-    val->rsvd2 = ( stat & 0x00000004 ) >> 2;
-    val->om1i  = ( stat & 0x00000002 ) >> 1;
-    val->om0i  = ( stat & 0x00000001 );
-
-    return I2OSUCCESS;
-}
-
-/********************************************************************
- * function: I2OInMsgStatGet
- *
- * description: Local processor reads its inbound msg unit interrupt status.
- *              Reading an interrupt status register,
- *              the register will be cleared.
- *
- *              The inbound msg interrupt status is AND with the inbound
- *              msg interrupt mask and result is returned.
- *
- * note:
- * eumbbar must be passed to the function.
- ********************************************************************/
-I2OSTATUS I2OInMsgStatGet(unsigned int eumbbar, I2OIMSTAT *val)
-{
-    unsigned int stat;
-    unsigned int mask;
-
-    if ( val == 0 )
-    {
-	    return I2OINVALID;
-    }
-
-    /* read device's outbound status */
-    stat = load_runtime_reg( eumbbar, I2O_OMISR );
-    mask = load_runtime_reg( eumbbar, I2O_OMIMR );
-    store_runtime_reg( eumbbar, I2O_OMISR, stat & 0xffffffe7 );
-
-    stat &= mask;
-    val->rsvd0 = ( stat & 0xfffffe00 ) >> 9;
-    val->ofoi  = ( stat & 0x00000100 ) >> 8;
-    val->ipoi  = ( stat & 0x00000080 ) >> 7;
-    val->rsvd1 = ( stat & 0x00000040 ) >> 6;
-    val->ipqi  = ( stat & 0x00000020 ) >> 5;
-    val->mci   = ( stat & 0x00000010 ) >> 4;
-    val->idi   = ( stat & 0x00000008 ) >> 3;
-    val->rsvd2 = ( stat & 0x00000004 ) >> 2;
-    val->im1i  = ( stat & 0x00000002 ) >> 1;
-    val->im0i  = ( stat & 0x00000001 );
-
-    return I2OSUCCESS;
-
-}
-
-/***********************************************************
- * function: I2OFIFOInit
- *
- * description: Configure the I2O FIFO, including QBAR,
- *              IFHPR/IFTPR, IPHPR/IPTPR, OFHPR/OFTPR,
- *              OPHPR/OPTPR, MUCR.
- *
- *              return I2OSUCCESS if no error,
- *              otherwise return I2OQUEINVALID
- *
- * note: It is NOT this driver's responsibility of initializing
- *       MFA blocks, i.e., FIFO queue itself. The MFA blocks
- *       must be initialized before I2O unit can be used.
- ***********************************************************/
-I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
-		       QUEUE_SIZE   sz,      /* value of CQS of MUCR */
-		       unsigned int qba)     /* queue base address that must be aligned at 1M */
-{
-
-    if ( ( qba & 0xfffff ) != 0 )
-    {
-	/* QBA must be aligned at 1Mbyte boundary */
-	return I2OQUEINVALID;
-    }
-
-    store_runtime_reg( eumbbar, I2O_QBAR, qba );
-    store_runtime_reg( eumbbar, I2O_MUCR, (unsigned int)sz );
-    store_runtime_reg( eumbbar, I2O_IFHPR, qba );
-    store_runtime_reg( eumbbar, I2O_IFTPR, qba );
-    store_runtime_reg( eumbbar, I2O_IPHPR, qba + 1 * ( sz << 11 ));
-    store_runtime_reg( eumbbar, I2O_IPTPR, qba + 1 * ( sz << 11 ));
-    store_runtime_reg( eumbbar, I2O_OFHPR, qba + 2 * ( sz << 11 ));
-    store_runtime_reg( eumbbar, I2O_OFTPR, qba + 2 * ( sz << 11 ));
-    store_runtime_reg( eumbbar, I2O_OPHPR, qba + 3 * ( sz << 11 ));
-    store_runtime_reg( eumbbar, I2O_OPTPR, qba + 3 * ( sz << 11 ));
-
-    fifo_stat.qsz = sz;
-    fifo_stat.qba = qba;
-
-    return I2OSUCCESS;
-}
-
-/**************************************************
- * function: I2OFIFOEnable
- *
- * description: Enable the circular queue
- *              return I2OSUCCESS if no error.
- *              Otherwise I2OQUEINVALID is returned.
- *
- * note:
- *************************************************/
-I2OSTATUS I2OFIFOEnable( unsigned int eumbbar )
-{
-    unsigned int val;
-
-    if ( fifo_stat.qba == 0xfffffff )
-    {
-	return I2OQUEINVALID;
-    }
-
-    val = load_runtime_reg( eumbbar, I2O_MUCR );
-    store_runtime_reg( eumbbar, I2O_MUCR, val | 0x1 );
-
-    return I2OSUCCESS;
-}
-
-/**************************************************
- * function: I2OFIFODisable
- *
- * description: Disable the circular queue
- *
- * note:
- *************************************************/
-void I2OFIFODisable( unsigned int eumbbar )
-{
-    if ( fifo_stat.qba == 0xffffffff )
-    {
-	/* not enabled */
-	return;
-    }
-
-    unsigned int val = load_runtime_reg( eumbbar, I2O_MUCR );
-    store_runtime_reg( eumbbar, I2O_MUCR, val & 0xfffffffe );
-}
-
-/****************************************************
- * function: I2OFIFOAlloc
- *
- * description: Allocate a free MFA from free FIFO.
- *              return I2OSUCCESS if no error.
- *              return I2OQUEEMPTY if no more free MFA.
- *              return I2OINVALID on other errors.
- *
- *              A free MFA must be allocated before a
- *              message can be posted.
- *
- * note:
- * PCI Master allocates a free MFA from inbound queue of device
- * (pcsrbar is the base,) through the inbound queue port of device
- * while local processor allocates a free MFA from its outbound
- * queue (eumbbar is the base.)
- *
- ****************************************************/
-I2OSTATUS I2OFIFOAlloc( LOCATION loc,
-			unsigned int base,
-			void         **pMsg )
-{
-    I2OSTATUS stat = I2OSUCCESS;
-    void *pHdr, *pTil;
-
-    if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
-    {
-	/* not configured */
-	return I2OQUEINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* pcsrbar is the base and read the inbound free tail ptr */
-	pTil = (void *)load_runtime_reg( base, I2O_IFQPR );
-	if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
-	{
-	    stat = I2OQUEEMPTY;
-	}
-	else
-	{
-	    *pMsg = pTil;
-	}
-    }
-    else
-    {
-	/* eumbbar is the base and read the outbound free tail ptr */
-	pHdr = (void *)load_runtime_reg( base, I2O_OFHPR ); /* queue head */
-	pTil = (void *)load_runtime_reg( base, I2O_OFTPR ); /* queue tail */
-
-	/* check underflow */
-	if ( pHdr == pTil )
-	{
-	    /* hdr and til point to the same fifo item, no free MFA */
-	    stat = I2OQUEEMPTY;
-	}
-	else
-	{
-	  /* update OFTPR */
-	  *pMsg = (void *)(*(unsigned char *)pTil);
-	  pTil = (void *)((unsigned int)pTil + 4);
-	  if ( (unsigned int)pTil == fifo_stat.qba + ( 4 * ( fifo_stat.qsz << 11 ) ) )
-	  {
-		/* reach the upper limit */
-		pTil = (void *)(fifo_stat.qba + ( 3 * (fifo_stat.qsz << 11) ));
-	  }
-	  store_runtime_reg( base, I2O_OFTPR, (unsigned int)pTil );
-	}
-    }
-
-    return stat;
-}
-
-/******************************************************
- * function: I2OFIFOFree
- *
- * description: Free a used MFA back to free queue after
- *              use.
- *              return I2OSUCCESS if no error.
- *              return I2OQUEFULL if inbound free queue
- *              overflow
- *
- * note: PCI Master frees a MFA into device's outbound queue
- *       (OFQPR) while local processor frees a MFA into its
- *       inbound queue (IFHPR).
- *****************************************************/
-I2OSTATUS I2OFIFOFree( LOCATION loc,
-		  unsigned int base,
-		  void *pMsg )
-{
-    void **pHdr, **pTil;
-    I2OSTATUS stat = I2OSUCCESS;
-
-    if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
-    {
-	    return I2OQUEINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* pcsrbar is the base */
-	store_runtime_reg( base, I2O_OFQPR, (unsigned int)pMsg );
-    }
-    else
-    {
-	/* eumbbar is the base */
-	pHdr = (void **)load_runtime_reg( base, I2O_IFHPR );
-	pTil = (void **)load_runtime_reg( base, I2O_IFTPR );
-
-	/* store MFA */
-	*pHdr = pMsg;
-
-	/* update IFHPR */
-	pHdr += 4;
-
-	if ( (unsigned int)pHdr == fifo_stat.qba + ( fifo_stat.qsz << 11 ) )
-	{
-	  /* reach the upper limit */
-	  pHdr = (void **)fifo_stat.qba;
-	}
-
-	/* check inbound free queue overflow */
-	if ( pHdr != pTil )
-	{
-	   store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
-	}
-	else
-	{
-	    stat = I2OQUEFULL;
-	}
-
-    }
-
-    return stat;
-
-}
-
-/*********************************************
- * function: I2OFIFOPost
- *
- * description: Post a msg into FIFO post queue
- *              the value of msg must be the one
- *              returned by I2OFIFOAlloc
- *
- * note: PCI Master posts a msg into device's inbound queue
- *       (IFQPR) while local processor post a msg into device's
- *       outbound queue (OPHPR)
- *********************************************/
-I2OSTATUS I2OFIFOPost( LOCATION loc,
-		       unsigned int base,
-		       void *pMsg )
-{
-    void **pHdr, **pTil;
-    I2OSTATUS stat = I2OSUCCESS;
-
-    if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
-    {
-	return I2OQUEINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* pcsrbar is the base */
-	store_runtime_reg( base, I2O_IFQPR, (unsigned int)pMsg );
-    }
-    else
-    {
-	/* eumbbar is the base */
-	pHdr = (void **)load_runtime_reg( base, I2O_OPHPR );
-	pTil = (void **)load_runtime_reg( base, I2O_OPTPR );
-
-	/* store MFA */
-	*pHdr = pMsg;
-
-	/* update IFHPR */
-	pHdr += 4;
-
-	if ( (unsigned int)pHdr == fifo_stat.qba + 3 * ( fifo_stat.qsz << 11 ) )
-	{
-	  /* reach the upper limit */
-	  pHdr = (void **)(fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) );
-	}
-
-	/* check post queue overflow */
-	if ( pHdr != pTil )
-	{
-	   store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
-	}
-	else
-	{
-	    stat = I2OQUEFULL;
-	}
-    }
-
-    return stat;
-}
-
-/************************************************
- * function: I2OFIFOGet
- *
- * description:  Read a msg from FIFO
- *               This function should be called
- *               only when there is a corresponding
- *               msg interrupt.
- *
- * note: PCI Master reads a msg from device's outbound queue
- *       (OFQPR) while local processor reads a msg from device's
- *       inbound queue (IPTPR)
- ************************************************/
-I2OSTATUS I2OFIFOGet( LOCATION loc,
-		       unsigned int base,
-		       void **pMsg )
-{
-    I2OSTATUS stat = I2OSUCCESS;
-    void *pHdr, *pTil;
-
-    if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
-    {
-	/* not configured */
-	return I2OQUEINVALID;
-    }
-
-    if ( loc == REMOTE )
-    {
-	/* pcsrbar is the base */
-	pTil = (void *)load_runtime_reg( base, I2O_OFQPR );
-	if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
-	{
-	    stat = I2OQUEEMPTY;
-	}
-	else
-	{
-	    *pMsg = pTil;
-	}
-    }
-    else
-    {
-	/* eumbbar is the base and read the outbound free tail ptr */
-	pHdr = (void *)load_runtime_reg( base, I2O_IPHPR ); /* queue head */
-	pTil = (void *)load_runtime_reg( base, I2O_IPTPR ); /* queue tail */
-
-	/* check underflow */
-	if ( pHdr == pTil )
-	{
-	    /* no free MFA */
-	    stat = I2OQUEEMPTY;
-	}
-	else
-	{
-	  /* update OFTPR */
-	  *pMsg = (void *)(*(unsigned char *)pTil);
-	  pTil = (void *)((unsigned int)pTil + 4);
-	  if ( (unsigned int)pTil == fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) )
-	  {
-		/* reach the upper limit */
-		pTil = (void *)(fifo_stat.qba + 1 * (fifo_stat.qsz << 11) );
-	  }
-
-	  store_runtime_reg( base, I2O_IPTPR, (unsigned int)pTil );
-	}
-    }
-
-    return stat;
-}
-
-/********************************************************
- * function: I2OIOP
- *
- * description: Get the I2O PCI configuration identification
- *              register.
- *
- * note: PCI master should pass pcsrbar while local processor
- *       should pass eumbbar.
- *********************************************************/
-I2OSTATUS I2OPCIConfigGet( LOCATION loc,
-			unsigned int base,
-			I2OIOP * val)
-{
-    unsigned int tmp;
-    if ( val == 0 )
-    {
-	    return I2OINVALID;
-    }
-    tmp = load_runtime_reg( base, PCI_CFG_CLA );
-    val->base_class = ( tmp & 0xFF) << 16;
-    tmp = load_runtime_reg( base, PCI_CFG_SCL );
-    val->sub_class= ( (tmp & 0xFF) << 8 );
-    tmp = load_runtime_reg( base, PCI_CFG_PIC );
-    val->prg_code = (tmp & 0xFF);
-    return I2OSUCCESS;
-}
-
-/*********************************************************
- * function: I2OFIFOIntEnable
- *
- * description: Enable the circular post queue interrupt
- *
- * note:
- * PCI master enables outbound FIFO interrupt of device
- * pscrbar is the base
- * Device enables its inbound FIFO interrupt
- * eumbbar is the base
- *******************************************************/
-void I2OFIFOIntEnable( LOCATION loc, unsigned int base  )
-{
-    unsigned int reg, val;
-
-    /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
-     *            LOCAL  : enable local inbound message, eumbbar as base
-     */
-    reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
-    val = load_runtime_reg( base, reg );
-
-    val &= 0xffffffdf; /* clear the msg interrupt bits */
-    store_runtime_reg( base, reg, val );
-
-}
-
-/****************************************************
- * function: I2OFIFOIntDisable
- *
- * description: Disable the circular post queue interrupt
- *
- * note:
- * PCI master disables outbound FIFO interrupt of device
- * (pscrbar is the base)
- * Device disables its inbound FIFO interrupt
- * (eumbbar is the base)
- *****************************************************/
-void I2OFIFOIntDisable( LOCATION loc, unsigned int base )
-{
-
-    /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
-     *            LOCAL  : disable local inbound message interrupt, eumbbar as base
-     */
-    unsigned int reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
-    unsigned int val = load_runtime_reg( base, reg );
-
-    val |= 0x00000020; /* masked out the msg interrupt bits */
-    store_runtime_reg( base, reg, val );
-
-}
-
-/*********************************************************
- * function: I2OFIFOOverflowIntEnable
- *
- * description: Enable the circular queue overflow interrupt
- *
- * note:
- * Device enables its inbound FIFO post overflow interrupt
- * and outbound free overflow interrupt.
- * eumbbar is the base
- *******************************************************/
-void I2OFIFOOverflowIntEnable( unsigned int eumbbar  )
-{
-    unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
-
-    val &= 0xfffffe7f; /* clear the two overflow interrupt bits */
-    store_runtime_reg( eumbbar, I2O_IMIMR, val );
-
-}
-
-/****************************************************
- * function: I2OFIFOOverflowIntDisable
- *
- * description: Disable the circular queue overflow interrupt
- *
- * note:
- * Device disables its inbound post FIFO overflow interrupt
- * and outbound free FIFO overflow interrupt
- * (eumbbar is the base)
- *****************************************************/
-void I2OFIFOOverflowIntDisable( unsigned int eumbbar )
-{
-
-    unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
-
-    val |= 0x00000180; /* masked out the msg overflow interrupt bits */
-    store_runtime_reg( eumbbar, I2O_IMIMR, val );
-}
diff --git a/cpu/mpc824x/drivers/i2o/i2o2.S b/cpu/mpc824x/drivers/i2o/i2o2.S
deleted file mode 100644
index 990f9ef..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o2.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-/**********************************************************
- * function: load_runtime_reg
- *
- * input:  r3 - value of eumbbar
- *         r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
-      .text
-      .align 2
-      .global load_runtime_reg
-
-load_runtime_reg:
-
-		  xor r5,r5,r5
-	  or  r5,r5,r3       /* save eumbbar */
-
-	      lwbrx	r3,r4,r5
-	      sync
-
-	      bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- *        r4 - register offset in embedded utility space
- *        r5 - new value to be stored
- *
- ****************************************************************/
-	   .text
-	   .align 2
-	   .global store_runtime_reg
-store_runtime_reg:
-
-		  xor r0,r0,r0
-
-	      stwbrx r5,  r4, r3
-	      sync
-
-		  bclr   20,0
diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile
index b4c269f..80d7852 100644
--- a/cpu/mpc8260/Makefile
+++ b/cpu/mpc8260/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o kgdb.o
-OBJS	= traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
+COBJS	= traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
 	  interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \
 	  bedbug_603e.o pci.o spi.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS) kgdb.o
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(obj)kgdb.o
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index 60df4cd..b2a6b3e 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -1,4 +1,7 @@
 #
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
 # Copyright 2004 Freescale Semiconductor, Inc.
 #
 # See file CREDITS for list of people who contributed to this
@@ -22,31 +25,26 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
-START	= start.o \
-	resetvec.o
+START	= start.o resetvec.o
+COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
+	  i2c.o spd_sdram.o
 
-COBJS	= traps.o \
-	  cpu.o \
-	  cpu_init.o \
-	  speed.o \
-	  interrupts.o \
-	  i2c.o \
-	  spd_sdram.o
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
 
-OBJS	= $(COBJS)
-
-all:	.depend $(START) $(LIB)
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile
index 5298dc1..ff67dcd 100644
--- a/cpu/mpc85xx/Makefile
+++ b/cpu/mpc85xx/Makefile
@@ -1,4 +1,7 @@
 #
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
 # (C) Copyright 2002,2003 Motorola Inc.
 # Xianghua Xiao,X.Xiao@motorola.com
 #
@@ -23,23 +26,26 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o resetvec.o
 COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
-	  pci.o serial_scc.o commproc.o ether_fcc.o i2c.o spd_sdram.o
-OBJS	= $(COBJS)
+	  pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c
index f7fe22e..0507c47 100644
--- a/cpu/mpc85xx/cpu.c
+++ b/cpu/mpc85xx/cpu.c
@@ -30,7 +30,10 @@
 #include <command.h>
 #include <asm/cache.h>
 
-/* ------------------------------------------------------------------------- */
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
 
 int checkcpu (void)
 {
@@ -227,3 +230,48 @@
 	return dma_check();
 }
 #endif
+
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+	u32 *p;
+	ulong clock;
+	int len;
+
+	clock = bd->bi_busfreq;
+	p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+	p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+	p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+#if defined(CONFIG_MPC85XX_TSEC1)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
+		memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH1)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
+		memcpy(p, bd->bi_enet1addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH2)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
+		memcpy(p, bd->bi_enet2addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH3)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
+		memcpy(p, bd->bi_enet3addr, 6);
+#endif
+
+}
+#endif
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index c12b47b..9f4d36c 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -32,6 +32,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+
 #ifdef CONFIG_CPM2
 static void config_8560_ioports (volatile immap_t * immr)
 {
diff --git a/cpu/mpc85xx/i2c.c b/cpu/mpc85xx/i2c.c
deleted file mode 100644
index 32dcf5d..0000000
--- a/cpu/mpc85xx/i2c.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * (C) Copyright 2003,Motorola Inc.
- * Xianghua Xiao <x.xiao@motorola.com>
- * Adapted for Motorola 85xx chip.
- *
- * (C) Copyright 2003
- * Gleb Natapov <gnatapov@mrv.com>
- * Some bits are taken from linux driver writen by adrian@humboldt.co.uk
- *
- * Hardware I2C driver for MPC107 PCI bridge.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <command.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-#include <i2c.h>
-
-#define TIMEOUT (CFG_HZ/4)
-
-#define I2C_Addr ((u8 *)(CFG_CCSRBAR + 0x3000))
-
-#define I2CADR  &I2C_Addr[0]
-#define I2CFDR  &I2C_Addr[4]
-#define I2CCCR  &I2C_Addr[8]
-#define I2CCSR  &I2C_Addr[12]
-#define I2CCDR  &I2C_Addr[16]
-#define I2CDFSRR &I2C_Addr[20]
-
-#define I2C_READ  1
-#define I2C_WRITE 0
-
-void
-i2c_init(int speed, int slaveadd)
-{
-	/* stop I2C controller */
-	writeb(0x0, I2CCCR);
-
-	/* set clock */
-	writeb(0x3f, I2CFDR);
-
-	/* set default filter */
-	writeb(0x10,I2CDFSRR);
-
-	/* write slave address */
-	writeb(slaveadd, I2CADR);
-
-	/* clear status register */
-	writeb(0x0, I2CCSR);
-
-	/* start I2C controller */
-	writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-}
-
-static __inline__ int
-i2c_wait4bus (void)
-{
-	ulong timeval = get_timer (0);
-
-	while (readb(I2CCSR) & MPC85xx_I2CSR_MBB) {
-		if (get_timer (timeval) > TIMEOUT) {
-			return -1;
-		}
-	}
-
-  return 0;
-}
-
-static __inline__ int
-i2c_wait (int write)
-{
-	u32 csr;
-	ulong timeval = get_timer (0);
-
-	do {
-		csr = readb(I2CCSR);
-
-		if (!(csr & MPC85xx_I2CSR_MIF))
-			continue;
-
-		writeb(0x0, I2CCSR);
-
-		if (csr & MPC85xx_I2CSR_MAL) {
-			debug("i2c_wait: MAL\n");
-			return -1;
-		}
-
-		if (!(csr & MPC85xx_I2CSR_MCF))	{
-			debug("i2c_wait: unfinished\n");
-			return -1;
-		}
-
-		if (write == I2C_WRITE && (csr & MPC85xx_I2CSR_RXAK)) {
-			debug("i2c_wait: No RXACK\n");
-			return -1;
-		}
-
-		return 0;
-	} while (get_timer (timeval) < TIMEOUT);
-
-	debug("i2c_wait: timed out\n");
-	return -1;
-}
-
-static __inline__ int
-i2c_write_addr (u8 dev, u8 dir, int rsta)
-{
-	writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX |
-	       (rsta?MPC85xx_I2CCR_RSTA:0),
-	       I2CCCR);
-
-	writeb((dev << 1) | dir, I2CCDR);
-
-	if (i2c_wait (I2C_WRITE) < 0)
-		return 0;
-
-	return 1;
-}
-
-static __inline__ int
-__i2c_write (u8 *data, int length)
-{
-	int i;
-
-	writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX,
-	       I2CCCR);
-
-	for (i=0; i < length; i++) {
-		writeb(data[i], I2CCDR);
-
-		if (i2c_wait (I2C_WRITE) < 0)
-			break;
-	}
-
-	return i;
-}
-
-static __inline__ int
-__i2c_read (u8 *data, int length)
-{
-	int i;
-
-	writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
-	       ((length == 1) ? MPC85xx_I2CCR_TXAK : 0),
-	       I2CCCR);
-
-	/* dummy read */
-	readb(I2CCDR);
-
-	for (i=0; i < length; i++) {
-		if (i2c_wait (I2C_READ) < 0)
-			break;
-
-		/* Generate ack on last next to last byte */
-		if (i == length - 2)
-			writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
-			       MPC85xx_I2CCR_TXAK,
-			       I2CCCR);
-
-		/* Generate stop on last byte */
-		if (i == length - 1)
-			writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_TXAK, I2CCCR);
-
-		data[i] = readb(I2CCDR);
-	}
-
-	return i;
-}
-
-int
-i2c_read (u8 dev, uint addr, int alen, u8 *data, int length)
-{
-	int i = 0;
-	u8 *a = (u8*)&addr;
-
-	if (i2c_wait4bus () < 0)
-		goto exit;
-
-	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
-		goto exit;
-
-	if (__i2c_write (&a[4 - alen], alen) != alen)
-		goto exit;
-
-	if (i2c_write_addr (dev, I2C_READ, 1) == 0)
-		goto exit;
-
-	i = __i2c_read (data, length);
-
- exit:
-	writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-
-	return !(i == length);
-}
-
-int
-i2c_write (u8 dev, uint addr, int alen, u8 *data, int length)
-{
-	int i = 0;
-	u8 *a = (u8*)&addr;
-
-	if (i2c_wait4bus () < 0)
-		goto exit;
-
-	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
-		goto exit;
-
-	if (__i2c_write (&a[4 - alen], alen) != alen)
-		goto exit;
-
-	i = __i2c_write (data, length);
-
- exit:
-	writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-
-	return !(i == length);
-}
-
-int i2c_probe (uchar chip)
-{
-	int tmp;
-
-	/*
-	 * Try to read the first location of the chip.  The underlying
-	 * driver doesn't appear to support sending just the chip address
-	 * and looking for an <ACK> back.
-	 */
-	udelay(10000);
-	return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
-	uchar buf[1];
-
-	i2c_read (i2c_addr, reg, 1, buf, 1);
-
-	return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_write (i2c_addr, reg, 1, &val, 1);
-}
-
-#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c
index a94493e..84f839a 100644
--- a/cpu/mpc85xx/pci.c
+++ b/cpu/mpc85xx/pci.c
@@ -29,69 +29,101 @@
 #include <asm/cpm_85xx.h>
 #include <pci.h>
 
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
 
 #if defined(CONFIG_PCI)
 
+static struct pci_controller *pci_hose;
+
 void
-pci_mpc85xx_init(struct pci_controller *hose)
+pci_mpc85xx_init(struct pci_controller *board_hose)
 {
+	u16 reg16;
+	u32 dev;
+
 	volatile immap_t    *immap = (immap_t *)CFG_CCSRBAR;
 	volatile ccsr_pcix_t *pcix = &immap->im_pcix;
+#ifdef CONFIG_MPC85XX_PCI2
+	volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2;
+#endif
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	struct pci_controller * hose;
 
-	u16 reg16;
+	pci_hose = board_hose;
+
+	hose = &pci_hose[0];
 
 	hose->first_busno = 0;
 	hose->last_busno = 0xff;
 
-	pci_set_region(hose->regions + 0,
-		       CFG_PCI1_MEM_BASE,
-		       CFG_PCI1_MEM_PHYS,
-		       CFG_PCI1_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	pci_set_region(hose->regions + 1,
-		       CFG_PCI1_IO_BASE,
-		       CFG_PCI1_IO_PHYS,
-		       CFG_PCI1_IO_SIZE,
-		       PCI_REGION_IO);
-
-	hose->region_count = 2;
-
 	pci_setup_indirect(hose,
 			   (CFG_IMMR+0x8000),
 			   (CFG_IMMR+0x8004));
 
+	/*
+	 * Hose scan.
+	 */
+	dev = PCI_BDF(hose->first_busno, 0, 0);
+	pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+	/*
+	 * Clear non-reserved bits in status register.
+	 */
+	pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+	if (!(gur->pordevsr & PORDEVSR_PCI)) {
+		/* PCI-X init */
+		if (CONFIG_SYS_CLK_FREQ < 66000000)
+			printf("PCI-X will only work at 66 MHz\n");
+
+		reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
+			| PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+		pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16);
+	}
+
 	pcix->potar1   = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
 	pcix->potear1  = 0x00000000;
-	pcix->powbar1  = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+	pcix->powbar1  = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff;
 	pcix->powbear1 = 0x00000000;
-	pcix->powar1   = 0x8004401c;	/* 512M MEM space */
+	pcix->powar1 = (POWAR_EN | POWAR_MEM_READ |
+			POWAR_MEM_WRITE | POWAR_MEM_512M);
 
-	pcix->potar2   = 0x00000000;
+	pcix->potar2  = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
 	pcix->potear2  = 0x00000000;
-	pcix->powbar2  = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+	pcix->powbar2  = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff;
 	pcix->powbear2 = 0x00000000;
-	pcix->powar2   = 0x80088017;	/* 16M IO space */
+	pcix->powar2 = (POWAR_EN | POWAR_IO_READ |
+			POWAR_IO_WRITE | POWAR_IO_1M);
 
 	pcix->pitar1 = 0x00000000;
 	pcix->piwbar1 = 0x00000000;
-	pcix->piwar1 = 0xa0f5501e;	/* Enable, Prefetch, Local Mem,
-					 * Snoop R/W, 2G */
+	pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+			PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
 
-	/*
-	 * Hose scan.
-	 */
-	pci_register_hose(hose);
+	pcix->powar3 = 0;
+	pcix->powar4 = 0;
+	pcix->piwar2 = 0;
+	pcix->piwar3 = 0;
 
-	pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, &reg16);
-	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-	pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16);
+	pci_set_region(hose->regions + 0,
+		       CFG_PCI1_MEM_BASE,
+		       CFG_PCI1_MEM_PHYS,
+		       CFG_PCI1_MEM_SIZE,
+		       PCI_REGION_MEM);
 
-	/*
-	 * Clear non-reserved bits in status register.
-	 */
-	pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff);
-	pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80);
+	pci_set_region(hose->regions + 1,
+		       CFG_PCI1_IO_BASE,
+		       CFG_PCI1_IO_PHYS,
+		       CFG_PCI1_IO_SIZE,
+		       PCI_REGION_IO);
+
+	hose->region_count = 2;
+
+	pci_register_hose(hose);
 
 #if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS)
 	/*
@@ -117,6 +149,94 @@
 #endif
 
 	hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC85XX_PCI2
+	hose = &pci_hose[1];
+
+	hose->first_busno = pci_hose[0].last_busno + 1;
+	hose->last_busno = 0xff;
+
+	pci_setup_indirect(hose,
+			   (CFG_IMMR+0x9000),
+			   (CFG_IMMR+0x9004));
+
+	dev = PCI_BDF(hose->first_busno, 0, 0);
+	pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+	/*
+	 * Clear non-reserved bits in status register.
+	 */
+	pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+	pcix2->potar1   = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff;
+	pcix2->potear1  = 0x00000000;
+	pcix2->powbar1  = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff;
+	pcix2->powbear1 = 0x00000000;
+	pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ |
+			POWAR_MEM_WRITE | POWAR_MEM_512M);
+
+	pcix2->potar2  = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff;
+	pcix2->potear2  = 0x00000000;
+	pcix2->powbar2  = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff;
+	pcix2->powbear2 = 0x00000000;
+	pcix2->powar2 = (POWAR_EN | POWAR_IO_READ |
+			POWAR_IO_WRITE | POWAR_IO_1M);
+
+	pcix2->pitar1 = 0x00000000;
+	pcix2->piwbar1 = 0x00000000;
+	pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+			PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
+
+	pcix2->powar3 = 0;
+	pcix2->powar4 = 0;
+	pcix2->piwar2 = 0;
+	pcix2->piwar3 = 0;
+
+	pci_set_region(hose->regions + 0,
+		       CFG_PCI2_MEM_BASE,
+		       CFG_PCI2_MEM_PHYS,
+		       CFG_PCI2_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	pci_set_region(hose->regions + 1,
+		       CFG_PCI2_IO_BASE,
+		       CFG_PCI2_IO_PHYS,
+		       CFG_PCI2_IO_SIZE,
+		       PCI_REGION_IO);
+
+	hose->region_count = 2;
+
+	/*
+	 * Hose scan.
+	 */
+	pci_register_hose(hose);
+
+	hose->last_busno = pci_hose_scan(hose);
+#endif
 }
 
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+	u32 *p;
+	int len;
+
+	p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len);
+	if (p != NULL) {
+		p[0] = pci_hose[0].first_busno;
+		p[1] = pci_hose[0].last_busno;
+	}
+
+#ifdef CONFIG_MPC85XX_PCI2
+	p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len);
+	if (p != NULL) {
+		p[0] = pci_hose[1].first_busno;
+		p[1] = pci_hose[1].last_busno;
+	}
+#endif
+}
+#endif /* CONFIG_OF_FLAT_TREE */
 #endif /* CONFIG_PCI */
diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c
index af99282..6da5367 100644
--- a/cpu/mpc85xx/spd_sdram.c
+++ b/cpu/mpc85xx/spd_sdram.c
@@ -131,8 +131,8 @@
 		800,
 		900,
 		250,
-		330,	/* FIXME: Is 333 better/valid? */
-		660,	/* FIXME: Is 667 better/valid? */
+		330,
+		660,
 		750,
 		0,	/* undefined */
 		0	/* undefined */
@@ -146,6 +146,28 @@
 }
 
 
+/*
+ * Determine Refresh Rate.  Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
+ */
+unsigned int determine_refresh_rate(unsigned int spd_refresh)
+{
+	unsigned int refresh_time_ns[8] = {
+		15625000,	/* 0 Normal    1.00x */
+		3900000,	/* 1 Reduced    .25x */
+		7800000,	/* 2 Extended   .50x */
+		31300000,	/* 3 Extended  2.00x */
+		62500000,	/* 4 Extended  4.00x */
+		125000000,	/* 5 Extended  8.00x */
+		15625000,	/* 6 Normal    1.00x  filler */
+		15625000,	/* 7 Normal    1.00x  filler */
+	};
+
+	return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
+}
+
+
 long int
 spd_sdram(void)
 {
@@ -157,6 +179,10 @@
 	unsigned int rank_density;
 	unsigned int odt_rd_cfg, odt_wr_cfg;
 	unsigned int odt_cfg, mode_odt_enable;
+	unsigned int refresh_clk;
+#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
+	unsigned char clk_adjust;
+#endif
 	unsigned int dqs_cfg;
 	unsigned char twr_clk, twtr_clk, twr_auto_clk;
 	unsigned int tCKmin_ps, tCKmax_ps;
@@ -740,38 +766,21 @@
 	ddr->sdram_mode_2 = 0;
 	debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
 
-
 	/*
-	 * Determine Refresh Rate.  Ignore self refresh bit on DDR I.
-	 * Table from SPD Spec, Byte 12, converted to picoseconds and
-	 * filled in with "default" normal values.
+	 * Determine Refresh Rate.
 	 */
-	{
-		unsigned int refresh_clk;
-		unsigned int refresh_time_ns[8] = {
-			15625000,	/* 0 Normal    1.00x */
-			3900000,	/* 1 Reduced    .25x */
-			7800000,	/* 2 Extended   .50x */
-			31300000,	/* 3 Extended  2.00x */
-			62500000,	/* 4 Extended  4.00x */
-			125000000,	/* 5 Extended  8.00x */
-			15625000,	/* 6 Normal    1.00x  filler */
-			15625000,	/* 7 Normal    1.00x  filler */
-		};
-
-		refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]);
+	refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
 
-		/*
-		 * Set BSTOPRE to 0x100 for page mode
-		 * If auto-charge is used, set BSTOPRE = 0
-		 */
-		ddr->sdram_interval =
-			(0
-			 | (refresh_clk & 0x3fff) << 16
-			 | 0x100
-			 );
-		debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
-	}
+	/*
+	 * Set BSTOPRE to 0x100 for page mode
+	 * If auto-charge is used, set BSTOPRE = 0
+	 */
+	ddr->sdram_interval =
+	    (0
+	     | (refresh_clk & 0x3fff) << 16
+	     | 0x100
+	     );
+	debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
 
 	/*
 	 * Is this an ECC DDR chip?
@@ -835,28 +844,23 @@
 
 
 #ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
-	{
-		unsigned char clk_adjust;
-
-		/*
-		 * Setup the clock control.
-		 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
-		 * SDRAM_CLK_CNTL[5-7] = Clock Adjust
-		 *	0110	3/4 cycle late
-		 *	0111	7/8 cycle late
-		 */
-		if (spd.mem_type == SPD_MEMTYPE_DDR) {
-			clk_adjust = 0x6;
-		} else {
-			clk_adjust = 0x7;
-		}
+	/*
+	 * Setup the clock control.
+	 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+	 * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+	 *	0110	3/4 cycle late
+	 *	0111	7/8 cycle late
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR)
+		clk_adjust = 0x6;
+	else
+		clk_adjust = 0x7;
 
-		ddr->sdram_clk_cntl = (0
+	ddr->sdram_clk_cntl = (0
 			       | 0x80000000
 			       | (clk_adjust << 23)
 			       );
-		debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
-	}
+	debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
 #endif
 
 	/*
@@ -1081,26 +1085,16 @@
 		}
 	}
 
-	/* 8K */
-	dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
-	/* 16K */
-	dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
-	/* 32K */
-	dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
-	/* 64K */
-	dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
-	/* 128k */
-	dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
-	/* 256k */
-	dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
-	/* 512k */
-	dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
-	/* 1M */
-	dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
-	/* 2M */
-	dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
-	/* 4M */
-	dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
+	dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
+	dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
+	dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
+	dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
+	dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
+	dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
+	dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
+	dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+	dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+	dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
 
 	for (i = 1; i < dram_size / 0x800000; i++) {
 		dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
diff --git a/cpu/mpc86xx/Makefile b/cpu/mpc86xx/Makefile
new file mode 100644
index 0000000..fffcfd2
--- /dev/null
+++ b/cpu/mpc86xx/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2002,2003 Motorola Inc.
+# Xianghua Xiao,X.Xiao@motorola.com
+#
+# (C) Copyright 2004 Freescale Semiconductor. (MC86xx Port)
+# Jeff Brown
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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$(CPU).a
+
+START	= start.o #resetvec.o
+SOBJS	= cache.o
+COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
+	  pci.o pcie_indirect.o spd_sdram.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(ASOBJS) $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/mpc86xx/cache.S b/cpu/mpc86xx/cache.S
new file mode 100644
index 0000000..f316b3e
--- /dev/null
+++ b/cpu/mpc86xx/cache.S
@@ -0,0 +1,374 @@
+#include <config.h>
+#include <mpc86xx.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef CACHE_LINE_SIZE
+# define CACHE_LINE_SIZE L1_CACHE_BYTES
+#endif
+
+#if CACHE_LINE_SIZE == 128
+#define LG_CACHE_LINE_SIZE 7
+#elif CACHE_LINE_SIZE == 32
+#define LG_CACHE_LINE_SIZE 5
+#elif CACHE_LINE_SIZE == 16
+#define LG_CACHE_LINE_SIZE 4
+#elif CACHE_LINE_SIZE == 8
+#define LG_CACHE_LINE_SIZE 3
+#else
+# error "Invalid cache line size!"
+#endif
+
+/*
+ * Most of this code is taken from 74xx_7xx/cache.S
+ * and then cleaned up a bit
+ */
+
+/*
+ * Invalidate L1 instruction cache.
+ */
+_GLOBAL(invalidate_l1_instruction_cache)
+	/* use invalidate-all bit in HID0 */
+	mfspr	r3,HID0
+	ori	r3,r3,HID0_ICFI
+	mtspr	HID0,r3
+	isync
+	blr
+
+/*
+ * Invalidate L1 data cache.
+ */
+_GLOBAL(invalidate_l1_data_cache)
+	mfspr	r3,HID0
+	ori	r3,r3,HID0_DCFI
+	mtspr	HID0,r3
+	isync
+	blr
+
+/*
+ * Flush data cache.
+ */
+_GLOBAL(flush_data_cache)
+	lis	r3,0
+	lis	r5,CACHE_LINE_SIZE
+flush:
+	cmp	0,1,r3,r5
+	bge	done
+	lwz	r5,0(r3)
+	lis	r5,CACHE_LINE_SIZE
+	addi	r3,r3,0x4
+	b	flush
+done:
+	blr
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ * This is a no-op on the 601.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_icache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+	mr	r6,r3
+1:	dcbst	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbst's to get to ram */
+	mtctr	r4
+2:	icbi	0,r6
+	addi	r6,r6,CACHE_LINE_SIZE
+	bdnz	2b
+	sync				/* additional sync needed on g4 */
+	isync
+	blr
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ *
+ * clean_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(clean_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5	/* align r3 down to cache line */
+	subf	r4,r3,r4	/* r4 = offset of stop from start of cache line */
+	add	r4,r4,r5	/* r4 += cache_line_size-1 */
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE  /* r4 = number of cache lines to flush */
+	beqlr				  /* if r4 == 0 return */
+	mtctr	r4			  /* ctr = r4 */
+
+	sync
+1:	dcbst	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbst's to get to ram */
+	blr
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+
+	sync
+1:	dcbf	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbf's to get to ram */
+	blr
+
+/*
+ * Like above, but invalidate the D-cache.  This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+
+	sync
+1:	dcbi	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbi's to get to ram */
+	blr
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ *	void __flush_page_to_ram(void *page)
+ */
+_GLOBAL(__flush_page_to_ram)
+	rlwinm	r3,r3,0,0,19		/* Get page base address */
+	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
+	mtctr	r4
+	mr	r6,r3
+0:	dcbst	0,r3			/* Write line to ram */
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	0b
+	sync
+	mtctr	r4
+1:	icbi	0,r6
+	addi	r6,r6,CACHE_LINE_SIZE
+	bdnz	1b
+	sync
+	isync
+	blr
+
+/*
+ * Flush a particular page from the instruction cache.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ *	void __flush_icache_page(void *page)
+ */
+_GLOBAL(__flush_icache_page)
+	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
+	mtctr	r4
+1:	icbi	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync
+	isync
+	blr
+
+/*
+ * Clear a page using the dcbz instruction, which doesn't cause any
+ * memory traffic (except to write out any cache lines which get
+ * displaced).  This only works on cacheable memory.
+ */
+_GLOBAL(clear_page)
+	li	r0,4096/CACHE_LINE_SIZE
+	mtctr	r0
+1:	dcbz	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	blr
+
+/*
+ * Enable L1 Instruction cache
+ */
+_GLOBAL(icache_enable)
+	mfspr	r3, HID0
+	li	r5, HID0_ICFI|HID0_ILOCK
+	andc	r3, r3, r5
+	ori	r3, r3, HID0_ICE
+	ori	r5, r3, HID0_ICFI
+	mtspr	HID0, r5
+	mtspr	HID0, r3
+	isync
+	blr
+
+/*
+ * Disable L1 Instruction cache
+ */
+_GLOBAL(icache_disable)
+	mfspr	r3, HID0
+	li	r5, 0
+	ori	r5, r5, HID0_ICE
+	andc	r3, r3, r5
+	mtspr	HID0, r3
+	isync
+	blr
+
+/*
+ * Is instruction cache enabled?
+ */
+_GLOBAL(icache_status)
+	mfspr	r3, HID0
+	andi.	r3, r3, HID0_ICE
+	blr
+
+
+_GLOBAL(l1dcache_enable)
+	mfspr	r3, HID0
+	li	r5, HID0_DCFI|HID0_DLOCK
+	andc	r3, r3, r5
+	mtspr	HID0, r3		/* no invalidate, unlock */
+	ori	r3, r3, HID0_DCE
+	ori	r5, r3, HID0_DCFI
+	mtspr	HID0, r5		/* enable + invalidate */
+	mtspr	HID0, r3		/* enable */
+	sync
+	blr
+
+/*
+ * Enable data cache(s) - L1 and optionally L2
+ * Calls l2cache_enable. LR saved in r5
+ */
+_GLOBAL(dcache_enable)
+	mfspr	r3, HID0
+	li	r5, HID0_DCFI|HID0_DLOCK
+	andc	r3, r3, r5
+	mtspr	HID0, r3		/* no invalidate, unlock */
+	ori	r3, r3, HID0_DCE
+	ori	r5, r3, HID0_DCFI
+	mtspr	HID0, r5		/* enable + invalidate */
+	mtspr	HID0, r3		/* enable */
+	sync
+#ifdef CFG_L2
+	mflr	r5
+	bl	l2cache_enable		/* uses r3 and r4 */
+	sync
+	mtlr	r5
+#endif
+	blr
+
+
+/*
+ * Disable data cache(s) - L1 and optionally L2
+ * Calls flush_data_cache and l2cache_disable_no_flush.
+ * LR saved in r4
+ */
+_GLOBAL(dcache_disable)
+	mflr	r4			/* save link register */
+	bl	flush_data_cache	/* uses r3 and r5 */
+	sync
+	mfspr	r3, HID0
+	li	r5, HID0_DCFI|HID0_DLOCK
+	andc	r3, r3, r5
+	mtspr	HID0, r3		/* no invalidate, unlock */
+	li	r5, HID0_DCE|HID0_DCFI
+	andc	r3, r3, r5		/* no enable, no invalidate */
+	mtspr	HID0, r3
+	sync
+#ifdef CFG_L2
+	bl	l2cache_disable_no_flush /* uses r3 */
+#endif
+	mtlr	r4			/* restore link register */
+	blr
+
+/*
+ * Is data cache enabled?
+ */
+_GLOBAL(dcache_status)
+	mfspr	r3, HID0
+	andi.	r3, r3, HID0_DCE
+	blr
+
+/*
+ * Invalidate L2 cache using L2I, assume L2 is enabled
+ */
+_GLOBAL(l2cache_invalidate)
+	mfspr	r3, l2cr
+	rlwinm.	r3, r3, 0, 0, 0
+	beq	1f
+
+	mfspr	r3, l2cr
+	rlwinm	r3, r3, 0, 1, 31
+
+#ifdef	CONFIG_ALTIVEC
+	dssall
+#endif
+	sync
+	mtspr	l2cr, r3
+	sync
+1:	mfspr	r3, l2cr
+	oris	r3, r3, L2CR_L2I@h
+	mtspr	l2cr, r3
+
+invl2:
+	mfspr	r3, l2cr
+	andi.	r3, r3, L2CR_L2I@h
+	bne	invl2
+	blr
+
+/*
+ * Enable L2 cache
+ * Calls l2cache_invalidate. LR is saved in r4
+ */
+_GLOBAL(l2cache_enable)
+	mflr	r4			/* save link register */
+	bl	l2cache_invalidate	/* uses r3 */
+	sync
+	lis	r3, L2_ENABLE@h
+	ori	r3, r3, L2_ENABLE@l
+	mtspr	l2cr, r3
+	isync
+	mtlr	r4			/* restore link register */
+	blr
+
+/*
+ * Disable L2 cache
+ * Calls flush_data_cache. LR is saved in r4
+ */
+_GLOBAL(l2cache_disable)
+	mflr	r4			/* save link register */
+	bl	flush_data_cache	/* uses r3 and r5 */
+	sync
+	mtlr	r4			/* restore link register */
+l2cache_disable_no_flush:		/* provide way to disable L2 w/o flushing */
+	lis	r3, L2_INIT@h
+	ori	r3, r3, L2_INIT@l
+	mtspr	l2cr, r3
+	isync
+	blr
diff --git a/cpu/mpc86xx/config.mk b/cpu/mpc86xx/config.mk
new file mode 100644
index 0000000..3c54f4a
--- /dev/null
+++ b/cpu/mpc86xx/config.mk
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2004 Freescale Semiconductor.
+# Jeff Brown
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC86xx -ffixed-r2 -ffixed-r29 -mstring
diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c
new file mode 100644
index 0000000..551b243
--- /dev/null
+++ b/cpu/mpc86xx/cpu.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2006 Freescale Semiconductor
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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 <watchdog.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <mpc86xx.h>
+
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+#ifdef CONFIG_MPC8641HPCN
+extern void mpc8641_reset_board(cmd_tbl_t *cmdtp, int flag,
+				int argc, char *argv[]);
+#endif
+
+
+int
+checkcpu(void)
+{
+	sys_info_t sysinfo;
+	uint pvr, svr;
+	uint ver;
+	uint major, minor;
+	uint lcrr;		/* local bus clock ratio register */
+	uint clkdiv;		/* clock divider portion of lcrr */
+
+	puts("Freescale PowerPC\n");
+
+	pvr = get_pvr();
+	ver = PVR_VER(pvr);
+	major = PVR_MAJ(pvr);
+	minor = PVR_MIN(pvr);
+
+	puts("CPU:\n");
+	puts("    Core: ");
+
+	switch (ver) {
+	case PVR_VER(PVR_86xx):
+		puts("E600");
+		break;
+	default:
+		puts("Unknown");
+		break;
+	}
+	printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
+
+	svr = get_svr();
+	ver = SVR_VER(svr);
+	major = SVR_MAJ(svr);
+	minor = SVR_MIN(svr);
+
+	puts("    System: ");
+	switch (ver) {
+	case SVR_8641:
+	    if (SVR_SUBVER(svr) == 1) {
+		puts("8641D");
+	    } else {
+		puts("8641");
+	    }
+	    break;
+	default:
+		puts("Unknown");
+		break;
+	}
+	printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
+
+	get_sys_info(&sysinfo);
+
+	puts("    Clocks: ");
+	printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
+	printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000);
+	printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
+
+#if defined(CFG_LBC_LCRR)
+	lcrr = CFG_LBC_LCRR;
+#else
+	{
+		volatile immap_t *immap = (immap_t *) CFG_IMMR;
+		volatile ccsr_lbc_t *lbc = &immap->im_lbc;
+
+		lcrr = lbc->lcrr;
+	}
+#endif
+	clkdiv = lcrr & 0x0f;
+	if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
+		printf("LBC:%4lu MHz\n",
+		       sysinfo.freqSystemBus / 1000000 / clkdiv);
+	} else {
+		printf("    LBC: unknown (lcrr: 0x%08x)\n", lcrr);
+	}
+
+	puts("    L2: ");
+	if (get_l2cr() & 0x80000000)
+		puts("Enabled\n");
+	else
+		puts("Disabled\n");
+
+	return 0;
+}
+
+
+static inline void
+soft_restart(unsigned long addr)
+{
+#ifndef CONFIG_MPC8641HPCN
+
+	/*
+	 * SRR0 has system reset vector, SRR1 has default MSR value
+	 * rfi restores MSR from SRR1 and sets the PC to the SRR0 value
+	 */
+
+	__asm__ __volatile__ ("mtspr	26, %0"		:: "r" (addr));
+	__asm__ __volatile__ ("li	4, (1 << 6)"	::: "r4");
+	__asm__ __volatile__ ("mtspr	27, 4");
+	__asm__ __volatile__ ("rfi");
+
+#else /* CONFIG_MPC8641HPCN */
+
+	out8(PIXIS_BASE + PIXIS_RST, 0);
+
+#endif /* !CONFIG_MPC8641HPCN */
+
+	while (1) ;		/* not reached */
+}
+
+
+/*
+ * No generic way to do board reset. Simply call soft_reset.
+ */
+void
+do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#ifndef CONFIG_MPC8641HPCN
+
+#ifdef CFG_RESET_ADDRESS
+	ulong addr = CFG_RESET_ADDRESS;
+#else
+	/*
+	 * note: when CFG_MONITOR_BASE points to a RAM address,
+	 * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid
+	 * address. Better pick an address known to be invalid on your
+	 * system and assign it to CFG_RESET_ADDRESS.
+	 */
+	ulong addr = CFG_MONITOR_BASE - sizeof(ulong);
+#endif
+
+	/* flush and disable I/D cache */
+	__asm__ __volatile__ ("mfspr	3, 1008"	::: "r3");
+	__asm__ __volatile__ ("ori	5, 5, 0xcc00"	::: "r5");
+	__asm__ __volatile__ ("ori	4, 3, 0xc00"	::: "r4");
+	__asm__ __volatile__ ("andc	5, 3, 5"	::: "r5");
+	__asm__ __volatile__ ("sync");
+	__asm__ __volatile__ ("mtspr	1008, 4");
+	__asm__ __volatile__ ("isync");
+	__asm__ __volatile__ ("sync");
+	__asm__ __volatile__ ("mtspr	1008, 5");
+	__asm__ __volatile__ ("isync");
+	__asm__ __volatile__ ("sync");
+
+	soft_restart(addr);
+
+#else /* CONFIG_MPC8641HPCN */
+
+	mpc8641_reset_board(cmdtp, flag, argc, argv);
+
+#endif /* !CONFIG_MPC8641HPCN */
+
+	while (1) ;		/* not reached */
+}
+
+
+/*
+ * Get timebase clock frequency
+ */
+unsigned long
+get_tbclk(void)
+{
+	sys_info_t sys_info;
+
+	get_sys_info(&sys_info);
+	return (sys_info.freqSystemBus + 3L) / 4L;
+}
+
+
+#if defined(CONFIG_WATCHDOG)
+void
+watchdog_reset(void)
+{
+}
+#endif	/* CONFIG_WATCHDOG */
+
+
+#if defined(CONFIG_DDR_ECC)
+void
+dma_init(void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_dma_t *dma = &immap->im_dma;
+
+	dma->satr0 = 0x00040000;
+	dma->datr0 = 0x00040000;
+	asm("sync; isync");
+}
+
+uint
+dma_check(void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_dma_t *dma = &immap->im_dma;
+	volatile uint status = dma->sr0;
+
+	/* While the channel is busy, spin */
+	while ((status & 4) == 4) {
+		status = dma->sr0;
+	}
+
+	if (status != 0) {
+		printf("DMA Error: status = %x\n", status);
+	}
+	return status;
+}
+
+int
+dma_xfer(void *dest, uint count, void *src)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_dma_t *dma = &immap->im_dma;
+
+	dma->dar0 = (uint) dest;
+	dma->sar0 = (uint) src;
+	dma->bcr0 = count;
+	dma->mr0 = 0xf000004;
+	asm("sync;isync");
+	dma->mr0 = 0xf000005;
+	asm("sync;isync");
+	return dma_check();
+}
+
+#endif	/* CONFIG_DDR_ECC */
+
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+	u32 *p;
+	ulong clock;
+	int len;
+
+	clock = bd->bi_busfreq;
+	p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+	p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+	p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
+	if (p != NULL)
+		*p = cpu_to_be32(clock);
+
+#if defined(CONFIG_MPC86XX_TSEC1)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
+	memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC2)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
+	memcpy(p, bd->bi_enet1addr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC3)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
+	memcpy(p, bd->bi_enet2addr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC4)
+	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
+	memcpy(p, bd->bi_enet3addr, 6);
+#endif
+
+}
+#endif
diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c
new file mode 100644
index 0000000..4673d05
--- /dev/null
+++ b/cpu/mpc86xx/cpu_init.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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
+ */
+
+/*
+ * cpu_init.c - low level cpu init
+ */
+
+#include <common.h>
+#include <mpc86xx.h>
+
+/*
+ * Breathe some life into the CPU...
+ *
+ * Set up the memory map
+ * initialize a bunch of registers
+ */
+
+void cpu_init_f(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	volatile immap_t    *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_lbc_t *memctl = &immap->im_lbc;
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+	/* Clear initial global data */
+	memset ((void *) gd, 0, sizeof (gd_t));
+
+	/* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
+	 * addresses - these have to be modified later when FLASH size
+	 * has been determined
+	 */
+
+#if defined(CFG_OR0_REMAP)
+	memctl->or0 = CFG_OR0_REMAP;
+#endif
+#if defined(CFG_OR1_REMAP)
+	memctl->or1 = CFG_OR1_REMAP;
+#endif
+
+	/* now restrict to preliminary range */
+#if defined(CFG_BR0_PRELIM) && defined(CFG_OR0_PRELIM)
+	memctl->br0 = CFG_BR0_PRELIM;
+	memctl->or0 = CFG_OR0_PRELIM;
+#endif
+
+#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
+	memctl->or1 = CFG_OR1_PRELIM;
+	memctl->br1 = CFG_BR1_PRELIM;
+#endif
+
+#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
+	memctl->or2 = CFG_OR2_PRELIM;
+	memctl->br2 = CFG_BR2_PRELIM;
+#endif
+
+#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
+	memctl->or3 = CFG_OR3_PRELIM;
+	memctl->br3 = CFG_BR3_PRELIM;
+#endif
+
+#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
+	memctl->or4 = CFG_OR4_PRELIM;
+	memctl->br4 = CFG_BR4_PRELIM;
+#endif
+
+#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
+	memctl->or5 = CFG_OR5_PRELIM;
+	memctl->br5 = CFG_BR5_PRELIM;
+#endif
+
+#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
+	memctl->or6 = CFG_OR6_PRELIM;
+	memctl->br6 = CFG_BR6_PRELIM;
+#endif
+
+#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
+	memctl->or7 = CFG_OR7_PRELIM;
+	memctl->br7 = CFG_BR7_PRELIM;
+#endif
+
+	/* enable the timebase bit in HID0 */
+	set_hid0(get_hid0() | 0x4000000);
+
+	/* enable SYNCBE | ABE bits in  HID1 */
+	set_hid1(get_hid1() | 0x00000C00);
+}
+
+/*
+ * initialize higher level parts of CPU like timers
+ */
+int cpu_init_r(void)
+{
+	return 0;
+}
diff --git a/cpu/mpc86xx/interrupts.c b/cpu/mpc86xx/interrupts.c
new file mode 100644
index 0000000..1df6cdc
--- /dev/null
+++ b/cpu/mpc86xx/interrupts.c
@@ -0,0 +1,204 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 (440 port)
+ * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
+ *
+ * (C) Copyright 2003 Motorola Inc. (MPC85xx port)
+ * Xianghua Xiao (X.Xiao@motorola.com)
+ *
+ * (C) Copyright 2004 Freescale Semiconductor. (MPC86xx Port)
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.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 <mpc86xx.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <ppc_asm.tmpl>
+
+unsigned long decrementer_count;    /* count value for 1e6/HZ microseconds */
+unsigned long timestamp;
+
+
+static __inline__ unsigned long get_msr(void)
+{
+	unsigned long msr;
+
+	asm volatile ("mfmsr %0":"=r" (msr):);
+
+	return msr;
+}
+
+static __inline__ void set_msr(unsigned long msr)
+{
+	asm volatile ("mtmsr %0"::"r" (msr));
+}
+
+static __inline__ unsigned long get_dec(void)
+{
+	unsigned long val;
+
+	asm volatile ("mfdec %0":"=r" (val):);
+
+	return val;
+}
+
+static __inline__ void set_dec(unsigned long val)
+{
+	if (val)
+		asm volatile ("mtdec %0"::"r" (val));
+}
+
+/* interrupt is not supported yet */
+int interrupt_init_cpu(unsigned *decrementer_count)
+{
+	return 0;
+}
+
+int interrupt_init(void)
+{
+	int ret;
+
+	/* call cpu specific function from $(CPU)/interrupts.c */
+	ret = interrupt_init_cpu(&decrementer_count);
+
+	if (ret)
+		return ret;
+
+	decrementer_count = get_tbclk() / CFG_HZ;
+	debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n",
+	      (get_tbclk() / 1000000),
+	      decrementer_count);
+
+	set_dec(decrementer_count);
+
+	set_msr(get_msr() | MSR_EE);
+
+	debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n",
+	      get_msr(),
+	      get_dec());
+
+	return 0;
+}
+
+void enable_interrupts(void)
+{
+	set_msr(get_msr() | MSR_EE);
+}
+
+/* returns flag if MSR_EE was set before */
+int disable_interrupts(void)
+{
+	ulong msr = get_msr();
+
+	set_msr(msr & ~MSR_EE);
+	return (msr & MSR_EE) != 0;
+}
+
+void increment_timestamp(void)
+{
+	timestamp++;
+}
+
+/*
+ * timer_interrupt - gets called when the decrementer overflows,
+ * with interrupts disabled.
+ * Trivial implementation - no need to be really accurate.
+ */
+void timer_interrupt_cpu(struct pt_regs *regs)
+{
+	/* nothing to do here */
+}
+
+void timer_interrupt(struct pt_regs *regs)
+{
+	/* call cpu specific function from $(CPU)/interrupts.c */
+	timer_interrupt_cpu(regs);
+
+	timestamp++;
+
+	ppcDcbf(&timestamp);
+
+	/* Restore Decrementer Count */
+	set_dec(decrementer_count);
+
+#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
+	if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0)
+		WATCHDOG_RESET();
+#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
+
+#ifdef CONFIG_STATUS_LED
+	status_led_tick(timestamp);
+#endif /* CONFIG_STATUS_LED */
+
+#ifdef CONFIG_SHOW_ACTIVITY
+	board_show_activity(timestamp);
+#endif /* CONFIG_SHOW_ACTIVITY */
+
+}
+
+void reset_timer(void)
+{
+	timestamp = 0;
+}
+
+ulong get_timer(ulong base)
+{
+	return timestamp - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+/*
+ * Install and free a interrupt handler. Not implemented yet.
+ */
+
+void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+}
+
+void irq_free_handler(int vec)
+{
+}
+
+/*
+ * irqinfo - print information about PCI devices,not implemented.
+ */
+int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	printf("\nInterrupt-unsupported:\n");
+
+	return 0;
+}
+
+/*
+ * Handle external interrupts
+ */
+void external_interrupt(struct pt_regs *regs)
+{
+	puts("external_interrupt (oops!)\n");
+}
diff --git a/cpu/mpc86xx/pci.c b/cpu/mpc86xx/pci.c
new file mode 100644
index 0000000..b86548d
--- /dev/null
+++ b/cpu/mpc86xx/pci.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) Freescale Semiconductor,Inc.
+ * 2005, 2006. All rights reserved.
+ *
+ * Ed Swarthout (ed.swarthout@freescale.com)
+ * Jason Jin (Jason.jin@freescale.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
+ */
+
+/*
+ * PCIE Configuration space access support for PCIE Bridge
+ */
+#include <common.h>
+#include <pci.h>
+
+#if defined(CONFIG_PCI)
+void
+pci_mpc86xx_init(struct pci_controller *hose)
+{
+	volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
+	volatile ccsr_pex_t *pcie1 = &immap->im_pex1;
+	u16 temp16;
+	u32 temp32;
+
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
+	uint pcie1_host = (host1_agent == 2) || (host1_agent == 3);
+	uint pcie1_agent = (host1_agent == 0) || (host1_agent == 1);
+	uint devdisr = gur->devdisr;
+	uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
+
+	if ((io_sel == 2 || io_sel == 3 || io_sel == 5 || io_sel == 6 ||
+	     io_sel == 7 || io_sel == 0xf)
+	    && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
+		printf("PCI-EXPRESS 1: Configured as %s \n",
+		       pcie1_agent ? "Agent" : "Host");
+		if (pcie1_agent)
+			return;	/*Don't scan bus when configured as agent */
+		printf("               Scanning PCIE bus");
+		debug("0x%08x=0x%08x ",
+		      &pcie1->pme_msg_det,
+		      pcie1->pme_msg_det);
+		if (pcie1->pme_msg_det) {
+			pcie1->pme_msg_det = 0xffffffff;
+			debug(" with errors.  Clearing.  Now 0x%08x",
+			      pcie1->pme_msg_det);
+		}
+		debug("\n");
+	} else {
+		printf("PCI-EXPRESS 1 disabled!\n");
+		return;
+	}
+
+	/*
+	 * Set first_bus=0 only skipped B0:D0:F0 which is
+	 * a reserved device in M1575, but make it easy for
+	 * most of the scan process.
+	 */
+	hose->first_busno = 0x00;
+	hose->last_busno = 0xfe;
+
+	pcie_setup_indirect(hose, (CFG_IMMR + 0x8000), (CFG_IMMR + 0x8004));
+
+	pci_hose_read_config_word(hose,
+				  PCI_BDF(0, 0, 0), PCI_COMMAND, &temp16);
+	temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
+	    PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+	pci_hose_write_config_word(hose,
+				   PCI_BDF(0, 0, 0), PCI_COMMAND, temp16);
+
+	pci_hose_write_config_word(hose, PCI_BDF(0, 0, 0), PCI_STATUS, 0xffff);
+	pci_hose_write_config_byte(hose,
+				   PCI_BDF(0, 0, 0), PCI_LATENCY_TIMER, 0x80);
+
+	pci_hose_read_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
+				   &temp32);
+	temp32 = (temp32 & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
+	pci_hose_write_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
+				    temp32);
+
+	pcie1->powar1 = 0;
+	pcie1->powar2 = 0;
+	pcie1->piwar1 = 0;
+	pcie1->piwar1 = 0;
+
+	pcie1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+	pcie1->powar1 = 0x8004401c;	/* 512M MEM space */
+	pcie1->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+	pcie1->potear1 = 0x00000000;
+
+	pcie1->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+	pcie1->powar2 = 0x80088017;	/* 16M IO space */
+	pcie1->potar2 = 0x00000000;
+	pcie1->potear2 = 0x00000000;
+
+	pcie1->pitar1 = 0x00000000;
+	pcie1->piwbar1 = 0x00000000;
+	/* Enable, Prefetch, Local Mem, * Snoop R/W, 2G */
+	pcie1->piwar1 = 0xa0f5501e;
+
+	pci_set_region(hose->regions + 0,
+		       CFG_PCI_MEMORY_BUS,
+		       CFG_PCI_MEMORY_PHYS,
+		       CFG_PCI_MEMORY_SIZE,
+		       PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+	pci_set_region(hose->regions + 1,
+		       CFG_PCI1_MEM_BASE,
+		       CFG_PCI1_MEM_PHYS,
+		       CFG_PCI1_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	pci_set_region(hose->regions + 2,
+		       CFG_PCI1_IO_BASE,
+		       CFG_PCI1_IO_PHYS,
+		       CFG_PCI1_IO_SIZE,
+		       PCI_REGION_IO);
+
+	hose->region_count = 3;
+
+	pci_register_hose(hose);
+
+	hose->last_busno = pci_hose_scan(hose);
+	debug("pcie_mpc86xx_init: last_busno %x\n", hose->last_busno);
+	debug("pcie_mpc86xx init: current_busno %x\n ", hose->current_busno);
+
+	printf("....PCIE1 scan & enumeration done\n");
+}
+#endif				/* CONFIG_PCI */
diff --git a/cpu/mpc86xx/pcie_indirect.c b/cpu/mpc86xx/pcie_indirect.c
new file mode 100644
index 0000000..b00ad76
--- /dev/null
+++ b/cpu/mpc86xx/pcie_indirect.c
@@ -0,0 +1,199 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (c) Freescale Semiconductor, Inc.
+ * 2006. All rights reserved.
+ *
+ * Jason Jin <Jason.jin@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * partly derived from
+ * arch/powerpc/platforms/86xx/mpc86xx_pcie.c
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define PCI_CFG_OUT 	out_be32
+#define PEX_FIX		out_be32(hose->cfg_addr+0x4, 0x0400ffff)
+
+static int
+indirect_read_config_pcie(struct pci_controller *hose,
+			  pci_dev_t dev,
+			  int offset,
+			  int len,
+			  u32 *val)
+{
+	int bus = PCI_BUS(dev);
+
+	volatile unsigned char *cfg_data;
+	u32 temp;
+
+	PEX_FIX;
+	if (bus == 0xff) {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000001);
+	} else {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000000);
+	}
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+	cfg_data = hose->cfg_data;
+	PEX_FIX;
+	temp = in_le32((u32 *) cfg_data);
+	switch (len) {
+	case 1:
+		*val = (temp >> (((offset & 3)) * 8)) & 0xff;
+		break;
+	case 2:
+		*val = (temp >> (((offset & 3)) * 8)) & 0xffff;
+		break;
+	default:
+		*val = temp;
+		break;
+	}
+
+	return 0;
+}
+
+static int
+indirect_write_config_pcie(struct pci_controller *hose,
+			   pci_dev_t dev,
+			   int offset,
+			   int len,
+			   u32 val)
+{
+	int bus = PCI_BUS(dev);
+	volatile unsigned char *cfg_data;
+	u32 temp;
+
+	PEX_FIX;
+	if (bus == 0xff) {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000001);
+	} else {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    dev | (offset & 0xfc) | 0x80000000);
+	}
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+	cfg_data = hose->cfg_data;
+	switch (len) {
+	case 1:
+		PEX_FIX;
+		temp = in_le32((u32 *) cfg_data);
+		temp = (temp & ~(0xff << ((offset & 3) * 8))) |
+		    (val << ((offset & 3) * 8));
+		PEX_FIX;
+		out_le32((u32 *) cfg_data, temp);
+		break;
+	case 2:
+		PEX_FIX;
+		temp = in_le32((u32 *) cfg_data);
+		temp = (temp & ~(0xffff << ((offset & 3) * 8)));
+		temp |= (val << ((offset & 3) * 8));
+		PEX_FIX;
+		out_le32((u32 *) cfg_data, temp);
+		break;
+	default:
+		PEX_FIX;
+		out_le32((u32 *) cfg_data, val);
+		break;
+	}
+	PEX_FIX;
+	return 0;
+}
+
+static int
+indirect_read_config_byte_pcie(struct pci_controller *hose,
+			       pci_dev_t dev,
+			       int offset,
+			       u8 *val)
+{
+	u32 val32;
+	indirect_read_config_pcie(hose, dev, offset, 1, &val32);
+	*val = (u8) val32;
+	return 0;
+}
+
+static int
+indirect_read_config_word_pcie(struct pci_controller *hose,
+			       pci_dev_t dev,
+			       int offset,
+			       u16 *val)
+{
+	u32 val32;
+	indirect_read_config_pcie(hose, dev, offset, 2, &val32);
+	*val = (u16) val32;
+	return 0;
+}
+
+static int
+indirect_read_config_dword_pcie(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset,
+				u32 *val)
+{
+	return indirect_read_config_pcie(hose, dev, offset, 4, val);
+}
+
+static int
+indirect_write_config_byte_pcie(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset,
+				u8 val)
+{
+	return indirect_write_config_pcie(hose, dev, offset, 1, (u32) val);
+}
+
+static int
+indirect_write_config_word_pcie(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset,
+				unsigned short val)
+{
+	return indirect_write_config_pcie(hose, dev, offset, 2, (u32) val);
+}
+
+static int
+indirect_write_config_dword_pcie(struct pci_controller *hose,
+				 pci_dev_t dev,
+				 int offset,
+				 u32 val)
+{
+	return indirect_write_config_pcie(hose, dev, offset, 4, val);
+}
+
+void
+pcie_setup_indirect(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data)
+{
+	pci_set_ops(hose,
+		    indirect_read_config_byte_pcie,
+		    indirect_read_config_word_pcie,
+		    indirect_read_config_dword_pcie,
+		    indirect_write_config_byte_pcie,
+		    indirect_write_config_word_pcie,
+		    indirect_write_config_dword_pcie);
+
+	hose->cfg_addr = (unsigned int *)cfg_addr;
+	hose->cfg_data = (unsigned char *)cfg_data;
+}
+
+#endif				/* CONFIG_PCI */
diff --git a/cpu/mpc86xx/resetvec.S b/cpu/mpc86xx/resetvec.S
new file mode 100644
index 0000000..9a552f6
--- /dev/null
+++ b/cpu/mpc86xx/resetvec.S
@@ -0,0 +1,2 @@
+	.section .resetvec,"ax"
+	b _start
diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c
new file mode 100644
index 0000000..b18e822
--- /dev/null
+++ b/cpu/mpc86xx/spd_sdram.c
@@ -0,0 +1,1320 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * (C) Copyright 2003 Motorola Inc.
+ * Xianghua Xiao (X.Xiao@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 <asm/processor.h>
+#include <i2c.h>
+#include <spd.h>
+#include <asm/mmu.h>
+
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+extern void dma_init(void);
+extern uint dma_check(void);
+extern int dma_xfer(void *dest, uint count, void *src);
+#endif
+
+#ifdef CONFIG_SPD_EEPROM
+
+#ifndef	CFG_READ_SPD
+#define CFG_READ_SPD	i2c_read
+#endif
+
+/*
+ * Only one of the following three should be 1; others should be 0
+ * By default the cache line interleaving is selected if
+ * the CONFIG_DDR_INTERLEAVE flag is defined
+ */
+#define CFG_PAGE_INTERLEAVING		0
+#define CFG_BANK_INTERLEAVING		0
+#define CFG_SUPER_BANK_INTERLEAVING	0
+
+/*
+ * Convert picoseconds into clock cycles (rounding up if needed).
+ */
+
+int
+picos_to_clk(int picos)
+{
+	int clks;
+
+	clks = picos / (2000000000 / (get_bus_freq(0) / 1000));
+	if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) {
+		clks++;
+	}
+
+	return clks;
+}
+
+
+/*
+ * Calculate the Density of each Physical Rank.
+ * Returned size is in bytes.
+ *
+ * Study these table from Byte 31 of JEDEC SPD Spec.
+ *
+ *		DDR I	DDR II
+ *	Bit	Size	Size
+ *	---	-----	------
+ *	7 high	512MB	512MB
+ *	6	256MB	256MB
+ *	5	128MB	128MB
+ *	4	 64MB	 16GB
+ *	3	 32MB	  8GB
+ *	2	 16MB	  4GB
+ *	1	  2GB	  2GB
+ *	0 low	  1GB	  1GB
+ *
+ * Reorder Table to be linear by stripping the bottom
+ * 2 or 5 bits off and shifting them up to the top.
+ */
+
+unsigned int
+compute_banksize(unsigned int mem_type, unsigned char row_dens)
+{
+	unsigned int bsize;
+
+	if (mem_type == SPD_MEMTYPE_DDR) {
+		/* Bottom 2 bits up to the top. */
+		bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
+		debug("DDR: DDR I rank density = 0x%08x\n", bsize);
+	} else {
+		/* Bottom 5 bits up to the top. */
+		bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)) << 27;
+		debug("DDR: DDR II rank density = 0x%08x\n", bsize);
+	}
+	return bsize;
+}
+
+
+/*
+ * Convert a two-nibble BCD value into a cycle time.
+ * While the spec calls for nano-seconds, picos are returned.
+ *
+ * This implements the tables for bytes 9, 23 and 25 for both
+ * DDR I and II.  No allowance for distinguishing the invalid
+ * fields absent for DDR I yet present in DDR II is made.
+ * (That is, cycle times of .25, .33, .66 and .75 ns are
+ * allowed for both DDR II and I.)
+ */
+
+unsigned int
+convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
+{
+	/*
+	 * Table look up the lower nibble, allow DDR I & II.
+	 */
+	unsigned int tenths_ps[16] = {
+		0,
+		100,
+		200,
+		300,
+		400,
+		500,
+		600,
+		700,
+		800,
+		900,
+		250,
+		330,
+		660,
+		750,
+		0,	/* undefined */
+		0	/* undefined */
+	};
+
+	unsigned int whole_ns = (spd_val & 0xF0) >> 4;
+	unsigned int tenth_ns = spd_val & 0x0F;
+	unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns];
+
+	return ps;
+}
+
+
+/*
+ * Determine Refresh Rate.  Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
+ */
+unsigned int determine_refresh_rate(unsigned int spd_refresh)
+{
+	unsigned int refresh_time_ns[8] = {
+		15625000,	/* 0 Normal    1.00x */
+		3900000,	/* 1 Reduced    .25x */
+		7800000,	/* 2 Extended   .50x */
+		31300000,	/* 3 Extended  2.00x */
+		62500000,	/* 4 Extended  4.00x */
+		125000000,	/* 5 Extended  8.00x */
+		15625000,	/* 6 Normal    1.00x  filler */
+		15625000,	/* 7 Normal    1.00x  filler */
+	};
+
+	return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
+}
+
+
+long int
+spd_init(unsigned char i2c_address, unsigned int ddr_num,
+	 unsigned int dimm_num, unsigned int start_addr)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_ddr_t *ddr;
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	spd_eeprom_t spd;
+	unsigned int n_ranks;
+	unsigned int rank_density;
+	unsigned int odt_rd_cfg, odt_wr_cfg;
+	unsigned int odt_cfg, mode_odt_enable;
+	unsigned int refresh_clk;
+#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL
+	unsigned char clk_adjust;
+#endif
+	unsigned int dqs_cfg;
+	unsigned char twr_clk, twtr_clk, twr_auto_clk;
+	unsigned int tCKmin_ps, tCKmax_ps;
+	unsigned int max_data_rate;
+	unsigned int busfreq;
+	unsigned int memsize;
+	unsigned char caslat, caslat_ctrl;
+	unsigned int trfc, trfc_clk, trfc_low, trfc_high;
+	unsigned int trcd_clk;
+	unsigned int trtp_clk;
+	unsigned char cke_min_clk;
+	unsigned char add_lat;
+	unsigned char wr_lat;
+	unsigned char wr_data_delay;
+	unsigned char four_act;
+	unsigned char cpo;
+	unsigned char burst_len;
+	unsigned int mode_caslat;
+	unsigned char d_init;
+	unsigned int tCycle_ps, modfreq;
+
+	if (ddr_num == 1)
+		ddr = &immap->im_ddr1;
+	else
+		ddr = &immap->im_ddr2;
+
+	/*
+	 * Read SPD information.
+	 */
+	debug("Performing SPD read at I2C address 0x%02lx\n",i2c_address);
+	memset((void *)&spd, 0, sizeof(spd));
+	CFG_READ_SPD(i2c_address, 0, 1, (uchar *) &spd, sizeof(spd));
+
+	/*
+	 * Check for supported memory module types.
+	 */
+	if (spd.mem_type != SPD_MEMTYPE_DDR &&
+	    spd.mem_type != SPD_MEMTYPE_DDR2) {
+		debug("Warning: Unable to locate DDR I or DDR II module for DIMM %d of DDR controller %d.\n"
+		      "         Fundamental memory type is 0x%0x\n",
+		      dimm_num,
+		      ddr_num,
+		      spd.mem_type);
+		return 0;
+	}
+
+	debug("\nFound memory of type 0x%02lx  ", spd.mem_type);
+	if (spd.mem_type == SPD_MEMTYPE_DDR)
+		debug("DDR I\n");
+	else
+		debug("DDR II\n");
+
+	/*
+	 * These test gloss over DDR I and II differences in interpretation
+	 * of bytes 3 and 4, but irrelevantly.  Multiple asymmetric banks
+	 * are not supported on DDR I; and not encoded on DDR II.
+	 *
+	 * Also note that the 8548 controller can support:
+	 *    12 <= nrow <= 16
+	 * and
+	 *     8 <= ncol <= 11 (still, for DDR)
+	 *     6 <= ncol <=  9 (for FCRAM)
+	 */
+	if (spd.nrow_addr < 12 || spd.nrow_addr > 14) {
+		printf("DDR: Unsupported number of Row Addr lines: %d.\n",
+		       spd.nrow_addr);
+		return 0;
+	}
+	if (spd.ncol_addr < 8 || spd.ncol_addr > 11) {
+		printf("DDR: Unsupported number of Column Addr lines: %d.\n",
+		       spd.ncol_addr);
+		return 0;
+	}
+
+	/*
+	 * Determine the number of physical banks controlled by
+	 * different Chip Select signals.  This is not quite the
+	 * same as the number of DIMM modules on the board.  Feh.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		n_ranks = spd.nrows;
+	} else {
+		n_ranks = (spd.nrows & 0x7) + 1;
+	}
+
+	debug("DDR: number of ranks = %d\n", n_ranks);
+
+	if (n_ranks > 2) {
+		printf("DDR: Only 2 chip selects are supported: %d\n",
+		       n_ranks);
+		return 0;
+	}
+
+	/*
+	 * Adjust DDR II IO voltage biasing.  It just makes it work.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		gur->ddrioovcr = (0
+				  | 0x80000000		/* Enable */
+				  | 0x10000000		/* VSEL to 1.8V */
+				  );
+	}
+
+	/*
+	 * Determine the size of each Rank in bytes.
+	 */
+	rank_density = compute_banksize(spd.mem_type, spd.row_dens);
+
+	debug("Start address for this controller is 0x%08lx\n", start_addr);
+
+	/*
+	 * ODT configuration recommendation from DDR Controller Chapter.
+	 */
+	odt_rd_cfg = 0;			/* Never assert ODT */
+	odt_wr_cfg = 0;			/* Never assert ODT */
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		odt_wr_cfg = 1;		/* Assert ODT on writes to CS0 */
+	}
+
+#ifdef CONFIG_DDR_INTERLEAVE
+
+	if (dimm_num != 1) {
+		printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num);
+		return 0;
+	} else {
+		/*
+		 * Since interleaved memory only uses CS0, the
+		 * memory sticks have to be identical in size and quantity
+		 * of ranks.  That essentially gives double the size on
+		 * one rank, i.e on CS0 for both controllers put together.
+		 * Confirm this???
+		 */
+		rank_density *= 2;
+
+		/*
+		 * Eg: Bounds: 0x0000_0000 to 0x0f000_0000	first 256 Meg
+		 */
+		start_addr = 0;
+		ddr->cs0_bnds = (start_addr >> 8)
+			| (((start_addr + rank_density - 1) >> 24));
+		/*
+		 * Default interleaving mode to cache-line interleaving.
+		 */
+		ddr->cs0_config = ( 1 << 31
+#if	(CFG_PAGE_INTERLEAVING == 1)
+				    | (PAGE_INTERLEAVING)
+#elif	(CFG_BANK_INTERLEAVING == 1)
+				    | (BANK_INTERLEAVING)
+#elif	(CFG_SUPER_BANK_INTERLEAVING == 1)
+				    | (SUPER_BANK_INTERLEAVING)
+#else
+				    | (CACHE_LINE_INTERLEAVING)
+#endif
+				    | (odt_rd_cfg << 20)
+				    | (odt_wr_cfg << 16)
+				    | (spd.nrow_addr - 12) << 8
+				    | (spd.ncol_addr - 8) );
+
+		debug("DDR: cs0_bnds   = 0x%08x\n", ddr->cs0_bnds);
+		debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config);
+
+		/*
+		 * Adjustment for dual rank memory to get correct memory
+		 * size (return value of this function).
+		 */
+		if (n_ranks == 2) {
+			n_ranks = 1;
+			rank_density /= 2;
+		} else {
+			rank_density /= 2;
+		}
+	}
+#else	/* CONFIG_DDR_INTERLEAVE */
+
+	if (dimm_num == 1) {
+		/*
+		 * Eg: Bounds: 0x0000_0000 to 0x0f000_0000	first 256 Meg
+		 */
+		ddr->cs0_bnds = (start_addr >> 8)
+			| (((start_addr + rank_density - 1) >> 24));
+
+		ddr->cs0_config = ( 1 << 31
+				    | (odt_rd_cfg << 20)
+				    | (odt_wr_cfg << 16)
+				    | (spd.nrow_addr - 12) << 8
+				    | (spd.ncol_addr - 8) );
+
+		debug("DDR: cs0_bnds   = 0x%08x\n", ddr->cs0_bnds);
+		debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config);
+
+		if (n_ranks == 2) {
+			/*
+			 * Eg: Bounds: 0x1000_0000 to 0x1f00_0000,
+			 * second 256 Meg
+			 */
+			ddr->cs1_bnds = (((start_addr + rank_density) >> 8)
+					| (( start_addr + 2*rank_density - 1)
+					   >> 24));
+			ddr->cs1_config = ( 1<<31
+					    | (odt_rd_cfg << 20)
+					    | (odt_wr_cfg << 16)
+					    | (spd.nrow_addr - 12) << 8
+					    | (spd.ncol_addr - 8) );
+			debug("DDR: cs1_bnds   = 0x%08x\n", ddr->cs1_bnds);
+			debug("DDR: cs1_config = 0x%08x\n", ddr->cs1_config);
+		}
+
+	} else {
+		/*
+		 * This is the 2nd DIMM slot for this controller
+		 */
+		/*
+		 * Eg: Bounds: 0x0000_0000 to 0x0f000_0000	first 256 Meg
+		 */
+		ddr->cs2_bnds = (start_addr >> 8)
+			| (((start_addr + rank_density - 1) >> 24));
+
+		ddr->cs2_config = ( 1 << 31
+				    | (odt_rd_cfg << 20)
+				    | (odt_wr_cfg << 16)
+				    | (spd.nrow_addr - 12) << 8
+				    | (spd.ncol_addr - 8) );
+
+		debug("DDR: cs2_bnds   = 0x%08x\n", ddr->cs2_bnds);
+		debug("DDR: cs2_config = 0x%08x\n", ddr->cs2_config);
+
+		if (n_ranks == 2) {
+			/*
+			 * Eg: Bounds: 0x1000_0000 to 0x1f00_0000,
+			 * second 256 Meg
+			 */
+			ddr->cs3_bnds = (((start_addr + rank_density) >> 8)
+					| (( start_addr + 2*rank_density - 1)
+					   >> 24));
+			ddr->cs3_config = ( 1<<31
+					    | (odt_rd_cfg << 20)
+					    | (odt_wr_cfg << 16)
+					    | (spd.nrow_addr - 12) << 8
+					    | (spd.ncol_addr - 8) );
+			debug("DDR: cs3_bnds   = 0x%08x\n", ddr->cs3_bnds);
+			debug("DDR: cs3_config = 0x%08x\n", ddr->cs3_config);
+		}
+	}
+#endif /* CONFIG_DDR_INTERLEAVE */
+
+	/*
+	 * Find the largest CAS by locating the highest 1 bit
+	 * in the spd.cas_lat field.  Translate it to a DDR
+	 * controller field value:
+	 *
+	 *	CAS Lat	DDR I	DDR II	Ctrl
+	 *	Clocks	SPD Bit	SPD Bit	Value
+	 *	-------	-------	-------	-----
+	 *	1.0	0		0001
+	 *	1.5	1		0010
+	 *	2.0	2	2	0011
+	 *	2.5	3		0100
+	 *	3.0	4	3	0101
+	 *	3.5	5		0110
+	 *	4.0		4	0111
+	 *	4.5			1000
+	 *	5.0		5	1001
+	 */
+	caslat = __ilog2(spd.cas_lat);
+	if ((spd.mem_type == SPD_MEMTYPE_DDR)
+	    && (caslat > 5)) {
+		printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat);
+		return 0;
+
+	} else if (spd.mem_type == SPD_MEMTYPE_DDR2
+		   && (caslat < 2 || caslat > 5)) {
+		printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n",
+		       spd.cas_lat);
+		return 0;
+	}
+	debug("DDR: caslat SPD bit is %d\n", caslat);
+
+	/*
+	 * Calculate the Maximum Data Rate based on the Minimum Cycle time.
+	 * The SPD clk_cycle field (tCKmin) is measured in tenths of
+	 * nanoseconds and represented as BCD.
+	 */
+	tCKmin_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle);
+	debug("DDR: tCKmin = %d ps\n", tCKmin_ps);
+
+	/*
+	 * Double-data rate, scaled 1000 to picoseconds, and back down to MHz.
+	 */
+	max_data_rate = 2 * 1000 * 1000 / tCKmin_ps;
+	debug("DDR: Module max data rate = %d Mhz\n", max_data_rate);
+
+
+	/*
+	 * Adjust the CAS Latency to allow for bus speeds that
+	 * are slower than the DDR module.
+	 */
+	busfreq = get_bus_freq(0) / 1000000;	/* MHz */
+	tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle3);
+	modfreq = 2 * 1000 * 1000 / tCycle_ps;
+
+	if ((spd.mem_type == SPD_MEMTYPE_DDR2) && (busfreq < 266)) {
+		printf("DDR: platform frequency too low for correct DDR2 controller operation\n");
+		return 0;
+	} else if (busfreq < 90) {
+		printf("DDR: platform frequency too low for correct DDR1 operation\n");
+		return 0;
+	}
+
+	if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 2)))) {
+		caslat -= 2;
+	} else {
+		tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle2);
+		modfreq = 2 * 1000 * 1000 / tCycle_ps;
+		if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 1))))
+			caslat -= 1;
+		else if (busfreq > max_data_rate) {
+			printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n",
+		     	busfreq, max_data_rate);
+			return 0;
+		}
+	}
+
+	/*
+	 * Empirically set ~MCAS-to-preamble override for DDR 2.
+	 * Your milage will vary.
+	 */
+	cpo = 0;
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		if (busfreq <= 333) {
+			cpo = 0x7;
+		} else if (busfreq <= 400) {
+			cpo = 0x9;
+		} else {
+			cpo = 0xa;
+		}
+	}
+
+	/*
+	 * Convert caslat clocks to DDR controller value.
+	 * Force caslat_ctrl to be DDR Controller field-sized.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		caslat_ctrl = (caslat + 1) & 0x07;
+	} else {
+		caslat_ctrl =  (2 * caslat - 1) & 0x0f;
+	}
+
+	debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n",
+	      caslat, caslat_ctrl);
+
+	/*
+	 * Timing Config 0.
+	 * Avoid writing for DDR I.  The new PQ38 DDR controller
+	 * dreams up non-zero default values to be backwards compatible.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+		unsigned char taxpd_clk = 8;		/* By the book. */
+		unsigned char tmrd_clk = 2;		/* By the book. */
+		unsigned char act_pd_exit = 2;		/* Empirical? */
+		unsigned char pre_pd_exit = 6;		/* Empirical? */
+
+		ddr->timing_cfg_0 = (0
+			| ((act_pd_exit & 0x7) << 20)	/* ACT_PD_EXIT */
+			| ((pre_pd_exit & 0x7) << 16)	/* PRE_PD_EXIT */
+			| ((taxpd_clk & 0xf) << 8)	/* ODT_PD_EXIT */
+			| ((tmrd_clk & 0xf) << 0)	/* MRS_CYC */
+			);
+		debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
+
+	}
+
+
+	/*
+	 * Some Timing Config 1 values now.
+	 * Sneak Extended Refresh Recovery in here too.
+	 */
+
+	/*
+	 * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD,
+	 * use conservative value.
+	 * For DDR II, they are bytes 36 and 37, in quarter nanos.
+	 */
+
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		twr_clk = 3;	/* Clocks */
+		twtr_clk = 1;	/* Clocks */
+	} else {
+		twr_clk = picos_to_clk(spd.twr * 250);
+		twtr_clk = picos_to_clk(spd.twtr * 250);
+	}
+
+	/*
+	 * Calculate Trfc, in picos.
+	 * DDR I:  Byte 42 straight up in ns.
+	 * DDR II: Byte 40 and 42 swizzled some, in ns.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		trfc = spd.trfc * 1000;		/* up to ps */
+	} else {
+		unsigned int byte40_table_ps[8] = {
+			0,
+			250,
+			330,
+			500,
+			660,
+			750,
+			0,
+			0
+		};
+
+		trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000
+			+ byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7];
+	}
+	trfc_clk = picos_to_clk(trfc);
+
+	/*
+	 * Trcd, Byte 29, from quarter nanos to ps and clocks.
+	 */
+	trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7;
+
+	/*
+	 * Convert trfc_clk to DDR controller fields.  DDR I should
+	 * fit in the REFREC field (16-19) of TIMING_CFG_1, but the
+	 * 8548 controller has an extended REFREC field of three bits.
+	 * The controller automatically adds 8 clocks to this value,
+	 * so preadjust it down 8 first before splitting it up.
+	 */
+	trfc_low = (trfc_clk - 8) & 0xf;
+	trfc_high = ((trfc_clk - 8) >> 4) & 0x3;
+
+	/*
+	 * Sneak in some Extended Refresh Recovery.
+	 */
+	ddr->ext_refrec = (trfc_high << 16);
+	debug("DDR: ext_refrec = 0x%08x\n", ddr->ext_refrec);
+
+	ddr->timing_cfg_1 =
+	    (0
+	     | ((picos_to_clk(spd.trp * 250) & 0x07) << 28)	/* PRETOACT */
+	     | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24)	/* ACTTOPRE */
+	     | (trcd_clk << 20)					/* ACTTORW */
+	     | (caslat_ctrl << 16)				/* CASLAT */
+	     | (trfc_low << 12)					/* REFEC */
+	     | ((twr_clk & 0x07) << 8)				/* WRRREC */
+	     | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4)	/* ACTTOACT */
+	     | ((twtr_clk & 0x07) << 0)				/* WRTORD */
+	     );
+
+	debug("DDR: timing_cfg_1  = 0x%08x\n", ddr->timing_cfg_1);
+
+
+	/*
+	 * Timing_Config_2
+	 * Was: 0x00000800;
+	 */
+
+	/*
+	 * Additive Latency
+	 * For DDR I, 0.
+	 * For DDR II, with ODT enabled, use "a value" less than ACTTORW,
+	 * which comes from Trcd, and also note that:
+	 *	add_lat + caslat must be >= 4
+	 */
+	add_lat = 0;
+	if (spd.mem_type == SPD_MEMTYPE_DDR2
+	    && (odt_wr_cfg || odt_rd_cfg)
+	    && (caslat < 4)) {
+		add_lat = 4 - caslat;
+		if (add_lat >= trcd_clk) {
+			add_lat = trcd_clk - 1;
+		}
+	}
+
+	/*
+	 * Write Data Delay
+	 * Historically 0x2 == 4/8 clock delay.
+	 * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
+	 */
+	wr_data_delay = 3;
+
+	/*
+	 * Write Latency
+	 * Read to Precharge
+	 * Minimum CKE Pulse Width.
+	 * Four Activate Window
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		/*
+		 * This is a lie.  It should really be 1, but if it is
+		 * set to 1, bits overlap into the old controller's
+		 * otherwise unused ACSM field.  If we leave it 0, then
+		 * the HW will magically treat it as 1 for DDR 1.  Oh Yea.
+		 */
+		wr_lat = 0;
+
+		trtp_clk = 2;		/* By the book. */
+		cke_min_clk = 1;	/* By the book. */
+		four_act = 1;		/* By the book. */
+
+	} else {
+		wr_lat = caslat - 1;
+
+		/* Convert SPD value from quarter nanos to picos. */
+		trtp_clk = picos_to_clk(spd.trtp * 250);
+
+		cke_min_clk = 3;	/* By the book. */
+		four_act = picos_to_clk(37500);	/* By the book. 1k pages? */
+	}
+
+	ddr->timing_cfg_2 = (0
+		| ((add_lat & 0x7) << 28)		/* ADD_LAT */
+		| ((cpo & 0x1f) << 23)			/* CPO */
+		| ((wr_lat & 0x7) << 19)		/* WR_LAT */
+		| ((trtp_clk & 0x7) << 13)		/* RD_TO_PRE */
+		| ((wr_data_delay & 0x7) << 10)		/* WR_DATA_DELAY */
+		| ((cke_min_clk & 0x7) << 6)		/* CKE_PLS */
+		| ((four_act & 0x1f) << 0)		/* FOUR_ACT */
+		);
+
+	debug("DDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
+
+
+	/*
+	 * Determine the Mode Register Set.
+	 *
+	 * This is nominally part specific, but it appears to be
+	 * consistent for all DDR I devices, and for all DDR II devices.
+	 *
+	 *     caslat must be programmed
+	 *     burst length is always 4
+	 *     burst type is sequential
+	 *
+	 * For DDR I:
+	 *     operating mode is "normal"
+	 *
+	 * For DDR II:
+	 *     other stuff
+	 */
+
+	mode_caslat = 0;
+
+	/*
+	 * Table lookup from DDR I or II Device Operation Specs.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		if (1 <= caslat && caslat <= 4) {
+			unsigned char mode_caslat_table[4] = {
+				0x5,	/* 1.5 clocks */
+				0x2,	/* 2.0 clocks */
+				0x6,	/* 2.5 clocks */
+				0x3	/* 3.0 clocks */
+			};
+			mode_caslat = mode_caslat_table[caslat - 1];
+		} else {
+			puts("DDR I: Only CAS Latencies of 1.5, 2.0, "
+			     "2.5 and 3.0 clocks are supported.\n");
+			return 0;
+		}
+
+	} else {
+		if (2 <= caslat && caslat <= 5) {
+			mode_caslat = caslat;
+		} else {
+			puts("DDR II: Only CAS Latencies of 2.0, 3.0, "
+			     "4.0 and 5.0 clocks are supported.\n");
+			return 0;
+		}
+	}
+
+	/*
+	 * Encoded Burst Length of 4.
+	 */
+	burst_len = 2;			/* Fiat. */
+
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		twr_auto_clk = 0;	/* Historical */
+	} else {
+		/*
+		 * Determine tCK max in picos.  Grab tWR and convert to picos.
+		 * Auto-precharge write recovery is:
+		 *	WR = roundup(tWR_ns/tCKmax_ns).
+		 *
+		 * Ponder: Is twr_auto_clk different than twr_clk?
+		 */
+		tCKmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd.tckmax);
+		twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps;
+	}
+
+	/*
+	 * Mode Reg in bits 16 ~ 31,
+	 * Extended Mode Reg 1 in bits 0 ~ 15.
+	 */
+	mode_odt_enable = 0x0;			/* Default disabled */
+	if (odt_wr_cfg || odt_rd_cfg) {
+		/*
+		 * Bits 6 and 2 in Extended MRS(1)
+		 * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules.
+		 * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module.
+		 */
+		mode_odt_enable = 0x40;		/* 150 Ohm */
+	}
+
+	ddr->sdram_mode_1 =
+		(0
+		 | (add_lat << (16 + 3))	/* Additive Latency in EMRS1 */
+		 | (mode_odt_enable << 16)	/* ODT Enable in EMRS1 */
+		 | (twr_auto_clk << 9)		/* Write Recovery Autopre */
+		 | (mode_caslat << 4)		/* caslat */
+		 | (burst_len << 0)		/* Burst length */
+		 );
+
+	debug("DDR: sdram_mode   = 0x%08x\n", ddr->sdram_mode_1);
+
+	/*
+	 * Clear EMRS2 and EMRS3.
+	 */
+	ddr->sdram_mode_2 = 0;
+	debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
+
+	/*
+	 * Determine Refresh Rate.
+	 */
+	refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
+
+	/*
+	 * Set BSTOPRE to 0x100 for page mode
+	 * If auto-charge is used, set BSTOPRE = 0
+	 */
+	ddr->sdram_interval =
+		(0
+		 | (refresh_clk & 0x3fff) << 16
+		 | 0x100
+		 );
+	debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
+
+
+	/*
+	 * Is this an ECC DDR chip?
+	 * But don't mess with it if the DDR controller will init mem.
+	 */
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+	if (spd.config == 0x02) {
+		ddr->err_disable = 0x0000000d;
+		ddr->err_sbe = 0x00ff0000;
+	}
+	debug("DDR: err_disable = 0x%08x\n", ddr->err_disable);
+	debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe);
+#endif
+
+	asm volatile("sync;isync");
+	udelay(500);
+
+	/*
+	 * SDRAM Cfg 2
+	 */
+
+	/*
+	 * When ODT is enabled, Chap 9 suggests asserting ODT to
+	 * internal IOs only during reads.
+	 */
+	odt_cfg = 0;
+	if (odt_rd_cfg | odt_wr_cfg) {
+		odt_cfg = 0x2;		/* ODT to IOs during reads */
+	}
+
+	/*
+	 * Try to use differential DQS with DDR II.
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR) {
+		dqs_cfg = 0;		/* No Differential DQS for DDR I */
+	} else {
+		dqs_cfg = 0x1;		/* Differential DQS for DDR II */
+	}
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+	/*
+	 * Use the DDR controller to auto initialize memory.
+	 */
+	d_init = 1;
+	ddr->sdram_data_init = CONFIG_MEM_INIT_VALUE;
+	debug("DDR: ddr_data_init = 0x%08x\n", ddr->sdram_data_init);
+#else
+	/*
+	 * Memory will be initialized via DMA, or not at all.
+	 */
+	d_init = 0;
+#endif
+
+	ddr->sdram_cfg_2 = (0
+			    | (dqs_cfg << 26)	/* Differential DQS */
+			    | (odt_cfg << 21)	/* ODT */
+			    | (d_init << 4)	/* D_INIT auto init DDR */
+			    );
+
+	debug("DDR: sdram_cfg_2  = 0x%08x\n", ddr->sdram_cfg_2);
+
+
+#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL
+	/*
+	 * Setup the clock control.
+	 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+	 * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+	 *	0110	3/4 cycle late
+	 *	0111	7/8 cycle late
+	 */
+	if (spd.mem_type == SPD_MEMTYPE_DDR)
+		clk_adjust = 0x6;
+	else
+		clk_adjust = 0x7;
+
+	ddr->sdram_clk_cntl = (0
+			       | 0x80000000
+			       | (clk_adjust << 23)
+			       );
+	debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
+#endif
+
+	/*
+	 * Figure out memory size in Megabytes.
+	 */
+	debug("# ranks = %d, rank_density = 0x%08lx\n", n_ranks, rank_density);
+	memsize = n_ranks * rank_density / 0x100000;
+	return memsize;
+}
+
+
+unsigned int enable_ddr(unsigned int ddr_num)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	spd_eeprom_t spd1,spd2;
+	volatile ccsr_ddr_t *ddr;
+	unsigned sdram_cfg_1;
+	unsigned char sdram_type, mem_type, config, mod_attr;
+	unsigned char d_init;
+	unsigned int no_dimm1=0, no_dimm2=0;
+
+	/* Set up pointer to enable the current ddr controller */
+	if (ddr_num == 1)
+		ddr = &immap->im_ddr1;
+	else
+		ddr = &immap->im_ddr2;
+
+	/*
+	 * Read both dimm slots and decide whether
+	 * or not to enable this controller.
+	 */
+	memset((void *)&spd1,0,sizeof(spd1));
+	memset((void *)&spd2,0,sizeof(spd2));
+
+	if (ddr_num == 1) {
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS1,
+			     0, 1, (uchar *) &spd1, sizeof(spd1));
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS2,
+			     0, 1, (uchar *) &spd2, sizeof(spd2));
+	} else {
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS3,
+			     0, 1, (uchar *) &spd1, sizeof(spd1));
+		CFG_READ_SPD(SPD_EEPROM_ADDRESS4,
+			     0, 1, (uchar *) &spd2, sizeof(spd2));
+	}
+
+	/*
+	 * Check for supported memory module types.
+	 */
+	if (spd1.mem_type != SPD_MEMTYPE_DDR
+	    && spd1.mem_type != SPD_MEMTYPE_DDR2) {
+		no_dimm1 = 1;
+	} else {
+		debug("\nFound memory of type 0x%02lx  ",spd1.mem_type );
+		if (spd1.mem_type == SPD_MEMTYPE_DDR)
+			debug("DDR I\n");
+		else
+			debug("DDR II\n");
+	}
+
+	if (spd2.mem_type != SPD_MEMTYPE_DDR &&
+	    spd2.mem_type != SPD_MEMTYPE_DDR2) {
+		no_dimm2 = 1;
+	} else {
+		debug("\nFound memory of type 0x%02lx  ",spd2.mem_type );
+		if (spd2.mem_type == SPD_MEMTYPE_DDR)
+			debug("DDR I\n");
+		else
+			debug("DDR II\n");
+	}
+
+#ifdef CONFIG_DDR_INTERLEAVE
+	if (no_dimm1) {
+		printf("For interleaved operation memory modules need to be present in CS0 DIMM slots of both DDR controllers!\n");
+		return 0;
+	}
+#endif
+
+	/*
+	 * Memory is not present in DIMM1 and DIMM2 - so do not enable DDRn
+	 */
+	if (no_dimm1  && no_dimm2) {
+		printf("No memory modules found for DDR controller %d!!\n", ddr_num);
+		return 0;
+	} else {
+		mem_type = no_dimm2 ? spd1.mem_type : spd2.mem_type;
+
+		/*
+		 * Figure out the settings for the sdram_cfg register.
+		 * Build up the entire register in 'sdram_cfg' before
+		 * writing since the write into the register will
+		 * actually enable the memory controller; all settings
+		 * must be done before enabling.
+		 *
+		 * sdram_cfg[0]   = 1 (ddr sdram logic enable)
+		 * sdram_cfg[1]   = 1 (self-refresh-enable)
+		 * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM)
+		 *			010 DDR 1 SDRAM
+		 *			011 DDR 2 SDRAM
+		 */
+		sdram_type = (mem_type == SPD_MEMTYPE_DDR) ? 2 : 3;
+		sdram_cfg_1 = (0
+			       | (1 << 31)		/* Enable */
+			       | (1 << 30)		/* Self refresh */
+			       | (sdram_type << 24)	/* SDRAM type */
+			       );
+
+		/*
+		 * sdram_cfg[3] = RD_EN - registered DIMM enable
+		 *   A value of 0x26 indicates micron registered
+		 *   DIMMS (micron.com)
+		 */
+		mod_attr = no_dimm2 ? spd1.mod_attr : spd2.mod_attr;
+		if (mem_type == SPD_MEMTYPE_DDR && mod_attr == 0x26) {
+			sdram_cfg_1 |= 0x10000000;		/* RD_EN */
+		}
+
+#if defined(CONFIG_DDR_ECC)
+
+		config = no_dimm2 ? spd1.config : spd2.config;
+
+		/*
+		 * If the user wanted ECC (enabled via sdram_cfg[2])
+		 */
+		if (config == 0x02) {
+			ddr->err_disable = 0x00000000;
+			asm volatile("sync;isync;");
+			ddr->err_sbe = 0x00ff0000;
+			ddr->err_int_en = 0x0000000d;
+			sdram_cfg_1 |= 0x20000000;		/* ECC_EN */
+		}
+#endif
+
+		/*
+		 * Set 1T or 2T timing based on 1 or 2 modules
+		 */
+		{
+			if (!(no_dimm1 || no_dimm2)) {
+				/*
+				 * 2T timing,because both DIMMS are present.
+				 * Enable 2T timing by setting sdram_cfg[16].
+				 */
+				sdram_cfg_1 |= 0x8000;		/* 2T_EN */
+			}
+		}
+
+		/*
+		 * 200 painful micro-seconds must elapse between
+		 * the DDR clock setup and the DDR config enable.
+		 */
+		udelay(200);
+
+		/*
+		 * Go!
+		 */
+		ddr->sdram_cfg_1 = sdram_cfg_1;
+
+		asm volatile("sync;isync");
+		udelay(500);
+
+		debug("DDR: sdram_cfg   = 0x%08x\n", ddr->sdram_cfg_1);
+
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+		d_init = 1;
+		debug("DDR: memory initializing\n");
+
+		/*
+		 * Poll until memory is initialized.
+		 * 512 Meg at 400 might hit this 200 times or so.
+		 */
+		while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) {
+			udelay(1000);
+		}
+		debug("DDR: memory initialized\n\n");
+#endif
+
+		debug("Enabled DDR Controller %d\n", ddr_num);
+		return 1;
+	}
+}
+
+
+long int
+spd_sdram(void)
+{
+	int memsize_ddr1_dimm1 = 0;
+	int memsize_ddr1_dimm2 = 0;
+	int memsize_ddr2_dimm1 = 0;
+	int memsize_ddr2_dimm2 = 0;
+	int memsize_total = 0;
+	int memsize_ddr1 = 0;
+	int memsize_ddr2 = 0;
+	unsigned int ddr1_enabled = 0;
+	unsigned int ddr2_enabled = 0;
+	unsigned int law_size_ddr1;
+	unsigned int law_size_ddr2;
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+
+#ifdef CONFIG_DDR_INTERLEAVE
+	unsigned int law_size_interleaved;
+	volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;
+	volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2;
+
+	memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,
+				      1, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr1_dimm1;
+
+	memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,
+				      2, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr2_dimm1;
+
+	if (memsize_ddr1_dimm1 != memsize_ddr2_dimm1) {
+		if (memsize_ddr1_dimm1 <  memsize_ddr2_dimm1)
+			memsize_total -= memsize_ddr1_dimm1;
+		else
+			memsize_total -= memsize_ddr2_dimm1;
+		debug("Total memory available for interleaving 0x%08lx\n",
+		      memsize_total * 1024 * 1024);
+		debug("Adjusting CS0_BNDS to account for unequal DIMM sizes in interleaved memory\n");
+		ddr1->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;
+		ddr2->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;
+		debug("DDR1: cs0_bnds   = 0x%08x\n", ddr1->cs0_bnds);
+		debug("DDR2: cs0_bnds   = 0x%08x\n", ddr2->cs0_bnds);
+	}
+
+	ddr1_enabled = enable_ddr(1);
+	ddr2_enabled = enable_ddr(2);
+
+	/*
+	 * Both controllers need to be enabled for interleaving.
+	 */
+	if (ddr1_enabled && ddr2_enabled) {
+		law_size_interleaved = 19 + __ilog2(memsize_total);
+
+		/*
+		 * Set up LAWBAR for DDR 1 space.
+		 */
+		mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+		mcm->lawar1 = (LAWAR_EN
+			       | LAWAR_TRGT_IF_DDR_INTERLEAVED
+			       | (LAWAR_SIZE & law_size_interleaved));
+		debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);
+		debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);
+		debug("Interleaved memory size is 0x%08lx\n", memsize_total);
+
+#ifdef	CONFIG_DDR_INTERLEAVE
+#if (CFG_PAGE_INTERLEAVING == 1)
+		printf("Page ");
+#elif (CFG_BANK_INTERLEAVING == 1)
+		printf("Bank ");
+#elif (CFG_SUPER_BANK_INTERLEAVING == 1)
+		printf("Super-bank ");
+#else
+		printf("Cache-line ");
+#endif
+#endif
+		printf("Interleaved");
+		return memsize_total * 1024 * 1024;
+	}  else {
+		printf("Interleaved memory not enabled - check CS0 DIMM slots for both controllers.\n");
+		return 0;
+	}
+
+#else
+	/*
+	 * Call spd_sdram() routine to init ddr1 - pass I2c address,
+	 * controller number, dimm number, and starting address.
+	 */
+	memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,
+				      1, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr1_dimm1;
+
+	memsize_ddr1_dimm2 = spd_init(SPD_EEPROM_ADDRESS2,
+				      1, 2,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr1_dimm2;
+
+	/*
+	 * Enable the DDR controller - pass ddr controller number.
+	 */
+	ddr1_enabled = enable_ddr(1);
+
+	/* Keep track of memory to be addressed by DDR1 */
+	memsize_ddr1 = memsize_ddr1_dimm1 + memsize_ddr1_dimm2;
+
+	/*
+	 * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23.  Fnord.
+	 */
+	if (ddr1_enabled) {
+		law_size_ddr1 = 19 + __ilog2(memsize_ddr1);
+
+		/*
+		 * Set up LAWBAR for DDR 1 space.
+		 */
+		mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+		mcm->lawar1 = (LAWAR_EN
+			       | LAWAR_TRGT_IF_DDR1
+			       | (LAWAR_SIZE & law_size_ddr1));
+		debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);
+		debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);
+	}
+
+#if  (CONFIG_NUM_DDR_CONTROLLERS > 1)
+	memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,
+				      2, 1,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr2_dimm1;
+
+	memsize_ddr2_dimm2 = spd_init(SPD_EEPROM_ADDRESS4,
+				      2, 2,
+				      (unsigned int)memsize_total * 1024*1024);
+	memsize_total += memsize_ddr2_dimm2;
+
+	ddr2_enabled = enable_ddr(2);
+
+	/* Keep track of memory to be addressed by DDR2 */
+	memsize_ddr2 = memsize_ddr2_dimm1 + memsize_ddr2_dimm2;
+
+	if (ddr2_enabled) {
+		law_size_ddr2 = 19 + __ilog2(memsize_ddr2);
+
+		/*
+		 * Set up LAWBAR for DDR 2 space.
+		 */
+		if (ddr1_enabled)
+			mcm->lawbar8 = (((memsize_ddr1 * 1024 * 1024) >> 12)
+					& 0xfffff);
+		else
+			mcm->lawbar8 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+
+		mcm->lawar8 = (LAWAR_EN
+			       | LAWAR_TRGT_IF_DDR2
+			       | (LAWAR_SIZE & law_size_ddr2));
+		debug("\nDDR: LAWBAR8=0x%08x\n", mcm->lawbar8);
+		debug("DDR: LAWAR8=0x%08x\n", mcm->lawar8);
+	}
+#endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */
+
+	debug("\nMemory sizes are DDR1 = 0x%08lx, DDR2 = 0x%08lx\n",
+	      memsize_ddr1, memsize_ddr2);
+
+	/*
+	 * If neither DDR controller is enabled return 0.
+	 */
+	if (!ddr1_enabled && !ddr2_enabled)
+		return 0;
+
+	printf("Non-interleaved");
+	return memsize_total * 1024 * 1024;
+
+#endif /* CONFIG_DDR_INTERLEAVE */
+}
+
+
+#endif /* CONFIG_SPD_EEPROM */
+
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+
+/*
+ * Initialize all of memory for ECC, then enable errors.
+ */
+
+void
+ddr_enable_ecc(unsigned int dram_size)
+{
+	uint *p = 0;
+	uint i = 0;
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_ddr_t *ddr1= &immap->im_ddr1;
+
+	dma_init();
+
+	for (*p = 0; p < (uint *)(8 * 1024); p++) {
+		if (((unsigned int)p & 0x1f) == 0) {
+			ppcDcbz((unsigned long) p);
+		}
+		*p = (unsigned int)CONFIG_MEM_INIT_VALUE;
+		if (((unsigned int)p & 0x1c) == 0x1c) {
+			ppcDcbf((unsigned long) p);
+		}
+	}
+
+	dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
+	dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
+	dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
+	dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
+	dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
+	dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
+	dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
+	dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+	dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+	dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
+
+	for (i = 1; i < dram_size / 0x800000; i++) {
+		dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
+	}
+
+	/*
+	 * Enable errors for ECC.
+	 */
+	debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
+	ddr1->err_disable = 0x00000000;
+	asm volatile("sync;isync");
+	debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
+}
+
+#endif	/* CONFIG_DDR_ECC  && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */
diff --git a/cpu/mpc86xx/speed.c b/cpu/mpc86xx/speed.c
new file mode 100644
index 0000000..312ca12
--- /dev/null
+++ b/cpu/mpc86xx/speed.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc86xx.h>
+#include <asm/processor.h>
+
+
+void get_sys_info(sys_info_t *sysInfo)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile ccsr_gur_t *gur = &immap->im_gur;
+	uint plat_ratio, e600_ratio;
+
+	plat_ratio = (gur->porpllsr) & 0x0000003e;
+	plat_ratio >>= 1;
+
+	switch (plat_ratio) {
+	case 0x0:
+		sysInfo->freqSystemBus = 16 * CONFIG_SYS_CLK_FREQ;
+		break;
+	case 0x02:
+	case 0x03:
+	case 0x04:
+	case 0x05:
+	case 0x06:
+	case 0x08:
+	case 0x09:
+	case 0x0a:
+	case 0x0c:
+	case 0x10:
+		sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ;
+		break;
+	default:
+		sysInfo->freqSystemBus = 0;
+		break;
+	}
+
+	e600_ratio = (gur->porpllsr) & 0x003f0000;
+	e600_ratio >>= 16;
+
+	switch (e600_ratio) {
+	case 0x10:
+		sysInfo->freqProcessor = 2 * sysInfo->freqSystemBus;
+		break;
+	case 0x19:
+		sysInfo->freqProcessor = 5 * sysInfo->freqSystemBus / 2;
+		break;
+	case 0x20:
+		sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus;
+		break;
+	case 0x39:
+		sysInfo->freqProcessor = 7 * sysInfo->freqSystemBus / 2;
+		break;
+	case 0x28:
+		sysInfo->freqProcessor = 4 * sysInfo->freqSystemBus;
+		break;
+	case 0x1d:
+		sysInfo->freqProcessor = 9 * sysInfo->freqSystemBus / 2;
+		break;
+	default:
+		sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus;
+		break;
+	}
+}
+
+
+/*
+ * Measure CPU clock speed (core clock GCLK1, GCLK2)
+ * (Approx. GCLK frequency in Hz)
+ */
+
+int get_clocks(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	sys_info_t sys_info;
+
+	get_sys_info(&sys_info);
+	gd->cpu_clk = sys_info.freqProcessor;
+	gd->bus_clk = sys_info.freqSystemBus;
+
+	if (gd->cpu_clk != 0)
+		return 0;
+	else
+		return 1;
+}
+
+
+/*
+ * get_bus_freq
+ *	Return system bus freq in Hz
+ */
+
+ulong get_bus_freq(ulong dummy)
+{
+	ulong val;
+	sys_info_t sys_info;
+
+	get_sys_info(&sys_info);
+	val = sys_info.freqSystemBus;
+
+	return val;
+}
diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S
new file mode 100644
index 0000000..7406fe2
--- /dev/null
+++ b/cpu/mpc86xx/start.S
@@ -0,0 +1,1226 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Srikanth Srinivasan <srikanth.srinivaan@freescale.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
+ */
+
+/*  U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
+ *
+ *
+ *  The processor starts at 0xfff00100 and the code is executed
+ *  from flash. The code is organized to be at an other address
+ *  in memory, but as long we don't jump around before relocating.
+ *  board_init lies at a quite high address and when the cpu has
+ *  jumped there, everything is ok.
+ */
+#include <config.h>
+#include <mpc86xx.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef	CONFIG_IDENT_STRING
+#define CONFIG_IDENT_STRING ""
+#endif
+
+/* We don't want the  MMU yet.
+*/
+#undef	MSR_KERNEL
+/* Machine Check and Recoverable Interr. */
+#define MSR_KERNEL ( MSR_ME | MSR_RI )
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+	START_GOT
+	GOT_ENTRY(_GOT2_TABLE_)
+	GOT_ENTRY(_FIXUP_TABLE_)
+
+	GOT_ENTRY(_start)
+	GOT_ENTRY(_start_of_vectors)
+	GOT_ENTRY(_end_of_vectors)
+	GOT_ENTRY(transfer_to_handler)
+
+	GOT_ENTRY(__init_end)
+	GOT_ENTRY(_end)
+	GOT_ENTRY(__bss_start)
+	END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+	.text
+	.long	0x27051956		/* U-Boot Magic Number */
+	.globl	version_string
+version_string:
+	.ascii	U_BOOT_VERSION
+	.ascii	" (", __DATE__, " - ", __TIME__, ")"
+	.ascii	CONFIG_IDENT_STRING, "\0"
+
+	. = EXC_OFF_SYS_RESET
+	.globl	_start
+_start:
+	li	r21, BOOTFLAG_COLD	/* Normal Power-On: Boot from FLASH */
+	b	boot_cold
+	sync
+
+	. = EXC_OFF_SYS_RESET + 0x10
+
+	.globl	_start_warm
+_start_warm:
+	li	r21, BOOTFLAG_WARM	/* Software reboot */
+	b	boot_warm
+	sync
+
+	/* the boot code is located below the exception table */
+
+	.globl	_start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+
+/* Data Storage exception. */
+	STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+	STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+	. = 0x600
+Alignment:
+	EXCEPTION_PROLOG
+	mfspr	r4,DAR
+	stw	r4,_DAR(r21)
+	mfspr	r5,DSISR
+	stw	r5,_DSISR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_Alignment:
+	.long	AlignmentException - _start + EXC_OFF_SYS_RESET
+	.long	int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+	. = 0x700
+ProgramCheck:
+	EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_ProgramCheck:
+	.long	ProgramCheckException - _start + EXC_OFF_SYS_RESET
+	.long	int_return - _start + EXC_OFF_SYS_RESET
+
+	STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+
+	/* I guess we could implement decrementer, and may have
+	 * to someday for timekeeping.
+	 */
+	STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
+	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+	STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+	STD_EXCEPTION(0xd00, SingleStep, UnknownException)
+	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+	STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
+	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
+	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
+	STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
+	STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
+	STD_EXCEPTION(0x1500, Reserved5, UnknownException)
+	STD_EXCEPTION(0x1600, Reserved6, UnknownException)
+	STD_EXCEPTION(0x1700, Reserved7, UnknownException)
+	STD_EXCEPTION(0x1800, Reserved8, UnknownException)
+	STD_EXCEPTION(0x1900, Reserved9, UnknownException)
+	STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
+	STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
+	STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
+	STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
+	STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
+	STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
+
+	.globl	_end_of_vectors
+_end_of_vectors:
+
+	. = 0x2000
+
+boot_cold:
+boot_warm:
+
+	/* if this is a multi-core system we need to check which cpu
+	 * this is, if it is not cpu 0 send the cpu to the linux reset
+	 * vector */
+#if (CONFIG_NUM_CPUS > 1)
+	mfspr	r0, MSSCR0
+	andi.	r0, r0, 0x0020
+	rlwinm	r0,r0,27,31,31
+	mtspr	PIR, r0
+	beq	1f
+
+	bl	secondary_cpu_setup
+#endif
+
+	/* disable everything */
+1:	li	r0, 0
+	mtspr	HID0, r0
+	sync
+	mtmsr	0
+	bl	invalidate_bats
+	sync
+
+#ifdef CFG_L2
+	/* init the L2 cache */
+	addis	r3, r0, L2_INIT@h
+	ori	r3, r3, L2_INIT@l
+	mtspr	l2cr, r3
+	/* invalidate the L2 cache */
+	bl	l2cache_invalidate
+	sync
+#endif
+
+	/*
+	 * Calculate absolute address in FLASH and jump there
+	 *------------------------------------------------------*/
+	lis	r3, CFG_MONITOR_BASE@h
+	ori	r3, r3, CFG_MONITOR_BASE@l
+	addi	r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
+	mtlr	r3
+	blr
+
+in_flash:
+	/* let the C-code set up the rest			*/
+	/*							*/
+	/* Be careful to keep code relocatable !		*/
+	/*------------------------------------------------------*/
+	/* perform low-level init */
+
+	/* enable extended addressing */
+	bl	enable_ext_addr
+
+	/* setup the bats */
+	bl	setup_bats
+	sync
+
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+	/* setup ccsrbar */
+	bl	setup_ccsrbar
+#endif
+
+	/* Fix for SMP linux - Changing arbitration to round-robin */
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x1000
+	xor	r4, r4, r4
+	li	r4, 0x1000
+	stw	r4, 0(r3)
+
+	/* setup the law entries */
+	bl	law_entry
+	sync
+
+	/* Don't use this feature due to bug in 8641D PD4 */
+	/* Disable ERD_DIS */
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x1008
+	lwz	r4, 0(r3)
+	oris	r4, r4, 0x4000
+	stw	r4, 0(r3)
+	sync
+
+#if (EMULATOR_RUN == 1)
+	/* On the emulator we want to adjust these ASAP */
+	/* otherwise things are sloooow */
+	/* Setup OR0 (LALE FIX)*/
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x5004
+	li	r4, 0x0FF3
+	stw	r4, 0(r3)
+	sync
+
+	/* Setup LCRR */
+	lis	r3, CFG_CCSRBAR@h
+	ori	r3, r3, 0x50D4
+	lis	r4, 0x8000
+	ori	r4, r4, 0x0002
+	stw	r4, 0(r3)
+	sync
+#endif
+#if 1
+	/* make sure timer enabled in guts register too */
+	lis	r3, CFG_CCSRBAR@h
+	oris	r3,r3, 0xE
+	ori	r3,r3,0x0070
+	lwz	r4, 0(r3)
+	lis	r5,0xFFFC
+	ori	r5,r5,0x5FFF
+	and	r4,r4,r5
+	stw	r4,0(r3)
+#endif
+	/*
+	 * Cache must be enabled here for stack-in-cache trick.
+	 * This means we need to enable the BATS.
+	 * Cache should be turned on after BATs, since by default
+	 * everything is write-through.
+	 */
+
+	/* enable address translation */
+	bl	enable_addr_trans
+	sync
+
+	/* enable and invalidate the data cache */
+/*	bl	l1dcache_enable */
+	bl	dcache_enable
+	sync
+
+#if 1
+	bl	icache_enable
+#endif
+
+#ifdef CFG_INIT_RAM_LOCK
+	bl	lock_ram_in_cache
+	sync
+#endif
+
+	/* set up the stack pointer in our newly created
+	 * cache-ram (r1) */
+	lis	r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
+	ori	r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
+
+	li	r0, 0		/* Make room for stack frame header and */
+	stwu	r0, -4(r1)	/* clear final stack frame so that	*/
+	stwu	r0, -4(r1)	/* stack backtraces terminate cleanly	*/
+
+	GET_GOT			/* initialize GOT access	*/
+
+	/* run low-level CPU init code	   (from Flash) */
+	bl	cpu_init_f
+	sync
+
+#ifdef	RUN_DIAG
+
+	/* Sri:	 Code to run the diagnostic automatically */
+
+	/* Load PX_AUX register address in r4 */
+	lis	r4, 0xf810
+	ori	r4, r4, 0x6
+	/* Load contents of PX_AUX in r3 bits 24 to 31*/
+	lbz	r3, 0(r4)
+
+	/* Mask and obtain the bit in r3 */
+	rlwinm. r3, r3, 0, 24, 24
+	/* If not zero, jump and continue with u-boot */
+	bne	diag_done
+
+	/* Load back contents of PX_AUX in r3 bits 24 to 31 */
+	lbz	r3, 0(r4)
+	/* Set the MSB of the register value */
+	ori	r3, r3, 0x80
+	/* Write value in r3 back to PX_AUX */
+	stb	r3, 0(r4)
+
+	/* Get the address to jump to in r3*/
+	lis	r3, CFG_DIAG_ADDR@h
+	ori	r3, r3, CFG_DIAG_ADDR@l
+
+	/* Load the LR with the branch address */
+	mtlr	r3
+
+	/* Branch to diagnostic */
+	blr
+
+diag_done:
+#endif
+
+/*	bl	l2cache_enable */
+	mr	r3, r21
+
+	/* r3: BOOTFLAG */
+	/* run 1st part of board init code (from Flash)	  */
+	bl	board_init_f
+	sync
+
+	/* NOTREACHED */
+
+	.globl	invalidate_bats
+invalidate_bats:
+
+	/* invalidate BATs */
+	mtspr	IBAT0U, r0
+	mtspr	IBAT1U, r0
+	mtspr	IBAT2U, r0
+	mtspr	IBAT3U, r0
+	mtspr	IBAT4U, r0
+	mtspr	IBAT5U, r0
+	mtspr	IBAT6U, r0
+	mtspr	IBAT7U, r0
+
+	isync
+	mtspr	DBAT0U, r0
+	mtspr	DBAT1U, r0
+	mtspr	DBAT2U, r0
+	mtspr	DBAT3U, r0
+	mtspr	DBAT4U, r0
+	mtspr	DBAT5U, r0
+	mtspr	DBAT6U, r0
+	mtspr	DBAT7U, r0
+
+	isync
+	sync
+	blr
+
+
+	/* setup_bats - set them up to some initial state */
+	.globl	setup_bats
+setup_bats:
+
+	addis	r0, r0, 0x0000
+
+	/* IBAT 0 */
+	addis	r4, r0, CFG_IBAT0L@h
+	ori	r4, r4, CFG_IBAT0L@l
+	addis	r3, r0, CFG_IBAT0U@h
+	ori	r3, r3, CFG_IBAT0U@l
+	mtspr	IBAT0L, r4
+	mtspr	IBAT0U, r3
+	isync
+
+	/* DBAT 0 */
+	addis	r4, r0, CFG_DBAT0L@h
+	ori	r4, r4, CFG_DBAT0L@l
+	addis	r3, r0, CFG_DBAT0U@h
+	ori	r3, r3, CFG_DBAT0U@l
+	mtspr	DBAT0L, r4
+	mtspr	DBAT0U, r3
+	isync
+
+	/* IBAT 1 */
+	addis	r4, r0, CFG_IBAT1L@h
+	ori	r4, r4, CFG_IBAT1L@l
+	addis	r3, r0, CFG_IBAT1U@h
+	ori	r3, r3, CFG_IBAT1U@l
+	mtspr	IBAT1L, r4
+	mtspr	IBAT1U, r3
+	isync
+
+	/* DBAT 1 */
+	addis	r4, r0, CFG_DBAT1L@h
+	ori	r4, r4, CFG_DBAT1L@l
+	addis	r3, r0, CFG_DBAT1U@h
+	ori	r3, r3, CFG_DBAT1U@l
+	mtspr	DBAT1L, r4
+	mtspr	DBAT1U, r3
+	isync
+
+	/* IBAT 2 */
+	addis	r4, r0, CFG_IBAT2L@h
+	ori	r4, r4, CFG_IBAT2L@l
+	addis	r3, r0, CFG_IBAT2U@h
+	ori	r3, r3, CFG_IBAT2U@l
+	mtspr	IBAT2L, r4
+	mtspr	IBAT2U, r3
+	isync
+
+	/* DBAT 2 */
+	addis	r4, r0, CFG_DBAT2L@h
+	ori	r4, r4, CFG_DBAT2L@l
+	addis	r3, r0, CFG_DBAT2U@h
+	ori	r3, r3, CFG_DBAT2U@l
+	mtspr	DBAT2L, r4
+	mtspr	DBAT2U, r3
+	isync
+
+	/* IBAT 3 */
+	addis	r4, r0, CFG_IBAT3L@h
+	ori	r4, r4, CFG_IBAT3L@l
+	addis	r3, r0, CFG_IBAT3U@h
+	ori	r3, r3, CFG_IBAT3U@l
+	mtspr	IBAT3L, r4
+	mtspr	IBAT3U, r3
+	isync
+
+	/* DBAT 3 */
+	addis	r4, r0, CFG_DBAT3L@h
+	ori	r4, r4, CFG_DBAT3L@l
+	addis	r3, r0, CFG_DBAT3U@h
+	ori	r3, r3, CFG_DBAT3U@l
+	mtspr	DBAT3L, r4
+	mtspr	DBAT3U, r3
+	isync
+
+	/* IBAT 4 */
+	addis	r4, r0, CFG_IBAT4L@h
+	ori	r4, r4, CFG_IBAT4L@l
+	addis	r3, r0, CFG_IBAT4U@h
+	ori	r3, r3, CFG_IBAT4U@l
+	mtspr	IBAT4L, r4
+	mtspr	IBAT4U, r3
+	isync
+
+	/* DBAT 4 */
+	addis	r4, r0, CFG_DBAT4L@h
+	ori	r4, r4, CFG_DBAT4L@l
+	addis	r3, r0, CFG_DBAT4U@h
+	ori	r3, r3, CFG_DBAT4U@l
+	mtspr	DBAT4L, r4
+	mtspr	DBAT4U, r3
+	isync
+
+	/* IBAT 5 */
+	addis	r4, r0, CFG_IBAT5L@h
+	ori	r4, r4, CFG_IBAT5L@l
+	addis	r3, r0, CFG_IBAT5U@h
+	ori	r3, r3, CFG_IBAT5U@l
+	mtspr	IBAT5L, r4
+	mtspr	IBAT5U, r3
+	isync
+
+	/* DBAT 5 */
+	addis	r4, r0, CFG_DBAT5L@h
+	ori	r4, r4, CFG_DBAT5L@l
+	addis	r3, r0, CFG_DBAT5U@h
+	ori	r3, r3, CFG_DBAT5U@l
+	mtspr	DBAT5L, r4
+	mtspr	DBAT5U, r3
+	isync
+
+	/* IBAT 6 */
+	addis	r4, r0, CFG_IBAT6L@h
+	ori	r4, r4, CFG_IBAT6L@l
+	addis	r3, r0, CFG_IBAT6U@h
+	ori	r3, r3, CFG_IBAT6U@l
+	mtspr	IBAT6L, r4
+	mtspr	IBAT6U, r3
+	isync
+
+	/* DBAT 6 */
+	addis	r4, r0, CFG_DBAT6L@h
+	ori	r4, r4, CFG_DBAT6L@l
+	addis	r3, r0, CFG_DBAT6U@h
+	ori	r3, r3, CFG_DBAT6U@l
+	mtspr	DBAT6L, r4
+	mtspr	DBAT6U, r3
+	isync
+
+	/* IBAT 7 */
+	addis	r4, r0, CFG_IBAT7L@h
+	ori	r4, r4, CFG_IBAT7L@l
+	addis	r3, r0, CFG_IBAT7U@h
+	ori	r3, r3, CFG_IBAT7U@l
+	mtspr	IBAT7L, r4
+	mtspr	IBAT7U, r3
+	isync
+
+	/* DBAT 7 */
+	addis	r4, r0, CFG_DBAT7L@h
+	ori	r4, r4, CFG_DBAT7L@l
+	addis	r3, r0, CFG_DBAT7U@h
+	ori	r3, r3, CFG_DBAT7U@l
+	mtspr	DBAT7L, r4
+	mtspr	DBAT7U, r3
+	isync
+
+1:
+	addis	r3, 0, 0x0000
+	addis	r5, 0, 0x4	/* upper bound of 0x00040000 for 7400/750 */
+	isync
+
+tlblp:
+	tlbie	r3
+	sync
+	addi	r3, r3, 0x1000
+	cmp	0, 0, r3, r5
+	blt tlblp
+
+	blr
+
+	.globl enable_addr_trans
+enable_addr_trans:
+	/* enable address translation */
+	mfmsr	r5
+	ori	r5, r5, (MSR_IR | MSR_DR)
+	mtmsr	r5
+	isync
+	blr
+
+	.globl disable_addr_trans
+disable_addr_trans:
+	/* disable address translation */
+	mflr	r4
+	mfmsr	r3
+	andi.	r0, r3, (MSR_IR | MSR_DR)
+	beqlr
+	andc	r3, r3, r0
+	mtspr	SRR0, r4
+	mtspr	SRR1, r3
+	rfi
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+	.globl	transfer_to_handler
+transfer_to_handler:
+	stw	r22,_NIP(r21)
+	lis	r22,MSR_POW@h
+	andc	r23,r23,r22
+	stw	r23,_MSR(r21)
+	SAVE_GPR(7, r21)
+	SAVE_4GPRS(8, r21)
+	SAVE_8GPRS(12, r21)
+	SAVE_8GPRS(24, r21)
+	mflr	r23
+	andi.	r24,r23,0x3f00		/* get vector offset */
+	stw	r24,TRAP(r21)
+	li	r22,0
+	stw	r22,RESULT(r21)
+	mtspr	SPRG2,r22		/* r1 is now kernel sp */
+	lwz	r24,0(r23)		/* virtual address of handler */
+	lwz	r23,4(r23)		/* where to go when done */
+	mtspr	SRR0,r24
+	mtspr	SRR1,r20
+	mtlr	r23
+	SYNC
+	rfi				/* jump to handler, enable MMU */
+
+int_return:
+	mfmsr	r28		/* Disable interrupts */
+	li	r4,0
+	ori	r4,r4,MSR_EE
+	andc	r28,r28,r4
+	SYNC			/* Some chip revs need this... */
+	mtmsr	r28
+	SYNC
+	lwz	r2,_CTR(r1)
+	lwz	r0,_LINK(r1)
+	mtctr	r2
+	mtlr	r0
+	lwz	r2,_XER(r1)
+	lwz	r0,_CCR(r1)
+	mtspr	XER,r2
+	mtcrf	0xFF,r0
+	REST_10GPRS(3, r1)
+	REST_10GPRS(13, r1)
+	REST_8GPRS(23, r1)
+	REST_GPR(31, r1)
+	lwz	r2,_NIP(r1)	/* Restore environment */
+	lwz	r0,_MSR(r1)
+	mtspr	SRR0,r2
+	mtspr	SRR1,r0
+	lwz	r0,GPR0(r1)
+	lwz	r2,GPR2(r1)
+	lwz	r1,GPR1(r1)
+	SYNC
+	rfi
+
+	.globl	dc_read
+dc_read:
+	blr
+
+	.globl get_pvr
+get_pvr:
+	mfspr	r3, PVR
+	blr
+
+	.globl get_svr
+get_svr:
+	mfspr	r3, SVR
+	blr
+
+
+/*
+ * Function:	in8
+ * Description:	Input 8 bits
+ */
+	.globl	in8
+in8:
+	lbz	r3,0x0000(r3)
+	blr
+
+/*
+ * Function:	out8
+ * Description:	Output 8 bits
+ */
+	.globl	out8
+out8:
+	stb	r4,0x0000(r3)
+	blr
+
+/*
+ * Function:	out16
+ * Description:	Output 16 bits
+ */
+	.globl	out16
+out16:
+	sth	r4,0x0000(r3)
+	blr
+
+/*
+ * Function:	out16r
+ * Description:	Byte reverse and output 16 bits
+ */
+	.globl	out16r
+out16r:
+	sthbrx	r4,r0,r3
+	blr
+
+/*
+ * Function:	out32
+ * Description:	Output 32 bits
+ */
+	.globl	out32
+out32:
+	stw	r4,0x0000(r3)
+	blr
+
+/*
+ * Function:	out32r
+ * Description:	Byte reverse and output 32 bits
+ */
+	.globl	out32r
+out32r:
+	stwbrx	r4,r0,r3
+	blr
+
+/*
+ * Function:	in16
+ * Description:	Input 16 bits
+ */
+	.globl	in16
+in16:
+	lhz	r3,0x0000(r3)
+	blr
+
+/*
+ * Function:	in16r
+ * Description:	Input 16 bits and byte reverse
+ */
+	.globl	in16r
+in16r:
+	lhbrx	r3,r0,r3
+	blr
+
+/*
+ * Function:	in32
+ * Description:	Input 32 bits
+ */
+	.globl	in32
+in32:
+	lwz	3,0x0000(3)
+	blr
+
+/*
+ * Function:	in32r
+ * Description:	Input 32 bits and byte reverse
+ */
+	.globl	in32r
+in32r:
+	lwbrx	r3,r0,r3
+	blr
+
+/*
+ * Function:	ppcDcbf
+ * Description:	Data Cache block flush
+ * Input:	r3 = effective address
+ * Output:	none.
+ */
+	.globl	ppcDcbf
+ppcDcbf:
+	dcbf	r0,r3
+	blr
+
+/*
+ * Function:	ppcDcbi
+ * Description:	Data Cache block Invalidate
+ * Input:	r3 = effective address
+ * Output:	none.
+ */
+	.globl	ppcDcbi
+ppcDcbi:
+	dcbi	r0,r3
+	blr
+
+/*
+ * Function:	ppcDcbz
+ * Description:	Data Cache block zero.
+ * Input:	r3 = effective address
+ * Output:	none.
+ */
+	.globl	ppcDcbz
+ppcDcbz:
+	dcbz	r0,r3
+	blr
+
+/*
+ * Function:	ppcSync
+ * Description:	Processor Synchronize
+ * Input:	none.
+ * Output:	none.
+ */
+	.globl	ppcSync
+ppcSync:
+	sync
+	blr
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+	.globl	relocate_code
+relocate_code:
+
+	mr	r1,  r3		/* Set new stack pointer		*/
+	mr	r9,  r4		/* Save copy of Global Data pointer	*/
+	mr	r29, r9		/* Save for DECLARE_GLOBAL_DATA_PTR	*/
+	mr	r10, r5		/* Save copy of Destination Address	*/
+
+	mr	r3,  r5				/* Destination Address	*/
+	lis	r4, CFG_MONITOR_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CFG_MONITOR_BASE@l
+	lwz	r5, GOT(__init_end)
+	sub	r5, r5, r4
+	li	r6, CFG_CACHELINE_SIZE		/* Cache Line Size	*/
+
+	/*
+	 * Fix GOT pointer:
+	 *
+	 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+	 *
+	 * Offset:
+	 */
+	sub	r15, r10, r4
+
+	/* First our own GOT */
+	add	r14, r14, r15
+	/* then the one used by the C code */
+	add	r30, r30, r15
+
+	/*
+	 * Now relocate code
+	 */
+#ifdef CONFIG_ECC
+	bl	board_relocate_rom
+	sync
+	mr	r3, r10				/* Destination Address	*/
+	lis	r4, CFG_MONITOR_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CFG_MONITOR_BASE@l
+	lwz	r5, GOT(__init_end)
+	sub	r5, r5, r4
+	li	r6, CFG_CACHELINE_SIZE		/* Cache Line Size	*/
+#else
+	cmplw	cr1,r3,r4
+	addi	r0,r5,3
+	srwi.	r0,r0,2
+	beq	cr1,4f		/* In place copy is not necessary	*/
+	beq	7f		/* Protect against 0 count		*/
+	mtctr	r0
+	bge	cr1,2f
+
+	la	r8,-4(r4)
+	la	r7,-4(r3)
+1:	lwzu	r0,4(r8)
+	stwu	r0,4(r7)
+	bdnz	1b
+	b	4f
+
+2:	slwi	r0,r0,2
+	add	r8,r4,r0
+	add	r7,r3,r0
+3:	lwzu	r0,-4(r8)
+	stwu	r0,-4(r7)
+	bdnz	3b
+#endif
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4:	cmpwi	r6,0
+	add	r5,r3,r5
+	beq	7f		/* Always flush prefetch queue in any case */
+	subi	r0,r6,1
+	andc	r3,r3,r0
+	mr	r4,r3
+5:	dcbst	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	5b
+	sync			/* Wait for all dcbst to complete on bus */
+	mr	r4,r3
+6:	icbi	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	6b
+7:	sync			/* Wait for all icbi to complete on bus */
+	isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+	mtlr	r0
+	blr
+
+in_ram:
+#ifdef CONFIG_ECC
+	bl	board_init_ecc
+#endif
+	/*
+	 * Relocation Function, r14 point to got2+0x8000
+	 *
+	 * Adjust got2 pointers, no need to check for 0, this code
+	 * already puts a few entries in the table.
+	 */
+	li	r0,__got2_entries@sectoff@l
+	la	r3,GOT(_GOT2_TABLE_)
+	lwz	r11,GOT(_GOT2_TABLE_)
+	mtctr	r0
+	sub	r11,r3,r11
+	addi	r3,r3,-4
+1:	lwzu	r0,4(r3)
+	add	r0,r0,r11
+	stw	r0,0(r3)
+	bdnz	1b
+
+	/*
+	 * Now adjust the fixups and the pointers to the fixups
+	 * in case we need to move ourselves again.
+	 */
+2:	li	r0,__fixup_entries@sectoff@l
+	lwz	r3,GOT(_FIXUP_TABLE_)
+	cmpwi	r0,0
+	mtctr	r0
+	addi	r3,r3,-4
+	beq	4f
+3:	lwzu	r4,4(r3)
+	lwzux	r0,r4,r11
+	add	r0,r0,r11
+	stw	r10,0(r3)
+	stw	r0,0(r4)
+	bdnz	3b
+4:
+/* clear_bss: */
+	/*
+	 * Now clear BSS segment
+	 */
+	lwz	r3,GOT(__bss_start)
+	lwz	r4,GOT(_end)
+
+	cmplw	0, r3, r4
+	beq	6f
+
+	li	r0, 0
+5:
+	stw	r0, 0(r3)
+	addi	r3, r3, 4
+	cmplw	0, r3, r4
+	bne	5b
+6:
+	mr	r3, r9		/* Init Date pointer		*/
+	mr	r4, r10		/* Destination Address		*/
+	bl	board_init_r
+
+	/* not reached - end relocate_code */
+/*-----------------------------------------------------------------------*/
+
+	/*
+	 * Copy exception vector code to low memory
+	 *
+	 * r3: dest_addr
+	 * r7: source address, r8: end address, r9: target address
+	 */
+	.globl	trap_init
+trap_init:
+	lwz	r7, GOT(_start)
+	lwz	r8, GOT(_end_of_vectors)
+
+	li	r9, 0x100		/* reset vector always at 0x100 */
+
+	cmplw	0, r7, r8
+	bgelr				/* return if r7>=r8 - just in case */
+
+	mflr	r4			/* save link register		*/
+1:
+	lwz	r0, 0(r7)
+	stw	r0, 0(r9)
+	addi	r7, r7, 4
+	addi	r9, r9, 4
+	cmplw	0, r7, r8
+	bne	1b
+
+	/*
+	 * relocate `hdlr' and `int_return' entries
+	 */
+	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+	li	r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	2b
+
+	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+	bl	trap_reloc
+
+	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+	bl	trap_reloc
+
+	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET
+3:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	3b
+
+	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
+	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+4:
+	bl	trap_reloc
+	addi	r7, r7, 0x100		/* next exception vector	*/
+	cmplw	0, r7, r8
+	blt	4b
+
+	/* enable execptions from RAM vectors */
+	mfmsr	r7
+	li	r8,MSR_IP
+	andc	r7,r7,r8
+	mtmsr	r7
+
+	mtlr	r4			/* restore link register	*/
+	blr
+
+	/*
+	 * Function: relocate entries for one exception vector
+	 */
+trap_reloc:
+	lwz	r0, 0(r7)		/* hdlr ...			*/
+	add	r0, r0, r3		/*  ... += dest_addr		*/
+	stw	r0, 0(r7)
+
+	lwz	r0, 4(r7)		/* int_return ...		*/
+	add	r0, r0, r3		/*  ... += dest_addr		*/
+	stw	r0, 4(r7)
+
+	sync
+	isync
+
+	blr
+
+.globl enable_ext_addr
+enable_ext_addr:
+	mfspr	r0, HID0
+	lis	r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
+	ori	r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
+	mtspr	HID0, r0
+	sync
+	isync
+	blr
+
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+.globl setup_ccsrbar
+setup_ccsrbar:
+	/* Special sequence needed to update CCSRBAR itself */
+	lis	r4, CFG_CCSRBAR_DEFAULT@h
+	ori	r4, r4, CFG_CCSRBAR_DEFAULT@l
+
+	lis	r5, CFG_CCSRBAR@h
+	ori	r5, r5, CFG_CCSRBAR@l
+	srwi	r6,r5,12
+	stw	r6, 0(r4)
+	isync
+
+	lis	r5, 0xffff
+	ori	r5,r5,0xf000
+	lwz	r5, 0(r5)
+	isync
+
+	lis	r3, CFG_CCSRBAR@h
+	lwz	r5, CFG_CCSRBAR@l(r3)
+	isync
+
+	blr
+#endif
+
+#ifdef CFG_INIT_RAM_LOCK
+lock_ram_in_cache:
+	/* Allocate Initial RAM in data cache.
+	 */
+	lis	r3, (CFG_INIT_RAM_ADDR & ~31)@h
+	ori	r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
+	li	r2, ((CFG_INIT_RAM_END & ~31) + \
+		     (CFG_INIT_RAM_ADDR & 31) + 31) / 32
+	mtctr	r2
+1:
+	dcbz	r0, r3
+	addi	r3, r3, 32
+	bdnz	1b
+#if 1
+/* Lock the data cache */
+	mfspr	r0, HID0
+	ori	r0, r0, 0x1000
+	sync
+	mtspr	HID0, r0
+	sync
+	blr
+#endif
+#if 0
+	/* Lock the first way of the data cache */
+	mfspr	r0, LDSTCR
+	ori	r0, r0, 0x0080
+#if defined(CONFIG_ALTIVEC)
+	dssall
+#endif
+	sync
+	mtspr	LDSTCR, r0
+	sync
+	isync
+	blr
+#endif
+
+.globl unlock_ram_in_cache
+unlock_ram_in_cache:
+	/* invalidate the INIT_RAM section */
+	lis	r3, (CFG_INIT_RAM_ADDR & ~31)@h
+	ori	r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
+	li	r2, ((CFG_INIT_RAM_END & ~31) + \
+		     (CFG_INIT_RAM_ADDR & 31) + 31) / 32
+	mtctr	r2
+1:	icbi	r0, r3
+	addi	r3, r3, 32
+	bdnz	1b
+	sync			/* Wait for all icbi to complete on bus */
+	isync
+#if 1
+/* Unlock the data cache and invalidate it */
+	mfspr	r0, HID0
+	li	r3,0x1000
+	andc	r0,r0,r3
+	li	r3,0x0400
+	or	r0,r0,r3
+	sync
+	mtspr	HID0, r0
+	sync
+	blr
+#endif
+#if 0
+	/* Unlock the first way of the data cache */
+	mfspr	r0, LDSTCR
+	li	r3,0x0080
+	andc	r0,r0,r3
+#ifdef CONFIG_ALTIVEC
+	dssall
+#endif
+	sync
+	mtspr	LDSTCR, r0
+	sync
+	isync
+	li	r3,0x0400
+	or	r0,r0,r3
+	sync
+	mtspr	HID0, r0
+	sync
+	blr
+#endif
+#endif
+
+/* If this is a multi-cpu system then we need to handle the
+ * 2nd cpu.  The assumption is that the 2nd cpu is being
+ * held in boot holdoff mode until the 1st cpu unlocks it
+ * from Linux.	We'll do some basic cpu init and then pass
+ * it to the Linux Reset Vector.
+ * Sri:	 Much of this initialization is not required. Linux
+ * rewrites the bats, and the sprs and also enables the L1 cache.
+ */
+#if (CONFIG_NUM_CPUS > 1)
+.globl secondary_cpu_setup
+secondary_cpu_setup:
+	/* Do only core setup on all cores except cpu0 */
+	bl	invalidate_bats
+	sync
+	bl	enable_ext_addr
+
+#ifdef CFG_L2
+	/* init the L2 cache */
+	addis	r3, r0, L2_INIT@h
+	ori	r3, r3, L2_INIT@l
+	sync
+	mtspr	l2cr, r3
+#ifdef CONFIG_ALTIVEC
+	dssall
+#endif
+	/* invalidate the L2 cache */
+	bl	l2cache_invalidate
+	sync
+#endif
+
+	/* enable and invalidate the data cache */
+	bl	dcache_enable
+	sync
+
+	/* enable and invalidate the instruction cache*/
+	bl	icache_enable
+	sync
+
+	/* TBEN in HID0 */
+	mfspr	r4, HID0
+	oris	r4, r4, 0x0400
+	mtspr	HID0, r4
+	sync
+	isync
+
+	/*SYNCBE|ABE in HID1*/
+	mfspr	r4, HID1
+	ori	r4, r4, 0x0C00
+	mtspr	HID1, r4
+	sync
+	isync
+
+	lis	r3, CONFIG_LINUX_RESET_VEC@h
+	ori	r3, r3, CONFIG_LINUX_RESET_VEC@l
+	mtlr	r3
+	blr
+
+	/* Never Returns, Running in Linux Now */
+#endif
diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c
new file mode 100644
index 0000000..8ea14e5
--- /dev/null
+++ b/cpu/mpc86xx/traps.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
+
+/*
+ * Trap & Exception support
+ */
+
+void
+print_backtrace(unsigned long *sp)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int cnt = 0;
+	unsigned long i;
+
+	printf("Call backtrace: ");
+	while (sp) {
+		if ((uint) sp > END_OF_MEM)
+			break;
+
+		i = sp[1];
+		if (cnt++ % 7 == 0)
+			printf("\n");
+		printf("%08lX ", i);
+		if (cnt > 32)
+			break;
+		sp = (unsigned long *)*sp;
+	}
+	printf("\n");
+}
+
+void
+show_regs(struct pt_regs *regs)
+{
+	int i;
+
+	printf("NIP: %08lX XER: %08lX LR: %08lX REGS:"
+	       " %p TRAP: %04lx DAR: %08lX\n",
+	       regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
+	printf("MSR: %08lx EE: %01x PR: %01x FP:"
+	       " %01x ME: %01x IR/DR: %01x%01x\n",
+	       regs->msr, regs->msr & MSR_EE ? 1 : 0,
+	       regs->msr & MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,
+	       regs->msr & MSR_ME ? 1 : 0, regs->msr & MSR_IR ? 1 : 0,
+	       regs->msr & MSR_DR ? 1 : 0);
+
+	printf("\n");
+	for (i = 0; i < 32; i++) {
+		if ((i % 8) == 0) {
+			printf("GPR%02d: ", i);
+		}
+
+		printf("%08lX ", regs->gpr[i]);
+		if ((i % 8) == 7) {
+			printf("\n");
+		}
+	}
+}
+
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Exception in kernel pc %lx signal %d", regs->nip, signr);
+}
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+	unsigned long fixup;
+
+	/* Probing PCI using config cycles cause this exception
+	 * when a device is not present.  Catch it and return to
+	 * the PCI exception handler.
+	 */
+	if ((fixup = search_exception_table(regs->nip)) != 0) {
+		regs->nip = fixup;
+		return;
+	}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+
+	printf("Machine check in kernel mode.\n");
+	printf("Caused by (from msr): ");
+	printf("regs %p ", regs);
+	switch (regs->msr & 0x000F0000) {
+	case (0x80000000 >> 12):
+		printf("Machine check signal - probably due to mm fault\n"
+		       "with mmu off\n");
+		break;
+	case (0x80000000 >> 13):
+		printf("Transfer error ack signal\n");
+		break;
+	case (0x80000000 >> 14):
+		printf("Data parity signal\n");
+		break;
+	case (0x80000000 >> 15):
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+	unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL;
+	int i, j;
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	show_regs(regs);
+
+	p = (unsigned char *)((unsigned long)p & 0xFFFFFFE0);
+	p -= 32;
+	for (i = 0; i < 256; i += 16) {
+		printf("%08x: ", (unsigned int)p + i);
+		for (j = 0; j < 16; j++) {
+			printf("%02x ", p[i + j]);
+		}
+		printf("\n");
+	}
+
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Software Emulation Exception");
+}
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+		return;
+#endif
+	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(0, regs);
+}
+
+/*
+ * Probe an address by reading.
+ * If not present, return -1,
+ * otherwise return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+	return 0;
+}
diff --git a/cpu/mpc8xx/Makefile b/cpu/mpc8xx/Makefile
index de75fad..223b30c 100644
--- a/cpu/mpc8xx/Makefile
+++ b/cpu/mpc8xx/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -25,25 +25,29 @@
 
 # CFLAGS += -DET_DEBUG
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o kgdb.o
-OBJS	= bedbug_860.o commproc.o cpu.o cpu_init.o	\
+COBJS	= bedbug_860.o commproc.o cpu.o cpu_init.o	\
 	  fec.o i2c.o interrupts.o lcd.o scc.o		\
 	  serial.o speed.o spi.o \
 	  traps.o upatch.o video.o
 SOBJS	= plprcr_write.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
 
-$(LIB):	$(OBJS) $(SOBJS)
-	$(AR) crv $@ $(OBJS) $(SOBJS) kgdb.o
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(obj)kgdb.o
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c) $(SOBJS:.o=.S)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(SOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/nios/Makefile b/cpu/nios/Makefile
index 7855325..ad17456 100644
--- a/cpu/nios/Makefile
+++ b/cpu/nios/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,22 +23,26 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-AOBJS	= traps.o
-OBJS	= cpu.o interrupts.o serial.o asmi.o spi.o
+SOBJS	= traps.o
+COBJS	= cpu.o interrupts.o serial.o asmi.o spi.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
 
-$(LIB):	$(OBJS) $(AOBJS)
-	$(AR) crv $@ $(OBJS) $(AOBJS)
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
-	$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/nios2/Makefile b/cpu/nios2/Makefile
index 11fda50..75f30b4 100644
--- a/cpu/nios2/Makefile
+++ b/cpu/nios2/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,22 +23,26 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-AOBJS	= exceptions.o
-OBJS	= cpu.o interrupts.o serial.o sysid.o traps.o epcs.o
+SOBJS	= exceptions.o
+COBJS	= cpu.o interrupts.o serial.o sysid.o traps.o epcs.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
 
-$(LIB):	$(OBJS) $(AOBJS)
-	$(AR) crv $@ $(OBJS) $(AOBJS)
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
-	$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
index cf5eccb..03128d3 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -315,7 +315,6 @@
 #ifdef CONFIG_PCI_SCAN_SHOW
 		printf("PCI:   Bus Dev VenId DevId Class Int\n");
 #endif
-
 		hose->last_busno = pci_hose_scan(hose);
 	}
 #endif  /* CONFIG_PCI_PNP */
@@ -556,17 +555,20 @@
 #ifdef CONFIG_PCI_SCAN_SHOW
 		printf("PCI:   Bus Dev VenId DevId Class Int\n");
 #endif
-#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 		out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
 #endif
 		hose->last_busno = pci_hose_scan(hose);
 	}
 }
 
-
 void pci_init_board(void)
 {
 	pci_440_init (&ppc440_hose);
+#if defined(CONFIG_440SPE)
+	pcie_setup_hoses();
+#endif
 }
 
 #endif /* CONFIG_440 & CONFIG_PCI */
diff --git a/cpu/ppc4xx/440spe_pcie.c b/cpu/ppc4xx/440spe_pcie.c
new file mode 100644
index 0000000..6130cd2
--- /dev/null
+++ b/cpu/ppc4xx/440spe_pcie.c
@@ -0,0 +1,962 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.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.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm-ppc/io.h>
+#include <ppc4xx.h>
+#include <common.h>
+#include <pci.h>
+
+#include "440spe_pcie.h"
+
+#if defined(CONFIG_440SPE)
+#if defined(CONFIG_PCI)
+
+enum {
+	PTYPE_ENDPOINT		= 0x0,
+	PTYPE_LEGACY_ENDPOINT	= 0x1,
+	PTYPE_ROOT_PORT		= 0x4,
+
+	LNKW_X1			= 0x1,
+	LNKW_X4			= 0x4,
+	LNKW_X8			= 0x8
+};
+
+static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
+	int offset, int len, u32 *val) {
+
+	*val = 0;
+	/*
+	 * 440SPE implements only one function per port
+	 */
+	if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+		return 0;
+
+	devfn = PCI_BDF(0,0,0);
+	offset += devfn << 4;
+
+	switch (len) {
+	case 1:
+		*val = in_8(hose->cfg_data + offset);
+		break;
+	case 2:
+		*val = in_le16((u16 *)(hose->cfg_data + offset));
+		break;
+	default:
+		*val = in_le32((u32 *)(hose->cfg_data + offset));
+		break;
+	}
+	return 0;
+}
+
+static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
+	int offset, int len, u32 val) {
+
+	/*
+	 * 440SPE implements only one function per port
+	 */
+	if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+		return 0;
+
+	devfn = PCI_BDF(0,0,0);
+	offset += devfn << 4;
+
+	switch (len) {
+	case 1:
+		out_8(hose->cfg_data + offset, val);
+		break;
+	case 2:
+		out_le16((u16 *)(hose->cfg_data + offset), val);
+		break;
+	default:
+		out_le32((u32 *)(hose->cfg_data + offset), val);
+		break;
+	}
+	return 0;
+}
+
+int pcie_read_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 *val)
+{
+	u32 v;
+	int rv;
+
+	rv =  pcie_read_config(hose, dev, offset, 1, &v);
+	*val = (u8)v;
+	return rv;
+}
+
+int pcie_read_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 *val)
+{
+	u32 v;
+	int rv;
+
+	rv = pcie_read_config(hose, dev, offset, 2, &v);
+	*val = (u16)v;
+	return rv;
+}
+
+int pcie_read_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 *val)
+{
+	u32 v;
+	int rv;
+
+	rv = pcie_read_config(hose, dev, offset, 3, &v);
+	*val = (u32)v;
+	return rv;
+}
+
+int pcie_write_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 val)
+{
+	return pcie_write_config(hose,(u32)dev,offset,1,val);
+}
+
+int pcie_write_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 val)
+{
+	return pcie_write_config(hose,(u32)dev,offset,2,(u32 )val);
+}
+
+int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 val)
+{
+	return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
+}
+
+static void ppc440spe_setup_utl(u32 port) {
+
+	volatile void *utl_base = NULL;
+
+	/*
+	 * Map UTL registers
+	 */
+	switch (port) {
+	case 0:
+		mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
+		mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x20000000);
+		mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
+		mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
+		break;
+
+	case 1:
+		mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
+		mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x20001000);
+		mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
+		mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
+		break;
+
+	case 2:
+		mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
+		mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x20002000);
+		mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
+		mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
+		break;
+	}
+	utl_base = (unsigned int *)(CFG_PCIE_BASE + 0x1000 * port);
+
+	/*
+	 * Set buffer allocations and then assert VRB and TXE.
+	 */
+	out_be32(utl_base + PEUTL_OUTTR,   0x08000000);
+	out_be32(utl_base + PEUTL_INTR,    0x02000000);
+	out_be32(utl_base + PEUTL_OPDBSZ,  0x10000000);
+	out_be32(utl_base + PEUTL_PBBSZ,   0x53000000);
+	out_be32(utl_base + PEUTL_IPHBSZ,  0x08000000);
+	out_be32(utl_base + PEUTL_IPDBSZ,  0x10000000);
+	out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
+	out_be32(utl_base + PEUTL_PCTL,    0x80800066);
+}
+
+static int check_error(void)
+{
+	u32 valPE0, valPE1, valPE2;
+	int err = 0;
+
+	/* SDR0_PEGPLLLCT1 reset */
+	if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
+		printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0);
+	}
+
+	valPE0 = SDR_READ(PESDR0_RCSSET);
+	valPE1 = SDR_READ(PESDR1_RCSSET);
+	valPE2 = SDR_READ(PESDR2_RCSSET);
+
+	/* SDR0_PExRCSSET rstgu */
+	if (!(valPE0 & 0x01000000) ||
+	    !(valPE1 & 0x01000000) ||
+	    !(valPE2 & 0x01000000)) {
+		printf("PCIE:  SDR0_PExRCSSET rstgu error\n");
+		err = -1;
+	}
+
+	/* SDR0_PExRCSSET rstdl */
+	if (!(valPE0 & 0x00010000) ||
+	    !(valPE1 & 0x00010000) ||
+	    !(valPE2 & 0x00010000)) {
+		printf("PCIE:  SDR0_PExRCSSET rstdl error\n");
+		err = -1;
+	}
+
+	/* SDR0_PExRCSSET rstpyn */
+	if ((valPE0 & 0x00001000) ||
+	    (valPE1 & 0x00001000) ||
+	    (valPE2 & 0x00001000)) {
+		printf("PCIE:  SDR0_PExRCSSET rstpyn error\n");
+		err = -1;
+	}
+
+	/* SDR0_PExRCSSET hldplb */
+	if ((valPE0 & 0x10000000) ||
+	    (valPE1 & 0x10000000) ||
+	    (valPE2 & 0x10000000)) {
+		printf("PCIE:  SDR0_PExRCSSET hldplb error\n");
+		err = -1;
+	}
+
+	/* SDR0_PExRCSSET rdy */
+	if ((valPE0 & 0x00100000) ||
+	    (valPE1 & 0x00100000) ||
+	    (valPE2 & 0x00100000)) {
+		printf("PCIE:  SDR0_PExRCSSET rdy error\n");
+		err = -1;
+	}
+
+	/* SDR0_PExRCSSET shutdown */
+	if ((valPE0 & 0x00000100) ||
+	    (valPE1 & 0x00000100) ||
+	    (valPE2 & 0x00000100)) {
+		printf("PCIE:  SDR0_PExRCSSET shutdown error\n");
+		err = -1;
+	}
+	return err;
+}
+
+/*
+ * Initialize PCI Express core
+ */
+int ppc440spe_init_pcie(void)
+{
+	int time_out = 20;
+
+	/* Set PLL clock receiver to LVPECL */
+	SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
+
+	if (check_error())
+		return -1;
+
+	if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
+	{
+		printf("PCIE: PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+		       SDR_READ(PESDR0_PLLLCT2));
+		return -1;
+	}
+	/* De-assert reset of PCIe PLL, wait for lock */
+	SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
+	udelay(3);
+
+	while (time_out) {
+		if (!(SDR_READ(PESDR0_PLLLCT3) & 0x10000000)) {
+			time_out--;
+			udelay(1);
+		} else
+			break;
+	}
+	if (!time_out) {
+		printf("PCIE: VCO output not locked\n");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ *  Yucca board as End point and root point setup
+ *                    and
+ *    testing inbound and out bound windows
+ *
+ *  YUCCA board can be plugged into another yucca board or you can get PCI-E
+ *  cable which can be used to setup loop back from one port to another port.
+ *  Please rememeber that unless there is a endpoint plugged in to root port it
+ *  will not initialize. It is the same in case of endpoint , unless there is
+ *  root port attached it will not initialize.
+ *
+ *  In this release of software all the PCI-E ports are configured as either
+ *  endpoint or rootpoint.In future we will have support for selective ports
+ *  setup as endpoint and root point in single board.
+ *
+ *  Once your board came up as root point , you can verify by reading
+ *  /proc/bus/pci/devices. Where you can see the configuration registers
+ *  of end point device attached to the port.
+ *
+ *  Enpoint cofiguration can be verified by connecting Yucca board to any
+ *  host or another yucca board. Then try to scan the device. In case of
+ *  linux use "lspci" or appripriate os command.
+ *
+ *  How do I verify the inbound and out bound windows ?(yucca to yucca)
+ *  in this configuration inbound and outbound windows are setup to access
+ *  sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
+ *  is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
+ *  This is waere your POM(PLB out bound memory window) mapped. then
+ *  read the data from other yucca board's u-boot prompt at address
+ *  0x9000 0000(SRAM). Data should match.
+ *  In case of inbound , write data to u-boot command prompt at 0xb000 0000
+ *  which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
+ *  data at 0x9000 0000(SRAM).Data should match.
+ */
+int ppc440spe_init_pcie_rootport(int port)
+{
+	static int core_init;
+	volatile u32 val = 0;
+	int attempts;
+
+	if (!core_init) {
+		++core_init;
+		if (ppc440spe_init_pcie())
+			return -1;
+	}
+
+	/*
+	 * Initialize various parts of the PCI Express core for our port:
+	 *
+	 * - Set as a root port and enable max width
+	 *   (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+	 * - Set up UTL configuration.
+	 * - Increase SERDES drive strength to levels suggested by AMCC.
+	 * - De-assert RSTPYN, RSTDL and RSTGU.
+	 *
+	 * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
+	 * default setting 0x11310000. The register has new fields,
+	 * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+	 * hang.
+	 */
+	switch (port) {
+	case 0:
+		SDR_WRITE(PESDR0_DLPSET,  1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
+
+		SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
+		if (!ppc440spe_revB())
+			SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+		SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+		SDR_WRITE(PESDR0_RCSSET,
+			  (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+
+	case 1:
+		SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+		SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
+		if (!ppc440spe_revB())
+			SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+		SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+		SDR_WRITE(PESDR1_RCSSET,
+			  (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+
+	case 2:
+		SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+		SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
+		if (!ppc440spe_revB())
+			SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+		SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+		SDR_WRITE(PESDR2_RCSSET,
+			  (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+	}
+	/*
+	 * Notice: the following delay has critical impact on device
+	 * initialization - if too short (<50ms) the link doesn't get up.
+	 */
+	mdelay(100);
+
+	switch (port) {
+	case 0:
+		val = SDR_READ(PESDR0_RCSSTS);
+		break;
+	case 1:
+		val = SDR_READ(PESDR1_RCSSTS);
+		break;
+	case 2:
+		val = SDR_READ(PESDR2_RCSSTS);
+		break;
+	}
+
+	if (val & (1 << 20)) {
+		printf("PCIE%d: PGRST failed %08x\n", port, val);
+		return -1;
+	}
+
+	/*
+	 * Verify link is up
+	 */
+	val = 0;
+	switch (port) {
+	case 0:
+		val = SDR_READ(PESDR0_LOOP);
+		break;
+	case 1:
+		val = SDR_READ(PESDR1_LOOP);
+		break;
+	case 2:
+		val = SDR_READ(PESDR2_LOOP);
+		break;
+	}
+	if (!(val & 0x00001000)) {
+		printf("PCIE%d: link is not up.\n", port);
+		return -1;
+	}
+
+	/*
+	 * Setup UTL registers - but only on revA!
+	 * We use default settings for revB chip.
+	 */
+	if (!ppc440spe_revB())
+		ppc440spe_setup_utl(port);
+
+	/*
+	 * We map PCI Express configuration access into the 512MB regions
+	 *
+	 * NOTICE: revB is very strict about PLB real addressess and ranges to
+	 * be mapped for config space; it seems to only work with d_nnnn_nnnn
+	 * range (hangs the core upon config transaction attempts when set
+	 * otherwise) while revA uses c_nnnn_nnnn.
+	 *
+	 * For revA:
+	 *     PCIE0: 0xc_4000_0000
+	 *     PCIE1: 0xc_8000_0000
+	 *     PCIE2: 0xc_c000_0000
+	 *
+	 * For revB:
+	 *     PCIE0: 0xd_0000_0000
+	 *     PCIE1: 0xd_2000_0000
+	 *     PCIE2: 0xd_4000_0000
+	 */
+
+	switch (port) {
+	case 0:
+		if (ppc440spe_revB()) {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
+		} else {
+			/* revA */
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+		}
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+		break;
+
+	case 1:
+		if (ppc440spe_revB()) {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
+		} else {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+		}
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+		break;
+
+	case 2:
+		if (ppc440spe_revB()) {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
+		} else {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+		}
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+		break;
+	}
+
+	/*
+	 * Check for VC0 active and assert RDY.
+	 */
+	attempts = 10;
+	switch (port) {
+	case 0:
+		while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+			if (!(attempts--)) {
+				printf("PCIE0: VC0 not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+		SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+		break;
+	case 1:
+		while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+			if (!(attempts--)) {
+				printf("PCIE1: VC0 not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+
+		SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+		break;
+	case 2:
+		while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+			if (!(attempts--)) {
+				printf("PCIE2: VC0 not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+
+		SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+		break;
+	}
+	mdelay(100);
+
+	return 0;
+}
+
+int ppc440spe_init_pcie_endport(int port)
+{
+	static int core_init;
+	volatile u32 val = 0;
+	int attempts;
+
+	if (!core_init) {
+		++core_init;
+		if (ppc440spe_init_pcie())
+			return -1;
+	}
+
+	/*
+	 * Initialize various parts of the PCI Express core for our port:
+	 *
+	 * - Set as a end port and enable max width
+	 *   (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+	 * - Set up UTL configuration.
+	 * - Increase SERDES drive strength to levels suggested by AMCC.
+	 * - De-assert RSTPYN, RSTDL and RSTGU.
+	 *
+	 * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
+	 * default setting 0x11310000. The register has new fields,
+	 * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+	 * hang.
+	 */
+	switch (port) {
+	case 0:
+		SDR_WRITE(PESDR0_DLPSET,  1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X8 << 12);
+
+		SDR_WRITE(PESDR0_UTLSET1, 0x20222222);
+		if (!ppc440spe_revB())
+			SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+		SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+		SDR_WRITE(PESDR0_RCSSET,
+			(SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+
+	case 1:
+		SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
+		SDR_WRITE(PESDR1_UTLSET1, 0x20222222);
+		if (!ppc440spe_revB())
+			SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+		SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+		SDR_WRITE(PESDR1_RCSSET,
+			(SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+
+	case 2:
+		SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
+		SDR_WRITE(PESDR2_UTLSET1, 0x20222222);
+		if (!ppc440spe_revB())
+			SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+		SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+		SDR_WRITE(PESDR2_RCSSET,
+			(SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+	}
+	/*
+	 * Notice: the following delay has critical impact on device
+	 * initialization - if too short (<50ms) the link doesn't get up.
+	 */
+	mdelay(100);
+
+	switch (port) {
+	case 0: val = SDR_READ(PESDR0_RCSSTS); break;
+	case 1: val = SDR_READ(PESDR1_RCSSTS); break;
+	case 2: val = SDR_READ(PESDR2_RCSSTS); break;
+	}
+
+	if (val & (1 << 20)) {
+		printf("PCIE%d: PGRST failed %08x\n", port, val);
+		return -1;
+	}
+
+	/*
+	 * Verify link is up
+	 */
+	val = 0;
+	switch (port)
+	{
+		case 0:
+			val = SDR_READ(PESDR0_LOOP);
+			break;
+		case 1:
+			val = SDR_READ(PESDR1_LOOP);
+			break;
+		case 2:
+			val = SDR_READ(PESDR2_LOOP);
+			break;
+	}
+	if (!(val & 0x00001000)) {
+		printf("PCIE%d: link is not up.\n", port);
+		return -1;
+	}
+
+	/*
+	 * Setup UTL registers - but only on revA!
+	 * We use default settings for revB chip.
+	 */
+	if (!ppc440spe_revB())
+		ppc440spe_setup_utl(port);
+
+	/*
+	 * We map PCI Express configuration access into the 512MB regions
+	 *
+	 * NOTICE: revB is very strict about PLB real addressess and ranges to
+	 * be mapped for config space; it seems to only work with d_nnnn_nnnn
+	 * range (hangs the core upon config transaction attempts when set
+	 * otherwise) while revA uses c_nnnn_nnnn.
+	 *
+	 * For revA:
+	 *     PCIE0: 0xc_4000_0000
+	 *     PCIE1: 0xc_8000_0000
+	 *     PCIE2: 0xc_c000_0000
+	 *
+	 * For revB:
+	 *     PCIE0: 0xd_0000_0000
+	 *     PCIE1: 0xd_2000_0000
+	 *     PCIE2: 0xd_4000_0000
+	 */
+	switch (port) {
+	case 0:
+		if (ppc440spe_revB()) {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
+		} else {
+			/* revA */
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+		}
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+		break;
+
+	case 1:
+		if (ppc440spe_revB()) {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
+		} else {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+		}
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+		break;
+
+	case 2:
+		if (ppc440spe_revB()) {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
+		} else {
+			mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+			mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+		}
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+		break;
+	}
+
+	/*
+	 * Check for VC0 active and assert RDY.
+	 */
+	attempts = 10;
+	switch (port) {
+	case 0:
+		while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+			if (!(attempts--)) {
+				printf("PCIE0: VC0 not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+		SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+		break;
+	case 1:
+		while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+			if (!(attempts--)) {
+				printf("PCIE1: VC0 not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+
+		SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+		break;
+	case 2:
+		while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+			if (!(attempts--)) {
+				printf("PCIE2: VC0 not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+
+		SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+		break;
+	}
+	mdelay(100);
+
+	return 0;
+}
+
+void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
+{
+	volatile void *mbase = NULL;
+	volatile void *rmbase = NULL;
+
+	pci_set_ops(hose,
+		    pcie_read_config_byte,
+		    pcie_read_config_word,
+		    pcie_read_config_dword,
+		    pcie_write_config_byte,
+		    pcie_write_config_word,
+		    pcie_write_config_dword);
+
+	switch (port) {
+	case 0:
+		mbase = (u32 *)CFG_PCIE0_XCFGBASE;
+		rmbase = (u32 *)CFG_PCIE0_CFGBASE;
+		hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
+		break;
+	case 1:
+		mbase = (u32 *)CFG_PCIE1_XCFGBASE;
+		rmbase = (u32 *)CFG_PCIE1_CFGBASE;
+		hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
+		break;
+	case 2:
+		mbase = (u32 *)CFG_PCIE2_XCFGBASE;
+		rmbase = (u32 *)CFG_PCIE2_CFGBASE;
+		hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
+		break;
+	}
+
+	/*
+	 * Set bus numbers on our root port
+	 */
+	out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
+	out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
+	out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
+
+	/*
+	 * Set up outbound translation to hose->mem_space from PLB
+	 * addresses at an offset of 0xd_0000_0000.  We set the low
+	 * bits of the mask to 11 to turn off splitting into 8
+	 * subregions and to enable the outbound translation.
+	 */
+	out_le32(mbase + PECFG_POM0LAH, 0x00000000);
+	out_le32(mbase + PECFG_POM0LAL, 0x00000000);
+
+	switch (port) {
+	case 0:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0),  CFG_PCIE_MEMBASE +
+			port * CFG_PCIE_MEMSIZE);
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+			~(CFG_PCIE_MEMSIZE - 1) | 3);
+		break;
+	case 1:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1),  (CFG_PCIE_MEMBASE +
+			port * CFG_PCIE_MEMSIZE));
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+			~(CFG_PCIE_MEMSIZE - 1) | 3);
+		break;
+	case 2:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2),  (CFG_PCIE_MEMBASE +
+			port * CFG_PCIE_MEMSIZE));
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+			~(CFG_PCIE_MEMSIZE - 1) | 3);
+		break;
+	}
+
+	/* Set up 16GB inbound memory window at 0 */
+	out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+	out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+	out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+	out_le32(mbase + PECFG_BAR0LMPA, 0);
+
+	out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
+	out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
+	out_le32(mbase + PECFG_PIM0LAL, 0);
+	out_le32(mbase + PECFG_PIM0LAH, 0);
+	out_le32(mbase + PECFG_PIM1LAL,  0x00000000);
+	out_le32(mbase + PECFG_PIM1LAH,  0x00000004);
+	out_le32(mbase + PECFG_PIMEN, 0x1);
+
+	/* Enable I/O, Mem, and Busmaster cycles */
+	out_le16((u16 *)(mbase + PCI_COMMAND),
+		 in_le16((u16 *)(mbase + PCI_COMMAND)) |
+		 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	printf("PCIE:%d successfully set as rootpoint\n",port);
+}
+
+int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
+{
+	volatile void *mbase = NULL;
+	int attempts = 0;
+
+	pci_set_ops(hose,
+		    pcie_read_config_byte,
+		    pcie_read_config_word,
+		    pcie_read_config_dword,
+		    pcie_write_config_byte,
+		    pcie_write_config_word,
+		    pcie_write_config_dword);
+
+	switch (port) {
+	case 0:
+		mbase = (u32 *)CFG_PCIE0_XCFGBASE;
+		hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
+		break;
+	case 1:
+		mbase = (u32 *)CFG_PCIE1_XCFGBASE;
+		hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
+		break;
+	case 2:
+		mbase = (u32 *)CFG_PCIE2_XCFGBASE;
+		hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
+		break;
+	}
+
+	/*
+	 * Set up outbound translation to hose->mem_space from PLB
+	 * addresses at an offset of 0xd_0000_0000.  We set the low
+	 * bits of the mask to 11 to turn off splitting into 8
+	 * subregions and to enable the outbound translation.
+	 */
+	out_le32(mbase + PECFG_POM0LAH, 0x00001ff8);
+	out_le32(mbase + PECFG_POM0LAL, 0x00001000);
+
+	switch (port) {
+	case 0:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0),  CFG_PCIE_MEMBASE +
+			port * CFG_PCIE_MEMSIZE);
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+			~(CFG_PCIE_MEMSIZE - 1) | 3);
+		break;
+	case 1:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1),  (CFG_PCIE_MEMBASE +
+			port * CFG_PCIE_MEMSIZE));
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+			~(CFG_PCIE_MEMSIZE - 1) | 3);
+		break;
+	case 2:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2),  (CFG_PCIE_MEMBASE +
+			port * CFG_PCIE_MEMSIZE));
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+			~(CFG_PCIE_MEMSIZE - 1) | 3);
+		break;
+	}
+
+	/* Set up 16GB inbound memory window at 0 */
+	out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+	out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+	out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+	out_le32(mbase + PECFG_BAR0LMPA, 0);
+	out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
+	out_le32(mbase + PECFG_PIM0LAH, 0x00000004);	/* pointing to SRAM */
+	out_le32(mbase + PECFG_PIMEN, 0x1);
+
+	/* Enable I/O, Mem, and Busmaster cycles */
+	out_le16((u16 *)(mbase + PCI_COMMAND),
+		 in_le16((u16 *)(mbase + PCI_COMMAND)) |
+		 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	out_le16(mbase + 0x200,0xcaad);			/* Setting vendor ID */
+	out_le16(mbase + 0x202,0xfeed);			/* Setting device ID */
+	attempts = 10;
+	switch (port) {
+	case 0:
+		while (!(SDR_READ(PESDR0_RCSSTS) & (1 << 8))) {
+			if (!(attempts--)) {
+				printf("PCIE0: BMEN is  not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+		break;
+	case 1:
+		while (!(SDR_READ(PESDR1_RCSSTS) & (1 << 8))) {
+			if (!(attempts--)) {
+				printf("PCIE1: BMEN is not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+		break;
+	case 2:
+		while (!(SDR_READ(PESDR2_RCSSTS) & (1 << 8))) {
+			if (!(attempts--)) {
+				printf("PCIE2: BMEN is  not active\n");
+				return -1;
+			}
+			mdelay(1000);
+		}
+		break;
+	}
+	printf("PCIE:%d successfully set as endpoint\n",port);
+
+	return 0;
+}
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_440SPE */
diff --git a/cpu/ppc4xx/440spe_pcie.h b/cpu/ppc4xx/440spe_pcie.h
new file mode 100644
index 0000000..2becc77
--- /dev/null
+++ b/cpu/ppc4xx/440spe_pcie.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <ppc4xx.h>
+#ifndef __440SPE_PCIE_H
+#define __440SPE_PCIE_H
+
+#define mdelay(n) ({unsigned long __ms=(n); while (__ms--) udelay(1000);})
+
+#define DCRN_SDR0_CFGADDR	0x00e
+#define DCRN_SDR0_CFGDATA	0x00f
+
+#define DCRN_PCIE0_BASE		0x100
+#define DCRN_PCIE1_BASE		0x120
+#define DCRN_PCIE2_BASE		0x140
+#define PCIE0			DCRN_PCIE0_BASE
+#define PCIE1			DCRN_PCIE1_BASE
+#define PCIE2			DCRN_PCIE2_BASE
+
+#define DCRN_PEGPL_CFGBAH(base)		(base + 0x00)
+#define DCRN_PEGPL_CFGBAL(base)		(base + 0x01)
+#define DCRN_PEGPL_CFGMSK(base)		(base + 0x02)
+#define DCRN_PEGPL_MSGBAH(base)		(base + 0x03)
+#define DCRN_PEGPL_MSGBAL(base)		(base + 0x04)
+#define DCRN_PEGPL_MSGMSK(base)		(base + 0x05)
+#define DCRN_PEGPL_OMR1BAH(base)	(base + 0x06)
+#define DCRN_PEGPL_OMR1BAL(base)	(base + 0x07)
+#define DCRN_PEGPL_OMR1MSKH(base)	(base + 0x08)
+#define DCRN_PEGPL_OMR1MSKL(base)	(base + 0x09)
+#define DCRN_PEGPL_REGBAH(base)		(base + 0x12)
+#define DCRN_PEGPL_REGBAL(base)		(base + 0x13)
+#define DCRN_PEGPL_REGMSK(base)		(base + 0x14)
+#define DCRN_PEGPL_SPECIAL(base)	(base + 0x15)
+
+/*
+ * System DCRs (SDRs)
+ */
+#define PESDR0_PLLLCT1		0x03a0
+#define PESDR0_PLLLCT2		0x03a1
+#define PESDR0_PLLLCT3		0x03a2
+
+#define PESDR0_UTLSET1		0x0300
+#define PESDR0_UTLSET2		0x0301
+#define PESDR0_DLPSET		0x0302
+#define PESDR0_LOOP		0x0303
+#define PESDR0_RCSSET		0x0304
+#define PESDR0_RCSSTS		0x0305
+#define PESDR0_HSSL0SET1	0x0306
+#define PESDR0_HSSL0SET2	0x0307
+#define PESDR0_HSSL0STS		0x0308
+#define PESDR0_HSSL1SET1	0x0309
+#define PESDR0_HSSL1SET2	0x030a
+#define PESDR0_HSSL1STS		0x030b
+#define PESDR0_HSSL2SET1	0x030c
+#define PESDR0_HSSL2SET2	0x030d
+#define PESDR0_HSSL2STS		0x030e
+#define PESDR0_HSSL3SET1	0x030f
+#define PESDR0_HSSL3SET2	0x0310
+#define PESDR0_HSSL3STS		0x0311
+#define PESDR0_HSSL4SET1	0x0312
+#define PESDR0_HSSL4SET2	0x0313
+#define PESDR0_HSSL4STS		0x0314
+#define PESDR0_HSSL5SET1	0x0315
+#define PESDR0_HSSL5SET2	0x0316
+#define PESDR0_HSSL5STS		0x0317
+#define PESDR0_HSSL6SET1	0x0318
+#define PESDR0_HSSL6SET2	0x0319
+#define PESDR0_HSSL6STS		0x031a
+#define PESDR0_HSSL7SET1	0x031b
+#define PESDR0_HSSL7SET2	0x031c
+#define PESDR0_HSSL7STS		0x031d
+#define PESDR0_HSSCTLSET	0x031e
+#define PESDR0_LANE_ABCD	0x031f
+#define PESDR0_LANE_EFGH	0x0320
+
+#define PESDR1_UTLSET1		0x0340
+#define PESDR1_UTLSET2		0x0341
+#define PESDR1_DLPSET		0x0342
+#define PESDR1_LOOP		0x0343
+#define PESDR1_RCSSET		0x0344
+#define PESDR1_RCSSTS		0x0345
+#define PESDR1_HSSL0SET1	0x0346
+#define PESDR1_HSSL0SET2	0x0347
+#define PESDR1_HSSL0STS		0x0348
+#define PESDR1_HSSL1SET1	0x0349
+#define PESDR1_HSSL1SET2	0x034a
+#define PESDR1_HSSL1STS		0x034b
+#define PESDR1_HSSL2SET1	0x034c
+#define PESDR1_HSSL2SET2	0x034d
+#define PESDR1_HSSL2STS		0x034e
+#define PESDR1_HSSL3SET1	0x034f
+#define PESDR1_HSSL3SET2	0x0350
+#define PESDR1_HSSL3STS		0x0351
+#define PESDR1_HSSCTLSET	0x0352
+#define PESDR1_LANE_ABCD	0x0353
+
+#define PESDR2_UTLSET1		0x0370
+#define PESDR2_UTLSET2		0x0371
+#define PESDR2_DLPSET		0x0372
+#define PESDR2_LOOP		0x0373
+#define PESDR2_RCSSET		0x0374
+#define PESDR2_RCSSTS		0x0375
+#define PESDR2_HSSL0SET1	0x0376
+#define PESDR2_HSSL0SET2	0x0377
+#define PESDR2_HSSL0STS		0x0378
+#define PESDR2_HSSL1SET1	0x0379
+#define PESDR2_HSSL1SET2	0x037a
+#define PESDR2_HSSL1STS		0x037b
+#define PESDR2_HSSL2SET1	0x037c
+#define PESDR2_HSSL2SET2	0x037d
+#define PESDR2_HSSL2STS		0x037e
+#define PESDR2_HSSL3SET1	0x037f
+#define PESDR2_HSSL3SET2	0x0380
+#define PESDR2_HSSL3STS		0x0381
+#define PESDR2_HSSCTLSET	0x0382
+#define PESDR2_LANE_ABCD	0x0383
+
+/*
+ * UTL register offsets
+ */
+#define PEUTL_PBBSZ		0x20
+#define PEUTL_OPDBSZ		0x68
+#define PEUTL_IPHBSZ		0x70
+#define PEUTL_IPDBSZ		0x78
+#define PEUTL_OUTTR		0x90
+#define PEUTL_INTR		0x98
+#define PEUTL_PCTL		0xa0
+#define PEUTL_RCIRQEN		0xb8
+
+/*
+ * Config space register offsets
+ */
+#define PECFG_BAR0LMPA		0x210
+#define PECFG_BAR0HMPA		0x214
+#define PECFG_BAR1MPA		0x218
+#define PECFG_BAR2MPA		0x220
+
+#define PECFG_PIMEN		0x33c
+#define PECFG_PIM0LAL		0x340
+#define PECFG_PIM0LAH		0x344
+#define PECFG_PIM1LAL     	0x348
+#define PECFG_PIM1LAH     	0x34c
+#define PECFG_PIM01SAL		0x350
+#define PECFG_PIM01SAH		0x354
+
+#define PECFG_POM0LAL		0x380
+#define PECFG_POM0LAH		0x384
+
+#define SDR_READ(offset) ({\
+	mtdcr(DCRN_SDR0_CFGADDR, offset); \
+	mfdcr(DCRN_SDR0_CFGDATA);})
+
+#define SDR_WRITE(offset, data) ({\
+	mtdcr(DCRN_SDR0_CFGADDR, offset); \
+	mtdcr(DCRN_SDR0_CFGDATA,data);})
+
+int ppc440spe_init_pcie(void);
+int ppc440spe_init_pcie_rootport(int port);
+void yucca_setup_pcie_fpga_rootpoint(int port);
+void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port);
+int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port);
+int yucca_pcie_card_present(int port);
+int pcie_hose_scan(struct pci_controller *hose, int bus);
+#endif /* __440SPE_PCIE_H */
diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c
index fab65af..81d49ff 100644
--- a/cpu/ppc4xx/4xx_enet.c
+++ b/cpu/ppc4xx/4xx_enet.c
@@ -130,7 +130,17 @@
 #define BI_PHYMODE_NONE	 0
 #define BI_PHYMODE_ZMII	 1
 #define BI_PHYMODE_RGMII 2
+#define BI_PHYMODE_GMII  3
+#define BI_PHYMODE_RTBI  4
+#define BI_PHYMODE_TBI   5
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define BI_PHYMODE_SMII  6
+#define BI_PHYMODE_MII   7
+#endif
 
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_MFR_ETH_CLK_SEL_V(n)	((0x01<<27) / (n+1))
+#endif
 
 /*-----------------------------------------------------------------------------+
  * Global variables. TX and RX descriptors and buffers.
@@ -181,7 +191,7 @@
 {
 	EMAC_4XX_HW_PST hw_p = dev->priv;
 	uint32_t failsafe = 10000;
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	unsigned long mfr;
 #endif
 
@@ -205,19 +215,19 @@
 	}
 
 	/* EMAC RESET */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* provide clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr |= 0x08000000;
+	mfr |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
 	out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* remove clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr &= ~0x08000000;
+	mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
@@ -317,10 +327,50 @@
 	out32 (RGMII_FER, rmiifer);
 
 	return ((int)pfc1);
-
 }
 #endif	/* CONFIG_440_GX */
 
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+	unsigned long zmiifer=0x0;
+
+	/*
+	 * Right now only 2*RGMII is supported. Please extend when needed.
+	 * sr - 2006-08-29
+	 */
+	switch (1) {
+	case 0:
+		/* 1 x GMII port */
+		out32 (ZMII_FER, 0x00);
+		out32 (RGMII_FER, 0x00000037);
+		bis->bi_phymode[0] = BI_PHYMODE_GMII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	case 1:
+		/* 2 x RGMII ports */
+		out32 (ZMII_FER, 0x00);
+		out32 (RGMII_FER, 0x00000055);
+		bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+		break;
+	case 2:
+		/* 2 x SMII ports */
+
+		break;
+	default:
+		break;
+	}
+
+	/* Ensure we setup mdio for this devnum and ONLY this devnum */
+	zmiifer = in32 (ZMII_FER);
+	zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
+	out32 (ZMII_FER, zmiifer);
+
+	return ((int)0x0);
+}
+#endif	/* CONFIG_440EPX */
+
 static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 {
 	int i, j;
@@ -332,13 +382,16 @@
 	unsigned mode_reg;
 	unsigned short devnum;
 	unsigned short reg_short;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	sys_info_t sysinfo;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	int ethgroup = -1;
 #endif
 #endif
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || defined(CONFIG_440SPE)
 	unsigned long mfr;
 #endif
 
@@ -352,7 +405,9 @@
 		return -1;
 	}
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	/* Need to get the OPB frequency so we can access the PHY */
 	get_sys_info (&sysinfo);
 #endif
@@ -407,7 +462,7 @@
 
 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
 	out32 (ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
-#elif defined(CONFIG_440GX)
+#elif defined(CONFIG_440GX) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
 #elif defined(CONFIG_440GP)
 	/* set RMII mode */
@@ -429,10 +484,10 @@
 	__asm__ volatile ("eieio");
 
 	/* reset emac so we have access to the phy */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* provide clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr |= 0x08000000;
+	mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
@@ -444,15 +499,19 @@
 		udelay (1000);
 		failsafe--;
 	}
+	if (failsafe <= 0)
+		printf("\nProblem resetting EMAC!\n");
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* remove clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr &= ~0x08000000;
+	mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	/* Whack the M1 register */
 	mode_reg = 0x0;
 	mode_reg &= ~0x00000038;
@@ -502,15 +561,39 @@
 	 * otherwise, just check the speeds & feeds
 	 */
 	if (hw_p->first_init == 0) {
+#if defined(CONFIG_88E1111_CLK_DELAY)
+		/*
+		 * On some boards (e.g. ALPR) the Marvell 88E1111 PHY needs
+		 * the "RGMII transmit timing control" and "RGMII receive
+		 * timing control" bits set, so that Gbit communication works
+		 * without problems.
+		 * Also set the "Transmitter disable" to 1 to enable the
+		 * transmitter.
+		 * After setting these bits a soft-reset must occur for this
+		 * change to become active.
+		 */
+		miiphy_read (dev->name, reg, 0x14, &reg_short);
+		reg_short |= (1 << 7) | (1 << 1) | (1 << 0);
+		miiphy_write (dev->name, reg, 0x14, reg_short);
+#endif
+#if defined(CONFIG_M88E1111_PHY) /* test-only: merge with CONFIG_88E1111_CLK_DELAY !!! */
+		miiphy_write (dev->name, reg, 0x14, 0x0ce3);
+		miiphy_write (dev->name, reg, 0x18, 0x4101);
+		miiphy_write (dev->name, reg, 0x09, 0x0e00);
+		miiphy_write (dev->name, reg, 0x04, 0x01e1);
+#endif
 		miiphy_reset (dev->name, reg);
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+
 #if defined(CONFIG_CIS8201_PHY)
 		/*
 		 * Cicada 8201 PHY needs to have an extended register whacked
 		 * for RGMII mode.
 		 */
-		if ( ((devnum == 2) || (devnum ==3)) && (4 == ethgroup) ) {
+		if (((devnum == 2) || (devnum == 3)) && (4 == ethgroup)) {
 #if defined(CONFIG_CIS8201_SHORT_ETCH)
 			miiphy_write (dev->name, reg, 23, 0x1300);
 #else
@@ -580,7 +663,8 @@
 			(int) speed, (duplex == HALF) ? "HALF" : "FULL");
 	}
 
-#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
+#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
 	mfsdr(sdr_mfr, reg);
 	if (speed == 100) {
@@ -603,15 +687,34 @@
 			reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
 		else if (speed == 100)
 			reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
-		else
+		else if (speed == 10)
 			reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
-
+		else {
+			printf("Error in RGMII Speed\n");
+			return -1;
+		}
 		out32 (RGMII_SSR, reg);
 	}
 #endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
 
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+	if (speed == 1000)
+		reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
+	else if (speed == 100)
+		reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
+	else if (speed == 10)
+		reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
+	else {
+		printf("Error in RGMII Speed\n");
+		return -1;
+	}
+	out32 (RGMII_SSR, reg);
+#endif
+
 	/* set the Mal configuration reg */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
 	       MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000);
 #else
@@ -795,8 +898,10 @@
 
 	/* set speed */
 	if (speed == _1000BASET) {
-#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 		unsigned long pfc1;
+
 		mfsdr (sdr_pfc1, pfc1);
 		pfc1 |= SDR0_PFC1_EM_1000;
 		mtsdr (sdr_pfc1, pfc1);
@@ -942,6 +1047,14 @@
 #define UIC0SR		uic0sr
 #endif
 
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define UICMSR_ETHX	uic0msr
+#define UICSR_ETHX	uic0sr
+#else
+#define UICMSR_ETHX	uic1msr
+#define UICSR_ETHX	uic1sr
+#endif
+
 int enetInt (struct eth_device *dev)
 {
 	int serviced;
@@ -950,6 +1063,7 @@
 	unsigned long emac_isr = 0;
 	unsigned long mal_rx_eob;
 	unsigned long my_uic0msr, my_uic1msr;
+	unsigned long my_uicmsr_ethx;
 
 #if defined(CONFIG_440GX)
 	unsigned long my_uic2msr;
@@ -977,8 +1091,11 @@
 #if defined(CONFIG_440GX)
 		my_uic2msr = mfdcr (uic2msr);
 #endif
+		my_uicmsr_ethx = mfdcr (UICMSR_ETHX);
+
 		if (!(my_uic0msr & (UIC_MRE | UIC_MTE))
-		    && !(my_uic1msr & (UIC_ETH0 | UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE))) {
+		    && !(my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))
+		    && !(my_uicmsr_ethx & (UIC_ETH0 | UIC_ETH1))) {
 			/* not for us */
 			return (rc);
 		}
@@ -997,8 +1114,7 @@
 			mal_isr = mfdcr (malesr);
 			/* look for mal error */
 			if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) {
-				mal_err (dev, mal_isr, my_uic0msr,
-					 MAL_UIC_DEF, MAL_UIC_ERR);
+				mal_err (dev, mal_isr, my_uic1msr, MAL_UIC_DEF, MAL_UIC_ERR);
 				serviced = 1;
 				rc = 0;
 			}
@@ -1006,7 +1122,7 @@
 
 		/* port by port dispatch of emac interrupts */
 		if (hw_p->devnum == 0) {
-			if (UIC_ETH0 & my_uic1msr) {	/* look for EMAC errors */
+			if (UIC_ETH0 & my_uicmsr_ethx) {	/* look for EMAC errors */
 				emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
 				if ((hw_p->emac_ier & emac_isr) != 0) {
 					emac_err (dev, emac_isr);
@@ -1017,14 +1133,15 @@
 			if ((hw_p->emac_ier & emac_isr)
 			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
 				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */
-				mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
+				mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
+				mtdcr (UICSR_ETHX, UIC_ETH0); /* Clear */
 				return (rc);	/* we had errors so get out */
 			}
 		}
 
 #if !defined(CONFIG_440SP)
 		if (hw_p->devnum == 1) {
-			if (UIC_ETH1 & my_uic1msr) {	/* look for EMAC errors */
+			if (UIC_ETH1 & my_uicmsr_ethx) {	/* look for EMAC errors */
 				emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
 				if ((hw_p->emac_ier & emac_isr) != 0) {
 					emac_err (dev, emac_isr);
@@ -1035,7 +1152,8 @@
 			if ((hw_p->emac_ier & emac_isr)
 			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
 				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */
-				mtdcr (uic1sr, UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
+				mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+				mtdcr (UICSR_ETHX, UIC_ETH1); /* Clear */
 				return (rc);	/* we had errors so get out */
 			}
 		}
@@ -1102,10 +1220,10 @@
 		mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
 		switch (hw_p->devnum) {
 		case 0:
-			mtdcr (uic1sr, UIC_ETH0);
+			mtdcr (UICSR_ETHX, UIC_ETH0);
 			break;
 		case 1:
-			mtdcr (uic1sr, UIC_ETH1);
+			mtdcr (UICSR_ETHX, UIC_ETH1);
 			break;
 #if defined (CONFIG_440GX)
 		case 2:
@@ -1512,7 +1630,7 @@
 
 		if (0 == virgin) {
 			/* set the MAL IER ??? names may change with new spec ??? */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 			mal_ier =
 				MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE |
 				MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ;
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index c563457..baecf70 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,28 +23,31 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o resetvec.o kgdb.o
-AOBJS	= dcr.o
+SOBJS	= dcr.o
 COBJS	= 405gp_pci.o 4xx_enet.o \
 	  bedbug_405.o commproc.o \
 	  cpu.o cpu_init.o i2c.o interrupts.o \
-	  miiphy.o sdram.o serial.o \
-	  spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o
+	  miiphy.o ndfc.o sdram.o serial.o \
+	  spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o \
+	  440spe_pcie.o
 
-OBJS	= $(AOBJS) $(COBJS)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
 
-all:	.depend $(START) $(LIB)
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index 71303bc..f4a7208 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -41,14 +41,15 @@
 DECLARE_GLOBAL_DATA_PTR;
 #endif
 
-
 #if defined(CONFIG_440)
 #define FREQ_EBC		(sys_info.freqEPB)
 #else
 #define FREQ_EBC		(sys_info.freqPLB / sys_info.pllExtBusDiv)
 #endif
 
-#if defined(CONFIG_405GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_405GP) || \
+    defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 
 #define PCI_ASYNC
 
@@ -58,7 +59,8 @@
 	return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
 #endif
 
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	unsigned long val;
 
 	mfsdr(sdr_sdstp1, val);
@@ -82,9 +84,10 @@
 	return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-     defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-     defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	unsigned long val;
 
 	mfsdr(sdr_sdstp1, val);
@@ -93,8 +96,10 @@
 }
 #endif
 
-#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) ||  \
-     defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_405EP) || defined(CONFIG_440GX) || \
+    defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 
 #define I2C_BOOTROM
 
@@ -102,17 +107,75 @@
 {
 #if defined(CONFIG_405EP)
 	return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
-#endif
-
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-     defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
+#else
 	unsigned long val;
 
 	mfsdr(sdr_sdcs, val);
 	return (val & SDR0_SDCS_SDD);
 #endif
+}
+
+#if defined(CONFIG_440GX)
+#define SDR0_PINSTP_SHIFT	29
+static char *bootstrap_str[] = {
+	"EBC (16 bits)",
+	"EBC (8 bits)",
+	"EBC (32 bits)",
+	"EBC (8 bits)",
+	"PCI",
+	"I2C (Addr 0x54)",
+	"Reserved",
+	"I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#define SDR0_PINSTP_SHIFT	30
+static char *bootstrap_str[] = {
+	"EBC (8 bits)",
+	"PCI",
+	"I2C (Addr 0x54)",
+	"I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#define SDR0_PINSTP_SHIFT	29
+static char *bootstrap_str[] = {
+	"EBC (8 bits)",
+	"PCI",
+	"NAND (8 bits)",
+	"EBC (16 bits)",
+	"EBC (16 bits)",
+	"I2C (Addr 0x54)",
+	"PCI",
+	"I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_PINSTP_SHIFT	29
+static char *bootstrap_str[] = {
+	"EBC (8 bits)",
+	"EBC (16 bits)",
+	"EBC (16 bits)",
+	"NAND (8 bits)",
+	"PCI",
+	"I2C (Addr 0x54)",
+	"PCI",
+	"I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(SDR0_PINSTP_SHIFT)
+static int bootstrap_option(void)
+{
+	unsigned long val;
+
+	mfsdr(sdr_pinstp, val);
+	return ((val & 0xe0000000) >> SDR0_PINSTP_SHIFT);
 }
+#endif /* SDR0_PINSTP_SHIFT */
 #endif
 
 
@@ -129,6 +192,7 @@
 	char buf[32];
 
 #if !defined(CONFIG_IOP480)
+	char addstr[64] = "";
 	sys_info_t sys_info;
 
 	puts ("CPU:   ");
@@ -244,6 +308,26 @@
 #endif /* CONFIG_440GR */
 #endif /* CONFIG_440 */
 
+	case PVR_440EPX1_RA:
+		puts("EPx Rev. A");
+		strcpy(addstr, "Security/Kasumi support");
+		break;
+
+	case PVR_440EPX2_RA:
+		puts("EPx Rev. A");
+		strcpy(addstr, "No Security/Kasumi support");
+		break;
+
+	case PVR_440GRX1_RA:
+		puts("GRx Rev. A");
+		strcpy(addstr, "Security/Kasumi support");
+		break;
+
+	case PVR_440GRX2_RA:
+		puts("GRx Rev. A");
+		strcpy(addstr, "No Security/Kasumi support");
+		break;
+
 	case PVR_440SP_RA:
 		puts("SP Rev. A");
 		break;
@@ -270,9 +354,16 @@
 	       sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
 	       FREQ_EBC / 1000000);
 
+	if (addstr[0] != 0)
+		printf("       %s\n", addstr);
+
 #if defined(I2C_BOOTROM)
 	printf ("       I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
-#endif
+#if defined(SDR0_PINSTP_SHIFT)
+	printf ("       Bootstrap Option %c - ", (char)bootstrap_option() + 'A');
+	printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
+#endif	/* SDR0_PINSTP_SHIFT */
+#endif	/* I2C_BOOTROM */
 
 #if defined(CONFIG_PCI)
 	printf ("       Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
@@ -315,6 +406,17 @@
 	return 0;
 }
 
+#if defined (CONFIG_440SPE)
+int ppc440spe_revB() {
+	unsigned int pvr;
+
+	pvr = get_pvr();
+	if (pvr == PVR_440SPe_RB)
+		return 1;
+	else
+		return 0;
+}
+#endif
 
 /* ------------------------------------------------------------------------- */
 
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index b27567f..def46f1 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -226,13 +226,19 @@
 	/*
 	 * GPIO0 setup (select GPIO or alternate function)
 	 */
-	out32(GPIO0_OSRH, CFG_GPIO0_OSRH);   /* output select */
+#if defined(CFG_GPIO0_OR)
+	out32(GPIO0_OR, CFG_GPIO0_OR);		/* set initial state of output pins	*/
+#endif
+#if defined(CFG_GPIO0_ODR)
+	out32(GPIO0_ODR, CFG_GPIO0_ODR);	/* open-drain select			*/
+#endif
+	out32(GPIO0_OSRH, CFG_GPIO0_OSRH);	/* output select			*/
 	out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
-	out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
+	out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H);	/* input select				*/
 	out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
-	out32(GPIO0_TSRH, CFG_GPIO0_TSRH);   /* three-state select */
+	out32(GPIO0_TSRH, CFG_GPIO0_TSRH);	/* three-state select			*/
 	out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
-	out32(GPIO0_TCR, CFG_GPIO0_TCR);     /* enable output driver for outputs */
+	out32(GPIO0_TCR, CFG_GPIO0_TCR);	/* enable output driver for outputs	*/
 
 	/*
 	 * Set EMAC noise filter bits
diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c
index 886f405..c5a9f02 100644
--- a/cpu/ppc4xx/interrupts.c
+++ b/cpu/ppc4xx/interrupts.c
@@ -57,12 +57,13 @@
 
 void uic1_interrupt( void * parms); /* UIC1 handler */
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 static struct irq_action irq_vecs2[32]; /* For UIC2 */
 void uic2_interrupt( void * parms); /* UIC2 handler */
 #endif /* CONFIG_440GX CONFIG_440SPE */
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 static struct irq_action irq_vecs3[32]; /* For UIC3 */
 void uic3_interrupt( void * parms); /* UIC3 handler */
 #endif /* CONFIG_440SPE */
@@ -119,12 +120,13 @@
 		irq_vecs1[vec].handler = NULL;
 		irq_vecs1[vec].arg = NULL;
 		irq_vecs1[vec].count = 0;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 		irq_vecs2[vec].handler = NULL;
 		irq_vecs2[vec].arg = NULL;
 		irq_vecs2[vec].count = 0;
 #endif /* CONFIG_440GX */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 		irq_vecs3[vec].handler = NULL;
 		irq_vecs3[vec].arg = NULL;
 		irq_vecs3[vec].count = 0;
@@ -230,6 +232,32 @@
 
 } /* external_interrupt CONFIG_440GX */
 
+#elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+void external_interrupt(struct pt_regs *regs)
+{
+	ulong uic_msr;
+
+	/*
+	 * Read masked interrupt status register to determine interrupt source
+	 */
+	/* 440 SPe uses base uic register */
+	uic_msr = mfdcr(uic0msr);
+
+	if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
+		uic1_interrupt(0);
+
+	if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
+		uic2_interrupt(0);
+
+	if (uic_msr & ~(UICB0_ALL))
+		uic0_interrupt(0);
+
+	mtdcr(uic0sr, uic_msr);
+
+	return;
+
+} /* external_interrupt CONFIG_440EPX & CONFIG_440GRX */
+
 #elif defined(CONFIG_440SPE)
 void external_interrupt(struct pt_regs *regs)
 {
@@ -303,7 +331,8 @@
 }
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 /* Handler for UIC0 interrupt */
 void uic0_interrupt( void * parms)
 {
@@ -394,7 +423,8 @@
 }
 #endif /* defined(CONFIG_440) */
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 /* Handler for UIC2 interrupt */
 void uic2_interrupt( void * parms)
 {
@@ -496,7 +526,8 @@
 	int i = vec;
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64)) {
 		i = vec - 32;
 		irqa = irq_vecs1;
@@ -523,7 +554,8 @@
 	irqa[i].arg = arg;
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64))
 		mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
 	else if (vec > 63)
@@ -546,7 +578,8 @@
 	int i = vec;
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64)) {
 		irqa = irq_vecs1;
 		i = vec - 32;
@@ -567,7 +600,8 @@
 #endif
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64))
 		mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
 	else if (vec > 63)
@@ -635,7 +669,8 @@
 	printf("\n");
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	printf ("\nUIC 2\n");
 	printf ("Nr  Routine   Arg       Count\n");
 
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index aa580ed..6b98025 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -173,7 +173,8 @@
 	}
 	sta_reg = reg;		/* reg address */
 	/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 #if defined(CONFIG_IBM_EMAC4_V4)      /* EMAC4 V4 changed bit setting */
 		sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
 #else
@@ -183,7 +184,9 @@
 	sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
 #endif
 
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 	sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
 #endif
 	sta_reg = sta_reg | (addr << 5);	/* Phy address */
@@ -244,7 +247,8 @@
 	sta_reg = 0;
 	sta_reg = reg;		/* reg address */
 	/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 #if defined(CONFIG_IBM_EMAC4_V4)      /* EMAC4 V4 changed bit setting */
 		sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
 #else
@@ -254,7 +258,9 @@
 	sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
 #endif
 
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 	sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;	/* Set clock frequency (PLB freq. dependend) */
 #endif
 	sta_reg = sta_reg | ((unsigned long) addr << 5);/* Phy address */
diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c
new file mode 100644
index 0000000..3521731
--- /dev/null
+++ b/cpu/ppc4xx/ndfc.c
@@ -0,0 +1,193 @@
+/*
+ * Overview:
+ *   Platform independend driver for NDFC (NanD Flash Controller)
+ *   integrated into EP440 cores
+ *
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Based on original work by
+ *	Thomas Gleixner
+ *	Copyright 2006 IBM
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY) && \
+	(defined(CONFIG_440EP) || defined(CONFIG_440GR) ||	     \
+	 defined(CONFIG_440EPX) || defined(CONFIG_440GRX))
+
+#include <nand.h>
+#include <linux/mtd/ndfc.h>
+#include <asm/processor.h>
+#include <ppc440.h>
+
+static u8 hwctl = 0;
+
+static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd)
+{
+	switch (cmd) {
+	case NAND_CTL_SETCLE:
+		hwctl |= 0x1;
+		break;
+
+	case NAND_CTL_CLRCLE:
+		hwctl &= ~0x1;
+		break;
+
+	case NAND_CTL_SETALE:
+		hwctl |= 0x2;
+		break;
+
+	case NAND_CTL_CLRALE:
+		hwctl &= ~0x2;
+		break;
+	}
+}
+
+static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+
+	if (hwctl & 0x1)
+		out8(base + NDFC_CMD, byte);
+	else if (hwctl & 0x2)
+		out8(base + NDFC_ALE, byte);
+	else
+		out8(base + NDFC_DATA, byte);
+}
+
+static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+
+	return (in8(base + NDFC_DATA));
+}
+
+static int ndfc_dev_ready(struct mtd_info *mtdinfo)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+
+	while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY))
+		;
+
+	return 1;
+}
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * Don't use these speedup functions in NAND boot image, since the image
+ * has to fit into 4kByte.
+ */
+
+/*
+ * Speedups for buffer read/write/verify
+ *
+ * NDFC allows 32bit read/write of data. So we can speed up the buffer
+ * functions. No further checking, as nand_base will always read/write
+ * page aligned.
+ */
+static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+	uint32_t *p = (uint32_t *) buf;
+
+	for (;len > 0; len -= 4)
+		*p++ = in32(base + NDFC_DATA);
+}
+
+static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+	uint32_t *p = (uint32_t *) buf;
+
+	for (; len > 0; len -= 4)
+		out32(base + NDFC_DATA, *p++);
+}
+
+static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+	uint32_t *p = (uint32_t *) buf;
+
+	for (; len > 0; len -= 4)
+		if (*p++ != in32(base + NDFC_DATA))
+			return -1;
+
+	return 0;
+}
+#endif /* #ifndef CONFIG_NAND_SPL */
+
+void board_nand_select_device(struct nand_chip *nand, int chip)
+{
+	/*
+	 * Don't use "chip" to address the NAND device,
+	 * generate the cs from the address where it is encoded.
+	 */
+	int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
+	ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
+
+	/* Set NandFlash Core Configuration Register */
+	/* 1col x 2 rows */
+	out32(base + NDFC_CCR, 0x00000000 | (cs << 24));
+}
+
+void board_nand_init(struct nand_chip *nand)
+{
+	int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
+	ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
+
+	nand->eccmode = NAND_ECC_SOFT;
+
+	nand->hwcontrol  = ndfc_hwcontrol;
+	nand->read_byte  = ndfc_read_byte;
+	nand->write_byte = ndfc_write_byte;
+	nand->dev_ready  = ndfc_dev_ready;
+
+#ifndef CONFIG_NAND_SPL
+	nand->write_buf  = ndfc_write_buf;
+	nand->read_buf   = ndfc_read_buf;
+	nand->verify_buf = ndfc_verify_buf;
+#else
+	/*
+	 * Setup EBC (CS0 only right now)
+	 */
+	mtdcr(ebccfga, xbcfg);
+	mtdcr(ebccfgd, 0xb8400000);
+
+	mtebc(pb0cr, CFG_EBC_PB0CR);
+	mtebc(pb0ap, CFG_EBC_PB0AP);
+#endif
+
+	/*
+	 * Select required NAND chip in NDFC
+	 */
+	board_nand_select_device(nand, cs);
+	out32(base + NDFC_BCFG0 + (cs << 2), 0x80002222);
+}
+
+#endif
diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c
index ad3ca6e..fab0d95 100644
--- a/cpu/ppc4xx/serial.c
+++ b/cpu/ppc4xx/serial.c
@@ -264,10 +264,12 @@
 #endif	/* CONFIG_IOP480 */
 
 /*****************************************************************************/
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405EP)
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) || \
+    defined(CONFIG_440)
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 #define UART0_BASE  CFG_PERIPHERAL_BASE + 0x00000300
 #define UART1_BASE  CFG_PERIPHERAL_BASE + 0x00000400
 #else
@@ -279,15 +281,34 @@
 #define UART2_BASE  CFG_PERIPHERAL_BASE + 0x00000600
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
-#define CR0_MASK        0xdfffffff
-#define CR0_EXTCLK_ENA  0x00800000
-#define CR0_UDIV_POS    0
-#else
+#if defined(CONFIG_440GP)
 #define CR0_MASK        0x3fff0000
 #define CR0_EXTCLK_ENA  0x00600000
 #define CR0_UDIV_POS    16
-#endif /* CONFIG_440GX */
+#define UDIV_SUBTRACT	1
+#define UART0_SDR	cntrl0
+#define MFREG(a, d)	d = mfdcr(a)
+#define MTREG(a, d)	mtdcr(a, d)
+#else /* #if defined(CONFIG_440GP) */
+/* all other 440 PPC's access clock divider via sdr register */
+#define CR0_MASK        0xdfffffff
+#define CR0_EXTCLK_ENA  0x00800000
+#define CR0_UDIV_POS    0
+#define UDIV_SUBTRACT	0
+#define UART0_SDR	sdr_uart0
+#define UART1_SDR	sdr_uart1
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+    defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPe)
+#define UART2_SDR	sdr_uart2
+#endif
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+    defined(CONFIG_440GR) || defined(CONFIG_440GRx)
+#define UART3_SDR	sdr_uart3
+#endif
+#define MFREG(a, d)	mfsdr(a, d)
+#define MTREG(a, d)	mtsdr(a, d)
+#endif /* #if defined(CONFIG_440GP) */
 #elif defined(CONFIG_405EP)
 #define UART0_BASE      0xef600300
 #define UART1_BASE      0xef600400
@@ -309,23 +330,17 @@
 #if defined(CONFIG_UART1_CONSOLE)
 #define ACTING_UART0_BASE	UART1_BASE
 #define ACTING_UART1_BASE	UART0_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-#define UART0_SDR           sdr_uart1
-#define UART1_SDR           sdr_uart0
-#endif /* CONFIG_440GX */
 #else
 #define ACTING_UART0_BASE	UART0_BASE
 #define ACTING_UART1_BASE	UART1_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-#define UART0_SDR           sdr_uart0
-#define UART1_SDR           sdr_uart1
-#endif /* CONFIG_440GX */
 #endif
 
+#if defined(CONFIG_SERIAL_MULTI)
+#define UART_BASE	dev_base
+#else
+#define UART_BASE	ACTING_UART0_BASE
+#endif
+
 #if defined(CONFIG_405EP) && defined(CFG_EXT_SERIAL_CLOCK)
 #error "External serial clock not supported on AMCC PPC405EP!"
 #endif
@@ -419,7 +434,7 @@
 	*pbdiv = div/udiv;
 
 }
-#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK */
+#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK) */
 
 /*
  * Minimal serial functions needed to use one of the SMC ports
@@ -441,23 +456,9 @@
 	unsigned long tmp;
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-#if defined(CONFIG_SERIAL_MULTI)
-	if (UART0_BASE == dev_base) {
-		mfsdr(UART0_SDR,reg);
-		reg &= ~CR0_MASK;
-	} else {
-		mfsdr(UART1_SDR,reg);
-		reg &= ~CR0_MASK;
-	}
-#else
-	mfsdr(UART0_SDR,reg);
+	MFREG(UART0_SDR, reg);
 	reg &= ~CR0_MASK;
-#endif
-#else
-	reg = mfdcr(cntrl0) & ~CR0_MASK;
-#endif /* CONFIG_440GX */
+
 #ifdef CFG_EXT_SERIAL_CLOCK
 	reg |= CR0_EXTCLK_ENA;
 	udiv = 1;
@@ -471,47 +472,34 @@
 	serial_divs (gd->baudrate, &udiv, &bdiv);
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-	reg |= udiv << CR0_UDIV_POS;	/* set the UART divisor */
-#if defined(CONFIG_SERIAL_MULTI)
-	if (UART0_BASE == dev_base) {
-		mtsdr (UART0_SDR,reg);
-	} else {
-		mtsdr (UART1_SDR,reg);
-	}
-#else
-	mtsdr (UART0_SDR,reg);
+	reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS;	/* set the UART divisor */
+
+	/*
+	 * Configure input clock to baudrate generator for all
+	 * available serial ports here
+	 */
+	MTREG(UART0_SDR, reg);
+#if defined(UART1_SDR)
+	MTREG(UART1_SDR, reg);
 #endif
-#else
-	reg |= (udiv - 1) << CR0_UDIV_POS;	/* set the UART divisor */
-	mtdcr (cntrl0, reg);
+#if defined(UART2_SDR)
+	MTREG(UART2_SDR, reg);
 #endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (dev_base + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (dev_base + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (dev_base + UART_LSR);	/* clear line status */
-	val = in8 (dev_base + UART_RBR);	/* read receive buffer */
-	out8 (dev_base + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (dev_base + UART_IER, 0x00);	/* set interrupt enable reg */
-#else
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (ACTING_UART0_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (ACTING_UART0_BASE + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (ACTING_UART0_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (ACTING_UART0_BASE + UART_LSR);	/* clear line status */
-	val = in8 (ACTING_UART0_BASE + UART_RBR);	/* read receive buffer */
-	out8 (ACTING_UART0_BASE + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (ACTING_UART0_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
+#if defined(UART3_SDR)
+	MTREG(UART3_SDR, reg);
 #endif
+
+	out8(UART_BASE + UART_LCR, 0x80);	/* set DLAB bit */
+	out8(UART_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
+	out8(UART_BASE + UART_DLM, bdiv >> 8);	/* set baudrate divisor */
+	out8(UART_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	out8(UART_BASE + UART_FCR, 0x00);	/* disable FIFO */
+	out8(UART_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
+	val = in8(UART_BASE + UART_LSR);	/* clear line status */
+	val = in8(UART_BASE + UART_RBR);	/* read receive buffer */
+	out8(UART_BASE + UART_SCR, 0x00);	/* set scratchpad */
+	out8(UART_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
+
 	return (0);
 }
 
@@ -564,29 +552,17 @@
 	tmp = gd->baudrate * udiv * 16;
 	bdiv = (clk + tmp / 2) / tmp;
 
-#if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (dev_base + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (dev_base + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (dev_base + UART_LSR);	/* clear line status */
-	val = in8 (dev_base + UART_RBR);	/* read receive buffer */
-	out8 (dev_base + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (dev_base + UART_IER, 0x00);	/* set interrupt enable reg */
-#else
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (ACTING_UART0_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (ACTING_UART0_BASE + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (ACTING_UART0_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (ACTING_UART0_BASE + UART_LSR);	/* clear line status */
-	val = in8 (ACTING_UART0_BASE + UART_RBR);	/* read receive buffer */
-	out8 (ACTING_UART0_BASE + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (ACTING_UART0_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
-#endif
+	out8(UART_BASE + UART_LCR, 0x80);	/* set DLAB bit */
+	out8(UART_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
+	out8(UART_BASE + UART_DLM, bdiv >> 8);	/* set baudrate divisor */
+	out8(UART_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	out8(UART_BASE + UART_FCR, 0x00);	/* disable FIFO */
+	out8(UART_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
+	val = in8(UART_BASE + UART_LSR);	/* clear line status */
+	val = in8(UART_BASE + UART_RBR);	/* read receive buffer */
+	out8(UART_BASE + UART_SCR, 0x00);	/* set scratchpad */
+	out8(UART_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
+
 	return (0);
 }
 
@@ -598,55 +574,10 @@
 void serial_setbrg (void)
 #endif
 {
-	unsigned long tmp;
-	unsigned long clk;
-	unsigned long udiv;
-	unsigned short bdiv;
-
-#ifdef CFG_EXT_SERIAL_CLOCK
-	clk = CFG_EXT_SERIAL_CLOCK;
-#else
-	clk = gd->cpu_clk;
-#endif
-
-#ifdef CONFIG_405EP
-	udiv = ((mfdcr (cpc0_ucr) & UCR0_MASK) >> UCR0_UDIV_POS);
-#else
-	udiv = ((mfdcr (cntrl0) & 0x3e) >> 1) + 1;
-#endif /* CONFIG_405EP */
-
-#if !defined(CFG_EXT_SERIAL_CLOCK) && \
-	( defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	  defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	  defined(CONFIG_440SPE) )
-	serial_divs (gd->baudrate, &udiv, &bdiv);
-	tmp = udiv << CR0_UDIV_POS;		/* set the UART divisor */
-#if defined(CONFIG_SERIAL_MULTI)
-	if (UART0_BASE == dev_base) {
-		mtsdr (UART0_SDR, tmp);
-	} else {
-		mtsdr (UART1_SDR, tmp);
-	}
-#else
-	mtsdr (UART0_SDR, tmp);
-#endif
-
-#else
-
-	tmp = gd->baudrate * udiv * 16;
-	bdiv = (clk + tmp / 2) / tmp;
-#endif /* !defined(CFG_EXT_SERIAL_CLOCK) && (...) */
-
 #if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	serial_init_dev(dev_base);
 #else
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (ACTING_UART0_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	serial_init();
 #endif
 }
 
@@ -667,19 +598,11 @@
 
 	/* check THRE bit, wait for transmiter available */
 	for (i = 1; i < 3500; i++) {
-#if defined(CONFIG_SERIAL_MULTI)
-		if ((in8 (dev_base + UART_LSR) & 0x20) == 0x20)
-#else
-		if ((in8 (ACTING_UART0_BASE + UART_LSR) & 0x20) == 0x20)
-#endif
+		if ((in8 (UART_BASE + UART_LSR) & 0x20) == 0x20)
 			break;
 		udelay (100);
 	}
-#if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_THR, c);	/* put character out */
-#else
-	out8 (ACTING_UART0_BASE + UART_THR, c);	/* put character out */
-#endif
+	out8 (UART_BASE + UART_THR, c);	/* put character out */
 }
 
 #if defined(CONFIG_SERIAL_MULTI)
@@ -709,11 +632,7 @@
 #if defined(CONFIG_HW_WATCHDOG)
 		WATCHDOG_RESET ();	/* Reset HW Watchdog, if needed */
 #endif	/* CONFIG_HW_WATCHDOG */
-#if defined(CONFIG_SERIAL_MULTI)
-		status = in8 (dev_base + UART_LSR);
-#else
-		status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+		status = in8 (UART_BASE + UART_LSR);
 		if ((status & asyncLSRDataReady1) != 0x0) {
 			break;
 		}
@@ -721,22 +640,14 @@
 				asyncLSROverrunError1 |
 				asyncLSRParityError1  |
 				asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
-			out8 (dev_base + UART_LSR,
-#else
-			out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+			out8 (UART_BASE + UART_LSR,
 			      asyncLSRFramingError1 |
 			      asyncLSROverrunError1 |
 			      asyncLSRParityError1  |
 			      asyncLSRBreakInterrupt1);
 		}
 	}
-#if defined(CONFIG_SERIAL_MULTI)
-	return (0x000000ff & (int) in8 (dev_base));
-#else
-	return (0x000000ff & (int) in8 (ACTING_UART0_BASE));
-#endif
+	return (0x000000ff & (int) in8 (UART_BASE));
 }
 
 #if defined(CONFIG_SERIAL_MULTI)
@@ -747,11 +658,7 @@
 {
 	unsigned char status;
 
-#if defined(CONFIG_SERIAL_MULTI)
-	status = in8 (dev_base + UART_LSR);
-#else
-	status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+	status = in8 (UART_BASE + UART_LSR);
 	if ((status & asyncLSRDataReady1) != 0x0) {
 		return (1);
 	}
@@ -759,11 +666,7 @@
 			asyncLSROverrunError1 |
 			asyncLSRParityError1  |
 			asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
-		out8 (dev_base + UART_LSR,
-#else
-		out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+		out8 (UART_BASE + UART_LSR,
 		      asyncLSRFramingError1 |
 		      asyncLSROverrunError1 |
 		      asyncLSRParityError1  |
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index e552c03..2d16a83 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -199,7 +199,8 @@
 
 #elif defined(CONFIG_440)
 
-#if  defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 void get_sys_info (sys_info_t *sysInfo)
 {
 	unsigned long temp;
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 699fa7f..8e000d3 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -117,12 +117,16 @@
 
 	.extern ext_bus_cntlr_init
 	.extern sdram_init
+#ifdef CONFIG_NAND_U_BOOT
+	.extern reconfig_tlb0
+#endif
 
 /*
  * Set up GOT: Global Offset Table
  *
  * Use r14 to access the GOT
  */
+#if !defined(CONFIG_NAND_SPL)
 	START_GOT
 	GOT_ENTRY(_GOT2_TABLE_)
 	GOT_ENTRY(_FIXUP_TABLE_)
@@ -136,6 +140,18 @@
 	GOT_ENTRY(_end)
 	GOT_ENTRY(__bss_start)
 	END_GOT
+#endif /* CONFIG_NAND_SPL */
+
+#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+	/*
+	 * NAND U-Boot image is started from offset 0
+	 */
+	.text
+	bl	reconfig_tlb0
+	GET_GOT
+	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
+	bl	board_init_f
+#endif
 
 /*
  * 440 Startup -- on reset only the top 4k of the effective
@@ -150,11 +166,21 @@
  */
 
 #if defined(CONFIG_440)
+#if !defined(CONFIG_NAND_SPL)
     .section .bootpg,"ax"
+#endif
     .globl _start_440
 
 /**************************************************************************/
 _start_440:
+	/*--------------------------------------------------------------------+
+	| 440EPX BUP Change - Hardware team request
+	+--------------------------------------------------------------------*/
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+	sync
+	nop
+	nop
+#endif
 	/*----------------------------------------------------------------+
 	| Core bug fix.  Clear the esr
 	+-----------------------------------------------------------------*/
@@ -171,15 +197,31 @@
 	mtspr	srr1,r0
 	mtspr	csrr0,r0
 	mtspr	csrr1,r0
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)  /* NOTE: 440GX adds machine check status regs */
+	/* NOTE: 440GX adds machine check status regs */
+#if defined(CONFIG_440) && !defined(CONFIG_440GP)
 	mtspr	mcsrr0,r0
 	mtspr	mcsrr1,r0
-	mfspr	r1, mcsr
+	mfspr	r1,mcsr
 	mtspr	mcsr,r1
 #endif
+
+	/*----------------------------------------------------------------*/
+	/* CCR0 init */
+	/*----------------------------------------------------------------*/
+	/* Disable store gathering & broadcast, guarantee inst/data
+	* cache block touch, force load/store alignment
+	* (see errata 1.12: 440_33)
+	*/
+	lis	r1,0x0030	/* store gathering & broadcast disable */
+	ori	r1,r1,0x6000	/* cache touch */
+	mtspr	ccr0,r1
+
 	/*----------------------------------------------------------------*/
 	/* Initialize debug */
 	/*----------------------------------------------------------------*/
+	mfspr	r1,dbcr0
+	andis.	r1, r1, 0x8000	/* test DBCR0[EDM] bit			*/
+	bne	skip_debug_init	/* if set, don't clear debug register	*/
 	mtspr	dbcr0,r0
 	mtspr	dbcr1,r0
 	mtspr	dbcr2,r0
@@ -193,17 +235,7 @@
 
 	mfspr	r1,dbsr
 	mtspr	dbsr,r1		/* Clear all valid bits */
-
-	/*----------------------------------------------------------------*/
-	/* CCR0 init */
-	/*----------------------------------------------------------------*/
-	/* Disable store gathering & broadcast, guarantee inst/data
-	* cache block touch, force load/store alignment
-	* (see errata 1.12: 440_33)
-	*/
-	lis	r1,0x0030	/* store gathering & broadcast disable */
-	ori	r1,r1,0x6000	/* cache touch */
-	mtspr	ccr0,r1
+skip_debug_init:
 
 #if defined (CONFIG_440SPE)
 	/*----------------------------------------------------------------+
@@ -315,7 +347,23 @@
 	/*----------------------------------------------------------------*/
 	/* TLB entry setup -- step thru tlbtab */
 	/*----------------------------------------------------------------*/
+#if defined(CONFIG_440SPE)
+	/*----------------------------------------------------------------*/
+	/* We have different TLB tables for revA and rev B of 440SPe */
+	/*----------------------------------------------------------------*/
+	mfspr	r1, PVR
+	lis	r0,0x5342
+	ori	r0,r0,0x1891
+	cmpw	r7,r1,r0
+	bne	r7,..revA
+	bl	tlbtabB
+	b	..goon
+..revA:
+	bl	tlbtabA
+..goon:
+#else
 	bl	tlbtab		/* Get tlbtab pointer */
+#endif
 	mr	r5,r0
 	li	r1,0x003f	/* 64 TLB entries max */
 	mtctr	r1
@@ -336,7 +384,53 @@
 	/*----------------------------------------------------------------*/
 	/* Continue from 'normal' start */
 	/*----------------------------------------------------------------*/
-2:	bl	3f
+2:
+
+#if defined(CONFIG_NAND_SPL)
+	/*
+	 * Enable internal SRAM
+	 */
+	lis	r2,0x7fff
+	ori	r2,r2,0xffff
+	mfdcr	r1,isram0_dpc
+	and	r1,r1,r2		/* Disable parity check */
+	mtdcr	isram0_dpc,r1
+	mfdcr	r1,isram0_pmeg
+	and	r1,r1,r2		/* Disable pwr mgmt */
+	mtdcr	isram0_pmeg,r1
+
+	/*
+	 * Copy SPL from cache into internal SRAM
+	 */
+	li	r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
+	mtctr	r4
+	lis	r2,CFG_NAND_BOOT_SPL_SRC@h
+	ori	r2,r2,CFG_NAND_BOOT_SPL_SRC@l
+	lis	r3,CFG_NAND_BOOT_SPL_DST@h
+	ori	r3,r3,CFG_NAND_BOOT_SPL_DST@l
+spl_loop:
+	lwzu	r4,4(r2)
+	stwu	r4,4(r3)
+	bdnz	spl_loop
+
+	/*
+	 * Jump to code in RAM
+	 */
+	bl	00f
+00:	mflr	r10
+	lis	r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
+	ori	r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
+	sub	r10,r10,r3
+	addi	r10,r10,28
+	mtlr	r10
+	blr
+
+start_ram:
+	sync
+	isync
+#endif
+
+	bl	3f
 	b	_start
 
 3:	li	r0,0
@@ -350,6 +444,7 @@
  * r3 - 1st arg to board_init(): IMMP pointer
  * r4 - 2nd arg to board_init(): boot flag
  */
+#ifndef CONFIG_NAND_SPL
 	.text
 	.long	0x27051956		/* U-Boot Magic Number			*/
 	.globl	version_string
@@ -363,6 +458,7 @@
  * location (0x100) is where the CriticalInput Execption should be.
  */
 	. = EXC_OFF_SYS_RESET
+#endif
 	.globl	_start
 _start:
 
@@ -401,7 +497,8 @@
 	/* Setup the internal SRAM */
 	/*----------------------------------------------------------------*/
 	li	r0,0
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+
+#ifdef CFG_INIT_RAM_DCACHE
 	/* Clear Dcache to use as RAM */
 	addis	r3,r0,CFG_INIT_RAM_ADDR@h
 	ori	r3,r3,CFG_INIT_RAM_ADDR@l
@@ -417,19 +514,22 @@
 	dcbz	r0,r3
 	addi	r3,r3,32
 	bdnz	..d_ag
-#else
-#if defined (CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#endif /* CFG_INIT_RAM_DCACHE */
+
+	/* 440EP & 440GR are only 440er PPC's without internal SRAM */
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+	/* not all PPC's have internal SRAM usable as L2-cache */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	mtdcr	l2_cache_cfg,r0		/* Ensure L2 Cache is off */
 #endif
-	mtdcr	isram0_sb1cr,r0		/* Disable bank 1 */
 
-	li	r2,0x7fff
+	lis	r2,0x7fff
 	ori	r2,r2,0xffff
 	mfdcr	r1,isram0_dpc
 	and	r1,r1,r2		/* Disable parity check */
 	mtdcr	isram0_dpc,r1
 	mfdcr	r1,isram0_pmeg
-	andis.	r1,r1,r2		/* Disable pwr mgmt */
+	and	r1,r1,r2		/* Disable pwr mgmt */
 	mtdcr	isram0_pmeg,r1
 
 	lis	r1,0x8000		/* BAS = 8000_0000 */
@@ -458,11 +558,12 @@
 	lis	r1, 0x0003
 	ori	r1,r1, 0x0984		/* fourth 64k */
 	mtdcr	isram0_sb3cr,r1
-#else
+#elif defined(CONFIG_440GP)
 	ori	r1,r1,0x0380		/* 8k rw */
 	mtdcr	isram0_sb0cr,r1
-#endif
+	mtdcr	isram0_sb1cr,r0		/* Disable bank 1 */
 #endif
+#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
 
 	/*----------------------------------------------------------------*/
 	/* Setup the stack in internal SRAM */
@@ -479,10 +580,14 @@
 	stwu	r1,-8(r1)		/* Save back chain and move SP */
 	stw	r0,+12(r1)		/* Save return addr (underflow vect) */
 
+#ifdef CONFIG_NAND_SPL
+	bl	nand_boot		/* will not return */
+#else
 	GET_GOT
 
 	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
 	bl	board_init_f
+#endif
 
 #endif /* CONFIG_440 */
 
@@ -792,6 +897,7 @@
 	/*----------------------------------------------------------------------- */
 
 
+#ifndef CONFIG_NAND_SPL
 /*****************************************************************************/
 	.globl	_start_of_vectors
 _start_of_vectors:
@@ -997,6 +1103,7 @@
 	lwz	r1,GPR1(r1)
 	SYNC
 	rfci
+#endif /* CONFIG_NAND_SPL */
 
 /* Cache functions.
 */
@@ -1238,6 +1345,7 @@
 
 /*------------------------------------------------------------------------------*/
 
+#ifndef CONFIG_NAND_SPL
 /*
  * void relocate_code (addr_sp, gd, addr_moni)
  *
@@ -1251,7 +1359,9 @@
  */
 	.globl	relocate_code
 relocate_code:
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    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.
@@ -1466,22 +1576,22 @@
 	cmplw	0, r7, r8
 	blt	4b
 
-#if !defined(CONFIG_440GX) && !defined(CONFIG_440SPE)
+#if !defined(CONFIG_440)
 	addi	r7,r0,0x1000		/* set ME bit (Machine Exceptions) */
 	oris	r7,r7,0x0002		/* set CE bit (Critical Exceptions) */
 	mtmsr	r7			/* change MSR */
 #else
-	bl	__440gx_msr_set
-	b	__440gx_msr_continue
+	bl	__440_msr_set
+	b	__440_msr_continue
 
-__440gx_msr_set:
+__440_msr_set:
 	addi	r7,r0,0x1000		/* set ME bit (Machine Exceptions) */
 	oris	r7,r7,0x0002		/* set CE bit (Critical Exceptions) */
 	mtspr	srr1,r7
 	mflr	r7
 	mtspr	srr0,r7
 	rfi
-__440gx_msr_continue:
+__440_msr_continue:
 #endif
 
 	mtlr	r4			/* restore link register	*/
@@ -1500,6 +1610,7 @@
 	stw	r0, 4(r7)
 
 	blr
+#endif /* CONFIG_NAND_SPL */
 
 
 /**************************************************************************/
@@ -1587,7 +1698,8 @@
 	mtdcr	ebccfgd,r3
 #endif
 
-	addi	r3,0,CPC0_PCI_HOST_CFG_EN
+#ifndef CFG_CPC0_PCI
+	li	r3,CPC0_PCI_HOST_CFG_EN
 #ifdef CONFIG_BUBINGA
 	/*
 	!-----------------------------------------------------------------------
@@ -1602,6 +1714,9 @@
 	beq	..pci_cfg_set		  /* if not set, then bypass reg write*/
 #endif
 	ori	r3,r3,CPC0_PCI_ARBIT_EN
+#else /* CFG_CPC0_PCI */
+	li	r3,CFG_CPC0_PCI
+#endif /* CFG_CPC0_PCI */
 ..pci_cfg_set:
 	mtdcr	CPC0_PCI, r3		 /* Enable internal arbiter*/
 
diff --git a/cpu/ppc4xx/usb_ohci.c b/cpu/ppc4xx/usb_ohci.c
index bb57658..ab852c5 100644
--- a/cpu/ppc4xx/usb_ohci.c
+++ b/cpu/ppc4xx/usb_ohci.c
@@ -76,7 +76,7 @@
 #define m16_swap(x) swap_16(x)
 #define m32_swap(x) swap_32(x)
 
-#ifdef CONFIG_440EP
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
 #define ohci_cpu_to_le16(x) (x)
 #define ohci_cpu_to_le32(x) (x)
 #else
@@ -1599,7 +1599,11 @@
 	gohci.disabled = 1;
 	gohci.sleeping = 0;
 	gohci.irq = -1;
-	gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#if defined(CONFIG_440EP)
+ 	gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#elif defined(CONFIG_440EPX)
+	gohci.regs = (struct ohci_regs *)(CFG_USB_HOST);
+#endif
 
 	gohci.flags = 0;
 	gohci.slot_name = "ppc440";
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 8262c54..6140d2a 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -3,7 +3,7 @@
 #include <common.h>
 #include <asm/processor.h>
 
-#ifdef CONFIG_440EP
+#if (defined(CONFIG_440EP) || defined(CONFIG_440EPX)) && (CONFIG_COMMANDS & CFG_CMD_USB)
 
 #include <usb.h>
 #include "usbdev.h"
@@ -186,8 +186,23 @@
 	return 0;
 }
 
+#if defined(CONFIG_440EPX)
 void usb_dev_init()
 {
+	printf("USB 2.0 Device init\n");
+
+	/*usb dev init */
+	*(unsigned char *)USB2D0_POWER_8 = 0xa1;	/* 2.0 */
+
+	/*enable interrupts */
+	*(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f;
+
+	irq_install_handler(VECNUM_HSB2D, (interrupt_handler_t *) usbInt,
+			    NULL);
+}
+#else
+void usb_dev_init()
+{
 #ifdef USB_2_0_DEVICE
 	printf("USB 2.0 Device init\n");
 	/*select 2.0 device */
@@ -210,5 +225,6 @@
 	irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,
 			    NULL);
 }
+#endif
 
-#endif				/*CONFIG_440EP */
+#endif /* CONFIG_440EP || CONFIG_440EPX */
diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h
index 93cef02..685d48b 100644
--- a/cpu/ppc4xx/vecnum.h
+++ b/cpu/ppc4xx/vecnum.h
@@ -31,7 +31,94 @@
 #ifndef _VECNUMS_H_
 #define _VECNUMS_H_
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+
+/* UIC 0 */
+#define VECNUM_U0                   0  /* UART 0                        */
+#define VECNUM_U1                   1  /* UART 1                        */
+#define VECNUM_IIC0                 2  /* IIC                           */
+#define VECNUM_KRD                  3  /* Kasumi Ready for data         */
+#define VECNUM_KDA                  4  /* Kasumi Data Available         */
+#define VECNUM_PCRW                 5  /* PCI command register write    */
+#define VECNUM_PPM                  6  /* PCI power management          */
+#define VECNUM_IIC1                 7  /* IIC                           */
+#define VECNUM_SPI                  8  /* SPI                           */
+#define VECNUM_EPCISER              9  /* External PCI SERR             */
+#define VECNUM_MTE                 10  /* MAL TXEOB                     */
+#define VECNUM_MRE                 11  /* MAL RXEOB                     */
+#define VECNUM_D0                  12  /* DMA channel 0                 */
+#define VECNUM_D1                  13  /* DMA channel 1                 */
+#define VECNUM_D2                  14  /* DMA channel 2                 */
+#define VECNUM_D3                  15  /* DMA channel 3                 */
+#define VECNUM_UD0                 16  /* UDMA irq 0                    */
+#define VECNUM_UD1                 17  /* UDMA irq 1                    */
+#define VECNUM_UD2                 18  /* UDMA irq 2                    */
+#define VECNUM_UD3                 19  /* UDMA irq 3                    */
+#define VECNUM_HSB2D               20  /* USB2.0 Device                 */
+#define VECNUM_USBDEV		   20  /* USB 1.1/USB 2.0 Device        */
+#define VECNUM_OHCI1               21  /* USB2.0 Host OHCI irq 1        */
+#define VECNUM_OHCI2               22  /* USB2.0 Host OHCI irq 2        */
+#define VECNUM_EIP94               23  /* Security EIP94                */
+#define VECNUM_ETH0                24  /* Emac 0                        */
+#define VECNUM_ETH1                25  /* Emac 1                        */
+#define VECNUM_EHCI                26  /* USB2.0 Host EHCI              */
+#define VECNUM_EIR4                27  /* External interrupt 4          */
+#define VECNUM_UIC2NC              28  /* UIC2 non-critical interrupt   */
+#define VECNUM_UIC2C               29  /* UIC2 critical interrupt       */
+#define VECNUM_UIC1NC              30  /* UIC1 non-critical interrupt   */
+#define VECNUM_UIC1C               31  /* UIC1 critical interrupt       */
+
+/* UIC 1 */
+#define VECNUM_MS           (32 +  0)  /* MAL SERR                      */
+#define VECNUM_MTDE         (32 +  1)  /* MAL TXDE                      */
+#define VECNUM_MRDE         (32 +  2)  /* MAL RXDE                      */
+#define VECNUM_U2           (32 +  3)  /* UART 2                        */
+#define VECNUM_U3           (32 +  4)  /* UART 3                        */
+#define VECNUM_EBCO         (32 +  5)  /* EBCO interrupt status         */
+#define VECNUM_NDFC         (32 +  6)  /* NDFC                          */
+#define VECNUM_KSLE         (32 +  7)  /* KASUMI slave error            */
+#define VECNUM_CT5          (32 +  8)  /* GPT compare timer 5           */
+#define VECNUM_CT6          (32 +  9)  /* GPT compare timer 6           */
+#define VECNUM_PLB34I0      (32 + 10)  /* PLB3X4X MIRQ0                 */
+#define VECNUM_PLB34I1      (32 + 11)  /* PLB3X4X MIRQ1                 */
+#define VECNUM_PLB34I2      (32 + 12)  /* PLB3X4X MIRQ2                 */
+#define VECNUM_PLB34I3      (32 + 13)  /* PLB3X4X MIRQ3                 */
+#define VECNUM_PLB34I4      (32 + 14)  /* PLB3X4X MIRQ4                 */
+#define VECNUM_PLB34I5      (32 + 15)  /* PLB3X4X MIRQ5                 */
+#define VECNUM_CT0          (32 + 16)  /* GPT compare timer 0           */
+#define VECNUM_CT1          (32 + 17)  /* GPT compare timer 1           */
+#define VECNUM_EIR7         (32 + 18)  /* External interrupt 7          */
+#define VECNUM_EIR8         (32 + 19)  /* External interrupt 8          */
+#define VECNUM_EIR9         (32 + 20)  /* External interrupt 9          */
+#define VECNUM_CT2          (32 + 21)  /* GPT compare timer 2           */
+#define VECNUM_CT3          (32 + 22)  /* GPT compare timer 3           */
+#define VECNUM_CT4          (32 + 23)  /* GPT compare timer 4           */
+#define VECNUM_SRE          (32 + 24)  /* Serial ROM error              */
+#define VECNUM_GPTDC        (32 + 25)  /* GPT decrementer pulse         */
+#define VECNUM_RSVD0        (32 + 26)  /* Reserved                      */
+#define VECNUM_EPCIPER      (32 + 27)  /* External PCI PERR             */
+#define VECNUM_EIR0         (32 + 28)  /* External interrupt 0          */
+#define VECNUM_EWU0         (32 + 29)  /* Ethernet 0 wakeup             */
+#define VECNUM_EIR1         (32 + 30)  /* External interrupt 1          */
+#define VECNUM_EWU1         (32 + 31)  /* Ethernet 1 wakeup             */
+
+#define VECNUM_TXDE         VECNUM_MTDE
+#define VECNUM_RXDE         VECNUM_MRDE
+
+/* UIC 2 */
+#define VECNUM_EIR5         (62 +  0)  /* External interrupt 5          */
+#define VECNUM_EIR6         (62 +  1)  /* External interrupt 6          */
+#define VECNUM_OPB          (62 +  2)  /* OPB to PLB bridge int stat    */
+#define VECNUM_EIR2         (62 +  3)  /* External interrupt 2          */
+#define VECNUM_EIR3         (62 +  4)  /* External interrupt 3          */
+#define VECNUM_DDR2         (62 +  5)  /* DDR2 sdram                    */
+#define VECNUM_MCTX0        (62 +  6)  /* MAl intp coalescence TX0      */
+#define VECNUM_MCTX1        (62 +  7)  /* MAl intp coalescence TX1      */
+#define VECNUM_MCTR0        (62 +  8)  /* MAl intp coalescence TR0      */
+#define VECNUM_MCTR1        (62 +  9)  /* MAl intp coalescence TR1      */
+
+#elif defined(CONFIG_440SPE)
+
 /* UIC 0 */
 #define VECNUM_U0           0           /* UART0                        */
 #define VECNUM_U1           1           /* UART1                        */
diff --git a/cpu/pxa/Makefile b/cpu/pxa/Makefile
index bd476f1..8b4367e 100644
--- a/cpu/pxa/Makefile
+++ b/cpu/pxa/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000, 2002
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o usb.o
+COBJS	= serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o usb.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/s3c44b0/Makefile b/cpu/s3c44b0/Makefile
index d43c73e..790faeb 100644
--- a/cpu/s3c44b0/Makefile
+++ b/cpu/s3c44b0/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= serial.o interrupts.o cpu.o
+COBJS	= serial.o interrupts.o cpu.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################
diff --git a/cpu/sa1100/Makefile b/cpu/sa1100/Makefile
index 8c950da..790faeb 100644
--- a/cpu/sa1100/Makefile
+++ b/cpu/sa1100/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= lib$(CPU).a
+LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-OBJS	= serial.o interrupts.o cpu.o
+COBJS	= serial.o interrupts.o cpu.o
 
-all:	.depend $(START) $(LIB)
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 #########################################################################
 
-.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
-		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-sinclude .depend
+sinclude $(obj).depend
 
 #########################################################################