From c77a20e85b7303d4f019d1430a550d3f4d0746a6 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 16 Jul 2021 16:07:23 +0200 Subject: bsp/leon3: Use new IRQ(A)MP register block API --- bsps/sparc/leon3/clock/ckinit.c | 39 ++++++----- 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, 203 insertions(+), 106 deletions(-) diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c index 2ec701fe2a..613ad3509d 100644 --- a/bsps/sparc/leon3/clock/ckinit.c +++ b/bsps/sparc/leon3/clock/ckinit.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -69,12 +70,14 @@ static struct timecounter leon3_tc; static void leon3_tc_tick_irqmp_timestamp(void) { - volatile struct irqmp_timestamp_regs *irqmp_ts = - &LEON3_IrqCtrl_Regs->timestamp[0]; - unsigned int first = irqmp_ts->assertion; - unsigned int second = irqmp_ts->counter; + irqamp_timestamp *irqmp_ts = + irqamp_get_timestamp_registers(LEON3_IrqCtrl_Regs); + uint32_t first = grlib_load_32(&irqmp_ts->itstmpas); + uint32_t second = grlib_load_32(&irqmp_ts->itcnt); + uint32_t control = grlib_load_32(&irqmp_ts->itstmpc); - irqmp_ts->control |= IRQMP_TIMESTAMP_S1_S2; + control |= IRQMP_TIMESTAMP_S1_S2; + grlib_store_32(&irqmp_ts->itstmpc, control); _Profiling_Update_max_interrupt_delay(_Per_CPU_Get(), second - first); @@ -100,11 +103,13 @@ static void leon3_tc_tick_irqmp_timestamp_init(void) bool done = true; #endif - volatile struct irqmp_timestamp_regs *irqmp_ts = - &LEON3_IrqCtrl_Regs->timestamp[0]; - unsigned int ks = 1U << 5; + irqamp_timestamp *irqmp_ts = + irqamp_get_timestamp_registers(LEON3_IrqCtrl_Regs); + uint32_t ks = 1U << 5; + uint32_t control = grlib_load_32(&irqmp_ts->itstmpc); - irqmp_ts->control = ks | IRQMP_TIMESTAMP_S1_S2 | (unsigned int) clkirq; + control = ks | IRQMP_TIMESTAMP_S1_S2 | (unsigned int) clkirq; + grlib_store_32(&irqmp_ts->itstmpc, control); if (done) { leon3_tc_tick = leon3_tc_tick_irqmp_timestamp; @@ -116,14 +121,14 @@ static void leon3_tc_tick_irqmp_timestamp_init(void) static void leon3_tc_tick_default(void) { -#ifndef RTEMS_SMP +#if !defined(RTEMS_SMP) SPARC_Counter *counter; rtems_interrupt_level level; counter = &_SPARC_Counter_mutable; rtems_interrupt_local_disable(level); - LEON3_IrqCtrl_Regs->iclear = counter->pending_mask; + grlib_store_32(&LEON3_IrqCtrl_Regs->iclear, counter->pending_mask); counter->accumulated += counter->interval; rtems_interrupt_local_enable(level); @@ -179,11 +184,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 +206,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 +223,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 /* @@ -237,7 +242,7 @@ static void leon3_clock_initialize(void) counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled; counter->read = _SPARC_Counter_read_clock; counter->counter_register = &gpt->timer[LEON3_CLOCK_INDEX].value; - counter->pending_register = &LEON3_IrqCtrl_Regs->ipend; + counter->pending_register = grlib_load_32(&LEON3_IrqCtrl_Regs->ipend); counter->pending_mask = UINT32_C(1) << clkirq; counter->accumulated = rtems_configuration_get_microseconds_per_tick(); counter->interval = rtems_configuration_get_microseconds_per_tick(); 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 #include #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 -#include +#include +#include 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 #include +#include #include #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(®s->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 #include #include +#include #include #include #include @@ -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( ®s->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 +#include #include #include @@ -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 #include #include +#include /* 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(®s->pimask[LEON3_Cpu_Index], 0); + grlib_store_32(®s->piforce[LEON3_Cpu_Index], 0); + grlib_store_32(®s->iclear, 0xffffffff); + LEON3_IrqCtrl_EIrq = IRQAMP_MPSTAT_EIRQ_GET(grlib_load_32(®s->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(®s->ipend) & bit) != 0 || + (grlib_load_32(®s->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(®s->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(®s->ipend); + ipend |= bit; + grlib_store_32(®s->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(®s->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(®s->iclear, bit); if (vector <= BSP_INTERRUPT_VECTOR_MAX_STD) { - LEON3_IrqCtrl_Regs->force[rtems_scheduler_get_processor()] = bit << 16; + grlib_store_32(®s->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(®s->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(®s->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(®s->pimask[cpu_index], pimask); } + brdcst = grlib_load_32(®s->brdcst); + if (unmasked > 1) { - LEON3_IrqCtrl_Regs->bcast |= bit; + brdcst |= bit; } else { - LEON3_IrqCtrl_Regs->bcast &= ~bit; + brdcst &= ~bit; } + + grlib_store_32(®s->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(®s->pimask[cpu_index]); + pimask |= bit; + grlib_store_32(®s->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(®s->pimask[cpu_index]); + pimask &= ~bit; + grlib_store_32(®s->pimask[cpu_index], pimask); } - LEON3_IrqCtrl_Regs->bcast &= ~bit; - - LEON3_IRQCTRL_RELEASE(&lock_context); + brdcst = grlib_load_32(®s->brdcst); + brdcst &= ~bit; + grlib_store_32(®s->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(®s->pimask[cpu_index]); + pimask &= ~bit; + grlib_store_32(®s->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(®s->pimask[cpu_index]) & bit) != 0) { leon3_interrupt_vector_enable(vector); break; } -- cgit v1.2.3