summaryrefslogtreecommitdiffstats
path: root/bsps/arm
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:50:39 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708 (patch)
tree5dc76f7a4527b0a500fbf5ee91486b2780e47a1a /bsps/arm
parentbsps: Move SPI drivers to bsps (diff)
downloadrtems-8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708.tar.bz2
bsps: Move interrupt controller support to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/arm')
-rw-r--r--bsps/arm/beagle/irq/irq.c144
-rw-r--r--bsps/arm/csb336/irq/irq.c51
-rw-r--r--bsps/arm/csb337/irq/irq.c56
-rw-r--r--bsps/arm/edb7312/irq/bsp_irq_asm.S323
-rw-r--r--bsps/arm/edb7312/irq/irq.c180
-rw-r--r--bsps/arm/gdbarmsim/irq/irq-dispatch.c50
-rw-r--r--bsps/arm/gdbarmsim/irq/irq.c71
-rw-r--r--bsps/arm/gumstix/irq/irq.c51
-rw-r--r--bsps/arm/lpc176x/irq/irq.c75
-rw-r--r--bsps/arm/lpc24xx/irq/irq-dispatch.c50
-rw-r--r--bsps/arm/lpc24xx/irq/irq.c120
-rwxr-xr-xbsps/arm/lpc32xx/irq/irq.c344
-rw-r--r--bsps/arm/raspberrypi/irq/irq.c168
-rw-r--r--bsps/arm/rtl22xx/irq/irq.c70
-rw-r--r--bsps/arm/shared/irq/irq-armv7m.c67
-rw-r--r--bsps/arm/shared/irq/irq-dispatch-armv7m.c32
-rw-r--r--bsps/arm/shared/irq/irq-gic.c180
-rw-r--r--bsps/arm/smdk2410/irq/irq.c45
-rw-r--r--bsps/arm/tms570/irq/irq.c202
19 files changed, 2279 insertions, 0 deletions
diff --git a/bsps/arm/beagle/irq/irq.c b/bsps/arm/beagle/irq/irq.c
new file mode 100644
index 0000000000..2fa1a5b0f0
--- /dev/null
+++ b/bsps/arm/beagle/irq/irq.c
@@ -0,0 +1,144 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ * @ingroup arm_beagle
+ *
+ * @brief Interrupt support.
+ */
+
+/*
+ * Copyright (c) 2014 Ben Gras <beng@shrike-systems.com>. All rights reserved.
+ *
+ * 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/linker-symbols.h>
+#include <bsp/fatal.h>
+
+#include <rtems/score/armv4.h>
+
+#include <libcpu/arm-cp15.h>
+
+struct omap_intr
+{
+ uint32_t base;
+ int size;
+};
+
+#if IS_DM3730
+static struct omap_intr omap_intr = {
+ .base = OMAP3_DM37XX_INTR_BASE,
+ .size = 0x1000,
+};
+#endif
+
+#if IS_AM335X
+static struct omap_intr omap_intr = {
+ .base = OMAP3_AM335X_INTR_BASE,
+ .size = 0x1000,
+};
+#endif
+
+/* Enables interrupts at the Interrupt Controller side. */
+static inline void omap_irq_ack(void)
+{
+ mmio_write(omap_intr.base + OMAP3_INTCPS_CONTROL, OMAP3_INTR_NEWIRQAGR);
+
+ /* Flush data cache to make sure all the previous writes are done
+ before re-enabling interrupts. */
+ flush_data_cache();
+}
+
+void bsp_interrupt_dispatch(void)
+{
+ const uint32_t reg = mmio_read(omap_intr.base + OMAP3_INTCPS_SIR_IRQ);
+
+ if ((reg & OMAP3_INTR_SPURIOUSIRQ_MASK) != OMAP3_INTR_SPURIOUSIRQ_MASK) {
+ const rtems_vector_number irq = reg & OMAP3_INTR_ACTIVEIRQ_MASK;
+
+ bsp_interrupt_handler_dispatch(irq);
+ } else {
+ /* Ignore spurious interrupts. We'll still ACK it so new interrupts
+ can be generated. */
+ }
+
+ omap_irq_ack();
+}
+
+/* There are 4 32-bit interrupt mask registers for a total of 128 interrupts.
+ The IRQ number tells us which register to use. */
+static uint32_t omap_get_mir_reg(rtems_vector_number vector, uint32_t *const mask)
+{
+ uint32_t mir_reg;
+
+ /* Select which bit to set/clear in the MIR register. */
+ *mask = 1ul << (vector % 32u);
+
+ if (vector < 32u) {
+ mir_reg = OMAP3_INTCPS_MIR0;
+ } else if (vector < 64u) {
+ mir_reg = OMAP3_INTCPS_MIR1;
+ } else if (vector < 96u) {
+ mir_reg = OMAP3_INTCPS_MIR2;
+ } else if (vector < 128u) {
+ mir_reg = OMAP3_INTCPS_MIR3;
+ } else {
+ /* Invalid IRQ number. This should never happen. */
+ bsp_fatal(0);
+ }
+
+ return mir_reg;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ uint32_t mask, cur;
+ uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
+
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ cur = mmio_read(omap_intr.base + mir_reg);
+ mmio_write(omap_intr.base + mir_reg, cur & ~mask);
+ flush_data_cache();
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ uint32_t mask, cur;
+ uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
+
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ cur = mmio_read(omap_intr.base + mir_reg);
+ mmio_write(omap_intr.base + mir_reg, cur | mask);
+ flush_data_cache();
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ int i;
+ uint32_t intc_ilrx;
+
+ /* AM335X TRM 6.2.1 Initialization Sequence */
+ mmio_write(omap_intr.base + OMAP3_INTCPS_SYSCONFIG, OMAP3_SYSCONFIG_AUTOIDLE);
+ mmio_write(omap_intr.base + OMAP3_INTCPS_IDLE, 0);
+ /* priority 0 to all IRQs */
+ for(intc_ilrx = 0x100; intc_ilrx <= 0x2fc; intc_ilrx += 4) {
+ mmio_write(omap_intr.base + intc_ilrx, 0);
+ }
+
+ /* Mask all interrupts */
+ for(i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; i++)
+ bsp_interrupt_vector_disable(i);
+
+ /* Install generic interrupt handler */
+ arm_cp15_set_exception_handler(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt);
+ arm_cp15_set_vector_base_address(bsp_vector_table_begin);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/csb336/irq/irq.c b/bsps/arm/csb336/irq/irq.c
new file mode 100644
index 0000000000..e5887b9717
--- /dev/null
+++ b/bsps/arm/csb336/irq/irq.c
@@ -0,0 +1,51 @@
+/*
+ * Motorola MC9328MXL Interrupt handler
+ *
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#include <mc9328mxl.h>
+
+void bsp_interrupt_dispatch(void)
+{
+
+ rtems_vector_number vector = MC9328MXL_AITC_NIVECSR >> 16;
+
+ bsp_interrupt_handler_dispatch(vector);
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ if (vector < MC9328MXL_NUM_INTS)
+ MC9328MXL_AITC_INTENNUM = vector;
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ if (vector < MC9328MXL_NUM_INTS)
+ MC9328MXL_AITC_INTDISNUM = vector;
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/csb337/irq/irq.c b/bsps/arm/csb337/irq/irq.c
new file mode 100644
index 0000000000..95e93845b9
--- /dev/null
+++ b/bsps/arm/csb337/irq/irq.c
@@ -0,0 +1,56 @@
+/*
+ * Atmel AT91RM9200 Interrupt handler
+ *
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#include <at91rm9200.h>
+
+void bsp_interrupt_dispatch(void)
+{
+ rtems_vector_number vector = AIC_CTL_REG(AIC_IVR);
+
+ bsp_interrupt_handler_dispatch(vector);
+
+ AIC_CTL_REG(AIC_EOICR) = 0;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ AIC_CTL_REG(AIC_IECR) = 1 << vector;
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ AIC_CTL_REG(AIC_IDCR) = 1 << vector;
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ unsigned long i = 0;
+
+ for (i = 0; i < 32; ++i) {
+ AIC_SVR_REG(i<<2) = i;
+ }
+
+ /* disable all interrupts */
+ AIC_CTL_REG(AIC_IDCR) = 0xffffffff;
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/edb7312/irq/bsp_irq_asm.S b/bsps/arm/edb7312/irq/bsp_irq_asm.S
new file mode 100644
index 0000000000..c48466967b
--- /dev/null
+++ b/bsps/arm/edb7312/irq/bsp_irq_asm.S
@@ -0,0 +1,323 @@
+/*
+ * Cirrus EP7312 Intererrupt handler
+ */
+
+/*
+ * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ * Copyright (c) 2002 by Charlie Steader <charlies@poliac.com>
+ *
+ * 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.
+*/
+
+#define __asm__
+#include <bsp.h>
+#include <bsp/irq.h>
+
+ .extern edb7312_interrupt_dispatch
+
+/*
+ * Function to obtain, execute an IT handler and acknowledge the IT
+ */
+
+ .globl bsp_interrupt_dispatch
+bsp_interrupt_dispatch :
+/*
+ * Look at interrupt status register to determine source.
+ * From source, determine offset into expanded vector table
+ * and load handler address into r0.
+ */
+
+ ldr r1, =0x80000000 /* close to interrupt status/mask registers 1 */
+ ldr r2, =0x80001000 /* close to interrupt status/mask registers 2 */
+ ldr r3, =0x80002000 /* close to interrupt status/mask registers 3 */
+
+ stmdb sp!,{r4, r5, r6}
+
+/*
+ * INTSR3
+ */
+check_dai:
+ ldr r4, [r3, #0x240]
+ ldr r5, [r3, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+ tst r6, #0x0001
+ beq check_extfiq
+ mov r0, #BSP_DAIINT
+ b get_handler
+
+/*
+ * INTSR1
+ */
+check_extfiq:
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+ tst r6, #0x0001
+ beq check_bl
+ mov r0, #BSP_EXTFIQ
+ b get_handler
+
+check_bl:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0002
+ beq check_we
+ mov r0, #BSP_BLINT
+ b get_handler
+
+check_we:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0004
+ beq check_mc
+ mov r0, #BSP_WEINT
+ b get_handler
+
+check_mc:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0008
+ beq check_cs
+ mov r0, #BSP_MCINT
+ b get_handler
+
+check_cs:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0010
+ beq check_e1
+ mov r0, #BSP_CSINT
+ b get_handler
+
+check_e1:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0020
+ beq check_e2
+ mov r0, #BSP_EINT1
+ b get_handler
+
+check_e2:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0040
+ beq check_e3
+ mov r0, #BSP_EINT2
+ b get_handler
+
+check_e3:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0080
+ beq check_tc1
+ mov r0, #BSP_EINT3
+ b get_handler
+
+check_tc1:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0100
+ beq check_tc2
+ mov r0, #BSP_TC1OI
+ b get_handler
+
+check_tc2:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0200
+ beq check_rtc
+ mov r0, #BSP_TC2OI
+ b get_handler
+
+check_rtc:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0400
+ beq check_tick
+ mov r0, #BSP_RTCMI
+ b get_handler
+
+check_tick:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0800
+ beq check_utx1
+ mov r0, #BSP_TINT
+ b get_handler
+
+check_utx1:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x1000
+ beq check_urx1
+ mov r0, #BSP_UTXINT1
+ b get_handler
+
+check_urx1:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x2000
+ beq check_ums
+ mov r0, #BSP_URXINT1
+ b get_handler
+
+check_ums:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x4000
+ beq check_sse
+ mov r0, #BSP_UMSINT
+ b get_handler
+
+check_sse:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r1, #0x240]
+ ldr r5, [r1, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x8000
+ beq check_kbd
+ mov r0, #BSP_SSEOTI
+ b get_handler
+
+/*
+ * INTSR2
+ */
+check_kbd:
+ ldr r4, [r2, #0x240]
+ ldr r5, [r2, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+ tst r6, #0x0001
+ beq check_ss2rx
+ mov r0, #BSP_KBDINT
+ b get_handler
+
+check_ss2rx:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r2, #0x240]
+ ldr r5, [r2, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0002
+ beq check_ss2tx
+ mov r0, #BSP_SS2RX
+ b get_handler
+
+check_ss2tx:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r2, #0x240]
+ ldr r5, [r2, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x0004
+ beq check_utx2
+ mov r0, #BSP_SS2TX
+ b get_handler
+
+check_utx2:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r2, #0x240]
+ ldr r5, [r2, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x1000
+ beq check_urx2
+ mov r0, #BSP_UTXINT2
+ b get_handler
+
+check_urx2:
+#if 0
+MUST REMEMBER TO UNCOMMENT IF THIS HANDLER MOVES
+ ldr r4, [r2, #0x240]
+ ldr r5, [r2, #0x280]
+ and r6, r4, r5 /* only look at interrupts which are enabled */
+#endif
+ tst r6, #0x2000
+ beq IRQ_NoInterrupt
+ mov r0, #BSP_URXINT2
+ b get_handler
+
+get_handler:
+
+ ldmia sp!,{r4, r5, r6}
+
+ /*
+ * re-enable interrupts at processor level as the current
+ * interrupt source is now masked via VEGA logic
+ */
+/*
+ mrs r1, cpsr
+ and r1, r1, #0xFFFFFF3F
+ msr cpsr, r1
+*/
+
+ stmdb sp!,{lr}
+ bl edb7312_interrupt_dispatch
+ ldmia sp!,{lr}
+
+IRQ_NoInterrupt:
+ /* return to the "main" interrupt handler */
+ mov pc, lr
diff --git a/bsps/arm/edb7312/irq/irq.c b/bsps/arm/edb7312/irq/irq.c
new file mode 100644
index 0000000000..1d9151a1bd
--- /dev/null
+++ b/bsps/arm/edb7312/irq/irq.c
@@ -0,0 +1,180 @@
+/*
+ * Cirrus EP7312 Intererrupt handler
+ */
+
+/*
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ * Copyright (c) 2002 by Charlie Steader <charlies@poliac.com>
+ *
+ * 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/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#include <ep7312.h>
+
+void edb7312_interrupt_dispatch(rtems_vector_number vector)
+{
+ bsp_interrupt_handler_dispatch(vector);
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ if(vector >= BSP_EXTFIQ && vector <= BSP_SSEOTI)
+ {
+ /* interrupt managed by INTMR1 and INTSR1 */
+ *EP7312_INTMR1 |= (1 << vector);
+ }
+ else if(vector >= BSP_KBDINT && vector <= BSP_SS2TX)
+ {
+ /* interrupt managed by INTMR2 and INTSR2 */
+ *EP7312_INTMR2 |= (1 << (vector - 16));
+ }
+ else if(vector >= BSP_UTXINT2 && vector <= BSP_URXINT2)
+ {
+ /* interrupt managed by INTMR2 and INTSR2 */
+ *EP7312_INTMR2 |= (1 << (vector - 7));
+ }
+ else if(vector == BSP_DAIINT)
+ {
+ /* interrupt managed by INTMR3 and INTSR3 */
+ *EP7312_INTMR3 |= (1 << (vector - 21));
+ }
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ if(vector >= BSP_EXTFIQ && vector <= BSP_SSEOTI)
+ {
+ /* interrupt managed by INTMR1 and INTSR1 */
+ *EP7312_INTMR1 &= ~(1 << vector);
+ }
+ else if(vector >= BSP_KBDINT && vector <= BSP_SS2TX)
+ {
+ /* interrupt managed by INTMR2 and INTSR2 */
+ *EP7312_INTMR2 &= ~(1 << (vector - 16));
+ }
+ else if(vector >= BSP_UTXINT2 && vector <= BSP_URXINT2)
+ {
+ /* interrupt managed by INTMR2 and INTSR2 */
+ *EP7312_INTMR2 &= ~(1 << (vector - 7));
+ }
+ else if(vector == BSP_DAIINT)
+ {
+ /* interrupt managed by INTMR3 and INTSR3 */
+ *EP7312_INTMR3 &= ~(1 << (vector - 21));
+ }
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ uint32_t int_stat = 0;
+
+ /* mask all interrupts */
+ *EP7312_INTMR1 = 0x0;
+ *EP7312_INTMR2 = 0x0;
+ *EP7312_INTMR3 = 0x0;
+
+ /* clear all pending interrupt status' */
+ int_stat = *EP7312_INTSR1;
+ if(int_stat & EP7312_INTR1_EXTFIQ)
+ {
+ }
+ if(int_stat & EP7312_INTR1_BLINT)
+ {
+ *EP7312_BLEOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_WEINT)
+ {
+ *EP7312_TEOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_MCINT)
+ {
+ }
+ if(int_stat & EP7312_INTR1_CSINT)
+ {
+ *EP7312_COEOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_EINT1)
+ {
+ }
+ if(int_stat & EP7312_INTR1_EINT2)
+ {
+ }
+ if(int_stat & EP7312_INTR1_EINT3)
+ {
+ }
+ if(int_stat & EP7312_INTR1_TC1OI)
+ {
+ *EP7312_TC1EOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_TC2OI)
+ {
+ *EP7312_TC2EOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_RTCMI)
+ {
+ *EP7312_RTCEOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_TINT)
+ {
+ *EP7312_TEOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_URXINT1)
+ {
+ }
+ if(int_stat & EP7312_INTR1_UTXINT1)
+ {
+ }
+ if(int_stat & EP7312_INTR1_UMSINT)
+ {
+ *EP7312_UMSEOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR1_SSEOTI)
+ {
+ *EP7312_SYNCIO;
+ }
+ int_stat = *EP7312_INTSR1;
+
+ int_stat = *EP7312_INTSR2;
+ if(int_stat & EP7312_INTR2_KBDINT)
+ {
+ *EP7312_KBDEOI = 0xFFFFFFFF;
+ }
+ if(int_stat & EP7312_INTR2_SS2RX)
+ {
+ }
+ if(int_stat & EP7312_INTR2_SS2TX)
+ {
+ }
+ if(int_stat & EP7312_INTR2_URXINT2)
+ {
+ }
+ if(int_stat & EP7312_INTR2_UTXINT2)
+ {
+ }
+ int_stat = *EP7312_INTSR2;
+
+ int_stat = *EP7312_INTSR3;
+ if(int_stat & EP7312_INTR2_DAIINT)
+ {
+ }
+ int_stat = *EP7312_INTSR3;
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/gdbarmsim/irq/irq-dispatch.c b/bsps/arm/gdbarmsim/irq/irq-dispatch.c
new file mode 100644
index 0000000000..f045fb8149
--- /dev/null
+++ b/bsps/arm/gdbarmsim/irq/irq-dispatch.c
@@ -0,0 +1,50 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief GDB ARM Simulator interrupt support.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <rtems/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+void bsp_interrupt_dispatch(void)
+{
+ /* Read current vector number */
+ /* rtems_vector_number vector = VICVectAddr; */
+ rtems_vector_number vector = 0;
+
+ /* Enable interrupts in program status register */
+ uint32_t psr = _ARMV4_Status_irq_enable();
+
+ /* Dispatch interrupt handlers */
+ bsp_interrupt_handler_dispatch(vector);
+
+ /* Restore program status register */
+ _ARMV4_Status_restore(psr);
+
+ /* Acknowledge interrupt */
+ //VICVectAddr = 0;
+}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/bsps/arm/gdbarmsim/irq/irq.c b/bsps/arm/gdbarmsim/irq/irq.c
new file mode 100644
index 0000000000..886f928d2d
--- /dev/null
+++ b/bsps/arm/gdbarmsim/irq/irq.c
@@ -0,0 +1,71 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief GDB ARM Simulator interrupt support.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <rtems/score/armv4.h>
+#include <rtems/score/armv7m.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+/*
+ * Prototypes
+ */
+void lpc24xx_irq_set_priority(rtems_vector_number, unsigned);
+unsigned lpc24xx_irq_get_priority(rtems_vector_number);
+
+static inline bool lpc24xx_irq_is_valid(rtems_vector_number vector)
+{
+ return vector <= BSP_INTERRUPT_VECTOR_MAX;
+}
+
+void lpc24xx_irq_set_priority(rtems_vector_number vector, unsigned priority)
+{
+}
+
+unsigned lpc24xx_irq_get_priority(rtems_vector_number vector)
+{
+ return 0; /* bogus value to avoid warning */
+}
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+}
+
+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)
+{
+ /* Install the IRQ exception handler */
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/bsps/arm/gumstix/irq/irq.c b/bsps/arm/gumstix/irq/irq.c
new file mode 100644
index 0000000000..425795b165
--- /dev/null
+++ b/bsps/arm/gumstix/irq/irq.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * PXA255 Interrupt handler by Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#include <pxa255.h>
+
+void bsp_interrupt_dispatch(void)
+{
+ rtems_vector_number vector = 31 - __builtin_clz(XSCALE_INT_ICIP);
+
+ bsp_interrupt_handler_dispatch(vector);
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ XSCALE_INT_ICMR |= 1 << vector;
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ XSCALE_INT_ICMR &= ~(1 << vector);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ /* disable all interrupts */
+ XSCALE_INT_ICMR = 0x0;
+
+ /* Direct the interrupt to IRQ*/
+ XSCALE_INT_ICLR = 0x0;
+
+ /* Install the IRQ exception handler */
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/lpc176x/irq/irq.c b/bsps/arm/lpc176x/irq/irq.c
new file mode 100644
index 0000000000..e05fd59e6c
--- /dev/null
+++ b/bsps/arm/lpc176x/irq/irq.c
@@ -0,0 +1,75 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief LPC176X interrupt support.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <rtems/score/armv4.h>
+#include <rtems/score/armv7m.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/lpc176x.h>
+#include <bsp/linker-symbols.h>
+
+/**
+ * @brief Checks if the current interrupt vector length is valid or not.
+ *
+ * @param vector The current interrupt vector length.
+ * @return TRUE if valid.
+ * FALSE otherwise.
+ */
+static inline bool lpc176x_irq_is_valid( const rtems_vector_number vector )
+{
+ return vector <= BSP_INTERRUPT_VECTOR_MAX;
+}
+
+void lpc176x_irq_set_priority(
+ const rtems_vector_number vector,
+ unsigned priority
+)
+{
+ if ( lpc176x_irq_is_valid( vector ) ) {
+ if ( priority > LPC176X_IRQ_PRIORITY_VALUE_MAX ) {
+ priority = LPC176X_IRQ_PRIORITY_VALUE_MAX;
+ }
+
+ /* else implies that the priority is unlocked. Also,
+ there is nothing to do. */
+
+ _ARMV7M_NVIC_Set_priority( (int) vector, (int) ( priority << 3u ) );
+ }
+
+ /* else implies that the rtems vector number is invalid. Also,
+ there is nothing to do. */
+}
+
+unsigned lpc176x_irq_get_priority( const rtems_vector_number vector )
+{
+ unsigned priority;
+
+ if ( lpc176x_irq_is_valid( vector ) ) {
+ priority = (unsigned) ( _ARMV7M_NVIC_Get_priority( (int) vector ) >> 3u );
+ } else {
+ priority = LPC176X_IRQ_PRIORITY_VALUE_MIN - 1u;
+ }
+
+ return priority;
+}
diff --git a/bsps/arm/lpc24xx/irq/irq-dispatch.c b/bsps/arm/lpc24xx/irq/irq-dispatch.c
new file mode 100644
index 0000000000..66d05fdf9d
--- /dev/null
+++ b/bsps/arm/lpc24xx/irq/irq-dispatch.c
@@ -0,0 +1,50 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief LPC24XX interrupt support.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <rtems/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/lpc24xx.h>
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+void bsp_interrupt_dispatch(void)
+{
+ /* Read current vector number */
+ rtems_vector_number vector = VICVectAddr;
+
+ /* Enable interrupts in program status register */
+ uint32_t psr = _ARMV4_Status_irq_enable();
+
+ /* Dispatch interrupt handlers */
+ bsp_interrupt_handler_dispatch(vector);
+
+ /* Restore program status register */
+ _ARMV4_Status_restore(psr);
+
+ /* Acknowledge interrupt */
+ VICVectAddr = 0;
+}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/bsps/arm/lpc24xx/irq/irq.c b/bsps/arm/lpc24xx/irq/irq.c
new file mode 100644
index 0000000000..7801c37843
--- /dev/null
+++ b/bsps/arm/lpc24xx/irq/irq.c
@@ -0,0 +1,120 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief LPC24XX interrupt support.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <rtems/score/armv4.h>
+#include <rtems/score/armv7m.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/lpc24xx.h>
+#include <bsp/linker-symbols.h>
+
+static inline bool lpc24xx_irq_is_valid(rtems_vector_number vector)
+{
+ return vector <= BSP_INTERRUPT_VECTOR_MAX;
+}
+
+void lpc24xx_irq_set_priority(rtems_vector_number vector, unsigned priority)
+{
+ if (lpc24xx_irq_is_valid(vector)) {
+ if (priority > LPC24XX_IRQ_PRIORITY_VALUE_MAX) {
+ priority = LPC24XX_IRQ_PRIORITY_VALUE_MAX;
+ }
+
+ #ifdef ARM_MULTILIB_ARCH_V4
+ VICVectPriorityBase [vector] = priority;
+ #else
+ _ARMV7M_NVIC_Set_priority((int) vector, (int) (priority << 3));
+ #endif
+ }
+}
+
+unsigned lpc24xx_irq_get_priority(rtems_vector_number vector)
+{
+ if (lpc24xx_irq_is_valid(vector)) {
+ #ifdef ARM_MULTILIB_ARCH_V4
+ return VICVectPriorityBase [vector];
+ #else
+ return (unsigned) (_ARMV7M_NVIC_Get_priority((int) vector) >> 3);
+ #endif
+ } else {
+ return LPC24XX_IRQ_PRIORITY_VALUE_MIN - 1U;
+ }
+}
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ VICIntEnable = 1U << vector;
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ VICIntEnClear = 1U << vector;
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ volatile uint32_t *addr = VICVectAddrBase;
+ volatile uint32_t *prio = VICVectPriorityBase;
+ rtems_vector_number i = 0;
+
+ /* Disable all interrupts */
+ VICIntEnClear = 0xffffffff;
+
+ /* Clear all software interrupts */
+ VICSoftIntClear = 0xffffffff;
+
+ /* Use IRQ category */
+ VICIntSelect = 0;
+
+ for (i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; ++i) {
+ /* Use the vector address register to store the vector number */
+ addr [i] = i;
+
+ /* Give vector lowest priority */
+ prio [i] = 15;
+ }
+
+ /* Reset priority mask register */
+ VICSWPrioMask = 0xffff;
+
+ /* Acknowledge interrupts for all priorities */
+ for (
+ i = LPC24XX_IRQ_PRIORITY_VALUE_MIN;
+ i <= LPC24XX_IRQ_PRIORITY_VALUE_MAX;
+ ++i
+ ) {
+ VICVectAddr = 0;
+ }
+
+ /* Install the IRQ exception handler */
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/bsps/arm/lpc32xx/irq/irq.c b/bsps/arm/lpc32xx/irq/irq.c
new file mode 100755
index 0000000000..eac320000b
--- /dev/null
+++ b/bsps/arm/lpc32xx/irq/irq.c
@@ -0,0 +1,344 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_interrupt
+ *
+ * @brief Interrupt support.
+ */
+
+/*
+ * Copyright (c) 2009
+ * 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.
+ */
+
+#include <rtems/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/lpc32xx.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/mmu.h>
+
+/*
+ * Mask out SIC 1 and 2 IRQ request. There is no need to mask out the FIQ,
+ * since a pending FIQ would be a fatal error. The default handler will be
+ * invoked in this case.
+ */
+#define LPC32XX_MIC_STATUS_MASK (~0x3U)
+
+typedef union {
+ struct {
+ uint32_t mic;
+ uint32_t sic_1;
+ uint32_t sic_2;
+ } field;
+ uint32_t fields_table [LPC32XX_IRQ_MODULE_COUNT];
+} lpc32xx_irq_fields;
+
+static uint8_t lpc32xx_irq_priority_table [LPC32XX_IRQ_COUNT];
+
+static lpc32xx_irq_fields lpc32xx_irq_priority_masks [LPC32XX_IRQ_PRIORITY_COUNT];
+
+static lpc32xx_irq_fields lpc32xx_irq_enable;
+
+static inline bool lpc32xx_irq_priority_is_valid(unsigned priority)
+{
+ return priority <= LPC32XX_IRQ_PRIORITY_LOWEST;
+}
+
+#define LPC32XX_IRQ_BIT_OPS_DEFINE \
+ unsigned bit = index & 0x1fU; \
+ unsigned module = index >> 5
+
+#define LPC32XX_IRQ_BIT_OPS_FOR_REG_DEFINE \
+ LPC32XX_IRQ_BIT_OPS_DEFINE; \
+ unsigned module_offset = module << 14; \
+ volatile uint32_t *reg = (volatile uint32_t *) \
+ ((volatile char *) &lpc32xx.mic + module_offset + register_offset)
+
+#define LPC32XX_IRQ_OFFSET_ER 0U
+#define LPC32XX_IRQ_OFFSET_RSR 4U
+#define LPC32XX_IRQ_OFFSET_SR 8U
+#define LPC32XX_IRQ_OFFSET_APR 12U
+#define LPC32XX_IRQ_OFFSET_ATR 16U
+#define LPC32XX_IRQ_OFFSET_ITR 20U
+
+static inline bool lpc32xx_irq_is_bit_set_in_register(unsigned index, unsigned register_offset)
+{
+ LPC32XX_IRQ_BIT_OPS_FOR_REG_DEFINE;
+
+ return *reg & (1U << bit);
+}
+
+static inline void lpc32xx_irq_set_bit_in_register(unsigned index, unsigned register_offset)
+{
+ LPC32XX_IRQ_BIT_OPS_FOR_REG_DEFINE;
+
+ *reg |= 1U << bit;
+}
+
+static inline void lpc32xx_irq_clear_bit_in_register(unsigned index, unsigned register_offset)
+{
+ LPC32XX_IRQ_BIT_OPS_FOR_REG_DEFINE;
+
+ *reg &= ~(1U << bit);
+}
+
+static inline void lpc32xx_irq_set_bit_in_field(unsigned index, lpc32xx_irq_fields *fields)
+{
+ LPC32XX_IRQ_BIT_OPS_DEFINE;
+
+ fields->fields_table [module] |= 1U << bit;
+}
+
+static inline void lpc32xx_irq_clear_bit_in_field(unsigned index, lpc32xx_irq_fields *fields)
+{
+ LPC32XX_IRQ_BIT_OPS_DEFINE;
+
+ fields->fields_table [module] &= ~(1U << bit);
+}
+
+static inline unsigned lpc32xx_irq_get_index(uint32_t val)
+{
+ ARM_SWITCH_REGISTERS;
+
+ __asm__ volatile (
+ ARM_SWITCH_TO_ARM
+ "clz %[val], %[val]\n"
+ "rsb %[val], %[val], #31\n"
+ ARM_SWITCH_BACK
+ : [val] "=r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
+ : "[val]" (val)
+ );
+
+ return val;
+}
+
+void lpc32xx_irq_set_priority(rtems_vector_number vector, unsigned priority)
+{
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ rtems_interrupt_level level;
+ unsigned i = 0;
+
+ if (priority > LPC32XX_IRQ_PRIORITY_LOWEST) {
+ priority = LPC32XX_IRQ_PRIORITY_LOWEST;
+ }
+
+ lpc32xx_irq_priority_table [vector] = (uint8_t) priority;
+
+ for (i = LPC32XX_IRQ_PRIORITY_HIGHEST; i <= priority; ++i) {
+ rtems_interrupt_disable(level);
+ lpc32xx_irq_clear_bit_in_field(vector, &lpc32xx_irq_priority_masks [i]);
+ rtems_interrupt_enable(level);
+ }
+
+ for (i = priority + 1; i <= LPC32XX_IRQ_PRIORITY_LOWEST; ++i) {
+ rtems_interrupt_disable(level);
+ lpc32xx_irq_set_bit_in_field(vector, &lpc32xx_irq_priority_masks [i]);
+ rtems_interrupt_enable(level);
+ }
+ }
+}
+
+unsigned lpc32xx_irq_get_priority(rtems_vector_number vector)
+{
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ return lpc32xx_irq_priority_table [vector];
+ } else {
+ return LPC32XX_IRQ_PRIORITY_LOWEST;
+ }
+}
+
+void lpc32xx_irq_set_activation_polarity(rtems_vector_number vector, lpc32xx_irq_activation_polarity activation_polarity)
+{
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+ if (activation_polarity == LPC32XX_IRQ_ACTIVE_HIGH_OR_RISING_EDGE) {
+ lpc32xx_irq_set_bit_in_register(vector, LPC32XX_IRQ_OFFSET_APR);
+ } else {
+ lpc32xx_irq_clear_bit_in_register(vector, LPC32XX_IRQ_OFFSET_APR);
+ }
+ rtems_interrupt_enable(level);
+ }
+}
+
+lpc32xx_irq_activation_polarity lpc32xx_irq_get_activation_polarity(rtems_vector_number vector)
+{
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ if (lpc32xx_irq_is_bit_set_in_register(vector, LPC32XX_IRQ_OFFSET_APR)) {
+ return LPC32XX_IRQ_ACTIVE_HIGH_OR_RISING_EDGE;
+ } else {
+ return LPC32XX_IRQ_ACTIVE_LOW_OR_FALLING_EDGE;
+ }
+ } else {
+ return LPC32XX_IRQ_ACTIVE_LOW_OR_FALLING_EDGE;
+ }
+}
+
+void lpc32xx_irq_set_activation_type(rtems_vector_number vector, lpc32xx_irq_activation_type activation_type)
+{
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+ if (activation_type == LPC32XX_IRQ_EDGE_SENSITIVE) {
+ lpc32xx_irq_set_bit_in_register(vector, LPC32XX_IRQ_OFFSET_ATR);
+ } else {
+ lpc32xx_irq_clear_bit_in_register(vector, LPC32XX_IRQ_OFFSET_ATR);
+ }
+ rtems_interrupt_enable(level);
+ }
+}
+
+lpc32xx_irq_activation_type lpc32xx_irq_get_activation_type(rtems_vector_number vector)
+{
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ if (lpc32xx_irq_is_bit_set_in_register(vector, LPC32XX_IRQ_OFFSET_ATR)) {
+ return LPC32XX_IRQ_EDGE_SENSITIVE;
+ } else {
+ return LPC32XX_IRQ_LEVEL_SENSITIVE;
+ }
+ } else {
+ return LPC32XX_IRQ_LEVEL_SENSITIVE;
+ }
+}
+
+void bsp_interrupt_dispatch(void)
+{
+ uint32_t status = lpc32xx.mic.sr & LPC32XX_MIC_STATUS_MASK;
+ uint32_t er_mic = lpc32xx.mic.er;
+ uint32_t er_sic_1 = lpc32xx.sic_1.er;
+ uint32_t er_sic_2 = lpc32xx.sic_2.er;
+ uint32_t psr = 0;
+ lpc32xx_irq_fields *masks = NULL;
+ rtems_vector_number vector = 0;
+ unsigned priority = 0;
+
+ if (status != 0) {
+ vector = lpc32xx_irq_get_index(status);
+ } else {
+ status = lpc32xx.sic_1.sr;
+ if (status != 0) {
+ vector = lpc32xx_irq_get_index(status) + LPC32XX_IRQ_MODULE_SIC_1;
+ } else {
+ status = lpc32xx.sic_2.sr;
+ if (status != 0) {
+ vector = lpc32xx_irq_get_index(status) + LPC32XX_IRQ_MODULE_SIC_2;
+ } else {
+ return;
+ }
+ }
+ }
+
+ priority = lpc32xx_irq_priority_table [vector];
+
+ masks = &lpc32xx_irq_priority_masks [priority];
+
+ lpc32xx.mic.er = er_mic & masks->field.mic;
+ lpc32xx.sic_1.er = er_sic_1 & masks->field.sic_1;
+ lpc32xx.sic_2.er = er_sic_2 & masks->field.sic_2;
+
+ psr = _ARMV4_Status_irq_enable();
+
+ bsp_interrupt_handler_dispatch(vector);
+
+ _ARMV4_Status_restore(psr);
+
+ lpc32xx.mic.er = er_mic & lpc32xx_irq_enable.field.mic;
+ lpc32xx.sic_1.er = er_sic_1 & lpc32xx_irq_enable.field.sic_1;
+ lpc32xx.sic_2.er = er_sic_2 & lpc32xx_irq_enable.field.sic_2;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ rtems_interrupt_level level;
+
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ rtems_interrupt_disable(level);
+ lpc32xx_irq_set_bit_in_register(vector, LPC32XX_IRQ_OFFSET_ER);
+ lpc32xx_irq_set_bit_in_field(vector, &lpc32xx_irq_enable);
+ rtems_interrupt_enable(level);
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ rtems_interrupt_level level;
+
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ rtems_interrupt_disable(level);
+ lpc32xx_irq_clear_bit_in_field(vector, &lpc32xx_irq_enable);
+ lpc32xx_irq_clear_bit_in_register(vector, LPC32XX_IRQ_OFFSET_ER);
+ rtems_interrupt_enable(level);
+}
+
+void lpc32xx_set_exception_handler(
+ Arm_symbolic_exception_name exception,
+ void (*handler)(void)
+)
+{
+ if ((unsigned) exception < MAX_EXCEPTIONS) {
+ uint32_t *table = (uint32_t *) bsp_vector_table_begin + MAX_EXCEPTIONS;
+
+ table [exception] = (uint32_t) handler;
+
+ #ifndef LPC32XX_DISABLE_MMU
+ rtems_cache_flush_multiple_data_lines(table, 64);
+ rtems_cache_invalidate_multiple_instruction_lines(NULL, 64);
+ #endif
+ }
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ size_t i = 0;
+
+ /* Set default priority */
+ for (i = 0; i < LPC32XX_IRQ_COUNT; ++i) {
+ lpc32xx_irq_priority_table [i] = LPC32XX_IRQ_PRIORITY_LOWEST;
+ }
+
+ /* Enable SIC 1 and 2 at all priorities */
+ for (i = 0; i < LPC32XX_IRQ_PRIORITY_COUNT; ++i) {
+ lpc32xx_irq_priority_masks [i].field.mic = 0xc0000003;
+ }
+
+ /* Disable all interrupts except SIC 1 and 2 */
+ lpc32xx_irq_enable.field.sic_2 = 0x0;
+ lpc32xx_irq_enable.field.sic_1 = 0x0;
+ lpc32xx_irq_enable.field.mic = 0xc0000003;
+ lpc32xx.sic_1.er = 0x0;
+ lpc32xx.sic_2.er = 0x0;
+ lpc32xx.mic.er = 0xc0000003;
+
+ /* Set interrupt types to IRQ */
+ lpc32xx.mic.itr = 0x0;
+ lpc32xx.sic_1.itr = 0x0;
+ lpc32xx.sic_2.itr = 0x0;
+
+ /* Set interrupt activation polarities */
+ lpc32xx.mic.apr = 0x3ff0efe0;
+ lpc32xx.sic_1.apr = 0xfbd27184;
+ lpc32xx.sic_2.apr = 0x801810c0;
+
+ /* Set interrupt activation types */
+ lpc32xx.mic.atr = 0x0;
+ lpc32xx.sic_1.atr = 0x26000;
+ lpc32xx.sic_2.atr = 0x0;
+
+ lpc32xx_set_exception_handler(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/raspberrypi/irq/irq.c b/bsps/arm/raspberrypi/irq/irq.c
new file mode 100644
index 0000000000..5b10385bfe
--- /dev/null
+++ b/bsps/arm/raspberrypi/irq/irq.c
@@ -0,0 +1,168 @@
+/**
+ * @file irq.c
+ *
+ * @ingroup raspberrypi_interrupt
+ *
+ * @brief Interrupt support.
+ */
+
+/*
+ * Copyright (c) 2014 Andre Marques <andre.lousa.marques at gmail.com>
+ *
+ * Copyright (c) 2009
+ * 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.
+ */
+
+#include <rtems/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/raspberrypi.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/mmu.h>
+#include <rtems/bspIo.h>
+#include <strings.h>
+
+#ifdef RTEMS_SMP
+#include <rtems/score/smp.h>
+#include <rtems/score/smpimpl.h>
+#endif
+
+typedef struct {
+ unsigned long enable_reg_addr;
+ unsigned long disable_reg_addr;
+} bcm2835_irq_ctrl_reg_t;
+
+static const bcm2835_irq_ctrl_reg_t bcm2835_irq_ctrl_reg_table[] = {
+ { BCM2835_IRQ_ENABLE1, BCM2835_IRQ_DISABLE1 },
+ { BCM2835_IRQ_ENABLE2, BCM2835_IRQ_DISABLE2 },
+ { BCM2835_IRQ_ENABLE_BASIC, BCM2835_IRQ_DISABLE_BASIC }
+};
+
+static inline const bcm2835_irq_ctrl_reg_t *
+bsp_vector_to_reg(rtems_vector_number vector)
+{
+ return bcm2835_irq_ctrl_reg_table + (vector >> 5);
+}
+
+static inline uint32_t
+bsp_vector_to_mask(rtems_vector_number vector)
+{
+ return 1 << (vector & 0x1f);
+}
+
+static const int bcm2835_irq_speedup_table[] =
+{
+ /* 0 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 0,
+ /* 1 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 1,
+ /* 2 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 2,
+ /* 3 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 3,
+ /* 4 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 4,
+ /* 5 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 5,
+ /* 6 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 6,
+ /* 7 */ BCM2835_IRQ_ID_BASIC_BASE_ID + 7,
+ /* 8 */ -1, /* One or more bits set in pending register 1 */
+ /* 9 */ -2, /* One or more bits set in pending register 2 */
+ /* 10 */ 7, /* GPU IRQ 7 */
+ /* 11 */ 9, /* GPU IRQ 9 */
+ /* 12 */ 10, /* GPU IRQ 10 */
+ /* 13 */ 18, /* GPU IRQ 18 */
+ /* 14 */ 19, /* GPU IRQ 19 */
+ /* 15 */ 53, /* GPU IRQ 53 */
+ /* 16 */ 54, /* GPU IRQ 54 */
+ /* 17 */ 55, /* GPU IRQ 55 */
+ /* 18 */ 56, /* GPU IRQ 56 */
+ /* 19 */ 57, /* GPU IRQ 57 */
+ /* 20 */ 62, /* GPU IRQ 62 */
+};
+
+/*
+ * Define which basic peding register (BCM2835_IRQ_BASIC) bits
+ * should be processed through bcm2835_irq_speedup_table
+ */
+
+#define BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS 0x1ffcff
+
+/*
+ * Determine the source of the interrupt and dispatch the correct handler.
+ */
+void bsp_interrupt_dispatch(void)
+{
+ unsigned int pend;
+ unsigned int pend_bit;
+
+ rtems_vector_number vector = 255;
+
+#ifdef RTEMS_SMP
+ uint32_t cpu_index_self = _SMP_Get_current_processor();
+ uint32_t local_source = BCM2835_REG(BCM2836_IRQ_SOURCE_REG(cpu_index_self));
+
+ if ( local_source & BCM2836_IRQ_SOURCE_MBOX3 ) {
+ /* reset mailbox 3 contents to zero */
+ BCM2835_REG(BCM2836_MAILBOX_3_READ_CLEAR_BASE + 0x10 * cpu_index_self) = 0xffffffff;
+ _SMP_Inter_processor_interrupt_handler();
+ }
+ if ( cpu_index_self != 0 )
+ return;
+#endif /* RTEMS_SMP */
+
+ pend = BCM2835_REG(BCM2835_IRQ_BASIC);
+ if ( pend & BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS ) {
+ pend_bit = ffs(pend) - 1;
+ vector = bcm2835_irq_speedup_table[pend_bit];
+ } else {
+ pend = BCM2835_REG(BCM2835_IRQ_PENDING1);
+ if ( pend != 0 ) {
+ pend_bit = ffs(pend) - 1;
+ vector = pend_bit;
+ } else {
+ pend = BCM2835_REG(BCM2835_IRQ_PENDING2);
+ if ( pend != 0 ) {
+ pend_bit = ffs(pend) - 1;
+ vector = pend_bit + 32;
+ }
+ }
+ }
+
+ if ( vector < 255 )
+ {
+ bsp_interrupt_handler_dispatch(vector);
+ }
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ BCM2835_REG(bsp_vector_to_reg(vector)->enable_reg_addr) =
+ bsp_vector_to_mask(vector);
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ BCM2835_REG(bsp_vector_to_reg(vector)->disable_reg_addr) =
+ bsp_vector_to_mask(vector);
+}
+
+void bsp_interrupt_handler_default(rtems_vector_number vector)
+{
+ printk("spurious interrupt: %lu\n", vector);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ BCM2835_REG(BCM2835_IRQ_DISABLE1) = 0xffffffff;
+ BCM2835_REG(BCM2835_IRQ_DISABLE2) = 0xffffffff;
+ BCM2835_REG(BCM2835_IRQ_DISABLE_BASIC) = 0xffffffff;
+ BCM2835_REG(BCM2835_IRQ_FIQ_CTRL) = 0;
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/rtl22xx/irq/irq.c b/bsps/arm/rtl22xx/irq/irq.c
new file mode 100644
index 0000000000..83e140bd7b
--- /dev/null
+++ b/bsps/arm/rtl22xx/irq/irq.c
@@ -0,0 +1,70 @@
+/*
+ * Philps LPC22XX Interrupt handler
+ *
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * Copyright (c) 2006 by Ray<rayx.cn@gmail.com> to support LPC ARM
+ * 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/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#include <lpc22xx.h>
+
+void bsp_interrupt_dispatch(void)
+{
+ rtems_vector_number vector = 31 - __builtin_clz(VICIRQStatus);
+
+ bsp_interrupt_handler_dispatch(vector);
+
+ VICVectAddr = 0;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ VICIntEnable |= 1 << vector;
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ VICIntEnClr = 1 << vector;
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ volatile uint32_t *ctrl = (volatile uint32_t *) VICVectCntlBase;
+ size_t i = 0;
+
+ /* Disable all interrupts */
+ VICIntEnClr = 0xffffffff;
+
+ /* Use IRQ category */
+ VICIntSelect = 0;
+
+ /* Enable access in USER mode */
+ VICProtection = 0;
+
+ for (i = 0; i < 16; ++i) {
+ /* Disable vector mode */
+ ctrl [i] = 0;
+
+ /* Acknowledge interrupts for all priorities */
+ VICVectAddr = 0;
+ }
+
+ /* Acknowledge interrupts for all priorities */
+ VICVectAddr = 0;
+
+ /* Install the IRQ exception handler */
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/shared/irq/irq-armv7m.c b/bsps/arm/shared/irq/irq-armv7m.c
new file mode 100644
index 0000000000..99c0e373bf
--- /dev/null
+++ b/bsps/arm/shared/irq/irq-armv7m.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011-2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <string.h>
+
+#include <rtems/score/armv7m.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/armv7m-irq.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ _ARMV7M_NVIC_Set_enable((int) vector);
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ _ARMV7M_NVIC_Clear_enable((int) vector);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ int i;
+ ARMV7M_Exception_handler *vector_table =
+ (ARMV7M_Exception_handler *) bsp_vector_table_begin;
+
+ if (bsp_vector_table_begin != bsp_start_vector_table_begin) {
+ memcpy(
+ vector_table,
+ bsp_start_vector_table_begin,
+ (size_t) bsp_vector_table_size
+ );
+ }
+
+ _ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVCLR | ARMV7M_SCB_ICSR_PENDSTCLR;
+
+ for (i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; ++i) {
+ vector_table [ARMV7M_VECTOR_IRQ(i)] = _ARMV7M_NVIC_Interrupt_dispatch;
+ _ARMV7M_NVIC_Clear_enable(i);
+ _ARMV7M_NVIC_Clear_pending(i);
+ _ARMV7M_NVIC_Set_priority(i, BSP_ARMV7M_IRQ_PRIORITY_DEFAULT);
+ }
+
+ _ARMV7M_SCB->vtor = vector_table;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/bsps/arm/shared/irq/irq-dispatch-armv7m.c b/bsps/arm/shared/irq/irq-dispatch-armv7m.c
new file mode 100644
index 0000000000..c810a9784a
--- /dev/null
+++ b/bsps/arm/shared/irq/irq-dispatch-armv7m.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011-2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <rtems/score/armv7m.h>
+
+#include <bsp/irq-generic.h>
+#include <bsp/armv7m-irq.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+void _ARMV7M_NVIC_Interrupt_dispatch(void)
+{
+ rtems_vector_number vector =
+ ARMV7M_SCB_ICSR_VECTACTIVE_GET(_ARMV7M_SCB->icsr);
+
+ _ARMV7M_Interrupt_service_enter();
+ bsp_interrupt_handler_dispatch(ARMV7M_IRQ_OF_VECTOR(vector));
+ _ARMV7M_Interrupt_service_leave();
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/bsps/arm/shared/irq/irq-gic.c b/bsps/arm/shared/irq/irq-gic.c
new file mode 100644
index 0000000000..ea4b6ef06a
--- /dev/null
+++ b/bsps/arm/shared/irq/irq-gic.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@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/arm-gic.h>
+
+#include <rtems/score/armv4.h>
+
+#include <libcpu/arm-cp15.h>
+
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/start.h>
+
+#define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE)
+
+#define PRIORITY_DEFAULT 127
+
+void bsp_interrupt_dispatch(void)
+{
+ volatile gic_cpuif *cpuif = GIC_CPUIF;
+ uint32_t icciar = cpuif->icciar;
+ rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
+ rtems_vector_number spurious = 1023;
+
+ if (vector != spurious) {
+ uint32_t psr = _ARMV4_Status_irq_enable();
+
+ bsp_interrupt_handler_dispatch(vector);
+
+ _ARMV4_Status_restore(psr);
+
+ cpuif->icceoir = icciar;
+ }
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ volatile gic_dist *dist = ARM_GIC_DIST;
+
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ gic_id_enable(dist, vector);
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ volatile gic_dist *dist = ARM_GIC_DIST;
+
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ gic_id_disable(dist, vector);
+}
+
+static inline uint32_t get_id_count(volatile gic_dist *dist)
+{
+ uint32_t id_count = GIC_DIST_ICDICTR_IT_LINES_NUMBER_GET(dist->icdictr);
+
+ id_count = 32 * (id_count + 1);
+ id_count = id_count <= 1020 ? id_count : 1020;
+
+ return id_count;
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ volatile gic_cpuif *cpuif = GIC_CPUIF;
+ volatile gic_dist *dist = ARM_GIC_DIST;
+ uint32_t id_count = get_id_count(dist);
+ uint32_t id;
+
+ arm_cp15_set_exception_handler(
+ ARM_EXCEPTION_IRQ,
+ _ARMV4_Exception_interrupt
+ );
+
+ for (id = 0; id < id_count; id += 32) {
+ dist->icdicer[id / 32] = 0xffffffff;
+ }
+
+ for (id = 0; id < id_count; ++id) {
+ gic_id_set_priority(dist, id, PRIORITY_DEFAULT);
+ }
+
+ for (id = 32; id < id_count; ++id) {
+ gic_id_set_targets(dist, id, 0x01);
+ }
+
+ cpuif->iccpmr = GIC_CPUIF_ICCPMR_PRIORITY(0xff);
+ cpuif->iccbpr = GIC_CPUIF_ICCBPR_BINARY_POINT(0x0);
+ cpuif->iccicr = GIC_CPUIF_ICCICR_ENABLE;
+
+ dist->icddcr = GIC_DIST_ICDDCR_ENABLE;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#ifdef RTEMS_SMP
+BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void)
+{
+ volatile gic_cpuif *cpuif = GIC_CPUIF;
+ volatile gic_dist *dist = ARM_GIC_DIST;
+
+ while ((dist->icddcr & GIC_DIST_ICDDCR_ENABLE) == 0) {
+ /* Wait */
+ }
+
+ cpuif->iccpmr = GIC_CPUIF_ICCPMR_PRIORITY(0xff);
+ cpuif->iccbpr = GIC_CPUIF_ICCBPR_BINARY_POINT(0x0);
+ cpuif->iccicr = GIC_CPUIF_ICCICR_ENABLE;
+}
+#endif
+
+rtems_status_code arm_gic_irq_set_priority(
+ rtems_vector_number vector,
+ uint8_t priority
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ volatile gic_dist *dist = ARM_GIC_DIST;
+
+ gic_id_set_priority(dist, vector, priority);
+ } else {
+ sc = RTEMS_INVALID_ID;
+ }
+
+ return sc;
+}
+
+rtems_status_code arm_gic_irq_get_priority(
+ rtems_vector_number vector,
+ uint8_t *priority
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ volatile gic_dist *dist = ARM_GIC_DIST;
+
+ *priority = gic_id_get_priority(dist, vector);
+ } else {
+ sc = RTEMS_INVALID_ID;
+ }
+
+ return sc;
+}
+
+void bsp_interrupt_set_affinity(
+ rtems_vector_number vector,
+ const Processor_mask *affinity
+)
+{
+ volatile gic_dist *dist = ARM_GIC_DIST;
+ uint8_t targets = (uint8_t) _Processor_mask_To_uint32_t(affinity, 0);
+
+ gic_id_set_targets(dist, vector, targets);
+}
+
+void bsp_interrupt_get_affinity(
+ rtems_vector_number vector,
+ Processor_mask *affinity
+)
+{
+ volatile gic_dist *dist = ARM_GIC_DIST;
+ uint8_t targets = gic_id_get_targets(dist, vector);
+
+ _Processor_mask_From_uint32_t(affinity, targets, 0);
+}
diff --git a/bsps/arm/smdk2410/irq/irq.c b/bsps/arm/smdk2410/irq/irq.c
new file mode 100644
index 0000000000..ea8f610353
--- /dev/null
+++ b/bsps/arm/smdk2410/irq/irq.c
@@ -0,0 +1,45 @@
+/* irq.c
+ *
+ * This file contains the implementation of the function described in irq.h
+ *
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * CopyRight (C) 2000 Canon Research France SA.
+ * Emmanuel Raguet, mailto:raguet@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 <rtems/score/armv4.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#include <s3c24xx.h>
+
+void bsp_interrupt_dispatch(void)
+{
+ rtems_vector_number vector = *((uint32_t *) rINTOFFSET_ADDR);
+
+ bsp_interrupt_handler_dispatch(vector);
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+}
+
+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)
+{
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/arm/tms570/irq/irq.c b/bsps/arm/tms570/irq/irq.c
new file mode 100644
index 0000000000..579c11ed2a
--- /dev/null
+++ b/bsps/arm/tms570/irq/irq.c
@@ -0,0 +1,202 @@
+/**
+ * @file irq.c
+ *
+ * @ingroup tms570
+ *
+ * @brief TMS570 interrupt support functions definitions.
+ */
+
+/*
+ * Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
+ *
+ * Google Summer of Code 2014 at
+ * Czech Technical University in Prague
+ * Zikova 1903/4
+ * 166 36 Praha 6
+ * Czech Republic
+ *
+ * Based on LPC24xx and LPC1768 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 <bsp.h>
+#include <bsp/irq-generic.h>
+#include <bsp/tms570-vim.h>
+#include <bsp/irq.h>
+#include <rtems/score/armv4.h>
+
+unsigned int priorityTable[BSP_INTERRUPT_VECTOR_MAX+1];
+
+/**
+ * @brief Set priority of the interrupt vector.
+ *
+ * This function is here because of compability. It should set
+ * priority of the interrupt vector.
+ * @warning It does not set any priority at HW layer. It is nearly imposible to
+ * @warning set priority of the interrupt on TMS570 in a nice way.
+ * @param[in] vector vector of isr
+ * @param[in] priority new priority assigned to the vector
+ * @return Void
+ */
+void tms570_irq_set_priority(
+ rtems_vector_number vector,
+ unsigned priority
+)
+{
+ if ( bsp_interrupt_is_valid_vector(vector) ) {
+ priorityTable[vector] = priority;
+ }
+}
+
+/**
+ * @brief Gets priority of the interrupt vector.
+ *
+ * This function is here because of compability. It returns priority
+ * of the isr vector last set by tms570_irq_set_priority function.
+ *
+ * @warning It does not return any real priority of the HW layer.
+ * @param[in] vector vector of isr
+ * @retval 0 vector is invalid.
+ * @retval priority priority of the interrupt
+ */
+unsigned tms570_irq_get_priority(
+ rtems_vector_number vector
+)
+{
+ if ( bsp_interrupt_is_valid_vector(vector) ) {
+ return priorityTable[vector];
+ }
+ return 0;
+}
+
+/**
+ * @brief Interrupt dispatch
+ *
+ * Called by OS to determine which interrupt occured.
+ * Function passes control to interrupt handler.
+ *
+ * @return Void
+ */
+void bsp_interrupt_dispatch(void)
+{
+ rtems_vector_number vector = TMS570_VIM.IRQINDEX-1;
+
+ bsp_interrupt_handler_dispatch(vector);
+}
+
+/**
+ * @brief enables interrupt vector in the HW
+ *
+ * Enables HW interrupt for specified vector
+ *
+ * @param[in] vector vector of the isr which needs to be enabled.
+ * @retval RTEMS_INVALID_ID vector is invalid.
+ * @retval RTEMS_SUCCESSFUL interrupt source enabled.
+ */
+void bsp_interrupt_vector_enable(
+ rtems_vector_number vector
+)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ TMS570_VIM.REQENASET[vector >> 5] = 1 << (vector & 0x1f);
+}
+
+/**
+ * @brief disables interrupt vector in the HW
+ *
+ * Disables HW interrupt for specified vector
+ *
+ * @param[in] vector vector of the isr which needs to be disabled.
+ * @retval RTEMS_INVALID_ID vector is invalid.
+ * @retval RTEMS_SUCCESSFUL interrupt source disabled.
+ */
+void bsp_interrupt_vector_disable(
+ rtems_vector_number vector
+)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ TMS570_VIM.REQENACLR[vector >> 5] = 1 << (vector & 0x1f);
+}
+
+/**
+ * @brief Init function of interrupt module
+ *
+ * Resets vectored interrupt interface to default state.
+ * Disables all interrupts.
+ * Set all sources as IRQ (not FIR).
+ *
+ * @retval RTEMS_SUCCESSFUL All is set
+ */
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ void (**vim_vec)(void) = (void (**)(void)) 0xFFF82000;
+ unsigned int value = 0x00010203;
+ unsigned int i = 0;
+ uint32_t sctlr;
+
+ /* Disable interrupts */
+ for ( i = 0; i < 3; i++ ) {
+ TMS570_VIM.REQENACLR[i] = 0xffffffff;
+ }
+ /* Map default events on interrupt vectors */
+ for ( i = 0; i < 24; i += 1, value += 0x04040404) {
+ TMS570_VIM.CHANCTRL[i] = value;
+ }
+ /* Set all vectors as IRQ (not FIR) */
+ TMS570_VIM.FIRQPR[0] = 3;
+ TMS570_VIM.FIRQPR[1] = 0;
+ TMS570_VIM.FIRQPR[2] = 0;
+
+ /*
+ _CPU_ISR_install_vector(
+ ARM_EXCEPTION_IRQ,
+ _ARMV4_Exception_interrupt,
+ NULL
+ );
+
+ Call to setup of interrupt entry in CPU level exception vectors table
+ is not used (necessary/possible) because the table is provided
+ by c/src/lib/libbsp/arm/shared/start/start.S and POM overlay
+ solution remaps that to address zero.
+ */
+
+ for ( i = 0; i <= 94; ++i ) {
+ vim_vec[i] = _ARMV4_Exception_interrupt;
+ }
+ /* Clear bit VE in SCTLR register to not use VIM IRQ exception bypass*/
+ asm volatile ("mrc p15, 0, %0, c1, c0, 0\n": "=r" (sctlr));
+ /*
+ * Disable bypass of CPU level exception table for interrupt entry which
+ * can be provided by VIM hardware
+ */
+ sctlr &= ~(1 << 24);
+ #if 0
+ /*
+ * Option to enable exception table bypass for interrupts
+ *
+ * Because RTEMS requires all interrupts to be serviced through
+ * common _ARMV4_Exception_interrupt handler to allow task switching
+ * on exit from interrupt working correctly, vim_vec cannot point
+ * directly to individual vector handlers and need to point
+ * to single entry path. But if TMS570_VIM.IRQINDEX is then used
+ * to target execution to corresponding service then for some
+ * peripherals (i.e. EMAC) interrupt is already acknowledged
+ * by VIM and IRQINDEX is read as zero which leads to spurious
+ * interrupt and peripheral not serviced/blocked.
+ *
+ * To analyze this behavior we used trampolines which setup
+ * bsp_interrupt_vector_inject and pass execution to
+ * _ARMV4_Exception_interrupt. It works but is more ugly than
+ * use of POM remap for these cases where application does not
+ * start at address 0x00000000. If RTEMS image is placed at
+ * memory space beginning then no of these constructs is necessary.
+ */
+ sctlr |= 1 << 24;
+ #endif
+ asm volatile ("mcr p15, 0, %0, c1, c0, 0\n": : "r" (sctlr));
+
+ return RTEMS_SUCCESSFUL;
+}