On 9/2/2026 4:30 PM, Philippe Mathieu-Daudé wrote:
On 1/9/26 19:33, Brian Cain wrote:
From: Sid Manning <[email protected]>
l2vic_set_irq() clears a level-triggered source's pending bit on
de-assertion, so a source that drops before it is latched into
int_status is not spuriously re-delivered on the next ciad.
Edge-triggered sources (int_type set) keep the pulse semantics they
already have via SOFT_INT/set_irq(level=1).
Reviewed-by: Pierrick Bouvier <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
hw/intc/hex-l2vic.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/intc/hex-l2vic.c b/hw/intc/hex-l2vic.c
index f07ec850d49..a986f0bdf35 100644
--- a/hw/intc/hex-l2vic.c
+++ b/hw/intc/hex-l2vic.c
@@ -299,6 +299,8 @@ static void l2vic_set_irq(void *opaque, int irq,
int level)
if (level) {
set_bit32(irq, s->int_pending);
+ } else if (!test_bit32(irq, s->int_type)) {
+ clear_bit32(irq, s->int_pending);
}
l2vic_update(s, irq);
I'm confused with l2vic_update() logic which seems to
duplicate a bit.
}
hw/intc/hex-l2vic.c-95- /* Edge or Level interrupt */
hw/intc/hex-l2vic.c:96: DECLARE_BITMAP32(int_type,
L2VIC_INTERRUPT_MAX);
Not obvious, so 0:edge and 1:level. Ah no...
hw/intc/hex-l2vic.c-268- * Only auto-disable for
edge-triggered interrupts (type=1).
So 1:edge and 0:level?
Tiny helpers can help to make the code more readable:
Agreed! I like this change. Sent a follow up.
static bool edge_triggered_irq(HexL2VICState *s, int irq)
{
return test_bit32(irq, s->int_type) == 1;
}