[SeaBIOS] [PATCH 2/2] q35: Add new PCI slot to irq routing function
Alex Williamson
alex.williamson at redhat.com
Tue Jan 22 23:21:16 CET 2013
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.williamson at 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[] = {
>
More information about the SeaBIOS
mailing list