From c657ab9750dd040db2af9011d32c112bcdca8a5d Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Mon, 1 Mar 2021 16:53:22 -0700 Subject: soc/intel/common/block/irq: Add support for intel_write_pci0_PRT Add a new function to fill out the data structures necessary to generate a _PRT table. BUG=b:130217151, b:171580862, b:176858827 Signed-off-by: Tim Wawrzynczak Change-Id: I21a4835890ca03bff83ed0e8791441b3af54cb62 Reviewed-on: https://review.coreboot.org/c/coreboot/+/51159 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- .../intel/common/block/include/intelblocks/irq.h | 2 + src/soc/intel/common/block/irq/Kconfig | 1 + src/soc/intel/common/block/irq/irq.c | 51 ++++++++++++++++++++++ 3 files changed, 54 insertions(+) (limited to 'src') diff --git a/src/soc/intel/common/block/include/intelblocks/irq.h b/src/soc/intel/common/block/include/intelblocks/irq.h index 1c267052c8..727020a5df 100644 --- a/src/soc/intel/common/block/include/intelblocks/irq.h +++ b/src/soc/intel/common/block/include/intelblocks/irq.h @@ -44,4 +44,6 @@ struct pci_irq_entry { const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *constraints, size_t num_slots); +void generate_pin_irq_map(const struct pci_irq_entry *entries); + #endif /* SOC_INTEL_COMMON_IRQ_H */ diff --git a/src/soc/intel/common/block/irq/Kconfig b/src/soc/intel/common/block/irq/Kconfig index d4d9ab1b03..ab6fc509cb 100644 --- a/src/soc/intel/common/block/irq/Kconfig +++ b/src/soc/intel/common/block/irq/Kconfig @@ -1,6 +1,7 @@ config SOC_INTEL_COMMON_BLOCK_IRQ bool select SOC_INTEL_COMMON_BLOCK_GPIO + select SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN help Intel common block support for assigning PCI IRQs dynamically. This allows coreboot to control the IRQ assignments. They are passed to the diff --git a/src/soc/intel/common/block/irq/irq.c b/src/soc/intel/common/block/irq/irq.c index 0a62bb58c9..eb4daf9a14 100644 --- a/src/soc/intel/common/block/irq/irq.c +++ b/src/soc/intel/common/block/irq/irq.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -343,3 +344,53 @@ const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *c return entries; } + +static enum pirq irq_to_pirq(unsigned int irq) +{ + if (irq >= MIN_SHARED_IRQ && irq <= MAX_SHARED_IRQ) + return (enum pirq)(irq - MIN_SHARED_IRQ + PIRQ_A); + else + /* + * Unknown if devices that require unique IRQs will + * even work in legacy PIC mode, given they cannot map + * to a PIRQ, therefore skip adding an entry. + */ + return PIRQ_INVALID; +} + +void generate_pin_irq_map(const struct pci_irq_entry *entries) +{ + struct slot_pin_irq_map *pin_irq_map; + const uint8_t *legacy_pirq_routing; + struct pic_pirq_map pirq_map = {0}; + size_t map_count = 0; + size_t pirq_routes; + size_t i; + + pin_irq_map = calloc(MAX_SLOTS, sizeof(struct slot_pin_irq_map) * PCI_INT_MAX); + + pirq_map.type = PIRQ_GSI; + legacy_pirq_routing = lpc_get_pic_pirq_routing(&pirq_routes); + for (i = 0; i < PIRQ_COUNT && i < pirq_routes; i++) + pirq_map.gsi[i] = legacy_pirq_routing[i]; + + const struct pci_irq_entry *entry = entries; + while (entry) { + const unsigned int slot = PCI_SLOT(entry->devfn); + + if (is_slot_pin_assigned(pin_irq_map, map_count, slot, entry->pin)) { + entry = entry->next; + continue; + } + + pin_irq_map[map_count].slot = slot; + pin_irq_map[map_count].pin = entry->pin; + pin_irq_map[map_count].apic_gsi = entry->irq; + pin_irq_map[map_count].pic_pirq = irq_to_pirq(entry->irq); + map_count++; + entry = entry->next; + } + + intel_write_pci0_PRT(pin_irq_map, map_count, &pirq_map); + free(pin_irq_map); +} -- cgit v1.2.3