Index: bsps/powerpc/beatnik/irq/discovery_pic.c
===================================================================
--- bsps/powerpc/beatnik/irq/discovery_pic.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/beatnik/irq/discovery_pic.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,993 @@
+/* Interrupt driver + dispatcher for the discovery host controller */
+
+/* Author: T. Straumann, 2005-2007
+ *
+ * Acknowledgements:
+ * Valuable information was obtained from the following drivers
+ *   netbsd: (C) Allegro Networks Inc; Wasabi Systems Inc.
+ *   linux:  (C) MontaVista, Software, Inc; Chris Zankel, Mark A. Greer.
+ *   rtems:  (C) Brookhaven National Laboratory; K. Feng
+ * but this implementation is original work by the author.
+ */
+
+/* 
+ * Authorship
+ * ----------
+ * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
+ *     created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
+ * 	   Stanford Linear Accelerator Center, Stanford University.
+ * 
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * The 'beatnik' BSP was produced by
+ *     the Stanford Linear Accelerator Center, Stanford University,
+ * 	   under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ * 
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ * 
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ * 
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software.  Hence, anyone may
+ * freely use it for any purpose without restriction.  
+ * 
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ * 
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */ 
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/gtreg.h>
+#include <bsp/gtintrreg.h>
+#include <rtems/bspIo.h>
+#include <bsp/vectors.h>
+#include <libcpu/byteorder.h>
+#include <libcpu/spr.h>
+
+/* dont change the order (main_lo, main_hi, gpp) which
+ * matches the interrupt numbers!
+ */
+#define MAIN_LO_IDX	0
+#define MAIN_HI_IDX	1
+#define GPP_IDX		2
+#define NUM_INTR_REGS 3
+
+
+#define SYNC() __asm__ volatile("sync")
+
+/* How many times should the ISR dispatcher check for
+ * pending interrupts until it decides that something's
+ * fishy (i.e., a user ISR fails to clear the interrupt
+ * source)
+ */
+#define MAX_SPIN_LOOPS 100
+
+/* If FASTER is defined, a few obscure I/O statements found in the linux
+ * driver are removed
+ */
+#define	FASTER
+
+/* Array helper */
+#define NumberOf(arr) (sizeof(arr)/sizeof((arr)[0]))
+
+
+/* MVME6100 specific; re-define watchdog NMI pin to be a normal output
+ * so we have a way to raise an interrupt in software (GPP[26] is wired to
+ * GPP[6] on the MVME6100).
+ */
+#define	MVME6100_IRQ_DEBUG 4
+
+#define GPP_WIRED_OUT_BIT_6100 26	/* CAVEAT: this is bit 26 on the 6100 */
+#define GPP_WIRED_OUT_BIT_5500 24	/* CAVEAT: this is bit 24 on the 5500 */
+#define GPP_WIRED_IN_BIT   6
+
+/* Ored mask of debugging features to enable */
+#define IRQ_DEBUG_BASIC			1
+/* This is _very_ lowlevel */
+#define IRQ_DEBUG_DISPATCHER	2
+/* Record maximal dispatching latency */
+#define IRQ_DEBUG_MAXLAT		8	/* PPC only */
+
+#define IRQ_DEBUG (0 /*|(IRQ_DEBUG_BASIC)*/|(MVME6100_IRQ_DEBUG)|(IRQ_DEBUG_MAXLAT))
+
+/**********
+ * Typedefs
+ **********/
+
+/* Set of the three relevant cause registers */
+typedef volatile unsigned IrqMask[NUM_INTR_REGS];
+
+#define REGP(x) ((volatile uint32_t *)(x))
+
+/* Information we keep about the PIC         */
+typedef struct _Mv64x60PicRec {
+							/* base address as seen from CPU  */
+	uintptr_t	 			reg_base;
+
+							/* addresses of 'cause' registers */
+	volatile uint32_t		*causes[NUM_INTR_REGS];
+
+							/* addresses of 'mask'  registers */
+	volatile uint32_t		*masks[NUM_INTR_REGS];
+
+							/* masks for all priorities. If an
+							 * interrupt source has priority X,
+							 * its corresponding bit is set
+							 * (enabled) in mcache[i] for all
+							 * i < X and cleared for i >= X
+							 */
+	volatile IrqMask		mcache[BSP_IRQ_MAX_PRIO+1];
+
+							/* Priority we're executing at.
+							 * Thread-level is priority 0,
+							 * ISRs range from 1..MAX_PRIO
+							 */
+	volatile rtems_irq_prio	current_priority;
+} Mv64x60PicRec, *Mv64x60Pic;
+
+/**********
+ * Globals
+ **********/
+
+
+/* Copy of the configuration */
+static rtems_irq_global_settings	theConfig;
+/* PIC description           */
+static Mv64x60PicRec				thePic;
+
+#if	(IRQ_DEBUG) & MVME6100_IRQ_DEBUG
+static unsigned long				gpp_out_bit = 0;
+#endif
+
+#if	(IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
+unsigned long						discovery_pic_max_dispatching_latency = 0;
+#ifdef __PPC__
+static inline unsigned long mftb(void)
+{
+unsigned long rval;
+	asm volatile("mftb %0":"=r"(rval));
+	return rval;
+}
+#else
+#define mftb()	0
+#endif
+#endif
+
+/**********
+ * Functions
+ **********/
+
+/* Debugging helper routines */
+static void pregs(volatile uint32_t **p)
+{
+int i;
+	for (i=NUM_INTR_REGS-1; i>=0; i--) {
+		printk(" 0x%08x", ld_le32(p[i]));
+		printk( i ? " --":"\n");
+	}
+}
+
+static void pmsks(volatile IrqMask p)
+{
+int i;
+	for (i=NUM_INTR_REGS-1; i>=0; i--) {
+		printk(" 0x%08x", p[i]);
+		printk( i ? " --":"\n");
+	}
+}
+
+static void discovery_dump_picregs(void)
+{
+		printk("       ..GPP_IRQ. -- ..MAIN_HI. -- ..MAIN_LO.\n");
+		printk("Cause:"); pregs(thePic.causes);
+		printk("Mask: "); pregs(thePic.masks);
+}
+
+/* Small inline helpers      */
+
+/* return 0 if this PIC is not 'responsible' for a given irq number
+ * we also 'ignore' the GPP summary bits - these must always remain
+ * enabled.
+ */
+static inline int
+validIrqNo(rtems_irq_number irq)
+{
+	return
+		   irq >= BSP_PCI_IRQ_LOWEST_OFFSET
+		&& irq <= BSP_PCI_IRQ_MAX_OFFSET
+		&& ! (IMH_GPP_SUM & (1<<(irq-32)));
+}
+
+/* return 0 if a given priority is outside the valid range          */
+static inline int
+validPri(rtems_irq_prio pri)
+{
+	/* silence compiler warning about limited range of type;
+	 * hope it never changes...
+	 */
+	return /* pri>=0 && */ pri <=BSP_IRQ_MAX_PRIO;
+}
+
+/* Return position of the most significant bit that is set in 'x'  */
+static inline int
+__ilog2(unsigned x)
+{
+	asm volatile("cntlzw %0, %0":"=&r"(x):"0"(x));
+	return 31-x;
+}
+
+/* Convert irq number to cause register index
+ * (array of handles in the PicRec).
+ * ASSUMES: 'irq' within valid range.
+ */
+static inline unsigned
+irqDiv32(unsigned irq)
+{
+	return (irq-BSP_PCI_IRQ_LOWEST_OFFSET)>>5;
+}
+
+/* Convert irq number to cause/mask bit number.
+ * ASSUMES: 'irq' within valid range.
+ */
+
+static inline unsigned
+irqMod32(unsigned irq)
+{
+	return (irq-BSP_PCI_IRQ_LOWEST_OFFSET)&31;
+}
+
+/* NON-ATOMICALLY set/clear bits in a MV64x60 register
+ *
+ * register contents at offset 'off' are ANDed with
+ * complement of the 'clr' mask and ORed with 'set' mask:
+ *
+ *   *off = (*off & ~clr) | set
+ * 
+ * ASSUMES: executed from IRQ-disabled section
+ */
+static inline void
+gt_bitmod(unsigned off, unsigned set, unsigned clr)
+{
+	st_le32(REGP(thePic.reg_base + off),
+			(ld_le32(REGP(thePic.reg_base+off)) & ~clr) | set);
+}
+
+static inline unsigned
+gt_read(unsigned off)
+{
+	return ld_le32(REGP(thePic.reg_base + off));
+}
+
+static inline void
+gt_write(unsigned off, unsigned val)
+{
+	st_le32(REGP(thePic.reg_base + off), val);
+}
+
+/* Enable interrupt number 'irq' at the PIC.
+ *
+ * Checks for valid arguments but has no way of
+ * communicating violation; prints to console
+ * if illegal arguments are given.
+ *
+ * This routine may be called from ISR level.
+ *
+ * Algorithm: set corresponding bit in masks
+ *            for all priorities lower than the
+ *            target irq's priority and push
+ *            mask for the currently executing
+ *            priority out to the PIC.
+ */
+
+void
+BSP_enable_irq_at_pic(rtems_irq_number irq)
+{
+unsigned		   i,j;
+unsigned long	   flags;
+volatile uint32_t *p;
+uint32_t 		   v,m;
+
+	if ( !validIrqNo(irq) ) {
+/* API change - must silently ignore...
+		printk("BSP_enable_irq_at_pic: Invalid argument (irq #%i)\n",irq);
+ */
+		return;
+	}
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
+	printk("IRQ: Enable #%i;",irq);
+#endif
+
+	if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
+		/* This is probably a more serious error; don't ignore silently */
+		printk("BSP_enable_irq_at_pic: illegal argument\n");
+		return;
+	}
+	/* compute register pointer and bit mask */
+	p = thePic.masks[i];
+	m = 1<<irqMod32(irq);
+		
+	rtems_interrupt_disable(flags);
+	{
+		/* access table from protected section to be thread-safe */
+		rtems_irq_prio	pri = theConfig.irqPrioTbl[irq];
+		for ( j=0; j<pri; j++ ) {
+			thePic.mcache[j][i] |= m;
+		}
+		st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
+		/* linux driver reads back GPP mask; maybe it's wise to do the same */
+		(void)ld_le32(thePic.masks[GPP_IDX]);
+	}
+	SYNC();
+	rtems_interrupt_enable(flags);
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
+	printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
+
+#endif
+}
+
+/* Disable interrupt number 'irq' at the PIC.
+ *
+ * Checks for valid arguments but has no way of
+ * communicating violation; prints to console
+ * if illegal arguments are given.
+ *
+ * This routine may be called from ISR level.
+ *
+ * Algorithm: clear corresponding bit in masks
+ *            for all priorities and push the
+ *            mask for the currently executing
+ *            priority out to the PIC.
+ */
+
+int
+BSP_disable_irq_at_pic(rtems_irq_number irq)
+{
+unsigned		   i,j;
+unsigned long	   flags;
+volatile uint32_t *p;
+uint32_t           v,m;
+int                rval;
+
+	if ( !validIrqNo(irq) ) {
+/* API change - must silently ignore...
+		printk("BSP_disable_irq_at_pic: Invalid argument (irq #%i)\n",irq);
+ */
+		return -1;
+	}
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
+	printk("IRQ: Disable #%i;",irq);
+#endif
+
+	if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
+		/* This is probably a more serious error; don't ignore silently */
+		printk("BSP_enable_irq_at_pic: illegal argument\n");
+		return -1;
+	}
+
+	/* compute register pointer and bit mask */
+	p = thePic.masks[i];
+	m = (1<<irqMod32(irq));
+
+	rtems_interrupt_disable(flags);
+	{
+		rval = thePic.mcache[thePic.current_priority][i] & m;
+		for (j=0; j<=BSP_IRQ_MAX_PRIO; j++)
+			thePic.mcache[j][i] &= ~m;
+		st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
+		/* linux driver reads back GPP mask; maybe it's wise to do the same */
+		(void)ld_le32(thePic.masks[GPP_IDX]);
+	}
+	SYNC();
+	rtems_interrupt_enable(flags);
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
+	printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
+#endif
+
+	return rval ? 1 : 0;
+}
+
+int
+BSP_irq_is_enabled_at_pic(rtems_irq_number irq)
+{
+unsigned i;
+	if ( !validIrqNo(irq) ) {
+		printk("BSP_irq_is_enabled_at_pic: Invalid argument (irq #%i)\n",irq);
+		return -1;
+	}
+
+	if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
+		printk("BSP_enable_irq_at_pic: illegal argument\n");
+		return -1;
+	}
+	return ld_le32(thePic.masks[i]) & (1<<irqMod32(irq)) ? 1 : 0;
+}
+
+
+/* Change priority of interrupt number 'irq' to 'pri'
+ *
+ * RETURNS: 0 on success, nonzero on failure (illegal args)
+ *
+ * NOTE: This routine must not be called from ISR level.
+ *
+ * Algorithm: Set bit corresponding to 'irq' in the masks for
+ *            all priorities < pri and clear in all masks
+ *            for priorities >=pri
+ */
+int
+BSP_irq_set_priority(rtems_irq_number irq, rtems_irq_prio pri)
+{
+unsigned long	   flags;
+volatile uint32_t *p;
+uint32_t 		   v,m;
+unsigned           i,j;
+
+	if ( thePic.current_priority > 0 ) {
+		printk("BSP_irq_set_priority: must not be called from ISR level\n");
+		return -1;
+	}
+
+	if ( !validPri(pri) ) {
+		printk("BSP_irq_set_priority: invalid argument (pri #%i)\n",pri);		
+		return -1;
+	}
+
+	if ( BSP_DECREMENTER != irq ) {
+		if ( !validIrqNo(irq) ) {
+			printk("BSP_irq_set_priority: invalid argument (irq #%i)\n",irq);		
+			return -1;
+		}
+
+		if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
+			printk("BSP_irq_set_priority: illegal argument (irq #%i not PCI?)\n", irq);
+			return -1;
+		}
+	}
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
+	printk("IRQ: Set Priority #%i -> %i;",irq,pri);
+#endif
+
+	if ( BSP_DECREMENTER == irq ) {
+		theConfig.irqPrioTbl[irq] = pri;
+		return 0;
+	}
+
+	/* compute register pointer and bit mask */
+	p = thePic.masks[i];
+	m = 1<<irqMod32(irq);
+	
+	rtems_interrupt_disable(flags);
+	{
+		for (j=0; j<=BSP_IRQ_MAX_PRIO; j++) {
+			if ( j<pri )
+				thePic.mcache[j][i] |= m;
+			else
+				thePic.mcache[j][i] &= ~m;
+		}
+		theConfig.irqPrioTbl[irq] = pri;
+		st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
+		/* linux driver reads back GPP mask; maybe it's wise to do the same */
+		(void)ld_le32(thePic.masks[GPP_IDX]);
+	}
+	SYNC();
+	rtems_interrupt_enable(flags);
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
+	printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
+#endif
+
+	return 0;
+}
+
+/* Initialize the PIC; routine needed by BSP framework
+ *
+ * RETURNS: NONZERO on SUCCESS, 0 on error!
+ */
+int
+BSP_setup_the_pic(rtems_irq_global_settings* config)
+{
+int i;
+   /*
+    * Store copy of configuration
+    */
+	theConfig				= *config;
+
+	/* check config */
+	if ( theConfig.irqNb <= BSP_PCI_IRQ_MAX_OFFSET ) {
+		printk("BSP_setup_the_pic: FATAL ERROR: configured IRQ table too small???\n");
+		return 0;
+	} 
+
+	for ( i=0; i<theConfig.irqNb; i++ ) {
+		if ( !validPri(theConfig.irqPrioTbl[i]) ) {
+			printk("BSP_setup_the_pic: invalid priority (%i) for irg #%i; setting to 1\n", theConfig.irqPrioTbl[i], i);
+			theConfig.irqPrioTbl[i]=1;
+		}
+	}
+
+	/* TODO: Detect; Switch wired-out bit;  */
+	thePic.reg_base = BSP_MV64x60_BASE;
+
+	thePic.current_priority = 0;
+
+#if	(IRQ_DEBUG) & MVME6100_IRQ_DEBUG
+#endif
+
+	switch ( BSP_getDiscoveryVersion(/* assert */ 1) ) {
+		case MV_64360:
+			thePic.causes[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_360_MIC_LO);
+			thePic.causes[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_360_MIC_HI);
+			thePic.masks[MAIN_LO_IDX]  = REGP(thePic.reg_base + ICR_360_C0IM_LO);
+			thePic.masks[MAIN_HI_IDX]  = REGP(thePic.reg_base + ICR_360_C0IM_HI);
+		break;
+
+		case GT_64260_A:
+		case GT_64260_B:
+			thePic.causes[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_260_MIC_LO);
+			thePic.causes[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_260_MIC_HI);
+			thePic.masks[MAIN_LO_IDX]  = REGP(thePic.reg_base + ICR_260_CIM_LO);
+			thePic.masks[MAIN_HI_IDX]  = REGP(thePic.reg_base + ICR_260_CIM_HI);
+		break;
+
+		default:
+			rtems_panic("Unable to initialize interrupt controller; unknown chip");
+		break;
+	}
+
+	thePic.causes[GPP_IDX]     = REGP(thePic.reg_base + GT_GPP_Interrupt_Cause);
+	thePic.masks[GPP_IDX]      = REGP(thePic.reg_base + GT_GPP_Interrupt_Mask);
+
+	/* Initialize mask cache */
+	for ( i=0; i<=BSP_IRQ_MAX_PRIO; i++ ) {
+		thePic.mcache[i][MAIN_LO_IDX] = 0;
+		/* Always enable the summary bits. Otherwise, GPP interrupts dont
+		 * make it 'through' to the GPP cause
+		 */
+		thePic.mcache[i][MAIN_HI_IDX] = IMH_GPP_SUM;
+		thePic.mcache[i][GPP_IDX]     = 0;
+	}
+
+	/* mask and clear everything */
+	for ( i=0; i<NUM_INTR_REGS; i++ ) {
+		st_le32(thePic.causes[i], 0);
+		st_le32(thePic.masks[i], 0);
+	}
+
+	/* make sure GPP Irqs are level sensitive */
+	gt_bitmod(
+		GT_CommUnitArb_Ctrl,							/* reg */
+		GT_CommUnitArb_Ctrl_GPP_Ints_Level_Sensitive,	/* set */
+		0);												/* clr */
+
+	/* enable summaries */
+	st_le32(thePic.masks[MAIN_LO_IDX], thePic.mcache[thePic.current_priority][MAIN_LO_IDX]);
+	st_le32(thePic.masks[MAIN_HI_IDX], thePic.mcache[thePic.current_priority][MAIN_HI_IDX]);
+	st_le32(thePic.masks[GPP_IDX    ], thePic.mcache[thePic.current_priority][GPP_IDX    ]);
+
+	/* believe the interrupts are all level sensitive (which is good); we leave all the
+	 * inputs configured they way the are by MotLoad...
+	 */
+	
+	/* Finally, enable all interrupts for which the configuration table has already
+	 * a handler installed.
+	 */
+	for ( i=BSP_PCI_IRQ_LOWEST_OFFSET; i<=BSP_PCI_IRQ_MAX_OFFSET; i++ ) {
+		if ( theConfig.irqHdlTbl[i].hdl != theConfig.defaultEntry.hdl ) {
+			BSP_enable_irq_at_pic(i);
+		}
+	}
+
+	return 1;
+}
+
+int discovery_pic_max_loops = 0;
+
+
+/* Change the priority level we're executing at and mask all interrupts of
+ * the same and lower priorities
+ *
+ * RETURNS old priority;
+ */
+
+static inline  rtems_irq_prio
+change_executing_prio_level(rtems_irq_prio pri)
+{
+register rtems_irq_prio rval = thePic.current_priority;
+	thePic.current_priority = pri;
+	st_le32(thePic.masks[MAIN_LO_IDX], thePic.mcache[pri][MAIN_LO_IDX]);
+	st_le32(thePic.masks[MAIN_HI_IDX], thePic.mcache[pri][MAIN_HI_IDX]);
+	st_le32(thePic.masks[GPP_IDX    ], thePic.mcache[pri][GPP_IDX    ]);
+	/* this DOES seem to be necessary */
+	(void)ld_le32(thePic.masks[GPP_IDX]);
+	return rval;
+}
+
+/* Scan the three cause register and find the pending interrupt with
+ * the highest priority.
+ *
+ * Two facts make this quite efficient
+ *   a) the PPC has an opcode for finding the number of leading zero-bits
+ *      in a register (__ilog2()).
+ *   b) as we proceed we mask all sources of equal or lower priorites; they won't be
+ *      seen while scanning:
+ *
+ *   maxpri = 0;
+ *   bits   = in_le32(cause);
+ *   while ( bits &= mask[maxpri] ) {
+ *      irq_no = __ilog2(bits);
+ *     	maxpri = priority[irq_no]; 
+ *   }
+ *   
+ *   a)  __ilog() is 1-2 machine instructions
+ *   b) while loop is only executed as many times as interrupts of different
+ *      priorities are pending at the same time (and only if lower-priority
+ *      ones are found first; otherwise, the iteration terminates quicker).
+ *
+ *   ==> highest priority source is found quickly. It takes at most
+ *
+ *		BSP_IRQ_MAX_PRIO * ( ~3 reg-only instructions + 2 memory access )
+ *      + 2 reg-only instructions + 1 I/O + 1 memory access.
+ *
+ *       
+ */
+
+static unsigned mlc, mhc, gpc;
+
+static int decrementerPending = 0;
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+int        decrementerIrqs    = 0;
+#endif
+
+static inline unsigned 
+find_highest_priority_pending_irq(rtems_irq_prio *ppri)
+{
+register int			rval = -1;
+register rtems_irq_prio *pt  = theConfig.irqPrioTbl + BSP_PCI_IRQ_LOWEST_OFFSET;
+register rtems_irq_prio pmax = *ppri;
+register unsigned		cse,ocse;
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+	discovery_dump_picregs();
+#endif
+
+	if ( decrementerPending ) {
+/* Don't flood 
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		printk("Decrementer IRQ pending\n");
+#endif
+*/
+		if ( theConfig.irqPrioTbl[BSP_DECREMENTER] > pmax ) {
+			pmax = theConfig.irqPrioTbl[BSP_DECREMENTER];
+			rval = BSP_DECREMENTER;
+		}
+	}
+
+	mlc = cse = ld_le32(thePic.causes[MAIN_LO_IDX]);
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+	printk("MAIN_LO; cse: 0x%08x, msk 0x%08x\n", cse ,thePic.mcache[pmax][MAIN_LO_IDX]);
+#endif
+	while ( cse &= thePic.mcache[pmax][MAIN_LO_IDX] ) {
+		rval = __ilog2(cse);
+		pmax = pt[rval];
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		printk("Max pri IRQ now %i\n",rval);
+#endif
+	}
+	mhc = cse = ocse = ld_le32(thePic.causes[MAIN_HI_IDX]);
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+	printk("MAIN_HI; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][MAIN_HI_IDX]);
+#endif
+	/* don't look at the GPP summary; only check for 'real' MAIN_HI sources */
+	cse &= ~IMH_GPP_SUM;
+	while ( cse &= thePic.mcache[pmax][MAIN_HI_IDX] ) {
+		rval = __ilog2(cse) + 32;
+		pmax = pt[rval];
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		printk("Max pri IRQ now %i\n",rval);
+#endif
+	}
+	gpc = cse = ld_le32(thePic.causes[GPP_IDX    ]);
+	/* if there were GPP ints, scan the GPP cause now */
+	if ( ocse & IMH_GPP_SUM ) {
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		printk("GPP; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][GPP_IDX    ]);
+#endif
+		cse &= thePic.mcache[pmax][GPP_IDX    ];
+		ocse = cse;
+		while ( cse ) {
+			rval = __ilog2(cse) + 64;
+			pmax = pt[rval];
+			cse &= thePic.mcache[pmax][GPP_IDX    ];
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+			printk("Max pri IRQ now %i\n",rval);
+#endif
+		}
+#ifndef FASTER
+		/* this doesn't seem to be necessary -- however, the linux people do it... */
+		out_le32(thePic.causes[GPP_IDX], ~ocse);
+#endif
+	}
+#ifndef FASTER
+	/* this doesn't seem to be necessary -- however, the linux people do it... */
+	(void)in_le32(thePic.causes[GPP_IDX]);
+#endif
+
+	*ppri = pmax;
+
+	if ( BSP_DECREMENTER == rval ) {
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		decrementerIrqs++;
+#endif
+		decrementerPending = 0;
+	}
+
+	return rval;
+}
+
+#if 0 /* TODO: should this be cleaned up ? */
+#define _IRQ_DEBUG IRQ_DEBUG_DISPATCHER
+static inline unsigned 
+ffind_highest_priority_pending_irq(rtems_irq_prio *ppri)
+{
+register int			rval = -1;
+register rtems_irq_prio *pt  = theConfig.irqPrioTbl + BSP_PCI_IRQ_LOWEST_OFFSET;
+register rtems_irq_prio pmax = *ppri;
+register unsigned		cse,ocse;
+
+#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+	discovery_dump_picregs();
+#endif
+
+	cse = in_le32(thePic.causes[MAIN_LO_IDX]);
+#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+	printk("MAIN_LO; cse: 0x%08x, msk 0x%08x\n", cse ,thePic.mcache[pmax][MAIN_LO_IDX]);
+#endif
+	while ( cse &= thePic.mcache[pmax][MAIN_LO_IDX] ) {
+		rval = __ilog2(cse);
+		pmax = pt[rval];
+#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		printk("Max pri IRQ now %i\n",rval);
+#endif
+	}
+	cse = ocse = in_le32(thePic.causes[MAIN_HI_IDX]);
+#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+	printk("MAIN_HI; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][MAIN_HI_IDX]);
+#endif
+	/* don't look at the GPP summary; only check for 'real' MAIN_HI sources */
+	cse &= ~IMH_GPP_SUM;
+	while ( cse &= thePic.mcache[pmax][MAIN_HI_IDX] ) {
+		rval = __ilog2(cse) + 32;
+		pmax = pt[rval];
+#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		printk("Max pri IRQ now %i\n",rval);
+#endif
+	}
+	/* if there were GPP ints, scan the GPP cause now */
+	if ( ocse & IMH_GPP_SUM ) {
+		cse = in_le32(thePic.causes[GPP_IDX    ]);
+#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		printk("GPP; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][GPP_IDX    ]);
+#endif
+		cse &= thePic.mcache[pmax][GPP_IDX    ];
+		ocse = cse;
+		while ( cse ) {
+			rval = __ilog2(cse) + 64;
+			pmax = pt[rval];
+			cse &= thePic.mcache[pmax][GPP_IDX    ];
+#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+			printk("Max pri IRQ now %i\n",rval);
+#endif
+		}
+		/* this doesn't seem to be necessary -- however, the linux people do it... */
+		out_le32(thePic.causes[GPP_IDX], ~ocse);
+	}
+	/* this doesn't seem to be necessary -- however, the linux people do it... */
+	(void)in_le32(thePic.causes[GPP_IDX]);
+
+	*ppri = pmax;
+	return rval;
+}
+#endif
+
+
+/* Here's our dispatcher; the BSP framework uses the same one for EE and decrementer
+ * exceptions...
+ */
+int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+register int             irq;
+int				         loop, last_irq;
+rtems_irq_prio           pri;
+#if	(IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
+unsigned long	         diff;
+#endif
+
+#if	(IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
+	diff = mftb();
+#endif
+
+	if (excNum == ASM_DEC_VECTOR) {
+		decrementerPending = 1;
+	}
+
+	/* Tradeoff: EITHER we loop as long as interrupts are pending
+	 *           incurring the overhead of one extra run of the 'find_pending_irq' routine.
+	 *           OR we do rely on the handler just being invoked again if multiple
+	 *			 interrupts are pending.
+	 *
+	 *           The first solution gives better worst-case behavior
+	 *			 the second slightly better average performance.
+	 *			 --> we go for the first solution. This also enables us to catch
+	 *			 runaway interrupts, i.e., bad drivers that don't clear interrupts
+	 *			 at the device. Can be very handy during driver development...
+	 */
+	for ( loop=0, last_irq=-1, pri = thePic.current_priority;
+		  (irq=find_highest_priority_pending_irq(&pri)) >=0;
+		  loop++, last_irq = irq ) {
+
+		/* raise priority level and remember current one */
+		pri = change_executing_prio_level(pri);
+
+		SYNC();
+
+#if	(IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
+		if ( 0 == loop ) {
+			diff = mftb()-diff;
+			if ( diff > discovery_pic_max_dispatching_latency )
+				discovery_pic_max_dispatching_latency = diff;
+		}
+#endif
+
+#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
+		if ( BSP_DECREMENTER == irq ) {
+			printk("IRQ: dispatching DECREMENTER\n");
+		} else {
+		int idx = irqDiv32(irq);
+			printk("IRQ: dispatching #%i; causes[%i]=0x%08x\n", irq, idx, ld_le32(thePic.causes[idx]));
+		}
+#endif
+
+		bsp_irq_dispatch_list( theConfig.irqHdlTbl, irq, theConfig.defaultEntry.hdl );
+
+		/* restore executing priority level */
+		(void)change_executing_prio_level(pri);
+
+		if ( (loop > MAX_SPIN_LOOPS) && (last_irq == irq) ) {
+			/* try to catch run-away interrupts without disabling a 'legal' one;
+			 * this should never happen with the decrementer (and
+			 * BSP_disable_irq_at_pic(BSP_DECREMENTER) would fail)
+			 */
+			printk("Runaway IRQ #%i; disabling\n", irq);
+			BSP_disable_irq_at_pic(irq);
+			loop = 0;
+		}
+	}
+
+	if (!loop) {
+		if ( decrementerPending && pri >= theConfig.irqPrioTbl[BSP_DECREMENTER] ) {
+			/* we cannot mask the decrementer interrupt so it is possible that it
+			 * gets delivered even though it has a lower priority than what we're
+			 * currently executing at.
+			 * In this case, we ignore the zero loop count and return;
+			 * the interrupted instance of C_dispatch_irq_handler() will eventually
+			 * lower the executing priority and catch the 'decrementerPending' flag
+			 * we just set.
+			 */
+		} else {
+			printk("Discovery: Spurious interrupt; causes were gpp: 0x%x, mhc: 0x%x, mlc: 0x%x\n", gpc, mhc, mlc);
+			printk("Current priority level %i, decrementerPending %i\n", pri, decrementerPending);
+			{
+				rtems_irq_prio p=pri;	
+				printk("PIC register dump:\n");
+				discovery_dump_picregs();
+				printk("Current Priority: %i, found %i\n",pri,find_highest_priority_pending_irq(&p));
+				discovery_dump_picregs();
+				for (p=0; p<=BSP_IRQ_MAX_PRIO; p++) {
+					printk("M[%i] :",p);pmsks(thePic.mcache[p]);
+				}
+			}
+		}
+	}
+	else if (loop>discovery_pic_max_loops)
+		discovery_pic_max_loops = loop;
+
+	return 0;
+}
+
+
+#if	(IRQ_DEBUG) & MVME6100_IRQ_DEBUG
+void
+discovery_pic_install_debug_irq(void)
+{
+	switch ( BSP_getBoardType() ) {
+		case	MVME6100:	gpp_out_bit = GPP_WIRED_OUT_BIT_6100; break;
+		case	MVME5500:	gpp_out_bit = GPP_WIRED_OUT_BIT_5500; break;
+		default:
+							gpp_out_bit = 0; break;
+							break;
+	}
+	if ( gpp_out_bit ) {
+		unsigned mppoff;
+		switch (gpp_out_bit / 8) {
+			default:	/* silence warning; this is never reached */
+			case 0: mppoff = GT_MPP_Control0; break;
+			case 1: mppoff = GT_MPP_Control1; break;
+			case 2: mppoff = GT_MPP_Control2; break;
+			case 3: mppoff = GT_MPP_Control3; break;
+		}
+
+		/* switch GPP pin allocated to watchdog (value 4) to
+		 * GPP I/O (value 0 ??; have no doc, found out by experimenting)
+		 */
+		gt_bitmod(mppoff, 0, (0xf<<(4*(gpp_out_bit % 8))));
+
+		/* make it an output */
+		gt_bitmod(GT_GPP_IO_Control, (1<<gpp_out_bit), 0);
+
+		/* don't invert levels */
+		gt_bitmod(GT_GPP_Level_Control, 0, (1<<GPP_WIRED_IN_BIT) | (1<<gpp_out_bit));
+
+		/* clear output */
+		gt_bitmod(GT_GPP_Value, 0, 1<<gpp_out_bit);
+
+		printk("GPP levelctl now 0x%08x\n", gt_read(GT_GPP_Level_Control));
+		printk("GPP value    now 0x%08x\n", gt_read(GT_GPP_Value));
+		printk("MPP ctl 0    now 0x%08x\n", gt_read(GT_MPP_Control0));
+		printk("MPP ctl 1    now 0x%08x\n", gt_read(GT_MPP_Control1));
+		printk("MPP ctl 2    now 0x%08x\n", gt_read(GT_MPP_Control2));
+		printk("MPP ctl 3    now 0x%08x\n", gt_read(GT_MPP_Control3));
+
+	}
+}
+
+/* Control the state of the external 'wire' that connects the
+ * GPP_WIRED_OUT --> GPP_WIRED_IN pins
+ */
+void
+discovery_pic_set_debug_irq(int on)
+{
+unsigned long flags, clr;
+	if ( !gpp_out_bit ) {
+		printk("discovery_pic_set_debug_irq(): unknown wire output\n");
+		return;
+	}
+	if (on) {
+		on  = 1<<gpp_out_bit;
+		clr = 0;
+	} else {
+		clr = 1<<gpp_out_bit;
+		on  = 0;
+	}
+	rtems_interrupt_disable(flags);
+		gt_bitmod(GT_GPP_Value, on, clr);
+	rtems_interrupt_enable(flags);
+}
+#endif
+
+#if 0
+/* Here's some code for testing */
+#endif
Index: bsps/powerpc/beatnik/irq/irq_init.c
===================================================================
--- bsps/powerpc/beatnik/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/beatnik/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,110 @@
+/* irq_init.c
+ *
+ *  This file contains the implementation of rtems initialization
+ *  related to interrupt handling.
+ *
+ *  CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ * to make it valid for MVME2300 Motorola boards.
+ *
+ * Modified by T. Straumann for the 'beatnik' BSP.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/vectors.h>
+#include <rtems/bspIo.h>
+
+#if 0
+#include <libcpu/io.h>
+#include <libcpu/spr.h>
+#include <bsp/pci.h>
+#include <bsp/residual.h>
+#include <bsp/openpic.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <bsp/motorola.h>
+#endif
+
+/*
+#define SHOW_ISA_PCI_BRIDGE_SETTINGS
+*/
+
+extern unsigned int external_exception_vector_prolog_code_size[];
+extern void external_exception_vector_prolog_code(void);
+extern unsigned int decrementer_exception_vector_prolog_code_size[];
+extern void decrementer_exception_vector_prolog_code(void);
+
+/*
+ * default handler
+ */
+static void nop_func(void *arg){}
+
+static rtems_irq_connect_data     	rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings    initial_config;
+static rtems_irq_prio				rtemsPrioTbl[BSP_IRQ_NUMBER];
+static rtems_irq_connect_data     	defaultIrq = {
+  name:   0,
+  hdl:    nop_func,
+  handle: 0,
+  on:     0,
+  off:    0,
+  isOn:   0
+};
+
+
+  /*
+   * This code assumes the exceptions management setup has already
+   * been done. We just need to replace the exceptions that will
+   * be handled like interrupt. On mcp750/mpc750 and many PPC processors
+   * this means the decrementer exception and the external exception.
+   */
+
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+int i;
+
+	/*
+	 * First initialize the Interrupt management hardware
+	 */
+
+	/*
+	 * Initialize Rtems management interrupt table
+	 */
+
+	/*
+	 * re-init the rtemsIrq table
+	 */
+	for (i = BSP_LOWEST_OFFSET; i <= BSP_MAX_OFFSET; i++) {
+		rtemsIrq[i]      = defaultIrq;
+		rtemsIrq[i].name = i;
+		rtemsPrioTbl[i]  = BSP_IRQ_DEFAULT_PRIORITY;
+	}
+
+	/*
+	 * Init initial Interrupt management config
+	 */
+	initial_config.irqNb 	= BSP_IRQ_NUMBER;
+	initial_config.defaultEntry = defaultIrq;
+	initial_config.irqHdlTbl	= rtemsIrq;
+	initial_config.irqBase	= BSP_LOWEST_OFFSET;
+	initial_config.irqPrioTbl	= rtemsPrioTbl;
+
+	if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+		/*
+		 * put something here that will show the failure...
+		 */
+		rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+	}
+
+#ifdef TRACE_IRQ_INIT  
+	printk("RTEMS IRQ management is now operationnal\n");
+#endif
+}
+
Index: bsps/powerpc/beatnik/irq/irq_test_app.c
===================================================================
--- bsps/powerpc/beatnik/irq/irq_test_app.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/beatnik/irq/irq_test_app.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,164 @@
+/*  Init
+ *
+ *  This routine is the initialization task for this test program.
+ *  It is called from init_exec and has the responsibility for creating
+ *  and starting the tasks that make up the test.  If the time of day
+ *  clock is required for the test, it should also be set to a known
+ *  value by this function.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  OAR init.c Template modified by T. Straumann who provided
+ *  the implementation of this application.
+ */
+
+#define CONFIGURE_INIT
+
+#include <rtems.h>
+
+/* functions */
+rtems_task Init(
+  rtems_task_argument argument
+);
+                                                                                                                                                            
+/* configuration information */
+#include <bsp.h> /* for device driver prototypes */
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_MAXIMUM_TASKS            1
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+#include <confdefs.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+
+
+void noop(){}
+int  connected() {return 1;}
+
+rtems_irq_connect_data blah = { 0, 0, noop, noop, connected };
+extern void discovery_pic_set_debug_irq();
+
+#define WIRE_IRQ (BSP_IRQ_GPP_0 + 6)
+#define ABRT_IRQ (BSP_IRQ_GPP_0 + 2)
+
+static volatile int testno=0;
+static volatile int wloops =0;
+static volatile int aloops =0;
+
+void wire_hdl()
+{
+	if ( 1 == testno ) {
+		BSP_disable_irq_at_pic(WIRE_IRQ);
+	}
+
+	if ( 2 == testno || 3 == testno ) {
+		discovery_pic_set_debug_irq(0);
+		printk("WIRE -- this message should be printed %s\n", 3==testno ? "FIRST":"SECOND");
+	} else {
+	}
+
+	/* assume the driver checks for less than 1000 loops */
+	if ( ++wloops > 1000) {
+		printk("wire IRQ. FAILURE -- driver couldn't catch runaway ISR. Disabling IRQ source.\n");
+		discovery_pic_set_debug_irq(0);
+		BSP_disable_irq_at_pic(WIRE_IRQ);
+	}
+	/*
+	*/
+}
+
+void abrt_hdl()
+{
+	aloops++;
+	if ( 2 == testno || 3 == testno ) {
+		discovery_pic_set_debug_irq(1);
+		printk("ABRT -- this message should be printed %s\n", 2==testno ? "FIRST":"SECOND");
+	} else 
+		printk("ABRT IRQ\n");
+
+	if ( 1== testno ) {
+		BSP_enable_irq_at_pic(WIRE_IRQ);
+	}
+	BSP_disable_irq_at_pic(ABRT_IRQ);
+}
+
+
+rtems_task Init(
+  rtems_task_argument ignored
+)
+{
+  blah.name = WIRE_IRQ;
+  blah.hdl  = wire_hdl;
+  if (!BSP_install_rtems_irq_handler(&blah)) {
+	fprintf(stderr,"installing handler 1 failed\n");
+  }
+  blah.name = ABRT_IRQ;
+  blah.hdl  = abrt_hdl;
+  if (!BSP_install_rtems_irq_handler(&blah)) {
+	fprintf(stderr,"installing handler 2 failed\n");
+  }
+  printf("Hello, testing the ISR dispatcher...\n");
+  printf(" 1. Trying to catch runaway interrupt\n");
+  printf("    If the system freezes, the test failed!\n");
+  fflush(stdout); sleep(1);
+  aloops = wloops = 0;
+  discovery_pic_set_debug_irq(1);
+  printf("    >>> %s\n", wloops<1000 ? "SUCCESS" : "FAILED");
+  discovery_pic_set_debug_irq(0);
+
+  testno++;
+  printf(" 2. Testing enabling / disabling interrupt from ISR\n");
+  printf("    Hit the ABORT key for this test\n");
+  fflush(stdout); sleep(1);
+  aloops = wloops = 0;
+  BSP_disable_irq_at_pic(WIRE_IRQ);
+  BSP_irq_set_priority(ABRT_IRQ,1);
+  BSP_enable_irq_at_pic(ABRT_IRQ);
+  discovery_pic_set_debug_irq(1);
+  while (!aloops)
+	;
+  discovery_pic_set_debug_irq(0);
+  sleep(2);
+  printf("    >>> disabling ABRT IRQ from isr %s\n", 1==aloops ? "SUCCESS":"FAILURE");
+  printf("        flashing  WIRE IRQ from isr %s\n", 1==wloops ? "SUCCESS":"FAILURE");
+
+  
+  testno++;
+  printf(" 3. Testing interrupt priorities\n");
+  BSP_irq_set_priority(ABRT_IRQ,2);
+  BSP_irq_set_priority(WIRE_IRQ,2);
+  BSP_enable_irq_at_pic(ABRT_IRQ);
+  BSP_enable_irq_at_pic(WIRE_IRQ);
+  printf("    Hit the ABORT key for this test\n");
+  fflush(stdout); sleep(1);
+  aloops = wloops = 0;
+  while (!aloops)
+	;
+  sleep(2);
+  testno++;
+  printf("    Now we are raising the priority of the wire interrupt\n");
+  BSP_irq_set_priority(WIRE_IRQ,3);
+  BSP_enable_irq_at_pic(ABRT_IRQ);
+  printf("    Hit the ABORT key for this test\n");
+  fflush(stdout); sleep(1);
+  aloops = wloops = 0;
+  while (!aloops)
+	;
+
+  sleep(2);
+  printf( "That's it; we're done...\n" );
+  exit( 0 );
+}
Index: bsps/powerpc/gen5200/irq/irq.c
===================================================================
--- bsps/powerpc/gen5200/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/gen5200/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,722 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP                              |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2005                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the irq controller handler                   |
+\*===============================================================*/
+/***********************************************************************/
+/*                                                                     */
+/*   Module:       irq.c                                               */
+/*   Date:         07/17/2003                                          */
+/*   Purpose:      RTEMS MPC5x00 CPU main interrupt handler & routines */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Description:  This file contains the implementation of the        */
+/*                 functions described in irq.h                        */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Code                                                              */
+/*   References:   MPC8260ads main interrupt handler & routines        */
+/*   Module:       irc.c                                               */
+/*   Project:      RTEMS 4.6.0pre1 / MCF8260ads BSP                    */
+/*   Version       1.2                                                 */
+/*   Date:         04/18/2002                                          */
+/*                                                                     */
+/*   Author(s) / Copyright(s):                                         */
+/*                                                                     */
+/*   Copyright (C) 1998, 1999 valette@crf.canon.fr                     */
+/*                                                                     */
+/*   Modified for mpc8260 Andy Dachs <a.dachs@sstl.co.uk>              */
+/*   Surrey Satellite Technology Limited, 2000                         */
+/*   Nested exception handlers not working yet.                        */
+/*                                                                     */
+/*   The license and distribution terms for this file may be           */
+/*   found in the file LICENSE in this distribution or at     */
+/*   http://www.rtems.org/license/LICENSE.                        */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Partially based on the code references which are named above.     */
+/*   Adaptions, modifications, enhancements and any recent parts of    */
+/*   the code are under the right of                                   */
+/*                                                                     */
+/*         IPR Engineering, Dachauer StraÃe 38, D-80335 MÃŒnchen        */
+/*                        Copyright(C) 2003                            */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   IPR Engineering makes no representation or warranties with        */
+/*   respect to the performance of this computer program, and          */
+/*   specifically disclaims any responsibility for any damages,        */
+/*   special or consequential, connected with the use of this program. */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Version history:  1.0                                             */
+/*                                                                     */
+/***********************************************************************/
+
+#include <inttypes.h>
+
+#include <rtems.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <bsp/vectors.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/mpc5200.h>
+
+/*
+ * bit in the SIU mask registers (PPC bit numbering) that should
+ * be set to enable the relevant interrupt, mask of 32 is for unused entries
+ *
+ */
+const static unsigned int SIU_MaskBit [BSP_SIU_IRQ_NUMBER] = {
+  0, 1, 2, 3,                   /* smart_comm, psc1, psc2, psc3            */
+  4, 5, 6, 7,                   /* irda/psc6, eth, usb, ata                */
+  8, 9, 10, 11,                 /* pci_ctrl, pci_sc_rx, pci_sc_tx, psc4    */
+  12, 13, 14, 15,               /* psc5,spi_modf, spi_spif, i2c1           */
+  16, 17, 18, 19,               /* i2c, can1, can2, ir_rx                  */
+  20, 21, 15, 16,               /* ir_rx, xlb_arb, slice_tim2, irq1,       */
+  17, 18, 19, 20,               /* irq2, irq3, lo_int, rtc_pint            */
+  21, 22, 23, 24,               /* rtc_sint, gpio_std, gpio_wkup, tmr0     */
+  25, 26, 27, 28,               /* tmr1, tmr2, tmr3, tmr4                  */
+  29, 30, 31, 32,               /* tmr5, tmr6, tmr7, res                   */
+  32, 32, 32                    /* res, res, res                           */
+};
+
+static unsigned char irqPrioTable [BSP_SIU_IRQ_NUMBER] = {
+/* per. int. priorities (0-7) / 4bit coding / msb is HI/LO selection               */
+/* msb = 0 -> non-critical per. int. is routed to main int. (LO_int)               */
+/* msb = 1 -> critical per. int. is routed to critical int. (HI_int)               */
+  0xF, 0, 0, 0,                 /* smart_comm (do not change!), psc1, psc2, psc3             */
+  0, 0, 0, 0,                   /* irda, eth, usb, ata                                       */
+  0, 0, 0, 0,                   /* pci_ctrl, pci_sc_rx, pci_sc_tx, res                       */
+  0, 0, 0, 0,                   /* res, spi_modf, spi_spif, i2c1                             */
+  0, 0, 0, 0,                   /* i2c, can1, can2, ir_rx                                    */
+  0, 0,                         /* ir_rx, xlb_arb                                            */
+/* main interrupt priorities (0-7) / 4bit coding / msb is INT/SMI selection        */
+/* msb = 0 -> main int. is routed to processor INT (low vector base 0x500 )        */
+/* msb = 1 -> main int. is routed to processor SMI (low vector base 0x1400 )       */
+  0, 0,                         /* slice_tim2, irq1                                          */
+  0, 0, 0, 0,                   /* irq2, irq3, lo_int, rtc_pint                              */
+  0, 0, 0, 0,                   /* rtc_sint, gpio_std, gpio_wkup, tmr0                       */
+  0, 0, 0, 0,                   /* tmr1, tmr2, tmr3, tmr4                                    */
+  0, 0, 0,                      /* tmr5, tmr6, tmr7                                          */
+  /* critical interrupt priorities (0-3) / 2bit coding / no special purpose of msb */
+  0,                            /* irq0                                                      */
+  0, 0, 0                       /* slice_tim1, hi_int, ccs_wkup                              */
+};
+
+static uint32_t irqMaskTable [BSP_PER_IRQ_NUMBER + BSP_MAIN_IRQ_NUMBER];
+
+/*
+ * Check if symbolic IRQ name is a Processor IRQ
+ */
+static inline bool is_processor_irq( rtems_vector_number irqLine)
+{
+
+  return ((irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET)
+    && (irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET));
+}
+
+/*
+ * Check for SIU IRQ and return base index
+ */
+static inline bool is_siu_irq( rtems_vector_number irqLine)
+{
+
+  return ((irqLine <= BSP_SIU_IRQ_MAX_OFFSET)
+    && (irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET));
+}
+
+/*
+ * Check for SIU IRQ and return base index
+ */
+static inline int get_siu_irq_base_index( rtems_vector_number irqLine)
+{
+  if (irqLine <= BSP_PER_IRQ_MAX_OFFSET)
+    return BSP_PER_IRQ_LOWEST_OFFSET;
+
+  if (irqLine <= BSP_MAIN_IRQ_MAX_OFFSET)
+    return BSP_MAIN_IRQ_LOWEST_OFFSET;
+
+  if (irqLine <= BSP_CRIT_IRQ_MAX_OFFSET)
+    return BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+  return -1;
+}
+
+static inline void BSP_enable_per_irq_at_siu(
+  rtems_vector_number irqLine
+)
+{
+  uint8_t lo_hi_ind = 0,
+    prio_index_offset;
+  uint32_t *reg;
+
+  /* calculate the index offset of priority value bit field */
+  prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8;
+
+  /* set interrupt priorities */
+  if (irqPrioTable [irqLine] <= 15) {
+
+    /* set peripheral int priority */
+    reg = (uint32_t *) (&(mpc5200.per_pri_1));
+
+    /* choose proper register */
+    reg += (irqLine >> 3);
+
+    /* set priority as given in priority table */
+    *reg |= (irqPrioTable [irqLine] << (28 - (prio_index_offset << 2)));
+
+    /* test msb (hash-bit) and set LO_/HI_int indicator */
+    if ((lo_hi_ind = (irqPrioTable [irqLine] >> 3))) {
+
+      /* set critical HI_int priority */
+      reg = (uint32_t *) (&(mpc5200.crit_pri_main_mask));
+      *reg |= (irqPrioTable [BSP_SIU_IRQ_HI_INT] << 26);
+
+      /*
+       * critical interrupt handling for the 603le core is not
+       * yet supported, routing of critical interrupts is forced
+       * to core_int (bit 31 / CEb)
+       */
+      mpc5200.ext_en_type |= 1;
+
+    } else {
+      if (irqPrioTable [irqLine] <= 15) {
+        /* set main LO_int priority */
+        reg = (uint32_t *) (&(mpc5200.main_pri_1));
+        *reg |= (irqPrioTable [BSP_SIU_IRQ_LO_INT] << 16);
+      }
+    }
+  }
+
+  /* if LO_int ind., enable (unmask) main interrupt */
+  if (!lo_hi_ind) {
+    mpc5200.crit_pri_main_mask &=
+      ~(0x80000000 >> SIU_MaskBit [BSP_SIU_IRQ_LO_INT]);
+  }
+
+  /* enable (unmask) peripheral interrupt */
+  mpc5200.per_mask &= ~(0x80000000 >> SIU_MaskBit [irqLine]);
+
+  /* FIXME: Why? */
+  mpc5200.main_pri_1;
+  mpc5200.crit_pri_main_mask;
+  mpc5200.per_pri_1;
+  mpc5200.per_mask;
+}
+
+static inline void BSP_enable_main_irq_at_siu(
+  rtems_vector_number irqLine
+)
+{
+
+  uint8_t prio_index_offset;
+  uint32_t *reg;
+
+  /* calculate the index offset of priority value bit field */
+  prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8;
+
+  /* set main interrupt priority */
+  if (irqPrioTable [irqLine] <= 15) {
+
+    /* set main int priority */
+    reg = (uint32_t *) (&(mpc5200.main_pri_1));
+
+    /* choose proper register */
+    reg += (irqLine >> 3);
+
+    /* set priority as given in priority table */
+    *reg |= (irqPrioTable [irqLine] << (28 - (prio_index_offset << 2)));
+
+    if ((irqLine >= BSP_SIU_IRQ_IRQ1) && (irqLine <= BSP_SIU_IRQ_IRQ3)) {
+      /* enable external irq-pin */
+      mpc5200.ext_en_type |= (0x80000000 >> (20 + prio_index_offset));
+    }
+  }
+
+  /* enable (unmask) main interrupt */
+  mpc5200.crit_pri_main_mask &= ~(0x80000000 >> SIU_MaskBit [irqLine]);
+
+}
+
+static inline void BSP_enable_crit_irq_at_siu(
+  rtems_vector_number irqLine
+)
+{
+  uint8_t prio_index_offset;
+  uint32_t *reg;
+
+  prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+  /*
+   * critical interrupt handling for the 603Le core is not
+   * yet supported, routing of critical interrupts is forced
+   * to core_int (bit 31 / CEb)
+   */
+  mpc5200.ext_en_type |= 1;
+
+  /* set critical interrupt priorities */
+  if (irqPrioTable [irqLine] <= 3) {
+
+    /* choose proper register */
+    reg = (uint32_t *) (&(mpc5200.crit_pri_main_mask));
+
+    /* set priority as given in priority table */
+    *reg |= (irqPrioTable [irqLine] << (30 - (prio_index_offset << 1)));
+
+    /* external irq0-pin */
+    if (irqLine == BSP_SIU_IRQ_IRQ1) {
+      /* enable external irq-pin */
+      mpc5200.ext_en_type |= (0x80000000 >> (20 + prio_index_offset));
+    }
+  }
+}
+
+static inline void BSP_disable_per_irq_at_siu(
+  rtems_vector_number irqLine
+)
+{
+  uint8_t prio_index_offset;
+  uint32_t *reg;
+
+  /* calculate the index offset of priority value bit field */
+  prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8;
+
+  /* disable (mask) peripheral interrupt */
+  mpc5200.per_mask |= (0x80000000 >> SIU_MaskBit [irqLine]);
+
+  /* reset priority to lowest level (reset value) */
+  reg = (uint32_t *) (&(mpc5200.per_pri_1));
+  reg += (irqLine >> 3);
+  *reg &= ~(15 << (28 - (prio_index_offset << 2)));
+}
+
+static inline void BSP_disable_main_irq_at_siu(
+  rtems_vector_number irqLine
+)
+{
+  uint8_t prio_index_offset;
+  uint32_t *reg;
+
+  /* calculate the index offset of priority value bit field */
+  prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8;
+
+  /* disable (mask) main interrupt */
+  mpc5200.crit_pri_main_mask |= (0x80000000 >> SIU_MaskBit [irqLine]);
+
+  if ((irqLine >= BSP_SIU_IRQ_IRQ1) && (irqLine <= BSP_SIU_IRQ_IRQ3)) {
+    /* disable external irq-pin */
+    mpc5200.ext_en_type &= ~(0x80000000 >> (20 + prio_index_offset));
+  }
+
+  /* reset priority to lowest level (reset value) */
+  reg = (uint32_t *) (&(mpc5200.main_pri_1));
+  reg += (irqLine >> 3);
+  *reg &= ~(15 << (28 - (prio_index_offset << 2)));
+}
+
+static inline void BSP_disable_crit_irq_at_siu( rtems_vector_number
+                                               irqLine)
+{
+  uint8_t prio_index_offset;
+  uint32_t *reg;
+
+  prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+  /* reset critical int priority to lowest level (reset value) */
+  reg = (uint32_t *) (&(mpc5200.crit_pri_main_mask));
+  *reg &= ~(3 << (30 - (prio_index_offset << 1)));
+
+  if (irqLine == BSP_SIU_IRQ_IRQ1) {
+    /* disable external irq0-pin */
+    mpc5200.ext_en_type &= ~(0x80000000 >> (20 + prio_index_offset));
+  }
+}
+
+/*
+ * This function enables a given siu interrupt
+ */
+void bsp_interrupt_vector_enable( rtems_vector_number vector)
+{
+  int base_index = get_siu_irq_base_index( vector);
+
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (is_siu_irq( vector)) {
+    rtems_interrupt_level level;
+
+    rtems_interrupt_disable( level);
+
+    switch (base_index) {
+      case BSP_PER_IRQ_LOWEST_OFFSET:
+        BSP_enable_per_irq_at_siu( vector);
+        break;
+      case BSP_MAIN_IRQ_LOWEST_OFFSET:
+        BSP_enable_main_irq_at_siu( vector);
+        break;
+      case BSP_CRIT_IRQ_LOWEST_OFFSET:
+        BSP_enable_crit_irq_at_siu( vector);
+        break;
+      default:
+        bsp_interrupt_assert(0);
+        break;
+    }
+
+    rtems_interrupt_enable( level);
+  }
+}
+
+/*
+ * This function disables a given siu interrupt
+ */
+void bsp_interrupt_vector_disable( rtems_vector_number vector)
+{
+  int base_index = get_siu_irq_base_index( vector);
+
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (is_siu_irq( vector)) {
+    rtems_interrupt_level level;
+
+    rtems_interrupt_disable( level);
+
+    switch (base_index) {
+      case BSP_PER_IRQ_LOWEST_OFFSET:
+        BSP_disable_per_irq_at_siu( vector);
+        break;
+      case BSP_MAIN_IRQ_LOWEST_OFFSET:
+        BSP_disable_main_irq_at_siu( vector);
+        break;
+      case BSP_CRIT_IRQ_LOWEST_OFFSET:
+        BSP_disable_crit_irq_at_siu( vector);
+        break;
+      default:
+        bsp_interrupt_assert(0);
+        break;
+    }
+
+    rtems_interrupt_enable( level);
+  }
+}
+
+#if (BENCHMARK_IRQ_PROCESSING == 0)
+void BSP_IRQ_Benchmarking_Reset( void)
+{
+}
+void BSP_IRQ_Benchmarking_Report( void)
+{
+}
+#else
+#include <stdio.h>
+uint64_t BSP_Starting_TBR;
+uint64_t BSP_Total_in_ISR;
+uint32_t BSP_ISR_Count;
+uint32_t BSP_Worst_ISR;
+
+#define BSP_COUNTED_IRQ 16
+uint32_t BSP_ISR_Count_Per [BSP_COUNTED_IRQ + 1];
+
+void BSP_IRQ_Benchmarking_Reset( void)
+{
+  int i;
+
+  BSP_Starting_TBR = PPC_Get_timebase_register();
+  BSP_Total_in_ISR = 0;
+  BSP_ISR_Count = 0;
+  BSP_Worst_ISR = 0;
+  for (i = 0; i < BSP_COUNTED_IRQ; i++)
+    BSP_ISR_Count_Per [i] = 0;
+}
+
+static const char *u64tostring( char *buffer, uint64_t v)
+{
+  sprintf( buffer, "%lld cycles %lld usecs", v, (v / 33));
+  return buffer;
+}
+
+void BSP_IRQ_Benchmarking_Report( void)
+{
+  uint64_t now;
+  char buffer [96];
+  int i;
+
+  now = PPC_Get_timebase_register();
+  printk( "Started at: %s\n", u64tostring( buffer, BSP_Starting_TBR));
+  printk( "Current   : %s\n", u64tostring( buffer, now));
+  printk( "System up : %s\n", u64tostring( buffer, now - BSP_Starting_TBR));
+  printk( "ISRs      : %d\n", BSP_ISR_Count);
+  printk( "ISRs ran  : %s\n", u64tostring( buffer, BSP_Total_in_ISR));
+  printk( "Worst ISR : %s\n", u64tostring( buffer, BSP_Worst_ISR));
+  for (i = 0; i < BSP_COUNTED_IRQ; i++)
+    printk( "IRQ %d: %d\n", i, BSP_ISR_Count_Per [i]);
+  printk( "Ticks     : %d\n", Clock_driver_ticks);
+}
+#endif
+
+static void dispatch(uint32_t irq, uint32_t offset, volatile uint32_t *maskreg)
+{
+  #if (ALLOW_IRQ_NESTING == 1)
+    uint32_t msr;
+    uint32_t mask = *maskreg;
+  #endif
+
+  irq += offset;
+
+  #if (ALLOW_IRQ_NESTING == 1)
+    *maskreg = mask | irqMaskTable [irq];
+    /* Make sure that the write operation completed (cache inhibited area) */
+    *maskreg;
+    msr = ppc_external_exceptions_enable();
+  #endif
+
+  bsp_interrupt_handler_dispatch(irq);
+
+  #if (ALLOW_IRQ_NESTING == 1)
+    ppc_external_exceptions_disable(msr);
+    *maskreg = mask;
+  #endif
+}
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+static int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum)
+{
+  uint32_t irq;
+  uint32_t pmce;
+
+#if (BENCHMARK_IRQ_PROCESSING == 1)
+  uint64_t start,
+    stop,
+    thisTime;
+
+  start = PPC_Get_timebase_register();
+  BSP_ISR_Count++;
+  if (excNum < BSP_COUNTED_IRQ)
+    BSP_ISR_Count_Per [excNum]++;
+  else
+    printk( "not counting %d\n", excNum);
+#endif
+
+  /* get the content of main interrupt status register */
+  pmce = mpc5200.pmce;
+
+  /* critical interrupts are routed to the core_int, see premature
+   * initialization
+   */
+  while ((pmce & (PMCE_CSE_STICKY | PMCE_MSE_STICKY)) != 0) {
+    /* first: check for critical interrupt sources (hierarchical order)
+     * -> HI_int indicates peripheral sources
+     */
+    if ((pmce & PMCE_CSE_STICKY) != 0) {
+      /* get source of critical interrupt */
+      irq = PMCE_CSE_SOURCE(pmce);
+
+      switch (irq) {
+          /* peripheral HI_int interrupt source detected */
+        case 2:
+          /* check for valid peripheral interrupt source */
+          if ((pmce & PMCE_PSE_STICKY) != 0) {
+            /* get source of peripheral interrupt */
+            irq = PMCE_PSE_SOURCE(pmce);
+
+            dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask);
+          } else {
+            /* this case may not occur: no valid peripheral
+             * interrupt source */
+            printk( "No valid peripheral HI_int interrupt source\n");
+          }
+          break;
+
+          /* irq0, slice timer 1 or ccs wakeup detected */
+        case 0:
+        case 1:
+        case 3:
+
+          /* add proper offset for critical interrupts in the siu
+           * handler array */
+          irq += BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+          /* Dispatch interrupt handlers */
+          bsp_interrupt_handler_dispatch( irq);
+
+          break;
+
+        default:
+          /* error: unknown interrupt source */
+          printk( "Unknown HI_int interrupt source\n");
+          break;
+      }
+    }
+
+    /* second: check for main interrupt sources (hierarchical order)
+     * -> LO_int indicates peripheral sources */
+    if ((pmce & PMCE_MSE_STICKY) != 0) {
+      /* get source of main interrupt */
+      irq = PMCE_MSE_SOURCE(pmce);
+
+      if (irq == 4) {
+          /* peripheral LO_int interrupt source detected */
+          /* check for valid peripheral interrupt source */
+          if ((pmce & PMCE_PSE_STICKY) != 0) {
+            /* get source of peripheral interrupt */
+            irq = PMCE_PSE_SOURCE(pmce);
+
+            dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask);
+          } else {
+            /* this case may not occur: no valid peripheral
+             * interrupt source */
+            printk( "No valid peripheral LO_int interrupt source\n");
+          }
+      } else if (irq <= 16) {
+          /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer
+           * 2 is always routed to SMI) */
+          dispatch(irq, BSP_MAIN_IRQ_LOWEST_OFFSET, &mpc5200.crit_pri_main_mask);
+      } else {
+          /* error: unknown interrupt source */
+          printk( "Unknown peripheral LO_int interrupt source\n");
+      }
+    }
+
+    /* force re-evaluation of interrupts */
+    mpc5200.pmce = PMCE_CSE_STICKY | PMCE_MSE_STICKY | PMCE_PSE_STICKY;
+
+    /* get the content of main interrupt status register */
+    pmce = mpc5200.pmce;
+  }
+
+#if (BENCHMARK_IRQ_PROCESSING == 1)
+  stop = PPC_Get_timebase_register();
+  thisTime = stop - start;
+  BSP_Total_in_ISR += thisTime;
+  if (thisTime > BSP_Worst_ISR)
+    BSP_Worst_ISR = thisTime;
+#endif
+
+  return 0;
+}
+
+/*
+ * setup irqMaskTable to support a priorized/nested interrupt environment
+ */
+static void setup_irqMaskTable( void)
+{
+  rtems_irq_prio prio = 0;
+  uint32_t i = 0,
+    j = 0,
+    mask = 0;
+
+  /* set up the priority dependent masks for peripheral interrupts */
+  for (i = BSP_PER_IRQ_LOWEST_OFFSET; i <= BSP_PER_IRQ_MAX_OFFSET; i++) {
+    prio = irqPrioTable [i];
+    mask = 0;
+
+    for (j = BSP_PER_IRQ_LOWEST_OFFSET; j <= BSP_PER_IRQ_MAX_OFFSET; j++) {
+      if (prio > irqPrioTable [j]) {
+        mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET));
+      }
+
+      if ((prio == irqPrioTable [j]) && (j >= i)) {
+        mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET));
+      }
+    }
+
+    irqMaskTable [i] = mask;
+  }
+
+  /* set up the priority dependent masks for main interrupts */
+  for (i = BSP_MAIN_IRQ_LOWEST_OFFSET; i <= BSP_MAIN_IRQ_MAX_OFFSET; i++) {
+    prio = irqPrioTable [i];
+    mask = 0;
+
+    for (j = BSP_MAIN_IRQ_LOWEST_OFFSET; j <= BSP_MAIN_IRQ_MAX_OFFSET; j++) {
+      if (prio > irqPrioTable [j]) {
+        mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET));
+      }
+
+      if ((prio == irqPrioTable [j]) && (j >= i)) {
+        mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET));
+      }
+    }
+
+    irqMaskTable [i] = mask;
+  }
+}
+
+/*
+ * Initialize MPC5x00 SIU interrupt management
+ */
+static void BSP_SIU_irq_init( void)
+{
+
+  /* disable all peripheral interrupts */
+  mpc5200.per_mask = 0xFFFFFC00;
+
+  /* peripheral interrupt priorities according to reset value */
+  mpc5200.per_pri_1 = 0xF0000000;
+  mpc5200.per_pri_2 = 0x00000000;
+  mpc5200.per_pri_3 = 0x00000000;
+
+  /* disable external interrupts IRQ0-4 / critical interrupts are routed to core_int */
+  mpc5200.ext_en_type = 0x0F000001;
+
+  /* disable main interrupts / crit. int. priorities according to reset values */
+  mpc5200.crit_pri_main_mask = 0x0001FFFF;
+
+  /* main priorities according to reset value */
+  mpc5200.main_pri_1 = 0;
+  mpc5200.main_pri_2 = 0;
+
+  /* reset all status indicators */
+  mpc5200.csa = 0x0001FFFF;
+  mpc5200.msa = 0x0001FFFF;
+  mpc5200.psa = 0x003FFFFF;
+  mpc5200.psa_be = 0x03000000;
+
+  setup_irqMaskTable();
+}
+
+rtems_status_code bsp_interrupt_facility_initialize( void)
+{
+  BSP_SIU_irq_init();
+
+  /* Install exception handler */
+  if (ppc_exc_set_handler( ASM_EXT_VECTOR, C_dispatch_irq_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+  if (ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, C_dispatch_irq_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
+
+void bsp_interrupt_handler_default( rtems_vector_number vector)
+{
+  if (vector != BSP_DECREMENTER) {
+    printk( "Spurious interrupt: 0x%08" PRIx32 "\n", vector);
+  }
+}
Index: bsps/powerpc/gen83xx/irq/irq.c
===================================================================
--- bsps/powerpc/gen83xx/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/gen83xx/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,596 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC83xx BSP                              |
++-----------------------------------------------------------------+
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file integrates the IPIC irq controller                    |
+\*===============================================================*/
+
+#include <mpc83xx/mpc83xx.h>
+
+#include <rtems.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <bsp/vectors.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#define MPC83XX_IPIC_VECTOR_NUMBER 92
+
+#define MPC83XX_IPIC_IS_VALID_VECTOR( vector) ((vector) >= 0 && (vector) < MPC83XX_IPIC_VECTOR_NUMBER)
+
+#define MPC83XX_IPIC_INVALID_MASK_POSITION 255
+
+typedef struct {
+  volatile uint32_t *pend_reg;
+  volatile uint32_t *mask_reg;
+  const uint32_t bit_num;
+} BSP_isrc_rsc_t;
+
+/*
+ * data structure to handle all mask registers in the IPIC
+ *
+ * Mask positions:
+ *   simsr [0] :  0 .. 31
+ *   simsr [1] : 32 .. 63
+ *   semsr     : 64 .. 95
+ *   sermr     : 96 .. 127
+ */
+typedef struct {
+  uint32_t simsr_mask [2];
+  uint32_t semsr_mask;
+  uint32_t sermr_mask;
+} mpc83xx_ipic_mask_t;
+
+static const BSP_isrc_rsc_t mpc83xx_ipic_isrc_rsc [MPC83XX_IPIC_VECTOR_NUMBER] = {
+  /* vector 0 */
+  {&mpc83xx.ipic.sersr, &mpc83xx.ipic.sermr, 31},
+  {NULL, NULL, 0},
+  {NULL, NULL, 0},
+  {NULL, NULL, 0},
+  {NULL, NULL, 0},
+  {NULL, NULL, 0},
+  {NULL, NULL, 0},
+  {NULL, NULL, 0},
+  /* vector  8 */
+  {NULL, NULL, 0},  /* reserved vector  8 */
+  /* vector  9: UART1 SIxxR_H, Bit 24 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 24},
+  /* vector 10: UART2 SIxxR_H, Bit 25 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 25},
+  /* vector 11: SEC   SIxxR_H, Bit 26 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 26},
+  {NULL, NULL, 0},  /* reserved vector 12 */
+  {NULL, NULL, 0},  /* reserved vector 13 */
+  /* vector 14: I2C1 SIxxR_H, Bit 29 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 29},
+  /* vector 15: I2C2 SIxxR_H, Bit 30 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 30},
+  /* vector 16: SPI  SIxxR_H, Bit 31 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 31},
+  /* vector 17: IRQ1 SExxR  , Bit  1 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 1},
+  /* vector 18: IRQ2 SExxR  , Bit  2 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 2},
+  /* vector 19: IRQ3 SExxR  , Bit  3 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 3},
+  /* vector 20: IRQ4 SExxR  , Bit  4 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 4},
+  /* vector 21: IRQ5 SExxR  , Bit  5 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 5},
+  /* vector 22: IRQ6 SExxR  , Bit  6 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 6},
+  /* vector 23: IRQ7 SExxR  , Bit  7 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 7},
+  {NULL, NULL, 0},  /* reserved vector 24 */
+  {NULL, NULL, 0},  /* reserved vector 25 */
+  {NULL, NULL, 0},  /* reserved vector 26 */
+  {NULL, NULL, 0},  /* reserved vector 27 */
+  {NULL, NULL, 0},  /* reserved vector 28 */
+  {NULL, NULL, 0},  /* reserved vector 29 */
+  {NULL, NULL, 0},  /* reserved vector 30 */
+  {NULL, NULL, 0},  /* reserved vector 31 */
+  /* vector 32: TSEC1 Tx  SIxxR_H  , Bit  0 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 0},
+  /* vector 33: TSEC1 Rx  SIxxR_H  , Bit  1 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 1},
+  /* vector 34: TSEC1 Err SIxxR_H  , Bit  2 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 2},
+  /* vector 35: TSEC2 Tx  SIxxR_H  , Bit  3 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 3},
+  /* vector 36: TSEC2 Rx  SIxxR_H  , Bit  4 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 4},
+  /* vector 37: TSEC2 Err SIxxR_H  , Bit  5 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 5},
+  /* vector 38: USB DR    SIxxR_H  , Bit  6 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 6},
+  /* vector 39: USB MPH   SIxxR_H  , Bit  7 */
+  {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 7},
+  {NULL, NULL, 0},  /* reserved vector 40 */
+  {NULL, NULL, 0},  /* reserved vector 41 */
+  {NULL, NULL, 0},  /* reserved vector 42 */
+  {NULL, NULL, 0},  /* reserved vector 43 */
+  {NULL, NULL, 0},  /* reserved vector 44 */
+  {NULL, NULL, 0},  /* reserved vector 45 */
+  {NULL, NULL, 0},  /* reserved vector 46 */
+  {NULL, NULL, 0},  /* reserved vector 47 */
+  /* vector 48: IRQ0 SExxR  , Bit  0 */
+  {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 0},
+  {NULL, NULL, 0},  /* reserved vector 49 */
+  {NULL, NULL, 0},  /* reserved vector 50 */
+  {NULL, NULL, 0},  /* reserved vector 51 */
+  {NULL, NULL, 0},  /* reserved vector 52 */
+  {NULL, NULL, 0},  /* reserved vector 53 */
+  {NULL, NULL, 0},  /* reserved vector 54 */
+  {NULL, NULL, 0},  /* reserved vector 55 */
+  {NULL, NULL, 0},  /* reserved vector 56 */
+  {NULL, NULL, 0},  /* reserved vector 57 */
+  {NULL, NULL, 0},  /* reserved vector 58 */
+  {NULL, NULL, 0},  /* reserved vector 59 */
+  {NULL, NULL, 0},  /* reserved vector 60 */
+  {NULL, NULL, 0},  /* reserved vector 61 */
+  {NULL, NULL, 0},  /* reserved vector 62 */
+  {NULL, NULL, 0},  /* reserved vector 63 */
+  /* vector 64: RTC SEC   SIxxR_L  , Bit  0 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 0},
+  /* vector 65: PIT       SIxxR_L  , Bit  1 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 1},
+  /* vector 66: PCI1      SIxxR_L  , Bit  2 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 2},
+  /* vector 67: PCI2      SIxxR_L  , Bit  3 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 3},
+  /* vector 68: RTC ALR   SIxxR_L  , Bit  4 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 4},
+  /* vector 69: MU        SIxxR_L  , Bit  5 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 5},
+  /* vector 70: SBA       SIxxR_L  , Bit  6 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 6},
+  /* vector 71: DMA       SIxxR_L  , Bit  7 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 7},
+  /* vector 72: GTM4      SIxxR_L  , Bit  8 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 8},
+  /* vector 73: GTM8      SIxxR_L  , Bit  9 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 9},
+  /* vector 74: GPIO1     SIxxR_L  , Bit 10 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 10},
+  /* vector 75: GPIO2     SIxxR_L  , Bit 11 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 11},
+  /* vector 76: DDR       SIxxR_L  , Bit 12 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 12},
+  /* vector 77: LBC       SIxxR_L  , Bit 13 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 13},
+  /* vector 78: GTM2      SIxxR_L  , Bit 14 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 14},
+  /* vector 79: GTM6      SIxxR_L  , Bit 15 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 15},
+  /* vector 80: PMC       SIxxR_L  , Bit 16 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 16},
+  {NULL, NULL, 0},  /* reserved vector 81 */
+  {NULL, NULL, 0},  /* reserved vector 82 */
+  {NULL, NULL, 0},  /* reserved vector 63 */
+  /* vector 84: GTM3      SIxxR_L  , Bit 20 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 20},
+  /* vector 85: GTM7      SIxxR_L  , Bit 21 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 21},
+  {NULL, NULL, 0},  /* reserved vector 81 */
+  {NULL, NULL, 0},  /* reserved vector 82 */
+  {NULL, NULL, 0},  /* reserved vector 63 */
+  {NULL, NULL, 0},  /* reserved vector 63 */
+  /* vector 90: GTM1      SIxxR_L  , Bit 26 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 26},
+  /* vector 91: GTM5      SIxxR_L  , Bit 27 */
+  {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 27}
+};
+
+static const uint8_t
+    mpc83xx_ipic_mask_position_table [MPC83XX_IPIC_VECTOR_NUMBER] = {
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  7,
+  6,
+  5,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  2,
+  1,
+  0,
+  94,
+  93,
+  92,
+  91,
+  90,
+  89,
+  88,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  31,
+  30,
+  29,
+  28,
+  27,
+  26,
+  25,
+  24,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  95,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  63,
+  62,
+  61,
+  60,
+  59,
+  58,
+  57,
+  56,
+  55,
+  54,
+  53,
+  52,
+  51,
+  50,
+  49,
+  48,
+  47,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  43,
+  42,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  MPC83XX_IPIC_INVALID_MASK_POSITION,
+  37,
+  36
+};
+
+/*
+ * this array will be filled with mask values needed
+ * to temporarily disable all IRQ soures with lower or same
+ * priority of the current source (whose vector is the array index)
+ */
+static mpc83xx_ipic_mask_t mpc83xx_ipic_prio2mask [MPC83XX_IPIC_VECTOR_NUMBER];
+
+rtems_status_code mpc83xx_ipic_set_mask(
+  rtems_vector_number vector,
+  rtems_vector_number mask_vector,
+  bool mask
+)
+{
+  uint8_t pos = 0;
+  mpc83xx_ipic_mask_t *mask_entry;
+  uint32_t *mask_reg;
+  rtems_interrupt_level level;
+
+  /* Parameter check */
+  if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector) ||
+      !MPC83XX_IPIC_IS_VALID_VECTOR( mask_vector)) {
+    return RTEMS_INVALID_NUMBER;
+  } else if (vector == mask_vector) {
+    return RTEMS_RESOURCE_IN_USE;
+  }
+
+  /* Position and mask entry */
+  pos = mpc83xx_ipic_mask_position_table [mask_vector];
+  mask_entry = &mpc83xx_ipic_prio2mask [vector];
+
+  /* Mask register and position */
+  if (pos < 32) {
+    mask_reg = &mask_entry->simsr_mask [0];
+  } else if (pos < 64) {
+    pos -= 32;
+    mask_reg = &mask_entry->simsr_mask [1];
+  } else if (pos < 96) {
+    pos -= 64;
+    mask_reg = &mask_entry->semsr_mask;
+  } else if (pos < 128) {
+    pos -= 96;
+    mask_reg = &mask_entry->sermr_mask;
+  } else {
+    return RTEMS_NOT_IMPLEMENTED;
+  }
+
+  /* Mask or unmask */
+  if (mask) {
+    rtems_interrupt_disable( level);
+    *mask_reg &= ~(1 << pos);
+    rtems_interrupt_enable( level);
+  } else {
+    rtems_interrupt_disable( level);
+    *mask_reg |= 1 << pos;
+    rtems_interrupt_enable( level);
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code mpc83xx_ipic_set_highest_priority_interrupt(
+  rtems_vector_number vector,
+  int type
+)
+{
+  rtems_interrupt_level level;
+  uint32_t reg = 0;
+
+  if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector)) {
+    return RTEMS_INVALID_NUMBER;
+  } else if (type < 0 || type > MPC83XX_IPIC_INTERRUPT_CRITICAL) {
+    return RTEMS_INVALID_NUMBER;
+  }
+
+  rtems_interrupt_disable( level);
+  reg = mpc83xx.ipic.sicfr;
+  mpc83xx.ipic.sicfr = (reg & ~0x7f000300) | (vector << 24) | (type << 8);
+  rtems_interrupt_enable( level);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * functions to enable/disable a source at the ipic
+ */
+void bsp_interrupt_vector_enable( rtems_vector_number vector)
+{
+  rtems_vector_number vecnum = vector - BSP_IPIC_IRQ_LOWEST_OFFSET;
+  const BSP_isrc_rsc_t *rsc_ptr;
+
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
+    rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
+    if (rsc_ptr->mask_reg != NULL) {
+      uint32_t bit = 1U << (31 - rsc_ptr->bit_num);
+      rtems_interrupt_level level;
+
+      rtems_interrupt_disable(level);
+      *(rsc_ptr->mask_reg) |= bit;
+      rtems_interrupt_enable(level);
+    }
+  }
+}
+
+void bsp_interrupt_vector_disable( rtems_vector_number vector)
+{
+  rtems_vector_number vecnum = vector - BSP_IPIC_IRQ_LOWEST_OFFSET;
+  const BSP_isrc_rsc_t *rsc_ptr;
+
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
+    rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
+    if (rsc_ptr->mask_reg != NULL) {
+      uint32_t bit = 1U << (31 - rsc_ptr->bit_num);
+      rtems_interrupt_level level;
+
+      rtems_interrupt_disable(level);
+      *(rsc_ptr->mask_reg) &= ~bit;
+      rtems_interrupt_enable(level);
+    }
+  }
+}
+
+/*
+ *  IRQ Handler: this is called from the primary exception dispatcher
+ */
+static int BSP_irq_handle_at_ipic( unsigned excNum)
+{
+  int32_t vecnum;
+#ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
+  mpc83xx_ipic_mask_t mask_save;
+  const mpc83xx_ipic_mask_t *mask_ptr;
+  uint32_t msr = 0;
+  rtems_interrupt_level level;
+#endif
+
+  /* Get vector number */
+  switch (excNum) {
+    case ASM_EXT_VECTOR:
+      vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.sivcr);
+      break;
+    case ASM_E300_SYSMGMT_VECTOR:
+      vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.smvcr);
+      break;
+    case ASM_E300_CRIT_VECTOR:
+      vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.scvcr);
+      break;
+    default:
+      return 1;
+  }
+
+  /*
+   * Check the vector number, mask lower priority interrupts, enable
+   * exceptions and dispatch the handler.
+   */
+  if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
+#ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
+    mask_ptr = &mpc83xx_ipic_prio2mask [vecnum];
+
+    rtems_interrupt_disable( level);
+
+    /* Save current mask registers */
+    mask_save.simsr_mask [0] = mpc83xx.ipic.simsr [0];
+    mask_save.simsr_mask [1] = mpc83xx.ipic.simsr [1];
+    mask_save.semsr_mask = mpc83xx.ipic.semsr;
+    mask_save.sermr_mask = mpc83xx.ipic.sermr;
+
+    /* Mask all lower priority interrupts */
+    mpc83xx.ipic.simsr [0] &= mask_ptr->simsr_mask [0];
+    mpc83xx.ipic.simsr [1] &= mask_ptr->simsr_mask [1];
+    mpc83xx.ipic.semsr &= mask_ptr->semsr_mask;
+    mpc83xx.ipic.sermr &= mask_ptr->sermr_mask;
+
+    rtems_interrupt_enable( level);
+
+    /* Enable all interrupts */
+    if (excNum != ASM_E300_CRIT_VECTOR) {
+      msr = ppc_external_exceptions_enable();
+    }
+#endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */
+
+    /* Dispatch interrupt handlers */
+    bsp_interrupt_handler_dispatch( vecnum + BSP_IPIC_IRQ_LOWEST_OFFSET);
+
+#ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
+    /* Restore machine state */
+    if (excNum != ASM_E300_CRIT_VECTOR) {
+      ppc_external_exceptions_disable( msr);
+    }
+
+    /* Restore initial masks */
+    rtems_interrupt_disable( level);
+    mpc83xx.ipic.simsr [0] = mask_save.simsr_mask [0];
+    mpc83xx.ipic.simsr [1] = mask_save.simsr_mask [1];
+    mpc83xx.ipic.semsr = mask_save.semsr_mask;
+    mpc83xx.ipic.sermr = mask_save.sermr_mask;
+    rtems_interrupt_enable( level);
+#endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */
+  } else {
+    bsp_interrupt_handler_default( vecnum);
+  }
+
+  return 0;
+}
+
+/*
+ * Fill the array mpc83xx_ipic_prio2mask to allow masking of lower prio sources
+ * to implement nested interrupts.
+ */
+static rtems_status_code mpc83xx_ipic_calc_prio2mask(void)
+{
+  rtems_status_code rc = RTEMS_SUCCESSFUL;
+
+  /*
+   * FIXME: fill the array
+   */
+  return rc;
+}
+
+/*
+ * Activate the interrupt controller
+ */
+static rtems_status_code mpc83xx_ipic_initialize(void)
+{
+  /*
+   * mask off all interrupts
+   */
+  mpc83xx.ipic.simsr [0] = 0;
+  mpc83xx.ipic.simsr [1] = 0;
+  mpc83xx.ipic.semsr = 0;
+  mpc83xx.ipic.sermr = 0;
+  /*
+   * set desired configuration as defined in bspopts.h
+   * normally, the default values should be fine
+   */
+#if defined( BSP_SICFR_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.sicfr = BSP_SICFR_VAL;
+#endif
+
+  /*
+   * set desired priorities as defined in bspopts.h
+   * normally, the default values should be fine
+   */
+#if defined( BSP_SIPRR0_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.siprr [0] = BSP_SIPRR0_VAL;
+#endif
+
+#if defined( BSP_SIPRR1_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.siprr [1] = BSP_SIPRR1_VAL;
+#endif
+
+#if defined( BSP_SIPRR2_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.siprr [2] = BSP_SIPRR2_VAL;
+#endif
+
+#if defined( BSP_SIPRR3_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.siprr [3] = BSP_SIPRR3_VAL;
+#endif
+
+#if defined( BSP_SMPRR0_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.smprr [0] = BSP_SMPRR0_VAL;
+#endif
+
+#if defined( BSP_SMPRR1_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.smprr [1] = BSP_SMPRR1_VAL;
+#endif
+
+#if defined( BSP_SECNR_VAL)  /* defined in bspopts.h ? */
+  mpc83xx.ipic.secnr = BSP_SECNR_VAL;
+#endif
+
+  /*
+   * calculate priority masks
+   */
+  return mpc83xx_ipic_calc_prio2mask();
+}
+
+static int mpc83xx_exception_handler(
+  BSP_Exception_frame *frame,
+  unsigned exception_number
+)
+{
+  return BSP_irq_handle_at_ipic( exception_number);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize()
+{
+  /* Install exception handler */
+  if (ppc_exc_set_handler( ASM_EXT_VECTOR, mpc83xx_exception_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+  if (ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, mpc83xx_exception_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+  if (ppc_exc_set_handler( ASM_E300_CRIT_VECTOR, mpc83xx_exception_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+
+  /* Initialize the interrupt controller */
+  return mpc83xx_ipic_initialize();
+}
Index: bsps/powerpc/haleakala/irq/irq.c
===================================================================
--- bsps/powerpc/haleakala/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/haleakala/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,237 @@
+/*
+ *
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Middleware support for PPC405 by M.Hamel ADInstruments Ltd 2008
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq_supp.h>
+#include <bsp/vectors.h>
+#include <libcpu/powerpc-utility.h>
+
+
+/* PPC405EX UIC numbers */
+#define UIC_DCR_BASE 0xc0
+#define UIC0_SR      (UIC_DCR_BASE+0x0)  /* UIC status                       */
+#define UIC0_SRS     (UIC_DCR_BASE+0x1)  /* UIC status set                   */
+#define UIC0_ER      (UIC_DCR_BASE+0x2)  /* UIC enable                       */
+#define UIC0_CR      (UIC_DCR_BASE+0x3)  /* UIC critical                     */
+#define UIC0_PR      (UIC_DCR_BASE+0x4)  /* UIC polarity                     */
+#define UIC0_TR      (UIC_DCR_BASE+0x5)  /* UIC triggering                   */
+#define UIC0_MSR     (UIC_DCR_BASE+0x6)  /* UIC masked status                */
+#define UIC0_VR      (UIC_DCR_BASE+0x7)  /* UIC vector                       */
+#define UIC0_VCR     (UIC_DCR_BASE+0x8)  /* UIC vector configuration         */
+
+#define UIC1_SR      (UIC_DCR_BASE+0x10)  /* UIC status                       */
+#define UIC1_SRS     (UIC_DCR_BASE+0x11)  /* UIC status set                   */
+#define UIC1_ER      (UIC_DCR_BASE+0x12)  /* UIC enable                       */
+#define UIC1_CR      (UIC_DCR_BASE+0x13)  /* UIC critical                     */
+#define UIC1_PR      (UIC_DCR_BASE+0x14)  /* UIC polarity                     */
+#define UIC1_TR      (UIC_DCR_BASE+0x15)  /* UIC triggering                   */
+#define UIC1_MSR     (UIC_DCR_BASE+0x16)  /* UIC masked status                */
+#define UIC1_VR      (UIC_DCR_BASE+0x17)  /* UIC vector                       */
+#define UIC1_VCR     (UIC_DCR_BASE+0x18)  /* UIC vector configuration         */
+
+#define UIC2_SR      (UIC_DCR_BASE+0x20)  /* UIC status                       */
+#define UIC2_SRS     (UIC_DCR_BASE+0x21)  /* UIC status set                   */
+#define UIC2_ER      (UIC_DCR_BASE+0x22)  /* UIC enable                       */
+#define UIC2_CR      (UIC_DCR_BASE+0x23)  /* UIC critical                     */
+#define UIC2_PR      (UIC_DCR_BASE+0x24)  /* UIC polarity                     */
+#define UIC2_TR      (UIC_DCR_BASE+0x25)  /* UIC triggering                   */
+#define UIC2_MSR     (UIC_DCR_BASE+0x26)  /* UIC masked status                */
+#define UIC2_VR      (UIC_DCR_BASE+0x27)  /* UIC vector                       */
+#define UIC2_VCR     (UIC_DCR_BASE+0x28)  /* UIC vector configuration         */
+
+enum { kUICWords = 3 };
+
+static rtems_irq_connect_data* rtems_hdl_tblP;
+static rtems_irq_connect_data  dflt_entry;
+
+static uint32_t	gEnabledInts[kUICWords];		/* 1-bits mean enabled */
+static uint32_t	gIntInhibited[kUICWords];		/* 1-bits disable, overriding gEnabledInts because the interrupt
+												   is being processed in C_dispatch_irq_handler */
+
+static inline int IsUICIRQ(const rtems_irq_number irqLine)
+{
+  return (((int) irqLine <= BSP_UIC_IRQ_MAX_OFFSET) &&
+	  ((int) irqLine >= BSP_UIC_IRQ_LOWEST_OFFSET)
+	 );
+}
+
+static void WriteIState(void)
+/* Write the gEnabledInts state masked by gIntInhibited to the hardware */
+{
+	PPC_SET_DEVICE_CONTROL_REGISTER(UIC0_ER,
+					gEnabledInts[0] & ~gIntInhibited[0]);
+	PPC_SET_DEVICE_CONTROL_REGISTER(UIC1_ER,
+					gEnabledInts[1] & ~gIntInhibited[1]);
+	PPC_SET_DEVICE_CONTROL_REGISTER(UIC2_ER,
+					gEnabledInts[2] & ~gIntInhibited[2]);
+}
+
+void
+BSP_enable_irq_at_pic(const rtems_irq_number irq)
+/* Enable an interrupt; this can be called from inside C_dispatch_irq_handler */
+{
+	if (IsUICIRQ(irq)) {
+		/* Set relevant bit in the state, write state to the UIC */
+		gEnabledInts[irq>>5] |= (0x80000000 >> (irq & 0x1F));
+		WriteIState();
+	}
+}
+
+int
+BSP_disable_irq_at_pic(const rtems_irq_number irq)
+/* Enable an interrupt; this can be called from inside C_dispatch_irq_handler */
+{
+	if (IsUICIRQ(irq)) {
+		uint32_t oldState;
+		int		 iword = irq>>5;
+		uint32_t mask = (0x80000000 >> (irq & 0x1F));
+
+		oldState = gEnabledInts[iword] & mask;
+		gEnabledInts[iword] &= ~mask;
+		WriteIState();
+		return oldState ? 1 : 0;
+	} else
+		return -1;
+}
+
+int
+BSP_setup_the_pic(rtems_irq_global_settings* config)
+{
+	int i;
+
+	dflt_entry     = config->defaultEntry;
+	rtems_hdl_tblP = config->irqHdlTbl;
+	for (i=0; i<kUICWords; i++)
+		gIntInhibited[i] = 0;
+
+	/* disable all interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_ER, 0x00000000);
+	/* Set Critical / Non Critical interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_CR, 0x00000000);
+	/* Set Interrupt Polarities */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_PR, 0xf7ffffff);
+	/* Set Interrupt Trigger Levels */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_TR, 0x01e1fff8);
+	/* Set Vect base=0,INT31 Highest priority */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_VR, 0x00000001);
+	/* clear all interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_SR, 0xffffffff);
+
+	/* disable all interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_ER, 0x00000000);
+	/* Set Critical / Non Critical interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_CR, 0x00000000);
+	/* Set Interrupt Polarities */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_PR, 0xfffac785);
+	/* Set Interrupt Trigger Levels */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_TR, 0x001d0040);
+	/* Set Vect base=0,INT31 Highest priority */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_VR, 0x00000001);
+	/* clear all interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_SR, 0xffffffff);
+
+	/* Disable all interrupts except cascade UIC0 and UIC1 */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_ER, 0x0000000a);
+	/* Set Critical / Non Critical interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_CR, 0x00000000);
+	/* Set Interrupt Polarities */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_PR, 0xffbfefef);
+	/* Set Interrupt Trigger Levels */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_TR, 0x00007000);
+	/* Set Vect base=0,INT31 Highest priority */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_VR, 0x00000001);
+	/* clear all interrupts */
+	PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_SR, 0xffffffff);
+
+	return 1;
+}
+
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry; decode and
+ * dispatch. Note that this routine needs to be re-entrant
+ *
+ * No support for critical interrupts here yet
+ */
+
+int
+C_dispatch_irq_handler( BSP_Exception_frame* frame, unsigned int excNum )
+{
+	if (excNum == ASM_EXT_VECTOR) {
+		uint32_t active[kUICWords];
+
+		/* Fetch the masked flags that tell us what external ints are active.
+		   Likely to be only one, but we need to handle more than one,
+		   OR the flags into gIntInhibited */
+		active[0] = PPC_DEVICE_CONTROL_REGISTER(UIC0_MSR);
+		active[1] = PPC_DEVICE_CONTROL_REGISTER(UIC1_MSR);
+		active[2] = PPC_DEVICE_CONTROL_REGISTER(UIC2_MSR);
+		gIntInhibited[0] |= active[0];
+		gIntInhibited[1] |= active[1];
+		gIntInhibited[2] |= active[2];
+
+		/*  ...and update the hardware so the active interrupts are disabled */
+		WriteIState();
+
+		/* Loop, calling bsp_irq_dispatch_list for each active interrupt */
+		while ((active[0] | active[1] | active[2]) != 0) {
+			uint32_t index = -1;
+			uint32_t bit, bmask;
+
+			/* Find an active interrupt, searching 0..2, bit 0..bit 31 (IBM order) */
+			do {
+				index++;
+				asm volatile ("	cntlzw %0, %1":"=r" (bit):"r" (active[index]));
+			} while (bit==32);
+
+			/* Call the matching handler */
+			bsp_irq_dispatch_list(rtems_hdl_tblP, (index*32)+bit, dflt_entry.hdl);
+
+			/* Write a 1-bit to the appropriate status register to clear it */
+			bmask = 0x80000000 >> bit;
+			switch (index) {
+			case 0:
+			  PPC_SET_DEVICE_CONTROL_REGISTER(UIC0_SR, bmask);
+			  break;
+			case 1:
+			  PPC_SET_DEVICE_CONTROL_REGISTER(UIC1_SR, bmask);
+			  break;
+			case 2:
+			  PPC_SET_DEVICE_CONTROL_REGISTER(UIC2_SR, bmask);
+			  break;
+			}
+
+			/* Clear in the active record and gIntInhibited */
+			active[index] &= ~bmask;
+			gIntInhibited[index] &= ~bmask;
+		};
+
+		/* Update the hardware again so the interrupts we have handled are unmasked */
+		WriteIState();
+		return 0;
+
+	} else if (excNum == ASM_DEC_VECTOR) {		/* 0x1000 remapped by C_dispatch_dec_handler_bookE  */
+		bsp_irq_dispatch_list(rtems_hdl_tblP, BSP_PIT, dflt_entry.hdl);
+		return 0;
+
+	} else if (excNum == ASM_BOOKE_FIT_VECTOR) {		/* 0x1010 mapped to 0x13 by ppc_get_vector_addr */
+		bsp_irq_dispatch_list(rtems_hdl_tblP, BSP_FIT, dflt_entry.hdl);
+		return 0;
+
+	} else if (excNum == ASM_BOOKE_WDOG_VECTOR) {		/* 0x1020 mapped to 0x14 by ppc_get_vector_addr */
+		bsp_irq_dispatch_list(rtems_hdl_tblP, BSP_WDOG, dflt_entry.hdl);
+		return 0;
+
+	} else
+		return -1; /* unhandled interrupt, panic time */
+}
+
Index: bsps/powerpc/haleakala/irq/irq_init.c
===================================================================
--- bsps/powerpc/haleakala/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/haleakala/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,96 @@
+/*===============================================================*\
+| Project: RTEMS Haleakala BSP                                    |
+|  *  by Michael Hamel ADInstruments Ltd 2008                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the irq controller handler                   |
+\*===============================================================*/
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <rtems/bspIo.h>
+#include <rtems/powerpc/powerpc.h>
+
+
+/*
+ * default on/off function
+ */
+static void nop_func(void)
+{
+}
+
+/*
+ * default isOn function
+ */
+static int not_connected(void)
+{
+	return 0;
+}
+
+static rtems_irq_connect_data      rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings   initial_config;
+static rtems_irq_connect_data      defaultIrq = {
+  .name   = 0,
+  .hdl    = NULL,
+  .handle = NULL,
+  .on     = (rtems_irq_enable) nop_func,
+  .off    = (rtems_irq_disable) nop_func,
+  .isOn   = (rtems_irq_is_enabled) not_connected,
+#ifdef BSP_SHARED_HANDLER_SUPPORT
+  .next_handler = NULL
+#endif
+};
+
+static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
+  /*
+   * Processor exceptions handled as interrupts
+   */
+  0
+};
+
+  /*
+   * This code assumes the exceptions management setup has already
+   * been done. We just need to replace the exceptions that will
+   * be handled like interrupt. On mcp750/mpc750 and many PPC processors
+   * this means the decrementer exception and the external exception.
+   */
+
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+  int i;
+
+  /*
+   * re-init the rtemsIrq table
+   */
+  for (i = 0; i < BSP_IRQ_NUMBER; i++) {
+    rtemsIrq[i]      = defaultIrq;
+    rtemsIrq[i].name = i;
+  }
+  /*
+   * Init initial Interrupt management config
+   */
+  initial_config.irqNb        = BSP_IRQ_NUMBER;
+  initial_config.defaultEntry = defaultIrq;
+  initial_config.irqHdlTbl    = rtemsIrq;
+  initial_config.irqBase      = BSP_LOWEST_OFFSET;
+  initial_config.irqPrioTbl   = irqPrioTable;
+
+  if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+    /*
+     * put something here that will show the failure...
+     */
+    rtems_panic(
+      "Unable to initialize RTEMS interrupt management!!! System locked\n"
+    );
+  }
+
+  #ifdef TRACE_IRQ_INIT
+    printk("RTEMS IRQ management is now operational\n");
+  #endif
+}
Index: bsps/powerpc/mpc8260ads/irq/irq.c
===================================================================
--- bsps/powerpc/mpc8260ads/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/mpc8260ads/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,372 @@
+/*
+ *
+ *  This file contains the implementation of the function described in irq.h
+ *
+ *  Copyright (C) 1998, 1999 valette@crf.canon.fr
+ *
+ *  Modified for mpc8260 Andy Dachs <a.dachs@sstl.co.uk>
+ *  Surrey Satellite Technology Limited, 2000
+ *    21/4/2002 Added support for nested interrupts and improved
+ *    masking operations.  Now we compute priority mask based
+ *     on table in irq_init.c
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <bsp/vectors.h>
+#include <mpc8260.h>
+
+/*
+ * Check if symbolic IRQ name is an CPM IRQ
+ */
+static inline int is_cpm_irq(const rtems_irq_number irqLine)
+{
+  return (((int) irqLine <= BSP_CPM_IRQ_MAX_OFFSET) &
+      ((int) irqLine >= BSP_CPM_IRQ_LOWEST_OFFSET)
+  );
+}
+
+typedef struct {
+  uint32_t         mask_h;  /* mask for sipnr_h and simr_h */
+  uint32_t         mask_l;  /* mask for sipnr_l and simr_l */
+  uint32_t         priority_h;  /* mask this and lower priority ints */
+  uint32_t         priority_l;
+} m82xxIrqMasks_t;
+
+static unsigned char irqPrioTable[BSP_CPM_IRQ_NUMBER]={
+  /*
+   * actual priorities for interrupt :
+   */
+  /*
+   * CPM Interrupts
+   */
+  0,  45, 63, 44, 66, 68, 35, 39, 50, 62, 34,  0,  30, 40, 52, 58,
+  2,  3,  0,  5,  15, 16, 17, 18, 49, 51,  0,  0,  0,  0,  0,  0,
+  6,  7,  8,  0,  11, 12, 0,  0,  20, 21, 22,  23, 0,  0,  0,  0,
+  29, 31, 33, 37, 38, 41, 47, 48, 55, 56, 57,  60, 64, 65, 69, 70,
+
+};
+
+/*
+ *  Mask fields should have a '1' in the bit position for that
+ *  interrupt.
+ *  Priority masks calculated later based on priority table
+ */
+
+static m82xxIrqMasks_t SIU_MaskBit[BSP_CPM_IRQ_NUMBER] =
+{
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* err */
+  { 0x00000000, 0x00008000, 0x00000000, 0x00000000 }, /* i2c */
+  { 0x00000000, 0x00004000, 0x00000000, 0x00000000 }, /* spi */
+  { 0x00000000, 0x00002000, 0x00000000, 0x00000000 }, /* rtt */
+  { 0x00000000, 0x00001000, 0x00000000, 0x00000000 }, /* smc1 */
+  { 0x00000000, 0x00000800, 0x00000000, 0x00000000 }, /* smc2 */
+  { 0x00000000, 0x00000400, 0x00000000, 0x00000000 }, /* idma1 */
+  { 0x00000000, 0x00000200, 0x00000000, 0x00000000 }, /* idma2 */
+  { 0x00000000, 0x00000100, 0x00000000, 0x00000000 }, /* idma3 */
+  { 0x00000000, 0x00000080, 0x00000000, 0x00000000 }, /* idma4 */
+  { 0x00000000, 0x00000040, 0x00000000, 0x00000000 }, /* sdma */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000010, 0x00000000, 0x00000000 }, /* tmr1 */
+  { 0x00000000, 0x00000008, 0x00000000, 0x00000000 }, /* tmr2 */
+  { 0x00000000, 0x00000004, 0x00000000, 0x00000000 }, /* tmr3 */
+  { 0x00000000, 0x00000002, 0x00000000, 0x00000000 }, /* tmr4 */
+  { 0x00000004, 0x00000000, 0x00000000, 0x00000000 }, /* tmcnt */
+  { 0x00000002, 0x00000000, 0x00000000, 0x00000000 }, /* pit */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00004000, 0x00000000, 0x00000000, 0x00000000 }, /* irq1 */
+  { 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* irq2 */
+  { 0x00001000, 0x00000000, 0x00000000, 0x00000000 }, /* irq3 */
+  { 0x00000800, 0x00000000, 0x00000000, 0x00000000 }, /* irq4 */
+  { 0x00000400, 0x00000000, 0x00000000, 0x00000000 }, /* irq5 */
+  { 0x00000200, 0x00000000, 0x00000000, 0x00000000 }, /* irq6 */
+  { 0x00000100, 0x00000000, 0x00000000, 0x00000000 }, /* irq7 */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x80000000, 0x00000000, 0x00000000 }, /* fcc1 */
+  { 0x00000000, 0x40000000, 0x00000000, 0x00000000 }, /* fcc2 */
+  { 0x00000000, 0x20000000, 0x00000000, 0x00000000 }, /* fcc3 */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x08000000, 0x00000000, 0x00000000 }, /* mcc1 */
+  { 0x00000000, 0x04000000, 0x00000000, 0x00000000 }, /* mcc2 */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00800000, 0x00000000, 0x00000000 }, /* scc1 */
+  { 0x00000000, 0x00400000, 0x00000000, 0x00000000 }, /* scc2 */
+  { 0x00000000, 0x00200000, 0x00000000, 0x00000000 }, /* scc3 */
+  { 0x00000000, 0x00100000, 0x00000000, 0x00000000 }, /* scc4 */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* reserved */
+  { 0x00010000, 0x00000000, 0x00000000, 0x00000000 }, /* pc15 */
+  { 0x00020000, 0x00000000, 0x00000000, 0x00000000 }, /* pc14 */
+  { 0x00040000, 0x00000000, 0x00000000, 0x00000000 }, /* pc13 */
+  { 0x00080000, 0x00000000, 0x00000000, 0x00000000 }, /* pc12 */
+  { 0x00100000, 0x00000000, 0x00000000, 0x00000000 }, /* pc11 */
+  { 0x00200000, 0x00000000, 0x00000000, 0x00000000 }, /* pc10 */
+  { 0x00400000, 0x00000000, 0x00000000, 0x00000000 }, /* pc9 */
+  { 0x00800000, 0x00000000, 0x00000000, 0x00000000 }, /* pc8 */
+  { 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc7 */
+  { 0x02000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc6 */
+  { 0x04000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc5 */
+  { 0x08000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc4 */
+  { 0x10000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc3 */
+  { 0x20000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc2 */
+  { 0x40000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc1 */
+  { 0x80000000, 0x00000000, 0x00000000, 0x00000000 }, /* pc0 */
+
+};
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+/*
+ * Caution : this function assumes the variable "internal_config"
+ * is already set and that the tables it contains are still valid
+ * and accessible.
+ */
+static void compute_SIU_IvectMask_from_prio (void)
+{
+  /*
+   * The actual masks defined
+   * correspond to the priorities defined
+   * for the SIU in irq_init.c.
+   */
+
+   int i,j;
+
+   for( i=0; i<BSP_CPM_IRQ_NUMBER; i++ )
+   {
+     for( j=0;j<BSP_CPM_IRQ_NUMBER; j++ )
+       if( irqPrioTable[j] < irqPrioTable[i] )
+       {
+        SIU_MaskBit[i].priority_h |= SIU_MaskBit[j].mask_h;
+        SIU_MaskBit[i].priority_l |= SIU_MaskBit[j].mask_l;
+      }
+   }
+
+}
+
+
+int BSP_irq_enable_at_cpm(const rtems_irq_number irqLine)
+{
+  int cpm_irq_index;
+
+  if (!is_cpm_irq(irqLine))
+    return 1;
+
+  cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
+
+  m8260.simr_h |= SIU_MaskBit[cpm_irq_index].mask_h;
+  m8260.simr_l |= SIU_MaskBit[cpm_irq_index].mask_l;
+
+  return 0;
+}
+
+int BSP_irq_disable_at_cpm(const rtems_irq_number irqLine)
+{
+  int cpm_irq_index;
+
+  if (!is_cpm_irq(irqLine))
+    return 1;
+
+  cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
+
+  m8260.simr_h &= ~(SIU_MaskBit[cpm_irq_index].mask_h);
+  m8260.simr_l &= ~(SIU_MaskBit[cpm_irq_index].mask_l);
+
+  return 0;
+}
+
+int BSP_irq_enabled_at_cpm(const rtems_irq_number irqLine)
+{
+       int cpm_irq_index;
+
+       if (!is_cpm_irq(irqLine))
+               return 0;
+
+       cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
+
+       return ((m8260.simr_h & SIU_MaskBit[cpm_irq_index].mask_h) ||
+                   (m8260.simr_l & SIU_MaskBit[cpm_irq_index].mask_l));
+}
+
+#ifdef DISPATCH_HANDLER_STAT
+volatile unsigned int maxLoop = 0;
+#endif
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned excNum)
+{
+  register unsigned int irq;
+#if 0
+  register unsigned oldMask;          /* old siu pic masks */
+#endif
+  register unsigned msr;
+  register unsigned new_msr;
+  register unsigned old_simr_h;
+  register unsigned old_simr_l;
+#ifdef DISPATCH_HANDLER_STAT
+  unsigned loopCounter;
+#endif
+
+  /*
+   * Handle decrementer interrupt
+   */
+  if (excNum == ASM_DEC_VECTOR) {
+    _CPU_MSR_GET(msr);
+    new_msr = msr | MSR_EE;
+    _CPU_MSR_SET(new_msr);
+
+    bsp_interrupt_handler_dispatch(BSP_DECREMENTER);
+
+    _CPU_MSR_SET(msr);
+
+    return 0;
+  }
+
+  /*
+   * Handle external interrupt generated by SIU on PPC core
+   */
+#ifdef DISPATCH_HANDLER_STAT
+  loopCounter = 0;
+#endif
+
+  while (1) {
+
+    if( ((m8260.sipnr_h & m8260.simr_h) | (m8260.sipnr_l & m8260.simr_l)) == 0 ) {
+#ifdef DISPATCH_HANDLER_STAT
+      if (loopCounter >  maxLoop) maxLoop = loopCounter;
+#endif
+      break;
+    }
+
+    irq = (m8260.sivec >> 26) + BSP_CPM_IRQ_LOWEST_OFFSET;
+
+    /* Clear mask and pending register */
+    if( irq <= BSP_CPM_IRQ_MAX_OFFSET ) {
+      /* save interrupt masks */
+      old_simr_h = m8260.simr_h;
+      old_simr_l = m8260.simr_l;
+
+      /* mask off current interrupt and lower priority ones */
+      m8260.simr_h &= SIU_MaskBit[irq].priority_h;
+      m8260.simr_l &= SIU_MaskBit[irq].priority_l;
+
+      /* clear pending bit */
+      m8260.sipnr_h |= SIU_MaskBit[irq].mask_h;
+      m8260.sipnr_l |= SIU_MaskBit[irq].mask_l;
+
+      /*
+       * make sure, that the masking operations in
+       * ICTL and MSR are executed in order
+       */
+      __asm__ volatile("sync":::"memory");
+
+      /* re-enable external exceptions */
+      _CPU_MSR_GET(msr);
+      new_msr = msr | MSR_EE;
+      _CPU_MSR_SET(new_msr);
+
+      /* call handler */
+      bsp_interrupt_handler_dispatch(irq);
+
+      /* disable exceptions again */
+      _CPU_MSR_SET(msr);
+
+      /*
+       * make sure, that the masking operations in
+       * ICTL and MSR are executed in order
+       */
+      __asm__ volatile("sync":::"memory");
+
+      /* restore interrupt masks */
+      m8260.simr_h = old_simr_h;
+      m8260.simr_l = old_simr_l;
+
+    }
+#ifdef DISPATCH_HANDLER_STAT
+    ++ loopCounter;
+#endif
+  }
+  return 0;
+}
+
+/*
+ * Initialize CPM interrupt management
+ */
+static void
+BSP_CPM_irq_init(void)
+{
+   m8260.simr_l = 0;
+   m8260.simr_h = 0;
+   m8260.sipnr_l = 0xffffffff;
+   m8260.sipnr_h = 0xffffffff;
+   m8260.sicr = 0;
+
+  /*
+   * Initialize the interrupt priorities.
+   */
+   m8260.siprr   = 0x05309770;	/* reset value */
+   m8260.scprr_h = 0x05309770;	/* reset value */
+   m8260.scprr_l = 0x05309770;	/* reset value */
+
+}
+
+void bsp_interrupt_vector_enable( rtems_vector_number irqnum)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(irqnum));
+
+  if (is_cpm_irq(irqnum)) {
+    /*
+     * Enable interrupt at PIC level
+     */
+    BSP_irq_enable_at_cpm (irqnum);
+  }
+}
+
+void bsp_interrupt_vector_disable( rtems_vector_number irqnum)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(irqnum));
+
+  if (is_cpm_irq(irqnum)) {
+    /*
+     * disable interrupt at PIC level
+     */
+    BSP_irq_disable_at_cpm (irqnum);
+  }
+}
+
+rtems_status_code bsp_interrupt_facility_initialize()
+{
+  /* Install exception handler */
+  if (ppc_exc_set_handler( ASM_EXT_VECTOR, C_dispatch_irq_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+  if (ppc_exc_set_handler( ASM_DEC_VECTOR, C_dispatch_irq_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+
+  /* Fill in priority masks */
+  compute_SIU_IvectMask_from_prio();
+
+  /* Initialize the interrupt controller */
+  BSP_CPM_irq_init();
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/mvme3100/irq/irq_init.c
===================================================================
--- bsps/powerpc/mvme3100/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/mvme3100/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,138 @@
+/* irq_init.c
+ *
+ *  This file contains the implementation of rtems initialization
+ *  related to interrupt handling.
+ *
+ *  CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ * to make it valid for MVME2300 Motorola boards.
+ *
+ * Till Straumann <strauman@slac.stanford.edu>, 12/20/2001:
+ * Use the new interface to openpic_init
+ *
+ * Adapted for the mvme3100 BSP by T. Straumann, 2007.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libcpu/io.h>
+#include <bsp/pci.h>
+#include <bsp/openpic.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <rtems/bspIo.h>
+
+static void nop_func(void *unused)
+{
+	printk("Unhandled IRQ\n");
+}
+
+static rtems_irq_connect_data     	rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings    initial_config;
+static rtems_irq_connect_data     	defaultIrq = {
+  /* vectorIdex,	 hdl		, handle	, on		, off		, isOn */
+  0, 			 nop_func	, NULL		, 0	, 0	, 0
+};
+
+static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
+  /*
+   * actual priorities for interrupt :
+   *	0   means that only current interrupt is masked
+   *	255 means all other interrupts are masked
+   */
+  /*
+   * PCI Interrupts
+   */
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,             /* for raven prio 0 means unactive... */
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
+  /*
+   * Processor exceptions handled as interrupts
+   */
+  0
+};
+
+  /*
+   * This code assumes the exceptions management setup has already
+   * been done. We just need to replace the exceptions that will
+   * be handled like interrupt. On mcp750/mpc750 and many PPC processors
+   * this means the decrementer exception and the external exception.
+   */
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+	/* We should really have a way to find the number of sources
+	 * the driver will use so that the size of the polarity-array
+	 * matches the driver's idea of it.
+	 */
+	unsigned char pol[56];
+	int i;
+
+	/* Note: The openpic driver initializes only as many
+	 *       'pic-external' interrupt sources as reported
+	 *       by the feature register.
+	 *       The 8540's openpic supports 12 core-external
+	 *       and 23 core-internal (both of these groups
+	 *       are external to the PIC, i.e., 'pic-external')
+	 *       interrupts but between the corresponding
+	 *       banks of vector/priority registers there is
+	 *       a gap leaving space for 4 (unsupported) irqs.
+	 *       The driver, not knowing of this gap, would
+	 *       initialize the 12 core-external sources
+	 *       followed by 4 unsupported sources and 19
+	 *       core-internal sources thus leaving the last
+	 *       four core-internal sources uninitialized.
+	 *       Luckily, the feature register reports
+	 *       too many sources:
+	 *          - the 4 IPI plus 4 timer plus 4 messaging
+	 *            sources are included with the count
+	 *          - there are unused core-internal sources 24..32
+	 *            which are also supported by the pic
+	 *       bringing the reported number of sources to
+	 *       a count of 56 (12+32+4+4+4) which is enough
+	 *       so that all pic-external sources are covered
+	 *       and initialized.
+	 *
+	 *       NOTE: All core-internal sources are active-high.
+	 *             The manual says that setting the polarity
+	 *             to 'low/0' will disable the interrupt but
+	 *             I found this not to be true: on the device
+	 *             I tested the interrupt was asserted hard.
+	 */
+
+	/* core-external sources on the mvme3100 are active-low,
+	 * core-internal sources are active high.
+	 */
+	for (i=0; i<BSP_EXT_IRQ_NUMBER; i++)
+		pol[i]=0;
+	for (i=BSP_EXT_IRQ_NUMBER; i< BSP_EXT_IRQ_NUMBER + BSP_CORE_IRQ_NUMBER; i++)
+		pol[i]=1;
+
+	openpic_init(1, pol, 0, 0, 0, 0);
+
+	/*
+	 * re-init the rtemsIrq table
+	 */
+	for (i = 0; i < BSP_IRQ_NUMBER; i++) {
+		rtemsIrq[i]      = defaultIrq;
+		rtemsIrq[i].name = i;
+	}
+	/*
+	 * Init initial Interrupt management config
+	 */
+	initial_config.irqNb 	= BSP_IRQ_NUMBER;
+	initial_config.defaultEntry = defaultIrq;
+	initial_config.irqHdlTbl	= rtemsIrq;
+	initial_config.irqBase	= BSP_LOWEST_OFFSET;
+	initial_config.irqPrioTbl	= irqPrioTable;
+
+	if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+		/*
+		 * put something here that will show the failure...
+		 */
+		rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+	}
+}
Index: bsps/powerpc/mvme5500/README.irq
===================================================================
--- bsps/powerpc/mvme5500/README.irq	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/mvme5500/README.irq	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,20 @@
+README.irq : Shuchen Kate Feng  <feng1@bnl.gov>, Sept. 2, 2007
+
+As per implementation in shared PPC code,
+the BSPirqPrioTable[96] listed in irq_init.c is where the
+software developers can change the levels of priority
+for all the interrupts based on the need of their
+applications.  The IRQs can be eanbled dynamically via the
+BSP_enable_pic_irq(), or disbaled dynamically via the
+BSP_disable_pic_irq(). 
+
+
+Support for run-time priority setup could be
+added easily, but there is no action taken yet due to concerns
+over computer security at VME CPU level. 
+
+
+The software developers are forbidden to setup picIsrTable[],
+as it is a powerful engine for the BSP to find the pending
+highest priority IRQ at run time. It ensures the fastest/faster
+interrupt service to the highest/higher priority IRQ, if pending.
Index: bsps/powerpc/mvme5500/irq/BSP_irq.c
===================================================================
--- bsps/powerpc/mvme5500/irq/BSP_irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/mvme5500/irq/BSP_irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,483 @@
+/*
+ *  This file contains the implementation of the function described in irq.h
+ */
+
+/*
+ *  Copyright (C) 1998, 1999 valette@crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  Acknowledgement May 2004, to Till Straumann <strauman@slac.stanford.edu>
+ *  for some inputs.
+ *
+ *  Copyright 2003, 2004, 2005, 2007  Shuchen Kate Feng <feng1@bnl.gov>,
+ *            NSLS, Brookhaven National Laboratory. All rights reserved.
+ *
+ *  1) Used GT_GPP_Value register instead of the GT_GPP_Interrupt_Cause
+ *     register to monitor the cause of the level sensitive interrupts.
+ *     (Copyright : NDA item)
+ *  2) The implementation of picPrioTable[] is an original work by the
+ *     author to optimize the software IRQ priority scheduling because
+ *     Discovery controller does not provide H/W IRQ priority schedule.
+ *     It ensures the fastest/faster interrupt service to the
+ *     highest/higher priority IRQ, if pendig.
+ *  3) _CPU_MSR_SET() needs RTEMS_COMPILER_MEMORY_BARRIER()
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <rtems/system.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/intr.h>
+#include <libcpu/io.h>
+#include <libcpu/byteorder.h>
+#include <bsp/vectors.h>
+
+#include <rtems/bspIo.h> /* for printk */
+#include "bsp/gtreg.h"
+
+#define HI_INT_CAUSE 0x40000000
+
+#define MAX_IRQ_LOOP 20
+
+/* #define DEBUG_IRQ*/
+
+/*
+ * pointer to the mask representing the additionnal irq vectors
+ * that must be disabled when a particular entry is activated.
+ * They will be dynamically computed from the table given
+ * in BSP_rtems_irq_mngt_set();
+ * CAUTION : this table is accessed directly by interrupt routine
+ * 	     prologue.
+ */
+static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER];
+
+/*
+ * location used to store initial tables used for interrupt
+ * management.BSP copy of the configuration
+ */
+static rtems_irq_global_settings	BSP_config;
+static rtems_irq_connect_data*		rtems_hdl_tbl;
+
+/*
+ * default handler connected on each irq after bsp initialization
+ * (locally cached copy)
+ */
+void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1;
+
+
+static volatile unsigned  *BSP_irqMask_reg[3];
+static volatile unsigned  *BSP_irqCause_reg[3];
+static volatile unsigned  BSP_irqMask_cache[3]={0,0,0};
+
+static int picPrioTblPtr=0;
+static unsigned int GPPIrqInTbl=0;
+static unsigned long long MainIrqInTbl=0;
+
+/*
+ * The software developers are forbidden to setup picPrioTable[],
+ * as it is a powerful engine for the BSP to find the pending
+ * highest priority IRQ at run time.  It ensures the fastest/faster
+ * interrupt service to the highest/higher priority IRQ, if pendig.
+ *
+ * The picPrioTable[96] is updated dynamically at run time
+ * based on the priority levels set at BSPirqPrioTable[96],
+ * while the BSP_enable_irq_at_pic(), and BSP_disable_irq_at_pic()
+ * commands are invoked.
+ *
+ * The picPrioTable[96] lists the enabled CPU main and GPP external interrupt
+ * numbers [0 (lowest)- 95 (highest)] starting from the highest priority
+ * one to the lowest priority one. The highest priority interrupt is
+ * located at picPrioTable[0], and the lowest priority interrupt is located
+ * at picPrioTable[picPrioTblPtr-1].
+ *
+ *
+ */
+#define DynamicIsrTable
+#ifdef DynamicIsrTable
+/* BitNums for Main Interrupt Lo/High Cause, -1 means invalid bit */
+static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1 };
+#else
+static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
+     80, 84, 76, 77, 32, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     -1, -1, -1, -1, -1, -1 };
+#endif
+
+/*
+ * Check if IRQ is a MAIN CPU internal IRQ or GPP external IRQ
+ */
+static inline int is_pic_irq(const rtems_irq_number irqLine)
+{
+  return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) &
+	  ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET)
+	 );
+}
+
+/*
+ * Check if IRQ is a Porcessor IRQ
+ */
+static inline int is_processor_irq(const rtems_irq_number irqLine)
+{
+  return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
+	  ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
+	 );
+}
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+/*
+ * Caution : this function assumes the variable "BSP_config"
+ * is already set and that the tables it contains are still valid
+ * and accessible.
+ */
+static void compute_pic_masks_from_prio(void)
+{
+  int i,j, k, isGppMain;
+  unsigned long long irq_prio_mask=0;
+
+  /*
+   * Always mask at least current interrupt to prevent re-entrance
+   */
+  for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) {
+    switch(i) {
+      case BSP_MAIN_GPP7_0_IRQ:
+      case BSP_MAIN_GPP15_8_IRQ:
+      case BSP_MAIN_GPP23_16_IRQ:
+      case BSP_MAIN_GPP31_24_IRQ:
+	for (k=0; k< 3; k++)
+	    BSP_irq_prio_mask_tbl[k][i]=0;
+
+        irq_prio_mask =0;
+        isGppMain =1;
+        break;
+      default :
+        isGppMain =0;
+        irq_prio_mask = (unsigned long long) (1LLU << i);
+	break;
+    }
+    if ( isGppMain) continue;
+    for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) {
+        /*
+         * Mask interrupts at PIC level that have a lower priority
+         * or <Till Straumann> a equal priority.
+         */
+        if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
+	   irq_prio_mask |= (unsigned long long)(1LLU << j);
+    }
+
+
+    BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff;
+    BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff;
+#if 0
+    printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i],
+	   BSP_irq_prio_mask_tbl[0][i]);
+#endif
+
+    BSP_irq_prio_mask_tbl[2][i] = 1<<i;
+    /* Compute for the GPP priority interrupt mask */
+    for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) {
+      if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
+	   BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET);
+    }
+#if 0
+    printk("GPPirq_mask_prio_tbl[%d]:0x%8x\n",i,BSP_irq_prio_mask_tbl[2][i]);
+#endif
+  }
+}
+
+static void UpdateMainIrqTbl(int irqNum)
+{
+  int i=0, j, shifted=0;
+
+  switch (irqNum) {
+    case BSP_MAIN_GPP7_0_IRQ:
+    case BSP_MAIN_GPP15_8_IRQ:
+    case BSP_MAIN_GPP23_16_IRQ:
+    case BSP_MAIN_GPP31_24_IRQ:
+      return;  /* Do nothing, let GPP take care of it */
+      break;
+  }
+#ifdef SHOW_MORE_INIT_SETTINGS
+  unsigned long val2, val1;
+#endif
+
+  /* If entry not in table*/
+  if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
+        (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) ||
+       ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
+        (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))))
+  {
+      while ( picPrioTable[i]!=-1) {
+        if (BSP_config.irqPrioTbl[irqNum]>BSP_config.irqPrioTbl[picPrioTable[i]]) {
+          /* all other lower priority entries shifted right */
+          for (j=picPrioTblPtr;j>i; j--) {
+              picPrioTable[j]=picPrioTable[j-1];
+          }
+          picPrioTable[i]=irqNum;
+          shifted=1;
+          break;
+       }
+       i++;
+     }
+     if (!shifted) picPrioTable[picPrioTblPtr] =irqNum;
+
+     if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
+        GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
+     else
+        MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
+     picPrioTblPtr++;
+  }
+#ifdef SHOW_MORE_INIT_SETTINGS
+  val2 = (MainIrqInTbl>>32) & 0xffffffff;
+  val1 = MainIrqInTbl&0xffffffff;
+  printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);
+  BSP_printPicIsrTbl();
+#endif
+
+}
+
+
+static void CleanMainIrqTbl(int irqNum)
+{
+  int i, j;
+
+  switch (irqNum) {
+    case BSP_MAIN_GPP7_0_IRQ:
+    case BSP_MAIN_GPP15_8_IRQ:
+    case BSP_MAIN_GPP23_16_IRQ:
+    case BSP_MAIN_GPP31_24_IRQ:
+      return;  /* Do nothing, let GPP take care of it */
+      break;
+  }
+  if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
+        ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) ||
+       ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
+        (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))
+  { /* If entry in table*/
+     for (i=0; i<64; i++) {
+       if (picPrioTable[i]==irqNum) {/*remove it from the entry */
+          /* all other lower priority entries shifted left */
+	  for (j=i;j<picPrioTblPtr; j++) {
+              picPrioTable[j]=picPrioTable[j+1];
+          }
+          if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
+            GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
+          else
+            MainIrqInTbl &= ~(1LLU << irqNum);
+          picPrioTblPtr--;
+          break;
+       }
+     }
+  }
+}
+
+void BSP_enable_irq_at_pic(const rtems_irq_number irqNum)
+{
+  unsigned bitNum, regNum;
+  unsigned int level;
+
+  if ( !is_pic_irq(irqNum) )
+  	return;
+
+  bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
+  regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
+
+  rtems_interrupt_disable(level);
+
+#ifdef DynamicIsrTable
+  UpdateMainIrqTbl((int) irqNum);
+#endif
+  BSP_irqMask_cache[regNum] |= (1 << bitNum);
+
+  out_le32((volatile uint32_t *)BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
+  while (in_le32((volatile uint32_t *)BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
+
+  rtems_interrupt_enable(level);
+}
+
+int BSP_disable_irq_at_pic(const rtems_irq_number irqNum)
+{
+  int      rval;
+  unsigned bitNum, regNum;
+  unsigned int level;
+
+  if ( ! is_pic_irq(irqNum) )
+    return -1;
+
+  bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
+  regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
+
+  rtems_interrupt_disable(level);
+
+#ifdef DynamicIsrTable
+  CleanMainIrqTbl((int) irqNum);
+#endif
+
+  rval = BSP_irqMask_cache[regNum] & (1<<bitNum);
+
+  BSP_irqMask_cache[regNum] &=  ~(1 << bitNum);
+
+  out_le32((volatile uint32_t *)BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
+  while (in_le32((volatile uint32_t *)BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
+
+  rtems_interrupt_enable(level);
+
+  return rval ? 1 : 0;
+}
+
+/* Use shared/irq : 2008 */
+int BSP_setup_the_pic(rtems_irq_global_settings* config)
+{
+  int i;
+
+  BSP_config = *config;
+  default_rtems_hdl = config->defaultEntry.hdl;
+  rtems_hdl_tbl     = config->irqHdlTbl;
+
+  /* Get ready for discovery BSP */
+  BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_LO);
+  BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_HI);
+  BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_LO);
+  BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_HI);
+  BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Interrupt_Mask);
+  BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Value);
+
+  /* Page 401, Table 598:
+   * Comm Unit Arbiter Control register :
+   * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0).
+   * MOTload default is set as level sensitive(1). Set it agin to make sure.
+   */
+  out_le32((volatile uint32_t *)GT_CommUnitArb_Ctrl,
+           (in_le32((volatile uint32_t *)GT_CommUnitArb_Ctrl)| (1<<10)));
+
+#if 0
+  printk("BSP_irqMask_reg[0] = 0x%" PRIx32 ", BSP_irqCause_reg[0] 0x%" PRIx32 "\n",
+         in_le32((volatile uint32_t *)BSP_irqMask_reg[0]),
+         in_le32((volatile uint32_t *)BSP_irqCause_reg[0]));
+  printk("BSP_irqMask_reg[1] = 0x%" PRIx32 ", BSP_irqCause_reg[1] 0x%" PRIx32 "\n",
+         in_le32((volatile uint32_t *)BSP_irqMask_reg[1]),
+         in_le32((volatile uint32_t *)BSP_irqCause_reg[1]));
+  printk("BSP_irqMask_reg[2] = 0x%" PRIx32 ", BSP_irqCause_reg[2] 0x%" PRIx32 "\n",
+         in_le32((volatile uint32_t *)BSP_irqMask_reg[2]),
+         in_le32((volatile uint32_t *)BSP_irqCause_reg[2]));
+#endif
+
+  /* Initialize the interrupt related  registers */
+  for (i=0; i<3; i++) {
+    out_le32((volatile uint32_t *)BSP_irqCause_reg[i], 0);
+    out_le32((volatile uint32_t *)BSP_irqMask_reg[i], 0);
+  }
+  in_le32((volatile uint32_t *)BSP_irqMask_reg[2]);
+  compute_pic_masks_from_prio();
+
+#if 0
+  printk("BSP_irqMask_reg[0] = 0x%" PRIx32 ", BSP_irqCause_reg[0] 0x%" PRIx32 "\n",
+         in_le32((volatile uint32_t *)BSP_irqMask_reg[0]),
+         in_le32((volatile uint32_t *)BSP_irqCause_reg[0]));
+  printk("BSP_irqMask_reg[1] = 0x%" PRIx32 ", BSP_irqCause_reg[1] 0x%" PRIx32 "\n",
+         in_le32((volatile uint32_t *)BSP_irqMask_reg[1]),
+         in_le32((volatile uint32_t *)BSP_irqCause_reg[1]));
+  printk("BSP_irqMask_reg[2] = 0x%" PRIx32 ", BSP_irqCause_reg[2] 0x%" PRIx32 "\n",
+         in_le32((volatile uint32_t *)BSP_irqMask_reg[2]),
+         in_le32((volatile uint32_t *)BSP_irqCause_reg[2]));
+#endif
+
+  /*
+   *
+   */
+  for (i=BSP_MICL_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET ; i++) {
+    if ( BSP_config.irqHdlTbl[i].hdl != BSP_config.defaultEntry.hdl) {
+      BSP_enable_irq_at_pic(i);
+      BSP_config.irqHdlTbl[i].on(&BSP_config.irqHdlTbl[i]);
+    }
+    else {
+      BSP_config.irqHdlTbl[i].off(&BSP_config.irqHdlTbl[i]);
+      BSP_disable_irq_at_pic(i);
+    }
+  }
+  for (i= BSP_MAIN_GPP7_0_IRQ; i < BSP_MAIN_GPP31_24_IRQ; i++)
+    BSP_enable_irq_at_pic(i);
+
+  return(1);
+}
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+  unsigned long irqCause[3]={0, 0,0};
+  unsigned oldMask[3]={0,0,0};
+  int loop=0, i=0, j;
+  int irq=0, group=0;
+
+  if (excNum == ASM_DEC_VECTOR) {
+      bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl);
+      return 0;
+  }
+
+  for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j];
+  for (j=0; j<3; j++) irqCause[j] = in_le32((volatile uint32_t *)BSP_irqCause_reg[j]) & in_le32((volatile uint32_t *)BSP_irqMask_reg[j]);
+
+  while (((irq = picPrioTable[i++])!=-1)&& (loop++ < MAX_IRQ_LOOP))
+  {
+    if (irqCause[group= irq/32] & ( 1<<(irq % 32))) {
+      for (j=0; j<3; j++)
+        BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]);
+
+      out_le32((volatile uint32_t *)BSP_irqMask_reg[0], BSP_irqMask_cache[0]);
+      out_le32((volatile uint32_t *)BSP_irqMask_reg[1], BSP_irqMask_cache[1]);
+      out_le32((volatile uint32_t *)BSP_irqMask_reg[2], BSP_irqMask_cache[2]);
+      in_le32((volatile uint32_t *)BSP_irqMask_reg[2]);
+
+      bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl);
+
+      for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j];
+
+      out_le32((volatile uint32_t *)BSP_irqMask_reg[0], oldMask[0]);
+      out_le32((volatile uint32_t *)BSP_irqMask_reg[1], oldMask[1]);
+      out_le32((volatile uint32_t *)BSP_irqMask_reg[2], oldMask[2]);
+      in_le32((volatile uint32_t *)BSP_irqMask_reg[2]);
+    }
+  }
+
+  return 0;
+}
+
+/* Only print part of the entries for now */
+void BSP_printPicIsrTbl(void)
+{
+  int i;
+
+  printf("picPrioTable[12]={ {irq# : ");
+  for (i=0; i<12; i++)
+    printf("%d,", picPrioTable[i]);
+  printf("}\n");
+
+  printf("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl);
+}
Index: bsps/powerpc/mvme5500/irq/irq_init.c
===================================================================
--- bsps/powerpc/mvme5500/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/mvme5500/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,148 @@
+/* irq_init.c
+ *
+ * This file contains the implementation of rtems initialization
+ * related to interrupt handling.
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * Modified and added support for the MVME5500.
+ * Copyright 2003, 2004, 2005, Brookhaven National Laboratory and
+ *                 Shuchen Kate Feng <feng1@bnl.gov>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE
+ *
+ */
+#include <libcpu/io.h>
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <bsp/vectors.h>  /* ASM_EXT_VECTOR, ASM_DEC_VECTOR ... */
+/*#define  TRACE_IRQ_INIT*/
+
+/*
+ * default on/off function
+ */
+static void nop_func(void){}
+/*
+ * default isOn function
+ */
+static int not_connected(void) {return 0;}
+
+static rtems_irq_connect_data     	rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings     	initial_config;
+
+static rtems_irq_connect_data     	defaultIrq = {
+  .name   = 0,
+  .hdl    = NULL,
+  .handle = NULL,
+  .on     = (rtems_irq_enable) nop_func,
+  .off    = (rtems_irq_disable) nop_func,
+  .isOn   = (rtems_irq_is_enabled) not_connected,
+#ifdef BSP_SHARED_HANDLER_SUPPORT
+  .next_handler = NULL
+#endif
+};
+
+rtems_irq_prio BSPirqPrioTable[BSP_PIC_IRQ_NUMBER] = {
+  /*
+   * This table is where the developers can change the levels of priority
+   * based on the need of their applications.
+   *
+   * actual priorities for CPU MAIN and GPP interrupts (0-95)
+   *
+   *	0   means that only current interrupt is masked (lowest priority)
+   *	255 is only used by bits 24, 25, 26 and 27 of the CPU high
+   *        interrupt Mask: (e.g. GPP7_0, GPP15_8, GPP23_16, GPP31_24).
+   *        The IRQs of those four bits are always enabled. When it's used,
+   *        the IRQ number is never listed in the dynamic picIsrTable[96].
+   *
+   *        The priorities of GPP interrupts were decided by their own
+   *        value set at  BSPirqPrioTable.
+   *
+   */
+  /* CPU Main cause low interrupt */
+  /* 0-15 */
+  0, 0, 0, 0, 0, 0, 0, 0, 64/*Timer*/, 0, 0, 0, 0, 0, 0, 0,
+   /* 16-31 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* CPU Main cause high interrupt */
+  /* 32-47 */
+  2/*10/100MHZ*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 48-63 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  255 /*GPP0-7*/, 255/*GPP8-15*/, 255/*GPP16-23*/, 255/*GPP24-31*/, 0, 0, 0, 0,
+  /* GPP interrupts */
+  /* GPP0-7 */
+  1/*serial*/,0, 0, 0, 0, 0, 0, 0,
+  /* GPP8-15 */
+  47/*PMC1A*/,46/*PMC1B*/,45/*PMC1C*/,44/*PMC1D*/,30/*VME0*/, 29/*VME1*/,3,1,
+  /* GPP16-23 */
+  37/*PMC2A*/,36/*PMC2B*/,35/*PMC2C*/,34/*PMC2D*/,23/*1GHZ*/, 0,0,0,
+  /* GPP24-31 */
+  7/*watchdog*/, 0,0,0,0,0,0,0
+};
+
+/*
+ * This code assumes the exceptions management setup has already
+ * been done. We just need to replace the exceptions that will
+ * be handled like interrupt. On MPC7455 and many PPC processors
+ * this means the decrementer exception and the external exception.
+ */
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+  int                   i;
+  rtems_interrupt_level level;
+
+  /*
+   * First initialize the Interrupt management hardware
+   */
+#ifdef TRACE_IRQ_INIT
+  printk("Initializing the interrupt controller of the GT64260\n");
+#endif
+
+#ifdef TRACE_IRQ_INIT
+  printk("Going to re-initialize the rtemsIrq table %d\n",BSP_IRQ_NUMBER);
+#endif
+  /*
+   * Initialize Rtems management interrupt table
+   */
+  /*
+   * re-init the rtemsIrq table
+   */
+  for (i = 0; i < BSP_IRQ_NUMBER; i++) {
+    rtemsIrq[i]      = defaultIrq;
+    rtemsIrq[i].name = i;
+  }
+
+  /*
+   * Init initial Interrupt management config
+   */
+  initial_config.irqNb 	= BSP_IRQ_NUMBER;
+  initial_config.defaultEntry   = defaultIrq;
+  initial_config.irqHdlTbl	= rtemsIrq;
+  initial_config.irqBase	= BSP_LOWEST_OFFSET;
+  initial_config.irqPrioTbl	= BSPirqPrioTable;
+
+#ifdef TRACE_IRQ_INIT
+  printk("Going to setup irq mngt configuration\n");
+#endif
+
+  rtems_interrupt_disable(level);
+  (void) level; /* avoid set but not used warning */
+
+  if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+      /*
+       * put something here that will show the failure...
+       */
+      rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+  }
+#ifdef TRACE_IRQ_INIT
+  printk("Done setup irq mngt configuration\n");
+#endif
+
+#ifdef TRACE_IRQ_INIT
+  printk("RTEMS IRQ management is now operationnal\n");
+#endif
+}
Index: bsps/powerpc/psim/irq/irq_init.c
===================================================================
--- bsps/powerpc/psim/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/psim/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,125 @@
+/*
+ *  This file contains the implementation of rtems initialization
+ *  related to interrupt handling
+ */
+
+/*
+ *  Copyright (C) 1999 valette@crf.canon.fr
+ *
+ *  Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ *  to make it valid for MVME2300 Motorola boards.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libcpu/io.h>
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <psim.h>
+#include <bsp/vectors.h>
+#include <rtems/bspIo.h>
+#include <bsp/openpic.h>
+#include <bsp/irq-generic.h>
+
+static rtems_irq_connect_data      rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings   initial_config;
+static rtems_irq_connect_data      defaultIrq = {
+  /* vectorIdex, hdl  , handle  , on  , off , isOn */
+      0,          NULL, NULL    , NULL, NULL, NULL
+};
+static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
+  /*
+   * Processor exceptions handled as interrupts
+   */
+  0
+};
+
+  /*
+   * This code assumes the exceptions management setup has already
+   * been done. We just need to replace the exceptions that will
+   * be handled like interrupt. On mcp750/mpc750 and many PPC processors
+   * this means the decrementer exception and the external exception.
+   */
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+  int i;
+
+  /*
+   * First initialize the Interrupt management hardware
+   */
+  OpenPIC = (void*)PSIM.OpenPIC;
+  openpic_init(1,0,0,16,0,0);
+
+  /*
+   * Initialize Rtems management interrupt table
+   */
+  /*
+   * re-init the rtemsIrq table
+   */
+  for (i = 0; i < BSP_IRQ_NUMBER; i++) {
+    rtemsIrq[i]      = defaultIrq;
+    rtemsIrq[i].name = i;
+  }
+  /*
+   * Init initial Interrupt management config
+   */
+  initial_config.irqNb        = BSP_IRQ_NUMBER;
+  initial_config.defaultEntry = defaultIrq;
+  initial_config.irqHdlTbl    = rtemsIrq;
+  initial_config.irqBase      = BSP_LOWEST_OFFSET;
+  initial_config.irqPrioTbl   = irqPrioTable;
+
+  for (i = BSP_PCI_IRQ_LOWEST_OFFSET; i< BSP_PCI_IRQ_NUMBER; i++ ) {
+  	irqPrioTable[i] = 8;
+  }
+
+  if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+    /*
+     * put something here that will show the failure...
+     */
+    rtems_panic(
+      "Unable to initialize RTEMS interrupt Management!!! System locked\n"
+    );
+  }
+
+  #ifdef TRACE_IRQ_INIT
+    printk("RTEMS IRQ management is now operationnal\n");
+  #endif
+}
+
+static int psim_exception_handler(
+  BSP_Exception_frame *frame,
+  unsigned exception_number
+)
+{
+  rtems_panic("Unexpected interrupt occured");
+  return 0;
+}
+
+/*
+ * functions to enable/disable a source at the ipic
+ */
+void bsp_interrupt_vector_enable( rtems_vector_number irqnum)
+{
+  /* FIXME: do something */
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(irqnum));
+}
+
+void bsp_interrupt_vector_disable( rtems_vector_number irqnum)
+{
+  /* FIXME: do something */
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(irqnum));
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+  /* Install exception handler */
+  if (ppc_exc_set_handler( ASM_EXT_VECTOR, psim_exception_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+  
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/qemuppc/irq/irq_init.c
===================================================================
--- bsps/powerpc/qemuppc/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/qemuppc/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,61 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC83xx BSP                              |
++-----------------------------------------------------------------+
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file integrates the IPIC irq controller                    |
+\*===============================================================*/
+
+#include <rtems.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/vectors.h>
+
+static int qemuppc_exception_handler(
+  BSP_Exception_frame *frame,
+  unsigned exception_number
+)
+{
+  rtems_panic("Unexpected interrupt occured");
+  return 0;
+}
+
+/*
+ * functions to enable/disable a source at the ipic
+ */
+void bsp_interrupt_vector_enable( rtems_vector_number irqnum)
+{
+  /* FIXME: do something */
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(irqnum));
+}
+
+void bsp_interrupt_vector_disable( rtems_vector_number irqnum)
+{
+  /* FIXME: do something */
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(irqnum));
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+  /* Install exception handler */
+  if (ppc_exc_set_handler( ASM_EXT_VECTOR, qemuppc_exception_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/qoriq/irq/irq.c
===================================================================
--- bsps/powerpc/qoriq/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/qoriq/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,387 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief Interrupt implementation.
+ */
+
+/*
+ * Copyright (c) 2010, 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <sys/param.h>
+
+#include <rtems.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <asm/epapr_hcalls.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/vectors.h>
+#include <bsp/utility.h>
+#include <bsp/qoriq.h>
+
+#ifdef RTEMS_SMP
+#include <rtems/score/smpimpl.h>
+#endif
+
+RTEMS_INTERRUPT_LOCK_DEFINE(static, lock, "QorIQ IRQ")
+
+#define SPURIOUS 0xffff
+
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+
+void bsp_interrupt_set_affinity(
+	rtems_vector_number vector,
+	const Processor_mask *affinity
+)
+{
+	uint32_t config;
+	unsigned int priority;
+	uint32_t destination;
+	uint32_t new_destination;
+	rtems_interrupt_lock_context lock_context;
+
+	new_destination = _Processor_mask_Find_last_set(affinity) - 1;
+
+	rtems_interrupt_lock_acquire(&lock, &lock_context);
+	ev_int_get_config(vector, &config, &priority, &destination);
+	ev_int_set_config(vector, config, priority, new_destination);
+	rtems_interrupt_lock_release(&lock, &lock_context);
+}
+
+void bsp_interrupt_get_affinity(
+	rtems_vector_number vector,
+	Processor_mask *affinity
+)
+{
+	uint32_t config;
+	unsigned int priority;
+	uint32_t destination;
+
+	ev_int_get_config(vector, &config, &priority, &destination);
+	_Processor_mask_From_uint32_t(affinity, destination, 0);
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+	bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+	ev_int_set_mask(vector, 0);
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+	bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+	ev_int_set_mask(vector, 1);
+}
+
+void bsp_interrupt_dispatch(uintptr_t exception_number)
+{
+	unsigned int vector;
+
+	if (exception_number == 10) {
+		qoriq_decrementer_dispatch();
+		return;
+	}
+
+#ifdef RTEMS_SMP
+	if (exception_number == 36) {
+		_SMP_Inter_processor_interrupt_handler();
+		return;
+	}
+#endif
+
+	/*
+	 * This works only if the "has-external-proxy" property is present in the
+	 * "epapr,hv-pic" device tree node.
+	 */
+	vector = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_EPR);
+
+	if (vector != SPURIOUS) {
+		uint32_t msr;
+
+		msr = ppc_external_exceptions_enable();
+		bsp_interrupt_handler_dispatch(vector);
+		ppc_external_exceptions_disable(msr);
+
+		ev_int_eoi(vector);
+	} else {
+		bsp_interrupt_handler_default(vector);
+	}
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+	unsigned int i;
+
+	for (i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; ++i) {
+		uint32_t config;
+		unsigned int priority;
+		uint32_t destination;
+		unsigned int err;
+
+		err = ev_int_get_config(i, &config, &priority, &destination);
+		if (err != EV_SUCCESS)
+			continue;
+
+		priority = QORIQ_PIC_PRIORITY_DEFAULT;
+
+		ev_int_set_config(i, config, priority, destination);
+	}
+
+	return RTEMS_SUCCESSFUL;
+}
+
+#else /* !QORIQ_IS_HYPERVISOR_GUEST */
+
+#define VPR_MSK BSP_BBIT32(0)
+#define VPR_A BSP_BBIT32(1)
+#define VPR_P BSP_BBIT32(8)
+#define VPR_S BSP_BBIT32(9)
+#define VPR_PRIORITY(val) BSP_BFLD32(val, 12, 15)
+#define VPR_PRIORITY_GET(reg) BSP_BFLD32GET(reg, 12, 15)
+#define VPR_PRIORITY_SET(reg, val) BSP_BFLD32SET(reg, val, 12, 15)
+#define VPR_VECTOR(val) BSP_BFLD32(val, 16, 31)
+#define VPR_VECTOR_GET(reg) BSP_BFLD32GET(reg, 16, 31)
+#define VPR_VECTOR_SET(reg, val) BSP_BFLD32SET(reg, val, 16, 31)
+
+#define GCR_RST BSP_BBIT32(0)
+#define GCR_M BSP_BBIT32(2)
+
+#define SRC_CFG_IDX(i) ((i) - QORIQ_IRQ_EXT_BASE)
+
+static const uint16_t src_cfg_offsets [] = {
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_0)] = 0x10000 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_1)] = 0x10020 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_2)] = 0x10040 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_3)] = 0x10060 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_4)] = 0x10080 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_5)] = 0x100a0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_6)] = 0x100c0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_7)] = 0x100e0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_8)] = 0x10100 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_9)] = 0x10120 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_10)] = 0x10140 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_EXT_11)] = 0x10160 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_IPI_0)] = 0x010a0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_IPI_1)] = 0x010b0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_IPI_2)] = 0x010c0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_IPI_3)] = 0x010d0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_0)] = 0x11600 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_1)] = 0x11620 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_2)] = 0x11640 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_3)] = 0x11660 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_4)] = 0x11680 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_5)] = 0x116a0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_6)] = 0x116c0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MI_7)] = 0x116e0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_0)] = 0x11c00 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_1)] = 0x11c20 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_2)] = 0x11c40 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_3)] = 0x11c60 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_4)] = 0x11c80 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_5)] = 0x11ca0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_6)] = 0x11cc0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_MSI_7)] = 0x11ce0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_A_0)] = 0x01120 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_A_1)] = 0x01160 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_A_2)] = 0x011a0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_A_3)] = 0x011e0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_B_0)] = 0x02120 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_B_1)] = 0x02160 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_B_2)] = 0x021a0 >> 4,
+	[SRC_CFG_IDX(QORIQ_IRQ_GT_B_3)] = 0x021e0 >> 4
+};
+
+static volatile qoriq_pic_src_cfg *get_src_cfg(rtems_vector_number vector)
+{
+	uint32_t n = MIN(RTEMS_ARRAY_SIZE(qoriq.pic.ii_0), QORIQ_IRQ_EXT_BASE);
+
+	if (vector < n) {
+		return &qoriq.pic.ii_0 [vector];
+	} else if (vector < QORIQ_IRQ_EXT_BASE) {
+		return &qoriq.pic.ii_1 [vector - n];
+	} else {
+		uintptr_t offs = ((uintptr_t)
+			src_cfg_offsets [vector - QORIQ_IRQ_EXT_BASE]) << 4;
+
+		return (volatile qoriq_pic_src_cfg *) ((uintptr_t) &qoriq.pic + offs);
+	}
+}
+
+rtems_status_code qoriq_pic_set_priority(
+	rtems_vector_number vector,
+	int new_priority,
+	int *old_priority
+)
+{
+	rtems_status_code sc = RTEMS_SUCCESSFUL;
+	uint32_t old_vpr = 0;
+
+	if (bsp_interrupt_is_valid_vector(vector)) {
+		volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
+
+		if (QORIQ_PIC_PRIORITY_IS_VALID(new_priority)) {
+			rtems_interrupt_lock_context lock_context;
+
+			rtems_interrupt_lock_acquire(&lock, &lock_context);
+			old_vpr = src_cfg->vpr;
+			src_cfg->vpr = VPR_PRIORITY_SET(old_vpr, (uint32_t) new_priority);
+			rtems_interrupt_lock_release(&lock, &lock_context);
+		} else if (new_priority < 0) {
+			old_vpr = src_cfg->vpr;
+		} else {
+			sc = RTEMS_INVALID_PRIORITY;
+		}
+	} else {
+		sc = RTEMS_INVALID_ID;
+	}
+
+	if (old_priority != NULL) {
+		*old_priority = (int) VPR_PRIORITY_GET(old_vpr);
+	}
+
+	return sc;
+}
+
+void bsp_interrupt_set_affinity(
+	rtems_vector_number vector,
+	const Processor_mask *affinity
+)
+{
+	volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
+
+	src_cfg->dr = _Processor_mask_To_uint32_t(affinity, 0);
+}
+
+void bsp_interrupt_get_affinity(
+	rtems_vector_number vector,
+	Processor_mask *affinity
+)
+{
+	volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
+
+	_Processor_mask_From_uint32_t(affinity, src_cfg->dr, 0);
+}
+
+static void pic_vector_enable(rtems_vector_number vector, uint32_t msk)
+{
+	volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
+	rtems_interrupt_lock_context lock_context;
+
+	bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+	rtems_interrupt_lock_acquire(&lock, &lock_context);
+	src_cfg->vpr = (src_cfg->vpr & ~VPR_MSK) | msk;
+	rtems_interrupt_lock_release(&lock, &lock_context);
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+	pic_vector_enable(vector, 0);
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+	pic_vector_enable(vector, VPR_MSK);
+}
+
+void bsp_interrupt_dispatch(uintptr_t exception_number)
+{
+	rtems_vector_number vector = qoriq.pic.iack;
+
+	if (vector != SPURIOUS) {
+		uint32_t msr = ppc_external_exceptions_enable();
+
+		bsp_interrupt_handler_dispatch(vector);
+
+		ppc_external_exceptions_disable(msr);
+
+		qoriq.pic.eoi = 0;
+		qoriq.pic.whoami;
+	} else {
+		bsp_interrupt_handler_default(vector);
+	}
+}
+
+static bool pic_is_ipi(rtems_vector_number vector)
+{
+	return QORIQ_IRQ_IPI_0 <= vector && vector <= QORIQ_IRQ_IPI_3;
+}
+
+static void pic_reset(void)
+{
+	qoriq.pic.gcr = GCR_RST;
+	while ((qoriq.pic.gcr & GCR_RST) != 0) {
+		/* Wait */
+	}
+}
+
+static void pic_global_timer_init(void)
+{
+	int i = 0;
+
+	qoriq.pic.tcra = 0;
+	qoriq.pic.tcrb = 0;
+
+	for (i = 0; i < 4; ++i) {
+		qoriq.pic.gta [0].bcr = GTBCR_CI;
+		qoriq.pic.gtb [0].bcr = GTBCR_CI;
+	}
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+	rtems_vector_number i = 0;
+	uint32_t processor_id = ppc_processor_id();
+
+	if (processor_id == 0) {
+		/* Core 0 must do the basic initialization */
+
+		pic_reset();
+
+		for (i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; ++i) {
+			volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(i);
+
+			src_cfg->vpr = VPR_MSK | VPR_P
+				| VPR_PRIORITY(QORIQ_PIC_PRIORITY_DEFAULT) | VPR_VECTOR(i);
+
+			if (!pic_is_ipi(i)) {
+				src_cfg->dr = 0x1;
+			}
+		}
+
+		qoriq.pic.mer03 = 0xf;
+		qoriq.pic.mer47 = 0xf;
+		qoriq.pic.svr = SPURIOUS;
+		qoriq.pic.gcr = GCR_M;
+
+		pic_global_timer_init();
+	}
+
+	qoriq.pic.ctpr = 0;
+
+	for (i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; ++i) {
+		qoriq.pic.iack;
+		qoriq.pic.eoi = 0;
+		qoriq.pic.whoami;
+	}
+
+	return RTEMS_SUCCESSFUL;
+}
+
+#endif /* QORIQ_IS_HYPERVISOR_GUEST */
Index: bsps/powerpc/shared/irq/i8259.c
===================================================================
--- bsps/powerpc/shared/irq/i8259.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/shared/irq/i8259.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,149 @@
+/*
+ *  This file contains the implementation of the function described in irq.h
+ *  related to Intel 8259 Programmable Interrupt controller.
+ *
+ *  Copyright (C) 1998, 1999 valette@crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/irq.h>
+
+/*-------------------------------------------------------------------------+
+| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
++--------------------------------------------------------------------------*/
+/*
+ * lower byte is interrupt mask on the master PIC.
+ * while upper bits are interrupt on the slave PIC.
+ */
+volatile rtems_i8259_masks i8259s_cache = 0xfffb;
+
+/*-------------------------------------------------------------------------+
+|         Function:  BSP_irq_disable_at_i8259s
+|      Description: Mask IRQ line in appropriate PIC chip.
+| Global Variables: i8259s_cache
+|        Arguments: vector_offset - number of IRQ line to mask.
+|          Returns: original state or -1 on error.
++--------------------------------------------------------------------------*/
+int BSP_irq_disable_at_i8259s    (const rtems_irq_number irqLine)
+{
+  unsigned short        mask;
+  rtems_interrupt_level level;
+  int                   rval;
+
+  if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
+       ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)
+       )
+    return -1;
+
+  rtems_interrupt_disable(level);
+
+  mask = 1 << irqLine;
+  rval = i8259s_cache & mask ? 0 : 1;
+  i8259s_cache |= mask;
+
+  if (irqLine < 8)
+  {
+    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
+  }
+  else
+  {
+    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
+  }
+  rtems_interrupt_enable(level);
+
+  return rval;
+}
+
+/*-------------------------------------------------------------------------+
+|         Function:  BSP_irq_enable_at_i8259s
+|      Description: Unmask IRQ line in appropriate PIC chip.
+| Global Variables: i8259s_cache
+|        Arguments: irqLine - number of IRQ line to mask.
+|          Returns: Nothing.
++--------------------------------------------------------------------------*/
+int BSP_irq_enable_at_i8259s    (const rtems_irq_number irqLine)
+{
+  unsigned short        mask;
+  rtems_interrupt_level level;
+
+  if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
+       ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET )
+       )
+    return 1;
+
+  rtems_interrupt_disable(level);
+
+  mask = ~(1 << irqLine);
+  i8259s_cache &= mask;
+
+  if (irqLine < 8)
+  {
+    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
+  }
+  else
+  {
+    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
+  }
+  rtems_interrupt_enable(level);
+
+  return 0;
+} /* mask_irq */
+
+int BSP_irq_enabled_at_i8259s        	(const rtems_irq_number irqLine)
+{
+  unsigned short mask;
+
+  if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
+       ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)
+     )
+    return 1;
+
+  mask = (1 << irqLine);
+  return  (~(i8259s_cache & mask));
+}
+
+/*-------------------------------------------------------------------------+
+|         Function: BSP_irq_ack_at_i8259s
+|      Description: Signal generic End Of Interrupt (EOI) to appropriate PIC.
+| Global Variables: None.
+|        Arguments: irqLine - number of IRQ line to acknowledge.
+|          Returns: Nothing.
++--------------------------------------------------------------------------*/
+int BSP_irq_ack_at_i8259s  	(const rtems_irq_number irqLine)
+{
+  if (irqLine >= 8) {
+    outport_byte(PIC_MASTER_COMMAND_IO_PORT, SLAVE_PIC_EOSI);
+    outport_byte(PIC_SLAVE_COMMAND_IO_PORT, (PIC_EOSI | (irqLine - 8)));
+  }
+  else {
+    outport_byte(PIC_MASTER_COMMAND_IO_PORT, (PIC_EOSI | irqLine));
+  }
+
+  return 0;
+
+} /* ackIRQ */
+
+void BSP_i8259s_init(void)
+{
+  /*
+   * init master 8259 interrupt controller
+   */
+  outport_byte(PIC_MASTER_COMMAND_IO_PORT, 0x11); /* Start init sequence */
+  outport_byte(PIC_MASTER_IMR_IO_PORT, 0x00);/* Vector base  = 0 */
+  outport_byte(PIC_MASTER_IMR_IO_PORT, 0x04);/* edge tiggered, Cascade (slave) on IRQ2 */
+  outport_byte(PIC_MASTER_IMR_IO_PORT, 0x01);/* Select 8086 mode */
+  outport_byte(PIC_MASTER_IMR_IO_PORT, 0xFB); /* Mask all except cascade */
+  /*
+   * init slave  interrupt controller
+   */
+  outport_byte(PIC_SLAVE_COMMAND_IO_PORT, 0x11); /* Start init sequence */
+  outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x08);/* Vector base  = 8 */
+  outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x02);/* edge triggered, Cascade (slave) on IRQ2 */
+  outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x01); /* Select 8086 mode */
+  outport_byte(PIC_SLAVE_IMR_IO_PORT, 0xFF); /* Mask all */
+
+}
Index: bsps/powerpc/shared/irq/irq_init.c
===================================================================
--- bsps/powerpc/shared/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/shared/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,364 @@
+/* irq_init.c
+ *
+ *  This file contains the implementation of rtems initialization
+ *  related to interrupt handling.
+ *
+ *  CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ * to make it valid for MVME2300 Motorola boards.
+ *
+ * Till Straumann <strauman@slac.stanford.edu>, 12/20/2001:
+ * Use the new interface to openpic_init
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libcpu/io.h>
+#include <libcpu/spr.h>
+#include <bsp/pci.h>
+#include <bsp/residual.h>
+#include <bsp/irq.h>
+#if BSP_PCI_IRQ_NUMBER > 0
+#include <bsp/openpic.h>
+#endif
+#include <bsp/irq_supp.h>
+#include <bsp.h>
+#include <bsp/motorola.h>
+#include <rtems/bspIo.h>
+
+typedef struct {
+  unsigned char bus;	/* few chance the PCI/ISA bridge is not on first bus but ... */
+  unsigned char device;
+  unsigned char function;
+} pci_isa_bridge_device;
+
+pci_isa_bridge_device* via_82c586 = 0;
+#ifndef qemu
+static pci_isa_bridge_device bridge;
+#endif
+
+/*
+ * default methods
+ */
+static void nop_hdl(rtems_irq_hdl_param ignored)
+{
+}
+
+static void nop_irq_enable(const struct __rtems_irq_connect_data__*ignored)
+{
+}
+
+static int irq_is_connected(const struct __rtems_irq_connect_data__*ignored)
+{
+  return 0;
+}
+
+
+static rtems_irq_connect_data     	rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings     	initial_config;
+static rtems_irq_connect_data     	defaultIrq = {
+  0,                /* vector */
+  nop_hdl,          /* hdl */
+  NULL,             /* handle */
+  nop_irq_enable,   /* on */
+  nop_irq_enable,   /* off */
+  irq_is_connected  /* isOn */
+#ifdef BSP_SHARED_HANDLER_SUPPORT
+  , NULL /* next_handler */
+#endif
+};
+static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
+  /*
+   * actual priorities for interrupt :
+   *	0   means that only current interrupt is masked
+   *	255 means all other interrupts are masked
+   */
+  /*
+   * ISA interrupts.
+   * The second entry has a priority of 255 because
+   * it is the slave pic entry and should always remain
+   * unmasked.
+   */
+  0,0,
+  255,
+  0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+#if BSP_PCI_IRQ_NUMBER > 0
+  /*
+   * PCI Interrupts
+   */
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
+#endif
+  /*
+   * Processor exceptions handled as interrupts
+   */
+  0
+};
+
+#if BSP_PCI_IRQ_NUMBER > 0
+#if defined(mvme2100)
+static unsigned char mvme2100_openpic_initpolarities[16] = {
+    0,  /* Not used - should be disabled */
+    0,	/* DEC21143 Controller */
+    0,  /* PMC/PC-MIP Type I Slot 0 */
+    0,  /* PC-MIP Type I Slot 1 */
+    0,  /* PC-MIP Type II Slot 0 */
+    0,  /* PC-MIP Type II Slot 1 */
+    0,  /* Not used - should be disabled */
+    0,  /* PCI Expansion Interrupt A/Universe II (LINT0) */
+    0,  /* PCI Expansion Interrupt B/Universe II (LINT1) */
+    0,  /* PCI Expansion Interrupt C/Universe II (LINT2) */
+    0,  /* PCI Expansion Interrupt D/Universe II (LINT3) */
+    0,  /* Not used - should be disabled */
+    0,  /* Not used - should be disabled */
+    1,  /* 16550 UART */
+    0,  /* Front panel Abort Switch */
+    0,  /* RTC IRQ */
+};
+
+static unsigned char mvme2100_openpic_initsenses[] = {
+    0,  /* Not used - should be disabled */
+    1,	/* DEC21143 Controller */
+    1,  /* PMC/PC-MIP Type I Slot 0 */
+    1,  /* PC-MIP Type I Slot 1 */
+    1,  /* PC-MIP Type II Slot 0 */
+    1,  /* PC-MIP Type II Slot 1 */
+    0,  /* Not used - should be disabled */
+    1,  /* PCI Expansion Interrupt A/Universe II (LINT0) */
+    1,  /* PCI Expansion Interrupt B/Universe II (LINT1) */
+    1,  /* PCI Expansion Interrupt C/Universe II (LINT2) */
+    1,  /* PCI Expansion Interrupt D/Universe II (LINT3) */
+    0,  /* Not used - should be disabled */
+    0,  /* Not used - should be disabled */
+    1,  /* 16550 UART */
+    0,  /* Front panel Abort Switch */
+    1,  /* RTC IRQ */
+};
+#else
+static unsigned char mcp750_openpic_initpolarities[16] = {
+    1,  /* 8259 cascade */
+    0,	/* all the rest of them */
+};
+
+static unsigned char mcp750_openpic_initsenses[] = {
+    1,	/* MCP750_INT_PCB(8259) */
+    0,	/* MCP750_INT_FALCON_ECC_ERR */
+    1,	/* MCP750_INT_PCI_ETHERNET */
+    1,	/* MCP750_INT_PCI_PMC */
+    1,	/* MCP750_INT_PCI_WATCHDOG_TIMER1 */
+    1,	/* MCP750_INT_PCI_PRST_SIGNAL */
+    1,	/* MCP750_INT_PCI_FALL_SIGNAL */
+    1,	/* MCP750_INT_PCI_DEG_SIGNAL */
+    1,	/* MCP750_INT_PCI_BUS1_INTA */
+    1,	/* MCP750_INT_PCI_BUS1_INTB */
+    1,	/* MCP750_INT_PCI_BUS1_INTC */
+    1,	/* MCP750_INT_PCI_BUS1_INTD */
+    1,	/* MCP750_INT_PCI_BUS2_INTA */
+    1,	/* MCP750_INT_PCI_BUS2_INTB */
+    1,	/* MCP750_INT_PCI_BUS2_INTC */
+    1,	/* MCP750_INT_PCI_BUS2_INTD */
+};
+#endif
+#endif
+
+#if BSP_ISA_IRQ_NUMBER > 0 && !defined(qemu)
+void VIA_isa_bridge_interrupts_setup(void)
+{
+  pci_isa_bridge_device pci_dev;
+  uint32_t temp;
+  unsigned char tmp;
+  unsigned char maxBus;
+  unsigned found = 0;
+
+  maxBus = pci_bus_count();
+  pci_dev.function 	= 0; /* Assumes the bidge is the first function */
+
+  for (pci_dev.bus = 0; pci_dev.bus < maxBus; pci_dev.bus++) {
+#ifdef SCAN_PCI_PRINT
+    printk("isa_bridge_interrupts_setup: Scanning bus %d\n", pci_dev.bus);
+#endif
+    for (pci_dev.device = 0; pci_dev.device < PCI_MAX_DEVICES; pci_dev.device++) {
+#ifdef SCAN_PCI_PRINT
+      printk("isa_bridge_interrupts_setup: Scanning device %d\n", pci_dev.device);
+#endif
+      pci_read_config_dword(pci_dev.bus, pci_dev.device,  pci_dev.function,
+			       PCI_VENDOR_ID, &temp);
+#ifdef SCAN_PCI_PRINT
+      printk("Vendor/device = %x\n", temp);
+#endif
+      if ((temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_0 << 16)))
+	 ) {
+	bridge = pci_dev;
+	via_82c586 = &bridge;
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+	/*
+	 * Should print : bus = 0, device = 11, function = 0 on a MCP750.
+	 */
+	printk("Via PCI/ISA bridge found at bus = %d, device = %d, function = %d\n",
+	       via_82c586->bus,
+	       via_82c586->device,
+	       via_82c586->function);
+#endif
+	found = 1;
+	goto loop_exit;
+
+      }
+    }
+  }
+loop_exit:
+  if (!found) rtems_panic("VIA_82C586 PCI/ISA bridge not found!n");
+
+  tmp = inb(0x810);
+  if  ( !(tmp & 0x2)) {
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+    printk("This is a second generation MCP750 board\n");
+    printk("We must reprogram the PCI/ISA bridge...\n");
+#endif
+    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+			 0x47,  &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
+#endif
+    /*
+     * Enable 4D0/4D1 ISA interrupt level/edge config registers
+     */
+    tmp |= 0x20;
+    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+			  0x47, tmp);
+    /*
+     * Now program the ISA interrupt edge/level
+     */
+    tmp = ELCRS_INT9_LVL | ELCRS_INT10_LVL | ELCRS_INT11_LVL;
+    outb(tmp, ISA8259_S_ELCR);
+    tmp = ELCRM_INT5_LVL;
+    outb(tmp, ISA8259_M_ELCR);
+    /*
+     * Set the Interrupt inputs to non-inverting level interrupt
+     */
+    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+			    0x54, &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
+#endif
+    tmp = 0;
+    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+			  0x54, tmp);
+  }
+  else {
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+    printk("This is a first generation MCP750 board\n");
+    printk("We just show the actual value used by PCI/ISA bridge\n");
+#endif
+    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+			 0x47,  &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
+#endif
+    /*
+     * Show the Interrupt inputs inverting/non-inverting level status
+     */
+    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+			 0x54, &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
+#endif
+  }
+}
+#endif
+
+  /*
+   * This code assumes the exceptions management setup has already
+   * been done. We just need to replace the exceptions that will
+   * be handled like interrupt. On mcp750/mpc750 and many PPC processors
+   * this means the decrementer exception and the external exception.
+   */
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+#if BSP_ISA_IRQ_NUMBER > 0 && !defined(mvme2100)
+  int known_cpi_isa_bridge = 0;
+#endif
+  int i;
+
+  /*
+   * First initialize the Interrupt management hardware
+   */
+#if defined(mvme2100)
+#ifdef TRACE_IRQ_INIT
+  printk("Going to initialize EPIC interrupt controller (openpic compliant)\n");
+#endif
+  /* EPIC sources don't start at the regular place; define appropriate offset
+   * prior to initializing the PIC.
+   */
+  openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses, 16, 16, BSP_bus_frequency);
+#else
+#if BSP_PCI_IRQ_NUMBER > 0
+#ifdef TRACE_IRQ_INIT
+  printk("Going to initialize raven interrupt controller (openpic compliant)\n");
+#endif
+  openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses, 0, 0, 0);
+#ifdef TRACE_IRQ_INIT
+  printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
+#endif
+#endif
+
+#if BSP_ISA_IRQ_NUMBER > 0
+  if ( currentBoard == MESQUITE ) {
+#ifndef qemu
+    VIA_isa_bridge_interrupts_setup();
+#endif
+    known_cpi_isa_bridge = 1;
+  }
+  if ( currentBoard == MVME_2300 ) {
+    /* nothing to do for W83C553 bridge */
+    known_cpi_isa_bridge = 1;
+  }
+  if ( currentBoard == MTX_WO_PP || currentBoard == MTX_W_PP ) {
+     /* W83C554, don't to anything at the moment.  gregm 11/6/2002 */
+     known_cpi_isa_bridge = 1;
+  }
+
+  if (!known_cpi_isa_bridge) {
+    printk("Please add code for PCI/ISA bridge init to libbsp/powerpc/shared/irq/irq_init.c\n");
+    printk("If your card works correctly please add a test and set known_cpi_isa_bridge to true\n");
+    printk("currentBoard = %i\n", currentBoard);
+  }
+#ifdef TRACE_IRQ_INIT
+  printk("Going to initialize the ISA PC legacy IRQ management hardware\n");
+#endif
+  BSP_i8259s_init();
+#endif
+
+#endif
+
+  /*
+   * Initialize RTEMS management interrupt table
+   */
+    /*
+     * re-init the rtemsIrq table
+     */
+    for (i = 0; i < BSP_IRQ_NUMBER; i++) {
+      rtemsIrq[i]      = defaultIrq;
+      rtemsIrq[i].name = i;
+    }
+    /*
+     * Init initial Interrupt management config
+     */
+    initial_config.irqNb 	= BSP_IRQ_NUMBER;
+    initial_config.defaultEntry = defaultIrq;
+    initial_config.irqHdlTbl	= rtemsIrq;
+    initial_config.irqBase	= BSP_LOWEST_OFFSET;
+    initial_config.irqPrioTbl	= irqPrioTable;
+
+    if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+      /*
+       * put something here that will show the failure...
+       */
+      rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+    }
+
+#ifdef TRACE_IRQ_INIT
+    printk("RTEMS IRQ management is now operational\n");
+#endif
+}
Index: bsps/powerpc/shared/irq/openpic.c
===================================================================
--- bsps/powerpc/shared/irq/openpic.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/shared/irq/openpic.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,622 @@
+/*
+ *  openpic.c -- OpenPIC Interrupt Handling
+ *
+ *  Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  Modified to compile in RTEMS development environment
+ *  by Eric Valette
+ *
+ *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+/*
+ *  Note: Interprocessor Interrupt (IPI) and Timer support is incomplete
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/bspIo.h>
+#include <bsp/openpic.h>
+#include <rtems/pci.h>
+#include <libcpu/io.h>
+#include <libcpu/byteorder.h>
+#include <rtems/bspIo.h>
+#include <inttypes.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+#define REGISTER_DEBUG
+#undef REGISTER_DEBUG
+
+volatile struct OpenPIC *OpenPIC = NULL;
+
+static unsigned int NumProcessors;
+static unsigned int NumSources;
+
+static unsigned int openpic_eoi_delay = 0;
+static          int openpic_src_offst = 0;
+#define SOURCE(irq)	Source[ (irq) + openpic_src_offst ]
+
+    /*
+     *  Accesses to the current processor's registers
+     */
+
+#define THIS_CPU		Processor[cpu]
+#define CHECK_THIS_CPU		check_arg_cpu(cpu)
+
+    /*
+     *  Sanity checks
+     */
+
+#if 1
+/* This software deliberately uses non-zero values to the method
+ * __builtin_return_address() and we want to avoid the GCC warning.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-address"
+#define check_arg_ipi(ipi) \
+    if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \
+	printk("openpic.c:%d: illegal ipi %d\n", __LINE__, ipi);
+#define check_arg_timer(timer) \
+    if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \
+	printk("openpic.c:%d: illegal timer %d\n", __LINE__, timer);
+#define check_arg_vec(vec) \
+    if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \
+	printk("openpic.c:%d: illegal vector %d\n", __LINE__, vec);
+#define check_arg_pri(pri) \
+    if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
+	printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri);
+#define check_arg_irq(irq) \
+    if (irq < 0 || irq >= NumSources) \
+	printk("openpic.c:%d: illegal irq %d from 0x%08" PRIxPTR ",[0x%08" PRIxPTR "],[[0x%08" PRIxPTR "]]\n", \
+	       __LINE__, irq, (uintptr_t) __builtin_return_address(0), \
+	       (uintptr_t) __builtin_return_address(1), (uintptr_t) __builtin_return_address(2) \
+	       );
+#define check_arg_cpu(cpu) \
+    if (cpu < 0 || cpu >= NumProcessors) \
+	printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu);
+#else
+#define check_arg_ipi(ipi)	do {} while (0)
+#define check_arg_timer(timer)	do {} while (0)
+#define check_arg_vec(vec)	do {} while (0)
+#define check_arg_pri(pri)	do {} while (0)
+#define check_arg_irq(irq)	do {} while (0)
+#define check_arg_cpu(cpu)	do {} while (0)
+#endif
+
+    /*
+     *  I/O functions
+     */
+
+static inline unsigned int openpic_read(volatile unsigned int *addr)
+{
+    unsigned int val;
+
+#ifdef BSP_OPEN_PIC_BIG_ENDIAN
+	val = in_be32((volatile uint32_t *)addr);
+#else
+    val = in_le32((volatile uint32_t *)addr);
+#endif
+#ifdef REGISTER_DEBUG
+    printk("openpic_read(0x%08x) = 0x%08x\n", (unsigned int)addr, val);
+#endif
+    return val;
+}
+
+static inline void openpic_write(volatile unsigned int *addr, unsigned int val)
+{
+#ifdef REGISTER_DEBUG
+    printk("openpic_write(0x%08x, 0x%08x)\n", (unsigned int)addr, val);
+#endif
+#ifdef BSP_OPEN_PIC_BIG_ENDIAN
+    out_be32((volatile uint32_t *)addr, val);
+#else
+	out_le32((volatile uint32_t *)addr, val);
+#endif
+}
+
+static inline unsigned int openpic_readfield(volatile unsigned int *addr, unsigned int mask)
+{
+    unsigned int val = openpic_read(addr);
+    return val & mask;
+}
+
+static inline void openpic_writefield(volatile unsigned int *addr, unsigned int mask,
+				      unsigned int field)
+{
+    unsigned int val = openpic_read(addr);
+    openpic_write(addr, (val & ~mask) | (field & mask));
+}
+
+static inline void openpic_clearfield(volatile unsigned int *addr, unsigned int mask)
+{
+    openpic_writefield(addr, mask, 0);
+}
+
+static inline void openpic_setfield(volatile unsigned int *addr, unsigned int mask)
+{
+    openpic_writefield(addr, mask, mask);
+}
+
+    /*
+     *  Update a Vector/Priority register in a safe manner. The interrupt will
+     *  be disabled.
+     */
+
+static void openpic_safe_writefield(volatile unsigned int *addr, unsigned int mask,
+				    unsigned int field)
+{
+    openpic_setfield(addr, OPENPIC_MASK);
+    /* wait until it's not in use */
+    while (openpic_read(addr) & OPENPIC_ACTIVITY);
+    openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
+}
+
+/* -------- Global Operations ---------------------------------------------- */
+
+    /*
+     *  Initialize the OpenPIC
+     *
+     * Add some kludge to use the Motorola Raven OpenPIC which does not
+     * report vendor and device id, and gets the wrong number of interrupts.
+     * (Motorola did a great job on that one!)
+     *
+     * T. Straumann, 12/20/2001: polarities and senses are now passed as
+     *                           parameters, eliminated global vars.
+     *                           IRQ0 is no longer treated specially.
+     */
+
+void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses, int num_sources, int source_offset, unsigned long epic_freq)
+{
+    unsigned int t, i;
+    unsigned int vendorid, devid, stepping, timerfreq;
+    const char *version, *vendor, *device;
+
+    if (!OpenPIC)
+	rtems_panic("No OpenPIC found");
+
+    t = openpic_read(&OpenPIC->Global.Feature_Reporting0);
+    switch (t & OPENPIC_FEATURE_VERSION_MASK) {
+	case 1:
+	    version = "1.0";
+	    break;
+	case 2:
+	    version = "1.2";
+	    break;
+	default:
+	    version = "?";
+	    break;
+    }
+    NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >>
+		     OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1;
+    NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
+		  OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1;
+    t = openpic_read(&OpenPIC->Global.Vendor_Identification);
+
+    vendorid = t & OPENPIC_VENDOR_ID_VENDOR_ID_MASK;
+    devid = (t & OPENPIC_VENDOR_ID_DEVICE_ID_MASK) >>
+	    OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT;
+    stepping = (t & OPENPIC_VENDOR_ID_STEPPING_MASK) >>
+	       OPENPIC_VENDOR_ID_STEPPING_SHIFT;
+
+    /* Kludge for the Raven */
+/*
+    pci_read_config_dword(0, 0, 0, 0, &t);
+*/
+    if (t == PCI_VENDOR_ID_MOTOROLA + (PCI_DEVICE_ID_MOTOROLA_RAVEN<<16)) {
+    	vendor = "Motorola";
+	device = "Raven";
+	NumSources += 1;
+    }
+    else if (t == PCI_VENDOR_ID_MOTOROLA + (PCI_DEVICE_ID_MOTOROLA_HAWK<<16)) {
+    	vendor = "Motorola";
+	device = "Hawk";
+	NumSources += 1;
+    } else {
+	switch (vendorid) {
+	    case OPENPIC_VENDOR_ID_APPLE:
+	  	vendor = "Apple";
+	    	break;
+	    default:
+	    	vendor = "Unknown";
+	    break;
+	}
+	switch (devid) {
+	    case OPENPIC_DEVICE_ID_APPLE_HYDRA:
+	    	device = "Hydra";
+		break;
+	    default:
+	        device = "Unknown";
+		break;
+	}
+    }
+    printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at 0x%08" PRIuPTR "\n", version,
+	   NumProcessors, NumSources, (uintptr_t) OpenPIC);
+
+    printk("OpenPIC Vendor %d (%s), Device %d (%s), Stepping %d\n", vendorid,
+	   vendor, devid, device, stepping);
+
+	/* Override if they desire */
+	if ( num_sources ) {
+		if ( NumSources != num_sources )
+			printk("Overriding NumSources (%i) from configuration with %i\n",
+				NumSources, num_sources);
+		NumSources = num_sources;
+	}
+
+	openpic_src_offst = source_offset;
+
+    timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
+    printk("OpenPIC timer frequency is ");
+    if (timerfreq)
+	printk("%d Hz\n", timerfreq);
+    else
+	printk("not set\n");
+
+    if ( main_pic )
+    {
+	    /* Initialize timer interrupts */
+	    for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
+		    /* Disabled, Priority 0 */
+		    openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i);
+		    /* No processor */
+		    openpic_maptimer(i, 0);
+	    }
+
+	    /* Initialize IPI interrupts */
+	    for (i = 0; i < OPENPIC_NUM_IPI; i++) {
+		    /* Disabled, Priority 0 */
+		    openpic_initipi(i, 0, OPENPIC_VEC_IPI+i);
+	    }
+
+	    /* Initialize external interrupts */
+	    for (i = 0; i < NumSources; i++) {
+		    /* Enabled, Priority 8 */
+		    openpic_initirq(i, 8, OPENPIC_VEC_SOURCE+i,
+					polarities ? polarities[i] : 0,
+					senses     ? senses[i]     : 1);
+		    /* Processor 0 */
+		    openpic_mapirq(i, 1<<0);
+	    }
+
+	    /* Initialize the spurious interrupt */
+	    openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
+#if 0
+	    if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT,
+			    "82c59 cascade", NULL))
+	      printk("Unable to get OpenPIC IRQ 0 for cascade\n");
+#endif
+	    openpic_set_priority(0, 0);
+	    openpic_disable_8259_pass_through();
+    }
+	if ( epic_freq ) {
+		/* Speed up the serial interface; if it is too slow then we might get spurious
+		 * interrupts:
+		 * After an ISR clears the interrupt condition at the source/device, the wire
+		 * remains asserted during the propagation delay introduced by the serial interface
+		 * (something really stupid). If the ISR returns while the wire is not released
+		 * yet, then a spurious interrupt happens.
+		 * The book says we should be careful if the serial clock is > 33MHz.
+		 * Empirically, it seems that running it at 33MHz is fast enough. Otherwise,
+		 * we should introduce a delay in openpic_eoi().
+		 * The maximal delay are 16 (serial) clock cycles. If the divisor is 8
+		 * [power-up default] then the lag is 2us [66MHz SDRAM clock; I assume this
+		 * is equal to the bus frequency].
+		 * FIXME: This should probably be a EPIC-specific piece in 'openpic.c'
+		 *        Unfortunately, there is no easy way of figuring out if the
+		 *        device is an EPIC or not.
+		 */
+		uint32_t eicr_val, ratio;
+		/* On the 8240 this is the EICR register */
+		eicr_val = in_le32( (volatile uint32_t *)&OpenPIC->Global.Global_Configuration1 ) & ~(7<<28);
+		if ( (1<<27) & eicr_val ) {
+			/* serial interface mode enabled */
+
+			/* round to nearest integer:
+			 *   round(Bus_freq/33000000) = floor( 2*(Bus_freq/33e6) + 1 ) / 2
+			 */
+			ratio   = epic_freq / 16500000 + 1;
+			ratio >>= 2; /* EICR value is half actual divisor */
+			if ( 0==ratio )
+				ratio = 1;
+			out_le32((volatile uint32_t *)&OpenPIC->Global.Global_Configuration1, eicr_val | ((ratio &7) << 28));
+			/*  Delay in TB cycles (assuming TB runs at 1/4 of the bus frequency) */
+			openpic_set_eoi_delay( 16 * (2*ratio) / 4 );
+		}
+	}
+}
+
+    /*
+     *  Reset the OpenPIC
+     */
+
+void openpic_reset(void)
+{
+    openpic_setfield(&OpenPIC->Global.Global_Configuration0,
+    		       OPENPIC_CONFIG_RESET);
+}
+
+    /*
+     *  Enable/disable 8259 Pass Through Mode
+     */
+
+void openpic_enable_8259_pass_through(void)
+{
+    openpic_clearfield(&OpenPIC->Global.Global_Configuration0,
+    		       OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
+}
+
+void openpic_disable_8259_pass_through(void)
+{
+    openpic_setfield(&OpenPIC->Global.Global_Configuration0,
+    		     OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
+}
+
+    /*
+     *  Find out the current interrupt
+     */
+
+unsigned int openpic_irq(unsigned int cpu)
+{
+    unsigned int vec;
+
+    check_arg_cpu(cpu);
+    vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge,
+			    OPENPIC_VECTOR_MASK);
+    return vec;
+}
+
+    /*
+     *  Signal end of interrupt (EOI) processing
+     */
+
+void openpic_eoi(unsigned int cpu)
+{
+    check_arg_cpu(cpu);
+    if ( openpic_eoi_delay )
+        rtems_bsp_delay_in_bus_cycles(openpic_eoi_delay);
+    openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
+}
+
+unsigned openpic_set_eoi_delay(unsigned tb_cycles)
+{
+unsigned rval = openpic_eoi_delay;
+    openpic_eoi_delay = tb_cycles;
+	return rval;
+}
+
+    /*
+     *  Get/set the current task priority
+     */
+
+unsigned int openpic_get_priority(unsigned int cpu)
+{
+    CHECK_THIS_CPU;
+    return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
+			     OPENPIC_CURRENT_TASK_PRIORITY_MASK);
+}
+
+void openpic_set_priority(unsigned int cpu, unsigned int pri)
+{
+    CHECK_THIS_CPU;
+    check_arg_pri(pri);
+    openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority,
+    		       OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri);
+}
+
+    /*
+     *  Get/set the spurious vector
+     */
+
+unsigned int openpic_get_spurious(void)
+{
+    return openpic_readfield(&OpenPIC->Global.Spurious_Vector,
+    			     OPENPIC_VECTOR_MASK);
+}
+
+void openpic_set_spurious(unsigned int vec)
+{
+    check_arg_vec(vec);
+    openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK,
+    		       vec);
+}
+
+    /*
+     *  Initialize one or more CPUs
+     */
+
+void openpic_init_processor(unsigned int cpumask)
+{
+    openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask);
+}
+
+/* -------- Interprocessor Interrupts -------------------------------------- */
+
+    /*
+     *  Initialize an interprocessor interrupt (and disable it)
+     *
+     *  ipi: OpenPIC interprocessor interrupt number
+     *  pri: interrupt source priority
+     *  vec: the vector it will produce
+     */
+
+void openpic_initipi(unsigned int ipi, unsigned int pri, unsigned int vec)
+{
+    check_arg_timer(ipi);
+    check_arg_pri(pri);
+    check_arg_vec(vec);
+    openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi),
+    			    OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
+    			    (pri << OPENPIC_PRIORITY_SHIFT) | vec);
+}
+
+    /*
+     *  Send an IPI to one or more CPUs
+     */
+
+void openpic_cause_IPI(unsigned int cpu, unsigned int ipi, unsigned int cpumask)
+{
+    CHECK_THIS_CPU;
+    check_arg_ipi(ipi);
+    openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask);
+}
+
+/* -------- Timer Interrupts ----------------------------------------------- */
+
+    /*
+     *  Initialize a timer interrupt (and disable it)
+     *
+     *  timer: OpenPIC timer number
+     *  pri: interrupt source priority
+     *  vec: the vector it will produce
+     */
+
+void openpic_inittimer(unsigned int timer, unsigned int pri, unsigned int vec)
+{
+    check_arg_timer(timer);
+    check_arg_pri(pri);
+    check_arg_vec(vec);
+    openpic_safe_writefield(&OpenPIC->Global.Timer[timer].Vector_Priority,
+    			    OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
+    			    (pri << OPENPIC_PRIORITY_SHIFT) | vec);
+}
+
+    /*
+     *  Map a timer interrupt to one or more CPUs
+     */
+
+void openpic_maptimer(unsigned int timer, unsigned int cpumask)
+{
+    check_arg_timer(timer);
+    openpic_write(&OpenPIC->Global.Timer[timer].Destination, cpumask);
+}
+
+    /*
+     *  Set base count and / or enable / disable interrupt.
+     */
+
+
+void openpic_settimer(unsigned int timer, unsigned int base_count, int irq_enable)
+{
+	check_arg_timer(timer);
+	if ( base_count )
+		openpic_write(&OpenPIC->Global.Timer[timer].Base_Count, base_count);
+	if ( irq_enable )
+		openpic_clearfield(&OpenPIC->Global.Timer[timer].Vector_Priority, OPENPIC_MASK);
+	else
+		openpic_setfield(&OpenPIC->Global.Timer[timer].Vector_Priority, OPENPIC_MASK);
+}
+
+unsigned int openpic_gettimer(unsigned int timer)
+{
+	check_arg_timer(timer);
+	return (openpic_read(&OpenPIC->Global.Timer[timer].Current_Count) & ~OPENPIC_MASK);
+}
+
+/* -------- Interrupt Sources ---------------------------------------------- */
+
+    /*
+     *  Enable/disable an interrupt source
+     */
+
+void openpic_enable_irq(unsigned int irq)
+{
+unsigned long flags;
+    check_arg_irq(irq);
+	rtems_interrupt_disable(flags);
+    openpic_clearfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK);
+	rtems_interrupt_enable(flags);
+}
+
+int openpic_disable_irq(unsigned int irq)
+{
+int           rval;
+unsigned long flags;
+    check_arg_irq(irq);
+	if ( irq < 0 || irq >=NumSources )
+		return -1;
+	rtems_interrupt_disable(flags);
+	rval = openpic_readfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK) ? 0 : 1;
+    openpic_setfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK);
+	rtems_interrupt_enable(flags);
+	return rval;
+}
+
+    /*
+     *  Initialize an interrupt source (and disable it!)
+     *
+     *  irq: OpenPIC interrupt number
+     *  pri: interrupt source priority
+     *  vec: the vector it will produce
+     *  pol: polarity (1 for positive, 0 for negative)
+     *  sense: 1 for level, 0 for edge
+     */
+
+void openpic_initirq(unsigned int irq, unsigned int pri, unsigned int vec, int pol, int sense)
+{
+#if 0
+  printk("openpic_initirq: irq=%d pri=%d vec=%d pol=%d sense=%d\n",
+    irq, pri, vec, pol, sense);
+#endif
+
+    check_arg_irq(irq);
+    check_arg_pri(pri);
+    check_arg_vec(vec);
+    openpic_safe_writefield(&OpenPIC->SOURCE(irq).Vector_Priority,
+    			    OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
+    			    OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL,
+    			    (pri << OPENPIC_PRIORITY_SHIFT) | vec |
+			    (pol ? OPENPIC_SENSE_POLARITY : 0) |
+			    (sense ? OPENPIC_SENSE_LEVEL : 0));
+}
+
+    /*
+     *  Map an interrupt source to one or more CPUs
+     */
+
+void openpic_mapirq(unsigned int irq, unsigned int cpumask)
+{
+    check_arg_irq(irq);
+    openpic_write(&OpenPIC->SOURCE(irq).Destination, cpumask);
+}
+
+	/*
+	 * Get the current priority of an external interrupt
+	 */
+unsigned int openpic_get_source_priority(unsigned int irq)
+{
+    check_arg_irq(irq);
+	return openpic_readfield(&OpenPIC->SOURCE(irq).Vector_Priority,
+							 OPENPIC_PRIORITY_MASK) >> OPENPIC_PRIORITY_SHIFT;
+}
+
+void openpic_set_source_priority(unsigned int irq, unsigned int pri)
+{
+unsigned long flags;
+    check_arg_irq(irq);
+    check_arg_pri(pri);
+	rtems_interrupt_disable(flags);
+	openpic_writefield(
+					&OpenPIC->SOURCE(irq).Vector_Priority,
+					OPENPIC_PRIORITY_MASK,
+					pri << OPENPIC_PRIORITY_SHIFT);
+	rtems_interrupt_enable(flags);
+}
+    /*
+     *  Set the sense for an interrupt source (and disable it!)
+     *
+     *  sense: 1 for level, 0 for edge
+     */
+
+void openpic_set_sense(unsigned int irq, int sense)
+{
+    check_arg_irq(irq);
+    openpic_safe_writefield(&OpenPIC->SOURCE(irq).Vector_Priority,
+    			    OPENPIC_SENSE_LEVEL,
+			    (sense ? OPENPIC_SENSE_LEVEL : 0));
+}
Index: bsps/powerpc/shared/irq/openpic_i8259_irq.c
===================================================================
--- bsps/powerpc/shared/irq/openpic_i8259_irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/shared/irq/openpic_i8259_irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,331 @@
+/*
+ *
+ *  This file contains the i8259/openpic-specific implementation of
+ *  the function described in irq.h
+ *
+ *  Copyright (C) 1998, 1999 valette@crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq_supp.h>
+#ifndef BSP_HAS_NO_VME
+#include <bsp/VMEConfig.h>
+#endif
+#if BSP_PCI_IRQ_NUMBER > 0
+#include <bsp/openpic.h>
+#endif
+#include <libcpu/io.h>
+#include <bsp/vectors.h>
+#include <stdlib.h>
+
+#include <rtems/bspIo.h> /* for printk */
+
+#ifndef qemu
+#define RAVEN_INTR_ACK_REG 0xfeff0030
+#else
+#define RAVEN_INTR_ACK_REG 0xbffffff0
+#endif
+
+#if BSP_ISA_IRQ_NUMBER > 0
+/*
+ * pointer to the mask representing the additionnal irq vectors
+ * that must be disabled when a particular entry is activated.
+ * They will be dynamically computed from the priority table given
+ * in BSP_rtems_irq_mngt_set();
+ * CAUTION : this table is accessed directly by interrupt routine
+ * 	     prologue.
+ */
+rtems_i8259_masks 	irq_mask_or_tbl[BSP_IRQ_NUMBER];
+#endif
+
+/*
+ * default handler connected on each irq after bsp initialization
+ */
+static rtems_irq_connect_data	default_rtems_entry;
+
+static rtems_irq_connect_data*		rtems_hdl_tbl;
+
+#if BSP_ISA_IRQ_NUMBER > 0
+/*
+ * Check if IRQ is an ISA IRQ
+ */
+static inline int is_isa_irq(const rtems_irq_number irqLine)
+{
+  return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &&
+	  ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
+	 );
+}
+#endif
+
+#if BSP_PCI_IRQ_NUMBER > 0
+/*
+ * Check if IRQ is an OPENPIC IRQ
+ */
+static inline int is_pci_irq(const rtems_irq_number irqLine)
+{
+  return OpenPIC && (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &&
+	  ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
+	 );
+}
+#endif
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+#if BSP_ISA_IRQ_NUMBER > 0
+/*
+ * Caution : this function assumes the variable "*config"
+ * is already set and that the tables it contains are still valid
+ * and accessible.
+ */
+static void compute_i8259_masks_from_prio (rtems_irq_global_settings* config)
+{
+  int i;
+  int j;
+  /*
+   * Always mask at least current interrupt to prevent re-entrance
+   */
+  for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
+    * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
+    for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) {
+      /*
+       * Mask interrupts at i8259 level that have a lower priority
+       */
+      if (config->irqPrioTbl [i] > config->irqPrioTbl [j]) {
+	* ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
+      }
+    }
+  }
+}
+#endif
+
+void
+BSP_enable_irq_at_pic(const rtems_irq_number name)
+{
+#if BSP_ISA_IRQ_NUMBER > 0
+    if (is_isa_irq(name)) {
+      /*
+       * Enable interrupt at PIC level
+       */
+      BSP_irq_enable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
+    }
+#endif
+
+#if BSP_PCI_IRQ_NUMBER > 0
+    if (is_pci_irq(name)) {
+      /*
+       * Enable interrupt at OPENPIC level
+       */
+      openpic_enable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
+    }
+#endif
+}
+
+int
+BSP_disable_irq_at_pic(const rtems_irq_number name)
+{
+#if BSP_ISA_IRQ_NUMBER > 0
+    if (is_isa_irq(name)) {
+      /*
+       * disable interrupt at PIC level
+       */
+      return BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
+    }
+#endif
+#if BSP_PCI_IRQ_NUMBER > 0
+    if (is_pci_irq(name)) {
+      /*
+       * disable interrupt at OPENPIC level
+       */
+      return openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
+    }
+#endif
+	return -1;
+}
+
+/*
+ * RTEMS Global Interrupt Handler Management Routines
+ */
+int BSP_setup_the_pic(rtems_irq_global_settings* config)
+{
+    int i;
+   /*
+    * Store various code accelerators
+    */
+    default_rtems_entry	= config->defaultEntry;
+    rtems_hdl_tbl 		= config->irqHdlTbl;
+
+    /*
+     * set up internal tables used by rtems interrupt prologue
+     */
+
+#if BSP_ISA_IRQ_NUMBER > 0
+    /*
+     * start with ISA IRQ
+     */
+    compute_i8259_masks_from_prio (config);
+
+    for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
+      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
+         BSP_irq_enable_at_i8259s (i);
+      }
+      else {
+         BSP_irq_disable_at_i8259s (i);
+      }
+    }
+
+	if ( BSP_ISA_IRQ_NUMBER > 0 ) {
+    	/*
+		 * must enable slave pic anyway
+		 */
+		BSP_irq_enable_at_i8259s (2);
+	}
+#endif
+
+#if BSP_PCI_IRQ_NUMBER > 0
+	if ( ! OpenPIC )
+		return 1;
+    /*
+     * continue with PCI IRQ
+     */
+    for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) {
+      /*
+       * Note that openpic_set_priority() sets the TASK priority of the PIC
+       */
+      openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET,
+				  config->irqPrioTbl[i]);
+      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
+         openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
+      }
+      else {
+         openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
+      }
+    }
+
+#ifdef BSP_PCI_ISA_BRIDGE_IRQ
+   	/*
+     * Must enable PCI/ISA bridge IRQ
+     */
+   	openpic_enable_irq (BSP_PCI_ISA_BRIDGE_IRQ);
+#endif
+#endif
+
+    return 1;
+}
+
+int _BSP_vme_bridge_irq = -1;
+
+unsigned BSP_spuriousIntr = 0;
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+  register unsigned int irq;
+#if BSP_ISA_IRQ_NUMBER > 0
+  register unsigned isaIntr;                  /* boolean */
+  register unsigned oldMask = 0;	      /* old isa pic masks */
+  register unsigned newMask;                  /* new isa pic masks */
+#endif
+
+  if (excNum == ASM_DEC_VECTOR) {
+
+  	bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);
+
+    return 0;
+
+  }
+
+#if BSP_PCI_IRQ_NUMBER > 0
+  if ( OpenPIC ) {
+    irq = openpic_irq(0);
+    if (irq == OPENPIC_VEC_SPURIOUS) {
+      ++BSP_spuriousIntr;
+      return 0;
+    }
+
+    /* some BSPs might want to use a different numbering... */
+    irq = irq - OPENPIC_VEC_SOURCE + BSP_PCI_IRQ_LOWEST_OFFSET;
+  } else {
+#if BSP_ISA_IRQ_NUMBER > 0
+#ifdef BSP_PCI_ISA_BRIDGE_IRQ
+	irq = BSP_PCI_ISA_BRIDGE_IRQ;
+#else
+#error "Configuration Error -- BSP with ISA + PCI IRQs MUST define BSP_PCI_ISA_BRIDGE_IRQ"
+#endif
+#else
+	rtems_panic("MUST have an OpenPIC if BSP has PCI IRQs but no ISA IRQs");
+	/* rtems_panic() never returns but the 'return' statement silences
+	 * a compiler warning about 'irq' possibly being used w/o initialization.
+	 */
+	return -1;
+#endif
+  }
+#endif
+
+#if BSP_ISA_IRQ_NUMBER > 0
+#ifdef BSP_PCI_ISA_BRIDGE_IRQ
+#if 0 == BSP_PCI_IRQ_NUMBER 
+#error "Configuration Error -- BSP w/o PCI IRQs MUST NOT define BSP_PCI_ISA_BRIDGE_IRQ"
+#endif
+  isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ);
+#else
+  isaIntr = 1;
+#endif
+  if (isaIntr)  {
+    /*
+     * Acknowledge and read 8259 vector
+     */
+    irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG);
+    /*
+     * store current PIC mask
+     */
+    oldMask = i8259s_cache;
+    newMask = oldMask | irq_mask_or_tbl [irq];
+    i8259s_cache = newMask;
+    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
+    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
+    BSP_irq_ack_at_i8259s (irq);
+#if BSP_PCI_IRQ_NUMBER > 0
+	if ( OpenPIC )
+      openpic_eoi(0);
+#endif
+  }
+#endif
+
+  /* dispatch handlers */
+  bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
+
+#if BSP_ISA_IRQ_NUMBER > 0
+  if (isaIntr)  {
+    i8259s_cache = oldMask;
+    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
+    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
+  }
+  else
+#endif
+  {
+#if BSP_PCI_IRQ_NUMBER > 0
+#ifdef BSP_PCI_VME_DRIVER_DOES_EOI
+	/* leave it to the VME bridge driver to do EOI, so
+     * it can re-enable the openpic while handling
+     * VME interrupts (-> VME priorities in software)
+	 */
+	if (_BSP_vme_bridge_irq != irq && OpenPIC)
+#endif
+    		openpic_eoi(0);
+#else
+	do {} while (0);
+#endif
+  }
+  return 0;
+}
Index: bsps/powerpc/t32mppc/irq/irq.c
===================================================================
--- bsps/powerpc/t32mppc/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/t32mppc/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+#include <bsp/vectors.h>
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+	bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+}
+
+void bsp_interrupt_dispatch(uintptr_t exception_number)
+{
+	if (exception_number == 10) {
+		t32mppc_decrementer_dispatch();
+	} else {
+		bsp_interrupt_handler_default(0);
+	}
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+	bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+	return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/tqm8xx/irq/irq.c
===================================================================
--- bsps/powerpc/tqm8xx/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/tqm8xx/irq/irq.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,231 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+
+#include <rtems.h>
+#include <mpc8xx.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <bsp/vectors.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+/*
+ * functions to enable/disable a source at the SIU/CPM irq controller
+ */
+
+static rtems_status_code bsp_irq_disable_at_SIU(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
+  m8xx.simask &= ~(1 << (31 - vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code bsp_irq_enable_at_SIU(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
+  m8xx.simask |= (1 << (31 - vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code bsp_irq_disable_at_CPM(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
+  m8xx.cimr &= ~(1 << (vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code bsp_irq_enable_at_CPM(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
+  m8xx.cimr |= (1 << (vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (BSP_IS_CPM_IRQ(vector)) {
+    bsp_irq_enable_at_CPM(vector);
+  } else if (BSP_IS_SIU_IRQ(vector)) {
+    bsp_irq_enable_at_SIU(vector);
+  }
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (BSP_IS_CPM_IRQ(vector)) {
+    bsp_irq_disable_at_CPM(vector);
+  } else if (BSP_IS_SIU_IRQ(vector)) {
+    bsp_irq_disable_at_SIU(vector);
+  }
+}
+
+/*
+ *  IRQ Handler: this is called from the primary exception dispatcher
+ */
+static int BSP_irq_handle_at_cpm(void)
+{
+  int32_t  cpvecnum;
+  uint32_t msr;
+
+  /* Get vector number: write IACK=1, then read vectir */
+  m8xx.civr = 1;
+  cpvecnum  = (m8xx.civr >> 11) + BSP_CPM_IRQ_LOWEST_OFFSET;
+
+  /*
+   * Check the vector number,
+   * enable exceptions and dispatch the handler.
+   * NOTE: lower-prio interrupts are automatically masked in CPIC
+   */
+  if (BSP_IS_CPM_IRQ(cpvecnum)) {
+    /* Enable all interrupts */
+    msr = ppc_external_exceptions_enable();
+    /* Dispatch interrupt handlers */
+    bsp_interrupt_handler_dispatch(cpvecnum);
+    /* Restore machine state */
+    ppc_external_exceptions_disable(msr);
+  }
+  else {
+    /* not valid vector */
+    bsp_interrupt_handler_default(cpvecnum);
+  }
+  /*
+   * clear "in-service" bit
+   */
+  m8xx.cisr = 1 << (cpvecnum - BSP_CPM_IRQ_LOWEST_OFFSET);
+
+  return 0;
+}
+
+static int BSP_irq_handle_at_siu( unsigned excNum)
+{
+  int32_t  sivecnum;
+  uint32_t msr;
+  bool  is_cpm_irq;
+  uint32_t simask_save;
+  /*
+   * check, if interrupt is pending
+   * and repeat as long as valid interrupts are pending
+   */
+  while (0 != (m8xx.simask & m8xx.sipend)) {
+    /* Get vector number */
+    sivecnum     = (m8xx.sivec >> 26);
+    is_cpm_irq = (sivecnum == BSP_CPM_INTERRUPT);
+    /*
+     * Check the vector number, mask lower priority interrupts, enable
+     * exceptions and dispatch the handler.
+     */
+    if (BSP_IS_SIU_IRQ(sivecnum)) {
+      simask_save = m8xx.simask;
+      /*
+       * if this is the CPM interrupt, mask lower prio interrupts at SIU
+       * else mask lower and same priority interrupts
+       */
+      m8xx.simask &= ~0 << (32
+			    - sivecnum
+			    - ((is_cpm_irq) ? 1 : 0));
+
+      if (is_cpm_irq) {
+	BSP_irq_handle_at_cpm();
+      }
+      else {
+	/* Enable all interrupts */
+	msr = ppc_external_exceptions_enable();
+	/* Dispatch interrupt handlers */
+	bsp_interrupt_handler_dispatch(sivecnum + BSP_SIU_IRQ_LOWEST_OFFSET);
+	/* Restore machine state */
+	ppc_external_exceptions_disable(msr);
+	/*
+	 * clear pending bit, if edge triggered interrupt input
+	 */
+	m8xx.sipend = 1 << (31 - sivecnum);
+      }
+
+
+      /* Restore initial masks */
+      m8xx.simask = simask_save;
+    } else {
+      /* not valid vector */
+      bsp_interrupt_handler_default(sivecnum);
+    }
+  }
+  return 0;
+}
+
+/*
+ * Activate the CPIC
+ */
+static rtems_status_code mpc8xx_cpic_initialize( void)
+{
+  /*
+   * mask off all interrupts
+   */
+  m8xx.cimr   = 0;
+  /*
+   * make sure CPIC request proper level at SIU interrupt controller
+   */
+  m8xx.cicr  = (0x00e41f80 |
+		((BSP_CPM_INTERRUPT/2) << 13));
+  /*
+   * enable CPIC interrupt in SIU interrupt controller
+   */
+  return bsp_irq_enable_at_SIU(BSP_CPM_INTERRUPT);
+}
+
+/*
+ * Activate the SIU interrupt controller
+ */
+static rtems_status_code mpc8xx_siu_int_initialize( void)
+{
+  /*
+   * mask off all interrupts
+   */
+  m8xx.simask = 0;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static int mpc8xx_exception_handler(BSP_Exception_frame *frame,
+			     unsigned exception_number)
+{
+  return BSP_irq_handle_at_siu(exception_number);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize()
+{
+  /* Install exception handler */
+  if (ppc_exc_set_handler(ASM_EXT_VECTOR, mpc8xx_exception_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+  /* Initialize the SIU interrupt controller */
+  if (mpc8xx_siu_int_initialize()) {
+    return RTEMS_IO_ERROR;
+  }
+  /* Initialize the CPIC interrupt controller */
+  return mpc8xx_cpic_initialize();
+}
Index: bsps/powerpc/virtex/irq/irq_init.c
===================================================================
--- bsps/powerpc/virtex/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/virtex/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,167 @@
+/*===============================================================*\
+| Project: RTEMS virtex BSP                                       |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the irq controller handler                   |
+\*===============================================================*/
+
+/*  Content moved from opbintctrl.c:
+ *
+ *  This file contains definitions and declarations for the
+ *  Xilinx Off Processor Bus (OPB) Interrupt Controller
+ *
+ *  Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
+ *  COPYRIGHT (c) 2005 Linn Products Ltd, Scotland.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/vectors.h>
+
+#include <libcpu/powerpc-utility.h>
+
+/*
+ * Acknowledge a mask of interrupts.
+ */
+static void set_iar(uint32_t mask)
+{
+  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask;
+}
+
+/*
+ * Set IER state.  Used to (dis)enable a mask of vectors.
+ * If you only have to do one, use enable/disable_vector.
+ */
+static void set_ier(uint32_t mask)
+{
+  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask;
+}
+
+/*
+ * Retrieve contents of Interrupt Pending Register
+ */
+static uint32_t get_ipr(void)
+{
+  uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR));
+  return c;
+}
+
+static void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum)
+{
+  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE))
+    = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
+}
+
+static void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum)
+{
+  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE))
+    = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
+}
+
+/*
+ *  IRQ Handler: this is called from the primary exception dispatcher
+ */
+static void BSP_irq_handle_at_opbintc(void)
+{
+  uint32_t ipr;
+
+  /* Get pending interrupts */
+  ipr = get_ipr();
+
+  if (ipr != 0) {
+    /* Acknowledge all pending interrupts now and service them afterwards */
+    set_iar(ipr);
+
+    do {
+      /* Get highest priority pending interrupt */
+      uint32_t i = 31 - ppc_count_leading_zeros(ipr);
+
+      ipr &= ~(1U << i);
+
+      bsp_interrupt_handler_dispatch(i+BSP_OPBINTC_IRQ_LOWEST_OFFSET);
+    } while (ipr != 0);
+  }
+}
+
+/*
+ * activate the interrupt controller
+ */
+static void opb_intc_init(void)
+{
+  uint32_t i, mask = 0;
+
+  /* mask off all interrupts */
+  set_ier(0x0);
+
+  for (i = 0; i < OPB_INTC_IRQ_MAX; i++) {
+    mask |= (1 << i);
+  }
+
+  /* make sure interupt status register is clear before we enable the interrupt controller */
+  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0;
+
+  /* acknowledge all interrupt sources */
+  set_iar(mask);
+
+  /* Turn on normal hardware operation of interrupt controller */
+  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
+    (OPB_INTC_MER_HIE);
+
+  /* Enable master interrupt switch for the interrupt controller */
+  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
+    (OPB_INTC_MER_HIE | OPB_INTC_MER_ME);
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (BSP_IS_OPBINTC_IRQ(vector)) {
+    BSP_irq_enable_at_opbintc(vector);
+  }
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (BSP_IS_OPBINTC_IRQ(vector)) {
+    BSP_irq_disable_at_opbintc(vector);
+  }
+}
+
+static int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned int excNum)
+{
+  BSP_irq_handle_at_opbintc();
+
+  return 0;
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+  opb_intc_init();
+
+  ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler);
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/virtex4/irq/irq_init.c
===================================================================
--- bsps/powerpc/virtex4/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/virtex4/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,326 @@
+/*===============================================================*\
+| Project: RTEMS virtex BSP                                       |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the irq controller handler                   |
+\*===============================================================*/
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <rtems/bspIo.h>
+#include <rtems/powerpc/powerpc.h>
+#include <bsp/vectors.h>
+
+static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
+rtems_irq_connect_data *BSP_rtems_irq_tbl;
+rtems_irq_global_settings* BSP_rtems_irq_config;
+
+/***********************************************************
+ * dummy functions for on/off/isOn calls
+ * these functions just do nothing fulfill the semantic
+ * requirements to enable/disable a certain interrupt or exception
+ */
+static void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
+{
+  /*
+   * nothing to do
+   */
+}
+
+static void BSP_irq_nop_hdl(void *hdl)
+{
+  /*
+   * nothing to do
+   */
+}
+
+static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
+{
+  /*
+   * nothing to do
+   */
+  return 0;
+}
+
+/***********************************************************
+ * interrupt handler and its enable/disable functions
+ ***********************************************************/
+
+/***********************************************************
+ * functions to enable/disable/query external/critical interrupts
+ */
+void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data)
+{
+  uint32_t msr_value;
+  /*
+   * get current MSR value
+   */
+  _CPU_MSR_GET(msr_value);
+
+  msr_value |= PPC_MSR_EE;
+  _CPU_MSR_SET(msr_value);
+}
+
+void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
+{
+  uint32_t msr_value;
+  /*
+   * get current MSR value
+   */
+  _CPU_MSR_GET(msr_value);
+
+  msr_value &= ~PPC_MSR_EE;
+  _CPU_MSR_SET(msr_value);
+}
+
+/***********************************************************
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+  /*
+   * Handle interrupt
+   */
+  switch(excNum) {
+  case ASM_EXT_VECTOR:
+    BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
+    break;
+  case ASM_BOOKE_DEC_VECTOR:
+    BSP_rtems_irq_tbl[BSP_PIT].hdl(BSP_rtems_irq_tbl[BSP_PIT].handle);
+    break;
+#if 0 /* Critical interrupts not yet supported */
+  case ASM_BOOKE_CRIT_VECTOR:
+    BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
+    break;
+#endif
+  }
+
+  return 0;
+}
+
+/***********************************************************
+ * functions to set/get/remove interrupt handlers
+ ***********************************************************/
+int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
+{
+  rtems_interrupt_level level;
+
+  /*
+   * check for valid irq name
+   * if invalid, print error and return 0
+   */
+  if (!BSP_IS_VALID_IRQ(irq->name)) {
+    printk("Invalid interrupt vector %d\n",irq->name);
+    return 0;
+  }
+
+  /*
+   * disable interrupts
+   */
+  rtems_interrupt_disable(level);
+
+  /*
+   * check, that default handler is installed now
+   */
+  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
+    rtems_interrupt_enable(level);
+    printk("IRQ vector %d already connected\n",irq->name);
+    return 0;
+  }
+
+  /*
+   * store new handler data
+   */
+  rtemsIrqTbl[irq->name] = *irq;
+
+  /*
+   * call "on" function to enable interrupt at device
+   */
+  irq->on(irq);
+
+  /*
+   * reenable interrupts
+   */
+  rtems_interrupt_enable(level);
+
+  return 1;
+}
+
+int BSP_get_current_rtems_irq_handler	(rtems_irq_connect_data* irq)
+{
+  rtems_interrupt_level level;
+
+  /*
+   * check for valid IRQ name
+   */
+  if (!BSP_IS_VALID_IRQ(irq->name)) {
+    return 0;
+  }
+  rtems_interrupt_disable(level);
+
+  /*
+   * return current IRQ entry
+   */
+  *irq = rtemsIrqTbl[irq->name];
+  rtems_interrupt_enable(level);
+  return 1;
+}
+
+int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
+{
+  rtems_interrupt_level level;
+
+  /*
+   * check for valid IRQ name
+   */
+  if (!BSP_IS_VALID_IRQ(irq->name)) {
+    return 0;
+  }
+  rtems_interrupt_disable(level);
+
+  /*
+   * check, that specified handler is really connected now
+   */
+  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
+    rtems_interrupt_enable(level);
+    return 0;
+  }
+
+  /*
+   * disable interrupt at source
+   */
+  irq->off(irq);
+
+  /*
+   * restore default interrupt handler
+   */
+  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
+
+  /*
+   * reenable interrupts
+   */
+  rtems_interrupt_enable(level);
+
+  return 1;
+}
+
+/***********************************************************
+ * functions to set/get the basic interrupt management setup
+ ***********************************************************/
+/*
+ * (Re) get info on current RTEMS interrupt management.
+ */
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
+{
+  *ret_ptr = BSP_rtems_irq_config;
+  return 0;
+}
+
+
+/*
+ * set management stuff
+ */
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+{
+  int                    i;
+  rtems_interrupt_level  level;
+
+  rtems_interrupt_disable(level);
+
+  /*
+   * store given configuration
+   */
+  BSP_rtems_irq_config = config;
+  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
+
+  /*
+   * store any irq-like processor exceptions
+   */
+  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
+       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
+       i++) {
+    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
+      if (BSP_rtems_irq_tbl[i].on != NULL) {
+	BSP_rtems_irq_tbl[i].on
+	  (&(BSP_rtems_irq_tbl[i]));
+      }
+    }
+    else {
+      if (BSP_rtems_irq_tbl[i].off != NULL) {
+	BSP_rtems_irq_tbl[i].off
+	  (&(BSP_rtems_irq_tbl[i]));
+      }
+    }
+  }
+  rtems_interrupt_enable(level);
+  return 1;
+}
+
+/*
+ * dummy for an empty IRQ handler entry
+ */
+static rtems_irq_connect_data emptyIrq = {
+  0, 		         /* IRQ Name                 */
+  BSP_irq_nop_hdl,       /* handler function         */
+  NULL,                  /* handle passed to handler */
+  BSP_irq_nop_func,      /* on function              */
+  BSP_irq_nop_func,      /* off function             */
+  BSP_irq_isOn_func      /* isOn function            */
+};
+
+static rtems_irq_global_settings initialConfig = {
+  BSP_IRQ_NUMBER,           /* IRQ Number               */
+  {  0, 		    /* IRQ Name                 */
+     BSP_irq_nop_hdl,       /* handler function         */
+     NULL,                  /* handle passed to handler */
+     BSP_irq_nop_func,      /* on function              */
+     BSP_irq_nop_func,      /* off function             */
+     BSP_irq_isOn_func      /* isOn function            */
+  }, /* emptyIrq */
+  rtemsIrqTbl, /* irqHdlTbl  */
+  0,           /* irqBase    */
+  NULL         /* irqPrioTbl */
+};
+
+void BSP_rtems_irq_mngt_init(unsigned cpuId)
+{
+  int i;
+
+  /*
+   * connect all exception vectors needed
+   */
+  ppc_exc_set_handler(ASM_EXT_VECTOR,       C_dispatch_irq_handler);
+  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler);
+
+  /*
+   * setup interrupt handlers table
+   */
+  for (i = 0;
+       i < BSP_IRQ_NUMBER;
+       i++) {
+    rtemsIrqTbl[i]      = emptyIrq;
+    rtemsIrqTbl[i].name = i;
+  }
+
+  /*
+   * initialize interrupt management
+   */
+  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
+    rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+  }
+}
Index: bsps/powerpc/virtex5/irq/irq_init.c
===================================================================
--- bsps/powerpc/virtex5/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
+++ bsps/powerpc/virtex5/irq/irq_init.c	(revision 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708)
@@ -0,0 +1,343 @@
+/*===============================================================*\
+| Project: RTEMS virtex BSP                                       |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the irq controller handler                   |
+\*===============================================================*/
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <rtems/bspIo.h>
+#include <rtems/powerpc/powerpc.h>
+#include <bsp/vectors.h>
+
+static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
+rtems_irq_connect_data *BSP_rtems_irq_tbl;
+rtems_irq_global_settings* BSP_rtems_irq_config;
+
+/***********************************************************
+ * dummy functions for on/off/isOn calls
+ * these functions just do nothing fulfill the semantic
+ * requirements to enable/disable a certain interrupt or exception
+ */
+static void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
+{
+  /*
+   * nothing to do
+   */
+}
+
+static void BSP_irq_nop_hdl(void *hdl)
+{
+  /*
+   * nothing to do
+   */
+}
+
+static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
+{
+  /*
+   * nothing to do
+   */
+  return 0;
+}
+
+/***********************************************************
+ * interrupt handler and its enable/disable functions
+ ***********************************************************/
+
+/***********************************************************
+ * functions to enable/disable/query external/critical interrupts
+ */
+void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data)
+{
+  uint32_t msr_value;
+  /*
+   * get current MSR value
+   */
+  _CPU_MSR_GET(msr_value);
+
+  msr_value |= PPC_MSR_EE;
+  _CPU_MSR_SET(msr_value);
+}
+
+void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
+{
+  uint32_t msr_value;
+  /*
+   * get current MSR value
+   */
+  _CPU_MSR_GET(msr_value);
+
+  msr_value &= ~PPC_MSR_EE;
+  _CPU_MSR_SET(msr_value);
+}
+
+SPR_RW(BOOKE_TSR)
+
+static int C_dispatch_dec_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+  /* Acknowledge the interrupt */
+  _write_BOOKE_TSR( BOOKE_TSR_DIS );
+
+  /* Handle the interrupt */
+  BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
+
+  return 0;
+}
+
+
+/***********************************************************
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+  /*
+   * Handle interrupt
+   */
+  switch(excNum) {
+  case ASM_EXT_VECTOR:
+    BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
+    break;
+#if 0 /* Dealt with by C_dispatch_dec_handler(), above */
+  case ASM_BOOKE_DEC_VECTOR:
+    _write_BOOKE_TSR( BOOKE_TSR_DIS );
+    BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
+    break;
+#endif
+#if 0 /* Critical interrupts not yet supported */
+  case ASM_BOOKE_CRIT_VECTOR:
+    BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
+    break;
+#endif
+  }
+
+  return 0;
+}
+
+/***********************************************************
+ * functions to set/get/remove interrupt handlers
+ ***********************************************************/
+int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
+{
+  rtems_interrupt_level level;
+
+  /*
+   * check for valid irq name
+   * if invalid, print error and return 0
+   */
+  if (!BSP_IS_VALID_IRQ(irq->name)) {
+    printk("Invalid interrupt vector %d\n",irq->name);
+    return 0;
+  }
+
+  /*
+   * disable interrupts
+   */
+  rtems_interrupt_disable(level);
+
+  /*
+   * check, that default handler is installed now
+   */
+  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
+    rtems_interrupt_enable(level);
+    printk("IRQ vector %d already connected\n",irq->name);
+    return 0;
+  }
+
+  /*
+   * store new handler data
+   */
+  rtemsIrqTbl[irq->name] = *irq;
+
+  /*
+   * call "on" function to enable interrupt at device
+   */
+  irq->on(irq);
+
+  /*
+   * reenable interrupts
+   */
+  rtems_interrupt_enable(level);
+
+  return 1;
+}
+
+int BSP_get_current_rtems_irq_handler	(rtems_irq_connect_data* irq)
+{
+  rtems_interrupt_level level;
+
+  /*
+   * check for valid IRQ name
+   */
+  if (!BSP_IS_VALID_IRQ(irq->name)) {
+    return 0;
+  }
+  rtems_interrupt_disable(level);
+
+  /*
+   * return current IRQ entry
+   */
+  *irq = rtemsIrqTbl[irq->name];
+  rtems_interrupt_enable(level);
+  return 1;
+}
+
+int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
+{
+  rtems_interrupt_level level;
+
+  /*
+   * check for valid IRQ name
+   */
+  if (!BSP_IS_VALID_IRQ(irq->name)) {
+    return 0;
+  }
+  rtems_interrupt_disable(level);
+
+  /*
+   * check, that specified handler is really connected now
+   */
+  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
+    rtems_interrupt_enable(level);
+    return 0;
+  }
+
+  /*
+   * disable interrupt at source
+   */
+  irq->off(irq);
+
+  /*
+   * restore default interrupt handler
+   */
+  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
+
+  /*
+   * reenable interrupts
+   */
+  rtems_interrupt_enable(level);
+
+  return 1;
+}
+
+/***********************************************************
+ * functions to set/get the basic interrupt management setup
+ ***********************************************************/
+/*
+ * (Re) get info on current RTEMS interrupt management.
+ */
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
+{
+  *ret_ptr = BSP_rtems_irq_config;
+  return 0;
+}
+
+
+/*
+ * set management stuff
+ */
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+{
+  int                    i;
+  rtems_interrupt_level  level;
+
+  rtems_interrupt_disable(level);
+
+  /*
+   * store given configuration
+   */
+  BSP_rtems_irq_config = config;
+  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
+
+  /*
+   * store any irq-like processor exceptions
+   */
+  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
+       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
+       i++) {
+    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
+      if (BSP_rtems_irq_tbl[i].on != NULL) {
+	BSP_rtems_irq_tbl[i].on
+	  (&(BSP_rtems_irq_tbl[i]));
+      }
+    }
+    else {
+      if (BSP_rtems_irq_tbl[i].off != NULL) {
+	BSP_rtems_irq_tbl[i].off
+	  (&(BSP_rtems_irq_tbl[i]));
+      }
+    }
+  }
+  rtems_interrupt_enable(level);
+  return 1;
+}
+
+/*
+ * dummy for an empty IRQ handler entry
+ */
+static rtems_irq_connect_data emptyIrq = {
+  0, 		         /* IRQ Name                 */
+  BSP_irq_nop_hdl,       /* handler function         */
+  NULL,                  /* handle passed to handler */
+  BSP_irq_nop_func,      /* on function              */
+  BSP_irq_nop_func,      /* off function             */
+  BSP_irq_isOn_func      /* isOn function            */
+};
+
+static rtems_irq_global_settings initialConfig = {
+  BSP_IRQ_NUMBER,           /* IRQ number               */
+  {  0, 		    /* IRQ Name                 */
+     BSP_irq_nop_hdl,       /* handler function         */
+     NULL,                  /* handle passed to handler */
+     BSP_irq_nop_func,      /* on function              */
+     BSP_irq_nop_func,      /* off function             */
+     BSP_irq_isOn_func      /* isOn function            */
+  }, /* emptyIrq */
+  rtemsIrqTbl, /* irqHdlTbl  */
+  0,           /* irqBase    */
+  NULL         /* irqPrioTbl */
+};
+
+void BSP_rtems_irq_mngt_init(unsigned cpuId)
+{
+  int i;
+
+  /*
+   * connect all exception vectors needed
+   */
+  ppc_exc_set_handler(ASM_EXT_VECTOR,       C_dispatch_irq_handler);
+  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler);
+
+  /*
+   * setup interrupt handlers table
+   */
+  for (i = 0;
+       i < BSP_IRQ_NUMBER;
+       i++) {
+    rtemsIrqTbl[i]      = emptyIrq;
+    rtemsIrqTbl[i].name = i;
+  }
+
+  /*
+   * initialize interrupt management
+   */
+  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
+    rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+  }
+}
