aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2013-03-01 18:03:12 +0000
committerPeter Maydell <peter.maydell@linaro.org>2013-03-01 18:03:53 +0000
commit7e8ce1b6d860f0cac588402585855aab673f627e (patch)
tree72e107ebbe0a731df69f568592acd86e80ca0514
parent042f0882a789ad85fcc936af1b15189132150b70 (diff)
hw/versatile_pci: Implement the correct PCI IRQ swizzlingfix-pci
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>
-rw-r--r--hw/lsi53c895a.c4
-rw-r--r--hw/versatile_pci.c14
2 files changed, 14 insertions, 4 deletions
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index adc713727d..860df328e5 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 58d0caf2a4..48929d17af 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -59,7 +59,15 @@ static const MemoryRegionOps pci_vpb_config_ops = {
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 @@ static void pci_vpb_init(Object *obj)
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)