[PATCH v3 16/38] bsp/leon3: Use new IRQ(A)MP register block API

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Jul 12 13:49:55 UTC 2023


---
 bsps/sparc/leon3/clock/ckinit.c        |  11 ++-
 bsps/sparc/leon3/include/bsp/irq.h     |   1 +
 bsps/sparc/leon3/include/bsp/irqimpl.h |  35 ++++++-
 bsps/sparc/leon3/include/leon.h        |  63 ++++++-------
 bsps/sparc/leon3/start/amba.c          |  11 ++-
 bsps/sparc/leon3/start/bspclean.c      |   9 +-
 bsps/sparc/leon3/start/bspsmp.c        |  16 +++-
 bsps/sparc/leon3/start/cpucounter.c    |  11 ++-
 bsps/sparc/leon3/start/eirq.c          | 124 ++++++++++++++++++-------
 9 files changed, 187 insertions(+), 94 deletions(-)

diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c
index 2ec701fe2a..b3761bed35 100644
--- a/bsps/sparc/leon3/clock/ckinit.c
+++ b/bsps/sparc/leon3/clock/ckinit.c
@@ -45,6 +45,7 @@
 #include <leon.h>
 #include <rtems/rtems/intr.h>
 #include <grlib/ambapp.h>
+#include <grlib/irqamp.h>
 #include <rtems/score/profiling.h>
 #include <rtems/score/sparcimpl.h>
 #include <rtems/timecounter.h>
@@ -179,11 +180,11 @@ static void bsp_clock_handler_install(rtems_interrupt_handler isr)
 
 static void leon3_clock_initialize(void)
 {
-  volatile struct irqmp_timestamp_regs *irqmp_ts;
+  irqamp_timestamp *irqmp_ts;
   volatile struct gptimer_regs *gpt;
   struct timecounter *tc;
 
-  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
+  irqmp_ts = irqamp_get_timestamp_registers(LEON3_IrqCtrl_Regs);
   gpt = LEON3_Timer_Regs;
   tc = &leon3_tc;
 
@@ -201,13 +202,13 @@ static void leon3_clock_initialize(void)
     tc->tc_frequency = leon3_up_counter_frequency();
 
 #ifdef RTEMS_PROFILING
-    if (!irqmp_has_timestamp(irqmp_ts)) {
+    if (irqmp_ts == NULL) {
       bsp_fatal(LEON3_FATAL_CLOCK_NO_IRQMP_TIMESTAMP_SUPPORT);
     }
 #endif
 
     leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
-  } else if (irqmp_has_timestamp(irqmp_ts)) {
+  } else if (irqmp_ts != NULL) {
     /* Use the interrupt controller timestamp counter if available */
     tc->tc_get_timecount = _SPARC_Get_timecount_up;
     tc->tc_frequency = ambapp_freq_get(ambapp_plb(), LEON3_Timer_Adev);
@@ -218,7 +219,7 @@ static void leon3_clock_initialize(void)
      * At least one TSISEL field must be non-zero to enable the timestamp
      * counter.  Use an arbitrary interrupt source.
      */
-    irqmp_ts->control = 0x1;
+    grlib_store_32(&irqmp_ts->itstmpc, IRQAMP_ITSTMPC_TSISEL(1));
   } else {
 #ifdef RTEMS_SMP
     /*
diff --git a/bsps/sparc/leon3/include/bsp/irq.h b/bsps/sparc/leon3/include/bsp/irq.h
index ef0f6245f9..38ea1de1f8 100644
--- a/bsps/sparc/leon3/include/bsp/irq.h
+++ b/bsps/sparc/leon3/include/bsp/irq.h
@@ -37,6 +37,7 @@
 #ifndef LIBBSP_LEON3_IRQ_CONFIG_H
 #define LIBBSP_LEON3_IRQ_CONFIG_H
 
+#include <rtems.h>
 #include <rtems/score/processormask.h>
 
 #define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
diff --git a/bsps/sparc/leon3/include/bsp/irqimpl.h b/bsps/sparc/leon3/include/bsp/irqimpl.h
index 60b198bd02..c957c7fbbc 100644
--- a/bsps/sparc/leon3/include/bsp/irqimpl.h
+++ b/bsps/sparc/leon3/include/bsp/irqimpl.h
@@ -38,7 +38,8 @@
 #define LIBBSP_SPARC_LEON3_BSP_IRQIMPL_H
 
 #include <rtems.h>
-#include <grlib/grlib.h>
+#include <grlib/irqamp-regs.h>
+#include <grlib/io.h>
 
 struct ambapp_dev;
 
@@ -52,15 +53,38 @@ extern "C" {
  * @{
  */
 
+/**
+ * @brief This object provides the index of the boot processor.
+ *
+ * This object should be read-only after initialization.
+ */
+extern uint32_t LEON3_Cpu_Index;
+
 /**
  * @brief This lock serializes the interrupt controller access.
  */
 extern rtems_interrupt_lock LEON3_IrqCtrl_Lock;
 
+/**
+ * @brief Acquires the interrupt controller lock.
+ *
+ * @param[out] _lock_context is the lock context.
+ */
+#define LEON3_IRQCTRL_ACQUIRE( _lock_context ) \
+  rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _lock_context )
+
+/**
+ * @brief Releases the interrupt controller lock.
+ *
+ * @param[in, out] _lock_context is the lock context.
+ */
+#define LEON3_IRQCTRL_RELEASE( _lock_context ) \
+  rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _lock_context )
+
 /**
  * @brief This pointer provides the IRQ(A)MP register block address.
  */
-extern volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
+extern irqamp *LEON3_IrqCtrl_Regs;
 
 /**
  * @brief This pointer provides the IRQ(A)MP device information block.
@@ -80,7 +104,7 @@ extern uint32_t LEON3_IrqCtrl_EIrq;
  *
  * @param[in, out] regs is the IRQ(A)MP register block address.
  */
-void leon3_ext_irq_init( volatile struct irqmp_regs *regs );
+void leon3_ext_irq_init( irqamp *regs );
 
 /**
  * @brief Acknowledges and maps extended interrupts if this feature is
@@ -91,12 +115,15 @@ void leon3_ext_irq_init( volatile struct irqmp_regs *regs );
 static inline uint32_t bsp_irq_fixup( uint32_t irq )
 {
   uint32_t eirq;
+  uint32_t cpu_self;
 
   if ( irq != LEON3_IrqCtrl_EIrq ) {
     return irq;
   }
 
-  eirq = LEON3_IrqCtrl_Regs->intid[ _LEON3_Get_current_processor() ] & 0x1f;
+  cpu_self = _LEON3_Get_current_processor();
+  eirq = grlib_load_32( &LEON3_IrqCtrl_Regs->pextack[ cpu_self ] );
+  eirq = IRQAMP_PEXTACK_EID_4_0_GET( eirq );
 
   if ( eirq < 16 ) {
     return irq;
diff --git a/bsps/sparc/leon3/include/leon.h b/bsps/sparc/leon3/include/leon.h
index 8a64285b3f..618d71af9b 100644
--- a/bsps/sparc/leon3/include/leon.h
+++ b/bsps/sparc/leon3/include/leon.h
@@ -44,6 +44,7 @@
 
 #include <rtems.h>
 #include <amba.h>
+#include <grlib/io.h>
 #include <bsp/irqimpl.h>
 
 #ifdef __cplusplus
@@ -151,9 +152,6 @@ extern "C" {
 extern volatile struct gptimer_regs *LEON3_Timer_Regs;
 extern struct ambapp_dev *LEON3_Timer_Adev;
 
-/* LEON3 CPU Index of boot CPU */
-extern uint32_t LEON3_Cpu_Index;
-
 /* Macros used for manipulating bits in LEON3 GP Timer Control Register */
 
 #define LEON3_IRQMPSTATUS_CPUNR     28
@@ -172,28 +170,21 @@ extern uint32_t LEON3_Cpu_Index;
  *        store the result back are vulnerable.
  */
 
-#define LEON3_IRQCTRL_ACQUIRE( _lock_context ) \
-  rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _lock_context )
-
-#define LEON3_IRQCTRL_RELEASE( _lock_context ) \
-  rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _lock_context )
-
 #define LEON_Clear_interrupt( _source ) \
-  do { \
-    LEON3_IrqCtrl_Regs->iclear = (1U << (_source)); \
-  } while (0)
+  grlib_store_32(&LEON3_IrqCtrl_Regs->iclear, 1U << (_source))
 
 #define LEON_Force_interrupt( _source ) \
-  do { \
-    LEON3_IrqCtrl_Regs->iforce = (1U << (_source)); \
-  } while (0)
+  grlib_store_32(&LEON3_IrqCtrl_Regs->iforce0, 1U << (_source))
 
 #define LEON_Enable_interrupt_broadcast( _source ) \
   do { \
     rtems_interrupt_lock_context _lock_context; \
     uint32_t _mask = 1U << ( _source ); \
+    uint32_t _brdcst; \
     LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
-    LEON3_IrqCtrl_Regs->bcast |= _mask; \
+    _brdcst = grlib_load_32(&LEON3_IrqCtrl_Regs->brdcst); \
+    _brdcst |= _mask; \
+    grlib_store_32(&LEON3_IrqCtrl_Regs->brdcst, _brdcst); \
     LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
@@ -201,30 +192,39 @@ extern uint32_t LEON3_Cpu_Index;
   do { \
     rtems_interrupt_lock_context _lock_context; \
     uint32_t _mask = 1U << ( _source ); \
+    uint32_t _brdcst; \
     LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
-    LEON3_IrqCtrl_Regs->bcast &= ~_mask; \
+    _brdcst = grlib_load_32(&LEON3_IrqCtrl_Regs->brdcst); \
+    _brdcst &= ~_mask; \
+    grlib_store_32(&LEON3_IrqCtrl_Regs->brdcst, _brdcst); \
     LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
 #define LEON_Is_interrupt_pending( _source ) \
-  (LEON3_IrqCtrl_Regs->ipend & (1U << (_source)))
+  (grlib_load_32(&LEON3_IrqCtrl_Regs->ipend) & (1U << (_source)))
 
 #define LEON_Cpu_Is_interrupt_masked( _source, _cpu ) \
-     (!(LEON3_IrqCtrl_Regs->mask[_cpu] & (1U << (_source))))
+     (!(grlib_load_32(&LEON3_IrqCtrl_Regs->pimask[_cpu]) & (1U << (_source))))
 
 #define LEON_Cpu_Mask_interrupt( _source, _cpu ) \
   do { \
     rtems_interrupt_lock_context _lock_context; \
+    uint32_t _pimask; \
     LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
-     LEON3_IrqCtrl_Regs->mask[_cpu]  &= ~(1U << (_source)); \
+    _pimask = grlib_load_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ]); \
+    _pimask &= ~(1U << (_source)); \
+    grlib_store_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ], _pimask); \
     LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
 #define LEON_Cpu_Unmask_interrupt( _source, _cpu ) \
   do { \
     rtems_interrupt_lock_context _lock_context; \
+    uint32_t _pimask; \
     LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
-    LEON3_IrqCtrl_Regs->mask[_cpu]  |= (1U << (_source)); \
+    _pimask = grlib_load_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ]); \
+    _pimask |= 1U << (_source); \
+    grlib_store_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ], _pimask); \
     LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
@@ -233,8 +233,8 @@ extern uint32_t LEON3_Cpu_Index;
     rtems_interrupt_lock_context _lock_context; \
     uint32_t _mask = 1U << (_source); \
     LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
-     (_previous) = LEON3_IrqCtrl_Regs->mask[_cpu]; \
-     LEON3_IrqCtrl_Regs->mask[_cpu] = _previous & ~_mask; \
+    (_previous) = grlib_load_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ]); \
+    grlib_store_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ], (_previous) & ~_mask); \
     LEON3_IRQCTRL_RELEASE( &_lock_context ); \
     (_previous) &= _mask; \
   } while (0)
@@ -242,10 +242,12 @@ extern uint32_t LEON3_Cpu_Index;
 #define LEON_Cpu_Restore_interrupt( _source, _previous, _cpu ) \
   do { \
     rtems_interrupt_lock_context _lock_context; \
-    uint32_t _mask = 1U << (_source); \
+    uint32_t _pimask; \
     LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
-      LEON3_IrqCtrl_Regs->mask[_cpu] = \
-        (LEON3_IrqCtrl_Regs->mask[_cpu] & ~_mask) | (_previous); \
+    _pimask = grlib_load_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ]); \
+    _pimask &= ~(1U << (_source)); \
+    _pimask |= _previous; \
+    grlib_store_32(&LEON3_IrqCtrl_Regs->pimask[_cpu ], _pimask); \
     LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
@@ -389,15 +391,6 @@ extern unsigned int leon3_timer_prescaler;
 
 RTEMS_NO_RETURN void leon3_power_down_loop(void);
 
-static inline uint32_t leon3_get_cpu_count(
-  volatile struct irqmp_regs *irqmp
-)
-{
-  uint32_t mpstat = irqmp->mpstat;
-
-  return ((mpstat >> LEON3_IRQMPSTATUS_CPUNR) & 0xf)  + 1;
-}
-
 static inline void leon3_set_system_register(uint32_t addr, uint32_t val)
 {
   __asm__ volatile(
diff --git a/bsps/sparc/leon3/start/amba.c b/bsps/sparc/leon3/start/amba.c
index 5ce3de6bdd..c1e26d316c 100644
--- a/bsps/sparc/leon3/start/amba.c
+++ b/bsps/sparc/leon3/start/amba.c
@@ -116,7 +116,7 @@ RTEMS_SYSINIT_ITEM(
 #endif
 
 /* Pointers to Interrupt Controller configuration registers */
-volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
+irqamp *LEON3_IrqCtrl_Regs;
 struct ambapp_dev *LEON3_IrqCtrl_Adev;
 volatile struct gptimer_regs *LEON3_Timer_Regs;
 struct ambapp_dev *LEON3_Timer_Adev;
@@ -133,7 +133,6 @@ struct ambapp_dev *LEON3_Timer_Adev;
 
 static void amba_initialize(void)
 {
-  int icsel;
   struct ambapp_dev *adev;
   struct ambapp_bus *plb;
 
@@ -151,15 +150,17 @@ static void amba_initialize(void)
     bsp_fatal(LEON3_FATAL_NO_IRQMP_CONTROLLER);
   }
 
-  LEON3_IrqCtrl_Regs = (volatile struct irqmp_regs *)DEV_TO_APB(adev)->start;
+  LEON3_IrqCtrl_Regs = (irqamp *)DEV_TO_APB(adev)->start;
   LEON3_IrqCtrl_Adev = adev;
-  if ((LEON3_IrqCtrl_Regs->ampctrl >> 28) > 0) {
+  if ((grlib_load_32(&LEON3_IrqCtrl_Regs->asmpctrl) >> 28) > 0) {
+    uint32_t icsel;
+
     /* IRQ Controller has support for multiple IRQ Controllers, each
      * CPU can be routed to different Controllers, we find out which
      * controller by looking at the IRQCTRL Select Register for this CPU.
      * Each Controller is located at a 4KByte offset.
      */
-    icsel = LEON3_IrqCtrl_Regs->icsel[LEON3_Cpu_Index/8];
+    icsel = grlib_load_32(&LEON3_IrqCtrl_Regs->icselr[LEON3_Cpu_Index/8]);
     icsel = (icsel >> ((7 - (LEON3_Cpu_Index & 0x7)) * 4)) & 0xf;
     LEON3_IrqCtrl_Regs += icsel;
   }
diff --git a/bsps/sparc/leon3/start/bspclean.c b/bsps/sparc/leon3/start/bspclean.c
index 8724c38862..7414a61b83 100644
--- a/bsps/sparc/leon3/start/bspclean.c
+++ b/bsps/sparc/leon3/start/bspclean.c
@@ -55,9 +55,9 @@ void bsp_fatal_extension(
       (code == SMP_FATAL_SHUTDOWN_RESPONSE)) {
     leon3_power_down_loop(); /* CPU didn't start shutdown sequence .. */
   } else {
-    volatile struct irqmp_regs *irqmp = LEON3_IrqCtrl_Regs;
+    irqamp *regs = LEON3_IrqCtrl_Regs;
 
-    if (irqmp != NULL) {
+    if (regs != NULL) {
       /*
        * Value was chosen to get something in the magnitude of 1ms on a 200MHz
        * processor.
@@ -76,7 +76,10 @@ void bsp_fatal_extension(
 
       /* Wait some time for secondary processors to halt */
       i = 0;
-      while ((irqmp->mpstat & halt_mask) != halt_mask && i < max_wait) {
+      while (
+        (grlib_load_32(&regs->mpstat) & halt_mask) != halt_mask &&
+        i < max_wait
+      ) {
         ++i;
       }
     }
diff --git a/bsps/sparc/leon3/start/bspsmp.c b/bsps/sparc/leon3/start/bspsmp.c
index acd932843a..a8ad60b497 100644
--- a/bsps/sparc/leon3/start/bspsmp.c
+++ b/bsps/sparc/leon3/start/bspsmp.c
@@ -17,6 +17,7 @@
 #include <bsp/bootcard.h>
 #include <bsp/fatal.h>
 #include <bsp/irq.h>
+#include <bsp/leon3.h>
 #include <leon.h>
 #include <rtems/bspIo.h>
 #include <rtems/sysinit.h>
@@ -75,6 +76,11 @@ static void leon3_install_inter_processor_interrupt( void )
   _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL );
 }
 
+static uint32_t leon3_get_cpu_count( const irqamp *regs )
+{
+  return IRQAMP_MPSTAT_NCPU_GET( grlib_load_32( &regs->mpstat ) ) + 1;
+}
+
 uint32_t _CPU_SMP_Initialize( void )
 {
   if ( !leon3_data_cache_snooping_enabled() )
@@ -89,7 +95,10 @@ bool _CPU_SMP_Start_processor( uint32_t cpu_index )
     printk( "Waking CPU %d\n", cpu_index );
   #endif
 
-  LEON3_IrqCtrl_Regs->mpstat = 1U << cpu_index;
+  grlib_store_32(
+    &LEON3_IrqCtrl_Regs->mpstat,
+    IRQAMP_MPSTAT_STATUS(1U << cpu_index)
+  );
 
   return true;
 }
@@ -111,7 +120,10 @@ void _CPU_SMP_Prepare_start_multitasking( void )
 void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
 {
   /* send interrupt to destination CPU */
-  LEON3_IrqCtrl_Regs->force[target_processor_index] = 1 << LEON3_mp_irq;
+  grlib_store_32(
+    &LEON3_IrqCtrl_Regs->piforce[target_processor_index],
+    1U << LEON3_mp_irq
+  );
 }
 
 #if defined(RTEMS_DRVMGR_STARTUP)
diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c
index b92840abb4..0a54ba9a74 100644
--- a/bsps/sparc/leon3/start/cpucounter.c
+++ b/bsps/sparc/leon3/start/cpucounter.c
@@ -26,6 +26,7 @@
  */
 
 #include <leon.h>
+#include <grlib/irqamp.h>
 
 #include <rtems/counter.h>
 #include <rtems/sysinit.h>
@@ -40,11 +41,11 @@ uint32_t _CPU_Counter_frequency(void)
 
 static void leon3_counter_initialize(void)
 {
-  volatile struct irqmp_timestamp_regs *irqmp_ts;
+  irqamp_timestamp *irqmp_ts;
   volatile struct gptimer_regs *gpt;
   SPARC_Counter *counter;
 
-  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
+  irqmp_ts = irqamp_get_timestamp_registers(LEON3_IrqCtrl_Regs);
   gpt = LEON3_Timer_Regs;
   counter = &_SPARC_Counter_mutable;
 
@@ -56,14 +57,14 @@ static void leon3_counter_initialize(void)
     counter->read = _SPARC_Counter_read_asr23;
 
     leon3_counter_frequency = leon3_up_counter_frequency();
-  } else if (irqmp_has_timestamp(irqmp_ts)) {
+  } else if (irqmp_ts != NULL) {
     /* Use the interrupt controller timestamp counter if available */
     counter->read_isr_disabled = _SPARC_Counter_read_up;
     counter->read = _SPARC_Counter_read_up;
-    counter->counter_register = &LEON3_IrqCtrl_Regs->timestamp[0].counter;
+    counter->counter_register = &irqmp_ts->itcnt;
 
     /* Enable interrupt timestamping for an arbitrary interrupt line */
-    irqmp_ts->control = 0x1;
+    grlib_store_32(&irqmp_ts->itstmpc, IRQAMP_ITSTMPC_TSISEL(1));
 
     leon3_counter_frequency = ambapp_freq_get(ambapp_plb(), LEON3_IrqCtrl_Adev);
   } else if (gpt != NULL) {
diff --git a/bsps/sparc/leon3/start/eirq.c b/bsps/sparc/leon3/start/eirq.c
index d9c5402dd0..5576c37c22 100644
--- a/bsps/sparc/leon3/start/eirq.c
+++ b/bsps/sparc/leon3/start/eirq.c
@@ -31,9 +31,9 @@
  *
  */
 
-#include <leon.h>
 #include <bsp/irq.h>
 #include <bsp/irq-generic.h>
+#include <bsp/irqimpl.h>
 
 /* GRLIB extended IRQ controller IRQ number */
 uint32_t LEON3_IrqCtrl_EIrq;
@@ -42,12 +42,12 @@ rtems_interrupt_lock LEON3_IrqCtrl_Lock =
   RTEMS_INTERRUPT_LOCK_INITIALIZER("LEON3 IrqCtrl");
 
 /* Initialize Extended Interrupt controller */
-void leon3_ext_irq_init(volatile struct irqmp_regs *regs)
+void leon3_ext_irq_init(irqamp *regs)
 {
-  regs->mask[LEON3_Cpu_Index] = 0;
-  regs->force[LEON3_Cpu_Index] = 0;
-  regs->iclear = 0xffffffff;
-  LEON3_IrqCtrl_EIrq = (regs->mpstat >> 16) & 0xf;
+  grlib_store_32(&regs->pimask[LEON3_Cpu_Index], 0);
+  grlib_store_32(&regs->piforce[LEON3_Cpu_Index], 0);
+  grlib_store_32(&regs->iclear, 0xffffffff);
+  LEON3_IrqCtrl_EIrq = IRQAMP_MPSTAT_EIRQ_GET(grlib_load_32(&regs->mpstat));
 }
 
 bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
@@ -112,14 +112,16 @@ rtems_status_code bsp_interrupt_is_pending(
 {
   rtems_interrupt_level level;
   uint32_t bit;
+  irqamp *regs;
 
   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
   bsp_interrupt_assert(pending != NULL);
   bit = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
 
   rtems_interrupt_local_disable(level);
-  *pending = (LEON3_IrqCtrl_Regs->ipend & bit) != 0 ||
-    (LEON3_IrqCtrl_Regs->force[rtems_scheduler_get_processor()] & bit) != 0;
+  *pending = (grlib_load_32(&regs->ipend) & bit) != 0 ||
+    (grlib_load_32(&regs->piforce[rtems_scheduler_get_processor()]) & bit) != 0;
   rtems_interrupt_local_enable(level);
   return RTEMS_SUCCESSFUL;
 }
@@ -127,9 +129,11 @@ rtems_status_code bsp_interrupt_is_pending(
 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
 {
   uint32_t bit;
+  irqamp *regs;
 
   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
   bit = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
 
   if ( vector <= BSP_INTERRUPT_VECTOR_MAX_STD ) {
     uint32_t cpu_count;
@@ -138,10 +142,11 @@ rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
     cpu_count = rtems_scheduler_get_processor_maximum();
 
     for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
-      LEON3_IrqCtrl_Regs->force[cpu_index] = bit;
+      grlib_store_32(&regs->piforce[cpu_index], bit);
     }
   } else {
     rtems_interrupt_lock_context lock_context;
+    uint32_t ipend;
 
     /*
      * This is a very dangerous operation and should only be used for test
@@ -149,7 +154,9 @@ rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
      * peripherals with this read-modify-write operation.
      */
     LEON3_IRQCTRL_ACQUIRE(&lock_context);
-    LEON3_IrqCtrl_Regs->ipend |= bit;
+    ipend = grlib_load_32(&regs->ipend);
+    ipend |= bit;
+    grlib_store_32(&regs->ipend, ipend);
     LEON3_IRQCTRL_RELEASE(&lock_context);
   }
 
@@ -162,6 +169,8 @@ rtems_status_code bsp_interrupt_raise_on(
   uint32_t            cpu_index
 )
 {
+  irqamp *regs;
+
   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
   bsp_interrupt_assert(cpu_index < rtems_scheduler_get_processor_maximum());
 
@@ -169,7 +178,8 @@ rtems_status_code bsp_interrupt_raise_on(
     return RTEMS_UNSATISFIED;
   }
 
-  LEON3_IrqCtrl_Regs->force[cpu_index] = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
+  grlib_store_32(&regs->piforce[cpu_index], 1U << vector);
   return RTEMS_SUCCESSFUL;
 }
 #endif
@@ -177,14 +187,16 @@ rtems_status_code bsp_interrupt_raise_on(
 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
 {
   uint32_t bit;
+  irqamp *regs;
 
   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
   bit = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
 
-  LEON3_IrqCtrl_Regs->iclear = bit;
+  grlib_store_32(&regs->iclear, bit);
 
   if (vector <= BSP_INTERRUPT_VECTOR_MAX_STD) {
-    LEON3_IrqCtrl_Regs->force[rtems_scheduler_get_processor()] = bit << 16;
+    grlib_store_32(&regs->piforce[rtems_scheduler_get_processor()], bit << 16);
   }
 
   return RTEMS_SUCCESSFUL;
@@ -195,9 +207,16 @@ rtems_status_code bsp_interrupt_vector_is_enabled(
   bool               *enabled
 )
 {
+  uint32_t bit;
+  irqamp *regs;
+  uint32_t pimask;
+
   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
-  *enabled =
-    !BSP_Cpu_Is_interrupt_masked(vector, _LEON3_Get_current_processor());
+
+  bit = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
+  pimask = grlib_load_32(&regs->pimask[_LEON3_Get_current_processor()]);
+  *enabled = (pimask & bit) != 0;
   return RTEMS_SUCCESSFUL;
 }
 
@@ -209,6 +228,8 @@ static void leon3_interrupt_vector_enable(rtems_vector_number vector)
   Processor_mask affinity;
   uint32_t bit;
   uint32_t unmasked;
+  uint32_t brdcst;
+  irqamp *regs;
 
   if (vector <= BSP_INTERRUPT_VECTOR_MAX_STD) {
     affinity = leon3_interrupt_affinities[vector];
@@ -218,72 +239,103 @@ static void leon3_interrupt_vector_enable(rtems_vector_number vector)
 
   cpu_count = rtems_scheduler_get_processor_maximum();
   bit = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
   unmasked = 0;
 
   for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
-    uint32_t mask;
+    uint32_t pimask;
 
-    mask = LEON3_IrqCtrl_Regs->mask[cpu_index];
+    pimask = grlib_load_32(&regs->pimask[cpu_index]);
 
     if (_Processor_mask_Is_set(&affinity, cpu_index)) {
       ++unmasked;
-      mask |= bit;
+      pimask |= bit;
     } else {
-      mask &= ~bit;
+      pimask &= ~bit;
     }
 
-    LEON3_IrqCtrl_Regs->mask[cpu_index] = mask;
+    grlib_store_32(&regs->pimask[cpu_index], pimask);
   }
 
+  brdcst = grlib_load_32(&regs->brdcst);
+
   if (unmasked > 1) {
-    LEON3_IrqCtrl_Regs->bcast |= bit;
+    brdcst |= bit;
   } else {
-    LEON3_IrqCtrl_Regs->bcast &= ~bit;
+    brdcst &= ~bit;
   }
+
+  grlib_store_32(&regs->brdcst, brdcst);
 }
 #endif
 
 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
 {
-#if defined(RTEMS_SMP)
   rtems_interrupt_lock_context lock_context;
+#if !defined(RTEMS_SMP)
+  uint32_t bit;
+  irqamp *regs;
+  uint32_t pimask;
+  uint32_t cpu_index;
+#endif
 
   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+#if !defined(RTEMS_SMP)
+  bit = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
+#endif
+
   LEON3_IRQCTRL_ACQUIRE(&lock_context);
+#if defined(RTEMS_SMP)
   leon3_interrupt_vector_enable(vector);
-  LEON3_IRQCTRL_RELEASE(&lock_context);
 #else
-  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
-  BSP_Cpu_Unmask_interrupt(vector, _LEON3_Get_current_processor());
+  cpu_index = _LEON3_Get_current_processor();
+  pimask = grlib_load_32(&regs->pimask[cpu_index]);
+  pimask |= bit;
+  grlib_store_32(&regs->pimask[cpu_index], pimask);
 #endif
+  LEON3_IRQCTRL_RELEASE(&lock_context);
   return RTEMS_SUCCESSFUL;
 }
 
 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
 {
-#if defined(RTEMS_SMP)
   rtems_interrupt_lock_context lock_context;
   uint32_t bit;
+  irqamp *regs;
+  uint32_t pimask;
   uint32_t cpu_index;
+#if defined(RTEMS_SMP)
   uint32_t cpu_count;
+  uint32_t brdcst;
+#endif
 
   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
   bit = 1U << vector;
-  cpu_count = rtems_scheduler_get_processor_maximum();
+  regs = LEON3_IrqCtrl_Regs;
 
   LEON3_IRQCTRL_ACQUIRE(&lock_context);
 
+#if defined(RTEMS_SMP)
+  cpu_count = rtems_scheduler_get_processor_maximum();
+
   for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
-    LEON3_IrqCtrl_Regs->mask[cpu_index] &= ~bit;
+    pimask = grlib_load_32(&regs->pimask[cpu_index]);
+    pimask &= ~bit;
+    grlib_store_32(&regs->pimask[cpu_index], pimask);
   }
 
-  LEON3_IrqCtrl_Regs->bcast &= ~bit;
-
-  LEON3_IRQCTRL_RELEASE(&lock_context);
+  brdcst = grlib_load_32(&regs->brdcst);
+  brdcst &= ~bit;
+  grlib_store_32(&regs->brdcst, brdcst);
 #else
-  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
-  BSP_Cpu_Mask_interrupt(vector, _LEON3_Get_current_processor());
+  cpu_index = _LEON3_Get_current_processor();
+  pimask = grlib_load_32(&regs->pimask[cpu_index]);
+  pimask &= ~bit;
+  grlib_store_32(&regs->pimask[cpu_index], pimask);
 #endif
+
+  LEON3_IRQCTRL_RELEASE(&lock_context);
   return RTEMS_SUCCESSFUL;
 }
 
@@ -297,6 +349,7 @@ rtems_status_code bsp_interrupt_set_affinity(
   uint32_t cpu_count;
   uint32_t cpu_index;
   uint32_t bit;
+  irqamp *regs;
 
   if (vector >= RTEMS_ARRAY_SIZE(leon3_interrupt_affinities)) {
     return RTEMS_UNSATISFIED;
@@ -304,6 +357,7 @@ rtems_status_code bsp_interrupt_set_affinity(
 
   cpu_count = rtems_scheduler_get_processor_maximum();
   bit = 1U << vector;
+  regs = LEON3_IrqCtrl_Regs;
 
   LEON3_IRQCTRL_ACQUIRE(&lock_context);
   leon3_interrupt_affinities[vector] = *affinity;
@@ -313,7 +367,7 @@ rtems_status_code bsp_interrupt_set_affinity(
    * using the new affinity.
    */
   for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
-    if ((LEON3_IrqCtrl_Regs->mask[cpu_index] & bit) != 0) {
+    if ((grlib_load_32(&regs->pimask[cpu_index]) & bit) != 0) {
       leon3_interrupt_vector_enable(vector);
       break;
     }
-- 
2.35.3



More information about the devel mailing list