* Some code cleanup

* Patch by Josef Baumgartner, 10 Feb 2004:
  Fixes for Coldfire port

* Patch by Brad Kemp, 11 Feb 2004:
  Fix CFI flash driver problems
diff --git a/cpu/mcf52x2/Makefile b/cpu/mcf52x2/Makefile
new file mode 100644
index 0000000..879deb7
--- /dev/null
+++ b/cpu/mcf52x2/Makefile
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+# CFLAGS += -DET_DEBUG
+
+LIB	= lib$(CPU).a
+
+START	=
+OBJS	= serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
+
+all:	.depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/mcf52x2/config.mk b/cpu/mcf52x2/config.mk
new file mode 100644
index 0000000..650db85
--- /dev/null
+++ b/cpu/mcf52x2/config.mk
@@ -0,0 +1,27 @@
+#
+# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de>
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
+PLATFORM_CPPFLAGS += -m5307
diff --git a/cpu/mcf52x2/cpu.c b/cpu/mcf52x2/cpu.c
new file mode 100644
index 0000000..b012222
--- /dev/null
+++ b/cpu/mcf52x2/cpu.c
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2003
+ * Josef Baumgartner <josef.baumgartner@telex.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>
+
+#ifdef	CONFIG_M5272
+#include <asm/immap_5272.h>
+#include <asm/m5272.h>
+#endif
+
+#ifdef	CONFIG_M5282
+
+#endif
+
+
+#ifdef	CONFIG_M5272
+int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) {
+	volatile wdog_t * wdp = (wdog_t *)(CFG_MBAR + MCFSIM_WRRR);
+
+	wdp->wdog_wrrr = 0;
+	udelay (1000);
+
+	/* enable watchdog, set timeout to 0 and wait */
+	wdp->wdog_wrrr = 1;
+	while (1);
+
+	/* we don't return! */
+	return 0;
+};
+
+int checkcpu(void) {
+	ulong *dirp = (ulong *)(CFG_MBAR + MCFSIM_DIR);
+	uchar msk;
+	char  *suf;
+
+	puts ("CPU:   ");
+	msk = (*dirp > 28) & 0xf;
+	switch (msk) {
+		case 0x2: suf = "1K75N"; break;
+		case 0x4: suf = "3K75N"; break;
+		default:
+			suf = NULL;
+			printf ("MOTOROLA MCF5272 (Mask:%01x)\n", msk);
+			break;
+		}
+
+	if (suf)
+		printf ("MOTOROLA MCF5272 %s\n", suf);
+	return 0;
+};
+
+
+#if defined(CONFIG_WATCHDOG)
+/* Called by macro WATCHDOG_RESET */
+void watchdog_reset (void)
+{
+	volatile immap_t * regp = (volatile immap_t *)CFG_MBAR;
+	regp->wdog_reg.wdog_wcr = 0;
+}
+
+int watchdog_disable (void)
+{
+	volatile immap_t *regp = (volatile immap_t *)CFG_MBAR;
+
+	regp->wdog_reg.wdog_wcr = 0;	/* reset watchdog counter */
+	regp->wdog_reg.wdog_wirr = 0;	/* disable watchdog interrupt */
+	regp->wdog_reg.wdog_wrrr = 0;	/* disable watchdog timer */
+
+	puts ("WATCHDOG:disabled\n");
+	return (0);
+}
+
+int watchdog_init (void)
+{
+	volatile immap_t *regp = (volatile immap_t *)CFG_MBAR;
+
+	regp->wdog_reg.wdog_wirr = 0;	/* disable watchdog interrupt */
+
+	/* set timeout and enable watchdog */
+	regp->wdog_reg.wdog_wrrr = ((CONFIG_WATCHDOG_TIMEOUT * CFG_HZ) / (32768 * 1000)) - 1;
+	regp->wdog_reg.wdog_wcr = 0;	/* reset watchdog counter */
+
+	puts ("WATCHDOG:enabled\n");
+	return (0);
+}
+#endif /* #ifdef CONFIG_WATCHDOG */
+
+#endif /* #ifdef CONFIG_M5272 */
+
+
+#ifdef	CONFIG_M5282
+int checkcpu (void)
+{
+	puts ("CPU:   MOTOROLA Coldfire MCF5282\n");
+	return 0;
+}
+
+int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) {
+	return 0;
+};
+#endif
diff --git a/cpu/mcf52x2/cpu_init.c b/cpu/mcf52x2/cpu_init.c
new file mode 100644
index 0000000..8aff8f1
--- /dev/null
+++ b/cpu/mcf52x2/cpu_init.c
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2003
+ * Josef Baumgartner <josef.baumgartner@telex.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>
+
+#ifdef	CONFIG_M5272
+#include <asm/m5272.h>
+#include <asm/immap_5272.h>
+#endif
+
+#ifdef	CONFIG_M5282
+#include <asm/m5282.h>
+#include <asm/immap_5282.h>
+#endif
+
+#ifdef	CONFIG_M5272
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ * initialize the UPM's
+ */
+void cpu_init_f (void)
+{
+	/* if we come from RAM we assume the CPU is
+	 * already initialized.
+	 */
+#ifndef CONFIG_MONITOR_IS_IN_RAM
+	volatile immap_t *regp = (immap_t *)CFG_MBAR;
+
+	volatile unsigned char	*mbar;
+	mbar = (volatile unsigned char *) CFG_MBAR;
+
+	regp->sysctrl_reg.sc_scr = CFG_SCR;
+	regp->sysctrl_reg.sc_spr = CFG_SPR;
+
+	/* Setup Ports:	*/
+	regp->gpio_reg.gpio_pacnt = CFG_PACNT;
+	regp->gpio_reg.gpio_paddr = CFG_PADDR;
+	regp->gpio_reg.gpio_padat = CFG_PADAT;
+	regp->gpio_reg.gpio_pbcnt = CFG_PBCNT;
+	regp->gpio_reg.gpio_pbddr = CFG_PBDDR;
+	regp->gpio_reg.gpio_pbdat = CFG_PBDAT;
+	regp->gpio_reg.gpio_pdcnt = CFG_PDCNT;
+
+	/* Memory Controller: */
+	regp->csctrl_reg.cs_br0 = CFG_BR0_PRELIM;
+	regp->csctrl_reg.cs_or0 = CFG_OR0_PRELIM;
+
+#if (defined(CFG_OR1_PRELIM) && defined(CFG_BR1_PRELIM))
+	regp->csctrl_reg.cs_br1 = CFG_BR1_PRELIM;
+	regp->csctrl_reg.cs_or1 = CFG_OR1_PRELIM;
+#endif
+
+#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM)
+	regp->csctrl_reg.cs_br2 = CFG_BR2_PRELIM;
+	regp->csctrl_reg.cs_or2 = CFG_OR2_PRELIM;
+#endif
+
+#if defined(CFG_OR3_PRELIM) && defined(CFG_BR3_PRELIM)
+	regp->csctrl_reg.cs_br3 = CFG_BR3_PRELIM;
+	regp->csctrl_reg.cs_or3 = CFG_OR3_PRELIM;
+#endif
+
+#if defined(CFG_OR4_PRELIM) && defined(CFG_BR4_PRELIM)
+	regp->csctrl_reg.cs_br4 = CFG_BR4_PRELIM;
+	regp->csctrl_reg.cs_or4 = CFG_OR4_PRELIM;
+#endif
+
+#if defined(CFG_OR5_PRELIM) && defined(CFG_BR5_PRELIM)
+	regp->csctrl_reg.cs_br5 = CFG_BR5_PRELIM;
+	regp->csctrl_reg.cs_or5 = CFG_OR5_PRELIM;
+#endif
+
+#if defined(CFG_OR6_PRELIM) && defined(CFG_BR6_PRELIM)
+	regp->csctrl_reg.cs_br6 = CFG_BR6_PRELIM;
+	regp->csctrl_reg.cs_or6 = CFG_OR6_PRELIM;
+#endif
+
+#if defined(CFG_OR7_PRELIM) && defined(CFG_BR7_PRELIM)
+	regp->csctrl_reg.cs_br7 = CFG_BR7_PRELIM;
+	regp->csctrl_reg.cs_or7 = CFG_OR7_PRELIM;
+#endif
+
+#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */
+
+    /* enable instruction cache now */
+    icache_enable();
+
+}
+
+/*
+ * initialize higher level parts of CPU like timers
+ */
+int cpu_init_r  (void)
+{
+	return (0);
+}
+#endif /* #ifdef CONFIG_M5272 */
+
+
+#ifdef	CONFIG_M5282
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ * initialize the UPM's
+ */
+void cpu_init_f (void)
+{
+
+}
+
+/*
+ * initialize higher level parts of CPU like timers
+ */
+int cpu_init_r  (void)
+{
+	return (0);
+}
+#endif
diff --git a/cpu/mcf52x2/fec.c b/cpu/mcf52x2/fec.c
new file mode 100644
index 0000000..623a01d
--- /dev/null
+++ b/cpu/mcf52x2/fec.c
@@ -0,0 +1,558 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/fec.h>
+
+#ifdef	CONFIG_M5272
+#include <asm/m5272.h>
+#include <asm/immap_5272.h>
+#endif
+
+#ifdef	CONFIG_M5282
+#include <asm/m5282.h>
+#include <asm/immap_5282.h>
+#endif
+
+#include <net.h>
+#include <command.h>
+
+#ifdef	CONFIG_M5272
+#define FEC_ADDR		(CFG_MBAR + 0x840)
+#endif
+#ifdef CONFIG_M5282
+#define FEC_ADDR 		(CFG_MBAR + 0x1000)
+#endif
+
+#undef	ET_DEBUG
+#undef	MII_DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
+
+#ifdef CFG_DISCOVER_PHY
+#include <miiphy.h>
+static void mii_discover_phy (void);
+#endif
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH  1520
+
+#define TX_BUF_CNT 2
+
+#define TOUT_LOOP 100
+
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1520
+
+
+static char txbuf[DBUF_LENGTH];
+
+static uint rxIdx;		/* index of the current RX buffer */
+static uint txIdx;		/* index of the current TX buffer */
+
+/*
+  * FEC Ethernet Tx and Rx buffer descriptors allocated at the
+  *  immr->udata_bd address on Dual-Port RAM
+  * Provide for Double Buffering
+  */
+
+typedef volatile struct CommonBufferDescriptor {
+	cbd_t rxbd[PKTBUFSRX];	/* Rx BD */
+	cbd_t txbd[TX_BUF_CNT];	/* Tx BD */
+} RTXBD;
+
+static RTXBD *rtx = NULL;
+
+int eth_send (volatile void *packet, int length)
+{
+	int j, rc;
+	volatile fec_t *fecp = (fec_t *) (FEC_ADDR);
+
+	/* section 16.9.23.3
+	 * Wait for ready
+	 */
+	j = 0;
+	while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY)
+	       && (j < TOUT_LOOP)) {
+		udelay (1);
+		j++;
+	}
+	if (j >= TOUT_LOOP) {
+		printf ("TX not ready\n");
+	}
+
+	rtx->txbd[txIdx].cbd_bufaddr = (uint) packet;
+	rtx->txbd[txIdx].cbd_datlen = length;
+	rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST;
+
+	/* Activate transmit Buffer Descriptor polling */
+	fecp->fec_x_des_active = 0x01000000;	/* Descriptor polling active    */
+
+	j = 0;
+	while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY)
+	       && (j < TOUT_LOOP)) {
+		udelay (1);
+		j++;
+	}
+	if (j >= TOUT_LOOP) {
+		printf ("TX timeout\n");
+	}
+#ifdef ET_DEBUG
+	printf ("%s[%d] %s: cycles: %d    status: %x  retry cnt: %d\n",
+		__FILE__, __LINE__, __FUNCTION__, j, rtx->txbd[txIdx].cbd_sc,
+		(rtx->txbd[txIdx].cbd_sc & 0x003C) >> 2);
+#endif
+
+	/* return only status bits */ ;
+	rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS);
+
+	txIdx = (txIdx + 1) % TX_BUF_CNT;
+
+	return rc;
+}
+
+int eth_rx (void)
+{
+	int length;
+	volatile fec_t *fecp = (fec_t *) FEC_ADDR;
+
+	for (;;) {
+		/* section 16.9.23.2 */
+		if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+			length = -1;
+			break;	/* nothing received - leave for() loop */
+		}
+
+		length = rtx->rxbd[rxIdx].cbd_datlen;
+
+		if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
+#ifdef ET_DEBUG
+			printf ("%s[%d] err: %x\n",
+				__FUNCTION__, __LINE__,
+				rtx->rxbd[rxIdx].cbd_sc);
+#endif
+		} else {
+			/* Pass the packet up to the protocol layers. */
+			NetReceive (NetRxPackets[rxIdx], length - 4);
+		}
+
+		/* Give the buffer back to the FEC. */
+		rtx->rxbd[rxIdx].cbd_datlen = 0;
+
+		/* wrap around buffer index when necessary */
+		if ((rxIdx + 1) >= PKTBUFSRX) {
+			rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
+				(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+			rxIdx = 0;
+		} else {
+			rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+			rxIdx++;
+		}
+
+		/* Try to fill Buffer Descriptors */
+		fecp->fec_r_des_active = 0x01000000;	/* Descriptor polling active    */
+	}
+
+	return length;
+}
+
+/**************************************************************
+ *
+ * FEC Ethernet Initialization Routine
+ *
+ *************************************************************/
+#define FEC_ECNTRL_ETHER_EN	0x00000002
+#define FEC_ECNTRL_RESET	0x00000001
+
+#define FEC_RCNTRL_BC_REJ	0x00000010
+#define FEC_RCNTRL_PROM		0x00000008
+#define FEC_RCNTRL_MII_MODE	0x00000004
+#define FEC_RCNTRL_DRT		0x00000002
+#define FEC_RCNTRL_LOOP		0x00000001
+
+#define FEC_TCNTRL_FDEN		0x00000004
+#define FEC_TCNTRL_HBC		0x00000002
+#define FEC_TCNTRL_GTS		0x00000001
+
+#define	FEC_RESET_DELAY		50000
+
+int eth_init (bd_t * bd)
+{
+
+	int i;
+	volatile fec_t *fecp = (fec_t *) (FEC_ADDR);
+
+	/* Whack a reset.
+	 * A delay is required between a reset of the FEC block and
+	 * initialization of other FEC registers because the reset takes
+	 * some time to complete. If you don't delay, subsequent writes
+	 * to FEC registers might get killed by the reset routine which is
+	 * still in progress.
+	 */
+	fecp->fec_ecntrl = FEC_ECNTRL_RESET;
+	for (i = 0;
+	     (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+	     ++i) {
+		udelay (1);
+	}
+	if (i == FEC_RESET_DELAY) {
+		printf ("FEC_RESET_DELAY timeout\n");
+		return 0;
+	}
+
+	/* We use strictly polling mode only
+	 */
+	fecp->fec_imask = 0;
+
+	/* Clear any pending interrupt */
+	fecp->fec_ievent = 0xffffffff;
+
+	/* Set station address   */
+#define ea bd->bi_enetaddr
+	fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) |
+		(ea[2] << 8) | (ea[3]);
+	fecp->fec_addr_high = (ea[4] << 24) | (ea[5] << 16);
+#ifdef ET_DEBUG
+	printf ("Eth Addrs: %02x:%02x:%02x:%02x:%02x:%02x\n",
+		ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
+#endif
+#undef ea
+
+	/* Clear multicast address hash table
+	 */
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low = 0;
+
+	/* Set maximum receive buffer size.
+	 */
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+
+	/*
+	 * Setup Buffers and Buffer Desriptors
+	 */
+	rxIdx = 0;
+	txIdx = 0;
+
+	if (!rtx) {
+		rtx = (RTXBD *) CFG_ENET_BD_BASE;
+	}
+
+	/*
+	 * Setup Receiver Buffer Descriptors (13.14.24.18)
+	 * Settings:
+	 *     Empty, Wrap
+	 */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+		rtx->rxbd[i].cbd_datlen = 0;	/* Reset */
+		rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+	}
+	rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+	/*
+	 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+	 * Settings:
+	 *    Last, Tx CRC
+	 */
+	for (i = 0; i < TX_BUF_CNT; i++) {
+		rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
+		rtx->txbd[i].cbd_datlen = 0;	/* Reset */
+		rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
+	}
+	rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+	/* Set receive and transmit descriptor base
+	 */
+	fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
+	fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
+
+	/* Enable MII mode
+	 */
+#if 0				/* Full duplex mode */
+	fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE;
+	fecp->fec_x_cntrl = FEC_TCNTRL_FDEN;
+#else  /* Half duplex mode */
+	fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
+	fecp->fec_x_cntrl = 0;
+#endif
+	/* Set MII speed */
+	fecp->fec_mii_speed = 0x0e;
+
+	/* Configure port B for MII.
+	 */
+	/* port initialization was already made in cpu_init_f() */
+
+	/* Now enable the transmit and receive processing
+	 */
+	fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN;
+
+#ifdef CFG_DISCOVER_PHY
+	/* wait for the PHY to wake up after reset */
+	mii_discover_phy ();
+#endif
+
+	/* And last, try to fill Rx Buffer Descriptors */
+	fecp->fec_r_des_active = 0x01000000;	/* Descriptor polling active    */
+
+	return 1;
+}
+
+void eth_halt (void)
+{
+	volatile fec_t *fecp = (fec_t *) FEC_ADDR;
+
+	fecp->fec_ecntrl = 0;
+}
+
+
+#if defined(CFG_DISCOVER_PHY) || (CONFIG_COMMANDS & CFG_CMD_MII)
+
+static int phyaddr = -1;	/* didn't find a PHY yet */
+static uint phytype;
+
+/* Make MII read/write commands for the FEC.
+*/
+
+#define mk_mii_read(ADDR, REG)	(0x60020000 | ((ADDR << 23) | \
+						(REG & 0x1f) << 18))
+
+#define mk_mii_write(ADDR, REG, VAL)	(0x50020000 | ((ADDR << 23) | \
+						(REG & 0x1f) << 18) | \
+						(VAL & 0xffff))
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR	((uint)0x80000000)	/* Heartbeat error */
+#define FEC_ENET_BABR	((uint)0x40000000)	/* Babbling receiver */
+#define FEC_ENET_BABT	((uint)0x20000000)	/* Babbling transmitter */
+#define FEC_ENET_GRA	((uint)0x10000000)	/* Graceful stop complete */
+#define FEC_ENET_TXF	((uint)0x08000000)	/* Full frame transmitted */
+#define FEC_ENET_TXB	((uint)0x04000000)	/* A buffer was transmitted */
+#define FEC_ENET_RXF	((uint)0x02000000)	/* Full frame received */
+#define FEC_ENET_RXB	((uint)0x01000000)	/* A buffer was received */
+#define FEC_ENET_MII	((uint)0x00800000)	/* MII interrupt */
+#define FEC_ENET_EBERR	((uint)0x00400000)	/* SDMA bus error */
+
+/* PHY identification
+ */
+#define PHY_ID_LXT970		0x78100000	/* LXT970 */
+#define PHY_ID_LXT971		0x001378e0	/* LXT971 and 972 */
+#define PHY_ID_82555		0x02a80150	/* Intel 82555 */
+#define PHY_ID_QS6612		0x01814400	/* QS6612 */
+#define PHY_ID_AMD79C784	0x00225610	/* AMD 79C784 */
+#define PHY_ID_LSI80225		0x0016f870	/* LSI 80225 */
+#define PHY_ID_LSI80225B	0x0016f880	/* LSI 80225/B */
+
+/* send command to phy using mii, wait for result */
+static uint mii_send (uint mii_cmd)
+{
+	uint mii_reply;
+	volatile fec_t *ep = (fec_t *) (FEC_ADDR);
+
+	ep->fec_mii_data = mii_cmd;	/* command to phy */
+
+	/* wait for mii complete */
+	while (!(ep->fec_ievent & FEC_ENET_MII));	/* spin until done */
+	mii_reply = ep->fec_mii_data;	/* result from phy */
+	ep->fec_ievent = FEC_ENET_MII;	/* clear MII complete */
+#ifdef ET_DEBUG
+	printf ("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
+		__FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply);
+#endif
+	return (mii_reply & 0xffff);	/* data read from phy */
+}
+#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */
+
+#if defined(CFG_DISCOVER_PHY)
+static void mii_discover_phy (void)
+{
+#define MAX_PHY_PASSES 11
+	uint phyno;
+	int pass;
+
+	phyaddr = -1;		/* didn't find a PHY yet */
+	for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
+		if (pass > 1) {
+			/* PHY may need more time to recover from reset.
+			 * The LXT970 needs 50ms typical, no maximum is
+			 * specified, so wait 10ms before try again.
+			 * With 11 passes this gives it 100ms to wake up.
+			 */
+			udelay (10000);	/* wait 10ms */
+		}
+		for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
+			phytype = mii_send (mk_mii_read (phyno, PHY_PHYIDR1));
+#ifdef ET_DEBUG
+			printf ("PHY type 0x%x pass %d type ", phytype, pass);
+#endif
+			if (phytype != 0xffff) {
+				phyaddr = phyno;
+				phytype <<= 16;
+				phytype |= mii_send (mk_mii_read (phyno,
+								  PHY_PHYIDR2));
+
+#ifdef ET_DEBUG
+				printf ("PHY @ 0x%x pass %d type ", phyno,
+					pass);
+				switch (phytype & 0xfffffff0) {
+				case PHY_ID_LXT970:
+					printf ("LXT970\n");
+					break;
+				case PHY_ID_LXT971:
+					printf ("LXT971\n");
+					break;
+				case PHY_ID_82555:
+					printf ("82555\n");
+					break;
+				case PHY_ID_QS6612:
+					printf ("QS6612\n");
+					break;
+				case PHY_ID_AMD79C784:
+					printf ("AMD79C784\n");
+					break;
+				case PHY_ID_LSI80225B:
+					printf ("LSI L80225/B\n");
+					break;
+				default:
+					printf ("0x%08x\n", phytype);
+					break;
+				}
+#endif
+			}
+		}
+	}
+	if (phyaddr < 0) {
+		printf ("No PHY device found.\n");
+	}
+}
+#endif /* CFG_DISCOVER_PHY */
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)
+
+static int mii_init_done = 0;
+
+/****************************************************************************
+ * mii_init -- Initialize the MII for MII command without ethernet
+ * This function is a subset of eth_init
+ ****************************************************************************
+ */
+void mii_init (void)
+{
+	volatile fec_t *fecp = (fec_t *) (FEC_ADDR);
+
+	int i;
+
+	if (mii_init_done != 0) {
+		return;
+	}
+
+	/* Whack a reset.
+	 * A delay is required between a reset of the FEC block and
+	 * initialization of other FEC registers because the reset takes
+	 * some time to complete. If you don't delay, subsequent writes
+	 * to FEC registers might get killed by the reset routine which is
+	 * still in progress.
+	 */
+
+	fecp->fec_ecntrl = FEC_ECNTRL_RESET;
+	for (i = 0;
+	     (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+	     ++i) {
+		udelay (1);
+	}
+	if (i == FEC_RESET_DELAY) {
+		printf ("FEC_RESET_DELAY timeout\n");
+		return;
+	}
+
+	/* We use strictly polling mode only
+	 */
+	fecp->fec_imask = 0;
+
+	/* Clear any pending interrupt
+	 */
+	fecp->fec_ievent = 0xffffffff;
+
+	/* Set MII speed */
+	fecp->fec_mii_speed = 0x0e;
+
+	/* Configure port B for MII.
+	 */
+	/* port initialization was already made in cpu_init_f() */
+
+	/* Now enable the transmit and receive processing */
+	fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN;
+
+	mii_init_done = 1;
+}
+
+/*****************************************************************************
+ * Read and write a MII PHY register, routines used by MII Utilities
+ *
+ * FIXME: These routines are expected to return 0 on success, but mii_send
+ *	  does _not_ return an error code. Maybe 0xFFFF means error, i.e.
+ *	  no PHY connected...
+ *	  For now always return 0.
+ * FIXME: These routines only work after calling eth_init() at least once!
+ *	  Otherwise they hang in mii_send() !!! Sorry!
+ *****************************************************************************/
+
+int miiphy_read (unsigned char addr, unsigned char reg, unsigned short *value)
+{
+	short rdreg;		/* register working value */
+
+#ifdef MII_DEBUG
+	printf ("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
+#endif
+	rdreg = mii_send (mk_mii_read (addr, reg));
+
+	*value = rdreg;
+
+#ifdef MII_DEBUG
+	printf ("0x%04x\n", *value);
+#endif
+
+	return 0;
+}
+
+int miiphy_write (unsigned char addr, unsigned char reg, unsigned short value)
+{
+	short rdreg;		/* register working value */
+
+#ifdef MII_DEBUG
+	printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
+#endif
+
+	rdreg = mii_send (mk_mii_write (addr, reg, value));
+
+#ifdef MII_DEBUG
+	printf ("0x%04x\n", value);
+#endif
+
+	return 0;
+}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII) */
+
+#endif /* CFG_CMD_NET, FEC_ENET */
diff --git a/cpu/mcf52x2/interrupts.c b/cpu/mcf52x2/interrupts.c
new file mode 100644
index 0000000..fa181d9
--- /dev/null
+++ b/cpu/mcf52x2/interrupts.c
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de>
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/processor.h>
+
+#ifdef	CONFIG_M5272
+#include <asm/m5272.h>
+#include <asm/immap_5272.h>
+#endif
+
+#ifdef	CONFIG_M5282
+#include <asm/m5282.h>
+#include <asm/immap_5282.h>
+#endif
+
+
+#define	NR_IRQS		31
+
+/*
+ * Interrupt vector functions.
+ */
+struct interrupt_action {
+	interrupt_handler_t *handler;
+	void *arg;
+}
+
+static struct interrupt_action irq_vecs[NR_IRQS];
+
+static __inline__ unsigned short get_sr (void)
+{
+	unsigned short sr;
+
+	asm volatile ("move.w %%sr,%0":"=r" (sr):);
+
+	return sr;
+}
+
+static __inline__ void set_sr (unsigned short sr)
+{
+	asm volatile ("move.w %0,%%sr"::"r" (sr));
+}
+
+/************************************************************************/
+/*
+ * Install and free an interrupt handler
+ */
+void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
+{
+#ifdef	CONFIG_M5272
+	volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
+#endif
+	int vec_base = 0;
+
+#ifdef	CONFIG_M5272
+	vec_base = intp->int_pivr & 0xe0;
+#endif
+
+	if ((vec < vec_base) || (vec > vec_base + NR_IRQS)) {
+		printf ("irq_install_handler: wrong interrupt vector %d\n",
+			vec);
+		return;
+	}
+
+	irq_vecs[vec - vec_base].handler = handler;
+	irq_vecs[vec - vec_base].arg = arg;
+}
+
+void irq_free_handler (int vec)
+{
+#ifdef	CONFIG_M5272
+	volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
+#endif
+	int vec_base = 0;
+
+#ifdef	CONFIG_M5272
+	vec_base = intp->int_pivr & 0xe0;
+#endif
+
+	if ((vec < vec_base) || (vec > vec_base + NR_IRQS)) {
+		return;
+	}
+
+	irq_vecs[vec - vec_base].handler = NULL;
+	irq_vecs[vec - vec_base].arg = NULL;
+}
+
+void enable_interrupts (void)
+{
+	unsigned short sr;
+
+	sr = get_sr ();
+	set_sr (sr & ~0x0700);
+}
+
+int disable_interrupts (void)
+{
+	unsigned short sr;
+
+	sr = get_sr ();
+	set_sr (sr | 0x0700);
+
+	return ((sr & 0x0700) == 0);	/* return TRUE, if interrupts were enabled before */
+}
+
+void int_handler (struct pt_regs *fp)
+{
+#ifdef	CONFIG_M5272
+	volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
+#endif
+	int vec, vec_base = 0;
+
+	vec = (fp->vector >> 2) & 0xff;
+#ifdef	CONFIG_M5272
+	vec_base = intp->int_pivr & 0xe0;
+#endif
+
+	if (irq_vecs[vec - vec_base].handler != NULL) {
+		irq_vecs[vec -
+			 vec_base].handler (irq_vecs[vec - vec_base].arg);
+	} else {
+		printf ("\nBogus External Interrupt Vector %ld\n", vec);
+	}
+}
+
+#ifdef	CONFIG_M5272
+int interrupt_init (void)
+{
+	volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
+
+	/* disable all external interrupts */
+	intp->int_icr1 = 0x88888888;
+	intp->int_icr2 = 0x88888888;
+	intp->int_icr3 = 0x88888888;
+	intp->int_icr4 = 0x88888888;
+	intp->int_pitr = 0x00000000;
+	/* initialize vector register */
+	intp->int_pivr = 0x40;
+
+	enable_interrupts ();
+
+	return 0;
+}
+#endif
+
+#ifdef	CONFIG_M5282
+int interrupt_init (void)
+{
+	return 0;
+}
+#endif
diff --git a/cpu/mcf52x2/serial.c b/cpu/mcf52x2/serial.c
new file mode 100644
index 0000000..fbbd14d
--- /dev/null
+++ b/cpu/mcf52x2/serial.c
@@ -0,0 +1,159 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+
+#include <asm/mcfuart.h>
+
+#ifdef CONFIG_M5272
+#include <asm/m5272.h>
+#endif
+
+#ifdef CONFIG_M5282
+#include <asm/m5282.h>
+#endif
+
+#define DoubleClock(a) ((double)(CFG_CLK) / 32.0 / (double)(a))
+
+void rs_serial_setbaudrate(int port,int baudrate)
+{
+#ifdef CONFIG_M5272
+	volatile unsigned char	*uartp;
+	double clock, fraction;
+
+	if (port == 0)
+	  uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+	else
+	  uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
+
+	clock = DoubleClock(baudrate);      /* Set baud above */
+
+	fraction = ((clock - (int)clock) * 16.0) + 0.5;
+
+	uartp[MCFUART_UBG1] = (((int)clock >> 8) & 0xff);  /* set msb baud */
+	uartp[MCFUART_UBG2] = ((int)clock & 0xff);  /* set lsb baud */
+	uartp[MCFUART_UFPD] = ((int)fraction & 0xf);  /* set baud fraction adjust */
+#endif
+};
+
+void rs_serial_init(int port,int baudrate)
+{
+	volatile unsigned char	*uartp;
+
+	/*
+	 *	Reset UART, get it into known state...
+	 */
+	if (port == 0)
+		uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+	else
+		uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
+
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;  /* reset RX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX;  /* reset TX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR;  /* reset MR pointer */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR;  /* reset Error pointer */
+
+	/*
+	 * Set port for CONSOLE_BAUD_RATE, 8 data bits, 1 stop bit, no parity.
+	 */
+	uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8;
+	uartp[MCFUART_UMR] = MCFUART_MR2_STOP1;
+
+	rs_serial_setbaudrate(port,baudrate);
+
+	uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
+	uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
+
+	return;
+}
+
+/****************************************************************************/
+/*
+ *	Output a single character, using UART polled mode.
+ *	This is used for console output.
+ */
+
+void rs_put_char(char ch)
+{
+	volatile unsigned char	*uartp;
+	int			i;
+
+	uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+
+	for (i = 0; (i < 0x10000); i++) {
+		if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY)
+			break;
+	}
+	uartp[MCFUART_UTB] = ch;
+	return;
+}
+
+int rs_is_char(void)
+{
+	volatile unsigned char	*uartp;
+
+	uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+	return((uartp[MCFUART_USR] & MCFUART_USR_RXREADY) ? 1 : 0);
+}
+
+int rs_get_char(void)
+{
+	volatile unsigned char	*uartp;
+
+	uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+	return(uartp[MCFUART_URB]);
+}
+
+void serial_setbrg(void) {
+	DECLARE_GLOBAL_DATA_PTR;
+	rs_serial_setbaudrate(0,gd->bd->bi_baudrate);
+}
+
+int serial_init(void) {
+	DECLARE_GLOBAL_DATA_PTR;
+	rs_serial_init(0,gd->baudrate);
+	return 0;
+}
+
+
+void serial_putc(const char c) {
+	if (c == '\n')
+		serial_putc ('\r');
+	rs_put_char(c);
+}
+
+void serial_puts (const char *s) {
+	while (*s) {
+		serial_putc(*s++);
+	}
+}
+
+int serial_getc(void) {
+	while(!rs_is_char());
+	return rs_get_char();
+}
+
+int serial_tstc() {
+	return rs_is_char();
+}
diff --git a/cpu/mcf52x2/speed.c b/cpu/mcf52x2/speed.c
new file mode 100644
index 0000000..8d5c92f
--- /dev/null
+++ b/cpu/mcf52x2/speed.c
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2003
+ * Josef Baumgartner <josef.baumgartner@telex.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+/*
+ * get_clocks() fills in gd->cpu_clock and gd->bus_clk
+ */
+int get_clocks (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->cpu_clk = CFG_CLK;
+	gd->bus_clk = gd->cpu_clk;
+	return (0);
+}
diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S
new file mode 100644
index 0000000..cf1b97d
--- /dev/null
+++ b/cpu/mcf52x2/start.S
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2003	Josef Baumgartner <josef.baumgartner@telex.de>
+ * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include "version.h"
+
+#ifndef	 CONFIG_IDENT_STRING
+#define	 CONFIG_IDENT_STRING ""
+#endif
+
+
+#define _START	_start
+#define _FAULT	_fault
+
+
+#define SAVE_ALL						\
+	move.w	#0x2700,%sr;		/* disable intrs */	\
+	subl	#60,%sp;		/* space for 15 regs */ \
+	moveml	%d0-%d7/%a0-%a6,%sp@;				\
+
+#define RESTORE_ALL						\
+	moveml	%sp@,%d0-%d7/%a0-%a6;				\
+	addl	#60,%sp;		/* space for 15 regs */ \
+	rte
+
+/* If we come from a pre-loader we don't need an initial exception
+ * table.
+ */
+#if !defined(CONFIG_MONITOR_IS_IN_RAM)
+
+.text
+/*
+ *	Vector table. This is used for initial platform startup.
+ *	These vectors are to catch any un-intended traps.
+ */
+_vectors:
+
+.long	0x00000000, _START
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
+
+#endif
+
+	.text
+
+	.globl	_start
+_start:
+	nop
+	nop
+	move.w #0x2700,%sr
+
+	/* if we come from a pre-loader we have no exception table and
+	 * therefore no VBR to set
+	 */
+#if !defined(CONFIG_MONITOR_IS_IN_RAM)
+	move.l	#CFG_FLASH_BASE, %d0
+	movec	%d0, %VBR
+#endif
+
+#ifdef CONFIG_M5272
+	move.l	#(CFG_MBAR + 1), %d0		/* set MBAR address + valid flag */
+	move.c	%d0, %MBAR
+
+	move.l	#(CFG_INIT_RAM_ADDR + 1), %d0
+	movec	%d0, %RAMBAR0
+#endif
+
+#ifdef CONFIG_M5282
+	/* Initialize IPSBAR */
+	move.l	#(CFG_MBAR + 1), %d0		/* set IPSBAR address + valid flag */
+	move.l	%d0, 0x40000000
+
+	/* Initialize FLASHBAR: locate internal Flash and validate it */
+	move.l	#(CFG_INT_FLASH_BASE + 0x21), %d0
+	movec	%d0, %RAMBAR0
+
+	/* Initialize RAMBAR1: locate SRAM and validate it */
+	move.l	#(CFG_INIT_RAM_ADDR + 0x21), %d0
+	movec	%d0, %RAMBAR1
+#endif
+
+	/* invalidate and disable cache */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0, %d0
+	movec	%d0, %ACR0
+	movec	%d0, %ACR1
+
+	/* set stackpointer to end of internal ram to get some stackspace for the first c-code */
+	move.l	#(CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET), %sp
+	clr.l %sp@-
+
+	move.l #__got_start, %a5		/* put relocation table address to a5 */
+
+	bsr cpu_init_f				/* run low-level CPU init code (from flash) */
+	bsr board_init_f			/* run low-level board init code (from flash) */
+
+	/* board_init_f() does not return
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * 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:
+	link.w %a6,#0
+	move.l 8(%a6), %sp		/* set new stack pointer */
+
+	move.l 12(%a6), %d0		/* Save copy of Global Data pointer */
+	move.l 16(%a6), %a0		/* Save copy of Destination Address */
+
+	move.l #CFG_MONITOR_BASE, %a1
+	move.l #__init_end, %a2
+	move.l %a0, %a3
+
+	/* copy the code to RAM */
+1:
+	move.l (%a1)+, (%a3)+
+	cmp.l  %a1,%a2
+	bgt.s	 1b
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+	move.l	%a0, %a1
+	add.l	#(in_ram - CFG_MONITOR_BASE), %a1
+	jmp	(%a1)
+
+in_ram:
+
+clear_bss:
+	/*
+	 * Now clear BSS segment
+	 */
+	move.l	%a0, %a1
+	add.l	#(_sbss - CFG_MONITOR_BASE),%a1
+	move.l	%a0, %d1
+	add.l	#(_ebss - CFG_MONITOR_BASE),%d1
+6:
+	clr.l	(%a1)+
+	cmp.l	%a1,%d1
+	bgt.s	6b
+
+	/*
+	 * fix got table in RAM
+	 */
+	move.l	%a0, %a1
+	add.l	#(__got_start - CFG_MONITOR_BASE),%a1
+	move.l	%a1,%a5		/* * fix got pointer register a5 */
+
+	move.l	%a0, %a2
+	add.l	#(__got_end - CFG_MONITOR_BASE),%a2
+
+7:
+	move.l	(%a1),%d1
+	sub.l	#_start,%d1
+	add.l	%a0,%d1
+	move.l	%d1,(%a1)+
+	cmp.l	%a2, %a1
+	bne	7b
+
+	/* calculate relative jump to board_init_r in ram */
+	move.l %a0, %a1
+	add.l #(board_init_r - CFG_MONITOR_BASE), %a1
+
+	/* set parameters for board_init_r */
+	move.l %a0,-(%sp)		/* dest_addr */
+	move.l %d0,-(%sp)		/* gd */
+	jsr	(%a1)
+
+/*------------------------------------------------------------------------------*/
+/* exception code */
+	.globl _fault
+_fault:
+	jmp _fault
+
+	.globl	_exc_handler
+_exc_handler:
+	SAVE_ALL
+	movel	%sp,%sp@-
+	bsr exc_handler
+	addql	#4,%sp
+	RESTORE_ALL
+
+	.globl	_int_handler
+_int_handler:
+	SAVE_ALL
+	movel	%sp,%sp@-
+	bsr int_handler
+	addql	#4,%sp
+	RESTORE_ALL
+
+/*------------------------------------------------------------------------------*/
+/* cache functions */
+#ifdef	CONFIG_M5272
+	.globl	icache_enable
+icache_enable:
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x0000c000, %d0		/* Setup cache mask */
+	movec	%d0, %ACR0			/* Enable cache */
+	move.l	#0xff00c000, %d0		/* Setup cache mask */
+	movec	%d0, %ACR1			/* Enable cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	moveq	#1, %d0
+	move.l	%d0, icache_state
+	rts
+#endif
+
+#ifdef CONFIG_M5282
+	.globl	icache_enable
+icache_enable:
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x0000c000, %d0		/* Setup cache mask */
+	movec	%d0, %ACR0			/* Enable cache */
+	move.l	#0xff00c000, %d0		/* Setup cache mask */
+	movec	%d0, %ACR1			/* Enable cache */
+	move.l	#0x80400100, %d0		/* Setup cache mask, data cache disabel*/
+	movec	%d0, %CACR			/* Enable cache */
+	moveq	#1, %d0
+	move.l	%d0, icache_state
+	rts
+#endif
+
+	.globl	icache_disable
+icache_disable:
+	move.l	#0x00000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	clr.l	%d0				/* Setup cache mask */
+	movec	%d0, %ACR0			/* Enable cache */
+	movec	%d0, %ACR1			/* Enable cache */
+	moveq	#0, %d0
+	move.l	%d0, icache_state
+	rts
+
+	.globl	icache_status
+icache_status:
+	move.l	icache_state, %d0
+	rts
+
+	.data
+icache_state:
+	.long	1
+
+/*------------------------------------------------------------------------------*/
+
+	.globl	version_string
+version_string:
+	.ascii U_BOOT_VERSION
+	.ascii " (", __DATE__, " - ", __TIME__, ")"
+	.ascii CONFIG_IDENT_STRING, "\0"