Naresh Solanki has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/76103?usp=email )
Change subject: soc/amd/common/block/pci: Generalise irq base calculation ......................................................................
soc/amd/common/block/pci: Generalise irq base calculation
Generalize IRQ base calculation for multiple IOMMU IO-APIC scenario.
Signed-off-by: Naresh Solanki Naresh.Solanki@9elements.com Change-Id: I2a8c4b54d7aa3d834cb8d86ee1ca10d7cd149b93 --- M src/soc/amd/common/block/pci/acpi_prt.c 1 file changed, 26 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/03/76103/1
diff --git a/src/soc/amd/common/block/pci/acpi_prt.c b/src/soc/amd/common/block/pci/acpi_prt.c index f748024..20e01a0 100644 --- a/src/soc/amd/common/block/pci/acpi_prt.c +++ b/src/soc/amd/common/block/pci/acpi_prt.c @@ -4,25 +4,23 @@ #include <acpi/acpigen.h> #include <acpi/acpigen_pci.h> #include <amdblocks/amd_pci_util.h> +#include <amdblocks/data_fabric.h> #include <arch/ioapic.h> #include <device/device.h>
-/* GNB IO-APIC is located after the FCH IO-APIC */ -#define FCH_IOAPIC_INTERRUPTS 24 -#define GNB_GSI_BASE FCH_IOAPIC_INTERRUPTS - -static void acpigen_write_PRT_GSI(const struct pci_routing_info *routing_info) +static void acpigen_write_PRT_GSI(uint16_t gsi_irq_base, const struct pci_routing_info *routing_info) { unsigned int irq;
acpigen_write_package(4); /* Package - APIC Routing */ for (unsigned int i = 0; i < 4; ++i) { - irq = pci_calculate_irq(routing_info, i); + irq = gsi_irq_base; + irq += pci_calculate_irq(routing_info, i);
acpigen_write_PRT_GSI_entry( 0, /* There is only one device attached to the bridge */ i, /* pin */ - GNB_GSI_BASE + irq); + irq); } acpigen_pop_len(); /* Package - APIC Routing */ } @@ -131,10 +129,30 @@ { const struct pci_routing_info *routing_info = get_pci_routing_info(dev->path.pci.devfn); + struct device *domain = NULL; + struct resource *res; + uint16_t gsi_irq_base;
if (!routing_info) return;
+ /* GNB IO-APIC is located after the FCH IO-APIC */ + gsi_irq_base = ioapic_get_max_vectors(VIO_APIC_VADDR); + + /* IRQs in the presence of multiple IOMMU IO-APICs */ + while ((domain = dev_find_path(domain, DEVICE_PATH_DOMAIN)) != NULL) { + + if (domain->link_list == dev->bus ) + break; + + res = probe_resource(domain, IOMMU_IOAPIC_IDX); + if (!res) + continue; + + gsi_irq_base += ioapic_get_max_vectors((u8 *)(uintptr_t)res->base); + } + printk(BIOS_DEBUG, "%s -> irq base: %x\n", dev_path(dev), gsi_irq_base); + acpigen_write_method("_PRT", 0);
/* If (PICM) */ @@ -143,7 +161,7 @@
/* Return (Package{...}) */ acpigen_emit_byte(RETURN_OP); - acpigen_write_PRT_GSI(routing_info); + acpigen_write_PRT_GSI(gsi_irq_base, routing_info);
/* Else */ acpigen_write_else();