Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/cxl/test/mock.c
29270 views
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_dev))
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_add_passthrough_decoder(struct cxl_port *port)
153
{
154
int rc, index;
155
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
156
157
if (ops && ops->is_mock_port(port->uport_dev))
158
rc = ops->devm_cxl_add_passthrough_decoder(port);
159
else
160
rc = devm_cxl_add_passthrough_decoder(port);
161
put_cxl_mock_ops(index);
162
163
return rc;
164
}
165
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, "CXL");
166
167
int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
168
struct cxl_endpoint_dvsec_info *info)
169
{
170
int rc, index;
171
struct cxl_port *port = cxlhdm->port;
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_enumerate_decoders(cxlhdm, info);
176
else
177
rc = devm_cxl_enumerate_decoders(cxlhdm, info);
178
put_cxl_mock_ops(index);
179
180
return rc;
181
}
182
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, "CXL");
183
184
int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port)
185
{
186
int rc, index;
187
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
188
189
if (ops && ops->is_mock_port(port->uport_dev))
190
rc = ops->devm_cxl_port_enumerate_dports(port);
191
else
192
rc = devm_cxl_port_enumerate_dports(port);
193
put_cxl_mock_ops(index);
194
195
return rc;
196
}
197
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, "CXL");
198
199
int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)
200
{
201
int rc, index;
202
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
203
204
if (ops && ops->is_mock_dev(cxlds->dev))
205
rc = 0;
206
else
207
rc = cxl_await_media_ready(cxlds);
208
put_cxl_mock_ops(index);
209
210
return rc;
211
}
212
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, "CXL");
213
214
int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds,
215
struct cxl_hdm *cxlhdm,
216
struct cxl_endpoint_dvsec_info *info)
217
{
218
int rc = 0, index;
219
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
220
221
if (ops && ops->is_mock_dev(cxlds->dev))
222
rc = 0;
223
else
224
rc = cxl_hdm_decode_init(cxlds, cxlhdm, info);
225
put_cxl_mock_ops(index);
226
227
return rc;
228
}
229
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, "CXL");
230
231
int __wrap_cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds,
232
struct cxl_endpoint_dvsec_info *info)
233
{
234
int rc = 0, index;
235
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
236
237
if (ops && ops->is_mock_dev(cxlds->dev))
238
rc = 0;
239
else
240
rc = cxl_dvsec_rr_decode(cxlds, info);
241
put_cxl_mock_ops(index);
242
243
return rc;
244
}
245
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, "CXL");
246
247
struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port,
248
struct device *dport_dev,
249
int port_id,
250
resource_size_t rcrb)
251
{
252
int index;
253
struct cxl_dport *dport;
254
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
255
256
if (ops && ops->is_mock_port(dport_dev)) {
257
dport = devm_cxl_add_dport(port, dport_dev, port_id,
258
CXL_RESOURCE_NONE);
259
if (!IS_ERR(dport)) {
260
dport->rcrb.base = rcrb;
261
dport->rch = true;
262
}
263
} else
264
dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb);
265
put_cxl_mock_ops(index);
266
267
return dport;
268
}
269
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, "CXL");
270
271
resource_size_t __wrap_cxl_rcd_component_reg_phys(struct device *dev,
272
struct cxl_dport *dport)
273
{
274
int index;
275
resource_size_t component_reg_phys;
276
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
277
278
if (ops && ops->is_mock_port(dev))
279
component_reg_phys = CXL_RESOURCE_NONE;
280
else
281
component_reg_phys = cxl_rcd_component_reg_phys(dev, dport);
282
put_cxl_mock_ops(index);
283
284
return component_reg_phys;
285
}
286
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcd_component_reg_phys, "CXL");
287
288
void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)
289
{
290
int index;
291
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
292
struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
293
294
if (ops && ops->is_mock_dev(cxlmd->dev.parent))
295
ops->cxl_endpoint_parse_cdat(port);
296
else
297
cxl_endpoint_parse_cdat(port);
298
put_cxl_mock_ops(index);
299
}
300
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
301
302
void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
303
{
304
int index;
305
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
306
307
if (!ops || !ops->is_mock_port(dport->dport_dev))
308
cxl_dport_init_ras_reporting(dport, host);
309
310
put_cxl_mock_ops(index);
311
}
312
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dport_init_ras_reporting, "CXL");
313
314
MODULE_LICENSE("GPL v2");
315
MODULE_DESCRIPTION("cxl_test: emulation module");
316
MODULE_IMPORT_NS("ACPI");
317
MODULE_IMPORT_NS("CXL");
318
319