Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/85195?usp=email )
Change subject: soc/amd/phoenix/pci_irq_routing.c: Populate PCI IRQ routing table ......................................................................
soc/amd/phoenix/pci_irq_routing.c: Populate PCI IRQ routing table
Populate the PCI bridge IRQ routing table for Phoenix from the SMN registers to replace the stub implementation. The base addresses are copied from Genoa OpenSIL headers, which also correspond to Phoenix.
TEST=Successful build and boot. There are no longer warnings about not being able to write PCI IRQ assignments.
Before applying patch:
[NOTE ] get_pci_routing_table stub: returning empty IRQ routing table [WARN ] Can't write PCI IRQ assignments because 'mainboard_pirq_data' structure does not exist
After applying patch:
[DEBUG] 01.1: group: 0, swizzle: 0, irq: 0 [DEBUG] 01.2: group: 1, swizzle: 0, irq: 0 [DEBUG] 01.4: group: 0, swizzle: 2, irq: 2 [DEBUG] 01.5: group: 3, swizzle: 0, irq: 0 [DEBUG] 01.6: group: 4, swizzle: 0, irq: 0 [DEBUG] 02.5: group: 5, swizzle: 0, irq: 0 [DEBUG] 02.4: group: 0, swizzle: 1, irq: 2 [DEBUG] 01.3: group: 1, swizzle: 1, irq: 2 [DEBUG] 02.1: group: 2, swizzle: 2, irq: 3 [DEBUG] 02.2: group: 1, swizzle: 2, irq: 2 [DEBUG] 02.3: group: 3, swizzle: 2, irq: 1 [DEBUG] 02.6: group: 4, swizzle: 2, irq: 1 [DEBUG] 03.1: group: 2, swizzle: 0, irq: 0 [DEBUG] 03.2: group: 5, swizzle: 0, irq: 1 [DEBUG] 03.3: group: 5, swizzle: 2, irq: 1 [DEBUG] 03.4: group: 5, swizzle: 2, irq: 1 [DEBUG] 04.1: group: 2, swizzle: 2, irq: 1 [DEBUG] 08.1: group: 3, swizzle: 2, irq: 4 [DEBUG] 08.2: group: 4, swizzle: 2, irq: 4 [DEBUG] 08.3: group: 5, swizzle: 2, irq: 4 [DEBUG] PCI_CFG IRQ: Write PCI config space IRQ assignments [DEBUG] PCI_CFG IRQ: Finished writing PCI config space IRQ assignments
Change-Id: Id014ff3e675831eec42bc46c0a76271341e0e3e4 Signed-off-by: Nicolas Kochlowski nickkochlowski@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/85195 Reviewed-by: Felix Held felix-coreboot@felixheld.de Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/soc/amd/phoenix/pci_irq_routing.c 1 file changed, 65 insertions(+), 4 deletions(-)
Approvals: build bot (Jenkins): Verified Felix Held: Looks good to me, approved
diff --git a/src/soc/amd/phoenix/pci_irq_routing.c b/src/soc/amd/phoenix/pci_irq_routing.c index 5c891c2..71202fa 100644 --- a/src/soc/amd/phoenix/pci_irq_routing.c +++ b/src/soc/amd/phoenix/pci_irq_routing.c @@ -1,14 +1,75 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/amd_pci_util.h> +#include <amdblocks/smn.h> #include <console/console.h> +#include <device/pci_def.h> #include <types.h>
+#define MAX_BRIDGES 20 + +#define SMN_DEVICE_REMAP_BASE_ADDR 0x13b100b8 +#define SMN_PCI_INTERRUPT_ROUTING_BASE_ADDR 0x14300040 + +union iohc_nb_prog_device_remap { + struct { + uint32_t fn_num : 3; /* [ 2.. 0] */ + uint32_t dev_num : 5; /* [ 7.. 3] */ + uint32_t : 24; /* [31.. 8] */ + }; + uint32_t raw; +}; + +union ioapic_br_irq_routing { + struct { + uint32_t intr_grp : 3; /* [ 2.. 0] */ + uint32_t : 1; /* [ 3.. 3] */ + uint32_t intr_swz : 2; /* [ 5.. 4] */ + uint32_t : 10; /* [15.. 6] */ + uint32_t intr_map : 5; /* [20..16] */ + uint32_t : 11; /* [31..21] */ + }; + uint32_t raw; +}; + const struct pci_routing_info *get_pci_routing_table(size_t *entries) { - /* TODO: still needs to be implemented for the non-FSP case */ - printk(BIOS_NOTICE, "%s stub: returning empty IRQ routing table\n", __func__); + static bool table_initialized; + static struct pci_routing_info routing_table[MAX_BRIDGES];
- *entries = 0; - return NULL; + union iohc_nb_prog_device_remap dev_remap; + union ioapic_br_irq_routing ioapic_routing; + + if (table_initialized) { + *entries = MAX_BRIDGES; + return routing_table; + } + + /* + * For Phoenix, the logical and physical bridge numbers map 1:1, which may not be + * the case for other SoCs. + */ + for (size_t i = 0; i < MAX_BRIDGES; ++i) { + dev_remap.raw = smn_read32(SMN_DEVICE_REMAP_BASE_ADDR + + sizeof(uint32_t) * i); + routing_table[i].devfn = (dev_remap.dev_num << 3) | dev_remap.fn_num; + } + + for (size_t i = 0; i < MAX_BRIDGES; ++i) { + ioapic_routing.raw = smn_read32(SMN_PCI_INTERRUPT_ROUTING_BASE_ADDR + + sizeof(uint32_t) * i); + routing_table[i].group = ioapic_routing.intr_grp; + routing_table[i].swizzle = ioapic_routing.intr_swz; + routing_table[i].bridge_irq = ioapic_routing.intr_map; + printk(BIOS_DEBUG, "%02x.%x: group: %u, swizzle: %u, irq: %u\n", + PCI_SLOT(routing_table[i].devfn), + PCI_FUNC(routing_table[i].devfn), + routing_table[i].group, + routing_table[i].swizzle, + routing_table[i].bridge_irq); + } + table_initialized = true; + + *entries = MAX_BRIDGES; + return routing_table; }