diff options
Diffstat (limited to 'hw/kvm/ioapic.c')
-rw-r--r-- | hw/kvm/ioapic.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c index 6c3b8fe39a..30db6230b4 100644 --- a/hw/kvm/ioapic.c +++ b/hw/kvm/ioapic.c @@ -13,7 +13,47 @@ #include "hw/pc.h" #include "hw/ioapic_internal.h" #include "hw/apic_internal.h" -#include "kvm.h" +#include "sysemu/kvm.h" + +/* PC Utility function */ +void kvm_pc_setup_irq_routing(bool pci_enabled) +{ + KVMState *s = kvm_state; + int i; + + if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) { + for (i = 0; i < 8; ++i) { + if (i == 2) { + continue; + } + kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_MASTER, i); + } + for (i = 8; i < 16; ++i) { + kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8); + } + if (pci_enabled) { + for (i = 0; i < 24; ++i) { + if (i == 0) { + kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, 2); + } else if (i != 2) { + kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, i); + } + } + } + } +} + +void kvm_pc_gsi_handler(void *opaque, int n, int level) +{ + GSIState *s = opaque; + + if (n < ISA_NUM_IRQS) { + /* Kernel will forward to both PIC and IOAPIC */ + qemu_set_irq(s->i8259_irq[n], level); + } else { + qemu_set_irq(s->ioapic_irq[n], level); + } +} typedef struct KVMIOAPICState KVMIOAPICState; |