diff options
author | Raul E Rangel <rrangel@chromium.org> | 2021-05-07 14:25:09 -0600 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-05-09 18:09:05 +0000 |
commit | 7502e10fdfe4085c5f7d03b0b29d0f7fb9b390fe (patch) | |
tree | 1ad2caa0d9719b6c7f54603bc0a1ad378540ff32 /src/soc/amd/common/block/pci/acpi_prt.c | |
parent | 1d1dbc4cfabf569b7d352dbcb5cee686fd5882d5 (diff) | |
download | coreboot-7502e10fdfe4085c5f7d03b0b29d0f7fb9b390fe.tar.xz |
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/amd/common/block/pci/acpi_prt.c')
-rw-r--r-- | src/soc/amd/common/block/pci/acpi_prt.c | 206 |
1 files changed, 206 insertions, 0 deletions
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); +} |