aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorBibo Mao <maobibo@loongson.cn>2023-07-07 17:15:57 +0800
committerSong Gao <gaosong@loongson.cn>2023-08-24 11:17:59 +0800
commit2948c1fb6b8d806d92394ec358e6ed727e946df9 (patch)
treed8797b8cfa3c65663bc57f255c7298fb3df8895b /hw/intc
parent14f21f673a01cf3efa22a70256947fb9b6bbfdfa (diff)
hw/intc/loongarch_pch: fix edge triggered irq handling
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> Reviewed-by: Song Gao <gaosong@loongson.cn> Message-Id: <20230707091557.1474790-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/loongarch_pch_pic.c7
1 files changed, 6 insertions, 1 deletions
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;