Initial revision
diff --git a/cpu/mpc824x/drivers/epic/README b/cpu/mpc824x/drivers/epic/README
new file mode 100644
index 0000000..ae95b88
--- /dev/null
+++ b/cpu/mpc824x/drivers/epic/README
@@ -0,0 +1,104 @@
+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/cpu/mpc824x/drivers/epic/epic2.S b/cpu/mpc824x/drivers/epic/epic2.S
new file mode 100644
index 0000000..8979f88
--- /dev/null
+++ b/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/cpu/mpc824x/drivers/epic/epicutil.S b/cpu/mpc824x/drivers/epic/epicutil.S
new file mode 100644
index 0000000..a83fbd8
--- /dev/null
+++ b/cpu/mpc824x/drivers/epic/epicutil.S
@@ -0,0 +1,58 @@
+/**************************************
+ *
+ * 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
+