diff options
-rw-r--r-- | src/pciinit.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/pciinit.c b/src/pciinit.c index 857e8af..c670a2b 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,31 @@ 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, pin_addend = 0; + + while (pci->parent != NULL) { + pin_addend += pci_bdf_to_dev(pci->bdf); + pci = pci->parent; + } + slot = pci_bdf_to_dev(pci->bdf); + + switch (slot) { + /* 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 + pin_addend + slot) & 3]; + break; + /* Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H) */ + case 25 ... 31: + irq = pci_irqs[(pin - 1 + pin_addend) & 3]; + break; + } + + return irq; +} + /* PIIX3/PIIX4 PCI to ISA bridge */ static void piix_isa_bridge_init(struct pci_device *pci, void *arg) { @@ -292,6 +319,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 +339,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[] = { |