diff options
Diffstat (limited to 'hw/i386/pc_piix.c')
| -rw-r--r-- | hw/i386/pc_piix.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index d5b0dcd1fe..42af03dbb4 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -71,6 +71,7 @@ #include "kvm/kvm-cpu.h" #define MAX_IDE_BUS 2 +#define XEN_IOAPIC_NUM_PIRQS 128ULL #ifdef CONFIG_IDE_ISA static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; @@ -89,6 +90,21 @@ static int pc_pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx) return (pci_intx + slot_addend) & 3; } +static void piix_intx_routing_notifier_xen(PCIDevice *dev) +{ + int i; + + /* Scan for updates to PCI link routes (0x60-0x63). */ + for (i = 0; i < PIIX_NUM_PIRQS; i++) { + uint8_t v = dev->config_read(dev, PIIX_PIRQCA + i, 1); + if (v & 0x80) { + v = 0; + } + v &= 0xf; + xen_set_pci_link_route(i, v); + } +} + /* PC hardware initialisation */ static void pc_init1(MachineState *machine, const char *host_type, const char *pci_type) @@ -223,8 +239,6 @@ static void pc_init1(MachineState *machine, if (pcmc->pci_enabled) { PIIX3State *piix3; PCIDevice *pci_dev; - const char *type = xen_enabled() ? TYPE_PIIX3_XEN_DEVICE - : TYPE_PIIX3_DEVICE; pci_bus = i440fx_init(pci_type, i440fx_host, @@ -237,7 +251,23 @@ static void pc_init1(MachineState *machine, : pc_pci_slot_get_pirq); pcms->bus = pci_bus; - pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, type); + pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, + TYPE_PIIX3_DEVICE); + + if (xen_enabled()) { + pci_device_set_intx_routing_notifier( + pci_dev, piix_intx_routing_notifier_xen); + + /* + * Xen supports additional interrupt routes from the PCI devices to + * the IOAPIC: the four pins of each PCI device on the bus are also + * connected to the IOAPIC directly. + * These additional routes can be discovered through ACPI. + */ + pci_bus_irqs(pci_bus, xen_intx_set_irq, pci_dev, + XEN_IOAPIC_NUM_PIRQS); + } + piix3 = PIIX3_PCI_DEVICE(pci_dev); piix3->pic = x86ms->gsi; piix3_devfn = piix3->dev.devfn; |