xref: /linux/tools/testing/cxl/test/mock.c (revision 7f5ff740ce0bcde242dafcc3f9bb3cbe6b5b8f3a)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //Copyright(c) 2021 Intel Corporation. All rights reserved.
3 
4 #include <linux/libnvdimm.h>
5 #include <linux/rculist.h>
6 #include <linux/device.h>
7 #include <linux/export.h>
8 #include <linux/acpi.h>
9 #include <linux/pci.h>
10 #include <cxlmem.h>
11 #include <cxlpci.h>
12 #include "mock.h"
13 
14 static LIST_HEAD(mock);
15 
16 void register_cxl_mock_ops(struct cxl_mock_ops *ops)
17 {
18 	list_add_rcu(&ops->list, &mock);
19 }
20 EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
21 
22 DEFINE_STATIC_SRCU(cxl_mock_srcu);
23 
24 void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
25 {
26 	list_del_rcu(&ops->list);
27 	synchronize_srcu(&cxl_mock_srcu);
28 }
29 EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
30 
31 struct cxl_mock_ops *get_cxl_mock_ops(int *index)
32 {
33 	*index = srcu_read_lock(&cxl_mock_srcu);
34 	return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list);
35 }
36 EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
37 
38 void put_cxl_mock_ops(int index)
39 {
40 	srcu_read_unlock(&cxl_mock_srcu, index);
41 }
42 EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
43 
44 bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
45 {
46 	struct acpi_device *adev =
47 		container_of(fwnode, struct acpi_device, fwnode);
48 	int index;
49 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
50 	bool retval = false;
51 
52 	if (ops)
53 		retval = ops->is_mock_adev(adev);
54 
55 	if (!retval)
56 		retval = is_acpi_device_node(fwnode);
57 
58 	put_cxl_mock_ops(index);
59 	return retval;
60 }
61 EXPORT_SYMBOL(__wrap_is_acpi_device_node);
62 
63 int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
64 				 acpi_tbl_entry_handler_arg handler_arg,
65 				 void *arg)
66 {
67 	int index, rc;
68 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
69 
70 	if (ops)
71 		rc = ops->acpi_table_parse_cedt(id, handler_arg, arg);
72 	else
73 		rc = acpi_table_parse_cedt(id, handler_arg, arg);
74 
75 	put_cxl_mock_ops(index);
76 
77 	return rc;
78 }
79 EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI");
80 
81 acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
82 					 acpi_string pathname,
83 					 struct acpi_object_list *arguments,
84 					 unsigned long long *data)
85 {
86 	int index;
87 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
88 	acpi_status status;
89 
90 	if (ops)
91 		status = ops->acpi_evaluate_integer(handle, pathname, arguments,
92 						    data);
93 	else
94 		status = acpi_evaluate_integer(handle, pathname, arguments,
95 					       data);
96 	put_cxl_mock_ops(index);
97 
98 	return status;
99 }
100 EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
101 
102 int __wrap_hmat_get_extended_linear_cache_size(struct resource *backing_res,
103 					       int nid,
104 					       resource_size_t *cache_size)
105 {
106 	int index, rc;
107 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
108 
109 	if (ops)
110 		rc = ops->hmat_get_extended_linear_cache_size(backing_res, nid,
111 							      cache_size);
112 	else
113 		rc = hmat_get_extended_linear_cache_size(backing_res, nid,
114 							 cache_size);
115 
116 	put_cxl_mock_ops(index);
117 
118 	return rc;
119 }
120 EXPORT_SYMBOL_GPL(__wrap_hmat_get_extended_linear_cache_size);
121 
122 struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
123 {
124 	int index;
125 	struct acpi_pci_root *root;
126 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
127 
128 	if (ops)
129 		root = ops->acpi_pci_find_root(handle);
130 	else
131 		root = acpi_pci_find_root(handle);
132 
133 	put_cxl_mock_ops(index);
134 
135 	return root;
136 }
137 EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
138 
139 struct nvdimm_bus *
140 __wrap_nvdimm_bus_register(struct device *dev,
141 			   struct nvdimm_bus_descriptor *nd_desc)
142 {
143 	int index;
144 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
145 
146 	if (ops && ops->is_mock_dev(dev->parent->parent))
147 		nd_desc->provider_name = "cxl_test";
148 	put_cxl_mock_ops(index);
149 
150 	return nvdimm_bus_register(dev, nd_desc);
151 }
152 EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
153 
154 int __wrap_devm_cxl_switch_port_decoders_setup(struct cxl_port *port)
155 {
156 	int rc, index;
157 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
158 
159 	if (ops && ops->is_mock_port(port->uport_dev))
160 		rc = ops->devm_cxl_switch_port_decoders_setup(port);
161 	else
162 		rc = devm_cxl_switch_port_decoders_setup(port);
163 	put_cxl_mock_ops(index);
164 
165 	return rc;
166 }
167 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_switch_port_decoders_setup, "CXL");
168 
169 int __wrap_devm_cxl_endpoint_decoders_setup(struct cxl_port *port)
170 {
171 	int rc, index;
172 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
173 
174 	if (ops && ops->is_mock_port(port->uport_dev))
175 		rc = ops->devm_cxl_endpoint_decoders_setup(port);
176 	else
177 		rc = devm_cxl_endpoint_decoders_setup(port);
178 	put_cxl_mock_ops(index);
179 
180 	return rc;
181 }
182 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_endpoint_decoders_setup, "CXL");
183 
184 int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)
185 {
186 	int rc, index;
187 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
188 
189 	if (ops && ops->is_mock_dev(cxlds->dev))
190 		rc = 0;
191 	else
192 		rc = cxl_await_media_ready(cxlds);
193 	put_cxl_mock_ops(index);
194 
195 	return rc;
196 }
197 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, "CXL");
198 
199 struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port,
200 						struct device *dport_dev,
201 						int port_id,
202 						resource_size_t rcrb)
203 {
204 	int index;
205 	struct cxl_dport *dport;
206 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
207 
208 	if (ops && ops->is_mock_port(dport_dev)) {
209 		dport = devm_cxl_add_dport(port, dport_dev, port_id,
210 					   CXL_RESOURCE_NONE);
211 		if (!IS_ERR(dport)) {
212 			dport->rcrb.base = rcrb;
213 			dport->rch = true;
214 		}
215 	} else
216 		dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb);
217 	put_cxl_mock_ops(index);
218 
219 	return dport;
220 }
221 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, "CXL");
222 
223 void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)
224 {
225 	int index;
226 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
227 	struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
228 
229 	if (ops && ops->is_mock_dev(cxlmd->dev.parent))
230 		ops->cxl_endpoint_parse_cdat(port);
231 	else
232 		cxl_endpoint_parse_cdat(port);
233 	put_cxl_mock_ops(index);
234 }
235 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
236 
237 struct cxl_dport *__wrap_devm_cxl_add_dport_by_dev(struct cxl_port *port,
238 						   struct device *dport_dev)
239 {
240 	int index;
241 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
242 	struct cxl_dport *dport;
243 
244 	if (ops && ops->is_mock_port(port->uport_dev))
245 		dport = ops->devm_cxl_add_dport_by_dev(port, dport_dev);
246 	else
247 		dport = devm_cxl_add_dport_by_dev(port, dport_dev);
248 	put_cxl_mock_ops(index);
249 
250 	return dport;
251 }
252 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_dport_by_dev, "CXL");
253 
254 MODULE_LICENSE("GPL v2");
255 MODULE_DESCRIPTION("cxl_test: emulation module");
256 MODULE_IMPORT_NS("ACPI");
257 MODULE_IMPORT_NS("CXL");
258