diff options
Diffstat (limited to 'hw/piix_pci.c')
-rw-r--r-- | hw/piix_pci.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 09e84f59b6..c497a014af 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -89,6 +89,7 @@ struct PCII440FXState { #define I440FX_SMRAM 0x72 static void piix3_set_irq(void *opaque, int pirq, int level); +static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pci_intx); static void piix3_write_config_xen(PCIDevice *dev, uint32_t address, uint32_t val, int len); @@ -315,6 +316,7 @@ static PCIBus *i440fx_common_init(const char *device_name, pci_create_simple_multifunction(b, -1, true, "PIIX3")); pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); + pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq); } piix3->pic = pic; *isa_bus = DO_UPCAST(ISABus, qbus, @@ -386,6 +388,22 @@ static void piix3_set_irq(void *opaque, int pirq, int level) piix3_set_irq_level(piix3, pirq, level); } +static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin) +{ + PIIX3State *piix3 = opaque; + int irq = piix3->dev.config[PIIX_PIRQC + pin]; + PCIINTxRoute route; + + if (irq < PIIX_NUM_PIC_IRQS) { + route.mode = PCI_INTX_ENABLED; + route.irq = irq; + } else { + route.mode = PCI_INTX_DISABLED; + route.irq = -1; + } + return route; +} + /* irq routing is changed. so rebuild bitmap */ static void piix3_update_irq_levels(PIIX3State *piix3) { @@ -405,6 +423,8 @@ static void piix3_write_config(PCIDevice *dev, if (ranges_overlap(address, len, PIIX_PIRQC, 4)) { PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev); int pic_irq; + + pci_bus_fire_intx_routing_notifier(piix3->dev.bus); piix3_update_irq_levels(piix3); for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) { piix3_set_irq_pic(piix3, pic_irq); |