Re: [PATCH v1 1/1] hw/intc: resample level IRQ on PLIC completion
Philippe Mathieu-Daudé <[email protected]> Mon, 27 Jul 2026 08:27:06 +0200
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, On 25/7/26 18:51, lanxiaoyun wrote: > From: lanxiaoyun1 <[email protected]> > > When an interrupt completion message is received, if the interrupt is > level-triggered and still asserted, forward a new interrupt request to > the PLIC core. > > This updates the SiFive PLIC IRQ handling so completion rechecks the > current source level and reasserts pending state when the input remains > high, matching the RISC-V PLIC specification. > > Signed-off-by: lanxiaoyun1 <[email protected]> > --- > hw/intc/sifive_plic.c | 4 +++- > include/hw/intc/sifive_plic.h | 1 + > 2 files changed, 4 insertions(+), 1 deletion(-) > > diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c > index 9c84ff06a9..43f235e329 100644 > --- a/hw/intc/sifive_plic.c > +++ b/hw/intc/sifive_plic.c > @@ -246,6 +246,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value, > } else if (contextid == 4) { > if (value < plic->num_sources) { > sifive_plic_set_claimed(plic, value, false); > + sifive_plic_set_pending(plic, value, !!plic->source[value]); > sifive_plic_update(plic); > } > } else { > @@ -276,6 +277,7 @@ static void sifive_plic_reset(DeviceState *dev) > int i; > > memset(s->source_priority, 0, sizeof(uint32_t) * s->num_sources); > + memset(s->source, 0, sizeof(uint32_t) * s->num_sources); > memset(s->target_priority, 0, sizeof(uint32_t) * s->num_addrs); > memset(s->pending, 0, sizeof(uint32_t) * s->bitfield_words); > memset(s->claimed, 0, sizeof(uint32_t) * s->bitfield_words); > @@ -353,7 +355,7 @@ static void parse_hart_config(SiFivePLICState *plic) > static void sifive_plic_irq_request(void *opaque, int irq, int level) > { > SiFivePLICState *s = opaque; > - > + s->source[irq] = !!level; > if (level > 0) { > sifive_plic_set_pending(s, irq, true); > sifive_plic_update(s); > diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h > index 32973dbf28..627a418ba1 100644 > --- a/include/hw/intc/sifive_plic.h > +++ b/include/hw/intc/sifive_plic.h > @@ -54,6 +54,7 @@ struct SiFivePLICState { > uint32_t num_enables; > PLICAddr *addr_config; > uint32_t *source_priority; > + uint32_t *source; > uint32_t *target_priority; > uint32_t *pending; > uint32_t *claimed; Where is this array initialized?