On Tue, 2013-01-22 at 15:12 -0700, Alex Williamson wrote: > q35/ich9 doesn't use the same interrupt mapping function as > i440fx/piix. PIRQA:D and PIRQE:H are programmed identically, but we > start at index 0, not index -1. Slots 25 through 31 are also > programmed independently. > > When running qemu w/o this patch, a device at address 0:6.0 will have > its PCI interrupt line register programmed with irq 10 (as seen by > info pci), but it actually uses irq 11 (as reported the guest). Half > of the interrupt lines are misprogrammedi like this. Functionally, a > fully emulated qemu guest doesn't care much, but when we try to use > device assignment, we really need to know the correct irqs. > > Signed-off-by: Alex Williamson <alex.william...@redhat.com> > --- > src/pciinit.c | 35 ++++++++++++++++++++++++++++++++++- > 1 file changed, 34 insertions(+), 1 deletion(-) > > diff --git a/src/pciinit.c b/src/pciinit.c > index 857e8af..ddac7e7 100644 > --- a/src/pciinit.c > +++ b/src/pciinit.c > @@ -91,8 +91,10 @@ const u8 pci_irqs[4] = { > 10, 10, 11, 11 > }; > > +static int (*pci_slot_get_irq)(struct pci_device *pci, int pin); > + > // Return the global irq number corresponding to a host bus device irq pin. > -static int pci_slot_get_irq(struct pci_device *pci, int pin) > +static int piix_pci_slot_get_irq(struct pci_device *pci, int pin) > { > int slot_addend = 0; > > @@ -104,6 +106,33 @@ static int pci_slot_get_irq(struct pci_device *pci, int > pin) > return pci_irqs[(pin - 1 + slot_addend) & 3]; > } > > +static int mch_pci_slot_get_irq(struct pci_device *pci, int pin) > +{ > + int irq, slot_addend = 0; > + > + while (pci->parent != NULL) { > + slot_addend += pci_bdf_to_dev(pci->bdf); > + pci = pci->parent; > + } > + slot_addend += pci_bdf_to_dev(pci->bdf); > + > + switch (slot_addend) {
Nak, I'm not accounting for the bridges properly here. > + /* Slots 0-24 rotate slot:pin mapping similar to piix above, but > + with a different starting index - see q35-acpi-dsdt.dsl */ > + case 0 ... 24: > + irq = pci_irqs[(pin - 1 + slot_addend) & 3]; > + break; > + /* Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H) */ > + case 25 ... 31: > + irq = pci_irqs[pin - 1]; > + break; > + default: > + irq = 0; > + } > + > + return irq; > +} > + > /* PIIX3/PIIX4 PCI to ISA bridge */ > static void piix_isa_bridge_init(struct pci_device *pci, void *arg) > { > @@ -292,6 +321,8 @@ void i440fx_mem_addr_init(struct pci_device *dev, void > *arg) > pcimem_start = 0x80000000; > else if (RamSize <= 0xc0000000) > pcimem_start = 0xc0000000; > + > + pci_slot_get_irq = piix_pci_slot_get_irq; > } > > void mch_mem_addr_init(struct pci_device *dev, void *arg) > @@ -310,6 +341,8 @@ void mch_mem_addr_init(struct pci_device *dev, void *arg) > > /* setup pci i/o window (above mmconfig) */ > pcimem_start = addr + size; > + > + pci_slot_get_irq = mch_pci_slot_get_irq; > } > > static const struct pci_device_id pci_platform_tbl[] = { > _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios