Move arch/ppc to arch/powerpc

As discussed on the list, move "arch/ppc" to "arch/powerpc" to
better match the Linux directory structure.

Please note that this patch also changes the "ppc" target in
MAKEALL to "powerpc" to match this new infrastructure. But "ppc"
is kept as an alias for now, to not break compatibility with
scripts using this name.

Signed-off-by: Stefan Roese <sr@denx.de>
Acked-by: Wolfgang Denk <wd@denx.de>
Acked-by: Detlev Zundel <dzu@denx.de>
Acked-by: Kim Phillips <kim.phillips@freescale.com>
Cc: Peter Tyser <ptyser@xes-inc.com>
Cc: Anatolij Gustschin <agust@denx.de>
diff --git a/arch/powerpc/cpu/mpc824x/.gitignore b/arch/powerpc/cpu/mpc824x/.gitignore
new file mode 100644
index 0000000..2d79931
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/.gitignore
@@ -0,0 +1 @@
+/bedbug_603e.c
diff --git a/arch/powerpc/cpu/mpc824x/Makefile b/arch/powerpc/cpu/mpc824x/Makefile
new file mode 100644
index 0000000..a57ad12
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/Makefile
@@ -0,0 +1,56 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)drivers/epic)
+$(shell mkdir -p $(obj)drivers/i2c)
+endif
+
+LIB	= $(obj)lib$(CPU).a
+
+START	= start.o
+COBJS	= traps.o cpu.o cpu_init.o interrupts.o speed.o \
+	  drivers/epic/epic1.o drivers/i2c/i2c.o pci.o
+COBJS_LN = bedbug_603e.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) $(addprefix $(obj),$(COBJS_LN:.o=.c))
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS_LN))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+$(obj)bedbug_603e.c:
+	ln -sf $(src)../mpc8260/bedbug_603e.c $(obj)bedbug_603e.c
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/powerpc/cpu/mpc824x/config.mk b/arch/powerpc/cpu/mpc824x/config.mk
new file mode 100644
index 0000000..27c2873
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/config.mk
@@ -0,0 +1,29 @@
+#
+# (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
+#
+
+PLATFORM_RELFLAGS += -fPIC -meabi
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -ffixed-r2 -mstring -mcpu=603e -msoft-float
+
+# Use default linker script.  Board port can override in board/*/config.mk
+LDSCRIPT := $(SRCTREE)/arch/powerpc/cpu/mpc824x/u-boot.lds
diff --git a/arch/powerpc/cpu/mpc824x/cpu.c b/arch/powerpc/cpu/mpc824x/cpu.c
new file mode 100644
index 0000000..08f6a94
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/cpu.c
@@ -0,0 +1,280 @@
+/*
+ * (C) Copyright 2000 - 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <mpc824x.h>
+#include <common.h>
+#include <command.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int checkcpu (void)
+{
+	unsigned int pvr = get_pvr ();
+	unsigned int version = pvr >> 16;
+	unsigned char revision;
+	ulong clock = gd->cpu_clk;
+	char buf[32];
+
+	puts ("CPU:   ");
+
+	switch (version) {
+	case CPU_TYPE_8240:
+		puts ("MPC8240");
+		break;
+
+	case CPU_TYPE_8245:
+		puts ("MPC8245");
+		break;
+
+	default:
+		return -1;		/*not valid for this source */
+	}
+
+	CONFIG_READ_BYTE (REVID, revision);
+
+	if (revision) {
+		printf (" Revision %d.%d",
+			(revision & 0xf0) >> 4,
+			(revision & 0x0f));
+	} else {
+		return -1;		/* no valid CPU revision info */
+	}
+
+	printf (" at %s MHz:", strmhz (buf, clock));
+
+	printf (" %u kB I-Cache", checkicache () >> 10);
+	printf (" %u kB D-Cache", checkdcache () >> 10);
+
+	puts ("\n");
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+/* L1 i-cache                                                                */
+
+int checkicache (void)
+{
+	 /*TODO*/
+	 return 128 * 4 * 32;
+};
+
+/* ------------------------------------------------------------------------- */
+/* L1 d-cache                                                                */
+
+int checkdcache (void)
+{
+	 /*TODO*/
+	 return 128 * 4 * 32;
+
+};
+
+/*------------------------------------------------------------------- */
+
+int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	ulong msr, addr;
+
+	/* Interrupts and MMU off */
+	__asm__ ("mtspr    81, 0");
+
+	/* Interrupts and MMU off */
+	__asm__ __volatile__ ("mfmsr    %0":"=r" (msr):);
+
+	msr &= ~0x1030;
+	__asm__ __volatile__ ("mtmsr    %0"::"r" (msr));
+
+	/*
+	 * Trying to execute the next instruction at a non-existing address
+	 * should cause a machine check, resulting in reset
+	 */
+#ifdef CONFIG_SYS_RESET_ADDRESS
+	addr = CONFIG_SYS_RESET_ADDRESS;
+#else
+	/*
+	 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
+	 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid
+	 * address. Better pick an address known to be invalid on
+	 * your system and assign it to CONFIG_SYS_RESET_ADDRESS.
+	 * "(ulong)-1" used to be a good choice for many systems...
+	 */
+	addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong);
+#endif
+	((void (*)(void)) addr) ();
+	return 1;
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Get timebase clock frequency (like cpu_clk in Hz)
+ * This is the sys_logic_clk (memory bus) divided by 4
+ */
+unsigned long get_tbclk (void)
+{
+	return ((get_bus_freq (0) + 2L) / 4L);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * The MPC824x has an integrated PCI controller known as the MPC107.
+ * The following are MPC107 Bridge Controller and PCI Support functions
+ *
+ */
+
+/*
+ *  This procedure reads a 32-bit address MPC107 register, and returns
+ *  a 32 bit value.  It swaps the address to little endian before
+ *  writing it to config address, and swaps the value to big endian
+ *  before returning to the caller.
+ */
+unsigned int mpc824x_mpc107_getreg (unsigned int regNum)
+{
+	unsigned int temp;
+
+	/* swap the addr. to little endian */
+	*(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum);
+	temp = *(volatile unsigned int *) CHRP_REG_DATA;
+	return PCISWAP (temp);		/* swap the data upon return */
+}
+
+/*
+ *  This procedure writes a 32-bit address MPC107 register.  It swaps
+ *  the address to little endian before writing it to config address.
+ */
+
+void mpc824x_mpc107_setreg (unsigned int regNum, unsigned int regVal)
+{
+	/* swap the addr. to little endian */
+	*(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum);
+	*(volatile unsigned int *) CHRP_REG_DATA = PCISWAP (regVal);
+	return;
+}
+
+
+/*
+ *  Write a byte (8 bits) to a memory location.
+ */
+void mpc824x_mpc107_write8 (unsigned int addr, unsigned char data)
+{
+	*(unsigned char *) addr = data;
+	__asm__ ("sync");
+}
+
+/*
+ *  Write a word (16 bits) to a memory location after the value
+ *  has been byte swapped (big to little endian or vice versa)
+ */
+
+void mpc824x_mpc107_write16 (unsigned int address, unsigned short data)
+{
+	*(volatile unsigned short *) address = BYTE_SWAP_16_BIT (data);
+	__asm__ ("sync");
+}
+
+/*
+ *  Write a long word (32 bits) to a memory location after the value
+ *  has been byte swapped (big to little endian or vice versa)
+ */
+
+void mpc824x_mpc107_write32 (unsigned int address, unsigned int data)
+{
+	*(volatile unsigned int *) address = LONGSWAP (data);
+	__asm__ ("sync");
+}
+
+/*
+ *  Read a byte (8 bits) from a memory location.
+ */
+unsigned char mpc824x_mpc107_read8 (unsigned int addr)
+{
+	return *(volatile unsigned char *) addr;
+}
+
+
+/*
+ *  Read a word (16 bits) from a memory location, and byte swap the
+ *  value before returning to the caller.
+ */
+unsigned short mpc824x_mpc107_read16 (unsigned int address)
+{
+	unsigned short retVal;
+
+	retVal = BYTE_SWAP_16_BIT (*(unsigned short *) address);
+	return retVal;
+}
+
+
+/*
+ *  Read a long word (32 bits) from a memory location, and byte
+ *  swap the value before returning to the caller.
+ */
+unsigned int mpc824x_mpc107_read32 (unsigned int address)
+{
+	unsigned int retVal;
+
+	retVal = LONGSWAP (*(unsigned int *) address);
+	return (retVal);
+}
+
+
+/*
+ *  Read a register in the Embedded Utilities Memory Block address
+ *  space.
+ *  Input: regNum - register number + utility base address.  Example,
+ *         the base address of EPIC is 0x40000, the register number
+ *	   being passed is 0x40000+the address of the target register.
+ *	   (See epic.h for register addresses).
+ *  Output:  The 32 bit little endian value of the register.
+ */
+
+unsigned int mpc824x_eummbar_read (unsigned int regNum)
+{
+	unsigned int temp;
+
+	temp = *(volatile unsigned int *) (EUMBBAR_VAL + regNum);
+	temp = PCISWAP (temp);
+	return temp;
+}
+
+
+/*
+ *  Write a value to a register in the Embedded Utilities Memory
+ *  Block address space.
+ *  Input: regNum - register number + utility base address.  Example,
+ *                  the base address of EPIC is 0x40000, the register
+ *	            number is 0x40000+the address of the target register.
+ *	            (See epic.h for register addresses).
+ *         regVal - value to be written to the register.
+ */
+
+void mpc824x_eummbar_write (unsigned int regNum, unsigned int regVal)
+{
+	*(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP (regVal);
+	return;
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/arch/powerpc/cpu/mpc824x/cpu_init.c b/arch/powerpc/cpu/mpc824x/cpu_init.c
new file mode 100644
index 0000000..395f776
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/cpu_init.c
@@ -0,0 +1,417 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor. Flying Pig Systems. robt@flyingpig.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 <mpc824x.h>
+
+#ifndef CONFIG_SYS_BANK0_ROW
+#define CONFIG_SYS_BANK0_ROW 0
+#endif
+#ifndef CONFIG_SYS_BANK1_ROW
+#define CONFIG_SYS_BANK1_ROW 0
+#endif
+#ifndef CONFIG_SYS_BANK2_ROW
+#define CONFIG_SYS_BANK2_ROW 0
+#endif
+#ifndef CONFIG_SYS_BANK3_ROW
+#define CONFIG_SYS_BANK3_ROW 0
+#endif
+#ifndef CONFIG_SYS_BANK4_ROW
+#define CONFIG_SYS_BANK4_ROW 0
+#endif
+#ifndef CONFIG_SYS_BANK5_ROW
+#define CONFIG_SYS_BANK5_ROW 0
+#endif
+#ifndef CONFIG_SYS_BANK6_ROW
+#define CONFIG_SYS_BANK6_ROW 0
+#endif
+#ifndef CONFIG_SYS_BANK7_ROW
+#define CONFIG_SYS_BANK7_ROW 0
+#endif
+#ifndef CONFIG_SYS_DBUS_SIZE2
+#define CONFIG_SYS_DBUS_SIZE2 0
+#endif
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ */
+void
+cpu_init_f (void)
+{
+/* MOUSSE board is initialized in asm */
+#if !defined(CONFIG_MOUSSE) && !defined(CONFIG_BMW)
+    register unsigned long val;
+    CONFIG_WRITE_HALFWORD(PCICR, 0x06); /* Bus Master, respond to PCI memory space acesses*/
+/*    CONFIG_WRITE_HALFWORD(PCISR, 0xffff); */ /*reset PCISR*/
+
+#if defined(CONFIG_MUSENKI) || defined(CONFIG_PN62)
+/* Why is this here, you ask?  Try, just try setting 0x8000
+ * in PCIACR with CONFIG_WRITE_HALFWORD()
+ * this one was a stumper, and we are annoyed
+ */
+
+#define M_CONFIG_WRITE_HALFWORD( addr, data ) \
+	__asm__ __volatile__("		\
+		stw  %2,0(%0)\n		\
+		sync\n			\
+		sth  %3,2(%1)\n		\
+		sync\n			\
+		"			\
+		: /* no output */	\
+		: "r" (CONFIG_ADDR), "r" (CONFIG_DATA),			\
+		"r" (PCISWAP(addr & ~3)), "r" (PCISWAP(data << 16))	\
+	);
+
+	M_CONFIG_WRITE_HALFWORD(PCIACR, 0x8000);
+#endif
+
+	CONFIG_WRITE_BYTE(PCLSR, 0x8);	/* set PCI cache line size */
+	CONFIG_WRITE_BYTE (PLTR, 0x40); /* set PCI latency timer */
+	/*
+	* Note that although this bit is cleared after a hard reset, it
+	* must be explicitly set and then cleared by software during
+	* initialization in order to guarantee correct operation of the
+	* DLL and the SDRAM_CLK[0:3] signals (if they are used).
+	*/
+	CONFIG_READ_BYTE (AMBOR, val);
+	CONFIG_WRITE_BYTE(AMBOR, val & 0xDF);
+	CONFIG_WRITE_BYTE(AMBOR, val | 0x20);
+	CONFIG_WRITE_BYTE(AMBOR, val & 0xDF);
+#ifdef CONFIG_MPC8245
+	/* silicon bug 28 MPC8245 */
+	CONFIG_READ_BYTE(AMBOR,val);
+	CONFIG_WRITE_BYTE(AMBOR,val|0x1);
+
+#if 0
+	/*
+	 * The following bug only affects older (XPC8245) processors.
+	 * DMA transfers initiated by external devices get corrupted due
+	 * to a hardware scheduling problem.
+	 *
+	 * The effect is:
+	 * when transferring X words, the first 32 words are transferred
+	 * OK, the next 3 x 32 words are 'old' data (from previous DMA)
+	 * while the rest of the X words is xferred fine.
+	 *
+	 * Disabling 3 of the 4 32 word hardware buffers solves the problem
+	 * with no significant performance loss.
+	 */
+
+	CONFIG_READ_BYTE(PCMBCR,val);
+	/* in order not to corrupt data which is being read over the PCI bus
+	* with the PPC as slave, we need to reduce the number of PCMRBs to 1,
+	* 4.11 in the  processor user manual
+	* */
+
+#if 1
+	CONFIG_WRITE_BYTE(PCMBCR,(val|0xC0)); /* 1 PCMRB */
+#else
+	CONFIG_WRITE_BYTE(PCMBCR,(val|0x80)); /* 2 PCMRBs */
+	CONFIG_WRITE_BYTE(PCMBCR,(val|0x40)); /* 3 PCMRBs */
+	/* default, 4 PCMRBs are used */
+#endif
+#endif
+#endif
+
+	CONFIG_READ_WORD(PICR1, val);
+#if defined(CONFIG_MPC8240)
+	CONFIG_WRITE_WORD( PICR1,
+		(val & (PICR1_ADDRESS_MAP | PICR1_RCS0)) |
+		       PIRC1_MSK | PICR1_PROC_TYPE_603E |
+		       PICR1_FLASH_WR_EN | PICR1_MCP_EN |
+		       PICR1_CF_DPARK | PICR1_EN_PCS |
+		       PICR1_CF_APARK );
+#elif defined(CONFIG_MPC8245)
+	CONFIG_WRITE_WORD( PICR1,
+		(val & (PICR1_RCS0)) |
+		       PICR1_PROC_TYPE_603E |
+		       PICR1_FLASH_WR_EN | PICR1_MCP_EN |
+		       PICR1_CF_DPARK | PICR1_NO_BUSW_CK |
+		       PICR1_DEC| PICR1_CF_APARK | 0x10); /* 8245 UM says bit 4 must be set */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+	CONFIG_READ_WORD(PICR2, val);
+	val= val & ~ (PICR2_CF_SNOOP_WS_MASK | PICR2_CF_APHASE_WS_MASK); /*mask off waitstate bits*/
+#ifndef CONFIG_PN62
+	val |= PICR2_CF_SNOOP_WS_1WS | PICR2_CF_APHASE_WS_1WS; /*1 wait state*/
+#endif
+	CONFIG_WRITE_WORD(PICR2, val);
+
+	CONFIG_WRITE_WORD(EUMBBAR, CONFIG_SYS_EUMB_ADDR);
+#ifndef CONFIG_SYS_RAMBOOT
+	CONFIG_WRITE_WORD(MCCR1, (CONFIG_SYS_ROMNAL << MCCR1_ROMNAL_SHIFT) |
+				 (CONFIG_SYS_BANK0_ROW) |
+				 (CONFIG_SYS_BANK1_ROW << MCCR1_BANK1ROW_SHIFT) |
+				 (CONFIG_SYS_BANK2_ROW << MCCR1_BANK2ROW_SHIFT) |
+				 (CONFIG_SYS_BANK3_ROW << MCCR1_BANK3ROW_SHIFT) |
+				 (CONFIG_SYS_BANK4_ROW << MCCR1_BANK4ROW_SHIFT) |
+				 (CONFIG_SYS_BANK5_ROW << MCCR1_BANK5ROW_SHIFT) |
+				 (CONFIG_SYS_BANK6_ROW << MCCR1_BANK6ROW_SHIFT) |
+				 (CONFIG_SYS_BANK7_ROW << MCCR1_BANK7ROW_SHIFT) |
+				 (CONFIG_SYS_ROMFAL << MCCR1_ROMFAL_SHIFT));
+#endif
+
+#if defined(CONFIG_SYS_ASRISE) && defined(CONFIG_SYS_ASFALL)
+	CONFIG_WRITE_WORD(MCCR2, CONFIG_SYS_REFINT << MCCR2_REFINT_SHIFT |
+				 CONFIG_SYS_ASRISE << MCCR2_ASRISE_SHIFT |
+				 CONFIG_SYS_ASFALL << MCCR2_ASFALL_SHIFT);
+#else
+	CONFIG_WRITE_WORD(MCCR2, CONFIG_SYS_REFINT << MCCR2_REFINT_SHIFT);
+#endif
+
+#if defined(CONFIG_MPC8240)
+	CONFIG_WRITE_WORD(MCCR3,
+		(((CONFIG_SYS_BSTOPRE & 0x003c) >> 2) << MCCR3_BSTOPRE2TO5_SHIFT) |
+		(CONFIG_SYS_REFREC << MCCR3_REFREC_SHIFT) |
+		(CONFIG_SYS_RDLAT  << MCCR3_RDLAT_SHIFT));
+#elif defined(CONFIG_MPC8245)
+	CONFIG_WRITE_WORD(MCCR3,
+		(((CONFIG_SYS_BSTOPRE & 0x003c) >> 2) << MCCR3_BSTOPRE2TO5_SHIFT) |
+		(CONFIG_SYS_REFREC << MCCR3_REFREC_SHIFT));
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+/* this is gross.  We think these should all be the same, and various boards
+ *  should define CONFIG_SYS_ACTORW to 0 if they don't want to set it, or even, if
+ *  its not set, we define it to zero in this file
+ */
+#if defined(CONFIG_CU824) || defined(CONFIG_PN62)
+	CONFIG_WRITE_WORD(MCCR4,
+	(CONFIG_SYS_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+	(CONFIG_SYS_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+	MCCR4_BIT21 |
+	(CONFIG_SYS_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+	((CONFIG_SYS_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+	(((CONFIG_SYS_SDMODE_CAS_LAT <<4) | (CONFIG_SYS_SDMODE_WRAP <<3) |
+		  CONFIG_SYS_SDMODE_BURSTLEN) << MCCR4_SDMODE_SHIFT) |
+	(CONFIG_SYS_ACTORW << MCCR4_ACTTORW_SHIFT) |
+	(((CONFIG_SYS_BSTOPRE & 0x03c0) >> 6) << MCCR4_BSTOPRE6TO9_SHIFT));
+#elif defined(CONFIG_MPC8240)
+	CONFIG_WRITE_WORD(MCCR4,
+	(CONFIG_SYS_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+	(CONFIG_SYS_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+	MCCR4_BIT21 |
+	(CONFIG_SYS_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+	((CONFIG_SYS_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+	(((CONFIG_SYS_SDMODE_CAS_LAT <<4) | (CONFIG_SYS_SDMODE_WRAP <<3) |
+		  (CONFIG_SYS_SDMODE_BURSTLEN)) <<MCCR4_SDMODE_SHIFT) |
+	(((CONFIG_SYS_BSTOPRE & 0x03c0) >> 6) <<MCCR4_BSTOPRE6TO9_SHIFT ));
+#elif defined(CONFIG_MPC8245)
+	CONFIG_READ_WORD(MCCR1, val);
+	val &= MCCR1_DBUS_SIZE0;    /* test for 64-bit mem bus */
+
+	CONFIG_WRITE_WORD(MCCR4,
+		(CONFIG_SYS_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+		(CONFIG_SYS_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+		(CONFIG_SYS_EXTROM ? MCCR4_EXTROM : 0) |
+		(CONFIG_SYS_REGDIMM ? MCCR4_REGDIMM : 0) |
+		(CONFIG_SYS_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+		((CONFIG_SYS_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+		(CONFIG_SYS_DBUS_SIZE2 << MCCR4_DBUS_SIZE2_SHIFT) |
+		(((CONFIG_SYS_SDMODE_CAS_LAT <<4) | (CONFIG_SYS_SDMODE_WRAP <<3) |
+		      (val ? 2 : 3)) << MCCR4_SDMODE_SHIFT)  |
+		(CONFIG_SYS_ACTORW << MCCR4_ACTTORW_SHIFT) |
+		(((CONFIG_SYS_BSTOPRE & 0x03c0) >> 6) <<MCCR4_BSTOPRE6TO9_SHIFT ));
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+	CONFIG_WRITE_WORD(MSAR1,
+		( (CONFIG_SYS_BANK0_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+		(((CONFIG_SYS_BANK1_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK2_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK3_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+	CONFIG_WRITE_WORD(EMSAR1,
+		( (CONFIG_SYS_BANK0_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+		(((CONFIG_SYS_BANK1_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK2_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK3_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+	CONFIG_WRITE_WORD(MSAR2,
+		( (CONFIG_SYS_BANK4_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+		(((CONFIG_SYS_BANK5_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK6_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK7_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+	CONFIG_WRITE_WORD(EMSAR2,
+		( (CONFIG_SYS_BANK4_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+		(((CONFIG_SYS_BANK5_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK6_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK7_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+	CONFIG_WRITE_WORD(MEAR1,
+		( (CONFIG_SYS_BANK0_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+		(((CONFIG_SYS_BANK1_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK2_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK3_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+	CONFIG_WRITE_WORD(EMEAR1,
+		( (CONFIG_SYS_BANK0_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+		(((CONFIG_SYS_BANK1_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK2_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK3_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+	CONFIG_WRITE_WORD(MEAR2,
+		( (CONFIG_SYS_BANK4_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+		(((CONFIG_SYS_BANK5_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK6_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK7_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+	CONFIG_WRITE_WORD(EMEAR2,
+		( (CONFIG_SYS_BANK4_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+		(((CONFIG_SYS_BANK5_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+		(((CONFIG_SYS_BANK6_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+		(((CONFIG_SYS_BANK7_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+
+	CONFIG_WRITE_BYTE(ODCR, CONFIG_SYS_ODCR);
+#ifdef CONFIG_SYS_DLL_MAX_DELAY
+	CONFIG_WRITE_BYTE(MIOCR1, CONFIG_SYS_DLL_MAX_DELAY);	/* needed to make DLL lock */
+#endif
+#if defined(CONFIG_SYS_DLL_EXTEND) && defined(CONFIG_SYS_PCI_HOLD_DEL)
+	CONFIG_WRITE_BYTE(PMCR2, CONFIG_SYS_DLL_EXTEND | CONFIG_SYS_PCI_HOLD_DEL);
+#endif
+#if defined(MIOCR2) && defined(CONFIG_SYS_SDRAM_DSCD)
+	CONFIG_WRITE_BYTE(MIOCR2, CONFIG_SYS_SDRAM_DSCD);	/* change memory input */
+#endif /* setup & hold time */
+
+	CONFIG_WRITE_BYTE(MBER,
+		 CONFIG_SYS_BANK0_ENABLE |
+		(CONFIG_SYS_BANK1_ENABLE << 1) |
+		(CONFIG_SYS_BANK2_ENABLE << 2) |
+		(CONFIG_SYS_BANK3_ENABLE << 3) |
+		(CONFIG_SYS_BANK4_ENABLE << 4) |
+		(CONFIG_SYS_BANK5_ENABLE << 5) |
+		(CONFIG_SYS_BANK6_ENABLE << 6) |
+		(CONFIG_SYS_BANK7_ENABLE << 7));
+
+#ifdef CONFIG_SYS_PGMAX
+	CONFIG_WRITE_BYTE(MPMR, CONFIG_SYS_PGMAX);
+#endif
+
+	/* ! Wait 200us before initialize other registers */
+	/*FIXME: write a decent udelay wait */
+	__asm__ __volatile__(
+		" mtctr	%0 \n \
+		0: bdnz	 0b\n"
+		:
+		: "r" (0x10000));
+
+	CONFIG_READ_WORD(MCCR1, val);
+	CONFIG_WRITE_WORD(MCCR1, val | MCCR1_MEMGO); /* set memory access going */
+	__asm__ __volatile__("eieio");
+
+#endif /* !CONFIG_MOUSSE && !CONFIG_BMW */
+}
+
+
+#ifdef CONFIG_MOUSSE
+#ifdef INCLUDE_MPC107_REPORT
+struct MPC107_s {
+	unsigned int iobase;
+	char desc[120];
+} MPC107Regs[] = {
+	{ BMC_BASE +  0x00, "MPC107 Vendor/Device ID"		},
+	{ BMC_BASE +  0x04, "MPC107 PCI Command/Status Register" },
+	{ BMC_BASE +  0x08, "MPC107 Revision"			},
+	{ BMC_BASE +  0x0C, "MPC107 Cache Line Size"		},
+	{ BMC_BASE +  0x10, "MPC107 LMBAR"			},
+	{ BMC_BASE +  0x14, "MPC824x PCSR"			},
+	{ BMC_BASE +  0xA8, "MPC824x PICR1"			},
+	{ BMC_BASE +  0xAC, "MPC824x PICR2"			},
+	{ BMC_BASE +  0x46, "MPC824x PACR"			},
+	{ BMC_BASE + 0x310, "MPC824x ITWR"			},
+	{ BMC_BASE + 0x300, "MPC824x OMBAR"			},
+	{ BMC_BASE + 0x308, "MPC824x OTWR"			},
+	{ BMC_BASE +  0x14, "MPC107 Peripheral Control and Status Register" },
+	{ BMC_BASE + 0x78, "MPC107 EUMBAR"			},
+	{ BMC_BASE + 0xC0, "MPC107 Processor Bus Error Status"	},
+	{ BMC_BASE + 0xC4, "MPC107 PCI Bus Error Status"	},
+	{ BMC_BASE + 0xC8, "MPC107 Processor/PCI Error Address"	},
+	{ BMC_BASE + 0xE0, "MPC107 AMBOR Register"		},
+	{ BMC_BASE + 0xF0, "MPC107 MCCR1 Register"		},
+	{ BMC_BASE + 0xF4, "MPC107 MCCR2 Register"		},
+	{ BMC_BASE + 0xF8, "MPC107 MCCR3 Register"		},
+	{ BMC_BASE + 0xFC, "MPC107 MCCR4 Register"		},
+};
+#define N_MPC107_Regs	(sizeof(MPC107Regs)/sizeof(MPC107Regs[0]))
+#endif /* INCLUDE_MPC107_REPORT */
+#endif /* CONFIG_MOUSSE */
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r (void)
+{
+#ifdef CONFIG_MOUSSE
+#ifdef INCLUDE_MPC107_REPORT
+	unsigned int tmp = 0, i;
+#endif
+	/*
+	 * Initialize the EUMBBAR (Embedded Util Mem Block Base Addr Reg).
+	 * This is necessary before the EPIC, DMA ctlr, I2C ctlr, etc. can
+	 * be accessed.
+	 */
+
+#ifdef CONFIG_MPC8240			/* only on MPC8240 */
+	mpc824x_mpc107_setreg (EUMBBAR, EUMBBAR_VAL);
+	/* MOT/SPS: Issue #10002, PCI (FD Alias enable) */
+	mpc824x_mpc107_setreg (AMBOR, 0x000000C0);
+#endif
+
+
+#ifdef INCLUDE_MPC107_REPORT
+	/* Check MPC824x PCI Device and Vendor ID */
+	while ((tmp = mpc824x_mpc107_getreg (BMC_BASE)) != 0x31057) {
+		printf ("	MPC107: offset=0x%x, val = 0x%x\n",
+			BMC_BASE,
+			tmp);
+	}
+
+	for (i = 0; i < N_MPC107_Regs; i++) {
+		printf ("	0x%x/%s = 0x%x\n",
+			MPC107Regs[i].iobase,
+			MPC107Regs[i].desc,
+			mpc824x_mpc107_getreg (MPC107Regs[i].iobase));
+	}
+
+	printf ("IBAT0L = 0x%08X\n", mfspr (IBAT0L));
+	printf ("IBAT0U = 0x%08X\n", mfspr (IBAT0U));
+	printf ("IBAT1L = 0x%08X\n", mfspr (IBAT1L));
+	printf ("IBAT1U = 0x%08X\n", mfspr (IBAT1U));
+	printf ("IBAT2L = 0x%08X\n", mfspr (IBAT2L));
+	printf ("IBAT2U = 0x%08X\n", mfspr (IBAT2U));
+	printf ("IBAT3L = 0x%08X\n", mfspr (IBAT3L));
+	printf ("IBAT3U = 0x%08X\n", mfspr (IBAT3U));
+	printf ("DBAT0L = 0x%08X\n", mfspr (DBAT0L));
+	printf ("DBAT0U = 0x%08X\n", mfspr (DBAT0U));
+	printf ("DBAT1L = 0x%08X\n", mfspr (DBAT1L));
+	printf ("DBAT1U = 0x%08X\n", mfspr (DBAT1U));
+	printf ("DBAT2L = 0x%08X\n", mfspr (DBAT2L));
+	printf ("DBAT2U = 0x%08X\n", mfspr (DBAT2U));
+	printf ("DBAT3L = 0x%08X\n", mfspr (DBAT3L));
+	printf ("DBAT3U = 0x%08X\n", mfspr (DBAT3U));
+#endif /* INCLUDE_MPC107_REPORT */
+#endif /* CONFIG_MOUSSE */
+	return (0);
+}
diff --git a/arch/powerpc/cpu/mpc824x/drivers/epic.h b/arch/powerpc/cpu/mpc824x/drivers/epic.h
new file mode 100644
index 0000000..2803f63
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/epic.h
@@ -0,0 +1 @@
+#include "epic/epic.h"
diff --git a/arch/powerpc/cpu/mpc824x/drivers/epic/README b/arch/powerpc/cpu/mpc824x/drivers/epic/README
new file mode 100644
index 0000000..5798996
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/epic/README
@@ -0,0 +1,102 @@
+CONTENT:
+
+   epic.h
+   epic1.c
+   epic2.s
+
+WHAT ARE THESE FILES:
+
+These files contain MPC8240 (Kahlua) EPIC
+driver routines. The driver routines are not
+written for any specific operating system.
+They serves the purpose of code sample, and
+jump-start for using the MPC8240 EPIC unit.
+
+For the reason of correctness of C language
+syntax, these files are compiled by Metaware
+C compiler and assembler.
+
+ENDIAN NOTATION:
+
+The algorithm is designed for big-endian mode,
+software is responsible for byte swapping.
+
+USAGE:
+
+1. The host system that is running on MPC8240
+   shall link the files listed here. The memory
+   location of driver routines shall take into
+   account of that driver routines need to run
+   in supervisor mode and they process external
+   interrupts.
+
+   The routine epic_exception shall be called by
+   exception vector at location 0x500, i.e.,
+   603e core external exception vector.
+
+2. The host system is responsible for configuring
+   the MPC8240 including Embedded Utilities Memory
+   Block. All EPIC driver functions require the
+   content of Embedded Utilities Memory Block
+   Base Address Register, EUMBBAR, as the first
+   parameter.
+
+3. Before EPIC unit of MPC8240 can be used,
+   initialize EPIC unit by calling epicInit
+   with the corresponding parameters.
+
+   The initialization shall disable the 603e
+   core External Exception by calling CoreExtIntDisable( ).
+   Next, call epicInit( ). Last, enable the 603e core
+   External Exception by calling CoreExtIntEnable( ).
+
+4. After EPIC unit has been successfully initialized,
+   epicIntSourceSet( ) shall be used to register each
+   external interrupt source. Anytime, an external
+   interrupt source can be disabled or enabled by
+   calling corresponding function, epicIntDisable( ),
+   or epicIntEnable( ).
+
+   Global Timers' resource, base count and frequency,
+   can be changed by calling epicTmFrequencySet( )
+   and epicTmBaseSet( ).
+
+   To stop counting a specific global timer, use
+   the function, epicTmInhibit while epicTmEnable
+   can be used to start counting a timer.
+
+5. To mask a set of external interrupts that are
+   are certain level below, epicIntPrioritySet( )
+   can be used. For example, if the processor's
+   current task priority register is set to 0x7,
+   only interrupts of priority 0x8 or higher will
+   be passed to the processor.
+
+   Be careful when using this function. It may
+   corrupt the current interrupt pending, selector,
+   and request registers, resulting an invalid vetor.
+
+   After enabling an interrupt, disable it may also
+   cause an invalid vector. User may consider using
+   the spurious vector interrupt service routine to
+   handle this case.
+
+6. The EPIC driver routines contains a set
+   of utilities, Set and Get, for host system
+   to query and modify the desired EPIC source
+   registers.
+
+7. Each external interrupt source shall register
+   its interrupt service routine. The routine
+   shall contain all interrupt source specific
+   processes and keep as short as possible.
+
+   Special customized end of interrupt routine
+   is optional. If it is needed, it shall contain
+   the external interrupt source specific end of
+   interrupt process.
+
+   External interrupt exception vector at 0x500
+   shall always call the epicEOI just before
+   rfi instruction. Refer to the routine,
+   epic_exception, for a code sample.
diff --git a/arch/powerpc/cpu/mpc824x/drivers/epic/epic.h b/arch/powerpc/cpu/mpc824x/drivers/epic/epic.h
new file mode 100644
index 0000000..58f81c5
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/epic/epic.h
@@ -0,0 +1,163 @@
+/*********************************************************************
+ * mpc8240epic.h - EPIC module of the MPC8240 micro-controller
+ *
+ * Copyrigh 1999  Motorola Inc.
+ *
+ * Modification History:
+ * =====================
+ * 01a,04Feb99,My  Created.
+ * 15Nov200, robt -modified to use in U-Boot
+ *
+*/
+
+#ifndef __INCEPICh
+#define __INCEPICh
+
+#define ULONG unsigned long
+#define MAXVEC             20
+#define MAXIRQ        5 /* IRQs */
+#define EPIC_DIRECT_IRQ     0 /* Direct interrupt type */
+
+/* EPIC register addresses */
+
+#define EPIC_EUMBBAR      0x40000     /* EUMBBAR of EPIC  */
+#define EPIC_FEATURES_REG (EPIC_EUMBBAR + 0x01000)/* Feature reporting */
+#define EPIC_GLOBAL_REG   (EPIC_EUMBBAR + 0x01020)/* Global config.  */
+#define EPIC_INT_CONF_REG (EPIC_EUMBBAR + 0x01030)/* Interrupt config. */
+#define EPIC_VENDOR_ID_REG  (EPIC_EUMBBAR + 0x01080)/* Vendor id */
+#define EPIC_PROC_INIT_REG  (EPIC_EUMBBAR + 0x01090)/* Processor init. */
+#define EPIC_SPUR_VEC_REG (EPIC_EUMBBAR + 0x010e0)/* Spurious vector */
+#define EPIC_TM_FREQ_REG  (EPIC_EUMBBAR + 0x010f0)/* Timer Frequency */
+
+#define EPIC_TM0_CUR_COUNT_REG  (EPIC_EUMBBAR + 0x01100)/* Gbl TM0 Cur. Count*/
+#define EPIC_TM0_BASE_COUNT_REG (EPIC_EUMBBAR + 0x01110)/* Gbl TM0 Base Count*/
+#define EPIC_TM0_VEC_REG  (EPIC_EUMBBAR + 0x01120)/* Gbl TM0 Vector Pri*/
+#define EPIC_TM0_DES_REG  (EPIC_EUMBBAR + 0x01130)/* Gbl TM0 Dest. */
+
+#define EPIC_TM1_CUR_COUNT_REG  (EPIC_EUMBBAR + 0x01140)/* Gbl TM1 Cur. Count*/
+#define EPIC_TM1_BASE_COUNT_REG (EPIC_EUMBBAR + 0x01150)/* Gbl TM1 Base Count*/
+#define EPIC_TM1_VEC_REG  (EPIC_EUMBBAR + 0x01160)/* Gbl TM1 Vector Pri*/
+#define EPIC_TM1_DES_REG  (EPIC_EUMBBAR + 0x01170)/* Gbl TM1 Dest. */
+
+#define EPIC_TM2_CUR_COUNT_REG  (EPIC_EUMBBAR + 0x01180)/* Gbl TM2 Cur. Count*/
+#define EPIC_TM2_BASE_COUNT_REG (EPIC_EUMBBAR + 0x01190)/* Gbl TM2 Base Count*/
+#define EPIC_TM2_VEC_REG  (EPIC_EUMBBAR + 0x011a0)/* Gbl TM2 Vector Pri*/
+#define EPIC_TM2_DES_REG  (EPIC_EUMBBAR + 0x011b0)/* Gbl TM2 Dest */
+
+#define EPIC_TM3_CUR_COUNT_REG  (EPIC_EUMBBAR + 0x011c0)/* Gbl TM3 Cur. Count*/
+#define EPIC_TM3_BASE_COUNT_REG (EPIC_EUMBBAR + 0x011d0)/* Gbl TM3 Base Count*/
+#define EPIC_TM3_VEC_REG  (EPIC_EUMBBAR + 0x011e0)/* Gbl TM3 Vector Pri*/
+#define EPIC_TM3_DES_REG  (EPIC_EUMBBAR + 0x011f0)/* Gbl TM3 Dest. */
+
+#define EPIC_EX_INT0_VEC_REG  (EPIC_EUMBBAR + 0x10200)/* Ext. Int. Sr0 Des */
+#define EPIC_EX_INT0_DES_REG  (EPIC_EUMBBAR + 0x10210)/* Ext. Int. Sr0 Vect*/
+#define EPIC_EX_INT1_VEC_REG  (EPIC_EUMBBAR + 0x10220)/* Ext. Int. Sr1 Des */
+#define EPIC_EX_INT1_DES_REG  (EPIC_EUMBBAR + 0x10230)/* Ext. Int. Sr1 Vect*/
+#define EPIC_EX_INT2_VEC_REG  (EPIC_EUMBBAR + 0x10240)/* Ext. Int. Sr2 Des */
+#define EPIC_EX_INT2_DES_REG  (EPIC_EUMBBAR + 0x10250)/* Ext. Int. Sr2 Vect*/
+#define EPIC_EX_INT3_VEC_REG  (EPIC_EUMBBAR + 0x10260)/* Ext. Int. Sr3 Des */
+#define EPIC_EX_INT3_DES_REG  (EPIC_EUMBBAR + 0x10270)/* Ext. Int. Sr3 Vect*/
+#define EPIC_EX_INT4_VEC_REG  (EPIC_EUMBBAR + 0x10280)/* Ext. Int. Sr4 Des */
+#define EPIC_EX_INT4_DES_REG  (EPIC_EUMBBAR + 0x10290)/* Ext. Int. Sr4 Vect*/
+
+#define EPIC_SR_INT0_VEC_REG  (EPIC_EUMBBAR + 0x10200)/* Sr. Int. Sr0 Des */
+#define EPIC_SR_INT0_DES_REG  (EPIC_EUMBBAR + 0x10210)/* Sr. Int. Sr0 Vect */
+#define EPIC_SR_INT1_VEC_REG  (EPIC_EUMBBAR + 0x10220)/* Sr. Int. Sr1 Des */
+#define EPIC_SR_INT1_DES_REG  (EPIC_EUMBBAR + 0x10230)/* Sr. Int. Sr1 Vect.*/
+#define EPIC_SR_INT2_VEC_REG  (EPIC_EUMBBAR + 0x10240)/* Sr. Int. Sr2 Des */
+#define EPIC_SR_INT2_DES_REG  (EPIC_EUMBBAR + 0x10250)/* Sr. Int. Sr2 Vect.*/
+#define EPIC_SR_INT3_VEC_REG  (EPIC_EUMBBAR + 0x10260)/* Sr. Int. Sr3 Des */
+#define EPIC_SR_INT3_DES_REG  (EPIC_EUMBBAR + 0x10270)/* Sr. Int. Sr3 Vect.*/
+#define EPIC_SR_INT4_VEC_REG  (EPIC_EUMBBAR + 0x10280)/* Sr. Int. Sr4 Des */
+#define EPIC_SR_INT4_DES_REG  (EPIC_EUMBBAR + 0x10290)/* Sr. Int. Sr4 Vect.*/
+
+#define EPIC_SR_INT5_VEC_REG  (EPIC_EUMBBAR + 0x102a0)/* Sr. Int. Sr5 Des */
+#define EPIC_SR_INT5_DES_REG  (EPIC_EUMBBAR + 0x102b0)/* Sr. Int. Sr5 Vect.*/
+#define EPIC_SR_INT6_VEC_REG  (EPIC_EUMBBAR + 0x102c0)/* Sr. Int. Sr6 Des */
+#define EPIC_SR_INT6_DES_REG  (EPIC_EUMBBAR + 0x102d0)/* Sr. Int. Sr6 Vect.*/
+#define EPIC_SR_INT7_VEC_REG  (EPIC_EUMBBAR + 0x102e0)/* Sr. Int. Sr7 Des */
+#define EPIC_SR_INT7_DES_REG  (EPIC_EUMBBAR + 0x102f0)/* Sr. Int. Sr7 Vect.*/
+#define EPIC_SR_INT8_VEC_REG  (EPIC_EUMBBAR + 0x10300)/* Sr. Int. Sr8 Des */
+#define EPIC_SR_INT8_DES_REG  (EPIC_EUMBBAR + 0x10310)/* Sr. Int. Sr8 Vect.*/
+#define EPIC_SR_INT9_VEC_REG  (EPIC_EUMBBAR + 0x10320)/* Sr. Int. Sr9 Des */
+#define EPIC_SR_INT9_DES_REG  (EPIC_EUMBBAR + 0x10330)/* Sr. Int. Sr9 Vect.*/
+
+#define EPIC_SR_INT10_VEC_REG (EPIC_EUMBBAR + 0x10340)/* Sr. Int. Sr10 Des */
+#define EPIC_SR_INT10_DES_REG (EPIC_EUMBBAR + 0x10350)/* Sr. Int. Sr10 Vect*/
+#define EPIC_SR_INT11_VEC_REG (EPIC_EUMBBAR + 0x10360)/* Sr. Int. Sr11 Des */
+#define EPIC_SR_INT11_DES_REG (EPIC_EUMBBAR + 0x10370)/* Sr. Int. Sr11 Vect*/
+#define EPIC_SR_INT12_VEC_REG (EPIC_EUMBBAR + 0x10380)/* Sr. Int. Sr12 Des */
+#define EPIC_SR_INT12_DES_REG (EPIC_EUMBBAR + 0x10390)/* Sr. Int. Sr12 Vect*/
+#define EPIC_SR_INT13_VEC_REG (EPIC_EUMBBAR + 0x103a0)/* Sr. Int. Sr13 Des */
+#define EPIC_SR_INT13_DES_REG (EPIC_EUMBBAR + 0x103b0)/* Sr. Int. Sr13 Vect*/
+#define EPIC_SR_INT14_VEC_REG (EPIC_EUMBBAR + 0x103c0)/* Sr. Int. Sr14 Des */
+#define EPIC_SR_INT14_DES_REG (EPIC_EUMBBAR + 0x103d0)/* Sr. Int. Sr14 Vect*/
+#define EPIC_SR_INT15_VEC_REG (EPIC_EUMBBAR + 0x103e0)/* Sr. Int. Sr15 Des */
+#define EPIC_SR_INT15_DES_REG (EPIC_EUMBBAR + 0x103f0)/* Sr. Int. Sr15 Vect*/
+
+#define EPIC_I2C_INT_VEC_REG  (EPIC_EUMBBAR + 0x11020)/* I2C Int. Vect Pri.*/
+#define EPIC_I2C_INT_DES_REG  (EPIC_EUMBBAR + 0x11030)/* I2C Int. Dest */
+#define EPIC_DMA0_INT_VEC_REG (EPIC_EUMBBAR + 0x11040)/* DMA0 Int. Vect Pri*/
+#define EPIC_DMA0_INT_DES_REG (EPIC_EUMBBAR + 0x11050)/* DMA0 Int. Dest */
+#define EPIC_DMA1_INT_VEC_REG (EPIC_EUMBBAR + 0x11060)/* DMA1 Int. Vect Pri*/
+#define EPIC_DMA1_INT_DES_REG (EPIC_EUMBBAR + 0x11070)/* DMA1 Int. Dest */
+#define EPIC_MSG_INT_VEC_REG  (EPIC_EUMBBAR + 0x110c0)/* Msg Int. Vect Pri*/
+#define EPIC_MSG_INT_DES_REG  (EPIC_EUMBBAR + 0x110d0)/* Msg Int. Dest  */
+
+#define EPIC_PROC_CTASK_PRI_REG (EPIC_EUMBBAR + 0x20080)/* Proc. current task*/
+#define EPIC_PROC_INT_ACK_REG (EPIC_EUMBBAR + 0x200a0)/* Int. acknowledge */
+#define EPIC_PROC_EOI_REG (EPIC_EUMBBAR + 0x200b0)/* End of interrupt */
+
+#define EPIC_VEC_PRI_MASK      0x80000000 /* Mask Interrupt bit in IVPR */
+#define EPIC_VEC_PRI_DFLT_PRI  8          /* Interrupt Priority in IVPR */
+
+/* Error code */
+
+#define OK       0
+#define ERROR    -1
+
+/* function prototypes */
+
+void epicVendorId( unsigned int *step,
+       unsigned int *devId,
+       unsigned int *venId
+     );
+void epicFeatures( unsigned int *noIRQs,
+	     unsigned int *noCPUs,
+       unsigned int *VerId );
+extern void epicInit( unsigned int IRQType, unsigned int clkRatio);
+ULONG sysEUMBBARRead ( ULONG regNum );
+void sysEUMBBARWrite ( ULONG regNum, ULONG regVal);
+extern void epicTmFrequencySet( unsigned int frq );
+extern unsigned int epicTmFrequencyGet(void);
+extern unsigned int epicTmBaseSet( ULONG srcAddr,
+		 unsigned int cnt,
+		 unsigned int inhibit );
+extern unsigned int epicTmBaseGet ( ULONG srcAddr, unsigned int *val );
+extern unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val );
+extern unsigned int epicTmInhibit( unsigned int timer );
+extern unsigned int epicTmEnable( ULONG srcAdr );
+extern void CoreExtIntEnable(void);  /* Enable 603e external interrupts */
+extern void CoreExtIntDisable(void); /* Disable 603e external interrupts */
+extern unsigned char epicIntTaskGet(void);
+extern void epicIntTaskSet( unsigned char val );
+extern unsigned int epicIntAck(void);
+extern void epicSprSet( unsigned int eumbbar, unsigned char );
+extern void epicConfigGet( unsigned int *clkRatio,
+	       unsigned int *serEnable );
+extern void SrcVecTableInit(void);
+extern unsigned int  epicModeGet(void);
+extern void epicIntEnable(int Vect);
+extern void epicIntDisable(int Vect);
+extern int epicIntSourceConfig(int Vect, int Polarity, int Sense, int Prio);
+extern unsigned int epicIntAck(void);
+extern void epicEOI(void);
+extern int epicCurTaskPrioSet(int Vect);
+
+struct SrcVecTable
+    {
+     ULONG srcAddr;
+     char  srcName[40];
+    };
+
+#endif   /*  EPIC_H */
diff --git a/arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c b/arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c
new file mode 100644
index 0000000..ecbb42d
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/epic/epic1.c
@@ -0,0 +1,517 @@
+/**************************************************
+ *
+ * copyright @ motorola, 1999
+ *
+ *************************************************/
+#include <mpc824x.h>
+#include <common.h>
+#include "epic.h"
+
+
+#define PRINT(format, args...) printf(format , ## args)
+
+typedef void (*VOIDFUNCPTR)  (void);  /* ptr to function returning void */
+struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */
+    {
+    { EPIC_EX_INT0_VEC_REG,  "External Direct/Serial Source 0"},
+    { EPIC_EX_INT1_VEC_REG,  "External Direct/Serial Source 1"},
+    { EPIC_EX_INT2_VEC_REG,  "External Direct/Serial Source 2"},
+    { EPIC_EX_INT3_VEC_REG,  "External Direct/Serial Source 3"},
+    { EPIC_EX_INT4_VEC_REG,  "External Direct/Serial Source 4"},
+
+    { EPIC_SR_INT5_VEC_REG,  "External Serial Source 5"},
+    { EPIC_SR_INT6_VEC_REG,  "External Serial Source 6"},
+    { EPIC_SR_INT7_VEC_REG,  "External Serial Source 7"},
+    { EPIC_SR_INT8_VEC_REG,  "External Serial Source 8"},
+    { EPIC_SR_INT9_VEC_REG,  "External Serial Source 9"},
+    { EPIC_SR_INT10_VEC_REG, "External Serial Source 10"},
+    { EPIC_SR_INT11_VEC_REG, "External Serial Source 11"},
+    { EPIC_SR_INT12_VEC_REG, "External Serial Source 12"},
+    { EPIC_SR_INT13_VEC_REG, "External Serial Source 13"},
+    { EPIC_SR_INT14_VEC_REG, "External Serial Source 14"},
+    { EPIC_SR_INT15_VEC_REG, "External Serial Source 15"},
+
+    { EPIC_I2C_INT_VEC_REG,  "Internal I2C Source"},
+    { EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"},
+    { EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"},
+    { EPIC_MSG_INT_VEC_REG,  "Internal Message Source"},
+    };
+
+VOIDFUNCPTR intVecTbl[MAXVEC];    /* Interrupt vector table */
+
+
+/****************************************************************************
+*  epicInit - Initialize the EPIC registers
+*
+*  This routine resets the Global Configuration Register, thus it:
+*     -  Disables all interrupts
+*     -  Sets epic registers to reset values
+*     -  Sets the value of the Processor Current Task Priority to the
+*        highest priority (0xF).
+*  epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass
+*  Through or 8259 compatible mode).
+*
+*  If IRQType (input) is Direct IRQs:
+*     - IRQType is written to the SIE bit of the EPIC Interrupt
+*       Configuration register (ICR).
+*     - clkRatio is ignored.
+*  If IRQType is Serial IRQs:
+*     - both IRQType and clkRatio will be written to the ICR register
+*/
+
+void epicInit
+    (
+    unsigned int IRQType,      /* Direct or Serial */
+    unsigned int clkRatio      /* Clk Ratio for Serial IRQs */
+    )
+    {
+    ULONG tmp;
+
+    tmp = sysEUMBBARRead(EPIC_GLOBAL_REG);
+    tmp |= 0xa0000000;                  /* Set the Global Conf. register */
+    sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp);
+	/*
+	 * Wait for EPIC to reset - CLH
+	 */
+    while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1);
+    sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000);
+    tmp = sysEUMBBARRead(EPIC_INT_CONF_REG);    /* Read interrupt conf. reg */
+
+    if (IRQType == EPIC_DIRECT_IRQ)             /* direct mode */
+	sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
+    else                                        /* Serial mode */
+	{
+	tmp = (clkRatio << 28) | 0x08000000;    /* Set clock ratio */
+	sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
+	}
+
+    while (epicIntAck() != 0xff)       /* Clear all pending interrupts */
+		epicEOI();
+}
+
+/****************************************************************************
+ *  epicIntEnable - Enable an interrupt source
+ *
+ *  This routine clears the mask bit of an external, an internal or
+ *  a Timer register to enable the interrupt.
+ *
+ *  RETURNS:  None
+ */
+void epicIntEnable(int intVec)
+{
+    ULONG tmp;
+    ULONG srAddr;
+
+    srAddr = SrcVecTable[intVec].srcAddr;  /* Retrieve src Vec/Prio register */
+    tmp = sysEUMBBARRead(srAddr);
+    tmp &= ~EPIC_VEC_PRI_MASK;             /* Clear the mask bit */
+    tmp |= (EPIC_VEC_PRI_DFLT_PRI << 16);   /* Set priority to Default - CLH */
+    tmp |= intVec;				           /* Set Vector number */
+    sysEUMBBARWrite(srAddr, tmp);
+
+    return;
+    }
+
+/****************************************************************************
+ *  epicIntDisable - Disable an interrupt source
+ *
+ *  This routine sets the mask bit of an external, an internal or
+ *  a Timer register to disable the interrupt.
+ *
+ *  RETURNS:  OK or ERROR
+ *
+ */
+
+void epicIntDisable
+    (
+    int intVec        /* Interrupt vector number */
+    )
+    {
+
+    ULONG tmp, srAddr;
+
+    srAddr = SrcVecTable[intVec].srcAddr;
+    tmp = sysEUMBBARRead(srAddr);
+    tmp |= 0x80000000;                      /* Set the mask bit */
+    sysEUMBBARWrite(srAddr, tmp);
+    return;
+    }
+
+/****************************************************************************
+ * epicIntSourceConfig - Set properties of an interrupt source
+ *
+ * This function sets interrupt properites (Polarity, Sense, Interrupt
+ * Prority, and Interrupt Vector) of an Interrupt Source.  The properties
+ * can be set when the current source is not in-request or in-service,
+ * which is determined by the Activity bit.  This routine return ERROR
+ * if the the Activity bit is 1 (in-request or in-service).
+ *
+ * This function assumes that the Source Vector/Priority register (input)
+ * is a valid address.
+ *
+ * RETURNS:  OK or ERROR
+ */
+
+int epicIntSourceConfig
+    (
+    int   Vect,                         /* interrupt source vector number */
+    int   Polarity,                     /* interrupt source polarity */
+    int   Sense,                        /* interrupt source Sense */
+    int   Prio                          /* interrupt source priority */
+    )
+
+    {
+    ULONG tmp, newVal;
+    ULONG actBit, srAddr;
+
+    srAddr = SrcVecTable[Vect].srcAddr;
+    tmp = sysEUMBBARRead(srAddr);
+    actBit = (tmp & 40000000) >> 30;    /* retrieve activity bit - bit 30 */
+    if (actBit == 1)
+	return ERROR;
+
+    tmp &= 0xff30ff00;     /* Erase previously set P,S,Prio,Vector bits */
+    newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect;
+    sysEUMBBARWrite(srAddr, tmp | newVal );
+    return (OK);
+    }
+
+/****************************************************************************
+ * epicIntAck - acknowledge an interrupt
+ *
+ * This function reads the Interrupt acknowldge register and return
+ * the vector number of the highest pending interrupt.
+ *
+ * RETURNS: Interrupt Vector number.
+ */
+
+unsigned int epicIntAck(void)
+{
+    return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG ));
+}
+
+/****************************************************************************
+ * epicEOI - signal an end of interrupt
+ *
+ * This function writes 0x0 to the EOI register to signal end of interrupt.
+ * It is usually called after an interrupt routine is served.
+ *
+ * RETURNS: None
+ */
+
+void epicEOI(void)
+    {
+    sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0);
+    }
+
+/****************************************************************************
+ *  epicCurTaskPrioSet - sets the priority of the Processor Current Task
+ *
+ *  This function should be called after epicInit() to lower the priority
+ *  of the processor current task.
+ *
+ *  RETURNS:  OK or ERROR
+ */
+
+int epicCurTaskPrioSet
+    (
+    int prioNum                 /* New priority value */
+    )
+    {
+
+    if ( (prioNum < 0) || (prioNum > 0xF))
+	return ERROR;
+    sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum);
+    return OK;
+    }
+
+
+/************************************************************************
+ * function: epicIntTaskGet
+ *
+ * description: Get value of processor current interrupt task priority register
+ *
+ * note:
+ ***********************************************************************/
+unsigned char epicIntTaskGet()
+{
+  /* get the interrupt task priority register */
+    ULONG reg;
+    unsigned char rec;
+
+    reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG );
+    rec = ( reg & 0x0F );
+    return rec;
+}
+
+
+/**************************************************************
+ * function: epicISR
+ *
+ * description: EPIC service routine called by the core exception
+ *              at 0x500
+ *
+ * note:
+ **************************************************************/
+unsigned int epicISR(void)
+{
+   return 0;
+}
+
+
+/************************************************************
+ * function: epicModeGet
+ *
+ * description: query EPIC mode, return 0 if pass through mode
+ *                               return 1 if mixed mode
+ *
+ * note:
+ *************************************************************/
+unsigned int epicModeGet(void)
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( EPIC_GLOBAL_REG );
+    return (( val & 0x20000000 ) >> 29);
+}
+
+
+/*********************************************
+ * function: epicConfigGet
+ *
+ * description: Get the EPIC interrupt Configuration
+ *              return 0 if not error, otherwise return 1
+ *
+ * note:
+ ********************************************/
+void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable)
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( EPIC_INT_CONF_REG );
+    *clkRatio = ( val & 0x70000000 ) >> 28;
+    *serEnable = ( val & 0x8000000 ) >> 27;
+}
+
+
+/*******************************************************************
+ *  sysEUMBBARRead - Read a 32-bit EUMBBAR register
+ *
+ *  This routine reads the content of a register in the Embedded
+ *  Utilities Memory Block, and swaps to big endian before returning
+ *  the value.
+ *
+ *  RETURNS:  The content of the specified EUMBBAR register.
+ */
+
+ULONG sysEUMBBARRead
+    (
+    ULONG regNum
+    )
+    {
+    ULONG temp;
+
+    temp = *(ULONG *) (CONFIG_SYS_EUMB_ADDR + regNum);
+    return ( LONGSWAP(temp));
+    }
+
+/*******************************************************************
+ *  sysEUMBBARWrite - Write a 32-bit EUMBBAR register
+ *
+ *  This routine swaps the value to little endian then writes it to
+ *  a register in the Embedded Utilities Memory Block address space.
+ *
+ *  RETURNS: N/A
+ */
+
+void sysEUMBBARWrite
+    (
+    ULONG regNum,               /* EUMBBAR register address */
+    ULONG regVal                /* Value to be written */
+    )
+    {
+
+    *(ULONG *) (CONFIG_SYS_EUMB_ADDR + regNum) = LONGSWAP(regVal);
+    return ;
+    }
+
+
+/********************************************************
+ * function: epicVendorId
+ *
+ * description: return the EPIC Vendor Identification
+ *              register:
+ *
+ *              siliccon version, device id, and vendor id
+ *
+ * note:
+ ********************************************************/
+void epicVendorId
+   (
+    unsigned int *step,
+    unsigned int *devId,
+    unsigned int *venId
+   )
+   {
+    ULONG val;
+    val = sysEUMBBARRead( EPIC_VENDOR_ID_REG );
+    *step  = ( val & 0x00FF0000 ) >> 16;
+    *devId = ( val & 0x0000FF00 ) >> 8;
+    *venId = ( val & 0x000000FF );
+    }
+
+/**************************************************
+ * function: epicFeatures
+ *
+ * description: return the number of IRQ supported,
+ *              number of CPU, and the version of the
+ *              OpenEPIC
+ *
+ * note:
+ *************************************************/
+void epicFeatures
+    (
+    unsigned int *noIRQs,
+    unsigned int *noCPUs,
+    unsigned int *verId
+    )
+    {
+    ULONG val;
+
+    val = sysEUMBBARRead( EPIC_FEATURES_REG );
+    *noIRQs  = ( val & 0x07FF0000 ) >> 16;
+    *noCPUs  = ( val & 0x00001F00 ) >> 8;
+    *verId   = ( val & 0x000000FF );
+}
+
+
+/*********************************************************
+ * function: epciTmFrequncySet
+ *
+ * description: Set the timer frequency reporting register
+ ********************************************************/
+void epicTmFrequencySet( unsigned int frq )
+{
+    sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq);
+}
+
+/*******************************************************
+ * function: epicTmFrequncyGet
+ *
+ * description: Get the current value of the Timer Frequency
+ * Reporting register
+ *
+ ******************************************************/
+unsigned int epicTmFrequencyGet(void)
+{
+    return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ;
+}
+
+
+/****************************************************
+ * function: epicTmBaseSet
+ *
+ * description: Set the #n global timer base count register
+ *              return 0 if no error, otherwise return 1.
+ *
+ * note:
+ ****************************************************/
+unsigned int epicTmBaseSet
+    (
+    ULONG srcAddr,         /* Address of the Timer Base register */
+    unsigned int cnt,    /* Base count */
+    unsigned int inhibit   /* 1 - count inhibit */
+    )
+{
+
+    unsigned int val = 0x80000000;
+    /* First inhibit counting the timer */
+    sysEUMBBARWrite(srcAddr, val) ;
+
+    /* set the new value */
+    val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31);
+    sysEUMBBARWrite(srcAddr, val) ;
+    return 0;
+}
+
+/***********************************************************************
+ * function: epicTmBaseGet
+ *
+ * description: Get the current value of the global timer base count register
+ *              return 0 if no error, otherwise return 1.
+ *
+ * note:
+ ***********************************************************************/
+unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val )
+{
+    *val = sysEUMBBARRead( srcAddr );
+    *val = *val & 0x7fffffff;
+    return 0;
+}
+
+/***********************************************************
+ * function: epicTmCountGet
+ *
+ * description: Get the value of a given global timer
+ *              current count register
+ *              return 0 if no error, otherwise return 1
+ * note:
+ **********************************************************/
+unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val )
+{
+    *val = sysEUMBBARRead( srcAddr );
+    *val = *val & 0x7fffffff;
+    return 0;
+}
+
+
+/***********************************************************
+ * function: epicTmInhibit
+ *
+ * description: Stop counting of a given global timer
+ *              return 0 if no error, otherwise return 1
+ *
+ * note:
+ ***********************************************************/
+unsigned int epicTmInhibit( unsigned int srcAddr )
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( srcAddr );
+    val |= 0x80000000;
+    sysEUMBBARWrite( srcAddr, val );
+    return 0;
+}
+
+/******************************************************************
+ * function: epicTmEnable
+ *
+ * description: Enable counting of a given global timer
+ *              return 0 if no error, otherwise return 1
+ *
+ * note:
+ *****************************************************************/
+unsigned int epicTmEnable( ULONG srcAddr )
+{
+    ULONG val;
+
+    val = sysEUMBBARRead( srcAddr );
+    val &= 0x7fffffff;
+    sysEUMBBARWrite( srcAddr, val );
+    return 0;
+}
+
+void epicSourcePrint(int Vect)
+    {
+    ULONG srcVal;
+
+    srcVal = sysEUMBBARRead(SrcVecTable[Vect].srcAddr);
+    PRINT("%s\n", SrcVecTable[Vect].srcName);
+    PRINT("Address   = 0x%lx\n", SrcVecTable[Vect].srcAddr);
+    PRINT("Vector    = %ld\n", (srcVal & 0x000000FF) );
+    PRINT("Mask      = %ld\n", srcVal >> 31);
+    PRINT("Activitiy = %ld\n", (srcVal & 40000000) >> 30);
+    PRINT("Polarity  = %ld\n", (srcVal & 0x00800000) >> 23);
+    PRINT("Sense     = %ld\n", (srcVal & 0x00400000) >> 22);
+    PRINT("Priority  = %ld\n", (srcVal & 0x000F0000) >> 16);
+    }
diff --git a/arch/powerpc/cpu/mpc824x/drivers/epic/epic2.S b/arch/powerpc/cpu/mpc824x/drivers/epic/epic2.S
new file mode 100644
index 0000000..52d19aa
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/epic/epic2.S
@@ -0,0 +1,196 @@
+/**************************************
+ *
+ * copyright @ Motorola, 1999
+ *
+ **************************************/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/processor.h>
+
+/*********************************************
+ * function: CoreExtIntEnable
+ *
+ * description: Enable 603e core external interrupt
+ *
+ * note: mtmsr is context-synchronization
+ **********************************************/
+		.text
+		.align 2
+	.global CoreExtIntEnable
+CoreExtIntEnable:
+	 mfmsr    r3
+
+	 ori      r3,r3,0x8000         /* enable external interrupt */
+	 mtmsr    r3
+
+	 bclr 20, 0
+
+/*******************************************
+ * function: CoreExtIntDisable
+ *
+ * description: Disable 603e core external interrupt
+ *
+ * note:
+ *******************************************/
+		.text
+		.align 2
+	.global CoreExtIntDisable
+CoreExtIntDisable:
+	mfmsr    r4
+
+	xor	r3,r3,r3
+	or      r3,r3,r4
+
+	andis.	r4,r4,0xffff
+	andi.   r3,r3,0x7fff         /* disable external interrupt */
+
+	or      r3,r3,r4
+	mtmsr    r3
+
+	bclr 20, 0
+
+/*********************************************************
+ * function: epicEOI
+ *
+ * description: signal the EOI and restore machine status
+ *       Input: r3 - value of eumbbar
+ *       Output: r3 - value of eumbbar
+ *               r4 - ISR vector value
+ * note:
+ ********************************************************/
+		.text
+		.align 2
+	.global epicEOI
+epicEOI:
+	lis	r5,0x0006	        /* Build End Of Interrupt Register offset */
+	ori	r5,r5,0x00b0
+	xor	r7,r7,r7	        /* Clear r7 */
+	stwbrx	r7,r5,r3	    /* Save r7, writing to this register will
+					     * intidate the end of processing the
+					     * highest interrupt.
+			     */
+	sync
+
+	/* ---RESTORE MACHINE STATE */
+	mfmsr	r13		        /* Clear Recoverable Interrupt bit in MSR */
+	or      r7,r7,r13
+
+	andis.  r7,r7,0xffff
+	andi.	r13,r13,0x7ffd	/* (and disable interrupts) */
+	or      r13,r13,r7
+	mtmsr	r13
+
+	lwz   r13,0x1c(r1)      /* pull ctr */
+	mtctr r13
+
+	lwz   r13,0x18(r1)      /* pull xer */
+	mtctr r13
+
+	lwz   r13,0x14(r1)      /* pull lr */
+	mtctr r13
+
+	lwz	    r13,0x10(r1)	/* Pull SRR1 from stack */
+	mtspr   SRR1,r13	    /* Restore SRR1 */
+
+	lwz	    r13,0xc(r1)	    /* Pull SRR0 from stack */
+	mtspr   SRR0,r13	    /* Restore SRR0 */
+
+	lwz	    r13,0x8(r1)	    /* Pull User stack pointer from stack */
+	mtspr   SPRG1,r13	    /* Restore SPRG1 */
+
+	lwz	r4,0x4(r1)          /* vector value */
+	lwz	r3,0x0(r1)          /* eumbbar */
+	sync
+
+	addi	r1,r1,0x20	/* Deallocate stack */
+	mtspr   SPRG0,r1	/* Save updated Supervisor stack pointer */
+	mfspr   r1,SPRG1	/* Restore User stack pointer */
+
+	bclr     20,0
+
+/***********************************************************
+ * function: exception routine called by exception vector
+ *           at 0x500, external interrupt
+ *
+ * description: Kahlua EPIC controller
+ *
+ * input:  r3 - content of eumbbar
+ * output: r3 - ISR return value
+ *         r4 - Interrupt vector number
+ * note:
+ ***********************************************************/
+
+       .text
+	   .align 2
+       .global epic_exception
+
+epic_exception:
+
+	/*---SAVE MACHINE STATE TO A STACK */
+	mtspr   SPRG1,r1	/* Save User stack pointer to SPRG1 */
+	mfspr	r1,SPRG0	/* Load Supervisor stack pointer into r1 */
+
+	stwu	r3,-0x20(r1)	/* Push the value of eumbbar onto stack */
+
+	mfspr	r3,SPRG1	/* Push User stack pointer onto stack */
+	stw	    r3,0x8(r1)
+	mfspr	r3,SRR0	    /* Push SRR0 onto stack */
+	stw	    r1,0xc(r1)
+	mfspr	r3,SRR1	    /* Push SRR1 onto stack */
+	stw	    r3,0x10(r1)
+	mflr    r3
+	stw     r3,0x14(r1) /* Push LR */
+	mfxer   r3
+	stw     r3,0x18(r1) /* Push Xer */
+	mfctr   r3
+	stw     r3,0x1c(r1) /* Push CTR */
+
+	mtspr	SPRG0,r1	/* Save updated Supervisor stack pointer
+					 * value to SPRG0
+			 */
+	mfmsr	r3
+	ori	    r3,r3,0x0002	/* Set Recoverable Interrupt bit in MSR */
+	mtmsr	r3
+
+	/* ---READ IN THE EUMBAR REGISTER */
+    lwz     r6,0(r1)       /* this is eumbbar */
+    sync
+
+	/* ---READ EPIC REGISTER:	PROCESSOR INTERRUPT ACKNOWLEDGE REGISTER */
+	lis	r5,0x0006	        /* Build Interrupt Acknowledge Register
+					     * offset
+			     */
+	ori	r5,r5,0x00a0
+	lwbrx	r7,r5,r6    /* Load interrupt vector into r7 */
+	sync
+
+	/* --MASK OFF ALL BITS EXCEPT THE VECTOR */
+	xor	r3,r3,r3
+    xor r4,r4,r4
+	or    r3, r3, r6        /*  eumbbar in r3 */
+	andi. r4,r7,0x00ff	/* Mask off bits, vector in r4 */
+
+    stw     r4,0x04(r1)     /* save the vector value */
+
+    lis     r5,epicISR@ha
+	ori     r5,r5,epicISR@l
+	mtlr    r5
+	blrl
+
+    xor   r30,r30,r30
+	or    r30,r30,r3        /* save the r3 which containts the return value from epicISR */
+
+	/* ---READ IN THE EUMBAR REGISTER */
+    lwz     r3,0(r1)
+    sync
+
+    lis     r5,epicEOI@ha
+	ori     r5,r5,epicEOI@l
+	mtlr    r5
+	blrl
+
+    xor  r3,r3,r3
+	or   r3,r3,r30           /* restore the ISR return value  */
+
+	bclr     20,0
diff --git a/arch/powerpc/cpu/mpc824x/drivers/epic/epicutil.S b/arch/powerpc/cpu/mpc824x/drivers/epic/epicutil.S
new file mode 100644
index 0000000..4877050
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/epic/epicutil.S
@@ -0,0 +1,57 @@
+/**************************************
+ *
+ * copyright @ Motorola, 1999
+ *
+ *
+ * This file contains two commonly used
+ * lower level utility routines.
+ *
+ * The utility routines are also in other
+ * Kahlua device driver libraries. The
+ * need to be linked in only once.
+ **************************************/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+/**********************************************************
+ * function: load_runtime_reg
+ *
+ * input:  r3 - value of eumbbar
+ *         r4 - register offset in embedded utility space
+ *
+ * output: r3 - register content
+ **********************************************************/
+      .text
+      .align 2
+      .global load_runtime_reg
+
+load_runtime_reg:
+
+		  xor r5,r5,r5
+	  or  r5,r5,r3       /* save eumbbar */
+
+	      lwbrx	r3,r4,r5
+	      sync
+
+	      bclr 20, 0
+
+/****************************************************************
+ * function: store_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ *        r4 - register offset in embedded utility space
+ *        r5 - new value to be stored
+ *
+ ****************************************************************/
+	   .text
+	   .align 2
+	   .global store_runtime_reg
+store_runtime_reg:
+
+		  xor r0,r0,r0
+
+	      stwbrx r5,  r4, r3
+	      sync
+
+		  bclr   20,0
diff --git a/arch/powerpc/cpu/mpc824x/drivers/errors.h b/arch/powerpc/cpu/mpc824x/drivers/errors.h
new file mode 100644
index 0000000..20794a2
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/errors.h
@@ -0,0 +1,212 @@
+/*	Copyright Motorola, Inc. 1993, 1994
+	ALL RIGHTS RESERVED
+
+	You are hereby granted a copyright license to use, modify, and
+	distribute the SOFTWARE so long as this entire notice is retained
+	without alteration in any modified and/or redistributed versions,
+	and that such modified versions are clearly identified as such.
+	No licenses are granted by implication, estoppel or otherwise under
+	any patents or trademarks of Motorola, Inc.
+
+	The SOFTWARE is provided on an "AS IS" basis and without warranty.
+	To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+	ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+	WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+	PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+	REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+	THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+
+	To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+	MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+	BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+	INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+	INABILITY TO USE THE SOFTWARE.   Motorola assumes no responsibility
+	for the maintenance and support of the SOFTWARE.
+
+*/
+
+
+#include "config.h"
+
+/*
+	 1         2         3         4         5         6         7         8
+01234567890123456789012345678901234567890123456789012345678901234567890123456789
+*/
+/* List define statements here */
+
+/* These are for all the toolboxes and functions to use. These will help
+to standardize the error handling in the current project */
+
+				/* this is the "data type" for the error
+				messages in the system */
+#define STATUS unsigned int
+
+				/* this is a success status code */
+#define SUCCESS 1
+
+				/* likewise this is failure */
+#define FAILURE 0
+
+#define NUM_ERRORS 47
+
+/* This first section of "defines" are for error codes ONLY.  The called
+   routine will return one of these error codes to the caller.  If the final
+   returned code is "VALID", then everything is a-okay.  However, if one
+   of the functions returns a non-valid status, that error code should be
+   propogated back to all the callers.  At the end, the last caller will
+   call an error_processing function, and send in the status which was
+   returned.  It's up to the error_processing function to determine which
+   error occured (as indicated by the status), and print an appropriate
+   message back to the user.
+*/
+/*----------------------------------------------------------------------*/
+/* these are specifically for the parser routines			*/
+
+#define UNKNOWN_COMMAND		0xfb00 /* "unrecognized command " */
+#define UNKNOWN_REGISTER	0xfb01 /* "unknown register "*/
+#define ILLEGAL_RD_STAGE	0xfb02 /* cannot specify reg. family in range*/
+#define ILLEGAL_REG_FAMILY	0xfb03 /* "cannot specify a range of special
+					or miscellaneous registers"*/
+#define RANGE_CROSS_FAMILY	0xfb04 /* "cannot specify a range across
+					register families" */
+#define UNIMPLEMENTED_STAGE	0xfb05 /* invalid rd or rmm parameter format */
+#define REG_NOT_WRITEABLE	0xfb06 /* "unknown operator in arguements"*/
+#define INVALID_FILENAME	0xfb07 /* "invalid download filename" */
+#define INVALID_BAUD_RATE	0xfb08	/* invalid baud rate from sb command */
+#define UNSUPPORTED_REGISTER	0xfb09	/* Special register is not supported */
+#define FOR_BOARD_ONLY		0xfb0a  /* "Not available for Unix." */
+
+
+/*----------------------------------------------------------------------*/
+/* these are for the error checking toolbox				*/
+
+#define INVALID			0xfd00 /* NOT valid */
+#define VALID			0xfd01 /* valid */
+
+					/* This error is found in the fcn:
+					is_right_size_input() to indicate
+					that the input was not 8 characters
+					long.  */
+#define INVALID_SIZE		0xfd02
+
+					/* This error is found in the fcn:
+					is_valid_address_range() to indicate
+					that the address given falls outside
+					of valid memory defined by MEM_START
+					to MEM_END.
+					*/
+#define OUT_OF_BOUNDS_ADDRESS	0xfd03
+
+					/* This error is found in the fcn:
+					is_valid_hex_input() to indicate that
+					one of more of the characters entered
+					are not valid hex characters.  Valid
+					hex characters are 0-9, A-F, a-f.
+					*/
+#define INVALID_HEX_INPUT	0xfd04
+
+					/* This error is found in the fcn:
+					is_valid_register_number() to indicate
+					that a given register does not exist.
+					*/
+#define REG_NOT_READABLE	0xfd05
+
+					/* This error is found in the fcn:
+					is_word_aligned_address() to indicate
+					that the given address is not word-
+					aligned.  A word-aligned address ends
+					in 0x0,0x4,0x8,0xc.
+					*/
+#define	NOT_WORD_ALIGNED	0xfd07
+
+					/* This error is found in the fcn:
+					is_valid_address_range() to indicate
+					that the starting address is greater
+					than the ending address.
+					*/
+#define REVERSED_ADDRESS	0xfd08
+
+					/* this error tells us that the address
+					specified as the destination is within
+					the source addresses  */
+#define RANGE_OVERLAP		0xfd09
+
+
+#define	ERROR			0xfd0a /* An error occured */
+#define INVALID_PARAM		0xfd0b /* "invalid input parameter " */
+
+
+#define INVALID_FLAG		0xfd0c	/* invalid flag */
+
+/*----------------------------------------------------------------------*/
+/* these are for the getarg toolbox					*/
+
+#define INVALID_NUMBER_ARGS	0xFE00 /* invalid number of commd arguements */
+#define UNKNOWN_PARAMETER	0xFE01 /* "unknown type of parameter "*/
+
+
+/*----------------------------------------------------------------------*/
+/* these are for the tokenizer toolbox					*/
+
+#define ILLEGAL_CHARACTER	0xFF00 /* unrecognized char. in input stream*/
+#define TTL_NOT_SORTED		0xFF01 /* token translation list not sorted */
+#define TTL_NOT_DEFINED		0xFF02 /* token translation list not assigned*/
+#define INVALID_STRING		0xFF03 /* unable to extract string from input */
+#define BUFFER_EMPTY		0xFF04 /* "input buffer is empty" */
+#define INVALID_MODE		0xFF05 /* input buf is in an unrecognized mode*/
+#define TOK_INTERNAL_ERROR	0xFF06 /* "internal tokenizer error" */
+#define TOO_MANY_IBS		0xFF07 /* "too many open input buffers" */
+#define NO_OPEN_IBS		0xFF08 /* "no open input buffers" */
+
+
+/* these are for the read from screen toolbox */
+
+#define RESERVED_WORD		0xFC00 /* used a reserved word as an arguement*/
+
+
+/* these are for the breakpoint routines */
+
+#define FULL_BPDS		0xFA00 /* breakpoint data structure is full */
+
+
+/* THESE are for the downloader */
+
+#define NOT_IN_S_RECORD_FORMAT	0xf900 /* "not in S-Record Format" */
+#define UNREC_RECORD_TYPE	0xf901 /* "unrecognized record type" */
+#define CONVERSION_ERROR	0xf902 /* "ascii to int conversion error" */
+#define INVALID_MEMORY		0xf903 /* "bad s-record memory address " */
+
+
+/* these are for the compression and decompression stuff */
+
+#define COMP_UNK_CHARACTER	0xf800 /* "unknown compressed character " */
+
+#define COMP_UNKNOWN_STATE	0xf801 /* "unknown binary state" */
+
+#define NOT_IN_COMPRESSED_FORMAT 0xf802 /* not in compressed S-Record format */
+
+
+/* these are for the DUART handling things */
+
+					/* "unrecognized serial port configuration" */
+#define UNKNOWN_PORT_STATE	0xf700
+
+
+/* these are for the register toolbox */
+
+					/* "cannot find register in special
+					 purpose register file " */
+#define SPR_NOT_FOUND		0xf600
+
+
+/* these are for the duart specific stuff */
+
+					/* "transparent mode needs access to
+						two serial ports" */
+#define TM_NEEDS_BOTH_PORTS	0xf500
+
+
+/*----------------------------------------------------------------------*/
+/* these are specifically for the flash routines			*/
+#define FLASH_ERROR		0xf100		/* general flash error */
diff --git a/arch/powerpc/cpu/mpc824x/drivers/i2c/i2c.c b/arch/powerpc/cpu/mpc824x/drivers/i2c/i2c.c
new file mode 100644
index 0000000..637ae4c
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/i2c/i2c.c
@@ -0,0 +1,270 @@
+/*
+ * (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>
+
+#undef I2CDBG
+
+#ifdef CONFIG_HARD_I2C
+#include <i2c.h>
+
+#define TIMEOUT (CONFIG_SYS_HZ/4)
+
+#define I2C_Addr ((unsigned *)(CONFIG_SYS_EUMB_ADDR + 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 MPC107_CCR_MEN  0x80
+#define MPC107_CCR_MIEN 0x40
+#define MPC107_CCR_MSTA 0x20
+#define MPC107_CCR_MTX  0x10
+#define MPC107_CCR_TXAK 0x08
+#define MPC107_CCR_RSTA 0x04
+
+#define MPC107_CSR_MCF  0x80
+#define MPC107_CSR_MAAS 0x40
+#define MPC107_CSR_MBB  0x20
+#define MPC107_CSR_MAL  0x10
+#define MPC107_CSR_SRW  0x04
+#define MPC107_CSR_MIF  0x02
+#define MPC107_CSR_RXAK 0x01
+
+#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 (0x1020, I2CFDR);
+	/* write slave address */
+	writel (slaveadd, I2CADR);
+	/* clear status register */
+	writel (0x0, I2CCSR);
+	/* start I2C controller */
+	writel (MPC107_CCR_MEN, I2CCCR);
+
+	return;
+}
+
+static __inline__ int i2c_wait4bus (void)
+{
+	ulong timeval = get_timer (0);
+
+	while (readl (I2CCSR) & MPC107_CSR_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 & MPC107_CSR_MIF))
+			continue;
+
+		writel (0x0, I2CCSR);
+
+		if (csr & MPC107_CSR_MAL) {
+#ifdef I2CDBG
+			printf ("i2c_wait: MAL\n");
+#endif
+			return -1;
+		}
+
+		if (!(csr & MPC107_CSR_MCF)) {
+#ifdef I2CDBG
+			printf ("i2c_wait: unfinished\n");
+#endif
+			return -1;
+		}
+
+		if (write == I2C_WRITE && (csr & MPC107_CSR_RXAK)) {
+#ifdef I2CDBG
+			printf ("i2c_wait: No RXACK\n");
+#endif
+			return -1;
+		}
+
+		return 0;
+	} while (get_timer (timeval) < TIMEOUT);
+
+#ifdef I2CDBG
+	printf ("i2c_wait: timed out\n");
+#endif
+	return -1;
+}
+
+static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta)
+{
+	writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX |
+		(rsta ? MPC107_CCR_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 (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_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 (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+		((length == 1) ? MPC107_CCR_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 (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+				MPC107_CCR_TXAK, I2CCCR);
+
+		/* Generate stop on last byte */
+		if (i == length - 1)
+			writel (MPC107_CCR_MEN | MPC107_CCR_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 (MPC107_CCR_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 (MPC107_CCR_MEN, I2CCCR);
+
+	return !(i == length);
+}
+
+int i2c_probe (uchar chip)
+{
+	int tmp;
+
+	/*
+	 * Try to read the first location of the chip.  The underlying
+	 * driver doesn't appear to support sending just the chip address
+	 * and looking for an <ACK> back.
+	 */
+	udelay (10000);
+	return i2c_read (chip, 0, 1, (uchar *) &tmp, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */
diff --git a/arch/powerpc/cpu/mpc824x/drivers/i2c_export.h b/arch/powerpc/cpu/mpc824x/drivers/i2c_export.h
new file mode 100644
index 0000000..6264d18
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/drivers/i2c_export.h
@@ -0,0 +1,103 @@
+#ifndef I2C_EXPORT_H
+#define I2C_EXPORT_H
+
+/****************************************************
+ *
+ * Copyright Motrola 1999
+ *
+ ****************************************************/
+
+/* These are the defined return values for the I2C_do_transaction function.
+ * Any non-zero value indicates failure.  Failure modes can be added for
+ * more detailed error reporting.
+ */
+typedef enum _i2c_status
+{
+ I2C_SUCCESS     = 0,
+ I2C_ERROR,
+} I2C_Status;
+
+/* These are the defined tasks for I2C_do_transaction.
+ * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
+ */
+typedef enum _i2c_transaction_mode
+{
+	I2C_MASTER_RCV =  0,
+	I2C_MASTER_XMIT = 1,
+} I2C_TRANSACTION_MODE;
+
+typedef enum _i2c_interrupt_mode
+{
+	I2C_INT_DISABLE =  0,
+	I2C_INT_ENABLE = 1,
+} I2C_INTERRUPT_MODE;
+
+typedef enum _i2c_stop
+{
+	I2C_NO_STOP =  0,
+	I2C_STOP = 1,
+} I2C_STOP_MODE;
+
+typedef enum _i2c_restart
+{
+	I2C_NO_RESTART =  0,
+	I2C_RESTART = 1,
+} I2C_RESTART_MODE;
+
+/******************** App. API ********************
+ * The application API is for user level application
+ * to use the functionality provided by I2C driver.
+ * This is a "generic" I2C interface, it should contain
+ * nothing specific to the Kahlua implementation.
+ * Only the generic functions are exported by the library.
+ *
+ * Note: Its App.s responsibility to swap the data
+ *       byte. In our API, we just transfer whatever
+ *       we are given
+ **************************************************/
+
+
+/*  Initialize I2C unit with the following:
+ *  driver's slave address
+ *  interrupt enabled
+ *  optional pointer to application layer print function
+ *
+ *  These parameters may be added:
+ *  desired clock rate
+ *  digital filter frequency sampling rate
+ *
+ *  This function must be called before I2C unit can be used.
+ */
+extern I2C_Status I2C_Initialize(
+	unsigned char addr,            /* driver's I2C slave address */
+	I2C_INTERRUPT_MODE en_int,     /* 1 - enable I2C interrupt
+					* 0 - disable I2C interrupt
+					*/
+	int (*app_print_function)(char *,...)); /* pointer to optional "printf"
+						 * provided by application
+						 */
+
+/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
+ * are implemented.  Both are only in polling mode.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * addr is the I2C address of the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ *        I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ *        I2C_RESTART, this is a continuation of existing transaction
+ */
+extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
+				      I2C_TRANSACTION_MODE act,
+				      unsigned char i2c_addr,
+				      unsigned char data_addr,
+				      int len,
+				      char *buffer,
+				      I2C_STOP_MODE stop,
+				      int retry,
+				      I2C_RESTART_MODE rsta);
+#endif
diff --git a/arch/powerpc/cpu/mpc824x/interrupts.c b/arch/powerpc/cpu/mpc824x/interrupts.c
new file mode 100644
index 0000000..139c52c
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/interrupts.c
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.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 <mpc824x.h>
+#include <asm/processor.h>
+#include <asm/pci_io.h>
+#include <commproc.h>
+#include "drivers/epic.h"
+
+int interrupt_init_cpu (unsigned *decrementer_count)
+{
+	*decrementer_count = (get_bus_freq (0) / 4) / CONFIG_SYS_HZ;
+
+	/*
+	 * It's all broken at the moment and I currently don't need
+	 * interrupts. If you want to fix it, have a look at the epic
+	 * drivers in dink32 v12. They do everthing and Motorola said
+	 * I could use the dink source in this project as long as
+	 * copyright notices remain intact.
+	 */
+
+	epicInit (EPIC_DIRECT_IRQ, 0);
+	/* EPIC won't generate INT unless Current Task Pri < 15 */
+	epicCurTaskPrioSet(0);
+
+	return (0);
+}
+
+/****************************************************************************/
+
+/*
+ * Handle external interrupts
+ */
+void external_interrupt (struct pt_regs *regs)
+{
+	register unsigned long temp;
+
+	pci_readl (CONFIG_SYS_EUMB_ADDR + EPIC_PROC_INT_ACK_REG, temp);
+	sync ();					/* i'm not convinced this is needed, but dink source has it */
+	temp &= 0xff;				/*get vector */
+
+	/*TODO: handle them -... */
+	epicEOI ();
+}
+
+/****************************************************************************/
+
+/*
+ * blank int handlers.
+ */
+
+void
+irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
+{
+}
+
+void irq_free_handler (int vec)
+{
+
+}
+
+/*TODO: some handlers for winbond and 87308 interrupts
+ and what about generic pci inteerupts?
+ vga?
+ */
+
+void timer_interrupt_cpu (struct pt_regs *regs)
+{
+	/* nothing to do here */
+	return;
+}
diff --git a/arch/powerpc/cpu/mpc824x/pci.c b/arch/powerpc/cpu/mpc824x/pci.c
new file mode 100644
index 0000000..72aaec7
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/pci.c
@@ -0,0 +1,78 @@
+/*
+ * arch/powerpc/kernel/mpc10x_common.c
+ *
+ * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
+ * Mem ctlr, EPIC, etc.
+ *
+ * Author: Mark A. Greer
+ *         mgreer@mvista.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <mpc824x.h>
+
+void pci_mpc824x_init (struct pci_controller *hose)
+{
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	/* System memory space */
+	pci_set_region(hose->regions + 0,
+		       CHRP_PCI_MEMORY_BUS,
+		       CHRP_PCI_MEMORY_PHYS,
+		       CHRP_PCI_MEMORY_SIZE,
+		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+	/* PCI memory space */
+	pci_set_region(hose->regions + 1,
+		       CHRP_PCI_MEM_BUS,
+		       CHRP_PCI_MEM_PHYS,
+		       CHRP_PCI_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* ISA/PCI memory space */
+	pci_set_region(hose->regions + 2,
+		       CHRP_ISA_MEM_BUS,
+		       CHRP_ISA_MEM_PHYS,
+		       CHRP_ISA_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* PCI I/O space */
+	pci_set_region(hose->regions + 3,
+		       CHRP_PCI_IO_BUS,
+		       CHRP_PCI_IO_PHYS,
+		       CHRP_PCI_IO_SIZE,
+		       PCI_REGION_IO);
+
+	/* ISA/PCI I/O space */
+	pci_set_region(hose->regions + 4,
+		       CHRP_ISA_IO_BUS,
+		       CHRP_ISA_IO_PHYS,
+		       CHRP_ISA_IO_SIZE,
+		       PCI_REGION_IO);
+
+	hose->region_count = 5;
+
+	pci_setup_indirect(hose,
+			   CHRP_REG_ADDR,
+			   CHRP_REG_DATA);
+
+	pci_register_hose(hose);
+
+	hose->last_busno = pci_hose_scan(hose);
+}
+
+#endif
diff --git a/arch/powerpc/cpu/mpc824x/speed.c b/arch/powerpc/cpu/mpc824x/speed.c
new file mode 100644
index 0000000..fdcb972
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/speed.c
@@ -0,0 +1,118 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Gregory E. Allen, gallen@arlut.utexas.edu
+ * Applied Research Laboratories, The University of Texas at Austin
+ *
+ * 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 <mpc824x.h>
+#include <asm/processor.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* ------------------------------------------------------------------------- */
+/* NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency on
+ * PCI_SYNC_IN .
+ *
+ * CONFIG_PLL_PCI_TO_MEM_MULTIPLIER is only required on MPC8240
+ * boards. It should be defined as the PCI to Memory Multiplier as
+ * documented in the MPC8240 Hardware Specs.
+ *
+ * Other mpc824x boards don't need CONFIG_PLL_PCI_TO_MEM_MULTIPLIER
+ * because they can determine it from the PCR.
+ *
+ * Gary Milliorn <gary.milliorn@motorola.com> (who should know since
+ * he designed the Sandpoint) told us that the PCR is not in all revs
+ * of the MPC8240 CPU, so it's not guaranteeable and we cannot do
+ * away with CONFIG_PLL_PCI_TO_MEM_MULTIPLIER altogether.
+ */
+/* ------------------------------------------------------------------------- */
+
+/* This gives the PCI to Memory multiplier times 10 */
+/* The index is the value of PLL_CFG[0:4] */
+/* This is documented in the MPC8240/5 Hardware Specs */
+
+short pll_pci_to_mem_multiplier[] = {
+#if defined(CONFIG_MPC8240)
+	30, 30, 10, 10, 20, 10,  0, 10,
+	10,  0, 20,  0, 20,  0, 20,  0,
+	30,  0, 15,  0, 20,  0, 20,  0,
+	25,  0, 10,  0, 15, 15,  0,  0,
+#elif defined(CONFIG_MPC8245)
+	30, 30, 10, 10, 20, 10, 10, 10,
+	10, 20, 20, 15, 20, 15, 20, 30,
+	30, 40, 15, 40, 20, 25, 20, 40,
+	25, 20, 10, 20, 15, 15, 15,  0,
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+};
+
+#define CU824_PLL_STATE_REG	0xFE80002F
+#define PCR			0x800000E2
+
+/* ------------------------------------------------------------------------- */
+
+/* compute the memory bus clock frequency */
+ulong get_bus_freq (ulong dummy)
+{
+	unsigned char pll_cfg;
+#if defined(CONFIG_MPC8240) && !defined(CONFIG_CU824)
+	return (CONFIG_SYS_CLK_FREQ) * (CONFIG_PLL_PCI_TO_MEM_MULTIPLIER);
+#elif defined(CONFIG_CU824)
+	pll_cfg = *(volatile unsigned char *) (CU824_PLL_STATE_REG);
+	pll_cfg &= 0x1f;
+#else
+	CONFIG_READ_BYTE(PCR, pll_cfg);
+	pll_cfg = (pll_cfg >> 3) & 0x1f;
+#endif
+	return ((CONFIG_SYS_CLK_FREQ) * pll_pci_to_mem_multiplier[pll_cfg] + 5) / 10;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/* This gives the Memory to CPU Core multiplier times 10 */
+/* The index is the value of PLLRATIO in HID1 */
+/* This is documented in the MPC8240 Hardware Specs */
+/* This is not documented for MPC8245 ? FIXME */
+short pllratio_to_factor[] = {
+     0,  0,  0, 10, 20, 20, 25, 45,
+    30,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0, 10,  0,  0,  0, 45,
+    30,  0, 40,  0,  0,  0, 35,  0,
+};
+
+/* compute the CPU and memory bus clock frequencies */
+int get_clocks (void)
+{
+	uint hid1 = mfspr(HID1);
+	hid1 = (hid1 >> (32-5)) & 0x1f;
+	gd->cpu_clk = (pllratio_to_factor[hid1] * get_bus_freq(0) + 5)
+			  / 10;
+	gd->bus_clk = get_bus_freq(0);
+	return (0);
+}
diff --git a/arch/powerpc/cpu/mpc824x/start.S b/arch/powerpc/cpu/mpc824x/start.S
new file mode 100644
index 0000000..f3f595a
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/start.S
@@ -0,0 +1,766 @@
+/*
+ *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* U-Boot - Startup Code for PowerPC based Embedded Boards
+ *
+ *
+ * The processor starts at 0x00000100 and the code is executed
+ * from flash. The code is organized to be at an other address
+ * in memory, but as long we don't jump around before relocating.
+ * board_init lies at a quite high address and when the cpu has
+ * jumped there, everything is ok.
+ * This works because the cpu gives the FLASH (CS0) the whole
+ * address space at startup, and board_init lies as a echo of
+ * the flash somewhere up there in the memorymap.
+ *
+ * board_init will change CS0 to be positioned at the correct
+ * address and (s)dram will be positioned at address 0
+ */
+#include <config.h>
+#include <mpc824x.h>
+#include <timestamp.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
+
+/* We don't want the MMU yet.
+*/
+#undef	MSR_KERNEL
+/* FP, Machine Check and Recoverable Interr. */
+#define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r12 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)
+#if defined(CONFIG_FADS)
+	GOT_ENTRY(environment)
+#endif
+	END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+	.text
+	.long	0x27051956		/* U-Boot Magic Number			*/
+	.globl	version_string
+version_string:
+	.ascii U_BOOT_VERSION
+	.ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
+	.ascii CONFIG_IDENT_STRING, "\0"
+
+	. = EXC_OFF_SYS_RESET
+	.globl	_start
+_start:
+	li	r21, BOOTFLAG_COLD	/* Normal Power-On: Boot from FLASH	*/
+	b	boot_cold
+
+	. = EXC_OFF_SYS_RESET + 0x10
+
+	.globl	_start_warm
+_start_warm:
+	li	r21, BOOTFLAG_WARM	/* Software reboot			*/
+	b	boot_warm
+
+boot_cold:
+boot_warm:
+
+	/* Initialize machine status; enable machine check interrupt		*/
+	/*----------------------------------------------------------------------*/
+	li	r3, MSR_KERNEL		/* Set FP, ME, RI flags */
+	mtmsr	r3
+	mtspr	SRR1, r3		/* Make SRR1 match MSR */
+
+	addis	r0,0,0x0000		/* lets make sure that r0 is really 0 */
+	mtspr   HID0, r0		/* disable I and D caches */
+
+	mfspr	r3, ICR			/* clear Interrupt Cause Register */
+
+	mfmsr	r3			/* turn off address translation */
+	addis	r4,0,0xffff
+	ori	r4,r4,0xffcf
+	and	r3,r3,r4
+	mtmsr	r3
+	isync
+	sync				/* the MMU should be off... */
+
+
+in_flash:
+#if defined(CONFIG_BMW)
+	bl early_init_f /* Must be ASM: no stack yet! */
+#endif
+	/*
+	 * Setup BATs - cannot be done in C since we don't have a stack yet
+	 */
+	bl	setup_bats
+
+	/* Enable MMU.
+	 */
+	mfmsr	r3
+	ori	r3, r3, (MSR_IR | MSR_DR)
+	mtmsr	r3
+#if !defined(CONFIG_BMW)
+	/* Enable and invalidate data cache.
+	 */
+	mfspr	r3, HID0
+	mr	r2, r3
+	ori	r3, r3, HID0_DCE | HID0_DCI
+	ori	r2, r2, HID0_DCE
+	sync
+	mtspr	HID0, r3
+	mtspr	HID0, r2
+	sync
+
+	/* Allocate Initial RAM in data cache.
+	 */
+	lis	r3, CONFIG_SYS_INIT_RAM_ADDR@h
+	ori	r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
+	li	r2, 128
+	mtctr	r2
+1:
+	dcbz	r0, r3
+	addi	r3, r3, 32
+	bdnz	1b
+
+	/* Lock way0 in data cache.
+	 */
+	mfspr	r3, 1011
+	lis	r2, 0xffff
+	ori	r2, r2, 0xff1f
+	and	r3, r3, r2
+	ori	r3, r3, 0x0080
+	sync
+	mtspr	1011, r3
+#endif /* !CONFIG_BMW */
+	/*
+	 * Thisk the stack pointer *somewhere* sensible. Doesnt
+	 * matter much where as we'll move it when we relocate
+	 */
+	lis	r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
+	ori	r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
+
+	li	r0, 0			/* Make room for stack frame header and	*/
+	stwu	r0, -4(r1)		/* clear final stack frame so that	*/
+	stwu	r0, -4(r1)		/* stack backtraces terminate cleanly	*/
+
+	/* let the C-code set up the rest					*/
+	/*									*/
+	/* Be careful to keep code relocatable !				*/
+	/*----------------------------------------------------------------------*/
+
+	GET_GOT			/* initialize GOT access			*/
+
+	/* r3: IMMR */
+	bl	cpu_init_f	/* run low-level CPU init code     (from Flash)	*/
+
+	mr	r3, r21
+	/* r3: BOOTFLAG */
+	bl	board_init_f	/* run 1st part of board init code (from Flash) */
+
+
+	.globl	_start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+	STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
+
+/* Data Storage exception.  "Never" generated on the 860. */
+	STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
+
+/* Instruction Storage exception.  "Never" generated on the 860. */
+	STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+	STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+	. = EXC_OFF_ALIGN
+Alignment:
+	EXCEPTION_PROLOG(SRR0, SRR1)
+	mfspr	r4,DAR
+	stw	r4,_DAR(r21)
+	mfspr	r5,DSISR
+	stw	r5,_DSISR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
+
+/* Program check exception */
+	. = EXC_OFF_PROGRAM
+ProgramCheck:
+	EXCEPTION_PROLOG(SRR0, SRR1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
+		MSR_KERNEL, COPY_EE)
+
+	/* No FPU on MPC8xx. This exception is not supposed to happen.
+	*/
+	STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
+
+	/* I guess we could implement decrementer, and may have
+	 * to someday for timekeeping.
+	 */
+	STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
+	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+	STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+
+	STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
+
+	STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
+	STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
+
+	STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
+	STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
+	STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
+	STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, DebugException)
+	STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, 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, ReservedC, UnknownException)
+	STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
+	STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
+	STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
+
+	STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
+
+	.globl	_end_of_vectors
+_end_of_vectors:
+
+
+	. = 0x3000
+
+/*
+ * 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)
+#if 0
+	andi.	r23,r23,MSR_PR
+	mfspr	r23,SPRG3		/* if from user, fix up tss.regs */
+	beq	2f
+	addi	r24,r1,STACK_FRAME_OVERHEAD
+	stw	r24,PT_REGS(r23)
+2:	addi	r2,r23,-TSS		/* set r2 to current */
+	tovirt(r2,r2,r23)
+#endif
+	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 */
+#if 0
+	addi	r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
+	cmplw	0,r1,r2
+	cmplw	1,r1,r24
+	crand	1,1,4
+	bgt	stack_ovf		/* if r2 < r1 < r2+TASK_STRUCT_SIZE */
+#endif
+	lwz	r24,0(r23)		/* virtual address of handler */
+	lwz	r23,4(r23)		/* where to go when done */
+	mtspr	SRR0,r24
+	ori	r20,r20,0x30		/* enable IR, DR */
+	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
+
+/* Cache functions.
+*/
+	.globl	icache_enable
+icache_enable:
+	mfspr	r5,HID0		/* turn on the I cache. */
+	ori	r5,r5,0x8800	/* Instruction cache only! */
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0xF7FF
+	and	r6,r5,r6	/* clear the invalidate bit */
+	sync
+	mtspr	HID0,r5
+	mtspr	HID0,r6
+	isync
+	sync
+	blr
+
+	.globl	icache_disable
+icache_disable:
+	mfspr	r5,HID0
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0x7FFF
+	and	r5,r5,r6
+	sync
+	mtspr	HID0,r5
+	isync
+	sync
+	blr
+
+	.globl	icache_status
+icache_status:
+	mfspr	r3, HID0
+	srwi	r3, r3, 15	/* >>15 & 1=> select bit 16 */
+	andi.	r3, r3, 1
+	blr
+
+	.globl	dcache_enable
+dcache_enable:
+	mfspr	r5,HID0		/* turn on the D cache. */
+	ori	r5,r5,0x4400	/* Data cache only! */
+	mfspr	r4, PVR		/* read PVR */
+	srawi	r3, r4, 16	/* shift off the least 16 bits */
+	cmpi	0, 0, r3, 0xC	/* Check for Max pvr */
+	bne	NotMax
+	ori	r5,r5,0x0040	/* setting the DCFA bit, for Max rev 1 errata */
+NotMax:
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0xFBFF
+	and	r6,r5,r6	/* clear the invalidate bit */
+	sync
+	mtspr	HID0,r5
+	mtspr	HID0,r6
+	isync
+	sync
+	blr
+
+	.globl	dcache_disable
+dcache_disable:
+	mfspr	r5,HID0
+	addis	r6,0,0xFFFF
+	ori	r6,r6,0xBFFF
+	and	r5,r5,r6
+	sync
+	mtspr	HID0,r5
+	isync
+	sync
+	blr
+
+	.globl	dcache_status
+dcache_status:
+	mfspr	r3, HID0
+	srwi	r3, r3, 14	/* >>14 & 1=> select bit 17 */
+	andi.	r3, r3, 1
+	blr
+
+	.globl	dc_read
+dc_read:
+/*TODO : who uses this, what should it do?
+*/
+	blr
+
+
+	.globl get_pvr
+get_pvr:
+	mfspr	r3, PVR
+	blr
+
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+	.globl	relocate_code
+relocate_code:
+
+	mr	r1,  r3		/* Set new stack pointer		*/
+	mr	r9,  r4		/* Save copy of Global Data pointer	*/
+	mr	r10, r5		/* Save copy of Destination Address	*/
+
+	GET_GOT
+	mr	r3,  r5				/* Destination Address	*/
+#ifdef CONFIG_SYS_RAMBOOT
+	lis	r4, CONFIG_SYS_SDRAM_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CONFIG_SYS_SDRAM_BASE@l
+#else
+	lis	r4, CONFIG_SYS_MONITOR_BASE@h		/* Source      Address	*/
+	ori	r4, r4, CONFIG_SYS_MONITOR_BASE@l
+#endif
+	lwz	r5, GOT(__init_end)
+	sub	r5, r5, r4
+	li	r6, CONFIG_SYS_CACHELINE_SIZE		/* Cache Line Size	*/
+
+	/*
+	 * Fix GOT pointer:
+	 *
+	 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
+	 *
+	 * Offset:
+	 */
+	sub	r15, r10, r4
+
+	/* First our own GOT */
+	add	r12, r12, 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
+
+4:
+#if !defined(CONFIG_BMW)
+/* Unlock the data cache and invalidate locked area */
+	xor	r0, r0, r0
+	mtspr	1011, r0
+	lis	r4, CONFIG_SYS_INIT_RAM_ADDR@h
+	ori	r4, r4, CONFIG_SYS_INIT_RAM_ADDR@l
+	li	r0, 128
+	mtctr	r0
+41:
+	dcbi	r0, r4
+	addi	r4, r4, 32
+	bdnz	41b
+#endif
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+	cmpwi	r6,0
+	add	r5,r3,r5
+	beq	7f		/* Always flush prefetch queue in any case */
+	subi	r0,r6,1
+	andc	r3,r3,r0
+	mr	r4,r3
+5:	dcbst	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	5b
+	sync			/* Wait for all dcbst to complete on bus */
+	mr	r4,r3
+6:	icbi	0,r4
+	add	r4,r4,r6
+	cmplw	r4,r5
+	blt	6b
+7:	sync			/* Wait for all icbi to complete on bus	*/
+	isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+
+	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+	mtlr	r0
+	blr
+
+in_ram:
+
+	/*
+	 * Relocation Function, r12 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)
+	cmpwi	r0,0
+	beq-	2f
+	add	r0,r0,r11
+	stw	r0,0(r3)
+2:	bdnz	1b
+
+	/*
+	 * Now adjust the fixups and the pointers to the fixups
+	 * in case we need to move ourselves again.
+	 */
+	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
+	blt	5b
+6:
+
+	mr	r3, r9		/* Global 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:
+	mflr	r4			/* save link register		*/
+	GET_GOT
+	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 */
+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
+
+	/* Setup the BAT registers.
+	 */
+setup_bats:
+	lis	r4, CONFIG_SYS_IBAT0L@h
+	ori	r4, r4, CONFIG_SYS_IBAT0L@l
+	lis	r3, CONFIG_SYS_IBAT0U@h
+	ori	r3, r3, CONFIG_SYS_IBAT0U@l
+	mtspr	IBAT0L, r4
+	mtspr	IBAT0U, r3
+	isync
+
+	lis	r4, CONFIG_SYS_DBAT0L@h
+	ori	r4, r4, CONFIG_SYS_DBAT0L@l
+	lis	r3, CONFIG_SYS_DBAT0U@h
+	ori	r3, r3, CONFIG_SYS_DBAT0U@l
+	mtspr	DBAT0L, r4
+	mtspr	DBAT0U, r3
+	isync
+
+	lis	r4, CONFIG_SYS_IBAT1L@h
+	ori	r4, r4, CONFIG_SYS_IBAT1L@l
+	lis	r3, CONFIG_SYS_IBAT1U@h
+	ori	r3, r3, CONFIG_SYS_IBAT1U@l
+	mtspr	IBAT1L, r4
+	mtspr	IBAT1U, r3
+	isync
+
+	lis	r4, CONFIG_SYS_DBAT1L@h
+	ori	r4, r4, CONFIG_SYS_DBAT1L@l
+	lis	r3, CONFIG_SYS_DBAT1U@h
+	ori	r3, r3, CONFIG_SYS_DBAT1U@l
+	mtspr	DBAT1L, r4
+	mtspr	DBAT1U, r3
+	isync
+
+	lis	r4, CONFIG_SYS_IBAT2L@h
+	ori	r4, r4, CONFIG_SYS_IBAT2L@l
+	lis	r3, CONFIG_SYS_IBAT2U@h
+	ori	r3, r3, CONFIG_SYS_IBAT2U@l
+	mtspr	IBAT2L, r4
+	mtspr	IBAT2U, r3
+	isync
+
+	lis	r4, CONFIG_SYS_DBAT2L@h
+	ori	r4, r4, CONFIG_SYS_DBAT2L@l
+	lis	r3, CONFIG_SYS_DBAT2U@h
+	ori	r3, r3, CONFIG_SYS_DBAT2U@l
+	mtspr	DBAT2L, r4
+	mtspr	DBAT2U, r3
+	isync
+
+	lis	r4, CONFIG_SYS_IBAT3L@h
+	ori	r4, r4, CONFIG_SYS_IBAT3L@l
+	lis	r3, CONFIG_SYS_IBAT3U@h
+	ori	r3, r3, CONFIG_SYS_IBAT3U@l
+	mtspr	IBAT3L, r4
+	mtspr	IBAT3U, r3
+	isync
+
+	lis	r4, CONFIG_SYS_DBAT3L@h
+	ori	r4, r4, CONFIG_SYS_DBAT3L@l
+	lis	r3, CONFIG_SYS_DBAT3U@h
+	ori	r3, r3, CONFIG_SYS_DBAT3U@l
+	mtspr	DBAT3L, r4
+	mtspr	DBAT3U, r3
+	isync
+
+	/* Invalidate TLBs.
+	 * -> for (val = 0; val < 0x20000; val+=0x1000)
+	 * ->   tlbie(val);
+	 */
+	lis	r3, 0
+	lis	r5, 2
+
+1:
+	tlbie	r3
+	addi	r3, r3, 0x1000
+	cmp	0, 0, r3, r5
+	blt	1b
+
+	blr
diff --git a/arch/powerpc/cpu/mpc824x/traps.c b/arch/powerpc/cpu/mpc824x/traps.c
new file mode 100644
index 0000000..163b983
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/traps.c
@@ -0,0 +1,219 @@
+/*
+ * linux/arch/powerpc/kernel/traps.c
+ *
+ * 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 <asm/processor.h>
+
+/* 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	0x00400000
+
+/*
+ * 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
+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;
+	}
+
+	printf("Machine check in kernel mode.\n");
+	printf("Caused by (from msr): ");
+	printf("regs %p ",regs);
+	switch( regs->msr & 0x000F0000) {
+	case (0x80000000>>12):
+		printf("Machine check signal - probably due to mm fault\n"
+			"with mmu off\n");
+		break;
+	case (0x80000000>>13):
+		printf("Transfer error ack signal\n");
+		break;
+	case (0x80000000>>14):
+		printf("Data parity signal\n");
+		break;
+	case (0x80000000>>15):
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Software Emulation Exception");
+}
+
+
+void
+UnknownException(struct pt_regs *regs)
+{
+	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(0, regs);
+}
+
+#if defined(CONFIG_CMD_BEDBUG)
+extern void do_bedbug_breakpoint(struct pt_regs *);
+#endif
+
+void
+DebugException(struct pt_regs *regs)
+{
+
+  printf("Debugger trap at @ %lx\n", regs->nip );
+  show_regs(regs);
+#if defined(CONFIG_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)
+{
+#if 0
+	int	retval;
+
+	__asm__ __volatile__(			\
+		"1:	lwz %0,0(%1)\n"		\
+		"	eieio\n"		\
+		"	li %0,0\n"		\
+		"2:\n"				\
+		".section .fixup,\"ax\"\n"	\
+		"3:	li %0,-1\n"		\
+		"	b 2b\n"			\
+		".section __ex_table,\"a\"\n"	\
+		"	.align 2\n"		\
+		"	.long 1b,3b\n"		\
+		".text"				\
+		: "=r" (retval) : "r"(addr));
+
+	return (retval);
+#endif
+	return 0;
+}
diff --git a/arch/powerpc/cpu/mpc824x/u-boot.lds b/arch/powerpc/cpu/mpc824x/u-boot.lds
new file mode 100644
index 0000000..d1fcd7c
--- /dev/null
+++ b/arch/powerpc/cpu/mpc824x/u-boot.lds
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2001-2007
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text)	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data)	}
+  .rel.rodata    : { *(.rel.rodata)	}
+  .rela.rodata   : { *(.rela.rodata)	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    arch/powerpc/cpu/mpc824x/start.o		(.text)
+    *(.text)
+    *(.got1)
+    . = ALIGN(16);
+    *(.eh_frame)
+    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  . = .;
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  . = .;
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss (NOLOAD)       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   . = ALIGN(4);
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}