aboutsummaryrefslogtreecommitdiff
path: root/hw/pci
diff options
context:
space:
mode:
authorMarcel Apfelbaum <marcel.a@redhat.com>2013-10-07 10:36:35 +0300
committerMichael S. Tsirkin <mst@redhat.com>2013-10-14 17:11:44 +0300
commitd98f08f54e0882b4da1177345161afabb8d47d94 (patch)
tree6eb01653c0c0430899c085cc5bb15ab0eae353b1 /hw/pci
parenta8a9d30bab2fae2e0ab3436fa0a40d89fbb0cf4e (diff)
hw/pci: add pci wrappers for allocating and asserting irqs
Interrupt pin is selected and saved into PCI_INTERRUPT_PIN register during device initialization. Devices should not call directly qemu_set_irq and specify the INTx pin on each call. Added pci_* wrappers to replace qemu_set_irq, qemu_irq_raise, qemu_irq_lower and qemu_irq_pulse, setting the irq based on PCI_INTERRUPT_PIN. Added pci_allocate_irq wrapper to be used by devices that still need PCIDevice infrastructure to assert irqs. Renamed a static method which was named already pci_set_irq. Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci')
-rw-r--r--hw/pci/pci.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 25626b8e19..ff4b697cce 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -83,7 +83,7 @@ static const TypeInfo pcie_bus_info = {
static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
static void pci_update_mappings(PCIDevice *d);
-static void pci_set_irq(void *opaque, int irq_num, int level);
+static void pci_irq_handler(void *opaque, int irq_num, int level);
static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom);
static void pci_del_option_rom(PCIDevice *pdev);
@@ -161,7 +161,7 @@ void pci_device_deassert_intx(PCIDevice *dev)
{
int i;
for (i = 0; i < PCI_NUM_PINS; ++i) {
- qemu_set_irq(dev->irq[i], 0);
+ pci_irq_handler(dev, i, 0);
}
}
@@ -889,7 +889,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
pci_dev->config_read = config_read;
pci_dev->config_write = config_write;
bus->devices[devfn] = pci_dev;
- pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, PCI_NUM_PINS);
+ pci_dev->irq = qemu_allocate_irqs(pci_irq_handler, pci_dev, PCI_NUM_PINS);
pci_dev->version_id = 2; /* Current pci device vmstate version */
return pci_dev;
}
@@ -1201,7 +1201,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
/* generic PCI irq support */
/* 0 <= irq_num <= 3. level must be 0 or 1 */
-static void pci_set_irq(void *opaque, int irq_num, int level)
+static void pci_irq_handler(void *opaque, int irq_num, int level)
{
PCIDevice *pci_dev = opaque;
int change;
@@ -1217,6 +1217,24 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
pci_change_irq_level(pci_dev, irq_num, change);
}
+static inline int pci_intx(PCIDevice *pci_dev)
+{
+ return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
+}
+
+qemu_irq pci_allocate_irq(PCIDevice *pci_dev)
+{
+ int intx = pci_intx(pci_dev);
+
+ return qemu_allocate_irq(pci_irq_handler, pci_dev, intx);
+}
+
+void pci_set_irq(PCIDevice *pci_dev, int level)
+{
+ int intx = pci_intx(pci_dev);
+ pci_irq_handler(pci_dev, intx, level);
+}
+
/* Special hooks used by device assignment */
void pci_bus_set_route_irq_fn(PCIBus *bus, pci_route_irq_fn route_intx_to_irq)
{