diff mbox series

hw/intc/loongarch_pch: fix edge triggered irq handling

Message ID 20230707091557.1474790-1-maobibo@loongson.cn (mailing list archive)
State New, archived
Headers show
Series hw/intc/loongarch_pch: fix edge triggered irq handling | expand

Commit Message

bibo mao July 7, 2023, 9:15 a.m. UTC
For edge triggered irq, qemu_irq_pulse is used to inject irq. It will
set irq with high level and low level soon to simluate pulse irq.

For edge triggered irq, irq is injected and set as pending at rising
level, do not clear irq at lowering level. LoongArch pch interrupt will
clear irq for lowering level irq, there will be problem. ACPI ged deivce
is edge-triggered irq, it is used for cpu/memory hotplug.

This patch fixes memory hotplug issue on LoongArch virt machine.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 hw/intc/loongarch_pch_pic.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

gaosong July 11, 2023, 12:42 p.m. UTC | #1
在 2023/7/7 下午5:15, Bibo Mao 写道:
> For edge triggered irq, qemu_irq_pulse is used to inject irq. It will
> set irq with high level and low level soon to simluate pulse irq.
>
> For edge triggered irq, irq is injected and set as pending at rising
> level, do not clear irq at lowering level. LoongArch pch interrupt will
> clear irq for lowering level irq, there will be problem. ACPI ged deivce
> is edge-triggered irq, it is used for cpu/memory hotplug.
>
> This patch fixes memory hotplug issue on LoongArch virt machine.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
>   hw/intc/loongarch_pch_pic.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
Reviewed-by: Song Gao <gaosong@loongson.cn>

Thanks.
Song Gao
> diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
> index 9208fc4460..6aa4cadfa4 100644
> --- a/hw/intc/loongarch_pch_pic.c
> +++ b/hw/intc/loongarch_pch_pic.c
> @@ -30,7 +30,11 @@ static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
>               qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
>           }
>       } else {
> -        val = mask & s->intisr;
> +        /*
> +         * intirr means requested pending irq
> +         * do not clear pending irq for edge-triggered on lowering edge
> +         */
> +        val = mask & s->intisr & ~s->intirr;
>           if (val) {
>               irq = ctz64(val);
>               s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
> @@ -51,6 +55,7 @@ static void pch_pic_irq_handler(void *opaque, int irq, int level)
>           /* Edge triggered */
>           if (level) {
>               if ((s->last_intirr & mask) == 0) {
> +                /* marked pending on a rising edge */
>                   s->intirr |= mask;
>               }
>               s->last_intirr |= mask;
diff mbox series

Patch

diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
index 9208fc4460..6aa4cadfa4 100644
--- a/hw/intc/loongarch_pch_pic.c
+++ b/hw/intc/loongarch_pch_pic.c
@@ -30,7 +30,11 @@  static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
             qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
         }
     } else {
-        val = mask & s->intisr;
+        /*
+         * intirr means requested pending irq
+         * do not clear pending irq for edge-triggered on lowering edge
+         */
+        val = mask & s->intisr & ~s->intirr;
         if (val) {
             irq = ctz64(val);
             s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
@@ -51,6 +55,7 @@  static void pch_pic_irq_handler(void *opaque, int irq, int level)
         /* Edge triggered */
         if (level) {
             if ((s->last_intirr & mask) == 0) {
+                /* marked pending on a rising edge */
                 s->intirr |= mask;
             }
             s->last_intirr |= mask;