From 7502e10fdfe4085c5f7d03b0b29d0f7fb9b390fe Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Fri, 7 May 2021 14:25:09 -0600 Subject: soc/amd/common/block/pci: Implement acpigen_write_pci_{GNB,FCH}_PRT This is loosely based off of picasso/pcie_gpp.c. This version uses the acpigen_write_PRT_X methods to write the actual records. There are also two functions, 1 for using the GNB, and one for using the FCH. The FCH one is useful when the GNB IO-APIC has not been initialized. BUG=b:184766519 TEST=Dump guybrush ACPI and verify it looks correct Signed-off-by: Raul E Rangel Change-Id: I926430074acb969ceb11fdb60ab56dcf91ac4c76 Reviewed-on: https://review.coreboot.org/c/coreboot/+/52917 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- .../common/block/include/amdblocks/amd_pci_util.h | 4 + src/soc/amd/common/block/pci/Makefile.inc | 9 +- src/soc/amd/common/block/pci/acpi_prt.c | 206 +++++++++++++++++++++ 3 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 src/soc/amd/common/block/pci/acpi_prt.c (limited to 'src/soc/amd') diff --git a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h index 83922c9468..0a4061f631 100644 --- a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h +++ b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h @@ -5,6 +5,7 @@ #include #include +#include /* FCH index/data registers */ #define PCI_INTR_INDEX 0xc00 @@ -60,4 +61,7 @@ const struct pci_routing_info *get_pci_routing_info(unsigned int devfn); unsigned int pci_calculate_irq(const struct pci_routing_info *routing_info, unsigned int pin); +void acpigen_write_pci_GNB_PRT(const struct device *dev); +void acpigen_write_pci_FCH_PRT(const struct device *dev); + #endif /* AMD_BLOCK_PCI_UTIL_H */ diff --git a/src/soc/amd/common/block/pci/Makefile.inc b/src/soc/amd/common/block/pci/Makefile.inc index 5df641b1d9..8c7a9899ae 100644 --- a/src/soc/amd/common/block/pci/Makefile.inc +++ b/src/soc/amd/common/block/pci/Makefile.inc @@ -1,5 +1,10 @@ -ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PCI) += amd_pci_util.c -ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PCI) += pci_routing_info.c +ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_PCI),y) + +ramstage-y += amd_pci_util.c +ramstage-y += pci_routing_info.c +ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi_prt.c + +endif # CONFIG_SOC_AMD_COMMON_BLOCK_PCI ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_PCI_MMCONF),y) diff --git a/src/soc/amd/common/block/pci/acpi_prt.c b/src/soc/amd/common/block/pci/acpi_prt.c new file mode 100644 index 0000000000..c4c50f5b6e --- /dev/null +++ b/src/soc/amd/common/block/pci/acpi_prt.c @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include +#include + +static void acpigen_write_PRT_GSI(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) { + /* GNB IO-APIC is located after the FCH IO-APIC */ + irq = IO_APIC_INTERRUPTS; + irq += pci_calculate_irq(routing_info, i); + + acpigen_write_PRT_GSI_entry( + 0, /* There is only one device attached to the bridge */ + i, /* pin */ + irq); + } + acpigen_pop_len(); /* Package - APIC Routing */ +} + +static void acpigen_write_PRT_PIC(const struct pci_routing_info *routing_info) +{ + unsigned int irq; + char link_template[] = "\\_SB.INTX"; + + acpigen_write_package(4); /* Package - PIC Routing */ + for (unsigned int i = 0; i < 4; ++i) { + irq = pci_calculate_irq(routing_info, i); + + link_template[8] = 'A' + (irq % 8); + + acpigen_write_PRT_source_entry( + 0, /* There is only one device attached to the bridge */ + i, /* pin */ + link_template /* Source */, + 0 /* Source Index */); + } + acpigen_pop_len(); /* Package - PIC Routing */ +} + +/* + * This method writes a PCI _PRT table that uses the GNB IO-APIC / PIC : + * Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table + * { + * If (PICM) + * { + * Return (Package (0x04) + * { + * Package (0x04) + * { + * 0x0000FFFF, + * 0x00, + * 0x00, + * 0x00000034 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x01, + * 0x00, + * 0x00000035 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x02, + * 0x00, + * 0x00000036 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x03, + * 0x00, + * 0x00000037 + * } + * }) + * } + * Else + * { + * Return (Package (0x04) + * { + * Package (0x04) + * { + * 0x0000FFFF, + * 0x00, + * \_SB.INTA, + * 0x00000000 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x01, + * \_SB.INTB, + * 0x00000000 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x02, + * \_SB.INTC, + * 0x00000000 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x03, + * \_SB.INTD, + * 0x00000000 + * } + * }) + * } + * } + */ +void acpigen_write_pci_GNB_PRT(const struct device *dev) +{ + const struct pci_routing_info *routing_info = + get_pci_routing_info(dev->path.pci.devfn); + + if (!routing_info) + return; + + acpigen_write_method("_PRT", 0); + + /* If (PICM) */ + acpigen_write_if(); + acpigen_emit_namestring("PICM"); + + /* Return (Package{...}) */ + acpigen_emit_byte(RETURN_OP); + acpigen_write_PRT_GSI(routing_info); + + /* Else */ + acpigen_write_else(); + + /* Return (Package{...}) */ + acpigen_emit_byte(RETURN_OP); + acpigen_write_PRT_PIC(routing_info); + + acpigen_pop_len(); /* End Else */ + + acpigen_pop_len(); /* Method */ +} + + /* + * This method writes a PCI _PRT table that uses the FCH IO-APIC / PIC : + * Name (_PRT, Package (0x04) + * { + * Package (0x04) + * { + * 0x0000FFFF, + * 0x00, + * \_SB.INTA, + * 0x00000000 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x01, + * \_SB.INTB, + * 0x00000000 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x02, + * \_SB.INTC, + * 0x00000000 + * }, + * + * Package (0x04) + * { + * 0x0000FFFF, + * 0x03, + * \_SB.INTD, + * 0x00000000 + * } + * }) + */ +void acpigen_write_pci_FCH_PRT(const struct device *dev) +{ + const struct pci_routing_info *routing_info = + get_pci_routing_info(dev->path.pci.devfn); + + if (!routing_info) + return; + + acpigen_write_name("_PRT"); + acpigen_write_PRT_PIC(routing_info); +} -- cgit v1.2.3