cxl/test: Mock acpi_table_parse_cedt()
authorDan Williams <dan.j.williams@intel.com>
Fri, 29 Oct 2021 19:51:53 +0000 (12:51 -0700)
committerDan Williams <dan.j.williams@intel.com>
Mon, 15 Nov 2021 19:03:00 +0000 (11:03 -0800)
Now that cxl_acpi has been converted to use the core ACPI CEDT sub-table
parser, update cxl_test to inject CFMWS and CHBS data directly into
cxl_acpi's handlers.

Cc: Alison Schofield <alison.schofield@intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://lore.kernel.org/r/163553711363.2509508.17428994087868269952.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/cxl/acpi.c
tools/testing/cxl/Kbuild
tools/testing/cxl/test/cxl.c
tools/testing/cxl/test/mock.c
tools/testing/cxl/test/mock.h

index 7820082..91e4072 100644 (file)
@@ -283,6 +283,7 @@ static int add_host_bridge_uport(struct device *match, void *arg)
 }
 
 struct cxl_chbs_context {
+       struct device *dev;
        unsigned long long uid;
        resource_size_t chbcr;
 };
@@ -327,6 +328,7 @@ static int add_host_bridge_dport(struct device *match, void *arg)
        }
 
        ctx = (struct cxl_chbs_context) {
+               .dev = host,
                .uid = uid,
        };
        acpi_table_parse_cedt(ACPI_CEDT_TYPE_CHBS, cxl_get_chbcr, &ctx);
index 86deba8..1acdf2f 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+ldflags-y += --wrap=acpi_table_parse_cedt
 ldflags-y += --wrap=is_acpi_device_node
-ldflags-y += --wrap=acpi_get_table
-ldflags-y += --wrap=acpi_put_table
 ldflags-y += --wrap=acpi_evaluate_integer
 ldflags-y += --wrap=acpi_pci_find_root
 ldflags-y += --wrap=pci_walk_bus
index cb32f9e..736d990 100644 (file)
@@ -182,6 +182,13 @@ static struct {
        },
 };
 
+struct acpi_cedt_cfmws *mock_cfmws[4] = {
+       [0] = &mock_cedt.cfmws0.cfmws,
+       [1] = &mock_cedt.cfmws1.cfmws,
+       [2] = &mock_cedt.cfmws2.cfmws,
+       [3] = &mock_cedt.cfmws3.cfmws,
+};
+
 struct cxl_mock_res {
        struct list_head list;
        struct range range;
@@ -232,12 +239,6 @@ static struct cxl_mock_res *alloc_mock_res(resource_size_t size)
 
 static int populate_cedt(void)
 {
-       struct acpi_cedt_cfmws *cfmws[4] = {
-               [0] = &mock_cedt.cfmws0.cfmws,
-               [1] = &mock_cedt.cfmws1.cfmws,
-               [2] = &mock_cedt.cfmws2.cfmws,
-               [3] = &mock_cedt.cfmws3.cfmws,
-       };
        struct cxl_mock_res *res;
        int i;
 
@@ -257,8 +258,8 @@ static int populate_cedt(void)
                chbs->length = size;
        }
 
-       for (i = 0; i < ARRAY_SIZE(cfmws); i++) {
-               struct acpi_cedt_cfmws *window = cfmws[i];
+       for (i = 0; i < ARRAY_SIZE(mock_cfmws); i++) {
+               struct acpi_cedt_cfmws *window = mock_cfmws[i];
 
                res = alloc_mock_res(window->window_size);
                if (!res)
@@ -269,21 +270,44 @@ static int populate_cedt(void)
        return 0;
 }
 
-static acpi_status mock_acpi_get_table(char *signature, u32 instance,
-                                      struct acpi_table_header **out_table)
+/*
+ * WARNING, this hack assumes the format of 'struct
+ * cxl_cfmws_context' and 'struct cxl_chbs_context' share the property that
+ * the first struct member is the device being probed by the cxl_acpi
+ * driver.
+ */
+struct cxl_cedt_context {
+       struct device *dev;
+};
+
+static int mock_acpi_table_parse_cedt(enum acpi_cedt_type id,
+                                     acpi_tbl_entry_handler_arg handler_arg,
+                                     void *arg)
 {
-       if (instance < U32_MAX || strcmp(signature, ACPI_SIG_CEDT) != 0)
-               return acpi_get_table(signature, instance, out_table);
+       struct cxl_cedt_context *ctx = arg;
+       struct device *dev = ctx->dev;
+       union acpi_subtable_headers *h;
+       unsigned long end;
+       int i;
 
-       *out_table = (struct acpi_table_header *) &mock_cedt;
-       return AE_OK;
-}
+       if (dev != &cxl_acpi->dev)
+               return acpi_table_parse_cedt(id, handler_arg, arg);
 
-static void mock_acpi_put_table(struct acpi_table_header *table)
-{
-       if (table == (struct acpi_table_header *) &mock_cedt)
-               return;
-       acpi_put_table(table);
+       if (id == ACPI_CEDT_TYPE_CHBS)
+               for (i = 0; i < ARRAY_SIZE(mock_cedt.chbs); i++) {
+                       h = (union acpi_subtable_headers *)&mock_cedt.chbs[i];
+                       end = (unsigned long)&mock_cedt.chbs[i + 1];
+                       handler_arg(h, arg, end);
+               }
+
+       if (id == ACPI_CEDT_TYPE_CFMWS)
+               for (i = 0; i < ARRAY_SIZE(mock_cfmws); i++) {
+                       h = (union acpi_subtable_headers *) mock_cfmws[i];
+                       end = (unsigned long) h + mock_cfmws[i]->header.length;
+                       handler_arg(h, arg, end);
+               }
+
+       return 0;
 }
 
 static bool is_mock_bridge(struct device *dev)
@@ -388,8 +412,7 @@ static struct cxl_mock_ops cxl_mock_ops = {
        .is_mock_port = is_mock_port,
        .is_mock_dev = is_mock_dev,
        .mock_port = mock_cxl_root_port,
-       .acpi_get_table = mock_acpi_get_table,
-       .acpi_put_table = mock_acpi_put_table,
+       .acpi_table_parse_cedt = mock_acpi_table_parse_cedt,
        .acpi_evaluate_integer = mock_acpi_evaluate_integer,
        .acpi_pci_find_root = mock_acpi_pci_find_root,
        .list = LIST_HEAD_INIT(cxl_mock_ops.list),
@@ -574,3 +597,4 @@ static __exit void cxl_test_exit(void)
 module_init(cxl_test_init);
 module_exit(cxl_test_exit);
 MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(ACPI);
index b8c108a..17408f8 100644 (file)
@@ -58,36 +58,23 @@ bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
 }
 EXPORT_SYMBOL(__wrap_is_acpi_device_node);
 
-acpi_status __wrap_acpi_get_table(char *signature, u32 instance,
-                                 struct acpi_table_header **out_table)
+int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
+                                acpi_tbl_entry_handler_arg handler_arg,
+                                void *arg)
 {
-       int index;
+       int index, rc;
        struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
-       acpi_status status;
 
        if (ops)
-               status = ops->acpi_get_table(signature, instance, out_table);
+               rc = ops->acpi_table_parse_cedt(id, handler_arg, arg);
        else
-               status = acpi_get_table(signature, instance, out_table);
+               rc = acpi_table_parse_cedt(id, handler_arg, arg);
 
        put_cxl_mock_ops(index);
 
-       return status;
-}
-EXPORT_SYMBOL(__wrap_acpi_get_table);
-
-void __wrap_acpi_put_table(struct acpi_table_header *table)
-{
-       int index;
-       struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
-
-       if (ops)
-               ops->acpi_put_table(table);
-       else
-               acpi_put_table(table);
-       put_cxl_mock_ops(index);
+       return rc;
 }
-EXPORT_SYMBOL(__wrap_acpi_put_table);
+EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI);
 
 acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
                                         acpi_string pathname,
@@ -169,3 +156,4 @@ __wrap_nvdimm_bus_register(struct device *dev,
 EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
 
 MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(ACPI);
index 805a94c..15ed0fd 100644 (file)
@@ -6,9 +6,9 @@
 struct cxl_mock_ops {
        struct list_head list;
        bool (*is_mock_adev)(struct acpi_device *dev);
-       acpi_status (*acpi_get_table)(char *signature, u32 instance,
-                                     struct acpi_table_header **out_table);
-       void (*acpi_put_table)(struct acpi_table_header *table);
+       int (*acpi_table_parse_cedt)(enum acpi_cedt_type id,
+                                    acpi_tbl_entry_handler_arg handler_arg,
+                                    void *arg);
        bool (*is_mock_bridge)(struct device *dev);
        acpi_status (*acpi_evaluate_integer)(acpi_handle handle,
                                             acpi_string pathname,