Index: c/src/lib/libbsp/sparc/Makefile.am
===================================================================
--- c/src/lib/libbsp/sparc/Makefile.am	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/Makefile.am	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -12,4 +12,7 @@
 EXTRA_DIST += shared/gnatcommon.c
 EXTRA_DIST += shared/start.S
+
+# Interrupt
+EXTRA_DIST += shared/irq/irq-shared.c
 
 # AMBA Plug&Play bus
Index: c/src/lib/libbsp/sparc/erc32/Makefile.am
===================================================================
--- c/src/lib/libbsp/sparc/erc32/Makefile.am	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/erc32/Makefile.am	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -34,5 +34,5 @@
 # startup
 libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
-    ../../shared/bsppredriverhook.c ../../sparc/shared/bspgetworkarea.c \
+    startup/bsppredriver.c ../../sparc/shared/bspgetworkarea.c \
     ../../sparc/shared/bsppretaskinghook.c ../../shared/bsppost.c \
     ../../shared/bspstart.c ../../shared/bootcard.c ../../shared/bspinit.c \
@@ -55,4 +55,18 @@
 # timer
 libbsp_a_SOURCES += timer/timer.c
+
+# IRQ
+include_bsp_HEADERS = \
+    ../../shared/include/irq-generic.h \
+    ../../shared/include/irq-info.h \
+    include/bsp/irq.h
+libbsp_a_SOURCES += \
+    ../../sparc/shared/irq/irq-shared.c \
+    ../../shared/src/irq-default-handler.c \
+    ../../shared/src/irq-generic.c \
+    ../../shared/src/irq-info.c \
+    ../../shared/src/irq-legacy.c \
+    ../../shared/src/irq-server.c \
+    ../../shared/src/irq-shell.c
 
 if HAS_SMP
Index: c/src/lib/libbsp/sparc/erc32/include/bsp.h
===================================================================
--- c/src/lib/libbsp/sparc/erc32/include/bsp.h	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/erc32/include/bsp.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -31,6 +31,6 @@
 #include <erc32.h>
 #include <rtems/clockdrv.h>
-
 #include <rtems/console.h>
+#include <rtems/irq-extension.h>
 
 /*
@@ -87,4 +87,77 @@
 void *bsp_early_malloc(int size);
 
+/* Interrupt Service Routine (ISR) pointer */
+typedef void (*bsp_shared_isr)(void *arg);
+
+/* Initializes the Shared System Interrupt service */
+extern int BSP_shared_interrupt_init(void);
+
+/* Registers a shared IRQ handler, and enable it at IRQ controller. Multiple
+ * interrupt handlers may use the same IRQ number, all ISRs will be called
+ * when an interrupt on that line is fired.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ *  info      Optional Name of IRQ source
+ *  isr       Function pointer to the ISR
+ *  arg       Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_register
+       (
+       int irq,
+       const char *info,
+       bsp_shared_isr isr,
+       void *arg
+       )
+{
+       return rtems_interrupt_handler_install(irq, info,
+                                       RTEMS_INTERRUPT_SHARED, isr, arg);
+}
+
+/* Unregister previously registered shared IRQ handler.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ *  isr       Function pointer to the ISR
+ *  arg       Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_unregister
+       (
+       int irq,
+       bsp_shared_isr isr,
+       void *arg
+       )
+{
+       return rtems_interrupt_handler_remove(irq, isr, arg);
+}
+
+/* Clear interrupt pending on IRQ controller, this is typically done on a
+ * level triggered interrupt source such as PCI to avoid taking double IRQs.
+ * In such a case the interrupt source must be cleared first on LEON, before
+ * acknowledging the IRQ with this function.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ */
+extern void BSP_shared_interrupt_clear(int irq);
+
+/* Enable Interrupt. This function will unmask the IRQ at the interrupt
+ * controller. This is normally done by _register(). Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ */
+extern void BSP_shared_interrupt_unmask(int irq);
+
+/* Disable Interrupt. This function will mask one IRQ at the interrupt
+ * controller. This is normally done by _unregister().  Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ *  irq         System IRQ number
+ */
+extern void BSP_shared_interrupt_mask(int irq);
+
 #ifdef __cplusplus
 }
Index: c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
===================================================================
--- c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,20 @@
+/* ERC32 generic shared IRQ setup
+ *
+ * Based on libbsp/shared/include/irq.h.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ERC32_IRQ_CONFIG_H
+#define LIBBSP_ERC32_IRQ_CONFIG_H
+
+#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
+#define BSP_INTERRUPT_VECTOR_MIN 0
+#define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_STD
+
+/* No extra check is needed */
+#undef BSP_INTERRUPT_CUSTOM_VALID_VECTOR
+
+#endif /* LIBBSP_ERC32_IRQ_CONFIG_H */
Index: c/src/lib/libbsp/sparc/erc32/include/erc32.h
===================================================================
--- c/src/lib/libbsp/sparc/erc32/include/erc32.h	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/erc32/include/erc32.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -325,4 +325,9 @@
 extern ERC32_Register_Map ERC32_MEC;
 
+static __inline__ int bsp_irq_fixup(int irq)
+{
+       return irq;
+}
+
 /*
  *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
@@ -396,4 +401,16 @@
     sparc_enable_interrupts( _level ); \
   } while (0)
+
+/* Make all SPARC BSPs have common macros for interrupt handling */
+#define BSP_Clear_interrupt(_source) ERC32_Clear_interrupt(_source)
+#define BSP_Force_interrupt(_source) ERC32_Force_interrupt(_source)
+#define BSP_Is_interrupt_pending(_source) ERC32_Is_interrupt_pending(_source)
+#define BSP_Is_interrupt_masked(_source) ERC32_Is_interrupt_masked(_source)
+#define BSP_Unmask_interrupt(_source) ERC32_Unmask_interrupt(_source)
+#define BSP_Mask_interrupt(_source) ERC32_Mask_interrupt(_source)
+#define BSP_Disable_interrupt(_source, _previous) \
+        ERC32_Disable_interrupt(_source, _prev)
+#define BSP_Restore_interrupt(_source, _previous) \
+        ERC32_Restore_interrupt(_source, _previous)
 
 /*
Index: c/src/lib/libbsp/sparc/erc32/preinstall.am
===================================================================
--- c/src/lib/libbsp/sparc/erc32/preinstall.am	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/erc32/preinstall.am	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -74,2 +74,14 @@
 PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
 
+$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
+
+$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: include/bsp/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
Index: c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c
===================================================================
--- c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,25 @@
+/*  Installs the BSP pre-driver hook
+ *
+ *  COPYRIGHT (c) 2011
+ *  Aeroflex Gaisler
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+
+/*
+ *  bsp_predriver_hook
+ *
+ *  BSP predriver hook. Called just before drivers are initialized.
+ *  Is used to initialize shared interrupt handling.
+ */
+void bsp_predriver_hook( void )
+{
+  /* Initialize shared interrupt handling, must be done after IRQ
+   * controller has been found and initialized.
+   */
+  BSP_shared_interrupt_init();
+}
Index: c/src/lib/libbsp/sparc/leon2/Makefile.am
===================================================================
--- c/src/lib/libbsp/sparc/leon2/Makefile.am	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon2/Makefile.am	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -52,5 +52,5 @@
 # startup
 libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
-    ../../shared/bsppost.c ../../shared/bsppredriverhook.c \
+    ../../shared/bsppost.c startup/bsppredriver.c \
     startup/bspstart.c ../../sparc/shared/bsppretaskinghook.c \
     ../../sparc/shared/bspgetworkarea.c ../../shared/bootcard.c \
@@ -67,4 +67,17 @@
 libbsp_a_SOURCES += clock/ckinit.c
 libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
+# IRQ
+include_bsp_HEADERS = \
+    ../../shared/include/irq-generic.h \
+    ../../shared/include/irq-info.h \
+    include/bsp/irq.h
+libbsp_a_SOURCES += \
+    ../../sparc/shared/irq/irq-shared.c \
+    ../../shared/src/irq-default-handler.c \
+    ../../shared/src/irq-generic.c \
+    ../../shared/src/irq-info.c \
+    ../../shared/src/irq-legacy.c \
+    ../../shared/src/irq-server.c \
+    ../../shared/src/irq-shell.c
 # AMBA PnP Scanning
 libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp.c
Index: c/src/lib/libbsp/sparc/leon2/include/bsp.h
===================================================================
--- c/src/lib/libbsp/sparc/leon2/include/bsp.h	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon2/include/bsp.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -31,4 +31,5 @@
 #include <rtems/clockdrv.h>
 #include <rtems/console.h>
+#include <rtems/irq-extension.h>
 
 /* SPARC CPU variant: LEON2 */
@@ -106,4 +107,77 @@
 void *bsp_early_malloc(int size);
 
+/* Interrupt Service Routine (ISR) pointer */
+typedef void (*bsp_shared_isr)(void *arg);
+
+/* Initializes the Shared System Interrupt service */
+extern int BSP_shared_interrupt_init(void);
+
+/* Registers a shared IRQ handler, and enable it at IRQ controller. Multiple
+ * interrupt handlers may use the same IRQ number, all ISRs will be called
+ * when an interrupt on that line is fired.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ *  info      Optional Name of IRQ source
+ *  isr       Function pointer to the ISR
+ *  arg       Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_register
+       (
+       int irq,
+       const char *info,
+       bsp_shared_isr isr,
+       void *arg
+       )
+{
+       return rtems_interrupt_handler_install(irq, info,
+                                       RTEMS_INTERRUPT_SHARED, isr, arg);
+}
+
+/* Unregister previously registered shared IRQ handler.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ *  isr       Function pointer to the ISR
+ *  arg       Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_unregister
+       (
+       int irq,
+       bsp_shared_isr isr,
+       void *arg
+       )
+{
+       return rtems_interrupt_handler_remove(irq, isr, arg);
+}
+
+/* Clear interrupt pending on IRQ controller, this is typically done on a
+ * level triggered interrupt source such as PCI to avoid taking double IRQs.
+ * In such a case the interrupt source must be cleared first on LEON, before
+ * acknowledging the IRQ with this function.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ */
+extern void BSP_shared_interrupt_clear(int irq);
+
+/* Enable Interrupt. This function will unmask the IRQ at the interrupt
+ * controller. This is normally done by _register(). Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ */
+extern void BSP_shared_interrupt_unmask(int irq);
+
+/* Disable Interrupt. This function will mask one IRQ at the interrupt
+ * controller. This is normally done by _unregister().  Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ *  irq         System IRQ number
+ */
+extern void BSP_shared_interrupt_mask(int irq);
+
 #ifdef __cplusplus
 }
Index: c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h
===================================================================
--- c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,20 @@
+/* LEON2 generic shared IRQ setup
+ *
+ * Based on libbsp/shared/include/irq.h.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_LEON2_IRQ_CONFIG_H
+#define LIBBSP_LEON2_IRQ_CONFIG_H
+
+#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
+#define BSP_INTERRUPT_VECTOR_MIN 0
+#define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_STD
+
+/* No extra check is needed */
+#undef BSP_INTERRUPT_CUSTOM_VALID_VECTOR
+
+#endif /* LIBBSP_LEON2_IRQ_CONFIG_H */
Index: c/src/lib/libbsp/sparc/leon2/include/leon.h
===================================================================
--- c/src/lib/libbsp/sparc/leon2/include/leon.h	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon2/include/leon.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -272,4 +272,9 @@
 extern LEON_Register_Map LEON_REG;
 
+static __inline__ int bsp_irq_fixup(int irq)
+{
+       return irq;
+}
+
 /*
  *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
@@ -339,4 +344,16 @@
   } while (0)
 
+/* Make all SPARC BSPs have common macros for interrupt handling */
+#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
+#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
+#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
+#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
+#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
+#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
+#define BSP_Disable_interrupt(_source, _previous) \
+        LEON_Disable_interrupt(_source, _prev)
+#define BSP_Restore_interrupt(_source, _previous) \
+        LEON_Restore_interrupt(_source, _previous)
+
 /*
  *  Each timer control register is organized as follows:
Index: c/src/lib/libbsp/sparc/leon2/preinstall.am
===================================================================
--- c/src/lib/libbsp/sparc/leon2/preinstall.am	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon2/preinstall.am	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -146,4 +146,16 @@
 PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
 
+$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
+
+$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: include/bsp/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
 $(PROJECT_INCLUDE)/i2cmst.h: ../../sparc/shared/include/i2cmst.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/i2cmst.h
Index: c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
===================================================================
--- c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,25 @@
+/*  Installs the BSP pre-driver hook
+ *
+ *  COPYRIGHT (c) 2011
+ *  Aeroflex Gaisler
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+
+/*
+ *  bsp_predriver_hook
+ *
+ *  BSP predriver hook. Called just before drivers are initialized.
+ *  Is used to initialize shared interrupt handling.
+ */
+void bsp_predriver_hook( void )
+{
+  /* Initialize shared interrupt handling, must be done after IRQ
+   * controller has been found and initialized.
+   */
+  BSP_shared_interrupt_init();
+}
Index: c/src/lib/libbsp/sparc/leon3/Makefile.am
===================================================================
--- c/src/lib/libbsp/sparc/leon3/Makefile.am	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon3/Makefile.am	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -36,5 +36,5 @@
 libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
     ../../shared/bsppost.c ../../shared/bootcard.c startup/bspstart.c \
-    ../../sparc/shared/bsppretaskinghook.c ../../shared/bsppredriverhook.c \
+    ../../sparc/shared/bsppretaskinghook.c startup/bsppredriver.c \
     ../../sparc/shared/bspgetworkarea.c ../../shared/sbrk.c startup/setvec.c \
     startup/spurious.c startup/bspidle.S startup/bspdelay.c \
@@ -56,4 +56,18 @@
 libbsp_a_SOURCES += clock/ckinit.c
 libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
+# IRQ
+include_bsp_HEADERS = \
+    ../../shared/include/irq-generic.h \
+    ../../shared/include/irq-info.h \
+    include/bsp/irq.h
+libbsp_a_SOURCES += \
+    startup/eirq.c \
+    ../../sparc/shared/irq/irq-shared.c \
+    ../../shared/src/irq-default-handler.c \
+    ../../shared/src/irq-generic.c \
+    ../../shared/src/irq-info.c \
+    ../../shared/src/irq-legacy.c \
+    ../../shared/src/irq-server.c \
+    ../../shared/src/irq-shell.c
 # PCI
 include_HEADERS += ../../sparc/shared/include/pci.h
Index: c/src/lib/libbsp/sparc/leon3/amba/amba.c
===================================================================
--- c/src/lib/libbsp/sparc/leon3/amba/amba.c	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon3/amba/amba.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -18,4 +18,7 @@
 /* Structure containing address to devices found on the Amba Plug&Play bus */
 amba_confarea_type amba_conf;
+
+/* GRLIB extended IRQ controller register */
+extern void leon3_ext_irq_init(void);
 
 /* Pointers to Interrupt Controller configuration registers */
@@ -49,4 +52,7 @@
   }
 
+  /* Init Extended IRQ controller if available */
+  leon3_ext_irq_init();
+
   /* find GP Timer */
   i = amba_find_apbslv(&amba_conf,VENDOR_GAISLER,GAISLER_GPTIMER,&dev);
Index: c/src/lib/libbsp/sparc/leon3/include/bsp.h
===================================================================
--- c/src/lib/libbsp/sparc/leon3/include/bsp.h	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon3/include/bsp.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -31,4 +31,5 @@
 #include <rtems/clockdrv.h>
 #include <rtems/console.h>
+#include <rtems/irq-extension.h>
 
 /* SPARC CPU variant: LEON3 */
@@ -116,4 +117,77 @@
 void *bsp_early_malloc(int size);
 
+/* Interrupt Service Routine (ISR) pointer */
+typedef void (*bsp_shared_isr)(void *arg);
+
+/* Initializes the Shared System Interrupt service */
+extern int BSP_shared_interrupt_init(void);
+
+/* Registers a shared IRQ handler, and enable it at IRQ controller. Multiple
+ * interrupt handlers may use the same IRQ number, all ISRs will be called
+ * when an interrupt on that line is fired.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ *  info      Optional Name of IRQ source
+ *  isr       Function pointer to the ISR
+ *  arg       Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_register
+       (
+       int irq,
+       const char *info,
+       bsp_shared_isr isr,
+       void *arg
+       )
+{
+       return rtems_interrupt_handler_install(irq, info,
+                                       RTEMS_INTERRUPT_SHARED, isr, arg);
+}
+
+/* Unregister previously registered shared IRQ handler.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ *  isr       Function pointer to the ISR
+ *  arg       Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_unregister
+       (
+       int irq,
+       bsp_shared_isr isr,
+       void *arg
+       )
+{
+       return rtems_interrupt_handler_remove(irq, isr, arg);
+}
+
+/* Clear interrupt pending on IRQ controller, this is typically done on a
+ * level triggered interrupt source such as PCI to avoid taking double IRQs.
+ * In such a case the interrupt source must be cleared first on LEON, before
+ * acknowledging the IRQ with this function.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ */
+extern void BSP_shared_interrupt_clear(int irq);
+
+/* Enable Interrupt. This function will unmask the IRQ at the interrupt
+ * controller. This is normally done by _register(). Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ *  irq       System IRQ number
+ */
+extern void BSP_shared_interrupt_unmask(int irq);
+
+/* Disable Interrupt. This function will mask one IRQ at the interrupt
+ * controller. This is normally done by _unregister().  Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ *  irq         System IRQ number
+ */
+extern void BSP_shared_interrupt_mask(int irq);
+
 #ifdef __cplusplus
 }
Index: c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
===================================================================
--- c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,36 @@
+/* LEON3 generic shared IRQ setup
+ *
+ * Based on libbsp/shared/include/irq.h.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_LEON3_IRQ_CONFIG_H
+#define LIBBSP_LEON3_IRQ_CONFIG_H
+
+#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
+#define BSP_INTERRUPT_VECTOR_MAX_EXT 31 /* Extended IRQ controller */
+
+#define BSP_INTERRUPT_VECTOR_MIN 0
+#define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_EXT
+
+/* The check is different depending on IRQ controller, runtime detected */
+#define BSP_INTERRUPT_CUSTOM_VALID_VECTOR
+
+extern int LEON3_IrqCtrl_EIrq;
+
+/**
+ * @brief Returns true if the interrupt vector with number @a vector is valid.
+ */
+static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
+{
+  return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
+    && ((vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX_STD &&
+        LEON3_IrqCtrl_EIrq == 0) ||
+       (vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX_EXT &&
+        LEON3_IrqCtrl_EIrq != 0));
+}
+
+#endif /* LIBBSP_LEON3_IRQ_CONFIG_H */
Index: c/src/lib/libbsp/sparc/leon3/include/leon.h
===================================================================
--- c/src/lib/libbsp/sparc/leon3/include/leon.h	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon3/include/leon.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -153,4 +153,21 @@
 extern int LEON3_Cpu_Index;
 
+/* The external IRQ number, -1 if not external interrupts */
+extern int LEON3_IrqCtrl_EIrq;
+
+static __inline__ int bsp_irq_fixup(int irq)
+{
+       int eirq;
+
+       if (LEON3_IrqCtrl_EIrq != 0 && irq == LEON3_IrqCtrl_EIrq) {
+               /* Get interrupt number from IRQ controller */
+               eirq = LEON3_IrqCtrl_Regs->intid[LEON3_Cpu_Index] & 0x1f;
+               if (eirq & 0x10)
+                       irq = eirq;
+       }
+
+       return irq;
+}
+
 /* Macros used for manipulating bits in LEON3 GP Timer Control Register */
 
@@ -233,4 +250,15 @@
   } while (0)
 
+/* Make all SPARC BSPs have common macros for interrupt handling */
+#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
+#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
+#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
+#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
+#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
+#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
+#define BSP_Disable_interrupt(_source, _previous) \
+        LEON_Disable_interrupt(_source, _prev)
+#define BSP_Restore_interrupt(_source, _previous) \
+        LEON_Restore_interrupt(_source, _previous)
 
 /*
Index: c/src/lib/libbsp/sparc/leon3/preinstall.am
===================================================================
--- c/src/lib/libbsp/sparc/leon3/preinstall.am	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/leon3/preinstall.am	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -86,4 +86,16 @@
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/ambapp.h
 
+$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
+
+$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: include/bsp/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
 $(PROJECT_INCLUDE)/pci.h: ../../sparc/shared/include/pci.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci.h
Index: c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c
===================================================================
--- c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,25 @@
+/*  Installs the BSP pre-driver hook
+ *
+ *  COPYRIGHT (c) 2011
+ *  Aeroflex Gaisler
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+
+/*
+ *  bsp_predriver_hook
+ *
+ *  BSP predriver hook. Called just before drivers are initialized.
+ *  Is used to initialize shared interrupt handling.
+ */
+void bsp_predriver_hook( void )
+{
+  /* Initialize shared interrupt handling, must be done after IRQ
+   * controller has been found and initialized.
+   */
+  BSP_shared_interrupt_init();
+}
Index: c/src/lib/libbsp/sparc/leon3/startup/eirq.c
===================================================================
--- c/src/lib/libbsp/sparc/leon3/startup/eirq.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/leon3/startup/eirq.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,25 @@
+/*
+ *  GRLIB/LEON3 extended interrupt controller
+ *
+ *  COPYRIGHT (c) 2011
+ *  Aeroflex Gaisler
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#include <bsp.h>
+
+/* GRLIB extended IRQ controller IRQ number */
+int LEON3_IrqCtrl_EIrq = -1;
+
+/* Initialize Extended Interrupt controller */
+void leon3_ext_irq_init(void)
+{
+  if ( (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf ) {
+    /* Extended IRQ controller available */
+    LEON3_IrqCtrl_EIrq = (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf;
+  }
+}
Index: c/src/lib/libbsp/sparc/shared/include/ambapp.h
===================================================================
--- c/src/lib/libbsp/sparc/shared/include/ambapp.h	(revision 8b8eecbc1d5655f442d4e04bce4612e1b20fadf0)
+++ c/src/lib/libbsp/sparc/shared/include/ambapp.h	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -273,4 +273,6 @@
   volatile unsigned int mask[16];
   volatile unsigned int force[16];
+  /* Extended IRQ registers */
+  volatile unsigned int intid[16];
 } LEON3_IrqCtrl_Regs_Map;
 
Index: c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
===================================================================
--- c/src/lib/libbsp/sparc/shared/irq/irq-shared.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
+++ c/src/lib/libbsp/sparc/shared/irq/irq-shared.c	(revision c74bd51514f548286f20577c48aef4275c9e1f3c)
@@ -0,0 +1,83 @@
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+
+static inline void bsp_dispatch_irq(int irq)
+{
+       bsp_interrupt_handler_entry *e =
+               &bsp_interrupt_handler_table[bsp_interrupt_handler_index(irq)];
+
+       while (e != NULL) {
+               (*e->handler)(e->arg);
+               e = e->next;
+       }
+}
+
+/* Called directly from IRQ trap handler TRAP[0x10..0x1F] = IRQ[0..15] */
+static void BSP_ISR_handler(rtems_vector_number vector)
+{
+       int irq = vector - 0x10;
+
+       /* Let BSP fixup and/or handle incomming IRQ */
+       irq = bsp_irq_fixup(irq);
+
+       bsp_dispatch_irq(irq);
+}
+
+/* Initialize interrupts */
+int BSP_shared_interrupt_init(void)
+{
+       rtems_vector_number vector;
+       rtems_isr_entry previous_isr;
+       int sc, i;
+
+       for (i=0; i <= BSP_INTERRUPT_VECTOR_MAX_STD; i++) {
+               vector = SPARC_ASYNCHRONOUS_TRAP(i) + 0x10;
+               rtems_interrupt_catch(BSP_ISR_handler, vector, &previous_isr);
+       }
+
+       /* Initalize interrupt support */
+       sc = bsp_interrupt_initialize();
+       if (sc != RTEMS_SUCCESSFUL)
+               return -1;
+
+       return 0;
+}
+
+/* Callback from bsp_interrupt_initialize() */
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+       return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+       BSP_Unmask_interrupt((int)vector);
+
+       return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+       BSP_Mask_interrupt((int)vector);
+
+       return RTEMS_SUCCESSFUL;
+}
+
+void BSP_shared_interrupt_mask(int irq)
+{
+       BSP_Mask_interrupt(irq);
+}
+
+void BSP_shared_interrupt_unmask(int irq)
+{
+       BSP_Unmask_interrupt(irq);
+}
+
+void BSP_shared_interrupt_clear(int irq)
+{
+       /* We don't have to interrupt lock here, because the register is only
+        * written and self clearing
+        */
+       BSP_Clear_interrupt(irq);
+}
