Skip to content

Commit

Permalink
tools/testing/cxl: Mock one level of switches
Browse files Browse the repository at this point in the history
The CXL port enumeration process adds intermediate CXL ports that are
discovered between "root" CXL ports enumerated by 'cxl_acpi' and
endpoints enumerated by 'cxl_pci + cxl_mem'. Test the dynamic discovery
of intermediate switch ports in a CXL topology.

Link: https://lore.kernel.org/r/164298432189.3018233.13142151550113000967.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Dan Williams committed Feb 9, 2022
1 parent a4a0ce2 commit c191514
Showing 1 changed file with 97 additions and 41 deletions.
138 changes: 97 additions & 41 deletions tools/testing/cxl/test/cxl.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,21 @@
#include <cxlmem.h>
#include "mock.h"

#define NR_CXL_HOST_BRIDGES 4
#define NR_CXL_HOST_BRIDGES 2
#define NR_CXL_ROOT_PORTS 2
#define NR_CXL_SWITCH_PORTS 2

static struct platform_device *cxl_acpi;
static struct platform_device *cxl_host_bridge[NR_CXL_HOST_BRIDGES];
static struct platform_device
*cxl_root_port[NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS];
struct platform_device *cxl_mem[NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS];
static struct platform_device
*cxl_switch_uport[NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS];
static struct platform_device
*cxl_switch_dport[NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS *
NR_CXL_SWITCH_PORTS];
struct platform_device
*cxl_mem[NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS * NR_CXL_SWITCH_PORTS];

static struct acpi_device acpi0017_mock;
static struct acpi_device host_bridge[NR_CXL_HOST_BRIDGES] = {
Expand All @@ -28,12 +35,6 @@ static struct acpi_device host_bridge[NR_CXL_HOST_BRIDGES] = {
[1] = {
.handle = &host_bridge[1],
},
[2] = {
.handle = &host_bridge[2],
},
[3] = {
.handle = &host_bridge[3],
},
};

static bool is_mock_dev(struct device *dev)
Expand Down Expand Up @@ -71,15 +72,15 @@ static struct {
} cfmws0;
struct {
struct acpi_cedt_cfmws cfmws;
u32 target[4];
u32 target[2];
} cfmws1;
struct {
struct acpi_cedt_cfmws cfmws;
u32 target[1];
} cfmws2;
struct {
struct acpi_cedt_cfmws cfmws;
u32 target[4];
u32 target[2];
} cfmws3;
} __packed mock_cedt = {
.cedt = {
Expand All @@ -105,22 +106,6 @@ static struct {
.uid = 1,
.cxl_version = ACPI_CEDT_CHBS_VERSION_CXL20,
},
.chbs[2] = {
.header = {
.type = ACPI_CEDT_TYPE_CHBS,
.length = sizeof(mock_cedt.chbs[0]),
},
.uid = 2,
.cxl_version = ACPI_CEDT_CHBS_VERSION_CXL20,
},
.chbs[3] = {
.header = {
.type = ACPI_CEDT_TYPE_CHBS,
.length = sizeof(mock_cedt.chbs[0]),
},
.uid = 3,
.cxl_version = ACPI_CEDT_CHBS_VERSION_CXL20,
},
.cfmws0 = {
.cfmws = {
.header = {
Expand All @@ -142,14 +127,14 @@ static struct {
.type = ACPI_CEDT_TYPE_CFMWS,
.length = sizeof(mock_cedt.cfmws1),
},
.interleave_ways = 2,
.interleave_ways = 1,
.granularity = 4,
.restrictions = ACPI_CEDT_CFMWS_RESTRICT_TYPE3 |
ACPI_CEDT_CFMWS_RESTRICT_VOLATILE,
.qtg_id = 1,
.window_size = SZ_256M * 4,
.window_size = SZ_256M * 2,
},
.target = { 0, 1, 2, 3 },
.target = { 0, 1, },
},
.cfmws2 = {
.cfmws = {
Expand All @@ -172,14 +157,14 @@ static struct {
.type = ACPI_CEDT_TYPE_CFMWS,
.length = sizeof(mock_cedt.cfmws3),
},
.interleave_ways = 2,
.interleave_ways = 1,
.granularity = 4,
.restrictions = ACPI_CEDT_CFMWS_RESTRICT_TYPE3 |
ACPI_CEDT_CFMWS_RESTRICT_PMEM,
.qtg_id = 3,
.window_size = SZ_256M * 4,
.window_size = SZ_256M * 2,
},
.target = { 0, 1, 2, 3 },
.target = { 0, 1, },
},
};

Expand Down Expand Up @@ -332,6 +317,17 @@ static bool is_mock_port(struct device *dev)
if (dev == &cxl_root_port[i]->dev)
return true;

for (i = 0; i < ARRAY_SIZE(cxl_switch_uport); i++)
if (dev == &cxl_switch_uport[i]->dev)
return true;

for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++)
if (dev == &cxl_switch_dport[i]->dev)
return true;

if (is_cxl_memdev(dev))
return is_mock_dev(dev->parent);

return false;
}

Expand Down Expand Up @@ -372,12 +368,6 @@ static struct acpi_pci_root mock_pci_root[NR_CXL_HOST_BRIDGES] = {
[1] = {
.bus = &mock_pci_bus[1],
},
[2] = {
.bus = &mock_pci_bus[2],
},
[3] = {
.bus = &mock_pci_bus[3],
},
};

static bool is_mock_bus(struct pci_bus *bus)
Expand Down Expand Up @@ -446,6 +436,26 @@ static int mock_cxl_port_enumerate_dports(struct cxl_port *port)
dev_name(&pdev->dev));
}

for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
struct platform_device *pdev = cxl_switch_dport[i];
struct cxl_dport *dport;

if (pdev->dev.parent != port->uport)
continue;

dport = devm_cxl_add_dport(port, &pdev->dev, pdev->id,
CXL_RESOURCE_NONE);

if (IS_ERR(dport)) {
dev_err(dev, "failed to add dport: %s (%ld)\n",
dev_name(&pdev->dev), PTR_ERR(dport));
return PTR_ERR(dport);
}

dev_dbg(dev, "add dport%d: %s\n", pdev->id,
dev_name(&pdev->dev));
}

return 0;
}

Expand Down Expand Up @@ -574,15 +584,51 @@ static __init int cxl_test_init(void)
cxl_root_port[i] = pdev;
}

BUILD_BUG_ON(ARRAY_SIZE(cxl_mem) != ARRAY_SIZE(cxl_root_port));
BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
for (i = 0; i < ARRAY_SIZE(cxl_switch_uport); i++) {
struct platform_device *root_port = cxl_root_port[i];
struct platform_device *pdev;

pdev = platform_device_alloc("cxl_switch_uport", i);
if (!pdev)
goto err_port;
pdev->dev.parent = &root_port->dev;

rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
goto err_uport;
}
cxl_switch_uport[i] = pdev;
}

for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
struct platform_device *uport =
cxl_switch_uport[i % ARRAY_SIZE(cxl_switch_uport)];
struct platform_device *pdev;

pdev = platform_device_alloc("cxl_switch_dport", i);
if (!pdev)
goto err_port;
pdev->dev.parent = &uport->dev;

rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
goto err_dport;
}
cxl_switch_dport[i] = pdev;
}

BUILD_BUG_ON(ARRAY_SIZE(cxl_mem) != ARRAY_SIZE(cxl_switch_dport));
for (i = 0; i < ARRAY_SIZE(cxl_mem); i++) {
struct platform_device *port = cxl_root_port[i];
struct platform_device *dport = cxl_switch_dport[i];
struct platform_device *pdev;

pdev = alloc_memdev(i);
if (!pdev)
goto err_mem;
pdev->dev.parent = &port->dev;
pdev->dev.parent = &dport->dev;
set_dev_node(&pdev->dev, i % 2);

rc = platform_device_add(pdev);
Expand Down Expand Up @@ -611,6 +657,12 @@ static __init int cxl_test_init(void)
err_mem:
for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
platform_device_unregister(cxl_mem[i]);
err_dport:
for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
platform_device_unregister(cxl_switch_dport[i]);
err_uport:
for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
platform_device_unregister(cxl_switch_uport[i]);
err_port:
for (i = ARRAY_SIZE(cxl_root_port) - 1; i >= 0; i--)
platform_device_unregister(cxl_root_port[i]);
Expand All @@ -633,6 +685,10 @@ static __exit void cxl_test_exit(void)
platform_device_unregister(cxl_acpi);
for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
platform_device_unregister(cxl_mem[i]);
for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
platform_device_unregister(cxl_switch_dport[i]);
for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
platform_device_unregister(cxl_switch_uport[i]);
for (i = ARRAY_SIZE(cxl_root_port) - 1; i >= 0; i--)
platform_device_unregister(cxl_root_port[i]);
for (i = ARRAY_SIZE(cxl_host_bridge) - 1; i >= 0; i--)
Expand Down

0 comments on commit c191514

Please sign in to comment.