bsps/arm: Improve GICv2 support

In addtion to 1023, the GICC_IAR register may return 1022 as a special value.
Simply check for a valid interrupt vector for the dispatching.

Check the GICC_IAR again after the dispatch to quickly process a next interrupt
without having to go through the interrupt prologue and epiloge.
This commit is contained in:
Sebastian Huber
2024-04-08 14:49:21 +02:00
committed by Amar Takhar
parent 70029fc7be
commit 39584528e9
3 changed files with 34 additions and 13 deletions

View File

@@ -46,14 +46,18 @@
extern "C" {
#endif
static inline void arm_interrupt_handler_dispatch(rtems_vector_number vector)
static inline uint32_t arm_interrupt_enable_interrupts(void)
{
uint32_t interrupt_level = _CPU_ISR_Get_level();
uint32_t status = _CPU_ISR_Get_level();
/* Enable interrupts for nesting */
_CPU_ISR_Set_level(0);
bsp_interrupt_handler_dispatch(vector);
return status;
}
static inline void arm_interrupt_restore_interrupts(uint32_t status)
{
/* Restore interrupts to previous level */
_CPU_ISR_Set_level(interrupt_level);
_CPU_ISR_Set_level(status);
}
static inline void arm_interrupt_facility_set_exception_handler(void)

View File

@@ -44,12 +44,14 @@
extern "C" {
#endif
static inline void arm_interrupt_handler_dispatch(rtems_vector_number vector)
static inline uint32_t arm_interrupt_enable_interrupts(void)
{
uint32_t psr = _ARMV4_Status_irq_enable();
bsp_interrupt_handler_dispatch(vector);
return _ARMV4_Status_irq_enable();
}
_ARMV4_Status_restore(psr);
static inline void arm_interrupt_restore_interrupts(uint32_t status)
{
_ARMV4_Status_restore(status);
}
static inline void arm_interrupt_facility_set_exception_handler(void)

View File

@@ -40,6 +40,14 @@
#include <bsp/start.h>
#include <rtems/score/processormaskimpl.h>
/*
* The GIC architecture reserves interrupt ID numbers 1020 to 1023 for special
* purposes.
*/
#if BSP_INTERRUPT_VECTOR_COUNT >= 1020
#error "BSP_INTERRUPT_VECTOR_COUNT is too large"
#endif
#define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE)
#define PRIORITY_DEFAULT 127
@@ -74,12 +82,19 @@
void bsp_interrupt_dispatch(void)
{
volatile gic_cpuif *cpuif = GIC_CPUIF;
uint32_t icciar = cpuif->icciar;
rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
rtems_vector_number spurious = 1023;
if (vector != spurious) {
arm_interrupt_handler_dispatch(vector);
while (true) {
uint32_t icciar = cpuif->icciar;
rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
uint32_t status;
if (!bsp_interrupt_is_valid_vector(vector)) {
break;
}
status = arm_interrupt_enable_interrupts();
bsp_interrupt_handler_dispatch_unchecked(vector);
arm_interrupt_restore_interrupts(status);
cpuif->icceoir = icciar;
}