]> git.proxmox.com Git - mirror_qemu.git/commitdiff
ich9: add support for pci assignment
authorJason Baron <jbaron@redhat.com>
Wed, 23 Jan 2013 02:11:37 +0000 (19:11 -0700)
committerMichael S. Tsirkin <mst@redhat.com>
Tue, 29 Jan 2013 23:31:09 +0000 (01:31 +0200)
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>
hw/ich9.h
hw/lpc_ich9.c
hw/pc_q35.c

index b8d8e6d3dfe20b8e37cbdfa7428ed153fb0ec2ac..d4509bb60670176f907b75a5ae2cf0a40383d8d6 100644 (file)
--- a/hw/ich9.h
+++ b/hw/ich9.h
@@ -18,6 +18,7 @@
 
 void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
 int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx);
+PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
 void ich9_lpc_pm_init(PCIDevice *pci_lpc, qemu_irq cmos_s3);
 PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus);
 i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
index 16843d76bc145b8588c2bdac823391ee7f8be0d3..e25689bf8744b53474b36d621f50f8f8ed3c5d59 100644 (file)
@@ -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)
index d82353e84f068a0e762be6c6bbe40a77636c847d..6f5ff8dcae274e6fae4febd5b52c7d256891ec93 100644 (file)
@@ -147,6 +147,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     ich9_lpc->ioapic = gsi_state->ioapic_irq;
     pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc,
                  ICH9_LPC_NB_PIRQS);
+    pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq);
     isa_bus = ich9_lpc->isa_bus;
 
     /*end early*/