summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2021-05-07 14:25:09 -0600
committerFelix Held <felix-coreboot@felixheld.de>2021-05-09 18:09:05 +0000
commit7502e10fdfe4085c5f7d03b0b29d0f7fb9b390fe (patch)
tree1ad2caa0d9719b6c7f54603bc0a1ad378540ff32 /src/soc
parent1d1dbc4cfabf569b7d352dbcb5cee686fd5882d5 (diff)
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 <rrangel@chromium.org> Change-Id: I926430074acb969ceb11fdb60ab56dcf91ac4c76 Reviewed-on: https://review.coreboot.org/c/coreboot/+/52917 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/amd/common/block/include/amdblocks/amd_pci_util.h4
-rw-r--r--src/soc/amd/common/block/pci/Makefile.inc9
-rw-r--r--src/soc/amd/common/block/pci/acpi_prt.c206
3 files changed, 217 insertions, 2 deletions
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 <types.h>
#include <soc/amd_pci_int_defs.h>
+#include <device/device.h>
/* 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 <acpi/acpi.h>
+#include <acpi/acpigen.h>
+#include <acpi/acpigen_pci.h>
+#include <amdblocks/amd_pci_util.h>
+#include <arch/ioapic.h>
+#include <console/console.h>
+#include <device/device.h>
+
+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);
+}