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 <twawrzynczak@chromium.org>
Change-Id: I21a4835890ca03bff83ed0e8791441b3af54cb62
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51159
Reviewed-by: Furquan Shaikh <furquan@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Tim Wawrzynczak
2021-03-01 16:53:22 -07:00
parent b59980b54e
commit c657ab9750
3 changed files with 54 additions and 0 deletions

View File

@ -44,4 +44,6 @@ struct pci_irq_entry {
const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *constraints, const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *constraints,
size_t num_slots); size_t num_slots);
void generate_pin_irq_map(const struct pci_irq_entry *entries);
#endif /* SOC_INTEL_COMMON_IRQ_H */ #endif /* SOC_INTEL_COMMON_IRQ_H */

View File

@ -1,6 +1,7 @@
config SOC_INTEL_COMMON_BLOCK_IRQ config SOC_INTEL_COMMON_BLOCK_IRQ
bool bool
select SOC_INTEL_COMMON_BLOCK_GPIO select SOC_INTEL_COMMON_BLOCK_GPIO
select SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN
help help
Intel common block support for assigning PCI IRQs dynamically. This Intel common block support for assigning PCI IRQs dynamically. This
allows coreboot to control the IRQ assignments. They are passed to the allows coreboot to control the IRQ assignments. They are passed to the

View File

@ -6,6 +6,7 @@
#include <device/pci_def.h> #include <device/pci_def.h>
#include <intelblocks/gpio.h> #include <intelblocks/gpio.h>
#include <intelblocks/irq.h> #include <intelblocks/irq.h>
#include <intelblocks/lpc_lib.h>
#include <southbridge/intel/common/acpi_pirq_gen.h> #include <southbridge/intel/common/acpi_pirq_gen.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -343,3 +344,53 @@ const struct pci_irq_entry *assign_pci_irqs(const struct slot_irq_constraints *c
return entries; 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);
}