summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libbsp/sparc/Makefile.am3
-rw-r--r--c/src/lib/libbsp/sparc/erc32/Makefile.am16
-rw-r--r--c/src/lib/libbsp/sparc/erc32/include/bsp.h75
-rw-r--r--c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h20
-rw-r--r--c/src/lib/libbsp/sparc/erc32/include/erc32.h17
-rw-r--r--c/src/lib/libbsp/sparc/erc32/preinstall.am12
-rw-r--r--c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c25
-rw-r--r--c/src/lib/libbsp/sparc/leon2/Makefile.am15
-rw-r--r--c/src/lib/libbsp/sparc/leon2/include/bsp.h74
-rw-r--r--c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h20
-rw-r--r--c/src/lib/libbsp/sparc/leon2/include/leon.h17
-rw-r--r--c/src/lib/libbsp/sparc/leon2/preinstall.am12
-rw-r--r--c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c25
-rw-r--r--c/src/lib/libbsp/sparc/leon3/Makefile.am16
-rw-r--r--c/src/lib/libbsp/sparc/leon3/amba/amba.c6
-rw-r--r--c/src/lib/libbsp/sparc/leon3/include/bsp.h74
-rw-r--r--c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h36
-rw-r--r--c/src/lib/libbsp/sparc/leon3/include/leon.h28
-rw-r--r--c/src/lib/libbsp/sparc/leon3/preinstall.am12
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c25
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/eirq.c25
-rw-r--r--c/src/lib/libbsp/sparc/shared/include/ambapp.h2
-rw-r--r--c/src/lib/libbsp/sparc/shared/irq/irq-shared.c83
23 files changed, 634 insertions, 4 deletions
diff --git a/c/src/lib/libbsp/sparc/Makefile.am b/c/src/lib/libbsp/sparc/Makefile.am
index b1b6a22869..4f445ba49d 100644
--- a/c/src/lib/libbsp/sparc/Makefile.am
+++ b/c/src/lib/libbsp/sparc/Makefile.am
@@ -12,6 +12,9 @@ EXTRA_DIST =
EXTRA_DIST += shared/gnatcommon.c
EXTRA_DIST += shared/start.S
+# Interrupt
+EXTRA_DIST += shared/irq/irq-shared.c
+
# AMBA Plug&Play bus
EXTRA_DIST += shared/include/ambapp.h
EXTRA_DIST += shared/amba/ambapp.c
diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
index e70310df54..615a3e098a 100644
--- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
+++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
@@ -33,7 +33,7 @@ libbsp_a_SOURCES =
# 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 \
../../shared/sbrk.c startup/setvec.c startup/spurious.c \
@@ -55,6 +55,20 @@ libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
# 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
libbsp_a_SOURCES += ../../shared/smp/getcpuid.c ../../shared/smp/smp_stub.c \
../../shared/smp/bspsmp_wait_for.c
diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp.h b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
index a88673ebf4..879e7144e0 100644
--- a/c/src/lib/libbsp/sparc/erc32/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
@@ -30,8 +30,8 @@ extern "C" {
#include <rtems/iosupp.h>
#include <erc32.h>
#include <rtems/clockdrv.h>
-
#include <rtems/console.h>
+#include <rtems/irq-extension.h>
/*
* BSP provides its own Idle thread body
@@ -86,6 +86,79 @@ void bsp_spurious_initialize( void );
*/
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
}
#endif
diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h b/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
new file mode 100644
index 0000000000..c0e931b1b2
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
@@ -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 */
diff --git a/c/src/lib/libbsp/sparc/erc32/include/erc32.h b/c/src/lib/libbsp/sparc/erc32/include/erc32.h
index dcc619069f..2795dcb13b 100644
--- a/c/src/lib/libbsp/sparc/erc32/include/erc32.h
+++ b/c/src/lib/libbsp/sparc/erc32/include/erc32.h
@@ -324,6 +324,11 @@ typedef struct {
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,
* and the Interrupt Pending Registers.
@@ -396,6 +401,18 @@ extern ERC32_Register_Map ERC32_MEC;
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)
+
/*
* The following macros attempt to hide the fact that the General Purpose
* Timer and Real Time Clock Timer share the Timer Control Register. Because
diff --git a/c/src/lib/libbsp/sparc/erc32/preinstall.am b/c/src/lib/libbsp/sparc/erc32/preinstall.am
index 6c0b907910..a235296e1f 100644
--- a/c/src/lib/libbsp/sparc/erc32/preinstall.am
+++ b/c/src/lib/libbsp/sparc/erc32/preinstall.am
@@ -73,3 +73,15 @@ $(PROJECT_LIB)/linkcmds.base: ../shared/startup/linkcmds.base $(PROJECT_LIB)/$(d
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.base
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
+
diff --git a/c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c b/c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c
new file mode 100644
index 0000000000..4084b5ca97
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c
@@ -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();
+}
diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
index 6e2697fb15..2acca78685 100644
--- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
@@ -51,7 +51,7 @@ libbsp_a_SOURCES =
# 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 \
../../shared/sbrk.c startup/setvec.c startup/spurious.c startup/bspidle.c \
@@ -66,6 +66,19 @@ libbsp_a_SOURCES += console/console.c console/debugputs.c
# clock
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
# PCI
diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
index 796290e915..e96a63ee90 100644
--- a/c/src/lib/libbsp/sparc/leon2/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
@@ -30,6 +30,7 @@ extern "C" {
#include <leon.h>
#include <rtems/clockdrv.h>
#include <rtems/console.h>
+#include <rtems/irq-extension.h>
/* SPARC CPU variant: LEON2 */
#define LEON2 1
@@ -105,6 +106,79 @@ void bsp_spurious_initialize( void );
*/
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
}
#endif
diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h b/c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h
new file mode 100644
index 0000000000..709b5631aa
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h
@@ -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 */
diff --git a/c/src/lib/libbsp/sparc/leon2/include/leon.h b/c/src/lib/libbsp/sparc/leon2/include/leon.h
index c183c90ff4..1e4bff2cb5 100644
--- a/c/src/lib/libbsp/sparc/leon2/include/leon.h
+++ b/c/src/lib/libbsp/sparc/leon2/include/leon.h
@@ -271,6 +271,11 @@ typedef struct {
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,
* and the Interrupt Pending Registers.
@@ -338,6 +343,18 @@ extern LEON_Register_Map LEON_REG;
sparc_enable_interrupts( _level ); \
} 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:
*
diff --git a/c/src/lib/libbsp/sparc/leon2/preinstall.am b/c/src/lib/libbsp/sparc/leon2/preinstall.am
index 4b7d4daf29..00ed05ea78 100644
--- a/c/src/lib/libbsp/sparc/leon2/preinstall.am
+++ b/c/src/lib/libbsp/sparc/leon2/preinstall.am
@@ -145,6 +145,18 @@ $(PROJECT_LIB)/linkcmds.base: ../shared/startup/linkcmds.base $(PROJECT_LIB)/$(d
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.base
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
PREINSTALL_FILES += $(PROJECT_INCLUDE)/i2cmst.h
diff --git a/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c b/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
new file mode 100644
index 0000000000..4084b5ca97
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
@@ -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();
+}
diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
index dc24051b64..ebbeb46b18 100644
--- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
@@ -35,7 +35,7 @@ libbsp_a_SOURCES =
# startup
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 \
../../shared/bspinit.c ../../sparc/shared/startup/early_malloc.c
@@ -55,6 +55,20 @@ libbsp_a_SOURCES += console/debugputs.c
# clock
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
libbsp_a_SOURCES += pci/pci.c ../../sparc/shared/pci/pcifinddevice.c
diff --git a/c/src/lib/libbsp/sparc/leon3/amba/amba.c b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
index b0a43f9c19..03af2265d2 100644
--- a/c/src/lib/libbsp/sparc/leon3/amba/amba.c
+++ b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
@@ -18,6 +18,9 @@
/* 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 */
volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;
@@ -48,6 +51,9 @@ void amba_initialize(void)
LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *) dev.start;
}
+ /* Init Extended IRQ controller if available */
+ leon3_ext_irq_init();
+
/* find GP Timer */
i = amba_find_apbslv(&amba_conf,VENDOR_GAISLER,GAISLER_GPTIMER,&dev);
if ( i > 0 ){
diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
index 07a7412e16..e5ae2c1912 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
@@ -30,6 +30,7 @@ extern "C" {
#include <leon.h>
#include <rtems/clockdrv.h>
#include <rtems/console.h>
+#include <rtems/irq-extension.h>
/* SPARC CPU variant: LEON3 */
#define LEON3 1
@@ -115,6 +116,79 @@ void bsp_spurious_initialize( void );
*/
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
}
#endif
diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h b/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
new file mode 100644
index 0000000000..71c0df3c5d
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
@@ -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 */
diff --git a/c/src/lib/libbsp/sparc/leon3/include/leon.h b/c/src/lib/libbsp/sparc/leon3/include/leon.h
index fd208b083a..819800cf59 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/leon.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/leon.h
@@ -152,6 +152,23 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
/* LEON3 CPU Index of boot CPU */
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 */
#define LEON3_GPTIMER_EN 1
@@ -232,6 +249,17 @@ extern int LEON3_Cpu_Index;
sparc_enable_interrupts( _level ); \
} 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:
diff --git a/c/src/lib/libbsp/sparc/leon3/preinstall.am b/c/src/lib/libbsp/sparc/leon3/preinstall.am
index b948529704..8c27b81933 100644
--- a/c/src/lib/libbsp/sparc/leon3/preinstall.am
+++ b/c/src/lib/libbsp/sparc/leon3/preinstall.am
@@ -85,6 +85,18 @@ $(PROJECT_INCLUDE)/ambapp.h: ../../sparc/shared/include/ambapp.h $(PROJECT_INCLU
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ambapp.h
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
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci.h
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c b/c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c
new file mode 100644
index 0000000000..4084b5ca97
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c
@@ -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();
+}
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/eirq.c b/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
new file mode 100644
index 0000000000..d62035ec84
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
@@ -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;
+ }
+}
diff --git a/c/src/lib/libbsp/sparc/shared/include/ambapp.h b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
index e2b557d85e..cc8e12005a 100644
--- a/c/src/lib/libbsp/sparc/shared/include/ambapp.h
+++ b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
@@ -272,6 +272,8 @@ typedef struct {
volatile unsigned int notused23;
volatile unsigned int mask[16];
volatile unsigned int force[16];
+ /* Extended IRQ registers */
+ volatile unsigned int intid[16];
} LEON3_IrqCtrl_Regs_Map;
/*****************************/
diff --git a/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
new file mode 100644
index 0000000000..22f2564723
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
@@ -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);
+}