diff options
author | Jason Baron <jbaron@redhat.com> | 2013-01-22 19:11:37 -0700 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2013-01-30 01:31:09 +0200 |
commit | 91c3f2f00810a9ba5e4404c9611197efd8f694c8 (patch) | |
tree | 317b938e539954fda77f338ad20aeab4e3dcdaa3 /hw/lpc_ich9.c | |
parent | dd23454ba2c83168b453155365671e67723b881f (diff) |
ich9: add support for pci assignment
Fills out support for the pci assignment API. Added:
PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin)
Add calls to pci_bus_fire_intx_routing_notifier() when routing changes
are made.
Signed-off-by: Jason Baron <jbaron@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/lpc_ich9.c')
-rw-r--r-- | hw/lpc_ich9.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c index 16843d76bc..e25689bf87 100644 --- a/hw/lpc_ich9.c +++ b/hw/lpc_ich9.c @@ -158,6 +158,7 @@ static void ich9_cc_write(void *opaque, hwaddr addr, ich9_cc_addr_len(&addr, &len); memcpy(lpc->chip_config + addr, &val, len); + pci_bus_fire_intx_routing_notifier(lpc->d.bus); ich9_cc_update(lpc); } @@ -286,6 +287,32 @@ int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx) return lpc->irr[PCI_SLOT(pci_dev->devfn)][intx]; } +PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin) +{ + ICH9LPCState *lpc = opaque; + PCIINTxRoute route; + int pic_irq; + int pic_dis; + + assert(0 <= pirq_pin); + assert(pirq_pin < ICH9_LPC_NB_PIRQS); + + route.mode = PCI_INTX_ENABLED; + ich9_lpc_pic_irq(lpc, pirq_pin, &pic_irq, &pic_dis); + if (!pic_dis) { + if (pic_irq < ICH9_LPC_PIC_NUM_PINS) { + route.irq = pic_irq; + } else { + route.mode = PCI_INTX_DISABLED; + route.irq = -1; + } + } else { + route.irq = ich9_pirq_to_gsi(pirq_pin); + } + + return route; +} + static int ich9_lpc_sci_irq(ICH9LPCState *lpc) { switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] & @@ -405,6 +432,12 @@ static void ich9_lpc_config_write(PCIDevice *d, if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) { ich9_lpc_rcba_update(lpc, rbca_old); } + if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) { + pci_bus_fire_intx_routing_notifier(lpc->d.bus); + } + if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) { + pci_bus_fire_intx_routing_notifier(lpc->d.bus); + } } static void ich9_lpc_reset(DeviceState *qdev) |