aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/apic.c4
-rw-r--r--hw/i8259.c15
-rw-r--r--hw/pc.c3
-rw-r--r--hw/pc.h2
4 files changed, 12 insertions, 12 deletions
diff --git a/hw/apic.c b/hw/apic.c
index d8f56c8..8289eef 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -23,6 +23,7 @@
#include "host-utils.h"
#include "sysbus.h"
#include "trace.h"
+#include "pc.h"
/* APIC Local Vector Table */
#define APIC_LVT_TIMER 0
@@ -399,6 +400,9 @@ static void apic_update_irq(APICState *s)
}
if (apic_irq_pending(s) > 0) {
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
+ } else if (apic_accept_pic_intr(&s->busdev.qdev) &&
+ pic_get_output(isa_pic)) {
+ apic_deliver_pic_intr(&s->busdev.qdev, 1);
}
}
diff --git a/hw/i8259.c b/hw/i8259.c
index e5323ff..6006123 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -146,8 +146,7 @@ static int pic_get_irq(PicState *s)
/* raise irq to CPU if necessary. must be called every time the active
irq may change */
-/* XXX: should not export it, but it is needed for an APIC kludge */
-void pic_update_irq(PicState2 *s)
+static void pic_update_irq(PicState2 *s)
{
int irq2, irq;
@@ -174,14 +173,9 @@ void pic_update_irq(PicState2 *s)
printf("pic: cpu_interrupt\n");
#endif
qemu_irq_raise(s->parent_irq);
- }
-
-/* all targets should do this rather than acking the IRQ in the cpu */
-#if defined(TARGET_MIPS) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
- else {
+ } else {
qemu_irq_lower(s->parent_irq);
}
-#endif
}
#ifdef DEBUG_IRQ_LATENCY
@@ -441,6 +435,11 @@ uint32_t pic_intack_read(PicState2 *s)
return ret;
}
+int pic_get_output(PicState2 *s)
+{
+ return (pic_get_irq(&s->pics[0]) >= 0);
+}
+
static void elcr_ioport_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
diff --git a/hw/pc.c b/hw/pc.c
index 9b68695..f0802b7 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -155,9 +155,6 @@ int cpu_get_pic_interrupt(CPUState *env)
intno = apic_get_interrupt(env->apic_state);
if (intno >= 0) {
- /* set irq request if a PIC irq is still pending */
- /* XXX: improve that */
- pic_update_irq(isa_pic);
return intno;
}
/* read the irq from the PIC */
diff --git a/hw/pc.h b/hw/pc.h
index 72f8c7c..d133dc0 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -66,7 +66,7 @@ void pic_set_irq(int irq, int level);
void pic_set_irq_new(void *opaque, int irq, int level);
qemu_irq *i8259_init(qemu_irq parent_irq);
int pic_read_irq(PicState2 *s);
-void pic_update_irq(PicState2 *s);
+int pic_get_output(PicState2 *s);
uint32_t pic_intack_read(PicState2 *s);
void pic_info(Monitor *mon);
void irq_info(Monitor *mon);