hw/versatile_pci: Implement the correct PCI IRQ swizzling

Implement the correct IRQ swizzling for the Versatile PCI controller
(it is the standard PCI one). Note that this change will break
Linux kernels which rely on the broken QEMU behaviour!

XXX not quite true -- it will break if they have more than
one PCI device -- slot B's irq mapping stays the same but
others break. [similarly true for all slots which == 2 mod 4]

TODO: making the controller slot 29 and the min slot 29
is correct for h/w but limits qemu to two PCI devices,
which is bad news. Consider changing back to 11...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index adc7137..860df32 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -17,8 +17,8 @@
 #include "scsi.h"
 #include "sysemu/dma.h"
 
-#define DEBUG_LSI
-#define DEBUG_LSI_REG
+//#define DEBUG_LSI
+//#define DEBUG_LSI_REG
 
 #ifdef DEBUG_LSI
 #define DPRINTF(fmt, ...) \
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 58d0caf..48929d1 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -59,7 +59,15 @@
 
 static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
 {
-    return irq_num;
+    /* Slot to IRQ mapping for RealView Platform Baseboard 926 backplane
+     *      name    slot    IntA    IntB    IntC    IntD
+     *      A       31      IRQ28   IRQ29   IRQ30   IRQ27
+     *      B       30      IRQ27   IRQ28   IRQ29   IRQ30
+     *      C       29      IRQ30   IRQ27   IRQ28   IRQ29
+     * Slot C is for the host bridge; A and B the peripherals.
+     * Our output irqs 0..3 correspond to the baseboard's 27..30.
+     */
+    return (PCI_SLOT(d->devfn) + irq_num - 2) % PCI_NUM_PINS;
 }
 
 static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
@@ -79,11 +87,13 @@
 
     pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), "pci",
                         get_system_memory(), &s->pci_io_space,
-                        PCI_DEVFN(11, 0));
+                        PCI_DEVFN(29, 0));
     h->bus = &s->pci_bus;
 
     object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST);
     qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
+    object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(29, 0), "addr",
+                            NULL);
 }
 
 static void pci_vpb_realize(DeviceState *dev, Error **errp)