xref: /linux/tools/testing/cxl/test/mock.c (revision 0526b56cbc3c489642bd6a5fe4b718dea7ef0ee8)
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 struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
103 {
104 	int index;
105 	struct acpi_pci_root *root;
106 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
107 
108 	if (ops)
109 		root = ops->acpi_pci_find_root(handle);
110 	else
111 		root = acpi_pci_find_root(handle);
112 
113 	put_cxl_mock_ops(index);
114 
115 	return root;
116 }
117 EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
118 
119 struct nvdimm_bus *
120 __wrap_nvdimm_bus_register(struct device *dev,
121 			   struct nvdimm_bus_descriptor *nd_desc)
122 {
123 	int index;
124 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
125 
126 	if (ops && ops->is_mock_dev(dev->parent->parent))
127 		nd_desc->provider_name = "cxl_test";
128 	put_cxl_mock_ops(index);
129 
130 	return nvdimm_bus_register(dev, nd_desc);
131 }
132 EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
133 
134 struct cxl_hdm *__wrap_devm_cxl_setup_hdm(struct cxl_port *port,
135 					  struct cxl_endpoint_dvsec_info *info)
136 
137 {
138 	int index;
139 	struct cxl_hdm *cxlhdm;
140 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
141 
142 	if (ops && ops->is_mock_port(port->uport))
143 		cxlhdm = ops->devm_cxl_setup_hdm(port, info);
144 	else
145 		cxlhdm = devm_cxl_setup_hdm(port, info);
146 	put_cxl_mock_ops(index);
147 
148 	return cxlhdm;
149 }
150 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL);
151 
152 int __wrap_devm_cxl_enable_hdm(struct cxl_port *port, struct cxl_hdm *cxlhdm)
153 {
154 	int index, rc;
155 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
156 
157 	if (ops && ops->is_mock_port(port->uport))
158 		rc = 0;
159 	else
160 		rc = devm_cxl_enable_hdm(port, cxlhdm);
161 	put_cxl_mock_ops(index);
162 
163 	return rc;
164 }
165 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enable_hdm, CXL);
166 
167 int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port)
168 {
169 	int rc, index;
170 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
171 
172 	if (ops && ops->is_mock_port(port->uport))
173 		rc = ops->devm_cxl_add_passthrough_decoder(port);
174 	else
175 		rc = devm_cxl_add_passthrough_decoder(port);
176 	put_cxl_mock_ops(index);
177 
178 	return rc;
179 }
180 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL);
181 
182 int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
183 				       struct cxl_endpoint_dvsec_info *info)
184 {
185 	int rc, index;
186 	struct cxl_port *port = cxlhdm->port;
187 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
188 
189 	if (ops && ops->is_mock_port(port->uport))
190 		rc = ops->devm_cxl_enumerate_decoders(cxlhdm, info);
191 	else
192 		rc = devm_cxl_enumerate_decoders(cxlhdm, info);
193 	put_cxl_mock_ops(index);
194 
195 	return rc;
196 }
197 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL);
198 
199 int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port)
200 {
201 	int rc, index;
202 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
203 
204 	if (ops && ops->is_mock_port(port->uport))
205 		rc = ops->devm_cxl_port_enumerate_dports(port);
206 	else
207 		rc = devm_cxl_port_enumerate_dports(port);
208 	put_cxl_mock_ops(index);
209 
210 	return rc;
211 }
212 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL);
213 
214 int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)
215 {
216 	int rc, index;
217 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
218 
219 	if (ops && ops->is_mock_dev(cxlds->dev))
220 		rc = 0;
221 	else
222 		rc = cxl_await_media_ready(cxlds);
223 	put_cxl_mock_ops(index);
224 
225 	return rc;
226 }
227 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL);
228 
229 int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds,
230 			       struct cxl_hdm *cxlhdm,
231 			       struct cxl_endpoint_dvsec_info *info)
232 {
233 	int rc = 0, index;
234 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
235 
236 	if (ops && ops->is_mock_dev(cxlds->dev))
237 		rc = 0;
238 	else
239 		rc = cxl_hdm_decode_init(cxlds, cxlhdm, info);
240 	put_cxl_mock_ops(index);
241 
242 	return rc;
243 }
244 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL);
245 
246 int __wrap_cxl_dvsec_rr_decode(struct device *dev, int dvsec,
247 			       struct cxl_endpoint_dvsec_info *info)
248 {
249 	int rc = 0, index;
250 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
251 
252 	if (ops && ops->is_mock_dev(dev))
253 		rc = 0;
254 	else
255 		rc = cxl_dvsec_rr_decode(dev, dvsec, info);
256 	put_cxl_mock_ops(index);
257 
258 	return rc;
259 }
260 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, CXL);
261 
262 resource_size_t __wrap_cxl_rcrb_to_component(struct device *dev,
263 					     resource_size_t rcrb,
264 					     enum cxl_rcrb which)
265 {
266 	int index;
267 	resource_size_t component_reg_phys;
268 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
269 
270 	if (ops && ops->is_mock_port(dev))
271 		component_reg_phys =
272 			ops->cxl_rcrb_to_component(dev, rcrb, which);
273 	else
274 		component_reg_phys = cxl_rcrb_to_component(dev, rcrb, which);
275 	put_cxl_mock_ops(index);
276 
277 	return component_reg_phys;
278 }
279 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcrb_to_component, CXL);
280 
281 MODULE_LICENSE("GPL v2");
282 MODULE_IMPORT_NS(ACPI);
283 MODULE_IMPORT_NS(CXL);
284