xref: /openbmc/linux/tools/testing/cxl/test/mock.c (revision 67dcdd4d)
1*67dcdd4dSDan Williams // SPDX-License-Identifier: GPL-2.0-only
2*67dcdd4dSDan Williams //Copyright(c) 2021 Intel Corporation. All rights reserved.
3*67dcdd4dSDan Williams 
4*67dcdd4dSDan Williams #include <linux/libnvdimm.h>
5*67dcdd4dSDan Williams #include <linux/rculist.h>
6*67dcdd4dSDan Williams #include <linux/device.h>
7*67dcdd4dSDan Williams #include <linux/export.h>
8*67dcdd4dSDan Williams #include <linux/acpi.h>
9*67dcdd4dSDan Williams #include <linux/pci.h>
10*67dcdd4dSDan Williams #include "mock.h"
11*67dcdd4dSDan Williams 
12*67dcdd4dSDan Williams static LIST_HEAD(mock);
13*67dcdd4dSDan Williams 
14*67dcdd4dSDan Williams void register_cxl_mock_ops(struct cxl_mock_ops *ops)
15*67dcdd4dSDan Williams {
16*67dcdd4dSDan Williams 	list_add_rcu(&ops->list, &mock);
17*67dcdd4dSDan Williams }
18*67dcdd4dSDan Williams EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
19*67dcdd4dSDan Williams 
20*67dcdd4dSDan Williams static DEFINE_SRCU(cxl_mock_srcu);
21*67dcdd4dSDan Williams 
22*67dcdd4dSDan Williams void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
23*67dcdd4dSDan Williams {
24*67dcdd4dSDan Williams 	list_del_rcu(&ops->list);
25*67dcdd4dSDan Williams 	synchronize_srcu(&cxl_mock_srcu);
26*67dcdd4dSDan Williams }
27*67dcdd4dSDan Williams EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
28*67dcdd4dSDan Williams 
29*67dcdd4dSDan Williams struct cxl_mock_ops *get_cxl_mock_ops(int *index)
30*67dcdd4dSDan Williams {
31*67dcdd4dSDan Williams 	*index = srcu_read_lock(&cxl_mock_srcu);
32*67dcdd4dSDan Williams 	return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list);
33*67dcdd4dSDan Williams }
34*67dcdd4dSDan Williams EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
35*67dcdd4dSDan Williams 
36*67dcdd4dSDan Williams void put_cxl_mock_ops(int index)
37*67dcdd4dSDan Williams {
38*67dcdd4dSDan Williams 	srcu_read_unlock(&cxl_mock_srcu, index);
39*67dcdd4dSDan Williams }
40*67dcdd4dSDan Williams EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
41*67dcdd4dSDan Williams 
42*67dcdd4dSDan Williams bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
43*67dcdd4dSDan Williams {
44*67dcdd4dSDan Williams 	struct acpi_device *adev =
45*67dcdd4dSDan Williams 		container_of(fwnode, struct acpi_device, fwnode);
46*67dcdd4dSDan Williams 	int index;
47*67dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
48*67dcdd4dSDan Williams 	bool retval = false;
49*67dcdd4dSDan Williams 
50*67dcdd4dSDan Williams 	if (ops)
51*67dcdd4dSDan Williams 		retval = ops->is_mock_adev(adev);
52*67dcdd4dSDan Williams 
53*67dcdd4dSDan Williams 	if (!retval)
54*67dcdd4dSDan Williams 		retval = is_acpi_device_node(fwnode);
55*67dcdd4dSDan Williams 
56*67dcdd4dSDan Williams 	put_cxl_mock_ops(index);
57*67dcdd4dSDan Williams 	return retval;
58*67dcdd4dSDan Williams }
59*67dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_is_acpi_device_node);
60*67dcdd4dSDan Williams 
61*67dcdd4dSDan Williams acpi_status __wrap_acpi_get_table(char *signature, u32 instance,
62*67dcdd4dSDan Williams 				  struct acpi_table_header **out_table)
63*67dcdd4dSDan Williams {
64*67dcdd4dSDan Williams 	int index;
65*67dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
66*67dcdd4dSDan Williams 	acpi_status status;
67*67dcdd4dSDan Williams 
68*67dcdd4dSDan Williams 	if (ops)
69*67dcdd4dSDan Williams 		status = ops->acpi_get_table(signature, instance, out_table);
70*67dcdd4dSDan Williams 	else
71*67dcdd4dSDan Williams 		status = acpi_get_table(signature, instance, out_table);
72*67dcdd4dSDan Williams 
73*67dcdd4dSDan Williams 	put_cxl_mock_ops(index);
74*67dcdd4dSDan Williams 
75*67dcdd4dSDan Williams 	return status;
76*67dcdd4dSDan Williams }
77*67dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_acpi_get_table);
78*67dcdd4dSDan Williams 
79*67dcdd4dSDan Williams void __wrap_acpi_put_table(struct acpi_table_header *table)
80*67dcdd4dSDan Williams {
81*67dcdd4dSDan Williams 	int index;
82*67dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
83*67dcdd4dSDan Williams 
84*67dcdd4dSDan Williams 	if (ops)
85*67dcdd4dSDan Williams 		ops->acpi_put_table(table);
86*67dcdd4dSDan Williams 	else
87*67dcdd4dSDan Williams 		acpi_put_table(table);
88*67dcdd4dSDan Williams 	put_cxl_mock_ops(index);
89*67dcdd4dSDan Williams }
90*67dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_acpi_put_table);
91*67dcdd4dSDan Williams 
92*67dcdd4dSDan Williams acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
93*67dcdd4dSDan Williams 					 acpi_string pathname,
94*67dcdd4dSDan Williams 					 struct acpi_object_list *arguments,
95*67dcdd4dSDan Williams 					 unsigned long long *data)
96*67dcdd4dSDan Williams {
97*67dcdd4dSDan Williams 	int index;
98*67dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
99*67dcdd4dSDan Williams 	acpi_status status;
100*67dcdd4dSDan Williams 
101*67dcdd4dSDan Williams 	if (ops)
102*67dcdd4dSDan Williams 		status = ops->acpi_evaluate_integer(handle, pathname, arguments,
103*67dcdd4dSDan Williams 						    data);
104*67dcdd4dSDan Williams 	else
105*67dcdd4dSDan Williams 		status = acpi_evaluate_integer(handle, pathname, arguments,
106*67dcdd4dSDan Williams 					       data);
107*67dcdd4dSDan Williams 	put_cxl_mock_ops(index);
108*67dcdd4dSDan Williams 
109*67dcdd4dSDan Williams 	return status;
110*67dcdd4dSDan Williams }
111*67dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
112*67dcdd4dSDan Williams 
113*67dcdd4dSDan Williams struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
114*67dcdd4dSDan Williams {
115*67dcdd4dSDan Williams 	int index;
116*67dcdd4dSDan Williams 	struct acpi_pci_root *root;
117*67dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
118*67dcdd4dSDan Williams 
119*67dcdd4dSDan Williams 	if (ops)
120*67dcdd4dSDan Williams 		root = ops->acpi_pci_find_root(handle);
121*67dcdd4dSDan Williams 	else
122*67dcdd4dSDan Williams 		root = acpi_pci_find_root(handle);
123*67dcdd4dSDan Williams 
124*67dcdd4dSDan Williams 	put_cxl_mock_ops(index);
125*67dcdd4dSDan Williams 
126*67dcdd4dSDan Williams 	return root;
127*67dcdd4dSDan Williams }
128*67dcdd4dSDan Williams EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
129*67dcdd4dSDan Williams 
130*67dcdd4dSDan Williams void __wrap_pci_walk_bus(struct pci_bus *bus,
131*67dcdd4dSDan Williams 			 int (*cb)(struct pci_dev *, void *), void *userdata)
132*67dcdd4dSDan Williams {
133*67dcdd4dSDan Williams 	int index;
134*67dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
135*67dcdd4dSDan Williams 
136*67dcdd4dSDan Williams 	if (ops && ops->is_mock_bus(bus)) {
137*67dcdd4dSDan Williams 		int rc, i;
138*67dcdd4dSDan Williams 
139*67dcdd4dSDan Williams 		/*
140*67dcdd4dSDan Williams 		 * Simulate 2 root ports per host-bridge and no
141*67dcdd4dSDan Williams 		 * depth recursion.
142*67dcdd4dSDan Williams 		 */
143*67dcdd4dSDan Williams 		for (i = 0; i < 2; i++) {
144*67dcdd4dSDan Williams 			rc = cb((struct pci_dev *) ops->mock_port(bus, i),
145*67dcdd4dSDan Williams 				userdata);
146*67dcdd4dSDan Williams 			if (rc)
147*67dcdd4dSDan Williams 				break;
148*67dcdd4dSDan Williams 		}
149*67dcdd4dSDan Williams 	} else
150*67dcdd4dSDan Williams 		pci_walk_bus(bus, cb, userdata);
151*67dcdd4dSDan Williams 
152*67dcdd4dSDan Williams 	put_cxl_mock_ops(index);
153*67dcdd4dSDan Williams }
154*67dcdd4dSDan Williams EXPORT_SYMBOL_GPL(__wrap_pci_walk_bus);
155*67dcdd4dSDan Williams 
156*67dcdd4dSDan Williams struct nvdimm_bus *
157*67dcdd4dSDan Williams __wrap_nvdimm_bus_register(struct device *dev,
158*67dcdd4dSDan Williams 			   struct nvdimm_bus_descriptor *nd_desc)
159*67dcdd4dSDan Williams {
160*67dcdd4dSDan Williams 	int index;
161*67dcdd4dSDan Williams 	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
162*67dcdd4dSDan Williams 
163*67dcdd4dSDan Williams 	if (ops && ops->is_mock_dev(dev->parent->parent))
164*67dcdd4dSDan Williams 		nd_desc->provider_name = "cxl_test";
165*67dcdd4dSDan Williams 	put_cxl_mock_ops(index);
166*67dcdd4dSDan Williams 
167*67dcdd4dSDan Williams 	return nvdimm_bus_register(dev, nd_desc);
168*67dcdd4dSDan Williams }
169*67dcdd4dSDan Williams EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
170*67dcdd4dSDan Williams 
171*67dcdd4dSDan Williams MODULE_LICENSE("GPL v2");
172