diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2024-04-08 14:49:21 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2024-04-16 07:26:35 +0200 |
commit | 899f92f7b891f51c5ff1d62bb5c3f42bf73f23a0 (patch) | |
tree | 069ba5ea3030e025dd17afbb190536a4b5e0136a /bsps/shared/dev/irq/arm-gicv2.c | |
parent | smptests/smpipi01: Fix sporadic test failure (diff) | |
download | rtems-899f92f7b891f51c5ff1d62bb5c3f42bf73f23a0.tar.bz2 |
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.
Diffstat (limited to '')
-rw-r--r-- | bsps/shared/dev/irq/arm-gicv2.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c index b7e30f2eb2..e3e31e5ab9 100644 --- a/bsps/shared/dev/irq/arm-gicv2.c +++ b/bsps/shared/dev/irq/arm-gicv2.c @@ -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; } |