Update #3269. --- bsps/sparc/leon3/start/eirq.c | 86 +++++++++++++++++++++++++++--- bsps/sparc/shared/irq/irq-shared.c | 17 ++++-- 2 files changed, 91 insertions(+), 12 deletions(-)
diff --git a/bsps/sparc/leon3/start/eirq.c b/bsps/sparc/leon3/start/eirq.c index d6373bf00a..4f5f910106 100644 --- a/bsps/sparc/leon3/start/eirq.c +++ b/bsps/sparc/leon3/start/eirq.c @@ -66,6 +66,19 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + bool is_standard_interrupt; + + is_standard_interrupt = (vector <= BSP_INTERRUPT_VECTOR_MAX_STD); + attributes->is_maskable = (vector != 15); + attributes->can_enable = true; + attributes->maybe_enable = true; + attributes->can_disable = true; + attributes->can_cause = true; + attributes->can_cause_on = is_standard_interrupt; + attributes->can_clear = true; + attributes->cleared_by_acknowledge = true; + attributes->can_get_affinity = is_standard_interrupt; + attributes->can_set_affinity = is_standard_interrupt; return RTEMS_SUCCESSFUL; } @@ -74,16 +87,56 @@ rtems_status_code bsp_interrupt_is_pending( bool *pending ) { +#if defined(RTEMS_SMP) + rtems_interrupt_level level; + uint32_t bit; + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); bsp_interrupt_assert(pending != NULL); - *pending = false; - return RTEMS_UNSATISFIED; + bit = 1U << vector; + + rtems_interrupt_local_disable(level); + *pending = (LEON3_IrqCtrl_Regs->ipend & bit) != 0 || + (LEON3_IrqCtrl_Regs->force[rtems_scheduler_get_processor()] & bit) != 0; + rtems_interrupt_local_enable(level); + return RTEMS_SUCCESSFUL; +#else + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + *pending = !BSP_Is_interrupt_pending(vector); + return RTEMS_SUCCESSFUL; +#endif } rtems_status_code bsp_interrupt_cause(rtems_vector_number vector) { + uint32_t bit; + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + bit = 1U << vector; + + if ( vector <= BSP_INTERRUPT_VECTOR_MAX_STD ) { + uint32_t cpu_count; + uint32_t cpu_index; + + cpu_count = rtems_scheduler_get_processor_maximum(); + + for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { + LEON3_IrqCtrl_Regs->force[cpu_index] = bit; + } + } else { + rtems_interrupt_lock_context lock_context; + + /* + * This is a very dangerous operation and should only be used for test + * software. We may accidentally clear the pending state set by + * peripherals with this read-modify-write operation. + */ + LEON3_IRQCTRL_ACQUIRE(&lock_context); + LEON3_IrqCtrl_Regs->ipend |= bit; + LEON3_IRQCTRL_RELEASE(&lock_context); + } + + return RTEMS_SUCCESSFUL; } #if defined(RTEMS_SMP) @@ -93,14 +146,31 @@ rtems_status_code bsp_interrupt_cause_on( ) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + bsp_interrupt_assert(cpu_index < rtems_scheduler_get_processor_maximum()); + + if ( vector > BSP_INTERRUPT_VECTOR_MAX_STD ) { + return RTEMS_UNSATISFIED; + } + + LEON3_IrqCtrl_Regs->force[cpu_index] = 1U << vector; + return RTEMS_SUCCESSFUL; } #endif rtems_status_code bsp_interrupt_clear(rtems_vector_number vector) { + uint32_t bit; + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + bit = 1U << vector; + + LEON3_IrqCtrl_Regs->iclear = bit; + + if (vector <= BSP_INTERRUPT_VECTOR_MAX_STD) { + LEON3_IrqCtrl_Regs->force[rtems_scheduler_get_processor()] = bit << 16; + } + + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_is_enabled( @@ -109,9 +179,9 @@ rtems_status_code bsp_interrupt_vector_is_enabled( ) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - bsp_interrupt_assert(enabled != NULL); - *enabled = false; - return RTEMS_UNSATISFIED; + *enabled = + !BSP_Cpu_Is_interrupt_masked(vector, _LEON3_Get_current_processor()); + return RTEMS_SUCCESSFUL; } #if defined(RTEMS_SMP) diff --git a/bsps/sparc/shared/irq/irq-shared.c b/bsps/sparc/shared/irq/irq-shared.c index aa1d412be0..d0b77bddbb 100644 --- a/bsps/sparc/shared/irq/irq-shared.c +++ b/bsps/sparc/shared/irq/irq-shared.c @@ -37,6 +37,13 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + attributes->is_maskable = vector != 15; + attributes->can_enable = true; + attributes->can_disable = true; + attributes->can_cause = true; + attributes->can_cause_on = true; + attributes->can_clear = true; + attributes->can_set_affinity = true; return RTEMS_SUCCESSFUL; } @@ -54,7 +61,8 @@ rtems_status_code bsp_interrupt_is_pending( rtems_status_code bsp_interrupt_cause(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + BSP_Force_interrupt(vector); + return RTEMS_SUCCESSFUL; } #if defined(RTEMS_SMP) @@ -71,7 +79,8 @@ rtems_status_code bsp_interrupt_cause_on( rtems_status_code bsp_interrupt_clear(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + BSP_Clear_interrupt(vector); + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_is_enabled( @@ -81,8 +90,8 @@ rtems_status_code bsp_interrupt_vector_is_enabled( { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); bsp_interrupt_assert(enabled != NULL); - *enabled = false; - return RTEMS_UNSATISFIED; + *enabled = !BSP_Cpu_Is_interrupt_masked(vector, bsp_irq_cpu(vector)); + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) -- 2.26.2 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel