diff options
Diffstat (limited to 'hw/i386/x86.c')
-rw-r--r-- | hw/i386/x86.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 5944fc44ed..d68a9eaefc 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -588,11 +588,21 @@ void gsi_handler(void *opaque, int n, int level) GSIState *s = opaque; trace_x86_gsi_interrupt(n, level); - if (n < ISA_NUM_IRQS) { - /* Under KVM, Kernel will forward to both PIC and IOAPIC */ - qemu_set_irq(s->i8259_irq[n], level); + switch (n) { + case 0 ... ISA_NUM_IRQS - 1: + if (s->i8259_irq[n]) { + /* Under KVM, Kernel will forward to both PIC and IOAPIC */ + qemu_set_irq(s->i8259_irq[n], level); + } + /* fall through */ + case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1: + qemu_set_irq(s->ioapic_irq[n], level); + break; + case IO_APIC_SECONDARY_IRQBASE + ... IO_APIC_SECONDARY_IRQBASE + IOAPIC_NUM_PINS - 1: + qemu_set_irq(s->ioapic2_irq[n - IO_APIC_SECONDARY_IRQBASE], level); + break; } - qemu_set_irq(s->ioapic_irq[n], level); } void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) @@ -618,6 +628,23 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) } } +DeviceState *ioapic_init_secondary(GSIState *gsi_state) +{ + DeviceState *dev; + SysBusDevice *d; + unsigned int i; + + dev = qdev_new(TYPE_IOAPIC); + d = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(d, &error_fatal); + sysbus_mmio_map(d, 0, IO_APIC_SECONDARY_ADDRESS); + + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + gsi_state->ioapic2_irq[i] = qdev_get_gpio_in(dev, i); + } + return dev; +} + struct setup_data { uint64_t next; uint32_t type; |