From 723dad7cfab2a457c2f9664f38207ac390a5cc6b Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 16 Jan 2024 16:09:38 +0200 Subject: [PATCH] arch/risc-v/src/mpfs/mpfs_irq.c: Fix up_irqinitialize for warm reboot It is possible that a PLIC IRQ is claimed but not completed at warm reset. This occurs at least if there is a fault in the middle of irq handler execution. To recover from such situation, we can complete all IRQ:s in PLIC; this completes any already claimed IRQ, but has no effect on IRQs which are not claimed or not enabled. Signed-off-by: Jukka Laitinen --- arch/risc-v/src/mpfs/mpfs_irq.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/risc-v/src/mpfs/mpfs_irq.c b/arch/risc-v/src/mpfs/mpfs_irq.c index a7550c5d7317d..b633e0652f228 100644 --- a/arch/risc-v/src/mpfs/mpfs_irq.c +++ b/arch/risc-v/src/mpfs/mpfs_irq.c @@ -50,6 +50,19 @@ void up_irqinitialize(void) up_irq_save(); + /* Complete possibly claimed IRQs in PLIC (for current hart) in case + * of warm reboot, e.g. after a crash in the middle of IRQ handler. + * This has no effect on non-claimed or disabled interrupts. + */ + + uintptr_t claim_address = mpfs_plic_get_claimbase(); + + int irq; + for (irq = MPFS_IRQ_EXT_START; irq < NR_IRQS; irq++) + { + putreg32(irq - MPFS_IRQ_EXT_START, claim_address); + } + /* Disable all global interrupts for current hart */ uintptr_t iebase = mpfs_plic_get_iebase(); @@ -61,12 +74,6 @@ void up_irqinitialize(void) putreg32(0x0, iebase + 16); putreg32(0x0, iebase + 20); - /* Clear pendings in PLIC (for current hart) */ - - uintptr_t claim_address = mpfs_plic_get_claimbase(); - uint32_t val = getreg32(claim_address); - putreg32(val, claim_address); - /* Colorize the interrupt stack for debug purposes */ #if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 15 @@ -77,7 +84,6 @@ void up_irqinitialize(void) /* Set priority for all global interrupts to 1 (lowest) */ int id; - for (id = 1; id <= NR_IRQS; id++) { putreg32(1, (uintptr_t)(MPFS_PLIC_PRIORITY + (4 * id)));