xref: /openbmc/linux/tools/testing/cxl/test/mock.c (revision d5b1a271)
167dcdd4dSDan Williams // SPDX-License-Identifier: GPL-2.0-only
267dcdd4dSDan Williams //Copyright(c) 2021 Intel Corporation. All rights reserved.
367dcdd4dSDan Williams 
467dcdd4dSDan Williams #include <linux/libnvdimm.h>
567dcdd4dSDan Williams #include <linux/rculist.h>
667dcdd4dSDan Williams #include <linux/device.h>
767dcdd4dSDan Williams #include <linux/export.h>
867dcdd4dSDan Williams #include <linux/acpi.h>
967dcdd4dSDan Williams #include <linux/pci.h>
1098d2d3a2SDan Williams #include <cxlmem.h>
1198d2d3a2SDan Williams #include <cxlpci.h>
1267dcdd4dSDan Williams #include "mock.h"
1367dcdd4dSDan Williams 
1467dcdd4dSDan Williams static LIST_HEAD(mock);
1567dcdd4dSDan Williams 
1667dcdd4dSDan Williams void register_cxl_mock_ops(struct cxl_mock_ops *ops)
1767dcdd4dSDan Williams {
1867dcdd4dSDan Williams 	list_add_rcu(&ops->list, &mock);
1967dcdd4dSDan Williams }
2067dcdd4dSDan Williams EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
2167dcdd4dSDan Williams 
2267dcdd4dSDan Williams static DEFINE_SRCU(cxl_mock_srcu);
2367dcdd4dSDan Williams 
2467dcdd4dSDan Williams void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
2567dcdd4dSDan Williams {
2667dcdd4dSDan Williams 	list_del_rcu(&ops->list);
2767dcdd4dSDan Williams 	synchronize_srcu(&cxl_mock_srcu);
2867dcdd4dSDan Williams }
2967dcdd4dSDan Williams EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
3067dcdd4dSDan Williams 
3167dcdd4dSDan Williams struct cxl_mock_ops *get_cxl_mock_ops(int *index)
3267dcdd4dSDan Williams {
3367dcdd4dSDan Williams 	*index = srcu_read_lock(&cxl_mock_srcu);
3467dcdd4dSDan Williams 	return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list);
3567dcdd4dSDan Williams }
3667dcdd4dSDan Williams EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
3767dcdd4dSDan Williams 
3867dcdd4dSDan Williams void put_cxl_mock_ops(int index)
3967dcdd4dSDan Williams {
4067dcdd4dSDan Williams 	srcu_read_unlock(&cxl_mock_srcu, index);
4167dcdd4dSDan Williams }
4267dcdd4dSDan Williams EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
4367dcdd4dSDan Williams 
4467dcdd4dSDan Williams bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
4567dcdd4dSDan Williams {
4667dcdd4dSDan Williams 	struct acpi_device *adev =
4767dcdd4dSDan Williams 		container_of(fwnode, struct acpi_device, fwnode);
4867dcdd4dSDan Williams 	int index;
4967dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
5067dcdd4dSDan Williams 	bool retval = false;
5167dcdd4dSDan Williams 
5267dcdd4dSDan Williams 	if (ops)
5367dcdd4dSDan Williams 		retval = ops->is_mock_adev(adev);
5467dcdd4dSDan Williams 
5567dcdd4dSDan Williams 	if (!retval)
5667dcdd4dSDan Williams 		retval = is_acpi_device_node(fwnode);
5767dcdd4dSDan Williams 
5867dcdd4dSDan Williams 	put_cxl_mock_ops(index);
5967dcdd4dSDan Williams 	return retval;
6067dcdd4dSDan Williams }
6167dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_is_acpi_device_node);
6267dcdd4dSDan Williams 
63814dff9aSDan Williams int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
64814dff9aSDan Williams 				 acpi_tbl_entry_handler_arg handler_arg,
65814dff9aSDan Williams 				 void *arg)
6667dcdd4dSDan Williams {
67814dff9aSDan Williams 	int index, rc;
6867dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
6967dcdd4dSDan Williams 
7067dcdd4dSDan Williams 	if (ops)
71814dff9aSDan Williams 		rc = ops->acpi_table_parse_cedt(id, handler_arg, arg);
7267dcdd4dSDan Williams 	else
73814dff9aSDan Williams 		rc = acpi_table_parse_cedt(id, handler_arg, arg);
74814dff9aSDan Williams 
7567dcdd4dSDan Williams 	put_cxl_mock_ops(index);
76814dff9aSDan Williams 
77814dff9aSDan Williams 	return rc;
7867dcdd4dSDan Williams }
79814dff9aSDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI);
8067dcdd4dSDan Williams 
8167dcdd4dSDan Williams acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
8267dcdd4dSDan Williams 					 acpi_string pathname,
8367dcdd4dSDan Williams 					 struct acpi_object_list *arguments,
8467dcdd4dSDan Williams 					 unsigned long long *data)
8567dcdd4dSDan Williams {
8667dcdd4dSDan Williams 	int index;
8767dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
8867dcdd4dSDan Williams 	acpi_status status;
8967dcdd4dSDan Williams 
9067dcdd4dSDan Williams 	if (ops)
9167dcdd4dSDan Williams 		status = ops->acpi_evaluate_integer(handle, pathname, arguments,
9267dcdd4dSDan Williams 						    data);
9367dcdd4dSDan Williams 	else
9467dcdd4dSDan Williams 		status = acpi_evaluate_integer(handle, pathname, arguments,
9567dcdd4dSDan Williams 					       data);
9667dcdd4dSDan Williams 	put_cxl_mock_ops(index);
9767dcdd4dSDan Williams 
9867dcdd4dSDan Williams 	return status;
9967dcdd4dSDan Williams }
10067dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
10167dcdd4dSDan Williams 
10267dcdd4dSDan Williams struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
10367dcdd4dSDan Williams {
10467dcdd4dSDan Williams 	int index;
10567dcdd4dSDan Williams 	struct acpi_pci_root *root;
10667dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
10767dcdd4dSDan Williams 
10867dcdd4dSDan Williams 	if (ops)
10967dcdd4dSDan Williams 		root = ops->acpi_pci_find_root(handle);
11067dcdd4dSDan Williams 	else
11167dcdd4dSDan Williams 		root = acpi_pci_find_root(handle);
11267dcdd4dSDan Williams 
11367dcdd4dSDan Williams 	put_cxl_mock_ops(index);
11467dcdd4dSDan Williams 
11567dcdd4dSDan Williams 	return root;
11667dcdd4dSDan Williams }
11767dcdd4dSDan Williams EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
11867dcdd4dSDan Williams 
11967dcdd4dSDan Williams struct nvdimm_bus *
12067dcdd4dSDan Williams __wrap_nvdimm_bus_register(struct device *dev,
12167dcdd4dSDan Williams 			   struct nvdimm_bus_descriptor *nd_desc)
12267dcdd4dSDan Williams {
12367dcdd4dSDan Williams 	int index;
12467dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
12567dcdd4dSDan Williams 
12667dcdd4dSDan Williams 	if (ops && ops->is_mock_dev(dev->parent->parent))
12767dcdd4dSDan Williams 		nd_desc->provider_name = "cxl_test";
12867dcdd4dSDan Williams 	put_cxl_mock_ops(index);
12967dcdd4dSDan Williams 
13067dcdd4dSDan Williams 	return nvdimm_bus_register(dev, nd_desc);
13167dcdd4dSDan Williams }
13267dcdd4dSDan Williams EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
13367dcdd4dSDan Williams 
134664bf115SDan Williams struct cxl_hdm *__wrap_devm_cxl_setup_hdm(struct cxl_port *port)
135d17d0540SDan Williams {
136d17d0540SDan Williams 	int index;
137d17d0540SDan Williams 	struct cxl_hdm *cxlhdm;
138d17d0540SDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
139d17d0540SDan Williams 
140d17d0540SDan Williams 	if (ops && ops->is_mock_port(port->uport))
141664bf115SDan Williams 		cxlhdm = ops->devm_cxl_setup_hdm(port);
142d17d0540SDan Williams 	else
143664bf115SDan Williams 		cxlhdm = devm_cxl_setup_hdm(port);
144d17d0540SDan Williams 	put_cxl_mock_ops(index);
145d17d0540SDan Williams 
146d17d0540SDan Williams 	return cxlhdm;
147d17d0540SDan Williams }
148d17d0540SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL);
149d17d0540SDan Williams 
150664bf115SDan Williams int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port)
151d17d0540SDan Williams {
152d17d0540SDan Williams 	int rc, index;
153d17d0540SDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
154d17d0540SDan Williams 
155d17d0540SDan Williams 	if (ops && ops->is_mock_port(port->uport))
156664bf115SDan Williams 		rc = ops->devm_cxl_add_passthrough_decoder(port);
157d17d0540SDan Williams 	else
158664bf115SDan Williams 		rc = devm_cxl_add_passthrough_decoder(port);
159d17d0540SDan Williams 	put_cxl_mock_ops(index);
160d17d0540SDan Williams 
161d17d0540SDan Williams 	return rc;
162d17d0540SDan Williams }
163d17d0540SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL);
164d17d0540SDan Williams 
165664bf115SDan Williams int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
166d17d0540SDan Williams {
167d17d0540SDan Williams 	int rc, index;
168d17d0540SDan Williams 	struct cxl_port *port = cxlhdm->port;
169d17d0540SDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
170d17d0540SDan Williams 
171d17d0540SDan Williams 	if (ops && ops->is_mock_port(port->uport))
172664bf115SDan Williams 		rc = ops->devm_cxl_enumerate_decoders(cxlhdm);
173d17d0540SDan Williams 	else
174664bf115SDan Williams 		rc = devm_cxl_enumerate_decoders(cxlhdm);
175d17d0540SDan Williams 	put_cxl_mock_ops(index);
176d17d0540SDan Williams 
177d17d0540SDan Williams 	return rc;
178d17d0540SDan Williams }
179d17d0540SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL);
180d17d0540SDan Williams 
181664bf115SDan Williams int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port)
18298d2d3a2SDan Williams {
18398d2d3a2SDan Williams 	int rc, index;
18498d2d3a2SDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
18598d2d3a2SDan Williams 
18698d2d3a2SDan Williams 	if (ops && ops->is_mock_port(port->uport))
187664bf115SDan Williams 		rc = ops->devm_cxl_port_enumerate_dports(port);
18898d2d3a2SDan Williams 	else
189664bf115SDan Williams 		rc = devm_cxl_port_enumerate_dports(port);
19098d2d3a2SDan Williams 	put_cxl_mock_ops(index);
19198d2d3a2SDan Williams 
19298d2d3a2SDan Williams 	return rc;
19398d2d3a2SDan Williams }
19498d2d3a2SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL);
19598d2d3a2SDan Williams 
1962e4ba0ecSDan Williams int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)
1972e4ba0ecSDan Williams {
1982e4ba0ecSDan Williams 	int rc, index;
1992e4ba0ecSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
2002e4ba0ecSDan Williams 
2012e4ba0ecSDan Williams 	if (ops && ops->is_mock_dev(cxlds->dev))
2022e4ba0ecSDan Williams 		rc = 0;
2032e4ba0ecSDan Williams 	else
2042e4ba0ecSDan Williams 		rc = cxl_await_media_ready(cxlds);
2052e4ba0ecSDan Williams 	put_cxl_mock_ops(index);
2062e4ba0ecSDan Williams 
2072e4ba0ecSDan Williams 	return rc;
2082e4ba0ecSDan Williams }
2092e4ba0ecSDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL);
2102e4ba0ecSDan Williams 
211863fdccdSDan Williams int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds,
212fcfbc93cSDan Williams 			       struct cxl_hdm *cxlhdm)
21314d78874SDan Williams {
21414d78874SDan Williams 	int rc = 0, index;
21514d78874SDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
21614d78874SDan Williams 
217863fdccdSDan Williams 	if (ops && ops->is_mock_dev(cxlds->dev))
218863fdccdSDan Williams 		rc = 0;
219863fdccdSDan Williams 	else
220fcfbc93cSDan Williams 		rc = cxl_hdm_decode_init(cxlds, cxlhdm);
22114d78874SDan Williams 	put_cxl_mock_ops(index);
22214d78874SDan Williams 
22314d78874SDan Williams 	return rc;
22414d78874SDan Williams }
225a12562bbSDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL);
22614d78874SDan Williams 
227*d5b1a271SRobert Richter resource_size_t __wrap_cxl_rcrb_to_component(struct device *dev,
228*d5b1a271SRobert Richter 					     resource_size_t rcrb,
229*d5b1a271SRobert Richter 					     enum cxl_rcrb which)
230*d5b1a271SRobert Richter {
231*d5b1a271SRobert Richter 	int index;
232*d5b1a271SRobert Richter 	resource_size_t component_reg_phys;
233*d5b1a271SRobert Richter 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
234*d5b1a271SRobert Richter 
235*d5b1a271SRobert Richter 	if (ops && ops->is_mock_port(dev))
236*d5b1a271SRobert Richter 		component_reg_phys =
237*d5b1a271SRobert Richter 			ops->cxl_rcrb_to_component(dev, rcrb, which);
238*d5b1a271SRobert Richter 	else
239*d5b1a271SRobert Richter 		component_reg_phys = cxl_rcrb_to_component(dev, rcrb, which);
240*d5b1a271SRobert Richter 	put_cxl_mock_ops(index);
241*d5b1a271SRobert Richter 
242*d5b1a271SRobert Richter 	return component_reg_phys;
243*d5b1a271SRobert Richter }
244*d5b1a271SRobert Richter EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcrb_to_component, CXL);
245*d5b1a271SRobert Richter 
24667dcdd4dSDan Williams MODULE_LICENSE("GPL v2");
247814dff9aSDan Williams MODULE_IMPORT_NS(ACPI);
24898d2d3a2SDan Williams MODULE_IMPORT_NS(CXL);
249