diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2024-03-08 09:49:15 +0100 |
---|---|---|
committer | Patrick Rudolph <patrick.rudolph@9elements.com> | 2024-03-19 09:18:20 +0000 |
commit | d425e881e339e8f92c48237d1e212275c5a7cdc3 (patch) | |
tree | 2a78c4f7b9333c99c968949ea279c601b38a2c24 | |
parent | f95565311adfd98108a4ece9a2df5de56a3c890d (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>
-rw-r--r-- | src/soc/intel/xeon_sp/uncore_acpi.c | 47 |
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; } |