summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Rudolph <patrick.rudolph@9elements.com>2024-02-15 16:30:16 +0100
committerPatrick Rudolph <patrick.rudolph@9elements.com>2024-02-23 07:45:33 +0000
commit425e421e8c58f600a534e0850bcfa80dbd2d2cac (patch)
treeab9eb52063305021ea6d67258293e68a02cac2e8
parent9fa4048e2deccd63d0e225152ae6a06e8c767865 (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.c79
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;