This can be done by using the newly introduced num_irqs property. In particular, this change introduces a special case if num_irqs is 1 in which case any interrupt pin will be connected to the single irq. The default case is untouched (but note that the only client is the Sam460ex board for which the special case was actually created).
Signed-off-by: Sebastian Bauer <m...@sebastianbauer.info> --- hw/ppc/ppc440_pcix.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index d8af04b70f..cb7d7cfd2b 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -57,6 +57,7 @@ typedef struct PPC440PCIXState { struct PLBOutMap pom[PPC440_PCIX_NR_POMS]; struct PLBInMap pim[PPC440_PCIX_NR_PIMS]; uint32_t sts; + uint16_t num_irqs; qemu_irq irq[PCI_NUM_PINS]; AddressSpace bm_as; MemoryRegion bm; @@ -423,6 +424,12 @@ static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int irq_num) return slot - 1; } +/* All pins from each slot are tied the same and only board IRQ. */ +static int ppc440_pcix_map_irq_single(PCIDevice *pci_dev, int irq_num) +{ + return 0; +} + static void ppc440_pcix_set_irq(void *opaque, int irq_num, int level) { qemu_irq *pci_irqs = opaque; @@ -469,6 +476,7 @@ const MemoryRegionOps ppc440_pcix_host_data_ops = { static int ppc440_pcix_initfn(SysBusDevice *dev) { + pci_map_irq_fn map_irq; PPC440PCIXState *s; PCIHostState *h; int i; @@ -476,14 +484,22 @@ static int ppc440_pcix_initfn(SysBusDevice *dev) h = PCI_HOST_BRIDGE(dev); s = PPC440_PCIX_HOST_BRIDGE(dev); - for (i = 0; i < ARRAY_SIZE(s->irq); i++) { + if (s->num_irqs > 4) { + fprintf(stderr, "%s: Number of irqs must not exceed 4\n", __func__); + return -1; + } + + for (i = 0; i < s->num_irqs; i++) { sysbus_init_irq(dev, &s->irq[i]); } memory_region_init(&s->busmem, OBJECT(dev), "pci bus memory", UINT64_MAX); + + map_irq = s->num_irqs == 1 ? + ppc440_pcix_map_irq_single : ppc440_pcix_map_irq; h->bus = pci_register_root_bus(DEVICE(dev), NULL, ppc440_pcix_set_irq, - ppc440_pcix_map_irq, s->irq, &s->busmem, - get_system_io(), PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS); + map_irq, s->irq, &s->busmem, get_system_io(), + PCI_DEVFN(0, 0), s->num_irqs, TYPE_PCI_BUS); s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), "ppc4xx-host-bridge"); @@ -507,6 +523,11 @@ static int ppc440_pcix_initfn(SysBusDevice *dev) return 0; } +static Property ppc440_pcix_properties[] = { + DEFINE_PROP_UINT16("num-irqs", PPC440PCIXState, num_irqs, 4), + DEFINE_PROP_END_OF_LIST(), +}; + static void ppc440_pcix_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); @@ -514,6 +535,7 @@ static void ppc440_pcix_class_init(ObjectClass *klass, void *data) k->init = ppc440_pcix_initfn; dc->reset = ppc440_pcix_reset; + dc->props = ppc440_pcix_properties; } static const TypeInfo ppc440_pcix_info = { -- 2.18.0