forked from Imagelibrary/rtems
bsp/leon3: Add and use LEON3_IrqCtrl_Lock
Disabling of interrupts is not enough to ensure mutual exclusion on SMP configurations.
This commit is contained in:
@@ -23,6 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
struct ambapp_bus ambapp_plb;
|
struct ambapp_bus ambapp_plb;
|
||||||
|
|
||||||
|
rtems_interrupt_lock LEON3_IrqCtrl_Lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
|
||||||
|
|
||||||
/* Pointers to Interrupt Controller configuration registers */
|
/* Pointers to Interrupt Controller configuration registers */
|
||||||
volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
|
volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#ifndef _INCLUDE_LEON_h
|
#ifndef _INCLUDE_LEON_h
|
||||||
#define _INCLUDE_LEON_h
|
#define _INCLUDE_LEON_h
|
||||||
|
|
||||||
#include <rtems/score/sparc.h>
|
#include <rtems.h>
|
||||||
#include <amba.h>
|
#include <amba.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -167,6 +167,14 @@ static __inline__ int bsp_irq_fixup(int irq)
|
|||||||
* store the result back are vulnerable.
|
* 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 ) \
|
#define LEON_Clear_interrupt( _source ) \
|
||||||
do { \
|
do { \
|
||||||
LEON3_IrqCtrl_Regs->iclear = (1 << (_source)); \
|
LEON3_IrqCtrl_Regs->iclear = (1 << (_source)); \
|
||||||
@@ -187,39 +195,39 @@ static __inline__ int bsp_irq_fixup(int irq)
|
|||||||
|
|
||||||
#define LEON_Mask_interrupt( _source ) \
|
#define LEON_Mask_interrupt( _source ) \
|
||||||
do { \
|
do { \
|
||||||
uint32_t _level; \
|
rtems_interrupt_level _level; \
|
||||||
_level = sparc_disable_interrupts(); \
|
LEON3_IRQCTRL_ACQUIRE( _level ); \
|
||||||
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] &= ~(1 << (_source)); \
|
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] &= ~(1 << (_source)); \
|
||||||
sparc_enable_interrupts( _level ); \
|
LEON3_IRQCTRL_RELEASE( _level ); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LEON_Unmask_interrupt( _source ) \
|
#define LEON_Unmask_interrupt( _source ) \
|
||||||
do { \
|
do { \
|
||||||
uint32_t _level; \
|
rtems_interrupt_level _level; \
|
||||||
_level = sparc_disable_interrupts(); \
|
LEON3_IRQCTRL_ACQUIRE( _level ); \
|
||||||
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] |= (1 << (_source)); \
|
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] |= (1 << (_source)); \
|
||||||
sparc_enable_interrupts( _level ); \
|
LEON3_IRQCTRL_RELEASE( _level ); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LEON_Disable_interrupt( _source, _previous ) \
|
#define LEON_Disable_interrupt( _source, _previous ) \
|
||||||
do { \
|
do { \
|
||||||
uint32_t _level; \
|
rtems_interrupt_level _level; \
|
||||||
uint32_t _mask = 1 << (_source); \
|
uint32_t _mask = 1 << (_source); \
|
||||||
_level = sparc_disable_interrupts(); \
|
LEON3_IRQCTRL_ACQUIRE( _level ); \
|
||||||
(_previous) = LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]; \
|
(_previous) = LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]; \
|
||||||
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = _previous & ~_mask; \
|
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = _previous & ~_mask; \
|
||||||
sparc_enable_interrupts( _level ); \
|
LEON3_IRQCTRL_RELEASE( _level ); \
|
||||||
(_previous) &= _mask; \
|
(_previous) &= _mask; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LEON_Restore_interrupt( _source, _previous ) \
|
#define LEON_Restore_interrupt( _source, _previous ) \
|
||||||
do { \
|
do { \
|
||||||
uint32_t _level; \
|
rtems_interrupt_level _level; \
|
||||||
uint32_t _mask = 1 << (_source); \
|
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] = \
|
||||||
(LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & ~_mask) | (_previous); \
|
(LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & ~_mask) | (_previous); \
|
||||||
sparc_enable_interrupts( _level ); \
|
LEON3_IRQCTRL_RELEASE( _level ); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Make all SPARC BSPs have common macros for interrupt handling */
|
/* Make all SPARC BSPs have common macros for interrupt handling */
|
||||||
|
|||||||
Reference in New Issue
Block a user