Shuo Liu has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/81098?usp=email )
Change subject: soc/intel/xeon_sp: Further share domain creation logics in Xeon-SP ......................................................................
soc/intel/xeon_sp: Further share domain creation logics in Xeon-SP
With this patch, all domain creation logics are moved into the scope of attach_iio_stack/chip_common.c for the ease of maintenance and future SoC integration where the domain creation process for specific stack types might be overriden.
Additionally, the assumption of socket0/stack0 is a PCIe stack is not always true for future generation SoCs and hence this assumption is removed.
TEST=intel/archercity CRB
1. Boot to CentOS 9 Stream Cloud. 2. Compare PCIe enumeration and ACPI table generation logs before and and after this patch, no changes.
Change-Id: If06bb5ff41b5f04cef766cf29d38369c6022da79 Signed-off-by: Shuo Liu shuo.liu@intel.com --- M src/soc/intel/xeon_sp/chip_common.c M src/soc/intel/xeon_sp/cpx/chip.c M src/soc/intel/xeon_sp/include/soc/chip_common.h M src/soc/intel/xeon_sp/skx/chip.c M src/soc/intel/xeon_sp/spr/chip.c M src/soc/intel/xeon_sp/spr/ioat.c 6 files changed, 74 insertions(+), 77 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/98/81098/1
diff --git a/src/soc/intel/xeon_sp/chip_common.c b/src/soc/intel/xeon_sp/chip_common.c index 03ae70a..6645555 100644 --- a/src/soc/intel/xeon_sp/chip_common.c +++ b/src/soc/intel/xeon_sp/chip_common.c @@ -148,22 +148,6 @@ } }
-void iio_pci_domain_scan_bus(struct device *dev) -{ - const STACK_RES *sr = domain_to_stack_res(dev); - if (!sr) - return; - - struct bus *bus = alloc_bus(dev); - bus->secondary = sr->BusBase; - bus->subordinate = sr->BusBase; - bus->max_subordinate = sr->BusLimit; - - printk(BIOS_SPEW, "Scanning IIO stack %d: busses %x-%x\n", dev->path.domain.domain, - dev->downstream->secondary, dev->downstream->max_subordinate); - pci_host_bridge_scan_bus(dev); -} - /* * Used by IIO stacks for PCIe bridges. Those contain 1 PCI host bridges, * all the bus numbers on the IIO stack can be used for this bridge @@ -171,12 +155,22 @@ static struct device_operations iio_pcie_domain_ops = { .read_resources = iio_pci_domain_read_resources, .set_resources = pci_domain_set_resources, - .scan_bus = iio_pci_domain_scan_bus, + .scan_bus = pci_host_bridge_scan_bus, #if CONFIG(HAVE_ACPI_TABLES) .acpi_name = soc_acpi_name, #endif };
+static struct device_operations iio_domain0_ops = { + .read_resources = iio_pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .scan_bus = pci_host_bridge_scan_bus, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = soc_acpi_name, + .write_acpi_tables = northbridge_write_acpi_tables, +#endif +}; + /* * Used by UBOX stacks. Those contain multiple PCI host bridges, each having * only one bus with UBOX devices. UBOX devices have no resources. @@ -190,19 +184,49 @@ #endif };
+static void soc_create_pcie_domains(const union xeon_domain_path dp, struct bus *upstream, + const STACK_RES *sr) +{ + union xeon_domain_path new_path = { + .domain_path = dp.domain_path + }; + new_path.bus = sr->BusBase; + + struct device_path path = { + .type = DEVICE_PATH_DOMAIN, + .domain = { + .domain = new_path.domain_path, + }, + }; + + struct device *const domain = alloc_find_dev(upstream, &path); + if (!domain) + die("%s: out of memory.\n", __func__); + + domain->ops = &iio_pcie_domain_ops; + iio_domain_set_acpi_name(domain, DOMAIN_TYPE_PCIE); + + struct bus *const bus = alloc_bus(domain); + bus->secondary = sr->BusBase; + bus->subordinate = sr->BusBase; + bus->max_subordinate = sr->BusLimit; +} + /* * On the first Xeon-SP generations there are no separate UBOX stacks, * and the UBOX devices reside on the first and second IIO. Starting * 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 unsigned int bus_base, const unsigned int bus_limit) + const STACK_RES *sr) { union xeon_domain_path new_path = { .domain_path = dp.domain_path };
/* Only expect 2 UBOX buses here */ + int bus_base = sr->BusBase; + int bus_limit = sr->BusLimit; assert(bus_base + 1 == bus_limit); for (int i = bus_base; i <= bus_limit; i++) { new_path.bus = i; @@ -213,7 +237,7 @@ .domain = new_path.domain_path, }, }; - struct device *const domain = alloc_dev(upstream, &path); + struct device *const domain = alloc_find_dev(upstream, &path); if (!domain) die("%s: out of memory.\n", __func__);
@@ -229,19 +253,16 @@ }
/* Attach stack as domains */ -void attach_iio_stacks(struct device *dev) +void attach_iio_stacks(void) { const IIO_UDS *hob = get_iio_uds(); union xeon_domain_path dn = { .domain_path = 0 }; if (!hob) return;
+ struct bus *root_bus = dev_root.downstream; for (int s = 0; s < hob->PlatformData.numofIIO; ++s) { for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) { - if (s == 0 && x == 0) { - iio_domain_set_acpi_name(dev, DOMAIN_TYPE_PCIE); - continue; - } const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x]; if (ri->BusBase > ri->BusLimit) continue; @@ -249,22 +270,24 @@ /* Prepare domain path */ dn.socket = s; dn.stack = x; - dn.bus = ri->BusBase;
if (is_ubox_stack_res(ri)) { - soc_create_ubox_domains(dn, dev->upstream, ri->BusBase, ri->BusLimit); + soc_create_ubox_domains(dn, root_bus, ri); } else if (is_pcie_iio_stack_res(ri)) { - struct device_path path; - path.type = DEVICE_PATH_DOMAIN; - path.domain.domain = dn.domain_path; - struct device *iio_domain = alloc_dev(dev->upstream, &path); - if (iio_domain == NULL) - die("%s: out of memory.\n", __func__); - - iio_domain->ops = &iio_pcie_domain_ops; - iio_domain_set_acpi_name(iio_domain, DOMAIN_TYPE_PCIE); - } else if (CONFIG(HAVE_IOAT_DOMAINS)) - soc_create_ioat_domains(dn, dev->upstream, ri); + soc_create_pcie_domains(dn, root_bus, ri); + } else if (CONFIG(HAVE_IOAT_DOMAINS) && is_ioat_iio_stack_res(ri)) + soc_create_ioat_domains(dn, root_bus, ri); } } + +#if CONFIG(HAVE_ACPI_TABLES) + /* rebind domain0 ops for uncore ACPI table writes */ + struct device *dev = NULL; + while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN))) { + if (dev->downstream->secondary == 0 && dev->downstream->segment_group == 0) { + dev->ops = &iio_domain0_ops; + break; + } + } +#endif } diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c index 5fc90e7..8a828c6 100644 --- a/src/soc/intel/xeon_sp/cpx/chip.c +++ b/src/soc/intel/xeon_sp/cpx/chip.c @@ -27,16 +27,6 @@ mainboard_silicon_init_params(silupd); }
-static struct device_operations pci_domain_ops = { - .read_resources = iio_pci_domain_read_resources, - .set_resources = pci_domain_set_resources, - .scan_bus = iio_pci_domain_scan_bus, -#if CONFIG(HAVE_ACPI_TABLES) - .write_acpi_tables = &northbridge_write_acpi_tables, - .acpi_name = soc_acpi_name, -#endif -}; - static struct device_operations cpu_bus_ops = { .read_resources = noop_read_resources, .set_resources = noop_set_resources, @@ -52,8 +42,7 @@ { /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_DOMAIN) { - dev->ops = &pci_domain_ops; - attach_iio_stacks(dev); + /* domain ops are assigned at their creation */ } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { dev->ops = &cpu_bus_ops; } else if (dev->path.type == DEVICE_PATH_GPIO) { @@ -176,6 +165,9 @@ { printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); fsp_silicon_init(); + + attach_iio_stacks(); + override_hpet_ioapic_bdf(); pch_enable_ioapic(); pch_lock_dmictl(); 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 a010bd1..47dea8e 100644 --- a/src/soc/intel/xeon_sp/include/soc/chip_common.h +++ b/src/soc/intel/xeon_sp/include/soc/chip_common.h @@ -30,8 +30,7 @@ #define DOMAIN_TYPE_UBX1 "UD"
void iio_pci_domain_read_resources(struct device *dev); -void iio_pci_domain_scan_bus(struct device *dev); -void attach_iio_stacks(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); struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device); diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c index 92663d9..1911e06 100644 --- a/src/soc/intel/xeon_sp/skx/chip.c +++ b/src/soc/intel/xeon_sp/skx/chip.c @@ -13,16 +13,6 @@ #include <soc/soc_util.h> #include <soc/util.h>
-static struct device_operations pci_domain_ops = { - .read_resources = iio_pci_domain_read_resources, - .set_resources = pci_domain_set_resources, - .scan_bus = iio_pci_domain_scan_bus, -#if CONFIG(HAVE_ACPI_TABLES) - .write_acpi_tables = &northbridge_write_acpi_tables, - .acpi_name = soc_acpi_name, -#endif -}; - static struct device_operations cpu_bus_ops = { .read_resources = noop_read_resources, .set_resources = noop_set_resources, @@ -37,8 +27,7 @@ { /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_DOMAIN) { - dev->ops = &pci_domain_ops; - attach_iio_stacks(dev); + /* domain ops are assigned at their creation */ } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { dev->ops = &cpu_bus_ops; } else if (dev->path.type == DEVICE_PATH_GPIO) { @@ -50,6 +39,9 @@ { printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); fsp_silicon_init(); + + attach_iio_stacks(); + override_hpet_ioapic_bdf(); pch_lock_dmictl(); } diff --git a/src/soc/intel/xeon_sp/spr/chip.c b/src/soc/intel/xeon_sp/spr/chip.c index cc3719d..a9387f4 100644 --- a/src/soc/intel/xeon_sp/spr/chip.c +++ b/src/soc/intel/xeon_sp/spr/chip.c @@ -38,17 +38,6 @@ mainboard_silicon_init_params(silupd); }
- -static struct device_operations pci_domain_ops = { - .read_resources = iio_pci_domain_read_resources, - .set_resources = pci_domain_set_resources, - .scan_bus = iio_pci_domain_scan_bus, -#if CONFIG(HAVE_ACPI_TABLES) - .write_acpi_tables = &northbridge_write_acpi_tables, - .acpi_name = soc_acpi_name, -#endif -}; - static struct device_operations cpu_bus_ops = { .read_resources = noop_read_resources, .set_resources = noop_set_resources, @@ -64,8 +53,7 @@ { /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_DOMAIN) { - dev->ops = &pci_domain_ops; - attach_iio_stacks(dev); + /* domain ops are assigned at their creation */ } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { dev->ops = &cpu_bus_ops; } else if (dev->path.type == DEVICE_PATH_GPIO) { @@ -138,6 +126,9 @@ { printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); fsp_silicon_init(); + + attach_iio_stacks(); + override_hpet_ioapic_bdf(); pch_enable_ioapic(); pch_lock_dmictl(); diff --git a/src/soc/intel/xeon_sp/spr/ioat.c b/src/soc/intel/xeon_sp/spr/ioat.c index 5528efa..d944976 100644 --- a/src/soc/intel/xeon_sp/spr/ioat.c +++ b/src/soc/intel/xeon_sp/spr/ioat.c @@ -45,7 +45,7 @@ .domain = new_path.domain_path, }, }; - struct device *const domain = alloc_dev(upstream, &path); + struct device *const domain = alloc_find_dev(upstream, &path); if (!domain) die("%s: out of memory.\n", __func__);