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 <shuo.liu@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81098 Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
@@ -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,
|
* 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
|
* 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 = {
|
static struct device_operations iio_pcie_domain_ops = {
|
||||||
.read_resources = iio_pci_domain_read_resources,
|
.read_resources = iio_pci_domain_read_resources,
|
||||||
.set_resources = pci_domain_set_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)
|
#if CONFIG(HAVE_ACPI_TABLES)
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
|
.write_acpi_tables = northbridge_write_acpi_tables,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -187,22 +172,53 @@ static struct device_operations ubox_pcie_domain_ops = {
|
|||||||
.scan_bus = pci_host_bridge_scan_bus,
|
.scan_bus = pci_host_bridge_scan_bus,
|
||||||
#if CONFIG(HAVE_ACPI_TABLES)
|
#if CONFIG(HAVE_ACPI_TABLES)
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
|
.write_acpi_tables = northbridge_write_acpi_tables,
|
||||||
#endif
|
#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,
|
* On the first Xeon-SP generations there are no separate UBOX stacks,
|
||||||
* and the UBOX devices reside on the first and second IIO. Starting
|
* 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.
|
* 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,
|
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 = {
|
union xeon_domain_path new_path = {
|
||||||
.domain_path = dp.domain_path
|
.domain_path = dp.domain_path
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Only expect 2 UBOX buses here */
|
/* Only expect 2 UBOX buses here */
|
||||||
|
int bus_base = sr->BusBase;
|
||||||
|
int bus_limit = sr->BusLimit;
|
||||||
assert(bus_base + 1 == bus_limit);
|
assert(bus_base + 1 == bus_limit);
|
||||||
for (int i = bus_base; i <= bus_limit; i++) {
|
for (int i = bus_base; i <= bus_limit; i++) {
|
||||||
new_path.bus = 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,
|
.domain = new_path.domain_path,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
struct device *const domain = alloc_dev(upstream, &path);
|
struct device *const domain = alloc_find_dev(upstream, &path);
|
||||||
if (!domain)
|
if (!domain)
|
||||||
die("%s: out of memory.\n", __func__);
|
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 */
|
/* Attach stack as domains */
|
||||||
void attach_iio_stacks(struct device *dev)
|
void attach_iio_stacks(void)
|
||||||
{
|
{
|
||||||
const IIO_UDS *hob = get_iio_uds();
|
const IIO_UDS *hob = get_iio_uds();
|
||||||
union xeon_domain_path dn = { .domain_path = 0 };
|
union xeon_domain_path dn = { .domain_path = 0 };
|
||||||
if (!hob)
|
if (!hob)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
struct bus *root_bus = dev_root.downstream;
|
||||||
for (int s = 0; s < hob->PlatformData.numofIIO; ++s) {
|
for (int s = 0; s < hob->PlatformData.numofIIO; ++s) {
|
||||||
for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) {
|
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];
|
const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x];
|
||||||
if (ri->BusBase > ri->BusLimit)
|
if (ri->BusBase > ri->BusLimit)
|
||||||
continue;
|
continue;
|
||||||
@@ -249,22 +262,13 @@ void attach_iio_stacks(struct device *dev)
|
|||||||
/* Prepare domain path */
|
/* Prepare domain path */
|
||||||
dn.socket = s;
|
dn.socket = s;
|
||||||
dn.stack = x;
|
dn.stack = x;
|
||||||
dn.bus = ri->BusBase;
|
|
||||||
|
|
||||||
if (is_ubox_stack_res(ri)) {
|
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)) {
|
else if (is_pcie_iio_stack_res(ri))
|
||||||
struct device_path path;
|
soc_create_pcie_domains(dn, root_bus, ri);
|
||||||
path.type = DEVICE_PATH_DOMAIN;
|
else if (CONFIG(HAVE_IOAT_DOMAINS) && is_ioat_iio_stack_res(ri))
|
||||||
path.domain.domain = dn.domain_path;
|
soc_create_ioat_domains(dn, root_bus, ri);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,16 +27,6 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
|
|||||||
mainboard_silicon_init_params(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 = {
|
static struct device_operations cpu_bus_ops = {
|
||||||
.read_resources = noop_read_resources,
|
.read_resources = noop_read_resources,
|
||||||
.set_resources = noop_set_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 */
|
/* Set the operations if it is a special bus type */
|
||||||
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
||||||
dev->ops = &pci_domain_ops;
|
/* domain ops are assigned at their creation */
|
||||||
attach_iio_stacks(dev);
|
|
||||||
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
||||||
dev->ops = &cpu_bus_ops;
|
dev->ops = &cpu_bus_ops;
|
||||||
} else if (dev->path.type == DEVICE_PATH_GPIO) {
|
} 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");
|
printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n");
|
||||||
fsp_silicon_init();
|
fsp_silicon_init();
|
||||||
|
|
||||||
|
attach_iio_stacks();
|
||||||
|
|
||||||
override_hpet_ioapic_bdf();
|
override_hpet_ioapic_bdf();
|
||||||
pch_enable_ioapic();
|
pch_enable_ioapic();
|
||||||
pch_lock_dmictl();
|
pch_lock_dmictl();
|
||||||
|
@@ -30,8 +30,7 @@ union xeon_domain_path {
|
|||||||
#define DOMAIN_TYPE_UBX1 "UD"
|
#define DOMAIN_TYPE_UBX1 "UD"
|
||||||
|
|
||||||
void iio_pci_domain_read_resources(struct device *dev);
|
void iio_pci_domain_read_resources(struct device *dev);
|
||||||
void iio_pci_domain_scan_bus(struct device *dev);
|
void attach_iio_stacks(void);
|
||||||
void attach_iio_stacks(struct device *dev);
|
|
||||||
|
|
||||||
void soc_create_ioat_domains(union xeon_domain_path path, struct bus *bus, const STACK_RES *sr);
|
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);
|
struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device);
|
||||||
|
@@ -13,16 +13,6 @@
|
|||||||
#include <soc/soc_util.h>
|
#include <soc/soc_util.h>
|
||||||
#include <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 = {
|
static struct device_operations cpu_bus_ops = {
|
||||||
.read_resources = noop_read_resources,
|
.read_resources = noop_read_resources,
|
||||||
.set_resources = noop_set_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 */
|
/* Set the operations if it is a special bus type */
|
||||||
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
||||||
dev->ops = &pci_domain_ops;
|
/* domain ops are assigned at their creation */
|
||||||
attach_iio_stacks(dev);
|
|
||||||
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
||||||
dev->ops = &cpu_bus_ops;
|
dev->ops = &cpu_bus_ops;
|
||||||
} else if (dev->path.type == DEVICE_PATH_GPIO) {
|
} 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");
|
printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n");
|
||||||
fsp_silicon_init();
|
fsp_silicon_init();
|
||||||
|
|
||||||
|
attach_iio_stacks();
|
||||||
|
|
||||||
override_hpet_ioapic_bdf();
|
override_hpet_ioapic_bdf();
|
||||||
pch_lock_dmictl();
|
pch_lock_dmictl();
|
||||||
}
|
}
|
||||||
|
@@ -38,17 +38,6 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
|
|||||||
mainboard_silicon_init_params(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 = {
|
static struct device_operations cpu_bus_ops = {
|
||||||
.read_resources = noop_read_resources,
|
.read_resources = noop_read_resources,
|
||||||
.set_resources = noop_set_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 */
|
/* Set the operations if it is a special bus type */
|
||||||
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
||||||
dev->ops = &pci_domain_ops;
|
/* domain ops are assigned at their creation */
|
||||||
attach_iio_stacks(dev);
|
|
||||||
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
||||||
dev->ops = &cpu_bus_ops;
|
dev->ops = &cpu_bus_ops;
|
||||||
} else if (dev->path.type == DEVICE_PATH_GPIO) {
|
} 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");
|
printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n");
|
||||||
fsp_silicon_init();
|
fsp_silicon_init();
|
||||||
|
|
||||||
|
attach_iio_stacks();
|
||||||
|
|
||||||
override_hpet_ioapic_bdf();
|
override_hpet_ioapic_bdf();
|
||||||
pch_enable_ioapic();
|
pch_enable_ioapic();
|
||||||
pch_lock_dmictl();
|
pch_lock_dmictl();
|
||||||
|
@@ -25,6 +25,7 @@ static struct device_operations ioat_domain_ops = {
|
|||||||
.scan_bus = pci_host_bridge_scan_bus,
|
.scan_bus = pci_host_bridge_scan_bus,
|
||||||
#if CONFIG(HAVE_ACPI_TABLES)
|
#if CONFIG(HAVE_ACPI_TABLES)
|
||||||
.acpi_name = soc_acpi_name,
|
.acpi_name = soc_acpi_name,
|
||||||
|
.write_acpi_tables = northbridge_write_acpi_tables,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ static void create_ioat_domain(const union xeon_domain_path dp, struct bus *cons
|
|||||||
.domain = new_path.domain_path,
|
.domain = new_path.domain_path,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
struct device *const domain = alloc_dev(upstream, &path);
|
struct device *const domain = alloc_find_dev(upstream, &path);
|
||||||
if (!domain)
|
if (!domain)
|
||||||
die("%s: out of memory.\n", __func__);
|
die("%s: out of memory.\n", __func__);
|
||||||
|
|
||||||
|
@@ -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,
|
unsigned long northbridge_write_acpi_tables(const struct device *device, unsigned long current,
|
||||||
struct acpi_rsdp *rsdp)
|
struct acpi_rsdp *rsdp)
|
||||||
{
|
{
|
||||||
|
/* Only write uncore ACPI tables for domain0 */
|
||||||
|
if (device->path.domain.domain != 0)
|
||||||
|
return current;
|
||||||
|
|
||||||
acpi_srat_t *srat;
|
acpi_srat_t *srat;
|
||||||
acpi_slit_t *slit;
|
acpi_slit_t *slit;
|
||||||
acpi_dmar_t *dmar;
|
acpi_dmar_t *dmar;
|
||||||
|
Reference in New Issue
Block a user