Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
14static LIST_HEAD(mock);
15
16void register_cxl_mock_ops(struct cxl_mock_ops *ops)
17{
18 list_add_rcu(&ops->list, &mock);
19}
20EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
21
22DEFINE_STATIC_SRCU(cxl_mock_srcu);
23
24void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
25{
26 list_del_rcu(&ops->list);
27 synchronize_srcu(&cxl_mock_srcu);
28}
29EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
30
31struct 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}
36EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
37
38void put_cxl_mock_ops(int index)
39{
40 srcu_read_unlock(&cxl_mock_srcu, index);
41}
42EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
43
44bool __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}
61EXPORT_SYMBOL(__wrap_is_acpi_device_node);
62
63int __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}
79EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI");
80
81acpi_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}
100EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
101
102int __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}
120EXPORT_SYMBOL_GPL(__wrap_hmat_get_extended_linear_cache_size);
121
122struct 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}
137EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
138
139struct 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}
152EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
153
154int __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}
167EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_switch_port_decoders_setup, "CXL");
168
169int __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}
182EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_endpoint_decoders_setup, "CXL");
183
184int __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}
197EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, "CXL");
198
199struct 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}
221EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, "CXL");
222
223void __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}
235EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
236
237struct 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}
252EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_dport_by_dev, "CXL");
253
254int __wrap_region_intersects(resource_size_t start, size_t size,
255 unsigned long flags, unsigned long desc)
256{
257 int rc = -1;
258 int index;
259 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
260
261 if (ops)
262 rc = ops->region_intersects(start, size, flags, desc);
263 if (rc < 0)
264 rc = region_intersects(start, size, flags, desc);
265 put_cxl_mock_ops(index);
266
267 return rc;
268}
269EXPORT_SYMBOL_GPL(__wrap_region_intersects);
270
271int __wrap_region_intersects_soft_reserve(resource_size_t start, size_t size)
272{
273 int rc = -1;
274 int index;
275 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
276
277 if (ops)
278 rc = ops->region_intersects_soft_reserve(start, size);
279 if (rc < 0)
280 rc = region_intersects_soft_reserve(start, size);
281 put_cxl_mock_ops(index);
282
283 return rc;
284}
285EXPORT_SYMBOL_GPL(__wrap_region_intersects_soft_reserve);
286
287int __wrap_walk_hmem_resources(struct device *host, walk_hmem_fn fn)
288{
289 int index, rc = 0;
290 bool is_mock = strcmp(dev_name(host), "hmem_platform.1") == 0;
291 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
292
293 if (is_mock) {
294 if (ops)
295 rc = ops->walk_hmem_resources(host, fn);
296 } else {
297 rc = walk_hmem_resources(host, fn);
298 }
299 put_cxl_mock_ops(index);
300 return rc;
301}
302EXPORT_SYMBOL_GPL(__wrap_walk_hmem_resources);
303
304MODULE_LICENSE("GPL v2");
305MODULE_DESCRIPTION("cxl_test: emulation module");
306MODULE_IMPORT_NS("ACPI");
307MODULE_IMPORT_NS("CXL");