From 425e421e8c58f600a534e0850bcfa80dbd2d2cac Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 15 Feb 2024 16:30:16 +0100 Subject: soc/intel/xeon_sp: Locate PCI devices by Ven/Dev ID Since the ACPI code is looking for VtdBars, that only appear on Vtd devices, search for the Vtd device in devicetree. With the previous commit the VtdBar is now exposed as a resource on the Vtd device and thus can easily be accessed and used. Drop the FSP HOB parsing and just use coreboot native functions. Allows the code to work with multiple PCI segment groups. Change-Id: I2c752dc595ac4c901f2b3a96718e256e413c76a7 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/80551 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans Reviewed-by: Shuo Liu --- src/soc/intel/xeon_sp/uncore_acpi.c | 79 +++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c index a9a5bac494..5ee9087040 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi.c +++ b/src/soc/intel/xeon_sp/uncore_acpi.c @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -18,7 +20,6 @@ #include #include #include - #include "chip.h" /* NUMA related ACPI table generation. SRAT, SLIT, etc */ @@ -382,26 +383,39 @@ static unsigned long acpi_create_drhd(unsigned long current, int socket, static unsigned long acpi_create_atsr(unsigned long current, const IIO_UDS *hob) { + struct device *child, *dev; + struct resource *resource; + + /* + * The assumption made here is that the host bridges on a socket share the + * PCI segment group and thus only one ATSR header needs to be emitted for + * a single socket. + * This is easier than to sort the host bridges by PCI segment group first + * and then generate one ATSR header for every new segment. + */ for (int socket = 0, iio = 0; iio < hob->PlatformData.numofIIO; ++socket) { if (!soc_cpu_is_enabled(socket)) continue; iio++; - - uint32_t pcie_seg = hob->PlatformData.CpuQpiInfo[socket].PcieSegment; unsigned long tmp = current; bool first = true; - IIO_RESOURCE_INSTANCE iio_resource = - hob->PlatformData.IIO_resource[socket]; - for (int stack = 0; stack < MAX_LOGIC_IIO_STACK; ++stack) { - uint32_t bus = iio_resource.StackRes[stack].BusBase; - uint32_t vtd_base = iio_resource.StackRes[stack].VtdBarAddress; - if (!vtd_base) + dev = NULL; + while ((dev = dev_find_device(PCI_VID_INTEL, MMAP_VTD_CFG_REG_DEVID, dev))) { + /* Only add devices for the current socket */ + if (iio_pci_domain_socket_from_dev(dev) != socket) continue; - uint64_t vtd_mmio_cap = read64p(vtd_base + VTD_EXT_CAP_LOW); - printk(BIOS_SPEW, "%s socket: %d, stack: %d, bus: 0x%x, vtd_base: 0x%x, " + /* See if there is a resource with the appropriate index. */ + resource = probe_resource(dev, VTD_BAR_CSR); + if (!resource) + continue; + int stack = iio_pci_domain_stack_from_dev(dev); + + uint64_t vtd_mmio_cap = read64(res2mmio(resource, VTD_EXT_CAP_LOW, 0)); + printk(BIOS_SPEW, "%s socket: %d, stack: %d, bus: 0x%x, vtd_base: %p, " "vtd_mmio_cap: 0x%llx\n", - __func__, socket, stack, bus, vtd_base, vtd_mmio_cap); + __func__, socket, stack, dev->upstream->secondary, + res2mmio(resource, 0, 0), vtd_mmio_cap); // ATSR is applicable only for platform supporting device IOTLBs // through the VT-d extended capability register @@ -409,17 +423,15 @@ static unsigned long acpi_create_atsr(unsigned long current, const IIO_UDS *hob) if ((vtd_mmio_cap & 0x4) == 0) // BIT 2 continue; - if (bus == 0) + if (dev->upstream->secondary == 0 && dev->upstream->segment_group == 0) continue; - struct device *dev = pcidev_path_on_bus(bus, PCI_DEVFN(0, 0)); - while (dev) { - if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) - current += + for (child = dev->upstream->children; child; child = child->sibling) { + if ((child->hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) + continue; + current += acpi_create_dmar_ds_pci_br_for_port( - current, dev, pcie_seg, true, &first); - - dev = dev->sibling; + current, child, child->upstream->segment_group, true, &first); } } if (tmp != current) @@ -463,24 +475,21 @@ static unsigned long acpi_create_rmrr(unsigned long current) static unsigned long acpi_create_rhsa(unsigned long current) { - const IIO_UDS *hob = get_iio_uds(); - - for (int socket = 0, iio = 0; iio < hob->PlatformData.numofIIO; ++socket) { - if (!soc_cpu_is_enabled(socket)) + struct device *dev = NULL; + struct resource *resource; + int socket; + + while ((dev = dev_find_device(PCI_VID_INTEL, MMAP_VTD_CFG_REG_DEVID, dev))) { + /* See if there is a resource with the appropriate index. */ + resource = probe_resource(dev, VTD_BAR_CSR); + if (!resource) continue; - iio++; - IIO_RESOURCE_INSTANCE iio_resource = - hob->PlatformData.IIO_resource[socket]; - for (int stack = 0; stack < MAX_LOGIC_IIO_STACK; ++stack) { - uint32_t vtd_base = iio_resource.StackRes[stack].VtdBarAddress; - if (!vtd_base) - continue; + socket = iio_pci_domain_socket_from_dev(dev); - printk(BIOS_DEBUG, "[Remapping Hardware Static Affinity] Base Address: 0x%x, " - "Proximity Domain: 0x%x\n", vtd_base, socket); - current += acpi_create_dmar_rhsa(current, vtd_base, socket); - } + printk(BIOS_DEBUG, "[Remapping Hardware Static Affinity] Base Address: %p, " + "Proximity Domain: 0x%x\n", res2mmio(resource, 0, 0), socket); + current += acpi_create_dmar_rhsa(current, (uintptr_t)res2mmio(resource, 0, 0), socket); } return current; -- cgit v1.2.3