On 4/28/2026 1:01 PM, Jim Shu wrote:
According to the AIA spec ch4.7 ("Precise effects on interrupt-pending
bits"), pending bit of APLIC should be set/cleared whenever the
rectified input value is high/low in the both level-trigger mode
and direct delivery mode.
Currently, QEMU APLIC only clears the pending bit when interrupt is
claimed in APLIC, but not clears it when the rectified input value is
low. (e.g. IRQ source signal is low in the LEVEL_HIGH/Level1 mode).
The software may receive an additional IRQ if the peripheral
triggers one after the software clears the APLIC IRQ but before it
clears the peripheral's IRQ.
Thus, we also clear the pending bit via the rectified input value in the
level-trigger mode.
This change doesn't affect MSI delivery mode. Calling
riscv_aplic_msi_irq_update() when IRQ pending is low will do nothing.
Signed-off-by: Jim Shu <[email protected]>
---
Reviewed-by: Daniel Henrique Barboza <[email protected]>
hw/intc/riscv_aplic.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index 8f700431114..791e0b01b96 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -591,14 +591,14 @@ static void riscv_aplic_request(void *opaque, int irq,
int level)
}
break;
case APLIC_SOURCECFG_SM_LEVEL_HIGH:
- if ((level > 0) && !(state & APLIC_ISTATE_PENDING)) {
- riscv_aplic_set_pending_raw(aplic, irq, true);
+ if ((level > 0) != !!(state & APLIC_ISTATE_PENDING)) {
+ riscv_aplic_set_pending_raw(aplic, irq, level > 0);
update = true;
}
break;
case APLIC_SOURCECFG_SM_LEVEL_LOW:
- if ((level <= 0) && !(state & APLIC_ISTATE_PENDING)) {
- riscv_aplic_set_pending_raw(aplic, irq, true);
+ if ((level <= 0) != !!(state & APLIC_ISTATE_PENDING)) {
+ riscv_aplic_set_pending_raw(aplic, irq, level <= 0);
update = true;
}
break;