[PATCH 4/4] bsp/leon3: Add and use LEON3_IrqCtrl_Lock

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Feb 18 11:53:12 UTC 2014


Disabling of interrupts is not enough to ensure mutual exclusion on SMP
configurations.
---
 c/src/lib/libbsp/sparc/leon3/amba/amba.c    |    2 +
 c/src/lib/libbsp/sparc/leon3/include/leon.h |   34 ++++++++++++++++----------
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/c/src/lib/libbsp/sparc/leon3/amba/amba.c b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
index 8873ae9..5cb1880 100644
--- a/c/src/lib/libbsp/sparc/leon3/amba/amba.c
+++ b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
@@ -23,6 +23,8 @@
  */
 struct ambapp_bus ambapp_plb;
 
+rtems_interrupt_lock LEON3_IrqCtrl_Lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
+
 /* Pointers to Interrupt Controller configuration registers */
 volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
 
diff --git a/c/src/lib/libbsp/sparc/leon3/include/leon.h b/c/src/lib/libbsp/sparc/leon3/include/leon.h
index 4ebb043..ebd0f90 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/leon.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/leon.h
@@ -23,7 +23,7 @@
 #ifndef _INCLUDE_LEON_h
 #define _INCLUDE_LEON_h
 
-#include <rtems/score/sparc.h>
+#include <rtems.h>
 #include <amba.h>
 
 #ifdef __cplusplus
@@ -167,6 +167,14 @@ static __inline__ int bsp_irq_fixup(int irq)
  *        store the result back are vulnerable.
  */
 
+extern rtems_interrupt_lock LEON3_IrqCtrl_Lock;
+
+#define LEON3_IRQCTRL_ACQUIRE(_level ) \
+  rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _level )
+
+#define LEON3_IRQCTRL_RELEASE(_level ) \
+  rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _level )
+
 #define LEON_Clear_interrupt( _source ) \
   do { \
     LEON3_IrqCtrl_Regs->iclear = (1 << (_source)); \
@@ -187,39 +195,39 @@ static __inline__ int bsp_irq_fixup(int irq)
 
 #define LEON_Mask_interrupt( _source ) \
   do { \
-    uint32_t _level; \
-    _level = sparc_disable_interrupts(); \
+    rtems_interrupt_level _level; \
+    LEON3_IRQCTRL_ACQUIRE( _level ); \
      LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]  &= ~(1 << (_source)); \
-    sparc_enable_interrupts( _level ); \
+    LEON3_IRQCTRL_RELEASE( _level ); \
   } while (0)
 
 #define LEON_Unmask_interrupt( _source ) \
   do { \
-    uint32_t _level; \
-    _level = sparc_disable_interrupts(); \
+    rtems_interrupt_level _level; \
+    LEON3_IRQCTRL_ACQUIRE( _level ); \
     LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]  |= (1 << (_source)); \
-    sparc_enable_interrupts( _level ); \
+    LEON3_IRQCTRL_RELEASE( _level ); \
   } while (0)
 
 #define LEON_Disable_interrupt( _source, _previous ) \
   do { \
-    uint32_t _level; \
+    rtems_interrupt_level _level; \
     uint32_t _mask = 1 << (_source); \
-    _level = sparc_disable_interrupts(); \
+    LEON3_IRQCTRL_ACQUIRE( _level ); \
      (_previous) = LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]; \
      LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = _previous & ~_mask; \
-    sparc_enable_interrupts( _level ); \
+    LEON3_IRQCTRL_RELEASE( _level ); \
     (_previous) &= _mask; \
   } while (0)
 
 #define LEON_Restore_interrupt( _source, _previous ) \
   do { \
-    uint32_t _level; \
+    rtems_interrupt_level _level; \
     uint32_t _mask = 1 << (_source); \
-    _level = sparc_disable_interrupts(); \
+    LEON3_IRQCTRL_ACQUIRE( _level ); \
       LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = \
         (LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & ~_mask) | (_previous); \
-    sparc_enable_interrupts( _level ); \
+    LEON3_IRQCTRL_RELEASE( _level ); \
   } while (0)
 
 /* Make all SPARC BSPs have common macros for interrupt handling */
-- 
1.7.7




More information about the devel mailing list