summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Rudolph <patrick.rudolph@9elements.com>2024-03-08 09:49:15 +0100
committerPatrick Rudolph <patrick.rudolph@9elements.com>2024-03-19 09:18:20 +0000
commitd425e881e339e8f92c48237d1e212275c5a7cdc3 (patch)
tree2a78c4f7b9333c99c968949ea279c601b38a2c24 /src
parentf95565311adfd98108a4ece9a2df5de56a3c890d (diff)
soc/intel/xeon_sp: Add SATC PCI segment group support
For every PCI segment group generate a new SATC header. Allows to generate proper ACPI code when multiple PCI segment groups are enabled. TEST=Booted on ibm/sbp1 with multiple PCI segment groups. Properly generates multiple SATC headers. TEST=intel/archercity CRB Change-Id: I93b8ee05a7e6798e034f7a5da2c6883f0ee7a0e5 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81180 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src')
-rw-r--r--src/soc/intel/xeon_sp/uncore_acpi.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c
index 590bd3a76f..ef7233583d 100644
--- a/src/soc/intel/xeon_sp/uncore_acpi.c
+++ b/src/soc/intel/xeon_sp/uncore_acpi.c
@@ -509,16 +509,49 @@ static unsigned long xeonsp_create_satc(unsigned long current, struct device *do
/* SoC Integrated Address Translation Cache */
static unsigned long acpi_create_satc(unsigned long current)
{
- const unsigned long tmp = current;
+ unsigned long tmp = current, seg = ~0;
+ struct device *dev;
- // Add the SATC header
- current += acpi_create_dmar_satc(current, 0, 0);
+ /*
+ * Best case only PCI segment group count SATC headers are emitted, worst
+ * case for every SATC entry a new SATC header is being generated.
+ *
+ * The assumption made here is that the host bridges on a socket share the
+ * PCI segment group and thus only one SATC 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 SATC header for every new segment.
+ *
+ * With this assumption the best case scenario should always be used.
+ */
+ for (int socket = 0; socket < CONFIG_MAX_SOCKET; ++socket) {
+ if (!soc_cpu_is_enabled(socket))
+ continue;
- struct device *dev = NULL;
- while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)))
- current = xeonsp_create_satc(current, dev);
+ dev = NULL;
+ while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN))) {
+ /* Only add devices for the current socket */
+ if (iio_pci_domain_socket_from_dev(dev) != socket)
+ continue;
+
+ if (seg != dev->downstream->segment_group) {
+ // Close previous header
+ if (tmp != current)
+ acpi_dmar_satc_fixup(tmp, current);
+
+ seg = dev->downstream->segment_group;
+ tmp = current;
+ printk(BIOS_DEBUG, "[SATC Segment Header] "
+ "Flags: 0x%x, PCI segment group: %lx\n", 0, seg);
+ // Add the SATC header
+ current += acpi_create_dmar_satc(current, 0, seg);
+ }
+ current = xeonsp_create_satc(current, dev);
+ }
+ }
+ if (tmp != current)
+ acpi_dmar_satc_fixup(tmp, current);
- acpi_dmar_satc_fixup(tmp, current);
return current;
}