From 779d4af3e995344742ec6a090c149ac9d6a48856 Mon Sep 17 00:00:00 2001 From: Stuart Ianna Date: Thu, 12 Sep 2024 04:32:03 +0000 Subject: [PATCH] arch/risc-v/src/litex: Claim all pending PLIC interrupts. Attempt to service all interrupts pending in the PLIC's claim register. Ideally, this is more efficient than switching context for each interrupt received. --- arch/risc-v/src/litex/litex_irq_dispatch.c | 46 +++++++++------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/arch/risc-v/src/litex/litex_irq_dispatch.c b/arch/risc-v/src/litex/litex_irq_dispatch.c index 0f2d3d72b4..3fabb1a3d6 100644 --- a/arch/risc-v/src/litex/litex_irq_dispatch.c +++ b/arch/risc-v/src/litex/litex_irq_dispatch.c @@ -47,48 +47,38 @@ * riscv_dispatch_irq ****************************************************************************/ +#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP void *riscv_dispatch_irq(uintptr_t vector, uintreg_t *regs) { -#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP int irq = (vector & 0x3f); + DEBUGASSERT(irq <= RISCV_IRQ_EXT); if ((vector & RISCV_IRQ_BIT) != 0) { irq += RISCV_IRQ_ASYNC; } - /* Firstly, check if the irq is machine external interrupt */ - - if (irq == RISCV_IRQ_EXT) + if (irq < RISCV_IRQ_EXT) { - uint32_t ext = getreg32(LITEX_PLIC_CLAIM); - - /* Add the value to nuttx irq which is offset to the ext */ - - irq = RISCV_IRQ_EXT + ext; - } - - /* Acknowledge the interrupt */ - - riscv_ack_irq(irq); - - /* EXT means no interrupt */ - - if (irq != RISCV_IRQ_EXT) - { - /* Deliver the IRQ */ - regs = riscv_doirq(irq, regs); } - - if (irq > RISCV_IRQ_EXT) + else { - /* Then write PLIC_CLAIM to clear pending in PLIC */ - - putreg32(irq - RISCV_IRQ_EXT, LITEX_PLIC_CLAIM); + uint32_t ext = getreg32(LITEX_PLIC_CLAIM); + do + { + regs = riscv_doirq(RISCV_IRQ_EXT + ext, regs); + putreg32(ext, LITEX_PLIC_CLAIM); + ext = getreg32(LITEX_PLIC_CLAIM); + } + while (ext); } -#else + return regs; +} +#else +void *riscv_dispatch_irq(uintptr_t vector, uintreg_t *regs) +{ int i; int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf); @@ -127,6 +117,6 @@ void *riscv_dispatch_irq(uintptr_t vector, uintreg_t *regs) regs = riscv_doirq(irq, regs); -#endif /* CONFIG_LITEX_CORE_VEXRISCV_SMP */ return regs; } +#endif