aboutsummaryrefslogtreecommitdiffstats
path: root/hw/prep_pci.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-09-24 00:16:34 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-09-24 00:16:34 +0000
commitd2b5931756fdb9f839180e33898cd1e3e4fbdc90 (patch)
treee8e31fd9d7497dce68c6be46136a8bbfc37528d3 /hw/prep_pci.c
parente69954b9fc698996c8416a2fb26c6b50ad9f49a9 (diff)
PCI shared IRQ fix (original patch by andrzej zaborowski).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2165 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/prep_pci.c')
-rw-r--r--hw/prep_pci.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index a31b74c80..b5ff8eb0f 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -117,11 +117,21 @@ static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
&PPC_PCIIO_readl,
};
-static void prep_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
+/* Don't know if this matches real hardware, but it agrees with OHW. */
+static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
{
- /* XXX: we do not simulate the hardware - we rely on the BIOS to
- set correctly for irq line field */
- pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);
+ return (irq_num + (pci_dev->devfn >> 3)) & 3;
+}
+
+static int prep_irq_levels[4];
+
+static void prep_set_irq(void *pic, int irq_num, int level)
+{
+ int pic_irq_num;
+ prep_irq_levels[irq_num] = level;
+ level |= prep_irq_levels[irq_num ^ 2];
+ pic_irq_num = (irq_num == 0 || irq_num == 2) ? 9 : 11;
+ pic_set_irq(pic_irq_num, level);
}
PCIBus *pci_prep_init(void)
@@ -131,7 +141,7 @@ PCIBus *pci_prep_init(void)
int PPC_io_memory;
s = qemu_mallocz(sizeof(PREPPCIState));
- s->bus = pci_register_bus(prep_set_irq, NULL, 0);
+ s->bus = pci_register_bus(prep_set_irq, prep_map_irq, NULL, 0);
register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);