diff --git a/devices.c b/devices.c index 5b627e9..b560a59 100644 --- a/devices.c +++ b/devices.c @@ -1,5 +1,7 @@ #include "kvm/devices.h" #include "kvm/kvm.h" +#include "kvm/pci.h" +#include "kvm/virtio-mmio.h" #include #include @@ -27,6 +29,17 @@ int device__register(struct device_header *dev) bus = &device_trees[dev->bus_type]; dev->dev_num = bus->dev_num++; + switch (dev->bus_type) { + case DEVICE_BUS_PCI: + pci__assign_irq(dev); + break; + case DEVICE_BUS_MMIO: + virtio_mmio_assign_irq(dev); + break; + default: + break; + } + node = &bus->root.rb_node; while (*node) { int num = rb_entry(*node, struct device_header, node)->dev_num; diff --git a/hw/pci-shmem.c b/hw/pci-shmem.c index 0571183..34de747 100644 --- a/hw/pci-shmem.c +++ b/hw/pci-shmem.c @@ -358,10 +358,6 @@ int pci_shmem__init(struct kvm *kvm) if (shmem_region == NULL) return 0; - /* Register good old INTx */ - pci_shmem_pci_device.irq_pin = 1; - pci_shmem_pci_device.irq_line = irq__alloc_line(); - /* Register MMIO space for MSI-X */ r = ioport__register(kvm, IOPORT_EMPTY, &shmem_pci__io_ops, IOPORT_SIZE, NULL); if (r < 0) diff --git a/hw/vesa.c b/hw/vesa.c index c7b8e66..a0b15a7 100644 --- a/hw/vesa.c +++ b/hw/vesa.c @@ -65,8 +65,6 @@ struct framebuffer *vesa__init(struct kvm *kvm) if (r < 0) return ERR_PTR(r); - vesa_pci_device.irq_pin = 1; - vesa_pci_device.irq_line = irq__alloc_line(); vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); device__register(&vesa_device); diff --git a/include/kvm/pci.h b/include/kvm/pci.h index e1e621d..b0c28a1 100644 --- a/include/kvm/pci.h +++ b/include/kvm/pci.h @@ -6,6 +6,7 @@ #include #include +#include "kvm/devices.h" #include "kvm/kvm.h" #include "kvm/msi.h" @@ -88,6 +89,7 @@ int pci__init(struct kvm *kvm); int pci__exit(struct kvm *kvm); struct pci_device_header *pci__find_dev(u8 dev_num); u32 pci_get_io_space_block(u32 size); +void pci__assign_irq(struct device_header *dev_hdr); void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size); void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size); diff --git a/include/kvm/virtio-mmio.h b/include/kvm/virtio-mmio.h index 4d6a671..835f421 100644 --- a/include/kvm/virtio-mmio.h +++ b/include/kvm/virtio-mmio.h @@ -56,4 +56,5 @@ int virtio_mmio_signal_config(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_exit(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class); +void virtio_mmio_assign_irq(struct device_header *dev_hdr); #endif diff --git a/pci.c b/pci.c index c4442c8..c2da152 100644 --- a/pci.c +++ b/pci.c @@ -1,6 +1,7 @@ #include "kvm/devices.h" #include "kvm/pci.h" #include "kvm/ioport.h" +#include "kvm/irq.h" #include "kvm/util.h" #include "kvm/kvm.h" @@ -28,6 +29,20 @@ u32 pci_get_io_space_block(u32 size) return block; } +void pci__assign_irq(struct device_header *dev_hdr) +{ + struct pci_device_header *pci_hdr = dev_hdr->data; + + /* + * PCI supports only INTA#,B#,C#,D# per device. + * + * A#,B#,C#,D# are allowed for multifunctional devices so stick + * with A# for our single function devices. + */ + pci_hdr->irq_pin = 1; + pci_hdr->irq_line = irq__alloc_line(); +} + static void *pci_config_address_ptr(u16 port) { unsigned long offset; diff --git a/virtio/mmio.c b/virtio/mmio.c index 1cb186b..e1fca2b 100644 --- a/virtio/mmio.c +++ b/virtio/mmio.c @@ -256,6 +256,14 @@ static void generate_virtio_mmio_fdt_node(void *fdt, } #endif +void virtio_mmio_assign_irq(struct device_header *dev_hdr) +{ + struct virtio_mmio *vmmio = container_of(dev_hdr, + struct virtio_mmio, + dev_hdr); + vmmio->irq = irq__alloc_line(); +} + int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class) { @@ -276,7 +284,6 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .queue_num_max = 256, }; - vmmio->irq = irq__alloc_line(); vmmio->dev_hdr = (struct device_header) { .bus_type = DEVICE_BUS_MMIO, .data = generate_virtio_mmio_fdt_node, diff --git a/virtio/pci.c b/virtio/pci.c index dbd6758..fa7aa00 100644 --- a/virtio/pci.c +++ b/virtio/pci.c @@ -408,8 +408,6 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, if (kvm__supports_extension(kvm, KVM_CAP_SIGNAL_MSI)) vpci->features |= VIRTIO_PCI_F_SIGNAL_MSI; - vpci->pci_hdr.irq_pin = 1; - vpci->pci_hdr.irq_line = irq__alloc_line(); r = device__register(&vpci->dev_hdr); if (r < 0) goto free_msix_mmio;