intc/ibex_plic: Clear interrupts that occur during claim process
authorAlistair Francis <alistair.francis@wdc.com>
Fri, 4 Dec 2020 16:47:37 +0000 (08:47 -0800)
committerAlistair Francis <alistair.francis@wdc.com>
Fri, 18 Dec 2020 05:56:43 +0000 (21:56 -0800)
Previously if an interrupt occured during the claim process (after the
interrupt is claimed but before it's completed) it would never be
cleared.
This patch ensures that we also clear the hidden_pending bits as well.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Jackie Ke <jackieke724@hotmail.com>
Message-id: 4e9786084a86f220689123cc8a7837af8fa071cf.1607100423.git.alistair.francis@wdc.com

hw/intc/ibex_plic.c

index 341c9db405575e60d7d090d5bb77324af8e7e415..c1b72fcab0bc293333a915085a4f1d882deb1501 100644 (file)
@@ -43,16 +43,23 @@ static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
 {
     int pending_num = irq / 32;
 
+    if (!level) {
+        /*
+         * If the level is low make sure we clear the hidden_pending.
+         */
+        s->hidden_pending[pending_num] &= ~(1 << (irq % 32));
+    }
+
     if (s->claimed[pending_num] & 1 << (irq % 32)) {
         /*
          * The interrupt has been claimed, but not completed.
          * The pending bit can't be set.
+         * Save the pending level for after the interrupt is completed.
          */
         s->hidden_pending[pending_num] |= level << (irq % 32);
-        return;
+    } else {
+        s->pending[pending_num] |= level << (irq % 32);
     }
-
-    s->pending[pending_num] |= level << (irq % 32);
 }
 
 static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)