summaryrefslogtreecommitdiffstats
path: root/bsps/sparc/shared/irq/irq-shared.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/sparc/shared/irq/irq-shared.c')
-rw-r--r--bsps/sparc/shared/irq/irq-shared.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/bsps/sparc/shared/irq/irq-shared.c b/bsps/sparc/shared/irq/irq-shared.c
new file mode 100644
index 0000000000..344ed71a34
--- /dev/null
+++ b/bsps/sparc/shared/irq/irq-shared.c
@@ -0,0 +1,103 @@
+/*
+* COPYRIGHT (c) 2012-2015
+* Cobham Gaisler
+*
+* The license and distribution terms for this file may be
+* found in the file LICENSE in this distribution or at
+* http://www.rtems.org/license/LICENSE.
+*
+*/
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+
+#if defined(RTEMS_SMP) && defined(LEON3)
+/* Interrupt to CPU map. Default to CPU0 since in BSS. */
+const unsigned char LEON3_irq_to_cpu[32] __attribute__((weak));
+
+/* On SMP use map table above relative to SMP Boot CPU (normally CPU0) */
+static inline int bsp_irq_cpu(int irq)
+{
+ /* protect from bad user configuration, default to boot cpu */
+ if (rtems_configuration_get_maximum_processors() <= LEON3_irq_to_cpu[irq])
+ return LEON3_Cpu_Index;
+ else
+ return LEON3_Cpu_Index + LEON3_irq_to_cpu[irq];
+}
+#else
+/* when not SMP the local CPU is returned */
+static inline int bsp_irq_cpu(int irq)
+{
+#ifdef LEON3
+ return _LEON3_Get_current_processor();
+#else
+ return 0;
+#endif
+}
+#endif
+
+/* Initialize interrupts */
+void BSP_shared_interrupt_init(void)
+{
+ rtems_vector_number vector;
+ rtems_isr_entry previous_isr;
+ int i;
+
+ for (i=0; i <= BSP_INTERRUPT_VECTOR_MAX_STD; i++) {
+#if defined(LEON3) && \
+ (defined(RTEMS_SMP) || defined(RTEMS_MULTIPROCESSING))
+ /* Don't install IRQ handler on IPI interrupt. An SMP kernel with max one
+ * CPU does not use IPIs
+ */
+#ifdef RTEMS_SMP
+ if (rtems_configuration_get_maximum_processors() > 1)
+#endif
+ if (i == LEON3_mp_irq)
+ continue;
+#endif
+ vector = SPARC_ASYNCHRONOUS_TRAP(i) + 0x10;
+ rtems_interrupt_catch(bsp_isr_handler, vector, &previous_isr);
+ }
+
+ /* Initalize interrupt support */
+ bsp_interrupt_initialize();
+}
+
+/* Callback from bsp_interrupt_initialize() */
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ int irq = (int)vector;
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ BSP_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq));
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ int irq = (int)vector;
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+ BSP_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq));
+}
+
+void BSP_shared_interrupt_mask(int irq)
+{
+ BSP_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq));
+}
+
+void BSP_shared_interrupt_unmask(int irq)
+{
+ BSP_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(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);
+}