Initial revision
diff --git a/cpu/74xx_7xx/traps.c b/cpu/74xx_7xx/traps.c
new file mode 100644
index 0000000..26db097
--- /dev/null
+++ b/cpu/74xx_7xx/traps.c
@@ -0,0 +1,234 @@
+/*
+ * linux/arch/ppc/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 <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+*/
+#define END_OF_MEM	0x02000000
+
+/*
+ * 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;
+	}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	printf("Machine check in kernel mode.\n");
+	printf("Caused by (from msr): ");
+	printf("regs %p ",regs);
+	switch( regs->msr & 0x0000F000)
+	{
+	case (1<<12) :
+		printf("Machine check signal - probably due to mm fault\n"
+			"with mmu off\n");
+		break;
+	case (1<<13) :
+		printf("Transfer error ack signal\n");
+		break;
+	case (1<<14) :
+		printf("Data parity signal\n");
+		break;
+	case (1<<15) :
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Software Emulation Exception");
+}
+
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(0, regs);
+}
+
+/* Probe an address by reading.  If not present, return -1, otherwise
+ * return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+#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/cpu/mpc824x/drivers/epic/epic1.c b/cpu/mpc824x/drivers/epic/epic1.c
new file mode 100644
index 0000000..362e129
--- /dev/null
+++ b/cpu/mpc824x/drivers/epic/epic1.c
@@ -0,0 +1,513 @@
+/**************************************************
+ *
+ * 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);
+    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 */
+}
+
+/****************************************************************************
+ *  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        /* Interrupt Vector Number */
+    )
+    {
+    ULONG tmp;
+    ULONG srAddr;
+
+    srAddr = SrcVecTable[intVec].srcAddr;  /* Retrieve src Vec/Prio register */
+    tmp = sysEUMBBARRead(srAddr);
+    tmp &= 0x7fffffff;             /* Clear the mask bit */
+    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 *) (CFG_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 *) (CFG_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/cpu/mpc824x/traps.c b/cpu/mpc824x/traps.c
new file mode 100644
index 0000000..11f51c2
--- /dev/null
+++ b/cpu/mpc824x/traps.c
@@ -0,0 +1,205 @@
+/*
+ * linux/arch/ppc/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 & 0x0000F000)
+	{
+	case (1<<12) :
+		printf("Machine check signal - probably due to mm fault\n"
+			"with mmu off\n");
+		break;
+	case (1<<13) :
+		printf("Transfer error ack signal\n");
+		break;
+	case (1<<14) :
+		printf("Data parity signal\n");
+		break;
+	case (1<<15) :
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+	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);
+}
+
+/* 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/cpu/mpc8260/ether_fcc.c b/cpu/mpc8260/ether_fcc.c
new file mode 100644
index 0000000..01ddf5c
--- /dev/null
+++ b/cpu/mpc8260/ether_fcc.c
@@ -0,0 +1,347 @@
+/*
+ * MPC8260 FCC Fast Ethernet
+ *
+ * Copyright (c) 2000 MontaVista Software, Inc.   Dan Malek (dmalek@jlc.net)
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * MPC8260 FCC Fast Ethernet
+ * Basic ET HW initialization and packet RX/TX routines
+ *
+ * This code will not perform the IO port configuration. This should be
+ * done in the iop_conf_t structure specific for the board.
+ *
+ * TODO:
+ * add a PHY driver to do the negotiation
+ * reflect negotiation results in FPSMR
+ * look for ways to configure the board specific stuff elsewhere, eg.
+ *    config_xxx.h or the board directory
+ */
+
+#include <common.h>
+#include <asm/cpm_8260.h>
+#include <mpc8260.h>
+#include <net.h>
+#include <command.h>
+#include <config.h>
+
+#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/*---------------------------------------------------------------------*/
+#if (CONFIG_ETHER_INDEX == 1)
+
+#define PROFF_ENET		PROFF_FCC1
+#define CPM_CR_ENET_SBLOCK	CPM_CR_FCC1_SBLOCK
+#define CPM_CR_ENET_SBLOCK	CPM_CR_FCC1_SBLOCK
+#define CPM_CR_ENET_PAGE	CPM_CR_FCC1_PAGE
+
+/*---------------------------------------------------------------------*/
+#elif (CONFIG_ETHER_INDEX == 2)
+
+#define PROFF_ENET		PROFF_FCC2
+#define CPM_CR_ENET_SBLOCK	CPM_CR_FCC2_SBLOCK
+#define CPM_CR_ENET_PAGE	CPM_CR_FCC2_PAGE
+
+/*---------------------------------------------------------------------*/
+#elif (CONFIG_ETHER_INDEX == 3)
+
+#define PROFF_ENET		PROFF_FCC3
+#define CPM_CR_ENET_SBLOCK	CPM_CR_FCC3_SBLOCK
+#define CPM_CR_ENET_PAGE	CPM_CR_FCC3_PAGE
+
+/*---------------------------------------------------------------------*/
+#else
+#error "FCC Ethernet not correctly defined"
+#endif
+/*---------------------------------------------------------------------*/
+
+/* Maximum input DMA size.  Must be a should(?) be a multiple of 4. */
+#define PKT_MAXDMA_SIZE         1520
+
+/* The FCC stores dest/src/type, data, and checksum for receive packets. */
+#define PKT_MAXBUF_SIZE         1518
+#define PKT_MINBUF_SIZE         64
+
+/* Maximum input buffer size.  Must be a multiple of 32. */
+#define PKT_MAXBLR_SIZE         1536
+
+#define TOUT_LOOP 1000000
+
+#define TX_BUF_CNT 2
+#ifdef __GNUC__
+static char txbuf[TX_BUF_CNT][PKT_MAXBLR_SIZE] __attribute__ ((aligned(8)));
+#else
+#error "txbuf must be 64-bit aligned"
+#endif
+
+static uint rxIdx;	/* index of the current RX buffer */
+static uint txIdx;	/* index of the current TX buffer */
+
+/*
+ * FCC Ethernet Tx and Rx buffer descriptors.
+ * Provide for Double Buffering
+ * Note: PKTBUFSRX is defined in net.h
+ */
+
+typedef volatile struct rtxbd {
+    cbd_t rxbd[PKTBUFSRX];
+    cbd_t txbd[TX_BUF_CNT];
+} RTXBD;
+
+/*  Good news: the FCC supports external BDs! */
+#ifdef __GNUC__
+static RTXBD rtx __attribute__ ((aligned(8)));
+#else
+#error "rtx must be 64-bit aligned"
+#endif
+
+int eth_send(volatile void *packet, int length)
+{
+    int i;
+    int result = 0;
+
+    if (length <= 0) {
+	printf("fec: bad packet size: %d\n", length);
+	goto out;
+    }
+
+    for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
+	if (i >= TOUT_LOOP) {
+	    printf("fec: tx buffer not ready\n");
+	    goto out;
+	}
+    }
+
+    rtx.txbd[txIdx].cbd_bufaddr = (uint)packet;
+    rtx.txbd[txIdx].cbd_datlen = length;
+    rtx.txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST |
+			       BD_ENET_TX_WRAP);
+
+    for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
+	if (i >= TOUT_LOOP) {
+	    printf("fec: tx error\n");
+	    goto out;
+	}
+    }
+
+#ifdef ET_DEBUG
+    printf("cycles: %d status: %04x\n", i, rtx.txbd[txIdx].cbd_sc);
+#endif
+
+    /* return only status bits */
+    result = rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_STATS;
+
+out:
+    return result;
+}
+
+int eth_rx(void)
+{
+    int length;
+
+    for (;;)
+    {
+	if (rtx.rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+	    length = -1;
+	    break;     /* nothing received - leave for() loop */
+	}
+	length = rtx.rxbd[rxIdx].cbd_datlen;
+
+	if (rtx.rxbd[rxIdx].cbd_sc & 0x003f) {
+	    printf("fec: rx error %04x\n", rtx.rxbd[rxIdx].cbd_sc);
+	}
+	else {
+	    /* Pass the packet up to the protocol layers. */
+	    NetReceive(NetRxPackets[rxIdx], length - 4);
+	}
+
+
+	/* Give the buffer back to the FCC. */
+	rtx.rxbd[rxIdx].cbd_datlen = 0;
+
+	/* wrap around buffer index when necessary */
+	if ((rxIdx + 1) >= PKTBUFSRX) {
+	    rtx.rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+	    rxIdx = 0;
+	}
+	else {
+	    rtx.rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+	    rxIdx++;
+	}
+    }
+    return length;
+}
+
+
+int eth_init(bd_t *bis)
+{
+    int i;
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+    volatile cpm8260_t *cp = &(immr->im_cpm);
+    fcc_enet_t *pram_ptr;
+    unsigned long mem_addr;
+
+#if 0
+    mii_discover_phy();
+#endif
+
+    /* 28.9 - (1-2): ioports have been set up already */
+
+    /* 28.9 - (3): connect FCC's tx and rx clocks */
+    immr->im_cpmux.cmx_uar = 0;
+    immr->im_cpmux.cmx_fcr = (immr->im_cpmux.cmx_fcr & ~CFG_CMXFCR_MASK) |
+    							CFG_CMXFCR_VALUE;
+
+    /* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */
+    immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_gfmr =
+      FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
+
+    /* 28.9 - (5): FPSMR: enable full duplex, select CCITT CRC for Ethernet */
+    immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
+
+    /* 28.9 - (6): FDSR: Ethernet Syn */
+    immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fdsr = 0xD555;
+
+    /* reset indeces to current rx/tx bd (see eth_send()/eth_rx()) */
+    rxIdx = 0;
+    txIdx = 0;
+
+    /* Setup Receiver Buffer Descriptors */
+    for (i = 0; i < PKTBUFSRX; i++)
+    {
+      rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+      rtx.rxbd[i].cbd_datlen = 0;
+      rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
+    }
+    rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+    /* Setup Ethernet Transmitter Buffer Descriptors */
+    for (i = 0; i < TX_BUF_CNT; i++)
+    {
+      rtx.txbd[i].cbd_sc = (BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+      rtx.txbd[i].cbd_datlen = 0;
+      rtx.txbd[i].cbd_bufaddr = (uint)&txbuf[i][0];
+    }
+    rtx.txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+    /* 28.9 - (7): initialise parameter ram */
+    pram_ptr = (fcc_enet_t *)&(immr->im_dprambase[PROFF_ENET]);
+
+    /* clear whole structure to make sure all reserved fields are zero */
+    memset((void*)pram_ptr, 0, sizeof(fcc_enet_t));
+
+    /*
+     * common Parameter RAM area
+     *
+     * Allocate space in the reserved FCC area of DPRAM for the
+     * internal buffers.  No one uses this space (yet), so we
+     * can do this.  Later, we will add resource management for
+     * this area.
+     */
+    mem_addr = CPM_FCC_SPECIAL_BASE + ((CONFIG_ETHER_INDEX-1) * 64);
+    pram_ptr->fen_genfcc.fcc_riptr = mem_addr;
+    pram_ptr->fen_genfcc.fcc_tiptr = mem_addr+32;
+    /*
+     * Set maximum bytes per receive buffer.
+     * It must be a multiple of 32.
+     */
+    pram_ptr->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE;
+    pram_ptr->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB |
+				       CFG_CPMFCR_RAMTYPE) << 24;
+    pram_ptr->fen_genfcc.fcc_rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
+    pram_ptr->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB |
+				       CFG_CPMFCR_RAMTYPE) << 24;
+    pram_ptr->fen_genfcc.fcc_tbase = (unsigned int)(&rtx.txbd[txIdx]);
+
+    /* protocol-specific area */
+    pram_ptr->fen_cmask = 0xdebb20e3;	/* CRC mask */
+    pram_ptr->fen_cpres = 0xffffffff;	/* CRC preset */
+    pram_ptr->fen_retlim = 15;		/* Retry limit threshold */
+    pram_ptr->fen_mflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
+    /*
+     * Set Ethernet station address.
+     *
+     * This is supplied in the board information structure, so we
+     * copy that into the controller.
+     * So, far we have only been given one Ethernet address. We make
+     * it unique by setting a few bits in the upper byte of the
+     * non-static part of the address.
+     */
+#define ea bis->bi_enetaddr
+    pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
+    pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
+    pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
+#undef ea
+    pram_ptr->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */
+    /* pad pointer. use tiptr since we don't need a specific padding char */
+    pram_ptr->fen_padptr = pram_ptr->fen_genfcc.fcc_tiptr;
+    pram_ptr->fen_maxd1 = PKT_MAXDMA_SIZE;	/* maximum DMA1 length */
+    pram_ptr->fen_maxd2 = PKT_MAXDMA_SIZE;	/* maximum DMA2 length */
+    pram_ptr->fen_rfthr = 1;
+    pram_ptr->fen_rfcnt = 1;
+#if 0
+    printf("pram_ptr->fen_genfcc.fcc_rbase %08lx\n",
+	pram_ptr->fen_genfcc.fcc_rbase);
+    printf("pram_ptr->fen_genfcc.fcc_tbase %08lx\n",
+	pram_ptr->fen_genfcc.fcc_tbase);
+#endif
+
+    /* 28.9 - (8): clear out events in FCCE */
+    immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fcce = ~0x0;
+
+    /* 28.9 - (9): FCCM: mask all events */
+    immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_fccm = 0;
+
+    /* 28.9 - (10-12): we don't use ethernet interrupts */
+
+    /* 28.9 - (13)
+     *
+     * Let's re-initialize the channel now.  We have to do it later
+     * than the manual describes because we have just now finished
+     * the BD initialization.
+     */
+    cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET_PAGE,
+			    CPM_CR_ENET_SBLOCK,
+			    0x0c,
+			    CPM_CR_INIT_TRX) | CPM_CR_FLG;
+    do {
+	__asm__ __volatile__ ("eieio");
+    } while (cp->cp_cpcr & CPM_CR_FLG);
+
+    /* 28.9 - (14): enable tx/rx in gfmr */
+    immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
+
+    return 1;
+}
+
+void eth_halt(void)
+{
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+    /* write GFMR: disable tx/rx */
+    immr->im_fcc[CONFIG_ETHER_INDEX-1].fcc_gfmr &=
+						~(FCC_GFMR_ENT | FCC_GFMR_ENR);
+}
+
+#endif	/* CONFIG_ETHER_ON_FCC && CFG_CMD_NET */
diff --git a/cpu/mpc8260/traps.c b/cpu/mpc8260/traps.c
new file mode 100644
index 0000000..a7f6f7e
--- /dev/null
+++ b/cpu/mpc8260/traps.c
@@ -0,0 +1,246 @@
+/*
+ * linux/arch/ppc/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 <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+*/
+#define END_OF_MEM	0x02000000
+
+/*
+ * 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;
+	}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	printf("Machine check in kernel mode.\n");
+	printf("Caused by (from msr): ");
+	printf("regs %p ",regs);
+	switch( regs->msr & 0x0000F000)
+	{
+	case (1<<12) :
+		printf("Machine check signal - probably due to mm fault\n"
+			"with mmu off\n");
+		break;
+	case (1<<13) :
+		printf("Transfer error ack signal\n");
+		break;
+	case (1<<14) :
+		printf("Data parity signal\n");
+		break;
+	case (1<<15) :
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Software Emulation Exception");
+}
+
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(0, regs);
+}
+
+#if (CONFIG_COMMANDS & CFG_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 (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+  do_bedbug_breakpoint( regs );
+#endif
+}
+
+/* Probe an address by reading.  If not present, return -1, otherwise
+ * return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+#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/cpu/mpc8xx/traps.c b/cpu/mpc8xx/traps.c
new file mode 100644
index 0000000..c432be6
--- /dev/null
+++ b/cpu/mpc8xx/traps.c
@@ -0,0 +1,245 @@
+/*
+ * linux/arch/ppc/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 <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+extern void do_bedbug_breakpoint(struct pt_regs *);
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+*/
+#define END_OF_MEM	0x02000000
+
+/*
+ * 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;
+	}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	printf("Machine check in kernel mode.\n");
+	printf("Caused by (from msr): ");
+	printf("regs %p ",regs);
+	switch( regs->msr & 0x0000F000)
+	{
+	case (1<<12) :
+		printf("Machine check signal - probably due to mm fault\n"
+			"with mmu off\n");
+		break;
+	case (1<<13) :
+		printf("Transfer error ack signal\n");
+		break;
+	case (1<<14) :
+		printf("Data parity signal\n");
+		break;
+	case (1<<15) :
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Software Emulation Exception");
+}
+
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(0, regs);
+}
+
+void
+DebugException(struct pt_regs *regs)
+{
+  printf("Debugger trap at @ %lx\n", regs->nip );
+  show_regs(regs);
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+  do_bedbug_breakpoint( regs );
+#endif
+}
+
+/* Probe an address by reading.  If not present, return -1, otherwise
+ * return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+#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/cpu/mpc8xx/upatch.c b/cpu/mpc8xx/upatch.c
new file mode 100644
index 0000000..99bdf53
--- /dev/null
+++ b/cpu/mpc8xx/upatch.c
@@ -0,0 +1,102 @@
+#include <common.h>
+#include <commproc.h>
+
+#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH)
+
+static void UcodeCopy (volatile cpm8xx_t *cpm);
+
+void cpm_load_patch (volatile immap_t *immr)
+{
+	immr->im_cpm.cp_rccr &= ~0x0003;	/* Disable microcode program area */
+
+	UcodeCopy ((cpm8xx_t *)&immr->im_cpm);	/* Copy ucode patch to DPRAM   */
+#ifdef CFG_SPI_UCODE_PATCH
+    {
+	volatile spi_t *spi = (spi_t *) & immr->im_cpm.cp_dparam[PROFF_SPI];
+	/* Activate the microcode per the instructions in the microcode manual */
+	/* NOTE:  We're only relocating the SPI parameters (not I2C).          */
+	immr->im_cpm.cp_cpmcr1 = 0x802a;	/* Write Trap register 1 value */
+	immr->im_cpm.cp_cpmcr2 = 0x8028;	/* Write Trap register 2 value */
+	spi->spi_rpbase = CFG_SPI_DPMEM_OFFSET;	/* Where to relocte SPI params */
+    }
+#endif
+
+#ifdef CFG_I2C_UCODE_PATCH
+    {
+	volatile iic_t *iip = (iic_t *) & immr->im_cpm.cp_dparam[PROFF_IIC];
+	/* Activate the microcode per the instructions in the microcode manual */
+	/* NOTE:  We're only relocating the I2C parameters (not SPI).          */
+	immr->im_cpm.cp_cpmcr3 = 0x802e;	/* Write Trap register 3 value */
+	immr->im_cpm.cp_cpmcr4 = 0x802c;	/* Write Trap register 4 value */
+	iip->iic_rpbase = CFG_I2C_DPMEM_OFFSET;	/* Where to relocte I2C params */
+    }
+#endif
+
+	/*
+         * Enable DPRAM microcode to execute from the first 512 bytes
+         * and a 256 byte extension of DPRAM.
+	 */
+	immr->im_cpm.cp_rccr |= 0x0001;
+}
+
+static ulong patch_2000[] = {
+	0x7FFFEFD9, 0x3FFD0000, 0x7FFB49F7, 0x7FF90000,
+	0x5FEFADF7, 0x5F88ADF7, 0x5FEFAFF7, 0x5F88AFF7,
+	0x3A9CFBC8, 0x77CAE1BB, 0xF4DE7FAD, 0xABAE9330,
+	0x4E08FDCF, 0x6E0FAFF8, 0x7CCF76CF, 0xFDAFF9CF,
+	0xABF88DC8, 0xAB5879F7, 0xB0927383, 0xDFD079F7,
+	0xB090E6BB, 0xE5BBE74F, 0xB3FA6F0F, 0x6FFB76CE,
+	0xEE0CF9CF, 0x2BFBEFEF, 0xCFEEF9CF, 0x76CEAD23,
+	0x90B3DF99, 0x7FDDD0C1, 0x4BF847FD, 0x7CCF76CE,
+	0xCFEF77CA, 0x7EAF7FAD, 0x7DFDF0B7, 0xEF7A7FCA,
+	0x77CAFBC8, 0x6079E722, 0xFBC85FFF, 0xDFFF5FB3,
+	0xFFFBFBC8, 0xF3C894A5, 0xE7C9EDF9, 0x7F9A7FAD,
+	0x5F36AFE8, 0x5F5BFFDF, 0xDF95CB9E, 0xAF7D5FC3,
+	0xAFED8C1B, 0x5FC3AFDD, 0x5FC5DF99, 0x7EFDB0B3,
+	0x5FB3FFFE, 0xABAE5FB3, 0xFFFE5FD0, 0x600BE6BB,
+	0x600B5FD0, 0xDFC827FB, 0xEFDF5FCA, 0xCFDE3A9C,
+	0xE7C9EDF9, 0xF3C87F9E, 0x54CA7FED, 0x2D3A3637,
+	0x756F7E9A, 0xF1CE37EF, 0x2E677FEE, 0x10EBADF8,
+	0xEFDECFEA, 0xE52F7D9F, 0xE12BF1CE, 0x5F647E9A,
+	0x4DF8CFEA, 0x5F717D9B, 0xEFEECFEA, 0x5F73E522,
+	0xEFDE5F73, 0xCFDA0B61, 0x7385DF61, 0xE7C9EDF9,
+	0x7E9A30D5, 0x1458BFFF, 0xF3C85FFF, 0xDFFFA7F8,
+	0x5F5BBFFE, 0x7F7D10D0, 0x144D5F33, 0xBFFFAF78,
+	0x5F5BBFFD, 0xA7F85F33, 0xBFFE77FD, 0x30BD4E08,
+	0xFDCFE5FF, 0x6E0FAFF8, 0x7EEF7E9F, 0xFDEFF1CF,
+	0x5F17ABF8, 0x0D5B5F5B, 0xFFEF79F7, 0x309EAFDD,
+	0x5F3147F8, 0x5F31AFED, 0x7FDD50AF, 0x497847FD,
+	0x7F9E7FED, 0x7DFD70A9, 0xEF7E7ECE, 0x6BA07F9E,
+	0x2D227EFD, 0x30DB5F5B, 0xFFFD5F5B, 0xFFEF5F5B,
+	0xFFDF0C9C, 0xAFED0A9A, 0xAFDD0C37, 0x5F37AFBD,
+	0x7FBDB081, 0x5F8147F8,
+};
+
+static ulong patch_2F00[] = {
+	0x3E303430, 0x34343737, 0xABBF9B99, 0x4B4FBDBD,
+	0x59949334, 0x9FFF37FB, 0x9B177DD9, 0x936956BB,
+	0xFBDD697B, 0xDD2FD113, 0x1DB9F7BB, 0x36313963,
+	0x79373369, 0x3193137F, 0x7331737A, 0xF7BB9B99,
+	0x9BB19795, 0x77FDFD3D, 0x573B773F, 0x737933F7,
+	0xB991D115, 0x31699315, 0x31531694, 0xBF4FBDBD,
+	0x35931497, 0x35376956, 0xBD697B9D, 0x96931313,
+	0x19797937, 0x69350000,
+};
+
+static void UcodeCopy (volatile cpm8xx_t *cpm)
+{
+	vu_long *p;
+	int i;
+
+	p = (vu_long *)&(cpm->cp_dpmem[0x0000]);
+	for (i=0; i < sizeof(patch_2000)/4; ++i) {
+		p[i] = patch_2000[i];
+	}
+
+	p = (vu_long *)&(cpm->cp_dpmem[0x0F00]);
+	for (i=0; i < sizeof(patch_2F00)/4; ++i) {
+		p[i] = patch_2F00[i];
+	}
+}
+
+#endif	/* CFG_I2C_UCODE_PATCH, CFG_SPI_UCODE_PATCH */
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
new file mode 100644
index 0000000..51ba471
--- /dev/null
+++ b/cpu/ppc4xx/miiphy.c
@@ -0,0 +1,182 @@
+/*-----------------------------------------------------------------------------+
+  |
+  |       This source code has been made available to you by IBM on an AS-IS
+  |       basis.  Anyone receiving this source is licensed under IBM
+  |       copyrights to use it in any way he or she deems fit, including
+  |       copying it, modifying it, compiling it, and redistributing it either
+  |       with or without modifications.  No license under IBM patents or
+  |       patent applications is to be implied by the copyright license.
+  |
+  |       Any user of this software should understand that IBM cannot provide
+  |       technical support for this software and will not be responsible for
+  |       any consequences resulting from the use of this software.
+  |
+  |       Any person who transfers this source code or any derivative work
+  |       must include the IBM copyright notice, this paragraph, and the
+  |       preceding two paragraphs in the transferred software.
+  |
+  |       COPYRIGHT   I B M   CORPORATION 1995
+  |       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+  +-----------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------+
+  |
+  |  File Name:  miiphy.c
+  |
+  |  Function:   This module has utilities for accessing the MII PHY through
+  |	       the EMAC3 macro.
+  |
+  |  Author:     Mark Wisner
+  |
+  |  Change Activity-
+  |
+  |  Date        Description of Change                                       BY
+  |  ---------   ---------------------                                       ---
+  |  05-May-99   Created                                                     MKW
+  |  01-Jul-99   Changed clock setting of sta_reg from 66Mhz to 50Mhz to
+  |              better match OPB speed. Also modified delay times.      	   JWB
+  |  29-Jul-99   Added Full duplex support                                   MKW
+  |  24-Aug-99   Removed printf from dp83843_duplex()                      JWB
+  |  19-Jul-00   Ported to esd cpci405                                       sr
+  |
+  +-----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <asm/processor.h>
+#include <ppc_asm.tmpl>
+#include <commproc.h>
+#include <405gp_enet.h>
+#include <405_mal.h>
+#include <miiphy.h>
+
+#if defined(CONFIG_405GP) || defined(CONFIG_440)
+
+
+/***********************************************************/
+/* Dump out to the screen PHY regs                         */
+/***********************************************************/
+
+void miiphy_dump (unsigned char addr)
+{
+	unsigned long i;
+	unsigned short data;
+
+
+	for (i = 0; i < 0x1A; i++) {
+		if (miiphy_read (addr, i, &data)) {
+			printf ("read error for reg %lx\n", i);
+			return;
+		}
+		printf ("Phy reg %lx ==> %4x\n", i, data);
+
+		/* jump to the next set of regs */
+		if (i == 0x07)
+			i = 0x0f;
+
+	} /* end for loop */
+} /* end dump */
+
+
+
+/***********************************************************/
+/* read a phy reg and return the value with a rc           */
+/***********************************************************/
+
+int miiphy_read (unsigned char addr, unsigned char reg,
+				 unsigned short *value)
+{
+	unsigned long sta_reg;		/* STA scratch area */
+	unsigned long i;
+
+	/* see if it is ready for 1000 nsec */
+	i = 0;
+
+	/* see if it is ready for  sec */
+	while ((in32 (EMAC_STACR) & EMAC_STACR_OC) == 0) {
+		udelay (7);
+		if (i > 5) {
+			printf ("read err 1\n");
+			return -1;
+		}
+		i++;
+	}
+	sta_reg = reg;				/* reg address */
+	/* set clock (50Mhz) and read flags */
+	sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
+	sta_reg = sta_reg | (addr << 5);	/* Phy address */
+
+	out32 (EMAC_STACR, sta_reg);
+#if 0	/* test-only */
+	printf ("a2: write: EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
+#endif
+
+	sta_reg = in32 (EMAC_STACR);
+	i = 0;
+	while ((sta_reg & EMAC_STACR_OC) == 0) {
+		udelay (7);
+		if (i > 5) {
+			printf ("read err 2\n");
+			return -1;
+		}
+		i++;
+		sta_reg = in32 (EMAC_STACR);
+	}
+	if ((sta_reg & EMAC_STACR_PHYE) != 0) {
+		printf ("read err 3\n");
+		printf ("a2: read: EMAC_STACR=0x%0lx, i=%d\n",
+			sta_reg, (int) i);	/* test-only */
+		return -1;
+	}
+
+	*value = *(short *) (&sta_reg);
+	return 0;
+
+
+} /* phy_read */
+
+
+/***********************************************************/
+/* write a phy reg and return the value with a rc           */
+/***********************************************************/
+
+int miiphy_write (unsigned char addr, unsigned char reg,
+		  unsigned short value)
+{
+	unsigned long sta_reg;		/* STA scratch area */
+	unsigned long i;
+
+	/* see if it is ready for 1000 nsec */
+	i = 0;
+
+	while ((in32 (EMAC_STACR) & EMAC_STACR_OC) == 0) {
+		if (i > 5)
+			return -1;
+		udelay (7);
+		i++;
+	}
+	sta_reg = 0;
+	sta_reg = reg;				/* reg address */
+	/* set clock (50Mhz) and read flags */
+	sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
+	sta_reg = sta_reg | ((unsigned long) addr << 5);	/* Phy address */
+	memcpy (&sta_reg, &value, 2);	/* put in data */
+
+	out32 (EMAC_STACR, sta_reg);
+
+	/* wait for completion */
+	i = 0;
+	sta_reg = in32 (EMAC_STACR);
+	while ((sta_reg & EMAC_STACR_OC) == 0) {
+		udelay (7);
+		if (i > 5)
+			return -1;
+		i++;
+		sta_reg = in32 (EMAC_STACR);
+	}
+
+	if ((sta_reg & EMAC_STACR_PHYE) != 0)
+		return -1;
+	return 0;
+
+} /* phy_read */
+
+#endif	/* CONFIG_405GP */
diff --git a/cpu/ppc4xx/traps.c b/cpu/ppc4xx/traps.c
new file mode 100644
index 0000000..85f2ea4
--- /dev/null
+++ b/cpu/ppc4xx/traps.c
@@ -0,0 +1,291 @@
+/*
+ * linux/arch/ppc/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 <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+ */
+#define END_OF_MEM	0x00400000
+
+
+static __inline__ void set_tsr(unsigned long val)
+{
+#if defined(CONFIG_440)
+	asm volatile("mtspr 0x150, %0" : : "r" (val));
+#else
+	asm volatile("mttsr %0" : : "r" (val));
+#endif
+}
+
+static __inline__ unsigned long get_esr(void)
+{
+	unsigned long val;
+
+#if defined(CONFIG_440)
+	asm volatile("mfspr %0, 0x03e" : "=r" (val) :);
+#else
+	asm volatile("mfesr %0" : "=r" (val) :);
+#endif
+	return val;
+}
+
+#define ESR_MCI 0x80000000
+#define ESR_PIL 0x08000000
+#define ESR_PPR 0x04000000
+#define ESR_PTR 0x02000000
+#define ESR_DST 0x00800000
+#define ESR_DIZ 0x00400000
+#define ESR_U0F 0x00008000
+
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+extern void do_bedbug_breakpoint(struct pt_regs *);
+#endif
+
+/*
+ * Trap & Exception support
+ */
+
+void
+print_backtrace(unsigned long *sp)
+{
+	int cnt = 0;
+	unsigned long i;
+
+	printf("Call backtrace: ");
+	while (sp) {
+		if ((uint)sp > END_OF_MEM)
+			break;
+
+		i = sp[1];
+		if (cnt++ % 7 == 0)
+			printf("\n");
+		printf("%08lX ", i);
+		if (cnt > 32) break;
+		sp = (unsigned long *)*sp;
+	}
+	printf("\n");
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	int i;
+
+	printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
+	       regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
+	printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
+	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
+	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
+	       regs->msr&MSR_IR ? 1 : 0,
+	       regs->msr&MSR_DR ? 1 : 0);
+
+	printf("\n");
+	for (i = 0;  i < 32;  i++) {
+		if ((i % 8) == 0)
+		{
+			printf("GPR%02d: ", i);
+		}
+
+		printf("%08lX ", regs->gpr[i]);
+		if ((i % 8) == 7)
+		{
+			printf("\n");
+		}
+	}
+}
+
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
+}
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+	unsigned long fixup;
+
+	/* Probing PCI using config cycles cause this exception
+	 * when a device is not present.  Catch it and return to
+	 * the PCI exception handler.
+	 */
+	if ((fixup = search_exception_table(regs->nip)) != 0) {
+		regs->nip = fixup;
+		return;
+	}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	printf("Machine check in kernel mode.\n");
+	printf("Caused by (from msr): ");
+	printf("regs %p ",regs);
+	switch( regs->msr & 0x0000F000)
+	{
+	case (1<<12) :
+		printf("Machine check signal - probably due to mm fault\n"
+		       "with mmu off\n");
+		break;
+	case (1<<13) :
+		printf("Transfer error ack signal\n");
+		break;
+	case (1<<14) :
+		printf("Data parity signal\n");
+		break;
+	case (1<<15) :
+		printf("Address parity signal\n");
+		break;
+	default:
+		printf("Unknown values in msr\n");
+	}
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+        long esr_val;
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	show_regs(regs);
+
+        esr_val = get_esr();
+        if( esr_val & ESR_PIL )
+		printf( "** Illegal Instruction **\n" );
+        else if( esr_val & ESR_PPR )
+		printf( "** Privileged Instruction **\n" );
+        else if( esr_val & ESR_PTR )
+		printf( "** Trap Instruction **\n" );
+
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("Program Check Exception");
+}
+
+void
+PITException(struct pt_regs *regs)
+{
+        /*
+         * Reset PIT interrupt
+         */
+        set_tsr(0x08000000);
+
+        /*
+         * Call timer_interrupt routine in interrupts.c
+         */
+        timer_interrupt(NULL);
+}
+
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+		return;
+#endif
+
+	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(0, regs);
+}
+
+void
+DebugException(struct pt_regs *regs)
+{
+	printf("Debugger trap at @ %lx\n", regs->nip );
+	show_regs(regs);
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+	do_bedbug_breakpoint( regs );
+#endif
+}
+
+/* Probe an address by reading.  If not present, return -1, otherwise
+ * return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+#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;
+}