diff options
| author | TENGZIJUN <[email protected]> | 2026-11-10 16:58:20 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-11-10 16:58:20 +0800 |
| commit | f50c9bf7fbfcd2cc5eb7990b82464c0331868fb7 (patch) | |
| tree | 6d26854171bc2e53631a8f7f51649676d87ebf1c | |
| parent | aee8d01b15a6613cb3b3650927193843058e62a0 (diff) | |
| -rw-r--r-- | libcpu/risc-v/common/pic/pic-riscv-aplic.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/libcpu/risc-v/common/pic/pic-riscv-aplic.c b/libcpu/risc-v/common/pic/pic-riscv-aplic.c index 8cc1d39997..9482809dee 100644 --- a/libcpu/risc-v/common/pic/pic-riscv-aplic.c +++ b/libcpu/risc-v/common/pic/pic-riscv-aplic.c @@ -236,12 +236,25 @@ static void aplic_irq_mask(struct rt_pic_irq *pirq) static void aplic_msi_irq_eoi(struct rt_pic_irq *pirq) { struct riscv_aplic *aplic = pirq->pic->priv_data; + rt_uint32_t input; switch (pirq->mode) { case RT_IRQ_MODE_LEVEL_HIGH: case RT_IRQ_MODE_LEVEL_LOW: - HWREG32(aplic->regs + APLIC_SETIPNUM_LE) = pirq->hwirq; + /* + * in_clrip reads the rectified input, including source polarity. + * Retrigger only while the device still asserts its interrupt. + * Older QEMU versions also set pending for deasserted inputs on + * setipnum_le writes, causing an endless stream of spurious MSIs. + */ + input = HWREG32(aplic->regs + APLIC_CLRIP_BASE + + (pirq->hwirq / APLIC_IRQBITS_PER_REG) * sizeof(rt_uint32_t)); + + if (input & RT_BIT(pirq->hwirq % APLIC_IRQBITS_PER_REG)) + { + HWREG32(aplic->regs + APLIC_SETIPNUM_LE) = pirq->hwirq; + } break; default: |
