mock.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. //Copyright(c) 2021 Intel Corporation. All rights reserved.
  3. #include <linux/libnvdimm.h>
  4. #include <linux/rculist.h>
  5. #include <linux/device.h>
  6. #include <linux/export.h>
  7. #include <linux/acpi.h>
  8. #include <linux/pci.h>
  9. #include <cxlmem.h>
  10. #include <cxlpci.h>
  11. #include "mock.h"
  12. static LIST_HEAD(mock);
  13. void register_cxl_mock_ops(struct cxl_mock_ops *ops)
  14. {
  15. list_add_rcu(&ops->list, &mock);
  16. }
  17. EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
  18. DEFINE_STATIC_SRCU(cxl_mock_srcu);
  19. void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
  20. {
  21. list_del_rcu(&ops->list);
  22. synchronize_srcu(&cxl_mock_srcu);
  23. }
  24. EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
  25. struct cxl_mock_ops *get_cxl_mock_ops(int *index)
  26. {
  27. *index = srcu_read_lock(&cxl_mock_srcu);
  28. return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list);
  29. }
  30. EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
  31. void put_cxl_mock_ops(int index)
  32. {
  33. srcu_read_unlock(&cxl_mock_srcu, index);
  34. }
  35. EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
  36. bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
  37. {
  38. struct acpi_device *adev =
  39. container_of(fwnode, struct acpi_device, fwnode);
  40. int index;
  41. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  42. bool retval = false;
  43. if (ops)
  44. retval = ops->is_mock_adev(adev);
  45. if (!retval)
  46. retval = is_acpi_device_node(fwnode);
  47. put_cxl_mock_ops(index);
  48. return retval;
  49. }
  50. EXPORT_SYMBOL(__wrap_is_acpi_device_node);
  51. int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
  52. acpi_tbl_entry_handler_arg handler_arg,
  53. void *arg)
  54. {
  55. int index, rc;
  56. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  57. if (ops)
  58. rc = ops->acpi_table_parse_cedt(id, handler_arg, arg);
  59. else
  60. rc = acpi_table_parse_cedt(id, handler_arg, arg);
  61. put_cxl_mock_ops(index);
  62. return rc;
  63. }
  64. EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI");
  65. acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
  66. acpi_string pathname,
  67. struct acpi_object_list *arguments,
  68. unsigned long long *data)
  69. {
  70. int index;
  71. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  72. acpi_status status;
  73. if (ops)
  74. status = ops->acpi_evaluate_integer(handle, pathname, arguments,
  75. data);
  76. else
  77. status = acpi_evaluate_integer(handle, pathname, arguments,
  78. data);
  79. put_cxl_mock_ops(index);
  80. return status;
  81. }
  82. EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
  83. int __wrap_hmat_get_extended_linear_cache_size(struct resource *backing_res,
  84. int nid,
  85. resource_size_t *cache_size)
  86. {
  87. int index, rc;
  88. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  89. if (ops)
  90. rc = ops->hmat_get_extended_linear_cache_size(backing_res, nid,
  91. cache_size);
  92. else
  93. rc = hmat_get_extended_linear_cache_size(backing_res, nid,
  94. cache_size);
  95. put_cxl_mock_ops(index);
  96. return rc;
  97. }
  98. EXPORT_SYMBOL_GPL(__wrap_hmat_get_extended_linear_cache_size);
  99. struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
  100. {
  101. int index;
  102. struct acpi_pci_root *root;
  103. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  104. if (ops)
  105. root = ops->acpi_pci_find_root(handle);
  106. else
  107. root = acpi_pci_find_root(handle);
  108. put_cxl_mock_ops(index);
  109. return root;
  110. }
  111. EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
  112. struct nvdimm_bus *
  113. __wrap_nvdimm_bus_register(struct device *dev,
  114. struct nvdimm_bus_descriptor *nd_desc)
  115. {
  116. int index;
  117. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  118. if (ops && ops->is_mock_dev(dev->parent->parent))
  119. nd_desc->provider_name = "cxl_test";
  120. put_cxl_mock_ops(index);
  121. return nvdimm_bus_register(dev, nd_desc);
  122. }
  123. EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
  124. int __wrap_devm_cxl_switch_port_decoders_setup(struct cxl_port *port)
  125. {
  126. int rc, index;
  127. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  128. if (ops && ops->is_mock_port(port->uport_dev))
  129. rc = ops->devm_cxl_switch_port_decoders_setup(port);
  130. else
  131. rc = devm_cxl_switch_port_decoders_setup(port);
  132. put_cxl_mock_ops(index);
  133. return rc;
  134. }
  135. EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_switch_port_decoders_setup, "CXL");
  136. int __wrap_devm_cxl_endpoint_decoders_setup(struct cxl_port *port)
  137. {
  138. int rc, index;
  139. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  140. if (ops && ops->is_mock_port(port->uport_dev))
  141. rc = ops->devm_cxl_endpoint_decoders_setup(port);
  142. else
  143. rc = devm_cxl_endpoint_decoders_setup(port);
  144. put_cxl_mock_ops(index);
  145. return rc;
  146. }
  147. EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_endpoint_decoders_setup, "CXL");
  148. int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)
  149. {
  150. int rc, index;
  151. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  152. if (ops && ops->is_mock_dev(cxlds->dev))
  153. rc = 0;
  154. else
  155. rc = cxl_await_media_ready(cxlds);
  156. put_cxl_mock_ops(index);
  157. return rc;
  158. }
  159. EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, "CXL");
  160. struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port,
  161. struct device *dport_dev,
  162. int port_id,
  163. resource_size_t rcrb)
  164. {
  165. int index;
  166. struct cxl_dport *dport;
  167. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  168. if (ops && ops->is_mock_port(dport_dev)) {
  169. dport = devm_cxl_add_dport(port, dport_dev, port_id,
  170. CXL_RESOURCE_NONE);
  171. if (!IS_ERR(dport)) {
  172. dport->rcrb.base = rcrb;
  173. dport->rch = true;
  174. }
  175. } else
  176. dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb);
  177. put_cxl_mock_ops(index);
  178. return dport;
  179. }
  180. EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, "CXL");
  181. void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)
  182. {
  183. int index;
  184. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  185. struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
  186. if (ops && ops->is_mock_dev(cxlmd->dev.parent))
  187. ops->cxl_endpoint_parse_cdat(port);
  188. else
  189. cxl_endpoint_parse_cdat(port);
  190. put_cxl_mock_ops(index);
  191. }
  192. EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
  193. struct cxl_dport *__wrap_devm_cxl_add_dport_by_dev(struct cxl_port *port,
  194. struct device *dport_dev)
  195. {
  196. int index;
  197. struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  198. struct cxl_dport *dport;
  199. if (ops && ops->is_mock_port(port->uport_dev))
  200. dport = ops->devm_cxl_add_dport_by_dev(port, dport_dev);
  201. else
  202. dport = devm_cxl_add_dport_by_dev(port, dport_dev);
  203. put_cxl_mock_ops(index);
  204. return dport;
  205. }
  206. EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_dport_by_dev, "CXL");
  207. MODULE_LICENSE("GPL v2");
  208. MODULE_DESCRIPTION("cxl_test: emulation module");
  209. MODULE_IMPORT_NS("ACPI");
  210. MODULE_IMPORT_NS("CXL");