Arthur Heymans has submitted this change. ( https://review.coreboot.org/c/coreboot/+/79878?usp=email )
Change subject: soc/intel/xeon_sp: Initial support for PCI multi segment groups ......................................................................
soc/intel/xeon_sp: Initial support for PCI multi segment groups
Add PCI enumeration support by reading the PCIeSegment reported in the FSP HOB and add it when creating the PCI domain for each stack.
The PCI enumeration will be able to scan the additional PCI segment groups and properly handle those devices.
TEST=Booted on ibm/sbp1 with multiple PCI segment groups enabled to ubuntu 22.04. TEST=intel/archercity CRB
Change-Id: I0ba5e426123234979d746d3bdfc1ddfbd71c3447 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/79878 Reviewed-by: Arthur Heymans arthur@aheymans.xyz Reviewed-by: Nico Huber nico.h@gmx.de Reviewed-by: Shuo Liu shuo.liu@intel.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/soc/intel/xeon_sp/chip_common.c M src/soc/intel/xeon_sp/include/soc/chip_common.h M src/soc/intel/xeon_sp/spr/ioat.c 3 files changed, 36 insertions(+), 23 deletions(-)
Approvals: Shuo Liu: Looks good to me, approved Arthur Heymans: Looks good to me, approved build bot (Jenkins): Verified Nico Huber: Looks good to me, but someone else must approve
diff --git a/src/soc/intel/xeon_sp/chip_common.c b/src/soc/intel/xeon_sp/chip_common.c index ef504d7..bec0d93 100644 --- a/src/soc/intel/xeon_sp/chip_common.c +++ b/src/soc/intel/xeon_sp/chip_common.c @@ -264,8 +264,9 @@ };
static void soc_create_domains(const union xeon_domain_path dp, struct bus *upstream, - int bus_base, int bus_limit, const char *type, - struct device_operations *ops) + int bus_base, int bus_limit, const char *type, + struct device_operations *ops, + const size_t pci_segment_group) { struct device_path path; init_xeon_domain_path(&path, dp.socket, dp.stack, bus_base); @@ -281,14 +282,15 @@ bus->secondary = bus_base; bus->subordinate = bus_base; bus->max_subordinate = bus_limit; + bus->segment_group = pci_segment_group; }
static void soc_create_pcie_domains(const union xeon_domain_path dp, struct bus *upstream, - const STACK_RES *sr) + const STACK_RES *sr, const size_t pci_segment_group) { soc_create_domains(dp, upstream, sr->BusBase, sr->BusLimit, DOMAIN_TYPE_PCIE, - &iio_pcie_domain_ops); + &iio_pcie_domain_ops, pci_segment_group); }
/* @@ -297,15 +299,15 @@ * with 3rd gen Xeon-SP the UBOX devices are located on their own IIO. */ static void soc_create_ubox_domains(const union xeon_domain_path dp, struct bus *upstream, - const STACK_RES *sr) + const STACK_RES *sr, const size_t pci_segment_group) { /* Only expect 2 UBOX buses here */ assert(sr->BusBase + 1 == sr->BusLimit);
soc_create_domains(dp, upstream, sr->BusBase, sr->BusBase, DOMAIN_TYPE_UBX0, - &ubox_pcie_domain_ops); + &ubox_pcie_domain_ops, pci_segment_group); soc_create_domains(dp, upstream, sr->BusLimit, sr->BusLimit, DOMAIN_TYPE_UBX1, - &ubox_pcie_domain_ops); + &ubox_pcie_domain_ops, pci_segment_group); }
#if CONFIG(SOC_INTEL_HAS_CXL) @@ -356,15 +358,16 @@ };
void soc_create_cxl_domains(const union xeon_domain_path dp, struct bus *bus, - const STACK_RES *sr) + const STACK_RES *sr, const size_t pci_segment_group) { assert(sr->BusBase + 1 <= sr->BusLimit); + /* 1st domain contains PCIe RCiEPs */ soc_create_domains(dp, bus, sr->BusBase, sr->BusBase, DOMAIN_TYPE_PCIE, - &iio_pcie_domain_ops); + &iio_pcie_domain_ops, pci_segment_group); /* 2nd domain contains CXL 1.1 end-points */ soc_create_domains(dp, bus, sr->BusBase + 1, sr->BusLimit, DOMAIN_TYPE_CXL, - &iio_cxl_domain_ops); + &iio_cxl_domain_ops, pci_segment_group); } #endif //CONFIG(SOC_INTEL_HAS_CXL)
@@ -382,6 +385,8 @@ continue; for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) { const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x]; + const size_t seg = hob->PlatformData.CpuQpiInfo[s].PcieSegment; + if (ri->BusBase > ri->BusLimit) continue;
@@ -390,13 +395,13 @@ dn.stack = x;
if (is_ubox_stack_res(ri)) - soc_create_ubox_domains(dn, root_bus, ri); + soc_create_ubox_domains(dn, root_bus, ri, seg); else if (CONFIG(SOC_INTEL_HAS_CXL) && is_iio_cxl_stack_res(ri)) - soc_create_cxl_domains(dn, root_bus, ri); + soc_create_cxl_domains(dn, root_bus, ri, seg); else if (is_pcie_iio_stack_res(ri)) - soc_create_pcie_domains(dn, root_bus, ri); + soc_create_pcie_domains(dn, root_bus, ri, seg); else if (CONFIG(HAVE_IOAT_DOMAINS) && is_ioat_iio_stack_res(ri)) - soc_create_ioat_domains(dn, root_bus, ri); + soc_create_ioat_domains(dn, root_bus, ri, seg); } } } diff --git a/src/soc/intel/xeon_sp/include/soc/chip_common.h b/src/soc/intel/xeon_sp/include/soc/chip_common.h index 53deffa..2b2d5de 100644 --- a/src/soc/intel/xeon_sp/include/soc/chip_common.h +++ b/src/soc/intel/xeon_sp/include/soc/chip_common.h @@ -53,8 +53,12 @@ void iio_cxl_domain_read_resources(struct device *dev); void attach_iio_stacks(void);
-void soc_create_ioat_domains(union xeon_domain_path path, struct bus *bus, const STACK_RES *sr); -void soc_create_cxl_domains(const union xeon_domain_path dp, struct bus *bus, const STACK_RES *sr); +void soc_create_cxl_domains(const union xeon_domain_path dp, struct bus *bus, + const STACK_RES *sr, const size_t pci_segment_group); +void soc_create_ioat_domains(union xeon_domain_path path, + struct bus *bus, + const STACK_RES *sr, + const size_t pci_segment_group);
struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device); struct device *dev_find_all_devices_on_socket(uint8_t socket, diff --git a/src/soc/intel/xeon_sp/spr/ioat.c b/src/soc/intel/xeon_sp/spr/ioat.c index 2e3baa3..cdf9834 100644 --- a/src/soc/intel/xeon_sp/spr/ioat.c +++ b/src/soc/intel/xeon_sp/spr/ioat.c @@ -34,7 +34,7 @@ const unsigned int bus_base, const unsigned int bus_limit, const resource_t mem32_base, const resource_t mem32_limit, const resource_t mem64_base, const resource_t mem64_limit, - const char *prefix) + const char *prefix, const size_t pci_segment_group) { union xeon_domain_path new_path = { .domain_path = dp.domain_path @@ -58,6 +58,7 @@ bus->secondary = bus_base; bus->subordinate = bus->secondary; bus->max_subordinate = bus_limit; + bus->segment_group = pci_segment_group;
unsigned int index = 0;
@@ -78,7 +79,10 @@ } }
-void soc_create_ioat_domains(const union xeon_domain_path path, struct bus *const bus, const STACK_RES *const sr) +void soc_create_ioat_domains(const union xeon_domain_path path, + struct bus *const bus, + const STACK_RES *const sr, + const size_t pci_segment_group) { if (sr->BusLimit < sr->BusBase + HQM_BUS_OFFSET + HQM_RESERVED_BUS) { printk(BIOS_WARNING, @@ -104,7 +108,7 @@ bus_base = sr->BusBase + CPM_BUS_OFFSET; bus_limit = bus_base + CPM_RESERVED_BUS; create_ioat_domain(path, bus, bus_base, bus_limit, -1, 0, mem64_base, mem64_limit, - DOMAIN_TYPE_CPM0); + DOMAIN_TYPE_CPM0, pci_segment_group);
/* HQM0 */ mem64_base = mem64_limit + 1; @@ -112,7 +116,7 @@ bus_base = sr->BusBase + HQM_BUS_OFFSET; bus_limit = bus_base + HQM_RESERVED_BUS; create_ioat_domain(path, bus, bus_base, bus_limit, -1, 0, mem64_base, mem64_limit, - DOMAIN_TYPE_HQM0); + DOMAIN_TYPE_HQM0, pci_segment_group);
/* CPM1 (optional) */ mem64_base = mem64_limit + 1; @@ -121,7 +125,7 @@ bus_limit = bus_base + CPM_RESERVED_BUS; if (bus_limit <= sr->BusLimit) create_ioat_domain(path, bus, bus_base, bus_limit, -1, 0, mem64_base, mem64_limit, - DOMAIN_TYPE_CPM1); + DOMAIN_TYPE_CPM1, pci_segment_group);
/* HQM1 (optional) */ mem64_base = mem64_limit + 1; @@ -130,7 +134,7 @@ bus_limit = bus_base + HQM_RESERVED_BUS; if (bus_limit <= sr->BusLimit) create_ioat_domain(path, bus, bus_base, bus_limit, -1, 0, mem64_base, mem64_limit, - DOMAIN_TYPE_HQM1); + DOMAIN_TYPE_HQM1, pci_segment_group);
/* DINO */ mem64_base = mem64_limit + 1; @@ -138,5 +142,5 @@ bus_base = sr->BusBase; bus_limit = bus_base; create_ioat_domain(path, bus, bus_base, bus_limit, sr->PciResourceMem32Base, sr->PciResourceMem32Limit, - mem64_base, mem64_limit, DOMAIN_TYPE_DINO); + mem64_base, mem64_limit, DOMAIN_TYPE_DINO, pci_segment_group); }