* 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"