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,
size_t num_slots);
void generate_pin_irq_map(const struct pci_irq_entry *entries);
#endif /* SOC_INTEL_COMMON_IRQ_H */

View File

@ -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

View File

@ -6,6 +6,7 @@
#include <device/pci_def.h>
#include <intelblocks/gpio.h>
#include <intelblocks/irq.h>
#include <intelblocks/lpc_lib.h>
#include <southbridge/intel/common/acpi_pirq_gen.h>
#include <stdlib.h>
#include <string.h>
@ -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);
}