Attention is currently required from: Arthur Heymans, Christian Walter, Johnny Lin, Lean Sheng Tan, Patrick Rudolph, Tim Chu.
Shuo Liu has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/81099?usp=email )
Change subject: soc/intel/xeon_sp: Create CXL domains ......................................................................
soc/intel/xeon_sp: Create CXL domains
TEST=intel/archercity CRB
P.S. The SUT is not with CXL cards however we hope this refactor could be integrated first as an improvement of the design.
Change-Id: I643bcfbae7b6e8cfe11c147cc89374bc6b4d5a80 Signed-off-by: Shuo Liu shuo.liu@intel.com --- M src/soc/intel/xeon_sp/chip_common.c M src/soc/intel/xeon_sp/include/soc/chip_common.h 2 files changed, 80 insertions(+), 36 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/99/81099/1
diff --git a/src/soc/intel/xeon_sp/chip_common.c b/src/soc/intel/xeon_sp/chip_common.c index 8060e2a..5ac886c 100644 --- a/src/soc/intel/xeon_sp/chip_common.c +++ b/src/soc/intel/xeon_sp/chip_common.c @@ -148,6 +148,41 @@ } }
+void iio_cxl_domain_read_resources(struct device *dev) +{ + struct resource *res; + const STACK_RES *sr = domain_to_stack_res(dev); + + if (!sr) + return; + + int index = 0; + + if (sr->IoBase < sr->PciResourceIoBase) { + res = new_resource(dev, index++); + res->base = sr->IoBase; + res->limit = sr->PciResourceIoBase - 1; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED; + } + + if (sr->Mmio32Base < sr->PciResourceMem32Base) { + res = new_resource(dev, index++); + res->base = sr->Mmio32Base; + res->limit = sr->PciResourceMem32Base - 1; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; + } + + if (sr->Mmio64Base < sr->PciResourceMem64Base) { + res = new_resource(dev, index++); + res->base = sr->Mmio64Base; + res->limit = sr->PciResourceMem64Base - 1; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; + } +} + /* * 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,6 +206,15 @@ #endif };
+static struct device_operations iio_cxl_domain_ops = { + .read_resources = iio_cxl_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, +#endif +}; + /* * Used by UBOX stacks. Those contain multiple PCI host bridges, each having * only one bus with UBOX devices. UBOX devices have no resources. @@ -184,13 +228,14 @@ #endif };
-static void soc_create_pcie_domains(const union xeon_domain_path dp, struct bus *upstream, - const STACK_RES *sr) +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) { union xeon_domain_path new_path = { .domain_path = dp.domain_path }; - new_path.bus = sr->BusBase; + new_path.bus = bus_base;
struct device_path path = { .type = DEVICE_PATH_DOMAIN, @@ -203,13 +248,31 @@ if (!domain) die("%s: out of memory.\n", __func__);
- domain->ops = &iio_pcie_domain_ops; - iio_domain_set_acpi_name(domain, DOMAIN_TYPE_PCIE); + domain->ops = ops; + iio_domain_set_acpi_name(domain, type);
struct bus *const bus = alloc_bus(domain); - bus->secondary = sr->BusBase; - bus->subordinate = sr->BusBase; - bus->max_subordinate = sr->BusLimit; + bus->secondary = bus_base; + bus->subordinate = bus_base; + bus->max_subordinate = bus_limit; +} + + +static void soc_create_pcie_domains(const union xeon_domain_path dp, struct bus *upstream, + const STACK_RES *sr) +{ + soc_create_domains(dp, upstream, sr->BusBase, sr->BusLimit, DOMAIN_TYPE_PCIE, + &iio_pcie_domain_ops); +} + +static void soc_create_cxl_domains(const union xeon_domain_path dp, struct bus *upstream, + const STACK_RES *sr) +{ + assert(sr->BusBase + 1 <= sr->BusLimit); + soc_create_domains(dp, upstream, sr->BusBase, sr->BusBase, DOMAIN_TYPE_PCIE, + &iio_cxl_domain_ops); + soc_create_domains(dp, upstream, sr->BusBase + 1, sr->BusLimit, DOMAIN_TYPE_CXL, + &iio_cxl_domain_ops); }
/* @@ -220,36 +283,13 @@ static void soc_create_ubox_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 - }; - /* 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; + assert(sr->BusBase + 1 == sr->BusLimit);
- 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 = &ubox_pcie_domain_ops; - const char *prefix = (i == bus_base) ? DOMAIN_TYPE_UBX0 : DOMAIN_TYPE_UBX1; - iio_domain_set_acpi_name(domain, prefix); - - struct bus *const bus = alloc_bus(domain); - bus->secondary = i; - bus->subordinate = bus->secondary; - bus->max_subordinate = bus->secondary; - } + soc_create_domains(dp, upstream, sr->BusBase, sr->BusBase, DOMAIN_TYPE_UBX0, + &ubox_pcie_domain_ops); + soc_create_domains(dp, upstream, sr->BusLimit, sr->BusLimit, DOMAIN_TYPE_UBX1, + &ubox_pcie_domain_ops); }
/* Attach stack as domains */ @@ -273,6 +313,8 @@
if (is_ubox_stack_res(ri)) soc_create_ubox_domains(dn, root_bus, ri); + else if (CONFIG(SOC_INTEL_HAS_CXL) && is_iio_cxl_stack_res(ri)) + soc_create_cxl_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)) 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 47dea8e..ab9b61a 100644 --- a/src/soc/intel/xeon_sp/include/soc/chip_common.h +++ b/src/soc/intel/xeon_sp/include/soc/chip_common.h @@ -28,8 +28,10 @@ #define DOMAIN_TYPE_PCIE "PC" #define DOMAIN_TYPE_UBX0 "UC" #define DOMAIN_TYPE_UBX1 "UD" +#define DOMAIN_TYPE_CXL "CX"
void iio_pci_domain_read_resources(struct device *dev); +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);