From 2cb0877f3a90693b60a8e2b1576c29a0ce91b112 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 18 Feb 2014 12:42:58 +0100 Subject: bsp/leon3: Add and use LEON3_IrqCtrl_Lock 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 8873ae9ee0..5cb1880ac5 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 4ebb043455..ebd0f907e2 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 +#include #include #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 */ -- cgit v1.2.3