From 255f9275152f5485e060956295542eb4ee06caa9 Mon Sep 17 00:00:00 2001 From: Shuo Liu Date: Wed, 29 Mar 2023 20:14:11 +0800 Subject: 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 overridden. 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 Reviewed-on: https://review.coreboot.org/c/coreboot/+/81098 Reviewed-by: Patrick Rudolph Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/soc/intel/xeon_sp/chip_common.c | 84 +++++++++++++------------ src/soc/intel/xeon_sp/cpx/chip.c | 16 ++--- src/soc/intel/xeon_sp/include/soc/chip_common.h | 3 +- src/soc/intel/xeon_sp/skx/chip.c | 16 ++--- src/soc/intel/xeon_sp/spr/chip.c | 17 ++--- src/soc/intel/xeon_sp/spr/ioat.c | 3 +- src/soc/intel/xeon_sp/uncore_acpi.c | 4 ++ 7 files changed, 63 insertions(+), 80 deletions(-) (limited to 'src/soc/intel/xeon_sp') diff --git a/src/soc/intel/xeon_sp/chip_common.c b/src/soc/intel/xeon_sp/chip_common.c index 03ae70af35..93949c870d 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_read_resources(struct device *dev) } } -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,9 +155,10 @@ void iio_pci_domain_scan_bus(struct device *dev) 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, + .write_acpi_tables = northbridge_write_acpi_tables, #endif }; @@ -187,22 +172,53 @@ static struct device_operations ubox_pcie_domain_ops = { .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 }; +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 +229,7 @@ static void soc_create_ubox_domains(const union xeon_domain_path dp, struct bus .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 +245,16 @@ static void soc_create_ubox_domains(const union xeon_domain_path dp, struct bus } /* 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 +262,13 @@ void attach_iio_stacks(struct device *dev) /* 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); - } 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); + + if (is_ubox_stack_res(ri)) + soc_create_ubox_domains(dn, root_bus, ri); + else if (is_pcie_iio_stack_res(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); } } } diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c index 5fc90e71a3..8a828c677e 100644 --- a/src/soc/intel/xeon_sp/cpx/chip.c +++ b/src/soc/intel/xeon_sp/cpx/chip.c @@ -27,16 +27,6 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd) 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 @@ static void chip_enable_dev(struct device *dev) { /* 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 @@ static void chip_init(void *data) { 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 a010bd1bb2..47dea8e948 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 @@ union xeon_domain_path { #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 92663d96b2..1911e0609f 100644 --- a/src/soc/intel/xeon_sp/skx/chip.c +++ b/src/soc/intel/xeon_sp/skx/chip.c @@ -13,16 +13,6 @@ #include #include -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 @@ static void soc_enable_dev(struct device *dev) { /* 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 @@ static void soc_init(void *data) { 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 cc3719d16d..a9387f4237 100644 --- a/src/soc/intel/xeon_sp/spr/chip.c +++ b/src/soc/intel/xeon_sp/spr/chip.c @@ -38,17 +38,6 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd) 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 @@ static void chip_enable_dev(struct device *dev) { /* 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 @@ static void chip_init(void *data) { 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 bde7ebacdb..2b6aafa883 100644 --- a/src/soc/intel/xeon_sp/spr/ioat.c +++ b/src/soc/intel/xeon_sp/spr/ioat.c @@ -25,6 +25,7 @@ static struct device_operations ioat_domain_ops = { .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 }; @@ -45,7 +46,7 @@ static void create_ioat_domain(const union xeon_domain_path dp, struct bus *cons .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__); diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c index b7c66407f2..81546387f4 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi.c +++ b/src/soc/intel/xeon_sp/uncore_acpi.c @@ -567,6 +567,10 @@ static unsigned long acpi_fill_dmar(unsigned long current) unsigned long northbridge_write_acpi_tables(const struct device *device, unsigned long current, struct acpi_rsdp *rsdp) { + /* Only write uncore ACPI tables for domain0 */ + if (device->path.domain.domain != 0) + return current; + acpi_srat_t *srat; acpi_slit_t *slit; acpi_dmar_t *dmar; -- cgit v1.2.3