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?