xref: /linux/tools/testing/cxl/test/mock.c (revision 0be3ff0c)
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 static DEFINE_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 {
136 	int index;
137 	struct cxl_hdm *cxlhdm;
138 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
139 
140 	if (ops && ops->is_mock_port(port->uport))
141 		cxlhdm = ops->devm_cxl_setup_hdm(port);
142 	else
143 		cxlhdm = devm_cxl_setup_hdm(port);
144 	put_cxl_mock_ops(index);
145 
146 	return cxlhdm;
147 }
148 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL);
149 
150 int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port)
151 {
152 	int rc, index;
153 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
154 
155 	if (ops && ops->is_mock_port(port->uport))
156 		rc = ops->devm_cxl_add_passthrough_decoder(port);
157 	else
158 		rc = devm_cxl_add_passthrough_decoder(port);
159 	put_cxl_mock_ops(index);
160 
161 	return rc;
162 }
163 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL);
164 
165 int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
166 {
167 	int rc, index;
168 	struct cxl_port *port = cxlhdm->port;
169 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
170 
171 	if (ops && ops->is_mock_port(port->uport))
172 		rc = ops->devm_cxl_enumerate_decoders(cxlhdm);
173 	else
174 		rc = devm_cxl_enumerate_decoders(cxlhdm);
175 	put_cxl_mock_ops(index);
176 
177 	return rc;
178 }
179 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL);
180 
181 int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port)
182 {
183 	int rc, index;
184 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
185 
186 	if (ops && ops->is_mock_port(port->uport))
187 		rc = ops->devm_cxl_port_enumerate_dports(port);
188 	else
189 		rc = devm_cxl_port_enumerate_dports(port);
190 	put_cxl_mock_ops(index);
191 
192 	return rc;
193 }
194 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL);
195 
196 MODULE_LICENSE("GPL v2");
197 MODULE_IMPORT_NS(ACPI);
198 MODULE_IMPORT_NS(CXL);
199