* Patches by Xianghua Xiao, 15 Oct 2003:

  - Added Motorola CPU 8540/8560 support (cpu/85xx)
  - Added Motorola MPC8540ADS board support (board/mpc8540ads)
  - Added Motorola MPC8560ADS board support (board/mpc8560ads)

* Minor code cleanup
diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile
new file mode 100644
index 0000000..996915e
--- /dev/null
+++ b/cpu/mpc85xx/Makefile
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2002,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 $(TOPDIR)/config.mk
+
+LIB	= lib$(CPU).a
+
+START	= start.o resetvec.o
+COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o tsec.o \
+	  pci.o serial_scc.o commproc.o ether_fcc.o i2c.o spd_sdram.o
+OBJS	= $(COBJS)
+
+all:	.depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend:	Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/mpc85xx/commproc.c b/cpu/mpc85xx/commproc.c
new file mode 100644
index 0000000..df11052
--- /dev/null
+++ b/cpu/mpc85xx/commproc.c
@@ -0,0 +1,214 @@
+/*
+ * Adapted for Motorola MPC8560 chips
+ * Xianghua Xiao <x.xiao@motorola.com>
+ *
+ * This file is based on "arch/ppc/8260_io/commproc.c" - here is it's
+ * copyright notice:
+ *
+ * General Purpose functions for the global management of the
+ * 8220 Communication Processor Module.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
+ * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
+ *	2.3.99 Updates
+ * Copyright (c) 2003 Motorola,Inc.
+ *
+ * In addition to the individual control of the communication
+ * channels, there are a few functions that globally affect the
+ * communication processor.
+ *
+ * Buffer descriptors must be allocated from the dual ported memory
+ * space.  The allocator for that is here.  When the communication
+ * process is reset, we reclaim the memory available.  There is
+ * currently no deallocator for this memory.
+ */
+#include <common.h>
+#include <asm/cpm_85xx.h>
+
+#if defined(CONFIG_MPC8560)
+/*
+ * because we have stack and init data in dual port ram
+ * we must reduce the size
+ */
+#undef	CPM_DATAONLY_SIZE
+#define CPM_DATAONLY_SIZE	((uint)(8 * 1024) - CPM_DATAONLY_BASE)
+
+void
+m8560_cpm_reset(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	volatile ulong count;
+
+	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+	/* Reclaim the DP memory for our use.
+	*/
+	gd->dp_alloc_base = CPM_DATAONLY_BASE;
+	gd->dp_alloc_top = gd->dp_alloc_base + CPM_DATAONLY_SIZE;
+
+	/*
+	 * Reset CPM
+	 */
+	immr->im_cpm.im_cpm_cp.cpcr = CPM_CR_RST;
+	count = 0;
+	do {			/* Spin until command processed		*/
+		__asm__ __volatile__ ("eieio");
+	} while ((immr->im_cpm.im_cpm_cp.cpcr & CPM_CR_FLG) && ++count < 1000000);
+}
+
+/* Allocate some memory from the dual ported ram.
+ * To help protocols with object alignment restrictions, we do that
+ * if they ask.
+ */
+uint
+m8560_cpm_dpalloc(uint size, uint align)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	uint	retloc;
+	uint	align_mask, off;
+	uint	savebase;
+
+	align_mask = align - 1;
+	savebase = gd->dp_alloc_base;
+
+	if ((off = (gd->dp_alloc_base & align_mask)) != 0)
+		gd->dp_alloc_base += (align - off);
+
+	if ((off = size & align_mask) != 0)
+		size += align - off;
+
+	if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top) {
+		gd->dp_alloc_base = savebase;
+		panic("m8560_cpm_dpalloc: ran out of dual port ram!");
+	}
+
+	retloc = gd->dp_alloc_base;
+	gd->dp_alloc_base += size;
+
+	memset((void *)&(immr->im_cpm.im_dprambase[retloc]), 0, size);
+
+	return(retloc);
+}
+
+/* We also own one page of host buffer space for the allocation of
+ * UART "fifos" and the like.
+ */
+uint
+m8560_cpm_hostalloc(uint size, uint align)
+{
+	/* the host might not even have RAM yet - just use dual port RAM */
+	return (m8560_cpm_dpalloc(size, align));
+}
+
+/* Set a baud rate generator.  This needs lots of work.  There are
+ * eight BRGs, which can be connected to the CPM channels or output
+ * as clocks.  The BRGs are in two different block of internal
+ * memory mapped space.
+ * The baud rate clock is the system clock divided by something.
+ * It was set up long ago during the initial boot phase and is
+ * is given to us.
+ * Baud rate clocks are zero-based in the driver code (as that maps
+ * to port numbers).  Documentation uses 1-based numbering.
+ */
+#define BRG_INT_CLK	gd->brg_clk
+#define BRG_UART_CLK	((BRG_INT_CLK + 15) / 16)
+
+/* This function is used by UARTS, or anything else that uses a 16x
+ * oversampled clock.
+ */
+void
+m8560_cpm_setbrg(uint brg, uint rate)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	volatile uint	*bp;
+
+	/* This is good enough to get SMCs running.....
+	*/
+	if (brg < 4) {
+		bp = (uint *)&(immr->im_cpm.im_cpm_brg1.brgc1);
+	}
+	else {
+		bp = (uint *)&(immr->im_cpm.im_cpm_brg2.brgc5);
+		brg -= 4;
+	}
+	bp += brg;
+	*bp = (((((BRG_UART_CLK+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
+}
+
+/* This function is used to set high speed synchronous baud rate
+ * clocks.
+ */
+void
+m8560_cpm_fastbrg(uint brg, uint rate, int div16)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	volatile uint	*bp;
+
+	/* This is good enough to get SMCs running.....
+	*/
+	if (brg < 4) {
+		bp = (uint *)&(immr->im_cpm.im_cpm_brg1.brgc1);
+	}
+	else {
+		bp = (uint *)&(immr->im_cpm.im_cpm_brg2.brgc5);
+		brg -= 4;
+	}
+	bp += brg;
+	*bp = (((((BRG_INT_CLK+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
+	if (div16)
+		*bp |= CPM_BRG_DIV16;
+}
+
+/* This function is used to set baud rate generators using an external
+ * clock source and 16x oversampling.
+ */
+
+void
+m8560_cpm_extcbrg(uint brg, uint rate, uint extclk, int pinsel)
+{
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	volatile uint	*bp;
+
+	if (brg < 4) {
+		bp = (uint *)&(immr->im_cpm.im_cpm_brg1.brgc1);
+	}
+	else {
+		bp = (uint *)&(immr->im_cpm.im_cpm_brg2.brgc5);
+		brg -= 4;
+	}
+	bp += brg;
+	*bp = ((((((extclk/16)+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
+	if (pinsel == 0)
+		*bp |= CPM_BRG_EXTC_CLK3_9;
+	else
+		*bp |= CPM_BRG_EXTC_CLK5_15;
+}
+
+#ifdef CONFIG_POST
+
+void post_word_store (ulong a)
+{
+	volatile ulong *save_addr =
+		(volatile ulong *)(CFG_IMMR + CPM_POST_WORD_ADDR);
+
+	*save_addr = a;
+}
+
+ulong post_word_load (void)
+{
+	volatile ulong *save_addr =
+		(volatile ulong *)(CFG_IMMR + CPM_POST_WORD_ADDR);
+
+	return *save_addr;
+}
+
+#endif	/* CONFIG_POST */
+
+#endif /* CONFIG_MPC8560 */
diff --git a/cpu/mpc85xx/config.mk b/cpu/mpc85xx/config.mk
new file mode 100644
index 0000000..c12e923
--- /dev/null
+++ b/cpu/mpc85xx/config.mk
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2002,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
+#
+
+PLATFORM_RELFLAGS += -mrelocatable -ffixed-r14 -meabi
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx -DCONFIG_E500 -ffixed-r2 -ffixed-r29 -Wa,-me500 -msoft-float
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c
new file mode 100644
index 0000000..64f2782
--- /dev/null
+++ b/cpu/mpc85xx/cpu.c
@@ -0,0 +1,151 @@
+/*
+ * (C) Copyright 2002, 2003 Motorola Inc.
+ * Xianghua Xiao (X.Xiao@motorola.com)
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <asm/cache.h>
+
+/* ------------------------------------------------------------------------- */
+
+int checkcpu (void)
+{
+	uint pir = get_pir();
+	uint pvr = get_pvr();
+
+	printf("Motorola PowerPC ProcessorID=%08x Rev. ",pir);
+	switch(pvr) {
+	default:
+		printf("PVR=%08x", pvr);
+		break;
+	}
+
+	printf("\n");
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+	/*
+	 * Initiate hard reset in debug control register DBCR0
+	 * Make sure MSR[DE] = 1
+	 */
+	__asm__ __volatile__("lis   3, 0x7000" ::: "r3");
+	mtspr(DBCR0,3);
+	return 1;
+}
+
+
+/*
+ * 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)
+{
+	int re_enable = disable_interrupts();
+	reset_85xx_watchdog();
+	if (re_enable) enable_interrupts();
+}
+
+void
+reset_85xx_watchdog(void)
+{
+	/*
+	 * Clear TSR(WIS) bit by writing 1
+	 */
+	unsigned long val;
+	val = mfspr(tsr);
+	val |= 0x40000000;
+	mtspr(tsr, val);
+}
+#endif	/* CONFIG_WATCHDOG */
+
+#if defined(CONFIG_DDR_ECC)
+__inline__ void dcbz(const void* addr)
+{
+	__asm__ __volatile__ ("dcbz 0,%0" :: "r" (addr));
+}
+
+__inline__ void dcbf(const void* addr)
+{
+	__asm__ __volatile__ ("dcbf 0,%0" :: "r" (addr));
+}
+
+void dma_init(void) {
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_dma_t *dma = &immap->im_dma;
+
+	dma->satr0 = 0x02c40000;
+	dma->datr0 = 0x02c40000;
+	asm("sync; isync; msync");
+	return;
+}
+
+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;msync");
+	dma->mr0 = 0xf000005;
+	asm("sync;isync;msync");
+	return dma_check();
+}
+#endif
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
new file mode 100644
index 0000000..3ffd558
--- /dev/null
+++ b/cpu/mpc85xx/cpu_init.c
@@ -0,0 +1,205 @@
+/*
+ * (C) Copyright 2003 Motorola Inc.
+ * Modified by Xianghua Xiao, X.Xiao@motorola.com
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/processor.h>
+#include <ioports.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MPC8560
+static void config_8560_ioports (volatile immap_t * immr)
+{
+	int portnum;
+
+	for (portnum = 0; portnum < 4; portnum++) {
+		uint pmsk = 0,
+		     ppar = 0,
+		     psor = 0,
+		     pdir = 0,
+		     podr = 0,
+		     pdat = 0;
+		iop_conf_t *iopc = (iop_conf_t *) & iop_conf_tab[portnum][0];
+		iop_conf_t *eiopc = iopc + 32;
+		uint msk = 1;
+
+		/*
+		 * NOTE:
+		 * index 0 refers to pin 31,
+		 * index 31 refers to pin 0
+		 */
+		while (iopc < eiopc) {
+			if (iopc->conf) {
+				pmsk |= msk;
+				if (iopc->ppar)
+					ppar |= msk;
+				if (iopc->psor)
+					psor |= msk;
+				if (iopc->pdir)
+					pdir |= msk;
+				if (iopc->podr)
+					podr |= msk;
+				if (iopc->pdat)
+					pdat |= msk;
+			}
+
+			msk <<= 1;
+			iopc++;
+		}
+
+		if (pmsk != 0) {
+			volatile ioport_t *iop = ioport_addr (immr, portnum);
+			uint tpmsk = ~pmsk;
+
+			/*
+			 * the (somewhat confused) paragraph at the
+			 * bottom of page 35-5 warns that there might
+			 * be "unknown behaviour" when programming
+			 * PSORx and PDIRx, if PPARx = 1, so I
+			 * decided this meant I had to disable the
+			 * dedicated function first, and enable it
+			 * last.
+			 */
+			iop->ppar &= tpmsk;
+			iop->psor = (iop->psor & tpmsk) | psor;
+			iop->podr = (iop->podr & tpmsk) | podr;
+			iop->pdat = (iop->pdat & tpmsk) | pdat;
+			iop->pdir = (iop->pdir & tpmsk) | pdir;
+			iop->ppar |= ppar;
+		}
+	}
+}
+#endif
+
+/*
+ * 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;
+	extern void m8560_cpm_reset (void);
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+	/* Clear initial global data */
+	memset ((void *) gd, 0, sizeof (gd_t));
+
+
+#ifdef CONFIG_MPC8560
+	config_8560_ioports(immap);
+#endif
+
+	/* 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(CONFIG_MPC85xx)
+#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
+	memctl->or2 = CFG_OR2_PRELIM;
+	memctl->br2 = CFG_BR2_PRELIM;
+#endif
+#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
+
+#if defined(CONFIG_MPC8560)
+	m8560_cpm_reset();
+#endif
+}
+
+/*
+ * We initialize L2 as cache here.
+ */
+int cpu_init_r (void)
+{
+#if defined(CONFIG_L2_CACHE)
+	volatile immap_t    *immap = (immap_t *)CFG_IMMR;
+	volatile ccsr_l2cache_t *l2cache = &immap->im_l2cache;
+	volatile uint temp;
+
+	asm("msync;isync");
+	l2cache->l2ctl = 0x68000000; /* invalidate */
+	temp = l2cache->l2ctl;
+	asm("msync;isync");
+	l2cache->l2ctl = 0xa8000000; /* enable 256KB L2 cache */
+	temp = l2cache->l2ctl;
+	asm("msync;isync");
+
+	printf("L2 cache enabled: 256KB\n");
+#else
+	printf("L2 cache disabled.\n");
+#endif
+
+	return 0;
+}
diff --git a/cpu/mpc85xx/ether_fcc.c b/cpu/mpc85xx/ether_fcc.c
new file mode 100644
index 0000000..f78e5b4
--- /dev/null
+++ b/cpu/mpc85xx/ether_fcc.c
@@ -0,0 +1,461 @@
+/*
+ * MPC8560 FCC Fast Ethernet
+ * Copyright (c) 2003 Motorola,Inc.
+ * Xianghua Xiao, (X.Xiao@motorola.com)
+ *
+ * Copyright (c) 2000 MontaVista Software, Inc.   Dan Malek (dmalek@jlc.net)
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * MPC8560 FCC Fast Ethernet
+ * Basic ET HW initialization and packet RX/TX routines
+ *
+ * This code will not perform the IO port configuration. This should be
+ * done in the iop_conf_t structure specific for the board.
+ *
+ * TODO:
+ * add a PHY driver to do the negotiation
+ * reflect negotiation results in FPSMR
+ * look for ways to configure the board specific stuff elsewhere, eg.
+ *    config_xxx.h or the board directory
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/cpm_85xx.h>
+#include <command.h>
+#include <config.h>
+#include <net.h>
+
+#if defined(CONFIG_MPC8560)
+
+#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_COMMANDS & CFG_CMD_NET) && \
+	defined(CONFIG_NET_MULTI)
+
+static struct ether_fcc_info_s
+{
+	int ether_index;
+	int proff_enet;
+	ulong cpm_cr_enet_sblock;
+	ulong cpm_cr_enet_page;
+	ulong cmxfcr_mask;
+	ulong cmxfcr_value;
+}
+	ether_fcc_info[] =
+{
+#ifdef CONFIG_ETHER_ON_FCC1
+{
+	0,
+	PROFF_FCC1,
+	CPM_CR_FCC1_SBLOCK,
+	CPM_CR_FCC1_PAGE,
+	CFG_CMXFCR_MASK1,
+	CFG_CMXFCR_VALUE1
+},
+#endif
+
+#ifdef CONFIG_ETHER_ON_FCC2
+{
+	1,
+	PROFF_FCC2,
+	CPM_CR_FCC2_SBLOCK,
+	CPM_CR_FCC2_PAGE,
+	CFG_CMXFCR_MASK2,
+	CFG_CMXFCR_VALUE2
+},
+#endif
+
+#ifdef CONFIG_ETHER_ON_FCC3
+{
+	2,
+	PROFF_FCC3,
+	CPM_CR_FCC3_SBLOCK,
+	CPM_CR_FCC3_PAGE,
+	CFG_CMXFCR_MASK3,
+	CFG_CMXFCR_VALUE3
+},
+#endif
+};
+
+/*---------------------------------------------------------------------*/
+
+/* Maximum input DMA size.  Must be a should(?) be a multiple of 4. */
+#define PKT_MAXDMA_SIZE         1520
+
+/* The FCC stores dest/src/type, data, and checksum for receive packets. */
+#define PKT_MAXBUF_SIZE         1518
+#define PKT_MINBUF_SIZE         64
+
+/* Maximum input buffer size.  Must be a multiple of 32. */
+#define PKT_MAXBLR_SIZE         1536
+
+#define TOUT_LOOP 1000000
+
+#define TX_BUF_CNT 2
+
+static uint rxIdx;	/* index of the current RX buffer */
+static uint txIdx;	/* index of the current TX buffer */
+
+/*
+ * FCC Ethernet Tx and Rx buffer descriptors.
+ * Provide for Double Buffering
+ * Note: PKTBUFSRX is defined in net.h
+ */
+
+typedef volatile struct rtxbd {
+    cbd_t rxbd[PKTBUFSRX];
+    cbd_t txbd[TX_BUF_CNT];
+} RTXBD;
+
+/*  Good news: the FCC supports external BDs! */
+#ifdef __GNUC__
+static RTXBD rtx __attribute__ ((aligned(8)));
+#else
+#error "rtx must be 64-bit aligned"
+#endif
+
+#define ET_DEBUG
+
+static int fec_send(struct eth_device* dev, volatile void *packet, int length)
+{
+    int i = 0;
+    int result = 0;
+
+    if (length <= 0) {
+	printf("fec: bad packet size: %d\n", length);
+	goto out;
+    }
+
+    for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
+	if (i >= TOUT_LOOP) {
+	    printf("fec: tx buffer not ready\n");
+	    goto out;
+	}
+    }
+
+    rtx.txbd[txIdx].cbd_bufaddr = (uint)packet;
+    rtx.txbd[txIdx].cbd_datlen = length;
+    rtx.txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST | \
+			       BD_ENET_TX_TC );
+
+    for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
+	if (i >= TOUT_LOOP) {
+	    printf("fec: tx error\n");
+	    goto out;
+	}
+    }
+
+#ifdef ET_DEBUG
+    printf("cycles: 0x%x txIdx=0x%04x status: 0x%04x\n", i, txIdx,rtx.txbd[txIdx].cbd_sc);
+    printf("packets at 0x%08x, length_in_bytes=0x%x\n",(uint)packet,length);
+    for(i=0;i<(length/16 + 1);i++) {
+	 printf("%08x %08x %08x %08x\n",*((uint *)rtx.txbd[txIdx].cbd_bufaddr+i*4),\
+    *((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 1),*((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 2), \
+    *((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 3));
+    }
+#endif
+
+    /* return only status bits */
+    result = rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_STATS;
+    txIdx = (txIdx + 1) % TX_BUF_CNT;
+
+out:
+    return result;
+}
+
+static int fec_recv(struct eth_device* dev)
+{
+    int length;
+
+    for (;;)
+    {
+	if (rtx.rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+	    length = -1;
+	    break;     /* nothing received - leave for() loop */
+	}
+	length = rtx.rxbd[rxIdx].cbd_datlen;
+
+	if (rtx.rxbd[rxIdx].cbd_sc & 0x003f) {
+	    printf("fec: rx error %04x\n", rtx.rxbd[rxIdx].cbd_sc);
+	}
+	else {
+	    /* Pass the packet up to the protocol layers. */
+	    NetReceive(NetRxPackets[rxIdx], length - 4);
+	}
+
+
+	/* Give the buffer back to the FCC. */
+	rtx.rxbd[rxIdx].cbd_datlen = 0;
+
+	/* wrap around buffer index when necessary */
+	if ((rxIdx + 1) >= PKTBUFSRX) {
+	    rtx.rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+	    rxIdx = 0;
+	}
+	else {
+	    rtx.rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+	    rxIdx++;
+	}
+    }
+    return length;
+}
+
+
+static int fec_init(struct eth_device* dev, bd_t *bis)
+{
+    struct ether_fcc_info_s * info = dev->priv;
+    int i;
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+    volatile ccsr_cpm_cp_t *cp = &(immr->im_cpm.im_cpm_cp);
+    fcc_enet_t *pram_ptr;
+    unsigned long mem_addr;
+
+#if 0
+    mii_discover_phy();
+#endif
+
+    /* 28.9 - (1-2): ioports have been set up already */
+
+    /* 28.9 - (3): connect FCC's tx and rx clocks */
+    immr->im_cpm.im_cpm_mux.cmxuar = 0; /* ATM */
+    immr->im_cpm.im_cpm_mux.cmxfcr = (immr->im_cpm.im_cpm_mux.cmxfcr & ~info->cmxfcr_mask) |
+							info->cmxfcr_value;
+
+    /* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, set Mode Ethernet */
+    if(info->ether_index == 0) {
+	immr->im_cpm.im_cpm_fcc1.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
+    } else if (info->ether_index == 1) {
+	immr->im_cpm.im_cpm_fcc2.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
+    } else if (info->ether_index == 2) {
+	immr->im_cpm.im_cpm_fcc3.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
+    }
+
+    /* 28.9 - (5): FPSMR: enable full duplex, select CCITT CRC for Ethernet,MII */
+    if(info->ether_index == 0) {
+	immr->im_cpm.im_cpm_fcc1.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
+    } else if (info->ether_index == 1){
+	immr->im_cpm.im_cpm_fcc2.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
+    } else if (info->ether_index == 2){
+	immr->im_cpm.im_cpm_fcc3.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
+    }
+
+    /* 28.9 - (6): FDSR: Ethernet Syn */
+    if(info->ether_index == 0) {
+	immr->im_cpm.im_cpm_fcc1.fdsr = 0xD555;
+    } else if (info->ether_index == 1) {
+	immr->im_cpm.im_cpm_fcc2.fdsr = 0xD555;
+    } else if (info->ether_index == 2) {
+	immr->im_cpm.im_cpm_fcc3.fdsr = 0xD555;
+    }
+
+    /* reset indeces to current rx/tx bd (see eth_send()/eth_rx()) */
+    rxIdx = 0;
+    txIdx = 0;
+
+    /* Setup Receiver Buffer Descriptors */
+    for (i = 0; i < PKTBUFSRX; i++)
+    {
+      rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+      rtx.rxbd[i].cbd_datlen = 0;
+      rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
+    }
+    rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+    /* Setup Ethernet Transmitter Buffer Descriptors */
+    for (i = 0; i < TX_BUF_CNT; i++)
+    {
+      rtx.txbd[i].cbd_sc = 0;
+      rtx.txbd[i].cbd_datlen = 0;
+      rtx.txbd[i].cbd_bufaddr = 0;
+    }
+    rtx.txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+    /* 28.9 - (7): initialize parameter ram */
+    pram_ptr = (fcc_enet_t *)&(immr->im_cpm.im_dprambase[info->proff_enet]);
+
+    /* clear whole structure to make sure all reserved fields are zero */
+    memset((void*)pram_ptr, 0, sizeof(fcc_enet_t));
+
+    /*
+     * common Parameter RAM area
+     *
+     * Allocate space in the reserved FCC area of DPRAM for the
+     * internal buffers.  No one uses this space (yet), so we
+     * can do this.  Later, we will add resource management for
+     * this area. CPM_FCC_SPECIAL_BASE: 0xb000.
+     */
+    mem_addr = CPM_FCC_SPECIAL_BASE + ((info->ether_index) * 64);
+    pram_ptr->fen_genfcc.fcc_riptr = mem_addr;
+    pram_ptr->fen_genfcc.fcc_tiptr = mem_addr+32;
+    /*
+     * Set maximum bytes per receive buffer.
+     * It must be a multiple of 32.
+     */
+    pram_ptr->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; /* 1536 */
+    /* localbus SDRAM should be preferred */
+    pram_ptr->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB |
+				       CFG_CPMFCR_RAMTYPE) << 24;
+    pram_ptr->fen_genfcc.fcc_rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
+    pram_ptr->fen_genfcc.fcc_rbdstat = 0;
+    pram_ptr->fen_genfcc.fcc_rbdlen = 0;
+    pram_ptr->fen_genfcc.fcc_rdptr = 0;
+    /* localbus SDRAM should be preferred */
+    pram_ptr->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB |
+				       CFG_CPMFCR_RAMTYPE) << 24;
+    pram_ptr->fen_genfcc.fcc_tbase = (unsigned int)(&rtx.txbd[txIdx]);
+    pram_ptr->fen_genfcc.fcc_tbdstat = 0;
+    pram_ptr->fen_genfcc.fcc_tbdlen = 0;
+    pram_ptr->fen_genfcc.fcc_tdptr = 0;
+
+    /* protocol-specific area */
+    pram_ptr->fen_statbuf = 0x0;
+    pram_ptr->fen_cmask = 0xdebb20e3;	/* CRC mask */
+    pram_ptr->fen_cpres = 0xffffffff;	/* CRC preset */
+    pram_ptr->fen_crcec = 0;
+    pram_ptr->fen_alec = 0;
+    pram_ptr->fen_disfc = 0;
+    pram_ptr->fen_retlim = 15;		/* Retry limit threshold */
+    pram_ptr->fen_retcnt = 0;
+    pram_ptr->fen_pper = 0;
+    pram_ptr->fen_boffcnt = 0;
+    pram_ptr->fen_gaddrh = 0;
+    pram_ptr->fen_gaddrl = 0;
+    pram_ptr->fen_mflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
+    /*
+     * Set Ethernet station address.
+     *
+     * This is supplied in the board information structure, so we
+     * copy that into the controller.
+     * So far we have only been given one Ethernet address. We make
+     * it unique by setting a few bits in the upper byte of the
+     * non-static part of the address.
+     */
+#define ea eth_get_dev()->enetaddr
+    pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
+    pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
+    pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
+#undef ea
+    pram_ptr->fen_ibdcount = 0;
+    pram_ptr->fen_ibdstart = 0;
+    pram_ptr->fen_ibdend = 0;
+    pram_ptr->fen_txlen = 0;
+    pram_ptr->fen_iaddrh = 0;  /* disable hash */
+    pram_ptr->fen_iaddrl = 0;
+    pram_ptr->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register: 64 */
+    /* pad pointer. use tiptr since we don't need a specific padding char */
+    pram_ptr->fen_padptr = pram_ptr->fen_genfcc.fcc_tiptr;
+    pram_ptr->fen_maxd1 = PKT_MAXDMA_SIZE;	/* maximum DMA1 length:1520 */
+    pram_ptr->fen_maxd2 = PKT_MAXDMA_SIZE;	/* maximum DMA2 length:1520 */
+
+#if defined(ET_DEBUG)
+    printf("parm_ptr(0xff788500) = %p\n",pram_ptr);
+    printf("pram_ptr->fen_genfcc.fcc_rbase %08x\n",
+	pram_ptr->fen_genfcc.fcc_rbase);
+    printf("pram_ptr->fen_genfcc.fcc_tbase %08x\n",
+	pram_ptr->fen_genfcc.fcc_tbase);
+#endif
+
+    /* 28.9 - (8)(9): clear out events in FCCE */
+    /* 28.9 - (9): FCCM: mask all events */
+    if(info->ether_index == 0) {
+	immr->im_cpm.im_cpm_fcc1.fcce = ~0x0;
+	immr->im_cpm.im_cpm_fcc1.fccm = 0;
+    } else if (info->ether_index == 1) {
+	immr->im_cpm.im_cpm_fcc2.fcce = ~0x0;
+	immr->im_cpm.im_cpm_fcc2.fccm = 0;
+    } else if (info->ether_index == 2) {
+	immr->im_cpm.im_cpm_fcc3.fcce = ~0x0;
+	immr->im_cpm.im_cpm_fcc3.fccm = 0;
+    }
+
+    /* 28.9 - (10-12): we don't use ethernet interrupts */
+
+    /* 28.9 - (13)
+     *
+     * Let's re-initialize the channel now.  We have to do it later
+     * than the manual describes because we have just now finished
+     * the BD initialization.
+     */
+    cp->cpcr = mk_cr_cmd(info->cpm_cr_enet_page,
+			    info->cpm_cr_enet_sblock,
+			    0x0c,
+			    CPM_CR_INIT_TRX) | CPM_CR_FLG;
+    do {
+	__asm__ __volatile__ ("eieio");
+    } while (cp->cpcr & CPM_CR_FLG);
+
+    /* 28.9 - (14): enable tx/rx in gfmr */
+    if(info->ether_index == 0) {
+	immr->im_cpm.im_cpm_fcc1.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
+    } else if (info->ether_index == 1) {
+	immr->im_cpm.im_cpm_fcc2.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
+    } else if (info->ether_index == 2) {
+	immr->im_cpm.im_cpm_fcc3.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
+    }
+
+    return 0;
+}
+
+static void fec_halt(struct eth_device* dev)
+{
+    struct ether_fcc_info_s * info = dev->priv;
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+    /* write GFMR: disable tx/rx */
+    if(info->ether_index == 0) {
+	immr->im_cpm.im_cpm_fcc1.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
+    } else if(info->ether_index == 1) {
+	immr->im_cpm.im_cpm_fcc2.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
+    } else if(info->ether_index == 2) {
+	immr->im_cpm.im_cpm_fcc3.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
+    }
+}
+
+int fec_initialize(bd_t *bis)
+{
+	struct eth_device* dev;
+	int i;
+
+	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
+	{
+		dev = (struct eth_device*) malloc(sizeof *dev);
+		memset(dev, 0, sizeof *dev);
+
+		sprintf(dev->name, "FCC%d ETHERNET",
+			ether_fcc_info[i].ether_index + 1);
+		dev->priv   = &ether_fcc_info[i];
+		dev->init   = fec_init;
+		dev->halt   = fec_halt;
+		dev->send   = fec_send;
+		dev->recv   = fec_recv;
+
+		eth_register(dev);
+	}
+
+	return 1;
+}
+
+#endif	/* CONFIG_ETHER_ON_FCC && CFG_CMD_NET && CONFIG_NET_MULTI */
+
+#endif /* CONFIG_MPC8560 */
diff --git a/cpu/mpc85xx/i2c.c b/cpu/mpc85xx/i2c.c
new file mode 100644
index 0000000..ae08d18
--- /dev/null
+++ b/cpu/mpc85xx/i2c.c
@@ -0,0 +1,288 @@
+/*
+ * (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>
+
+#define DEBUG
+
+#if defined(DEBUG)
+#define DEB(x)      x
+#else
+#define DEB(x)
+#endif
+
+#ifdef CONFIG_HARD_I2C
+#include <i2c.h>
+
+#define TIMEOUT (CFG_HZ/4)
+
+#define I2C_Addr ((unsigned *)(CFG_CCSRBAR + 0x3000))
+
+#define I2CADR  &I2C_Addr[0]
+#define I2CFDR  &I2C_Addr[1]
+#define I2CCCR  &I2C_Addr[2]
+#define I2CCSR  &I2C_Addr[3]
+#define I2CCDR  &I2C_Addr[4]
+#define I2CDFSRR &I2C_Addr[5]
+
+#define I2C_READ  1
+#define I2C_WRITE 0
+
+/* taken from linux include/asm-ppc/io.h */
+inline unsigned in_le32(volatile unsigned *addr)
+{
+  unsigned ret;
+
+  __asm__ __volatile__("lwbrx %0,0,%1;\n"
+		       "twi 0,%0,0;\n"
+		       "isync" : "=r" (ret) :
+		       "r" (addr), "m" (*addr));
+  return ret;
+}
+
+inline void out_le32(volatile unsigned *addr, int val)
+{
+  __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
+		       "r" (val), "r" (addr));
+}
+
+#define writel(val, addr) out_le32(addr, val)
+#define readl(addr) in_le32(addr)
+
+void
+i2c_init(int speed, int slaveadd)
+{
+  /* stop I2C controller */
+  writel (0x0, I2CCCR);
+  /* set clock */
+  writel (0x3f, I2CFDR);
+  /* set default filter */
+  writel (0x10,I2CDFSRR);
+  /* write slave address */
+  writel (slaveadd, I2CADR);
+  /* clear status register */
+  writel (0x0, I2CCSR);
+  /* start I2C controller */
+  writel (MPC85xx_I2CCR_MEN, I2CCCR);
+}
+
+static __inline__ int
+i2c_wait4bus (void)
+{
+  ulong timeval = get_timer (0);
+
+  while (readl (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  = readl (I2CCSR);
+
+      if (!(csr & MPC85xx_I2CSR_MIF))
+	continue;
+
+      writel (0x0, I2CCSR);
+
+      if (csr & MPC85xx_I2CSR_MAL)
+	{
+	  DEB(printf ("i2c_wait: MAL\n"));
+	  return -1;
+	}
+
+      if (!(csr & MPC85xx_I2CSR_MCF))
+	{
+	  DEB(printf ("i2c_wait: unfinished\n"));
+	  return -1;
+	}
+
+      if (write == I2C_WRITE && (csr & MPC85xx_I2CSR_RXAK))
+	{
+	  DEB(printf ("i2c_wait: No RXACK\n"));
+	  return -1;
+	}
+
+      return 0;
+    } while (get_timer (timeval) < TIMEOUT);
+
+  DEB(printf ("i2c_wait: timed out\n"));
+  return -1;
+}
+
+static __inline__ int
+i2c_write_addr (u8 dev, u8 dir, int rsta)
+{
+  writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX |
+	  (rsta?MPC85xx_I2CCR_RSTA:0), I2CCCR);
+
+  writel ((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;
+
+  writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX, I2CCCR);
+
+  for (i=0; i < length; i++)
+    {
+      writel (data[i], I2CCDR);
+
+      if (i2c_wait (I2C_WRITE) < 0)
+	break;
+    }
+
+  return i;
+}
+
+static __inline__ int
+__i2c_read (u8 *data, int length)
+{
+  int i;
+
+  writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
+	  ((length == 1) ? MPC85xx_I2CCR_TXAK : 0), I2CCCR);
+
+  /* dummy read */
+  readl (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)
+	writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
+		MPC85xx_I2CCR_TXAK, I2CCCR);
+
+      /* Generate stop on last byte */
+      if (i == length - 1)
+	writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_TXAK, I2CCCR);
+
+      data[i] = readl (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:
+  writel (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:
+  writel (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, (char *)&tmp, 1);
+}
+
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
+{
+	char 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/interrupts.c b/cpu/mpc85xx/interrupts.c
new file mode 100644
index 0000000..745b3b2
--- /dev/null
+++ b/cpu/mpc85xx/interrupts.c
@@ -0,0 +1,138 @@
+/*
+ * (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)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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/processor.h>
+#include <ppc_asm.tmpl>
+
+unsigned decrementer_count;		/* count value for 1e6/HZ microseconds */
+
+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));
+	asm volatile("isync");
+}
+
+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);
+}
+
+/* interrupt is not supported yet */
+int interrupt_init (void)
+{
+	return (0);
+}
+
+/*
+ * Install and free a interrupt handler. Not implemented yet.
+ */
+
+void
+irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+	return;
+}
+
+void
+irq_free_handler(int vec)
+{
+	return;
+}
+
+/****************************************************************************/
+
+
+volatile ulong timestamp = 0;
+
+/*
+ * timer_interrupt - gets called when the decrementer overflows,
+ * with interrupts disabled.
+ * Trivial implementation - no need to be really accurate.
+ */
+void timer_interrupt(struct pt_regs *regs)
+{
+	printf ("*** Timer Interrupt *** ");
+	timestamp++;
+
+#if defined(CONFIG_WATCHDOG)
+	if ((timestamp % 1000) == 0)
+		reset_85xx_watchdog();
+#endif /* CONFIG_WATCHDOG */
+}
+
+void reset_timer (void)
+{
+	timestamp = 0;
+}
+
+ulong get_timer (ulong base)
+{
+	return (timestamp - base);
+}
+
+void set_timer (ulong t)
+{
+	timestamp = t;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
+
+/*******************************************************************************
+ *
+ * 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;
+}
+
+#endif  /* CONFIG_COMMANDS & CFG_CMD_IRQ */
diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c
new file mode 100644
index 0000000..5732c29
--- /dev/null
+++ b/cpu/mpc85xx/pci.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 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
+ */
+
+/*
+ * PCI Configuration space access support for MPC85xx PCI Bridge
+ */
+#include <common.h>
+#include <asm/cpm_85xx.h>
+#include <pci.h>
+
+#if defined(CONFIG_PCI)
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc85xxads_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_IDSEL_NUMBER, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ }
+};
+#endif
+
+struct pci_controller local_hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_mpc85xxads_config_table,
+#endif
+};
+
+void pci_init_board(void)
+{
+    struct pci_controller* hose = (struct pci_controller *)&local_hose;
+    volatile immap_t    *immap = (immap_t *)CFG_CCSRBAR;
+    volatile ccsr_pcix_t *pcix = &immap->im_pcix;
+
+    u16 reg16;
+
+    hose->first_busno = 0;
+    hose->last_busno = 0xff;
+
+    pci_set_region(hose->regions + 0,
+	CFG_PCI_MEM_BASE,
+	CFG_PCI_MEM_PHYS,
+	(CFG_PCI_MEM_SIZE/2),
+	PCI_REGION_MEM);
+
+    pci_set_region(hose->regions + 1,
+	(CFG_PCI_MEM_BASE+0x08000000),
+	(CFG_PCI_MEM_PHYS+0x08000000),
+	0x1000000, /* 16M */
+	PCI_REGION_IO);
+
+    hose->region_count = 2;
+
+    pci_setup_indirect(hose,
+	(CFG_IMMR+0x8000),
+	(CFG_IMMR+0x8004));
+
+    pci_register_hose(hose);
+
+    hose->last_busno = pci_hose_scan(hose);
+
+    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);
+
+    /* 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);
+
+    pcix->potar1   = (CFG_PCI_MEM_BASE >> 12) & 0x000fffff;
+    pcix->potear1  = 0x00000000;
+    pcix->powbar1  = (CFG_PCI_MEM_BASE >> 12) & 0x000fffff;
+    pcix->powbear1 = 0x00000000;
+    pcix->powar1   = 0x8004401a; /* 128M MEM space */
+    pcix->potar2   = ((CFG_PCI_MEM_BASE + 0x08000000) >> 12)  & 0x000fffff;
+    pcix->potear2  = 0x00000000;
+    pcix->powbar2  = ((CFG_PCI_MEM_BASE + 0x08000000) >> 12) && 0x000fffff;
+    pcix->powbear2 = 0x00000000;
+    pcix->powar2   = 0x80088017; /* 16M IO  space */
+    pcix->pitar1 = 0x00000000;
+    pcix->piwbar1 = 0x00000000;
+    pcix->piwar1 = 0xa0F5501f;
+
+}
+#endif /* CONFIG_PCI */
diff --git a/cpu/mpc85xx/resetvec.S b/cpu/mpc85xx/resetvec.S
new file mode 100644
index 0000000..29555d4
--- /dev/null
+++ b/cpu/mpc85xx/resetvec.S
@@ -0,0 +1,2 @@
+	.section .resetvec,"ax"
+	b _start_e500
diff --git a/cpu/mpc85xx/serial_scc.c b/cpu/mpc85xx/serial_scc.c
new file mode 100644
index 0000000..ea82761
--- /dev/null
+++ b/cpu/mpc85xx/serial_scc.c
@@ -0,0 +1,274 @@
+/*
+ * (C) Copyright 2003 Motorola Inc.
+ * Xianghua Xiao (X.Xiao@motorola.com)
+ * Modified based on 8260 for 8560.
+ *
+ * (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
+ *
+ * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00.
+ */
+
+/*
+ * Minimal serial functions needed to use one of the SCC ports
+ * as serial console interface.
+ */
+
+#include <common.h>
+#include <asm/cpm_85xx.h>
+
+#if defined(CONFIG_MPC8560)
+#if defined(CONFIG_CONS_ON_SCC)
+
+#if CONFIG_CONS_INDEX == 1	/* Console on SCC1 */
+
+#define SCC_INDEX		0
+#define PROFF_SCC		PROFF_SCC1
+#define CMXSCR_MASK		(CMXSCR_GR1|CMXSCR_SC1|\
+					CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK)
+#define CMXSCR_VALUE		(CMXSCR_RS1CS_BRG1|CMXSCR_TS1CS_BRG1)
+#define CPM_CR_SCC_PAGE		CPM_CR_SCC1_PAGE
+#define CPM_CR_SCC_SBLOCK	CPM_CR_SCC1_SBLOCK
+
+#elif CONFIG_CONS_INDEX == 2	/* Console on SCC2 */
+
+#define SCC_INDEX		1
+#define PROFF_SCC		PROFF_SCC2
+#define CMXSCR_MASK		(CMXSCR_GR2|CMXSCR_SC2|\
+					CMXSCR_RS2CS_MSK|CMXSCR_TS2CS_MSK)
+#define CMXSCR_VALUE		(CMXSCR_RS2CS_BRG2|CMXSCR_TS2CS_BRG2)
+#define CPM_CR_SCC_PAGE		CPM_CR_SCC2_PAGE
+#define CPM_CR_SCC_SBLOCK	CPM_CR_SCC2_SBLOCK
+
+#elif CONFIG_CONS_INDEX == 3	/* Console on SCC3 */
+
+#define SCC_INDEX		2
+#define PROFF_SCC		PROFF_SCC3
+#define CMXSCR_MASK		(CMXSCR_GR3|CMXSCR_SC3|\
+					CMXSCR_RS3CS_MSK|CMXSCR_TS3CS_MSK)
+#define CMXSCR_VALUE		(CMXSCR_RS3CS_BRG3|CMXSCR_TS3CS_BRG3)
+#define CPM_CR_SCC_PAGE		CPM_CR_SCC3_PAGE
+#define CPM_CR_SCC_SBLOCK	CPM_CR_SCC3_SBLOCK
+
+#elif CONFIG_CONS_INDEX == 4	/* Console on SCC4 */
+
+#define SCC_INDEX		3
+#define PROFF_SCC		PROFF_SCC4
+#define CMXSCR_MASK		(CMXSCR_GR4|CMXSCR_SC4|\
+					CMXSCR_RS4CS_MSK|CMXSCR_TS4CS_MSK)
+#define CMXSCR_VALUE		(CMXSCR_RS4CS_BRG4|CMXSCR_TS4CS_BRG4)
+#define CPM_CR_SCC_PAGE		CPM_CR_SCC4_PAGE
+#define CPM_CR_SCC_SBLOCK	CPM_CR_SCC4_SBLOCK
+
+#else
+
+#error "console not correctly defined"
+
+#endif
+
+int serial_init (void)
+{
+	volatile immap_t *im = (immap_t *)CFG_IMMR;
+	volatile ccsr_cpm_scc_t *sp;
+	volatile scc_uart_t *up;
+	volatile cbd_t *tbdf, *rbdf;
+	volatile ccsr_cpm_cp_t *cp = &(im->im_cpm.im_cpm_cp);
+	uint	dpaddr;
+
+	/* initialize pointers to SCC */
+
+	sp = (ccsr_cpm_scc_t *) &(im->im_cpm.im_cpm_scc[SCC_INDEX]);
+	up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
+
+	/* Disable transmitter/receiver.
+	*/
+	sp->gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	/* put the SCC channel into NMSI (non multiplexd serial interface)
+	 * mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15).
+	 */
+	im->im_cpm.im_cpm_mux.cmxscr = \
+		(im->im_cpm.im_cpm_mux.cmxscr&~CMXSCR_MASK)|CMXSCR_VALUE;
+
+	/* Set up the baud rate generator.
+	*/
+	serial_setbrg ();
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	 * damm: allocating space after the two buffers for rx/tx data
+	 */
+
+	dpaddr = m8560_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16);
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+	rbdf = (cbd_t *)&(im->im_cpm.im_dprambase[dpaddr]);
+	rbdf->cbd_bufaddr = (uint) (rbdf+2);
+	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+	tbdf = rbdf + 1;
+	tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
+	tbdf->cbd_sc = BD_SC_WRAP;
+
+	/* Set up the uart parameters in the parameter ram.
+	*/
+	up->scc_genscc.scc_rbase = dpaddr;
+	up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
+	up->scc_genscc.scc_rfcr = CPMFCR_EB;
+	up->scc_genscc.scc_tfcr = CPMFCR_EB;
+	up->scc_genscc.scc_mrblr = 1;
+	up->scc_maxidl = 0;
+	up->scc_brkcr = 1;
+	up->scc_parec = 0;
+	up->scc_frmec = 0;
+	up->scc_nosec = 0;
+	up->scc_brkec = 0;
+	up->scc_uaddr1 = 0;
+	up->scc_uaddr2 = 0;
+	up->scc_toseq = 0;
+	up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000;
+	up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000;
+	up->scc_rccm = 0xc0ff;
+
+	/* Mask all interrupts and remove anything pending.
+	*/
+	sp->sccm = 0;
+	sp->scce = 0xffff;
+
+	/* Set 8 bit FIFO, 16 bit oversampling and UART mode.
+	*/
+	sp->gsmrh = SCC_GSMRH_RFW;	/* 8 bit FIFO */
+	sp->gsmrl = \
+		SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART;
+
+	/* Set CTS no flow control, 1 stop bit, 8 bit character length,
+	 * normal async UART mode, no parity
+	 */
+	sp->psmr = SCU_PSMR_CL;
+
+	/* execute the "Init Rx and Tx params" CP command.
+	*/
+
+	while (cp->cpcr & CPM_CR_FLG)  /* wait if cp is busy */
+	  ;
+
+	cp->cpcr = mk_cr_cmd(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK,
+					0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+	while (cp->cpcr & CPM_CR_FLG)  /* wait if cp is busy */
+	  ;
+
+	/* Enable transmitter/receiver.
+	*/
+	sp->gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT;
+
+	return (0);
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_CONS_USE_EXTC)
+	m8560_cpm_extcbrg(SCC_INDEX, gd->baudrate,
+		CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL);
+#else
+	m8560_cpm_setbrg(SCC_INDEX, gd->baudrate);
+#endif
+}
+
+void
+serial_putc(const char c)
+{
+	volatile scc_uart_t	*up;
+	volatile cbd_t		*tbdf;
+	volatile immap_t	*im;
+
+	if (c == '\n')
+		serial_putc ('\r');
+
+	im = (immap_t *)CFG_IMMR;
+	up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
+	tbdf = (cbd_t *)&(im->im_cpm.im_dprambase[up->scc_genscc.scc_tbase]);
+
+	/* Wait for last character to go.
+	 */
+	while (tbdf->cbd_sc & BD_SC_READY)
+		;
+
+	/* Load the character into the transmit buffer.
+	 */
+	*(volatile char *)tbdf->cbd_bufaddr = c;
+	tbdf->cbd_datlen = 1;
+	tbdf->cbd_sc |= BD_SC_READY;
+}
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
+
+int
+serial_getc(void)
+{
+	volatile cbd_t		*rbdf;
+	volatile scc_uart_t	*up;
+	volatile immap_t	*im;
+	unsigned char		c;
+
+	im = (immap_t *)CFG_IMMR;
+	up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
+	rbdf = (cbd_t *)&(im->im_cpm.im_dprambase[up->scc_genscc.scc_rbase]);
+
+	/* Wait for character to show up.
+	 */
+	while (rbdf->cbd_sc & BD_SC_EMPTY)
+		;
+
+	/* Grab the char and clear the buffer again.
+	 */
+	c = *(volatile unsigned char *)rbdf->cbd_bufaddr;
+	rbdf->cbd_sc |= BD_SC_EMPTY;
+
+	return (c);
+}
+
+int
+serial_tstc()
+{
+	volatile cbd_t		*rbdf;
+	volatile scc_uart_t	*up;
+	volatile immap_t	*im;
+
+	im = (immap_t *)CFG_IMMR;
+	up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
+	rbdf = (cbd_t *)&(im->im_cpm.im_dprambase[up->scc_genscc.scc_rbase]);
+
+	return ((rbdf->cbd_sc & BD_SC_EMPTY) == 0);
+}
+
+#endif	/* CONFIG_CONS_ON_SCC */
+
+#endif /* CONFIG_MPC8560 */
diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c
new file mode 100644
index 0000000..ccd06e9
--- /dev/null
+++ b/cpu/mpc85xx/spd_sdram.c
@@ -0,0 +1,308 @@
+/*
+ * (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>
+
+#ifdef CONFIG_SPD_EEPROM
+
+#undef DEBUG
+
+#if defined(DEBUG)
+#define DEB(x)      x
+#else
+#define DEB(x)
+#endif
+
+#define ns2clk(ns) ((ns) / (2000000000 /get_bus_freq(0) + 1))
+
+long int spd_sdram(void) {
+    	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+    	volatile ccsr_ddr_t *ddr = &immap->im_ddr;
+	volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm;
+    	spd_eeprom_t spd;
+    	unsigned int memsize,tmp,tmp1,tmp2;
+	unsigned char caslat;
+
+    	i2c_read (SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
+
+	if ( spd.nrows > 2 ) {
+		printf("DDR:Only two chip selects are supported on ADS.\n");
+		return 0;
+	}
+
+	if ( spd.nrow_addr < 12 || spd.nrow_addr > 14 || spd.ncol_addr < 8 || spd.ncol_addr > 11) {
+		printf("DDR:Row or Col number unsupported.\n");
+		return 0;
+	}
+
+	ddr->cs0_bnds = ((spd.row_dens>>2) - 1);
+	ddr->cs0_config = ( 1<<31 | (spd.nrow_addr-12)<<8 | (spd.ncol_addr-8) );
+	DEB(printf("\n"));
+	DEB(printf("cs0_bnds = 0x%08x\n",ddr->cs0_bnds));
+	DEB(printf("cs0_config = 0x%08x\n",ddr->cs0_config));
+	if ( spd.nrows == 2 ) {
+		ddr->cs1_bnds = ((spd.row_dens<<14) | ((spd.row_dens>>1) - 1));
+		ddr->cs1_config = ( 1<<31 | (spd.nrow_addr-12)<<8 | (spd.ncol_addr-8) );
+		DEB(printf("cs1_bnds = 0x%08x\n",ddr->cs1_bnds));
+		DEB(printf("cs1_config = 0x%08x\n",ddr->cs1_config));
+	}
+
+	memsize = spd.nrows * (4 * spd.row_dens);
+	if( spd.mem_type == 0x07 ) {
+		printf("DDR module detected, total size:%dMB.\n",memsize);
+	} else {
+		printf("No DDR module found!\n");
+		return 0;
+	}
+
+	switch(memsize) {
+		case 16:
+			tmp = 7;     /* TLB size */
+			tmp1 = 1;    /* TLB entry number */
+			tmp2 = 23;   /* Local Access Window size */
+			break;
+		case 32:
+			tmp = 7;
+			tmp1 = 2;
+			tmp2 = 24;
+			break;
+		case 64:
+			tmp = 8;
+			tmp1 = 1;
+			tmp2 = 25;
+			break;
+		case 128:
+			tmp = 8;
+			tmp1 = 2;
+			tmp2 = 26;
+			break;
+		case 256:
+			tmp = 9;
+			tmp1 = 1;
+			tmp2 = 27;
+			break;
+		case 512:
+			tmp = 9;
+			tmp1 = 2;
+			tmp2 = 28;
+			break;
+		case 1024:
+			tmp = 10;
+			tmp1 = 1;
+			tmp2 = 29;
+			break;
+		default:
+			printf("DDR:we only added support 16M,32M,64M,128M,256M,512M and 1G DDR I.\n");
+			return 0;
+			break;
+	}
+
+	/* configure DDR TLB to TLB1 Entry 4,5 */
+	mtspr(MAS0, TLB1_MAS0(1,4,0));
+	mtspr(MAS1, TLB1_MAS1(1,1,0,0,tmp));
+	mtspr(MAS2, TLB1_MAS2(((CFG_DDR_SDRAM_BASE>>12) & 0xfffff),0,0,0,0,0,0,0,0));
+	mtspr(MAS3, TLB1_MAS3(((CFG_DDR_SDRAM_BASE>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1));
+	asm volatile("isync;msync;tlbwe;isync");
+	DEB(printf("DDR:MAS0=0x%08x\n",TLB1_MAS0(1,4,0)));
+	DEB(printf("DDR:MAS1=0x%08x\n",TLB1_MAS1(1,1,0,0,tmp)));
+	DEB(printf("DDR:MAS2=0x%08x\n",TLB1_MAS2(((CFG_DDR_SDRAM_BASE>>12) \
+		& 0xfffff),0,0,0,0,0,0,0,0)));
+	DEB(printf("DDR:MAS3=0x%08x\n",TLB1_MAS3(((CFG_DDR_SDRAM_BASE>>12) \
+		& 0xfffff),0,0,0,0,0,1,0,1,0,1)));
+
+	if(tmp1 == 2) {
+		mtspr(MAS0, TLB1_MAS0(1,5,0));
+		mtspr(MAS1, TLB1_MAS1(1,1,0,0,tmp));
+		mtspr(MAS2, TLB1_MAS2((((CFG_DDR_SDRAM_BASE+(memsize*1024*1024)/2)>>12) \
+			& 0xfffff),0,0,0,0,0,0,0,0));
+		mtspr(MAS3, TLB1_MAS3((((CFG_DDR_SDRAM_BASE+(memsize*1024*1024)/2)>>12) \
+			& 0xfffff),0,0,0,0,0,1,0,1,0,1));
+		asm volatile("isync;msync;tlbwe;isync");
+		DEB(printf("DDR:MAS0=0x%08x\n",TLB1_MAS0(1,5,0)));
+		DEB(printf("DDR:MAS1=0x%08x\n",TLB1_MAS1(1,1,0,0,tmp)));
+		DEB(printf("DDR:MAS2=0x%08x\n",TLB1_MAS2((((CFG_DDR_SDRAM_BASE \
+			+(memsize*1024*1024)/2)>>12) & 0xfffff),0,0,0,0,0,0,0,0)));
+		DEB(printf("DDR:MAS3=0x%08x\n",TLB1_MAS3((((CFG_DDR_SDRAM_BASE \
+			+(memsize*1024*1024)/2)>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)));
+	}
+
+#if defined(CONFIG_RAM_AS_FLASH)
+	ecm->lawbar2 = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
+	ecm->lawar2 = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & tmp2));
+	DEB(printf("DDR:LAWBAR2=0x%08x\n",ecm->lawbar2));
+	DEB(printf("DDR:LARAR2=0x%08x\n",ecm->lawar2));
+#else
+	ecm->lawbar1 = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
+	ecm->lawar1 = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & tmp2));
+	DEB(printf("DDR:LAWBAR1=0x%08x\n",ecm->lawbar1));
+	DEB(printf("DDR:LARAR1=0x%08x\n",ecm->lawar1));
+#endif
+
+	tmp = 20000/(((spd.clk_cycle & 0xF0) >> 4) * 10 + (spd.clk_cycle & 0x0f));
+	DEB(printf("DDR:Module maximum data rate is: %dMhz\n",tmp));
+
+	/* find the largest CAS */
+	if(spd.cas_lat & 0x40) {
+		caslat = 7;
+	} else if (spd.cas_lat & 0x20) {
+		caslat = 6;
+	} else if (spd.cas_lat & 0x10) {
+		caslat = 5;
+	} else if (spd.cas_lat & 0x08) {
+		caslat = 4;
+	} else if (spd.cas_lat & 0x04) {
+		caslat = 3;
+	} else if (spd.cas_lat & 0x02) {
+		caslat = 2;
+	} else if (spd.cas_lat & 0x01) {
+		caslat = 1;
+	} else {
+		printf("DDR:no valid CAS Latency information.\n");
+		return 0;
+	}
+
+	tmp1 = get_bus_freq(0)/1000000;
+	if(tmp1<230 && tmp1>=90 && tmp>=230) {         /* 90~230 range, treated as DDR 200 */
+		if(spd.clk_cycle3 == 0xa0) caslat -= 2;
+		else if(spd.clk_cycle2 == 0xa0) caslat--;
+	} else if(tmp1<280 && tmp1>=230 && tmp>=280) { /* 230-280 range, treated as DDR 266 */
+		if(spd.clk_cycle3 == 0x75) caslat -= 2;
+		else if(spd.clk_cycle2 == 0x75) caslat--;
+	} else if(tmp1<350 && tmp1>=280 && tmp>=350) { /* 280~350 range, treated as DDR 333 */
+		if(spd.clk_cycle3 == 0x60) caslat -= 2;
+		else if(spd.clk_cycle2 == 0x60) caslat--;
+	} else if(tmp1<90 || tmp1 >=350) { /* DDR rate out-of-range */
+		printf("DDR:platform frequency is not fit for DDR rate\n");
+		return 0;
+	}
+
+	/* note: caslat must also be programmed into ddr->sdram_mode register */
+	/* note: WRREC(Twr) and WRTORD(Twtr) are not in SPD,use conservative value here */
+#if 1
+	ddr->timing_cfg_1 = 	(((ns2clk(spd.trp/4) & 0x07) << 28 ) | \
+				((ns2clk(spd.tras) & 0x0f ) << 24 ) | \
+				((ns2clk(spd.trcd/4) & 0x07) << 20 ) | \
+				((caslat & 0x07)<< 16 ) | \
+				(((ns2clk(spd.sset[6]) - 8) & 0x0f) << 12 ) | \
+				( 0x300 ) | \
+				((ns2clk(spd.trrd/4) & 0x07) << 4) | 1);
+#else
+	ddr->timing_cfg_1 = 0x37344321;
+	caslat = 4;
+#endif
+	DEB(printf("DDR:timing_cfg_1=0x%08x\n",ddr->timing_cfg_1));
+
+	/* note: hand-coded value for timing_cfg_2, see Errata DDR1*/
+#if defined(CONFIG_MPC85xx_REV1)
+	ddr->timing_cfg_2 = 0x00000800;
+#endif
+	DEB(printf("DDR:timing_cfg_2=0x%08x\n",ddr->timing_cfg_2));
+
+	/* only DDR I is supported, DDR I and II have different mode-register-set definition */
+	/* burst length is always 4 */
+	switch(caslat) {
+		case 2:
+			ddr->sdram_mode = 0x52; /* 1.5 */
+			break;
+		case 3:
+			ddr->sdram_mode = 0x22; /* 2.0 */
+			break;
+		case 4:
+			ddr->sdram_mode = 0x62; /* 2.5 */
+			break;
+		case 5:
+			ddr->sdram_mode = 0x32; /* 3.0 */
+			break;
+		default:
+			printf("DDR:only CAS Latency 1.5,2.0,2.5,3.0 is supported.\n");
+			return 0;
+	}
+	DEB(printf("DDR:sdram_mode=0x%08x\n",ddr->sdram_mode));
+
+	switch(spd.refresh) {
+		case 0x00:
+		case 0x80:
+			tmp = ns2clk(15625);
+			break;
+		case 0x01:
+		case 0x81:
+			tmp = ns2clk(3900);
+			break;
+		case 0x02:
+		case 0x82:
+			tmp = ns2clk(7800);
+			break;
+		case 0x03:
+		case 0x83:
+			tmp = ns2clk(31300);
+			break;
+		case 0x04:
+		case 0x84:
+			tmp = ns2clk(62500);
+			break;
+		case 0x05:
+		case 0x85:
+			tmp = ns2clk(125000);
+			break;
+		default:
+			tmp = 0x512;
+			break;
+	}
+
+	/* set BSTOPRE to 0x100 for page mode, if auto-charge is used, set BSTOPRE = 0 */
+	ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100;
+	DEB(printf("DDR:sdram_interval=0x%08x\n",ddr->sdram_interval));
+
+	/* is this an ECC DDR chip? */
+#if defined(CONFIG_DDR_ECC)
+	if(spd.config == 0x02) {
+		ddr->err_disable = 0x0000000d;
+		ddr->err_sbe = 0x00ff0000;
+	}
+	DEB(printf("DDR:err_disable=0x%08x\n",ddr->err_disable));
+	DEB(printf("DDR:err_sbe=0x%08x\n",ddr->err_sbe));
+#endif
+	asm("sync;isync;msync");
+
+	udelay(500);
+
+	/* registered or unbuffered? */
+#if defined(CONFIG_DDR_ECC)
+	ddr->sdram_cfg = (spd.config == 0x02)?0x20000000:0x0;
+#endif
+	ddr->sdram_cfg = 0xc2000000|((spd.mod_attr == 0x20) ? 0x0 : \
+		((spd.mod_attr == 0x26) ? 0x10000000:0x0));
+	asm("sync;isync;msync");
+
+	udelay(500);
+
+	DEB(printf("DDR:sdram_cfg=0x%08x\n",ddr->sdram_cfg));
+
+    	return (memsize*1024*1024);
+}
+
+#endif /* CONFIG_SPD_EEPROM */
diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c
new file mode 100644
index 0000000..a720cff
--- /dev/null
+++ b/cpu/mpc85xx/speed.c
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2003 Motorola Inc.
+ * Xianghua Xiao, (X.Xiao@motorola.com)
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ppc_asm.tmpl>
+#include <asm/processor.h>
+
+/* --------------------------------------------------------------- */
+
+#define ONE_BILLION        1000000000
+
+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,e500_ratio;
+
+	plat_ratio = (gur->porpllsr) & 0x0000003e;
+	plat_ratio >>= 1;
+	switch(plat_ratio) {
+	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;
+	}
+
+	e500_ratio = (gur->porpllsr) & 0x003f0000;
+	e500_ratio >>= 16;
+	switch(e500_ratio) {
+	case 0x04:
+		sysInfo->freqProcessor = 2*sysInfo->freqSystemBus;
+		break;
+	case 0x05:
+		sysInfo->freqProcessor = 5*sysInfo->freqSystemBus/2;
+		break;
+	case 0x06:
+		sysInfo->freqProcessor = 3*sysInfo->freqSystemBus;
+		break;
+	case 0x07:
+		sysInfo->freqProcessor = 7*sysInfo->freqSystemBus/2;
+		break;
+	default:
+		sysInfo->freqProcessor = 0;
+		break;
+	}
+}
+
+int get_clocks (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	sys_info_t sys_info;
+#if defined(CONFIG_MPC8560)
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	uint sccr, dfbrg;
+
+	/* set VCO = 4 * BRG */
+	immap->im_cpm.im_cpm_intctl.sccr &= 0xfffffffc;
+	sccr = immap->im_cpm.im_cpm_intctl.sccr;
+	dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT;
+#endif
+	get_sys_info (&sys_info);
+	gd->cpu_clk = sys_info.freqProcessor;
+	gd->bus_clk = sys_info.freqSystemBus;
+#if defined(CONFIG_MPC8560)
+	gd->vco_out = 2*sys_info.freqSystemBus;
+	gd->cpm_clk = gd->vco_out / 2;
+	gd->scc_clk = gd->vco_out / 4;
+	gd->brg_clk = gd->vco_out / (1 << (2 * (dfbrg + 1)));
+#endif
+
+	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/mpc85xx/start.S b/cpu/mpc85xx/start.S
new file mode 100644
index 0000000..468923c
--- /dev/null
+++ b/cpu/mpc85xx/start.S
@@ -0,0 +1,1156 @@
+/*
+ * Copyright (C) 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
+ */
+
+/* U-Boot Startup Code for Motorola 85xx PowerPC based Embedded Boards
+ *
+ * The processor starts at 0xfffffffc and the code is first executed in the
+ * last 4K page(0xfffff000-0xffffffff) in flash/rom.
+ *
+ */
+
+#include <config.h>
+#include <mpc85xx.h>
+#include <version.h>
+
+#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef	 CONFIG_IDENT_STRING
+#define	 CONFIG_IDENT_STRING ""
+#endif
+
+#undef	MSR_KERNEL
+#define MSR_KERNEL ( MSR_ME  )	/* Machine Check */
+
+/*
+ * 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
+
+/*
+ * e500 Startup -- after reset only the last 4KB of the effective
+ * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
+ * section is located at THIS LAST page and basically does three
+ * things: clear some registers, set up exception tables and
+ * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
+ * continue the boot procedure.
+
+ * Once the boot rom is mapped by TLB entries we can proceed
+ * with normal startup.
+ *
+ */
+
+    .section .bootpg,"ax"
+    .globl _start_e500
+
+_start_e500:
+#if defined(CONFIG_MPC85xx_REV1)
+	li	r0,0x2000
+	mtspr	977,r0
+#endif
+
+	/* Clear and set up some registers. Note: Some registers need strict
+	 * synchronization by sync/mbar/msync/isync when being "mtspr".
+	 * BookE: isync before PID,tlbivax,tlbwe
+	 * BookE: isync after MSR,PID; msync_isync after tlbivax & tlbwe
+	 * E500:  msync,isync before L1CSR0
+	 * E500:  isync after BBEAR,BBTAR,BUCSR,DBCR0,DBCR1,HID0,HID1,L1CSR0
+	 *        L1CSR1, MAS[0,1,2,3,4,6],MMUCSR0, PID[0,1,2],SPEFCSR
+	 */
+
+	/* invalidate d-cache */
+	mfspr	r0,L1CSR0
+	ori	r0,r0,0x0002
+	msync
+	isync
+	mtspr	L1CSR0,r0
+	isync
+
+	/* disable d-cache */
+	li	r0,0x0
+	mtspr	L1CSR0,r0
+	isync
+
+	/* invalidate i-cache */
+	mfspr	r0,L1CSR1
+	ori	r0,r0,0x0002
+	mtspr	L1CSR1,r0
+	isync
+
+	/* disable i-cache */
+	li	r0,0x0
+	mtspr	L1CSR1,r0
+	isync
+
+	/* clear registers */
+	sync
+	li	r0,0
+	mtspr	SRR0,r0
+	mtspr	SRR1,r0
+	mtspr	CSRR0,r0
+	mtspr	CSRR1,r0
+	mtspr	MCSRR0,r0
+	mtspr	MCSRR1,r0
+
+	mtspr	ESR,r0
+	mtspr	MCSR,r0
+	mtspr	DEAR,r0
+
+	mtspr	DBCR0,r0
+	isync
+	mtspr	DBCR1,r0
+	isync
+	mtspr	DBCR2,r0
+	isync
+	mtspr	IAC1,r0
+	mtspr	IAC2,r0
+	mtspr	DAC1,r0
+	mtspr	DAC2,r0
+
+	mfspr	r1,DBSR
+	mtspr	DBSR,r1		/* Clear all valid bits */
+
+	isync
+	mtspr	PID0,r0
+	isync
+	mtspr	PID1,r0
+	isync
+	mtspr	PID2,r0
+	isync
+
+	mtspr	TCR,r0
+
+	mtspr	BUCSR,r0	/* disable branch prediction */
+	isync
+
+	mtspr	HID0,r0
+	isync
+	mtspr	HID1,r0
+	isync
+
+	mtspr   MAS4,r0
+	isync
+	mtspr   MAS6,r0
+	isync
+
+	/* Setup interrupt vectors */
+	mtspr IVPR, r0
+
+	li      r1,0x0100
+	mtspr	IVOR0,r1	/* 0: Critical input */
+	li      r1,0x0200
+	mtspr	IVOR1,r1	/* 1: Machine check */
+	li      r1,0x0300
+	mtspr	IVOR2,r1	/* 2: Data storage */
+	li      r1,0x0400
+	mtspr	IVOR3,r1	/* 3: Instruction storage */
+	li	r1,0x0500
+	mtspr	IVOR4,r1	/* 4: External interrupt */
+	li	r1,0x0600
+	mtspr	IVOR5,r1	/* 5: Alignment */
+	li	r1,0x0700
+	mtspr	IVOR6,r1	/* 6: Program check */
+	li	r1,0x0800
+	mtspr	IVOR7,r1	/* 7: floating point unavailable */
+	li	r1,0x0c00
+	mtspr	IVOR8,r1	/* 8: System call */
+	/* 9: Auxiliary processor unavailable(unsupported) */
+	li	r1,0x1000
+	mtspr	IVOR10,r1	/* 10: Decrementer */
+	li	r1,0x1400
+	mtspr	IVOR13,r1	/* 13: Data TLB error */
+	li	r1,0x1300
+	mtspr	IVOR14,r1	/* 14: Instruction TLB error */
+	li	r1,0x2000
+	mtspr	IVOR15,r1	/* 15: Debug */
+
+	/* invalidate MMU L1/L2 */
+	/* Note: before invalidate MMU L1/L2, we read TLB1 Entry 0 and then
+	 * write it back immediately to fixup a bug(Errata CPU4)  for this initial
+	 * TLB1 entry 0,otherwise the TLB1 entry 0 will be invalidated.
+	 */
+#if defined(CONFIG_MPC85xx_REV1)
+	lis	r2,0x1000
+	mtspr	MAS0,r2
+	tlbre
+	tlbwe
+	isync
+	li      r2, 0x001e
+	mtspr   MMUCSR0, r2
+	isync
+#endif
+
+	/* After reset, CCSRBAR is located at CFG_CCSRBAR_DEFAULT, i.e.
+	 * 0xff700000-0xff800000. We need add a TLB1 entry for this 1MB
+	 * region before we can access any CCSR registers such as L2
+	 * registers, Local Access Registers,etc. We will also re-allocate
+	 * CFG_CCSRBAR_DEFAULT to CFG_CCSRBAR immediately after TLB1 setup.
+	 *
+	 * Please refer to board-specif directory for TLB1 entry configuration.
+	 * (e.g. board/<yourboard>/init.S)
+	 *
+	 */
+	bl 	tlb1_entry
+	mr	r5,r0
+	li	r1,0x000f	/* max 16 TLB1 entries */
+	mtctr	r1
+	lwzu	r4,0(r5)	/* how many TLB1 entries we actually use */
+
+0:	cmpwi	r4,0
+	beq	1f
+	lwzu	r0,4(r5)
+	lwzu	r1,4(r5)
+	lwzu	r2,4(r5)
+	lwzu	r3,4(r5)
+	mtspr	MAS0,r0
+	mtspr	MAS1,r1
+	mtspr	MAS2,r2
+	mtspr	MAS3,r3
+	isync
+	msync
+	tlbwe
+	isync
+	addi	r4,r4,-1
+	bdnz	0b
+
+1:
+#if (CFG_CCSRBAR_DEFAULT != CFG_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
+#endif
+
+	/*  invalidate all TLB0 entries */
+	li 	r3,4
+	li	r4,0
+	tlbivax	r4,r3
+#if defined(CONFIG_MPC85xx_REV1) /* Errata CPU6 */
+	nop
+#endif
+
+	/* set up local access windows, defined at board/<boardname>/init.S */
+	lis	r7,CFG_CCSRBAR@h
+	ori	r7,r7,CFG_CCSRBAR@l
+
+	bl 	law_entry
+	mr	r6,r0
+#if  defined(CONFIG_RAM_AS_FLASH)
+	li	r1,0x0006
+#else
+	li	r1,0x0007	/*we have 8 LAWs, but reseve one for boot-over-rio-or-pci */
+#endif
+	mtctr	r1
+	lwzu	r5,0(r6)	/* how many windows we actually use */
+
+#if defined(CONFIG_RAM_AS_FLASH)
+	li 	r2,0x0c48
+	li	r1,0x0c50
+#else
+	li	r2,0x0c28	/* the first pair is reserved for boot-over-rio-or-pci */
+	li	r1,0x0c30
+#endif
+
+0:	cmpwi	r5,0
+	beq	1f
+	lwzu	r4,4(r6)
+	lwzu	r3,4(r6)
+	stwx	r4,r7,r2
+	stwx	r3,r7,r1
+	addi	r5,r5,-1
+	addi	r2,r2,0x0020
+	addi	r1,r1,0x0020
+	bdnz	0b
+
+	/* Jump out the last 4K page and continue to 'normal' start */
+1:	bl	3f
+	b	_start
+
+3:	li	r0,0
+	mtspr	SRR1,r0		/* Keep things disabled for now */
+	mflr	r1
+	mtspr	SRR0,r1
+	rfi
+
+/*
+ * 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:
+	/* Clear and set up some registers. */
+	li	r0,0x0000
+	lis	r1,0xffff
+	mtspr	DEC,r0			/* prevent dec exceptions */
+	mttbl	r0			/* prevent fit & wdt exceptions */
+	mttbu	r0
+	mtspr	TSR,r1			/* clear all timer exception status */
+	mtspr	TCR,r0			/* disable all */
+	mtspr	ESR,r0			/* clear exception syndrome register */
+	mtspr	MCSR,r0			/* machine check syndrome register */
+	mtxer	r0			/* clear integer exception register */
+	lis	r1,0x0002		/* set CE bit (Critical Exceptions) */
+	ori	r1,r1,0x1200		/* set ME/DE bit */
+	mtmsr	r1			/* change MSR */
+	isync
+
+	/* Enable Time Base and Select Time Base Clock */
+	li	r0,0x4000		/* time base is processor clock */
+	mtspr	HID0,r0
+	isync
+
+#if defined(CONFIG_ADDR_STREAMING)
+	li	r0,0x2000
+	mtspr	HID1,r0
+	isync
+#endif
+
+	/* Enable Branch Prediction */
+#if defined(CONFIG_BTB)
+	li	r0,0x201		/* BBFI = 1, BPEN = 1 */
+	mtspr	BUCSR,r0
+	isync
+#endif
+
+#if defined(CFG_INIT_DBCR)
+	lis	r1,0xffff
+	ori	r1,r1,0xffff
+	mtspr	dbsr,r1			/* Clear all status bits */
+	lis	r0,CFG_INIT_DBCR@h	/* DBCR0[IDM] must be set */
+	ori	r0,r0,CFG_INIT_DBCR@l
+	mtspr	dbcr0,r0
+	isync
+#endif
+
+/* L1 DCache is used for initial RAM */
+	mfspr	r2, L1CSR0
+	ori    	r2, r2, 0x0003
+	oris   	r2, r2, 0x0001
+	msync
+	isync
+	mtspr  	L1CSR0, r2	/* enable/invalidate L1 Dcache */
+	isync
+
+	/* Allocate Initial RAM in data cache.
+	 */
+	lis     r3, CFG_INIT_RAM_ADDR@h
+	ori     r3, r3, CFG_INIT_RAM_ADDR@l
+	li      r2, 512 /* 512*32=16K */
+	mtctr   r2
+	li	r0, 0
+1:
+	dcbz	r0, r3
+	dcbtls  0,r0, r3
+	addi    r3, r3, 32
+	bdnz    1b
+
+#ifndef CFG_RAMBOOT
+	/* 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:
+#endif  /* CFG_RAMBOOT */
+
+	/* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
+	lis	r1,CFG_INIT_RAM_ADDR@h
+	ori	r1,r1,CFG_INIT_SP_OFFSET@l
+
+	li	r0,0
+	stwu	r0,-4(r1)
+	stwu	r0,-4(r1)		/* Terminate call chain */
+
+	stwu	r1,-8(r1)		/* Save back chain and move SP */
+	lis	r0,RESET_VECTOR@h	/* Address of reset vector */
+	ori	r0,r0, RESET_VECTOR@l
+	stwu	r1,-8(r1)		/* Save back chain and move SP */
+	stw	r0,+12(r1)		/* Save return addr (underflow vect) */
+
+	GET_GOT
+	bl	cpu_init_f
+	bl	icache_enable
+	bl	board_init_f
+	sync
+
+
+/* --FIXME-- machine check with MCSRRn and rfmci */
+
+	.globl	_start_of_vectors
+_start_of_vectors:
+#if 0
+/* Critical input. */
+	CRIT_EXCEPTION(0x0100, CritcalInput, CritcalInputException)
+#endif
+/* Machine check --FIXME-- Should be MACH_EXCEPTION */
+	CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+
+/* Data Storage exception. */
+	STD_EXCEPTION(0x0300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+	STD_EXCEPTION(0x0400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+	STD_EXCEPTION(0x0500, ExtInterrupt, UnknownException)
+
+/* Alignment exception. */
+	. = 0x0600
+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 */
+	. = 0x0700
+ProgramCheck:
+	EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_ProgramCheck:
+	.long	ProgramCheckException - _start + EXC_OFF_SYS_RESET
+	.long	int_return - _start + EXC_OFF_SYS_RESET
+
+	/* No FPU on MPC85xx.  This exception is not supposed to happen.
+	*/
+	STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
+	STD_EXCEPTION(0x0900, Decrementer, timer_interrupt)
+	STD_EXCEPTION(0x0a00, Trap_0a, UnknownException)
+	STD_EXCEPTION(0x0b00, Trap_0b, UnknownException)
+
+	. = 0x0c00
+/*
+ * r0 - SYSCALL number
+ * r3-... arguments
+ */
+SystemCall:
+	addis   r11,r0,0                /* get functions table addr */
+	ori     r11,r11,0               /* Note: this code is patched in trap_init */
+	addis   r12,r0,0                /* get number of functions */
+	ori     r12,r12,0
+
+	cmplw   0, r0, r12
+	bge     1f
+
+	rlwinm  r0,r0,2,0,31            /* fn_addr = fn_tbl[r0] */
+	add     r11,r11,r0
+	lwz     r11,0(r11)
+
+	li      r20,0xd00-4             /* Get stack pointer */
+	lwz     r12,0(r20)
+	subi    r12,r12,12              /* Adjust stack pointer */
+	li      r0,0xc00+_end_back-SystemCall
+	cmplw   0, r0, r12              /* Check stack overflow */
+	bgt     1f
+	stw     r12,0(r20)
+
+	mflr    r0
+	stw     r0,0(r12)
+	mfspr   r0,SRR0
+	stw     r0,4(r12)
+	mfspr   r0,SRR1
+	stw     r0,8(r12)
+
+	li      r12,0xc00+_back-SystemCall
+	mtlr    r12
+	mtspr   SRR0,r11
+
+1:      SYNC
+	rfi
+_back:
+
+	mfmsr   r11                     /* Disable interrupts */
+	li      r12,0
+	ori     r12,r12,MSR_EE
+	andc    r11,r11,r12
+	SYNC                            /* Some chip revs need this... */
+	mtmsr   r11
+	SYNC
+
+	li      r12,0xd00-4             /* restore regs */
+	lwz     r12,0(r12)
+
+	lwz     r11,0(r12)
+	mtlr    r11
+	lwz     r11,4(r12)
+	mtspr   SRR0,r11
+	lwz     r11,8(r12)
+	mtspr   SRR1,r11
+
+	addi    r12,r12,12              /* Adjust stack pointer */
+	li      r20,0xd00-4
+	stw     r12,0(r20)
+
+	SYNC
+	rfi
+_end_back:
+
+	STD_EXCEPTION(0xd00, SingleStep, UnknownException)
+
+	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+
+	STD_EXCEPTION(0x1000, PIT, PITException)
+
+	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)
+
+	CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
+
+	.globl  _end_of_vectors
+_end_of_vectors:
+
+
+	. = 0x2100
+
+/*
+ * 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
+
+crit_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	990,r2		/* SRR2 */
+	mtspr	991,r0		/* SRR3 */
+	lwz	r0,GPR0(r1)
+	lwz	r2,GPR2(r1)
+	lwz	r1,GPR1(r1)
+	SYNC
+	rfci
+
+/* Cache functions.
+*/
+invalidate_icache:
+	mfspr	r0,L1CSR1
+	ori	r0,r0,0x0002
+	mtspr	L1CSR1,r0
+	isync
+	blr				/*   entire I cache */
+
+invalidate_dcache:
+	mfspr	r0,L1CSR0
+	ori	r0,r0,0x0002
+	msync
+	isync
+	mtspr	L1CSR0,r0
+	isync
+	blr
+
+	.globl	icache_enable
+icache_enable:
+	mflr	r8
+	bl	invalidate_icache
+	mtlr	r8
+	isync
+	mfspr	r4,L1CSR1
+	ori	r4,r4,0x0001
+	oris	r4,r4,0x0001
+	mtspr	L1CSR1,r4
+	isync
+	blr
+
+	.globl	icache_disable
+icache_disable:
+	mfspr	r0,L1CSR1
+	lis	r1,0xfffffffe@h
+	ori	r1,r1,0xfffffffe@l
+	and	r0,r0,r1
+	mtspr	L1CSR1,r0
+	isync
+	blr
+
+	.globl	icache_status
+icache_status:
+	mfspr	r3,L1CSR1
+	srwi	r3, r3, 31	/* >>31 => select bit 0 */
+	blr
+
+	.globl	dcache_enable
+dcache_enable:
+	mflr	r8
+	bl	invalidate_dcache
+	mtlr	r8
+	isync
+	mfspr	r0,L1CSR0
+	ori	r0,r0,0x0001
+	oris	r0,r0,0x0001
+	msync
+	isync
+	mtspr	L1CSR0,r0
+	isync
+	blr
+
+	.globl	dcache_disable
+dcache_disable:
+	mfspr	r0,L1CSR0
+	lis	r1,0xfffffffe@h
+	ori	r1,r1,0xfffffffe@l
+	and	r0,r0,r1
+	msync
+	isync
+	mtspr	L1CSR0,r0
+	isync
+	blr
+
+	.globl	dcache_status
+dcache_status:
+	mfspr	r3,L1CSR0
+	srwi	r3, r3, 31	/* >>31 => select bit 0 */
+	blr
+
+	.globl get_pir
+get_pir:
+	mfspr	r3, PIR
+	blr
+
+	.globl get_pvr
+get_pvr:
+	mfspr	r3, PVR
+	blr
+
+	.globl wr_tcr
+wr_tcr:
+	mtspr	TCR, r3
+	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:	 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 Init Data pointer	*/
+	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
+	/* the the one used by the C code */
+	add	r30, r30, r15
+
+	/*
+	 * Now relocate code
+	 */
+
+	cmplw	cr1,r3,r4
+	addi	r0,r5,3
+	srwi.	r0,r0,2
+	beq	cr1,4f		/* In place copy is not necessary	*/
+	beq	7f		/* Protect against 0 count		*/
+	mtctr	r0
+	bge	cr1,2f
+
+	la	r8,-4(r4)
+	la	r7,-4(r3)
+1:	lwzu	r0,4(r8)
+	stwu	r0,4(r7)
+	bdnz	1b
+	b	4f
+
+2:	slwi	r0,r0,2
+	add	r8,r4,r0
+	add	r7,r3,r0
+3:	lwzu	r0,-4(r8)
+	stwu	r0,-4(r7)
+	bdnz	3b
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4:	cmpwi	r6,0
+	add	r5,r3,r5
+	beq	7f		/* Always flush prefetch queue in any case */
+	subi	r0,r6,1
+	andc	r3,r3,r0
+	mr	r4,r3
+5:	dcbst	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	5b
+	sync			/* Wait for all dcbst to complete on bus */
+	mr	r4,r3
+6:	icbi	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	6b
+7:	sync			/* Wait for all icbi to complete on bus */
+	isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+
+	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+	mtlr	r0
+	blr				/* NEVER RETURNS! */
+
+in_ram:
+
+	/*
+	 * Relocation Function, r14 point to got2+0x8000
+	 *
+	 * Adjust got2 pointers, no need to check for 0, this code
+	 * already puts a few entries in the table.
+	 */
+	li	r0,__got2_entries@sectoff@l
+	la	r3,GOT(_GOT2_TABLE_)
+	lwz	r11,GOT(_GOT2_TABLE_)
+	mtctr	r0
+	sub	r11,r3,r11
+	addi	r3,r3,-4
+1:	lwzu	r0,4(r3)
+	add	r0,r0,r11
+	stw	r0,0(r3)
+	bdnz	1b
+
+	/*
+	 * Now adjust the fixups and the pointers to the fixups
+	 * in case we need to move ourselves again.
+	 */
+2:	li	r0,__fixup_entries@sectoff@l
+	lwz	r3,GOT(_FIXUP_TABLE_)
+	cmpwi	r0,0
+	mtctr	r0
+	addi	r3,r3,-4
+	beq	4f
+3:	lwzu	r4,4(r3)
+	lwzux	r0,r4,r11
+	add	r0,r0,r11
+	stw	r10,0(r3)
+	stw	r0,0(r4)
+	bdnz	3b
+4:
+clear_bss:
+	/*
+	 * Now clear BSS segment
+	 */
+	lwz	r3,GOT(__bss_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 Data pointer		*/
+	mr	r4, r10		/* Destination Address		*/
+	bl	board_init_r
+
+	/*
+	 * 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
+
+	mtlr    r4                      /* restore link register        */
+	blr
+
+	/*
+	 * Function: relocate entries for one exception vector
+	 */
+trap_reloc:
+	lwz     r0, 0(r7)               /* hdlr ...                     */
+	add     r0, r0, r3              /*  ... += dest_addr            */
+	stw     r0, 0(r7)
+
+	lwz     r0, 4(r7)               /* int_return ...               */
+	add     r0, r0, r3              /*  ... += dest_addr            */
+	stw     r0, 4(r7)
+
+	blr
+
+#ifdef CFG_INIT_RAM_LOCK
+.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,512
+	mtctr	r2
+1:	icbi	r0, r3
+	dcbi	r0, r3
+	addi	r3, r3, 32
+	bdnz	1b
+	sync			/* Wait for all icbi to complete on bus	*/
+	isync
+	blr
+#endif
diff --git a/cpu/mpc85xx/traps.c b/cpu/mpc85xx/traps.c
new file mode 100644
index 0000000..fd0b436
--- /dev/null
+++ b/cpu/mpc85xx/traps.c
@@ -0,0 +1,272 @@
+/*
+ * linux/arch/ppc/kernel/traps.c
+ *
+ * Copyright (C) 2003 Motorola
+ * Modified by Xianghua Xiao(x.xiao@motorola.com)
+ *
+ * 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);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+ */
+#define END_OF_MEM	(CFG_SDRAM_SIZE * 1024 * 1024)
+
+
+static __inline__ void set_tsr(unsigned long val)
+{
+	asm volatile("mtspr 0x150, %0" : : "r" (val));
+}
+
+static __inline__ unsigned long get_esr(void)
+{
+	unsigned long val;
+	asm volatile("mfspr %0, 0x03e" : "=r" (val) :);
+	return val;
+}
+
+#define ESR_MCI 0x80000000
+#define ESR_PIL 0x08000000
+#define ESR_PPR 0x04000000
+#define ESR_PTR 0x02000000
+#define ESR_DST 0x00800000
+#define ESR_DIZ 0x00400000
+#define ESR_U0F 0x00008000
+
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+extern void do_bedbug_breakpoint(struct pt_regs *);
+#endif
+
+/*
+ * Trap & Exception support
+ */
+
+void
+print_backtrace(unsigned long *sp)
+{
+	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
+CritcalInputException(struct pt_regs *regs)
+{
+	panic("Critical Input Exception");
+}
+
+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 & 0x0000F000)
+	{
+	case (1<<12) :
+		printf("Machine check signal - probably due to mm fault\n"
+		       "with mmu off\n");
+		break;
+	case (1<<13) :
+		printf("Transfer error ack signal\n");
+		break;
+	case (1<<14) :
+		printf("Data parity signal\n");
+		break;
+	case (1<<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)
+{
+	long esr_val;
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	show_regs(regs);
+
+	esr_val = get_esr();
+	if( esr_val & ESR_PIL )
+		printf( "** Illegal Instruction **\n" );
+	else if( esr_val & ESR_PPR )
+		printf( "** Privileged Instruction **\n" );
+	else if( esr_val & ESR_PTR )
+		printf( "** Trap Instruction **\n" );
+
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+PITException(struct pt_regs *regs)
+{
+	/*
+	 * Reset PIT interrupt
+	 */
+	set_tsr(0x0c000000);
+
+	/*
+	 * Call timer_interrupt routine in interrupts.c
+	 */
+	timer_interrupt(NULL);
+}
+
+
+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);
+}
+
+void
+DebugException(struct pt_regs *regs)
+{
+	printf("Debugger trap at @ %lx\n", regs->nip );
+	show_regs(regs);
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+	do_bedbug_breakpoint( regs );
+#endif
+}
+
+/* Probe an address by reading.  If not present, return -1, otherwise
+ * return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+	return 0;
+}
diff --git a/cpu/mpc85xx/tsec.c b/cpu/mpc85xx/tsec.c
new file mode 100644
index 0000000..4a5731e
--- /dev/null
+++ b/cpu/mpc85xx/tsec.c
@@ -0,0 +1,441 @@
+/*
+ * tsec.c
+ * Motorola Three Speed Ethernet Controller driver
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * (C) Copyright 2003, Motorola, Inc.
+ * maintained by Xianghua Xiao (x.xiao@motorola.com)
+ * author Andy Fleming
+ *
+ */
+
+#include <config.h>
+#include <mpc85xx.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+
+#if defined(CONFIG_TSEC_ENET)
+#include "tsec.h"
+
+#define TX_BUF_CNT 2
+
+#undef TSEC_DEBUG
+#ifdef TSEC_DEBUG
+#define DBGPRINT(x) printf(x)
+#else
+#define DBGPRINT(x)
+#endif
+
+static uint rxIdx;	/* index of the current RX buffer */
+static uint txIdx;	/* index of the current TX buffer */
+
+typedef volatile struct rtxbd {
+	txbd8_t txbd[TX_BUF_CNT];
+	rxbd8_t rxbd[PKTBUFSRX];
+}  RTXBD;
+
+#ifdef __GNUC__
+static RTXBD rtx __attribute__ ((aligned(8)));
+#else
+#error "rtx must be 64-bit aligned"
+#endif
+
+static int tsec_send(struct eth_device* dev, volatile void *packet, int length);
+static int tsec_recv(struct eth_device* dev);
+static int tsec_init(struct eth_device* dev, bd_t * bd);
+static void tsec_halt(struct eth_device* dev);
+static void init_registers(tsec_t *regs);
+static void startup_tsec(tsec_t *regs);
+static void init_phy(tsec_t *regs);
+
+/* Initialize device structure.  returns 0 on failure, 1 on
+ * success */
+int tsec_initialize(bd_t *bis)
+{
+	struct eth_device* dev;
+	int i;
+
+	dev = (struct eth_device*) malloc(sizeof *dev);
+
+	if(dev == NULL)
+		return 0;
+
+	memset(dev, 0, sizeof *dev);
+
+	sprintf(dev->name, "MOTOROLA ETHERNET");
+	dev->iobase = 0;
+	dev->priv   = 0;
+	dev->init   = tsec_init;
+	dev->halt   = tsec_halt;
+	dev->send   = tsec_send;
+	dev->recv   = tsec_recv;
+
+	/* Tell u-boot to get the addr from the env */
+	for(i=0;i<6;i++)
+		dev->enetaddr[i] = 0;
+
+	eth_register(dev);
+
+	return 1;
+}
+
+
+/* Initializes data structures and registers for the controller,
+ * and brings the interface up */
+int tsec_init(struct eth_device* dev, bd_t * bd)
+{
+	tsec_t *regs;
+	uint tempval;
+	char tmpbuf[MAC_ADDR_LEN];
+	int i;
+
+	regs = (tsec_t *)(TSEC_BASE_ADDR);
+
+	/* Make sure the controller is stopped */
+	tsec_halt(dev);
+
+	/* Reset the MAC */
+	regs->maccfg1 |= MACCFG1_SOFT_RESET;
+
+	/* Clear MACCFG1[Soft_Reset] */
+	regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
+
+	/* Init MACCFG2.  Defaults to GMII/MII */
+	regs->maccfg2 = MACCFG2_INIT_SETTINGS;
+
+	/* Init ECNTRL */
+	regs->ecntrl = ECNTRL_INIT_SETTINGS;
+
+	/* Copy the station address into the address registers.
+	 * Backwards, because little endian MACS are dumb */
+	for(i=0;i<MAC_ADDR_LEN;i++) {
+		tmpbuf[MAC_ADDR_LEN - 1 - i] = bd->bi_enetaddr[i];
+	}
+	(uint)(regs->macstnaddr1) = *((uint *)(tmpbuf));
+
+	tempval = *((uint *)(tmpbuf +4));
+
+	(uint)(regs->macstnaddr2) = tempval;
+
+	/* Initialize the PHY */
+	init_phy(regs);
+
+	/* reset the indices to zero */
+	rxIdx = 0;
+	txIdx = 0;
+
+	/* Clear out (for the most part) the other registers */
+	init_registers(regs);
+
+	/* Ready the device for tx/rx */
+	startup_tsec(regs);
+
+	return 1;
+
+}
+
+
+/* Reads from the register at offset in the PHY at phyid, */
+/* using the register set defined in regbase.  It waits until the */
+/* bits in the miimstat are valid (miimind notvalid bit cleared), */
+/* and then passes those bits on to the variable specified in */
+/* value */
+/* Before it does the read, it needs to clear the command field */
+uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset)
+{
+	uint value;
+
+	/* Put the address of the phy, and the register number into
+	 * MIIMADD
+	 */
+	regbase->miimadd = (phyid << 8) | offset;
+
+	/* Clear the command register, and wait */
+	regbase->miimcom = 0;
+	asm("msync");
+
+	/* Initiate a read command, and wait */
+	regbase->miimcom = MIIM_READ_COMMAND;
+	asm("msync");
+
+	/* Wait for the the indication that the read is done */
+	while((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY)));
+
+	/* Grab the value read from the PHY */
+	value = regbase->miimstat;
+
+	return value;
+}
+
+/* Setup the PHY */
+static void init_phy(tsec_t *regs)
+{
+	uint testval;
+	unsigned int timeout = TSEC_TIMEOUT;
+
+	/* Assign a Physical address to the TBI */
+	regs->tbipa=TBIPA_VALUE;
+
+	/* reset the management interface */
+	regs->miimcfg=MIIMCFG_RESET;
+
+	regs->miimcfg=MIIMCFG_INIT_VALUE;
+
+	/* Wait until the bus is free */
+	while(regs->miimind & MIIMIND_BUSY);
+
+#ifdef CONFIG_PHY_CIS8201
+	/* override PHY config settings */
+	write_phy_reg(regs, 0, MIIM_AUX_CONSTAT, MIIM_AUXCONSTAT_INIT);
+
+	/* Set up interface mode */
+	write_phy_reg(regs, 0, MIIM_EXT_CON1, MIIM_EXTCON1_INIT);
+#endif
+
+	/* Set the PHY to gigabit, full duplex, Auto-negotiate */
+	write_phy_reg(regs, 0, MIIM_CONTROL, MIIM_CONTROL_INIT);
+
+	/* Wait until TBI_STATUS indicates AN is done */
+	DBGPRINT("Waiting for Auto-negotiation to complete\n");
+	testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
+
+	while((!(testval & MIIM_TBI_STATUS_AN_DONE))&& timeout--) {
+		testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
+	}
+
+	if(testval & MIIM_TBI_STATUS_AN_DONE)
+		DBGPRINT("Auto-negotiation done\n");
+	else
+		DBGPRINT("Auto-negotiation timed-out.\n");
+
+#ifdef CONFIG_PHY_CIS8201
+	/* Find out what duplexity (duplicity?) we have */
+	/* Read it twice to make sure */
+	testval=read_phy_reg(regs, 0, MIIM_AUX_CONSTAT);
+
+	if(testval & MIIM_AUXCONSTAT_DUPLEX) {
+		DBGPRINT("Enet starting in full duplex\n");
+		regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
+	} else {
+		DBGPRINT("Enet starting in half duplex\n");
+		regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
+	}
+
+	/* Also, we look to see what speed we are at
+	 * if Gigabit, MACCFG2 goes in GMII, otherwise,
+	 * MII mode.
+	 */
+	if((testval & MIIM_AUXCONSTAT_SPEED) != MIIM_AUXCONSTAT_GBIT) {
+		if((testval & MIIM_AUXCONSTAT_SPEED) == MIIM_AUXCONSTAT_100)
+			DBGPRINT("Enet starting in 100BT\n");
+		else
+			DBGPRINT("Enet starting in 10BT\n");
+
+		/* mark the mode in MACCFG2 */
+		regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
+	} else {
+		DBGPRINT("Enet starting in 1000BT\n");
+	}
+
+#endif
+
+#ifdef CONFIG_PHY_M88E1011
+	/* Read the PHY to see what speed and duplex we are */
+	testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
+
+	timeout = TSEC_TIMEOUT;
+	while((!(testval & MIIM_PHYSTAT_SPDDONE)) && timeout--) {
+		testval = read_phy_reg(regs,0,MIIM_PHY_STATUS);
+	}
+
+	if(!(testval & MIIM_PHYSTAT_SPDDONE))
+		DBGPRINT("Enet: Speed not resolved\n");
+
+	testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
+	if(testval & MIIM_PHYSTAT_DUPLEX) {
+		DBGPRINT("Enet starting in Full Duplex\n");
+		regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
+	} else {
+		DBGPRINT("Enet starting in Half Duplex\n");
+		regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
+	}
+
+	if(!((testval&MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_GBIT)) {
+		if((testval & MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_100)
+			DBGPRINT("Enet starting in 100BT\n");
+		else
+			DBGPRINT("Enet starting in 10BT\n");
+
+		regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
+	} else {
+		DBGPRINT("Enet starting in 1000BT\n");
+	}
+#endif
+
+}
+
+
+static void init_registers(tsec_t *regs)
+{
+	/* Clear IEVENT */
+	regs->ievent = IEVENT_INIT_CLEAR;
+
+	regs->imask = IMASK_INIT_CLEAR;
+
+	regs->hash.iaddr0 = 0;
+	regs->hash.iaddr1 = 0;
+	regs->hash.iaddr2 = 0;
+	regs->hash.iaddr3 = 0;
+	regs->hash.iaddr4 = 0;
+	regs->hash.iaddr5 = 0;
+	regs->hash.iaddr6 = 0;
+	regs->hash.iaddr7 = 0;
+
+	regs->hash.gaddr0 = 0;
+	regs->hash.gaddr1 = 0;
+	regs->hash.gaddr2 = 0;
+	regs->hash.gaddr3 = 0;
+	regs->hash.gaddr4 = 0;
+	regs->hash.gaddr5 = 0;
+	regs->hash.gaddr6 = 0;
+	regs->hash.gaddr7 = 0;
+
+	regs->rctrl = 0x00000000;
+
+	/* Init RMON mib registers */
+	memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
+
+	regs->rmon.cam1 = 0xffffffff;
+	regs->rmon.cam2 = 0xffffffff;
+
+	regs->mrblr = MRBLR_INIT_SETTINGS;
+
+	regs->minflr = MINFLR_INIT_SETTINGS;
+
+	regs->attr = ATTR_INIT_SETTINGS;
+	regs->attreli = ATTRELI_INIT_SETTINGS;
+
+}
+
+static void startup_tsec(tsec_t *regs)
+{
+	int i;
+
+	/* Point to the buffer descriptors */
+	regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
+	regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
+
+	/* Initialize the Rx Buffer descriptors */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		rtx.rxbd[i].status = RXBD_EMPTY;
+		rtx.rxbd[i].length = 0;
+		rtx.rxbd[i].bufPtr = (uint)NetRxPackets[i];
+	}
+	rtx.rxbd[PKTBUFSRX -1].status |= RXBD_WRAP;
+
+	/* Initialize the TX Buffer Descriptors */
+	for(i=0; i<TX_BUF_CNT; i++) {
+		rtx.txbd[i].status = 0;
+		rtx.txbd[i].length = 0;
+		rtx.txbd[i].bufPtr = 0;
+	}
+	rtx.txbd[TX_BUF_CNT -1].status |= TXBD_WRAP;
+
+	/* Enable Transmit and Receive */
+	regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
+
+	/* Tell the DMA it is clear to go */
+	regs->dmactrl |= DMACTRL_INIT_SETTINGS;
+	regs->tstat = TSTAT_CLEAR_THALT;
+	regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
+}
+
+/* This returns the status bits of the device.  The return value
+ * is never checked, and this is what the 8260 driver did, so we
+ * do the same.  Presumably, this would be zero if there were no
+ * errors */
+static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
+{
+	int i;
+	int result = 0;
+	tsec_t * regs = (tsec_t *)(TSEC_BASE_ADDR);
+
+	/* Find an empty buffer descriptor */
+	for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
+		if (i >= TOUT_LOOP) {
+			DBGPRINT("tsec: tx buffers full\n");
+			return result;
+		}
+	}
+
+	rtx.txbd[txIdx].bufPtr = (uint)packet;
+	rtx.txbd[txIdx].length = length;
+	rtx.txbd[txIdx].status |= (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
+
+	/* Tell the DMA to go */
+	regs->tstat = TSTAT_CLEAR_THALT;
+
+	/* Wait for buffer to be transmitted */
+	for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
+		if (i >= TOUT_LOOP) {
+			DBGPRINT("tsec: tx error\n");
+			return result;
+		}
+	}
+
+	txIdx = (txIdx + 1) % TX_BUF_CNT;
+	result = rtx.txbd[txIdx].status & TXBD_STATS;
+
+	return result;
+}
+
+static int tsec_recv(struct eth_device* dev)
+{
+	int length;
+	tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
+
+	while(!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
+
+		length = rtx.rxbd[rxIdx].length;
+
+		/* Send the packet up if there were no errors */
+		if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
+			NetReceive(NetRxPackets[rxIdx], length - 4);
+		}
+
+		rtx.rxbd[rxIdx].length = 0;
+
+		/* Set the wrap bit if this is the last element in the list */
+		rtx.rxbd[rxIdx].status = RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
+
+		rxIdx = (rxIdx + 1) % PKTBUFSRX;
+	}
+
+	if(regs->ievent&IEVENT_BSY) {
+		regs->ievent = IEVENT_BSY;
+		regs->rstat = RSTAT_CLEAR_RHALT;
+	}
+
+	return -1;
+
+}
+
+
+static void tsec_halt(struct eth_device* dev)
+{
+	tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
+
+	regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
+	regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
+
+	while(!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC)));
+
+	regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
+
+}
+#endif /* CONFIG_TSEC_ENET */
diff --git a/cpu/mpc85xx/tsec.h b/cpu/mpc85xx/tsec.h
new file mode 100644
index 0000000..cfcfd39
--- /dev/null
+++ b/cpu/mpc85xx/tsec.h
@@ -0,0 +1,393 @@
+/*
+ *  tsec.h
+ *
+ *  Driver for the Motorola Triple Speed Ethernet Controller
+ *
+ *  This software may be used and distributed according to the
+ *  terms of the GNU Public License, Version 2, incorporated
+ *  herein by reference.
+ *
+ * (C) Copyright 2003, Motorola, Inc.
+ * maintained by Xianghua Xiao (x.xiao@motorola.com)
+ * author Andy Fleming
+ *
+ */
+
+#ifndef __TSEC_H
+#define __TSEC_H
+
+#include <net.h>
+#include <mpc85xx.h>
+
+#define TSEC_BASE_ADDR	(CFG_IMMR + 0x24000)
+#define TSEC_MEM_SIZE	0x01000
+
+#define MAC_ADDR_LEN 6
+
+#define TSEC_TIMEOUT 	1000000
+#define TOUT_LOOP 	1000000
+
+/* MAC register bits */
+#define MACCFG1_SOFT_RESET	0x80000000
+#define MACCFG1_RESET_RX_MC	0x00080000
+#define MACCFG1_RESET_TX_MC	0x00040000
+#define MACCFG1_RESET_RX_FUN	0x00020000
+#define	MACCFG1_RESET_TX_FUN	0x00010000
+#define MACCFG1_LOOPBACK	0x00000100
+#define MACCFG1_RX_FLOW		0x00000020
+#define MACCFG1_TX_FLOW		0x00000010
+#define MACCFG1_SYNCD_RX_EN	0x00000008
+#define MACCFG1_RX_EN		0x00000004
+#define MACCFG1_SYNCD_TX_EN	0x00000002
+#define MACCFG1_TX_EN		0x00000001
+
+#define MACCFG2_INIT_SETTINGS	0x00007205
+#define MACCFG2_FULL_DUPLEX	0x00000001
+#define MACCFG2_IF              0x00000300
+#define MACCFG2_MII             0x00000100
+
+#define ECNTRL_INIT_SETTINGS	0x00001000
+#define ECNTRL_TBI_MODE         0x00000020
+
+#define TBIPA_VALUE		0x1f
+#define MIIMCFG_INIT_VALUE	0x00000003
+#define MIIMCFG_RESET		0x80000000
+
+#define MIIMIND_BUSY            0x00000001
+#define MIIMIND_NOTVALID        0x00000004
+
+#define MIIM_TBICON		0x11
+#define MIIM_TBICON_GMII	0x00000010
+#define MIIM_TBICON_AN		0x00000100
+
+#define MIIM_CONTROL            0x00
+#define MIIM_CONTROL_INIT       0x00001140
+#define MIIM_ANEN               0x00001000
+
+#define MIIM_TBI_STATUS		0x1
+#define MIIM_TBI_STATUS_AN_DONE 0x00000020
+
+#define MIIM_TBI_ANEX		0x6
+#define MIIM_TBI_ANEX_NP	0x00000004
+#define MIIM_TBI_ANEX_PRX	0x00000002
+
+#define MIIM_TBI_ANLPBPA	0x5
+#define MIIM_TBI_ANLPBPA_HALF	0x00000040
+#define MIIM_TBI_ANLPBPA_FULL	0x00000020
+
+#ifdef CONFIG_PHY_CIS8201
+#define MIIM_AUX_CONSTAT	0x1c
+#define MIIM_AUXCONSTAT_INIT	0x0004
+#define MIIM_AUXCONSTAT_DUPLEX	0x0020
+#define MIIM_AUXCONSTAT_SPEED   0x0018
+#define MIIM_AUXCONSTAT_GBIT    0x0010
+#define MIIM_AUXCONSTAT_100     0x0008
+
+#define MIIM_EXT_CON1		0x17
+#define MIIM_EXTCON1_INIT	0x0000
+
+#endif
+
+#ifdef CONFIG_PHY_M88E1011
+#define MIIM_ANAR		0x04
+#define MIIM_ANAR_ADVERTISEMENT	0x01e1
+
+#define MIIM_GBIT_CON		0x09
+#define MIIM_GBIT_CON_ADVERT	0x1e00
+
+#define MIIM_PHY_STATUS         0x11
+#define MIIM_PHYSTAT_SPEED      0xc000
+#define MIIM_PHYSTAT_GBIT       0x8000
+#define MIIM_PHYSTAT_100        0x4000
+#define MIIM_PHYSTAT_DUPLEX     0x2000
+#define MIIM_PHYSTAT_SPDDONE	0x0800
+#define MIIM_PHYSTAT_LINK	0x0400
+#endif
+
+#define MIIM_READ_COMMAND       0x00000001
+
+#define MRBLR_INIT_SETTINGS	PKTSIZE_ALIGN
+
+#define MINFLR_INIT_SETTINGS	0x00000040
+
+#define DMACTRL_INIT_SETTINGS   0x000000c3
+#define DMACTRL_GRS             0x00000010
+#define DMACTRL_GTS             0x00000008
+
+#define TSTAT_CLEAR_THALT       0x80000000
+#define RSTAT_CLEAR_RHALT       0x00800000
+
+/* Write value to the PHY at phyid to the register at offset, */
+/* using the register space defined in regbase.  Note that */
+/* miimcfg needs to have the clock speed setup correctly.  This */
+/* macro will wait until the write is done before it finishes */
+#define write_phy_reg(regbase, phyid, offset, value) do { \
+	int timeout=1000000; \
+	regbase->miimadd = (phyid << 8) | offset; \
+	regbase->miimcon = value; \
+	asm("msync"); \
+	while((regbase->miimind & MIIMIND_BUSY) && timeout--); \
+} while(0)
+
+
+#define IEVENT_INIT_CLEAR	0xffffffff
+#define IEVENT_BABR		0x80000000
+#define IEVENT_RXC		0x40000000
+#define IEVENT_BSY		0x20000000
+#define IEVENT_EBERR		0x10000000
+#define IEVENT_MSRO		0x04000000
+#define IEVENT_GTSC		0x02000000
+#define IEVENT_BABT		0x01000000
+#define IEVENT_TXC		0x00800000
+#define IEVENT_TXE		0x00400000
+#define IEVENT_TXB		0x00200000
+#define IEVENT_TXF		0x00100000
+#define IEVENT_IE		0x00080000
+#define IEVENT_LC		0x00040000
+#define IEVENT_CRL		0x00020000
+#define IEVENT_XFUN		0x00010000
+#define IEVENT_RXB0		0x00008000
+#define IEVENT_GRSC		0x00000100
+#define IEVENT_RXF0		0x00000080
+
+#define IMASK_INIT_CLEAR	0x00000000
+#define IMASK_TXEEN		0x00400000
+#define IMASK_TXBEN		0x00200000
+#define IMASK_TXFEN             0x00100000
+#define IMASK_RXFEN0		0x00000080
+
+
+/* Default Attribute fields */
+#define ATTR_INIT_SETTINGS     0x000000c0
+#define ATTRELI_INIT_SETTINGS  0x00000000
+
+
+/* TxBD status field bits */
+#define TXBD_READY		0x8000
+#define TXBD_PADCRC		0x4000
+#define TXBD_WRAP		0x2000
+#define TXBD_INTERRUPT		0x1000
+#define TXBD_LAST		0x0800
+#define TXBD_CRC		0x0400
+#define TXBD_DEF		0x0200
+#define TXBD_HUGEFRAME		0x0080
+#define TXBD_LATECOLLISION	0x0080
+#define TXBD_RETRYLIMIT		0x0040
+#define	TXBD_RETRYCOUNTMASK	0x003c
+#define TXBD_UNDERRUN		0x0002
+#define TXBD_STATS              0x03ff
+
+/* RxBD status field bits */
+#define RXBD_EMPTY		0x8000
+#define RXBD_RO1		0x4000
+#define RXBD_WRAP		0x2000
+#define RXBD_INTERRUPT		0x1000
+#define RXBD_LAST		0x0800
+#define RXBD_FIRST		0x0400
+#define RXBD_MISS		0x0100
+#define RXBD_BROADCAST		0x0080
+#define RXBD_MULTICAST		0x0040
+#define RXBD_LARGE		0x0020
+#define RXBD_NONOCTET		0x0010
+#define RXBD_SHORT		0x0008
+#define RXBD_CRCERR		0x0004
+#define RXBD_OVERRUN		0x0002
+#define RXBD_TRUNCATED		0x0001
+#define RXBD_STATS		0x003f
+
+typedef struct txbd8
+{
+	ushort       status;         /* Status Fields */
+	ushort       length;         /* Buffer length */
+	uint         bufPtr;         /* Buffer Pointer */
+} txbd8_t;
+
+typedef struct rxbd8
+{
+	ushort       status;         /* Status Fields */
+	ushort       length;         /* Buffer Length */
+	uint         bufPtr;         /* Buffer Pointer */
+} rxbd8_t;
+
+typedef struct rmon_mib
+{
+	/* Transmit and Receive Counters */
+	uint	tr64;		/* Transmit and Receive 64-byte Frame Counter */
+	uint	tr127;		/* Transmit and Receive 65-127 byte Frame Counter */
+	uint	tr255;		/* Transmit and Receive 128-255 byte Frame Counter */
+	uint	tr511;		/* Transmit and Receive 256-511 byte Frame Counter */
+	uint	tr1k;		/* Transmit and Receive 512-1023 byte Frame Counter */
+	uint	trmax;		/* Transmit and Receive 1024-1518 byte Frame Counter */
+	uint	trmgv;		/* Transmit and Receive 1519-1522 byte Good VLAN Frame */
+	/* Receive Counters */
+	uint	rbyt;		/* Receive Byte Counter */
+	uint	rpkt;		/* Receive Packet Counter */
+	uint	rfcs;		/* Receive FCS Error Counter */
+	uint	rmca;		/* Receive Multicast Packet (Counter) */
+	uint	rbca;		/* Receive Broadcast Packet */
+	uint	rxcf;		/* Receive Control Frame Packet */
+	uint	rxpf;		/* Receive Pause Frame Packet */
+	uint	rxuo;		/* Receive Unknown OP Code */
+	uint	raln;		/* Receive Alignment Error */
+	uint	rflr;		/* Receive Frame Length Error */
+	uint	rcde;		/* Receive Code Error */
+	uint	rcse;		/* Receive Carrier Sense Error */
+	uint	rund;		/* Receive Undersize Packet */
+	uint	rovr;		/* Receive Oversize Packet */
+	uint	rfrg;		/* Receive Fragments */
+	uint	rjbr;		/* Receive Jabber */
+	uint	rdrp;		/* Receive Drop */
+	/* Transmit Counters */
+	uint	tbyt;		/* Transmit Byte Counter */
+	uint	tpkt;		/* Transmit Packet */
+	uint	tmca;		/* Transmit Multicast Packet */
+	uint	tbca;		/* Transmit Broadcast Packet */
+	uint	txpf;		/* Transmit Pause Control Frame */
+	uint	tdfr;		/* Transmit Deferral Packet */
+	uint	tedf;		/* Transmit Excessive Deferral Packet */
+	uint	tscl;		/* Transmit Single Collision Packet */
+	/* (0x2_n700) */
+	uint	tmcl;		/* Transmit Multiple Collision Packet */
+	uint	tlcl;		/* Transmit Late Collision Packet */
+	uint	txcl;		/* Transmit Excessive Collision Packet */
+	uint	tncl;		/* Transmit Total Collision */
+
+	uint	res2;
+
+	uint	tdrp;		/* Transmit Drop Frame */
+	uint	tjbr;		/* Transmit Jabber Frame */
+	uint	tfcs;		/* Transmit FCS Error */
+	uint	txcf;		/* Transmit Control Frame */
+	uint	tovr;		/* Transmit Oversize Frame */
+	uint	tund;		/* Transmit Undersize Frame */
+	uint	tfrg;		/* Transmit Fragments Frame */
+	/* General Registers */
+	uint	car1;		/* Carry Register One */
+	uint	car2;		/* Carry Register Two */
+	uint	cam1;		/* Carry Register One Mask */
+	uint	cam2;		/* Carry Register Two Mask */
+} rmon_mib_t;
+
+typedef struct tsec_hash_regs
+{
+	uint	iaddr0;		/* Individual Address Register 0 */
+	uint	iaddr1;		/* Individual Address Register 1 */
+	uint	iaddr2;		/* Individual Address Register 2 */
+	uint	iaddr3;		/* Individual Address Register 3 */
+	uint	iaddr4;		/* Individual Address Register 4 */
+	uint	iaddr5;		/* Individual Address Register 5 */
+	uint	iaddr6;		/* Individual Address Register 6 */
+	uint	iaddr7;		/* Individual Address Register 7 */
+	uint	res1[24];
+	uint	gaddr0;		/* Group Address Register 0 */
+	uint	gaddr1;		/* Group Address Register 1 */
+	uint	gaddr2;		/* Group Address Register 2 */
+	uint	gaddr3;		/* Group Address Register 3 */
+	uint	gaddr4;		/* Group Address Register 4 */
+	uint	gaddr5;		/* Group Address Register 5 */
+	uint	gaddr6;		/* Group Address Register 6 */
+	uint	gaddr7;		/* Group Address Register 7 */
+	uint	res2[24];
+} tsec_hash_t;
+
+typedef struct tsec
+{
+	/* General Control and Status Registers (0x2_n000) */
+	uint	res000[4];
+
+	uint	ievent;		/* Interrupt Event */
+	uint	imask;		/* Interrupt Mask */
+	uint	edis;		/* Error Disabled */
+	uint	res01c;
+	uint	ecntrl;		/* Ethernet Control */
+	uint	minflr;		/* Minimum Frame Length */
+	uint	ptv;		/* Pause Time Value */
+	uint	dmactrl;	/* DMA Control */
+	uint	tbipa;		/* TBI PHY Address */
+
+	uint	res034[3];
+	uint	res040[48];
+
+	/* Transmit Control and Status Registers (0x2_n100) */
+	uint	tctrl;		/* Transmit Control */
+	uint 	tstat;		/* Transmit Status */
+	uint	res108;
+	uint	tbdlen;		/* Tx BD Data Length */
+	uint	res110[5];
+	uint	ctbptr;	        /* Current TxBD Pointer */
+	uint	res128[23];
+	uint	tbptr;		/* TxBD Pointer */
+	uint	res188[30];
+	/* (0x2_n200) */
+	uint        res200;
+	uint	tbase;		/* TxBD Base Address */
+	uint	res208[42];
+	uint	ostbd;		/* Out of Sequence TxBD */
+	uint	ostbdp;		/* Out of Sequence Tx Data Buffer Pointer */
+	uint        res2b8[18];
+
+	/* Receive Control and Status Registers (0x2_n300) */
+	uint	rctrl;		/* Receive Control */
+	uint	rstat;		/* Receive Status */
+	uint	res308;
+	uint	rbdlen;		/* RxBD Data Length */
+	uint	res310[4];
+	uint        res320;
+	uint	crbptr; 	/* Current Receive Buffer Pointer */
+	uint	res328[6];
+	uint	mrblr;  	/* Maximum Receive Buffer Length */
+	uint	res344[16];
+	uint	rbptr;   	/* RxBD Pointer */
+	uint        res388[30];
+	/* (0x2_n400) */
+	uint        res400;
+	uint	rbase;  	/* RxBD Base Address */
+	uint        res408[62];
+
+	/* MAC Registers (0x2_n500) */
+	uint	maccfg1;	/* MAC Configuration #1 */
+	uint	maccfg2;	/* MAC Configuration #2 */
+	uint	ipgifg;		/* Inter Packet Gap/Inter Frame Gap */
+	uint	hafdup;		/* Half-duplex */
+	uint	maxfrm;		/* Maximum Frame */
+	uint	res514;
+	uint	res518;
+
+	uint	res51c;
+
+	uint	miimcfg;	/* MII Management: Configuration */
+	uint	miimcom;	/* MII Management: Command */
+	uint	miimadd;	/* MII Management: Address */
+	uint	miimcon;	/* MII Management: Control */
+	uint	miimstat;	/* MII Management: Status */
+	uint	miimind;	/* MII Management: Indicators */
+
+	uint	res538;
+
+	uint	ifstat;		/* Interface Status */
+	uint	macstnaddr1;	/* Station Address, part 1 */
+	uint	macstnaddr2;	/* Station Address, part 2 */
+	uint	res548[46];
+
+	/* (0x2_n600) */
+	uint	res600[32];
+
+	/* RMON MIB Registers (0x2_n680-0x2_n73c) */
+	rmon_mib_t	rmon;
+	uint	res740[48];
+
+	/* Hash Function Registers (0x2_n800) */
+	tsec_hash_t	hash;
+
+	uint        res900[128];
+
+	/* Pattern Registers (0x2_nb00) */
+	uint        resb00[62];
+	uint        attr;          /* Default Attribute Register */
+	uint        attreli;       /* Default Attribute Extract Length and Index */
+
+	/* TSEC Future Expansion Space (0x2_nc00-0x2_nffc) */
+	uint	resc00[256];
+} tsec_t;
+
+#endif /* __TSEC_H */