On 07/31/2018 06:36 AM, Sebastian Bauer wrote: > 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) {
may be use PCI_NUM_PINS > + fprintf(stderr, "%s: Number of irqs must not exceed 4\n", __func__); error_report would be better. > + return -1; > + } It might be the right time to QOM'ify a bit more "ppc440-pcix-host" and introduce a realize() operation to handle errors. > + 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), PCI_NUM_PINS ? > + 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 = { >