[rtems commit] arm/raspberrypi: change interrupt dispatch and enable to generic vector id based approach.

Pavel Pisa ppisa at rtems.org
Sun Oct 2 08:47:07 UTC 2016


Module:    rtems
Branch:    4.11
Commit:    78627fe2825d19f810c60d4b2a42aea717712d7f
Changeset: http://git.rtems.org/rtems/commit/?id=78627fe2825d19f810c60d4b2a42aea717712d7f

Author:    Pavel Pisa <pisa at cmp.felk.cvut.cz>
Date:      Sat Jul 23 12:10:34 2016 +0200

arm/raspberrypi: change interrupt dispatch and enable to generic vector id based approach.

Using conditional branches to find bits is extremely inefficient
and for asynchronous delivery of different interrupt sources
lead to total confusion of branch prediction unit.

Updates #2783

---

 c/src/lib/libbsp/arm/raspberrypi/include/irq.h |   4 +
 c/src/lib/libbsp/arm/raspberrypi/irq/irq.c     | 133 +++++++++++++++++--------
 2 files changed, 94 insertions(+), 43 deletions(-)

diff --git a/c/src/lib/libbsp/arm/raspberrypi/include/irq.h b/c/src/lib/libbsp/arm/raspberrypi/include/irq.h
index 7ccfd3b..22ee29b 100644
--- a/c/src/lib/libbsp/arm/raspberrypi/include/irq.h
+++ b/c/src/lib/libbsp/arm/raspberrypi/include/irq.h
@@ -51,11 +51,15 @@
 #define BCM2835_IRQ_ID_UART          57
 
 
+#define BCM2835_IRQ_ID_BASIC_BASE_ID 64
 #define BCM2835_IRQ_ID_TIMER_0       64
 #define BCM2835_IRQ_ID_MAILBOX_0     65
 #define BCM2835_IRQ_ID_DOORBELL_0    66
 #define BCM2835_IRQ_ID_DOORBELL_1    67
 #define BCM2835_IRQ_ID_GPU0_HALTED   68
+#define BCM2835_IRQ_ID_GPU1_HALTED   69
+#define BCM2835_IRQ_ID_ILL_ACCESS_1  70
+#define BCM2835_IRQ_ID_ILL_ACCESS_0  71
 
 #define BSP_INTERRUPT_VECTOR_MIN    (0)
 #define BSP_INTERRUPT_VECTOR_MAX    (BCM2835_INTC_TOTAL_IRQ - 1)
diff --git a/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c b/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c
index ce5b363..e654d07 100644
--- a/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c
+++ b/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c
@@ -1,5 +1,5 @@
 /**
- * @file
+ * @file irq.c
  *
  * @ingroup raspberrypi_interrupt
  *
@@ -7,6 +7,8 @@
  */
 
 /*
+ * Copyright (c) 2014 Andre Marques <andre.lousa.marques at gmail.com>
+ *
  * Copyright (c) 2009
  * embedded brains GmbH
  * Obere Lagerstr. 30
@@ -27,78 +29,123 @@
 #include <bsp/raspberrypi.h>
 #include <bsp/linker-symbols.h>
 #include <bsp/mmu.h>
+#include <rtems/bspIo.h>
+#include <strings.h>
+
+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 */
+};
 
 /*
-** Determine the source of the interrupt and dispatch the correct handler.
-*/
+ * 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)
 {
-  rtems_vector_number vector = 255;
+  unsigned int pend;
+  unsigned int pend_bit;
 
-  /* ARM timer */
-  if (BCM2835_REG(BCM2835_IRQ_BASIC) && 0x1)
-  {
-      vector = BCM2835_IRQ_ID_TIMER_0;
+  rtems_vector_number vector = 255;
 
-  }
-  /* UART 0 */
-  else if ( BCM2835_REG(BCM2835_IRQ_BASIC) && BCM2835_BIT(19))
-  {
-      vector = BCM2835_IRQ_ID_UART;
+  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);
   }
-
 }
 
 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
 {
-  rtems_interrupt_level  level;
-
-  rtems_interrupt_disable(level);
+  if ( vector > BSP_INTERRUPT_VECTOR_MAX )
+    return RTEMS_INVALID_ID;
 
-   /* ARM Timer */
-  if ( vector == BCM2835_IRQ_ID_TIMER_0 )
-  {
-      BCM2835_REG(BCM2835_IRQ_ENABLE_BASIC) = 0x1;
-  }
-  /* UART 0 */
-  else if ( vector == BCM2835_IRQ_ID_UART )
-  {
-      BCM2835_REG(BCM2835_IRQ_ENABLE2) =  BCM2835_BIT(25);
-
-  }
-  rtems_interrupt_enable(level);
+  BCM2835_REG(bsp_vector_to_reg(vector)->enable_reg_addr) =
+              bsp_vector_to_mask(vector);
 
   return RTEMS_SUCCESSFUL;
 }
 
 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
 {
-  rtems_interrupt_level level;
+  if ( vector > BSP_INTERRUPT_VECTOR_MAX )
+    return RTEMS_INVALID_ID;
 
-  rtems_interrupt_disable(level);
-
-  if ( vector == BCM2835_IRQ_ID_TIMER_0 )
-  {
-      BCM2835_REG(BCM2835_IRQ_DISABLE_BASIC) = 0x1;
-  }
-  else if ( vector == BCM2835_IRQ_ID_UART )
-  {
-      BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(25);
-  }
-  rtems_interrupt_enable(level);
+  BCM2835_REG(bsp_vector_to_reg(vector)->disable_reg_addr) =
+              bsp_vector_to_mask(vector);
 
   return RTEMS_SUCCESSFUL;
 }
 
-
 void bsp_interrupt_handler_default(rtems_vector_number vector)
 {
-    printk("spurious interrupt: %u\n", vector);
+    printk("spurious interrupt: %lu\n", vector);
 }
 
 rtems_status_code bsp_interrupt_facility_initialize(void)




More information about the vc mailing list