diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2024-02-15 16:30:16 +0100 |
---|---|---|
committer | Patrick Rudolph <patrick.rudolph@9elements.com> | 2024-02-23 07:45:33 +0000 |
commit | 425e421e8c58f600a534e0850bcfa80dbd2d2cac (patch) | |
tree | ab9eb52063305021ea6d67258293e68a02cac2e8 | |
parent | 9fa4048e2deccd63d0e225152ae6a06e8c767865 (diff) |
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 <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/80551
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Shuo Liu <shuo.liu@intel.com>
-rw-r--r-- | src/soc/intel/xeon_sp/uncore_acpi.c | 79 |
1 files 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 <device/mmio.h> #include <device/pci.h> #include <device/pciexp.h> +#include <device/pci_ids.h> #include <soc/acpi.h> +#include <soc/chip_common.h> #include <soc/hest.h> #include <soc/iomap.h> #include <soc/numa.h> @@ -18,7 +20,6 @@ #include <soc/soc_util.h> #include <soc/util.h> #include <intelblocks/p2sb.h> - #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; |