rimt.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2024-2025, Ventana Micro Systems Inc
  4. * Author: Sunil V L <sunilvl@ventanamicro.com>
  5. *
  6. */
  7. #define pr_fmt(fmt) "ACPI: RIMT: " fmt
  8. #include <linux/acpi.h>
  9. #include <linux/acpi_rimt.h>
  10. #include <linux/iommu.h>
  11. #include <linux/list.h>
  12. #include <linux/pci.h>
  13. #include <linux/platform_device.h>
  14. #include "init.h"
  15. struct rimt_fwnode {
  16. struct list_head list;
  17. struct acpi_rimt_node *rimt_node;
  18. struct fwnode_handle *fwnode;
  19. };
  20. static LIST_HEAD(rimt_fwnode_list);
  21. static DEFINE_SPINLOCK(rimt_fwnode_lock);
  22. #define RIMT_TYPE_MASK(type) (1 << (type))
  23. #define RIMT_IOMMU_TYPE BIT(0)
  24. /* Root pointer to the mapped RIMT table */
  25. static struct acpi_table_header *rimt_table;
  26. /**
  27. * rimt_set_fwnode() - Create rimt_fwnode and use it to register
  28. * iommu data in the rimt_fwnode_list
  29. *
  30. * @rimt_node: RIMT table node associated with the IOMMU
  31. * @fwnode: fwnode associated with the RIMT node
  32. *
  33. * Returns: 0 on success
  34. * <0 on failure
  35. */
  36. static int rimt_set_fwnode(struct acpi_rimt_node *rimt_node,
  37. struct fwnode_handle *fwnode)
  38. {
  39. struct rimt_fwnode *np;
  40. np = kzalloc_obj(*np, GFP_ATOMIC);
  41. if (WARN_ON(!np))
  42. return -ENOMEM;
  43. INIT_LIST_HEAD(&np->list);
  44. np->rimt_node = rimt_node;
  45. np->fwnode = fwnode;
  46. spin_lock(&rimt_fwnode_lock);
  47. list_add_tail(&np->list, &rimt_fwnode_list);
  48. spin_unlock(&rimt_fwnode_lock);
  49. return 0;
  50. }
  51. static acpi_status rimt_match_node_callback(struct acpi_rimt_node *node,
  52. void *context)
  53. {
  54. acpi_status status = AE_NOT_FOUND;
  55. struct device *dev = context;
  56. if (node->type == ACPI_RIMT_NODE_TYPE_IOMMU) {
  57. struct acpi_rimt_iommu *iommu_node = (struct acpi_rimt_iommu *)&node->node_data;
  58. if (dev_is_pci(dev)) {
  59. struct pci_dev *pdev;
  60. u16 bdf;
  61. pdev = to_pci_dev(dev);
  62. bdf = PCI_DEVID(pdev->bus->number, pdev->devfn);
  63. if ((pci_domain_nr(pdev->bus) == iommu_node->pcie_segment_number) &&
  64. bdf == iommu_node->pcie_bdf) {
  65. status = AE_OK;
  66. } else {
  67. status = AE_NOT_FOUND;
  68. }
  69. } else {
  70. struct platform_device *pdev = to_platform_device(dev);
  71. struct resource *res;
  72. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  73. if (res && res->start == iommu_node->base_address)
  74. status = AE_OK;
  75. else
  76. status = AE_NOT_FOUND;
  77. }
  78. } else if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) {
  79. struct acpi_rimt_pcie_rc *pci_rc;
  80. struct pci_bus *bus;
  81. bus = to_pci_bus(dev);
  82. pci_rc = (struct acpi_rimt_pcie_rc *)node->node_data;
  83. /*
  84. * It is assumed that PCI segment numbers maps one-to-one
  85. * with root complexes. Each segment number can represent only
  86. * one root complex.
  87. */
  88. status = pci_rc->pcie_segment_number == pci_domain_nr(bus) ?
  89. AE_OK : AE_NOT_FOUND;
  90. } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) {
  91. struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
  92. struct acpi_rimt_platform_device *ncomp;
  93. struct device *plat_dev = dev;
  94. struct acpi_device *adev;
  95. /*
  96. * Walk the device tree to find a device with an
  97. * ACPI companion; there is no point in scanning
  98. * RIMT for a device matching a platform device if
  99. * the device does not have an ACPI companion to
  100. * start with.
  101. */
  102. do {
  103. adev = ACPI_COMPANION(plat_dev);
  104. if (adev)
  105. break;
  106. plat_dev = plat_dev->parent;
  107. } while (plat_dev);
  108. if (!adev)
  109. return status;
  110. status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf);
  111. if (ACPI_FAILURE(status)) {
  112. dev_warn(plat_dev, "Can't get device full path name\n");
  113. return status;
  114. }
  115. ncomp = (struct acpi_rimt_platform_device *)node->node_data;
  116. status = !strcmp(ncomp->device_name, buf.pointer) ?
  117. AE_OK : AE_NOT_FOUND;
  118. acpi_os_free(buf.pointer);
  119. }
  120. return status;
  121. }
  122. static struct acpi_rimt_node *rimt_scan_node(enum acpi_rimt_node_type type,
  123. void *context)
  124. {
  125. struct acpi_rimt_node *rimt_node, *rimt_end;
  126. struct acpi_table_rimt *rimt;
  127. int i;
  128. if (!rimt_table)
  129. return NULL;
  130. /* Get the first RIMT node */
  131. rimt = (struct acpi_table_rimt *)rimt_table;
  132. rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt,
  133. rimt->node_offset);
  134. rimt_end = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table,
  135. rimt_table->length);
  136. for (i = 0; i < rimt->num_nodes; i++) {
  137. if (WARN_TAINT(rimt_node >= rimt_end, TAINT_FIRMWARE_WORKAROUND,
  138. "RIMT node pointer overflows, bad table!\n"))
  139. return NULL;
  140. if (rimt_node->type == type &&
  141. ACPI_SUCCESS(rimt_match_node_callback(rimt_node, context)))
  142. return rimt_node;
  143. rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_node,
  144. rimt_node->length);
  145. }
  146. return NULL;
  147. }
  148. /*
  149. * RISC-V supports IOMMU as a PCI device or a platform device.
  150. * When it is a platform device, there should be a namespace device as
  151. * well along with RIMT. To create the link between RIMT information and
  152. * the platform device, the IOMMU driver should register itself with the
  153. * RIMT module. This is true for PCI based IOMMU as well.
  154. */
  155. int rimt_iommu_register(struct device *dev)
  156. {
  157. struct fwnode_handle *rimt_fwnode;
  158. struct acpi_rimt_node *node;
  159. node = rimt_scan_node(ACPI_RIMT_NODE_TYPE_IOMMU, dev);
  160. if (!node) {
  161. pr_err("Could not find IOMMU node in RIMT\n");
  162. return -ENODEV;
  163. }
  164. if (dev_is_pci(dev)) {
  165. rimt_fwnode = acpi_alloc_fwnode_static();
  166. if (!rimt_fwnode)
  167. return -ENOMEM;
  168. rimt_fwnode->dev = dev;
  169. if (!dev->fwnode)
  170. dev->fwnode = rimt_fwnode;
  171. rimt_set_fwnode(node, rimt_fwnode);
  172. } else {
  173. rimt_set_fwnode(node, dev->fwnode);
  174. }
  175. return 0;
  176. }
  177. #ifdef CONFIG_IOMMU_API
  178. /**
  179. * rimt_get_fwnode() - Retrieve fwnode associated with an RIMT node
  180. *
  181. * @node: RIMT table node to be looked-up
  182. *
  183. * Returns: fwnode_handle pointer on success, NULL on failure
  184. */
  185. static struct fwnode_handle *rimt_get_fwnode(struct acpi_rimt_node *node)
  186. {
  187. struct fwnode_handle *fwnode = NULL;
  188. struct rimt_fwnode *curr;
  189. spin_lock(&rimt_fwnode_lock);
  190. list_for_each_entry(curr, &rimt_fwnode_list, list) {
  191. if (curr->rimt_node == node) {
  192. fwnode = curr->fwnode;
  193. break;
  194. }
  195. }
  196. spin_unlock(&rimt_fwnode_lock);
  197. return fwnode;
  198. }
  199. static bool rimt_pcie_rc_supports_ats(struct acpi_rimt_node *node)
  200. {
  201. struct acpi_rimt_pcie_rc *pci_rc;
  202. pci_rc = (struct acpi_rimt_pcie_rc *)node->node_data;
  203. return pci_rc->flags & ACPI_RIMT_PCIE_ATS_SUPPORTED;
  204. }
  205. static int rimt_iommu_xlate(struct device *dev, struct acpi_rimt_node *node, u32 deviceid)
  206. {
  207. struct fwnode_handle *rimt_fwnode;
  208. if (!node)
  209. return -ENODEV;
  210. rimt_fwnode = rimt_get_fwnode(node);
  211. /*
  212. * The IOMMU drivers may not be probed yet.
  213. * Defer the IOMMU configuration
  214. */
  215. if (!rimt_fwnode)
  216. return -EPROBE_DEFER;
  217. /*
  218. * EPROBE_DEFER ensures IOMMU is probed before the devices that
  219. * depend on them. During shutdown, however, the IOMMU may be removed
  220. * first, leading to issues. To avoid this, a device link is added
  221. * which enforces the correct removal order.
  222. */
  223. device_link_add(dev, rimt_fwnode->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
  224. return acpi_iommu_fwspec_init(dev, deviceid, rimt_fwnode);
  225. }
  226. struct rimt_pci_alias_info {
  227. struct device *dev;
  228. struct acpi_rimt_node *node;
  229. const struct iommu_ops *ops;
  230. };
  231. static int rimt_id_map(struct acpi_rimt_id_mapping *map, u8 type, u32 rid_in, u32 *rid_out)
  232. {
  233. if (rid_in < map->source_id_base ||
  234. (rid_in > map->source_id_base + map->num_ids))
  235. return -ENXIO;
  236. *rid_out = map->dest_id_base + (rid_in - map->source_id_base);
  237. return 0;
  238. }
  239. static struct acpi_rimt_node *rimt_node_get_id(struct acpi_rimt_node *node,
  240. u32 *id_out, int index)
  241. {
  242. struct acpi_rimt_platform_device *plat_node;
  243. u32 id_mapping_offset, num_id_mapping;
  244. struct acpi_rimt_pcie_rc *pci_node;
  245. struct acpi_rimt_id_mapping *map;
  246. struct acpi_rimt_node *parent;
  247. if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) {
  248. pci_node = (struct acpi_rimt_pcie_rc *)&node->node_data;
  249. id_mapping_offset = pci_node->id_mapping_offset;
  250. num_id_mapping = pci_node->num_id_mappings;
  251. } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) {
  252. plat_node = (struct acpi_rimt_platform_device *)&node->node_data;
  253. id_mapping_offset = plat_node->id_mapping_offset;
  254. num_id_mapping = plat_node->num_id_mappings;
  255. } else {
  256. return NULL;
  257. }
  258. if (!id_mapping_offset || !num_id_mapping || index >= num_id_mapping)
  259. return NULL;
  260. map = ACPI_ADD_PTR(struct acpi_rimt_id_mapping, node,
  261. id_mapping_offset + index * sizeof(*map));
  262. /* Firmware bug! */
  263. if (!map->dest_offset) {
  264. pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
  265. node, node->type);
  266. return NULL;
  267. }
  268. parent = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table, map->dest_offset);
  269. if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE ||
  270. node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) {
  271. *id_out = map->dest_id_base;
  272. return parent;
  273. }
  274. return NULL;
  275. }
  276. static struct acpi_rimt_node *rimt_node_map_id(struct acpi_rimt_node *node,
  277. u32 id_in, u32 *id_out,
  278. u8 type_mask)
  279. {
  280. struct acpi_rimt_platform_device *plat_node;
  281. u32 id_mapping_offset, num_id_mapping;
  282. struct acpi_rimt_pcie_rc *pci_node;
  283. u32 id = id_in;
  284. /* Parse the ID mapping tree to find specified node type */
  285. while (node) {
  286. struct acpi_rimt_id_mapping *map;
  287. int i, rc = 0;
  288. u32 map_id = id;
  289. if (RIMT_TYPE_MASK(node->type) & type_mask) {
  290. if (id_out)
  291. *id_out = id;
  292. return node;
  293. }
  294. if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) {
  295. pci_node = (struct acpi_rimt_pcie_rc *)&node->node_data;
  296. id_mapping_offset = pci_node->id_mapping_offset;
  297. num_id_mapping = pci_node->num_id_mappings;
  298. } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) {
  299. plat_node = (struct acpi_rimt_platform_device *)&node->node_data;
  300. id_mapping_offset = plat_node->id_mapping_offset;
  301. num_id_mapping = plat_node->num_id_mappings;
  302. } else {
  303. goto fail_map;
  304. }
  305. if (!id_mapping_offset || !num_id_mapping)
  306. goto fail_map;
  307. map = ACPI_ADD_PTR(struct acpi_rimt_id_mapping, node,
  308. id_mapping_offset);
  309. /* Firmware bug! */
  310. if (!map->dest_offset) {
  311. pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
  312. node, node->type);
  313. goto fail_map;
  314. }
  315. /* Do the ID translation */
  316. for (i = 0; i < num_id_mapping; i++, map++) {
  317. rc = rimt_id_map(map, node->type, map_id, &id);
  318. if (!rc)
  319. break;
  320. }
  321. if (i == num_id_mapping)
  322. goto fail_map;
  323. node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table,
  324. rc ? 0 : map->dest_offset);
  325. }
  326. fail_map:
  327. /* Map input ID to output ID unchanged on mapping failure */
  328. if (id_out)
  329. *id_out = id_in;
  330. return NULL;
  331. }
  332. static struct acpi_rimt_node *rimt_node_map_platform_id(struct acpi_rimt_node *node, u32 *id_out,
  333. u8 type_mask, int index)
  334. {
  335. struct acpi_rimt_node *parent;
  336. u32 id;
  337. parent = rimt_node_get_id(node, &id, index);
  338. if (!parent)
  339. return NULL;
  340. if (!(RIMT_TYPE_MASK(parent->type) & type_mask))
  341. parent = rimt_node_map_id(parent, id, id_out, type_mask);
  342. else
  343. if (id_out)
  344. *id_out = id;
  345. return parent;
  346. }
  347. static int rimt_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
  348. {
  349. struct rimt_pci_alias_info *info = data;
  350. struct acpi_rimt_node *parent;
  351. u32 deviceid;
  352. parent = rimt_node_map_id(info->node, alias, &deviceid, RIMT_IOMMU_TYPE);
  353. return rimt_iommu_xlate(info->dev, parent, deviceid);
  354. }
  355. static int rimt_plat_iommu_map(struct device *dev, struct acpi_rimt_node *node)
  356. {
  357. struct acpi_rimt_node *parent;
  358. int err = -ENODEV, i = 0;
  359. u32 deviceid = 0;
  360. do {
  361. parent = rimt_node_map_platform_id(node, &deviceid,
  362. RIMT_IOMMU_TYPE,
  363. i++);
  364. if (parent)
  365. err = rimt_iommu_xlate(dev, parent, deviceid);
  366. } while (parent && !err);
  367. return err;
  368. }
  369. static int rimt_plat_iommu_map_id(struct device *dev,
  370. struct acpi_rimt_node *node,
  371. const u32 *in_id)
  372. {
  373. struct acpi_rimt_node *parent;
  374. u32 deviceid;
  375. parent = rimt_node_map_id(node, *in_id, &deviceid, RIMT_IOMMU_TYPE);
  376. if (parent)
  377. return rimt_iommu_xlate(dev, parent, deviceid);
  378. return -ENODEV;
  379. }
  380. /**
  381. * rimt_iommu_configure_id - Set-up IOMMU configuration for a device.
  382. *
  383. * @dev: device to configure
  384. * @id_in: optional input id const value pointer
  385. *
  386. * Returns: 0 on success, <0 on failure
  387. */
  388. int rimt_iommu_configure_id(struct device *dev, const u32 *id_in)
  389. {
  390. struct acpi_rimt_node *node;
  391. int err = -ENODEV;
  392. if (dev_is_pci(dev)) {
  393. struct iommu_fwspec *fwspec;
  394. struct pci_bus *bus = to_pci_dev(dev)->bus;
  395. struct rimt_pci_alias_info info = { .dev = dev };
  396. node = rimt_scan_node(ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX, &bus->dev);
  397. if (!node)
  398. return -ENODEV;
  399. info.node = node;
  400. err = pci_for_each_dma_alias(to_pci_dev(dev),
  401. rimt_pci_iommu_init, &info);
  402. fwspec = dev_iommu_fwspec_get(dev);
  403. if (fwspec && rimt_pcie_rc_supports_ats(node))
  404. fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
  405. } else {
  406. node = rimt_scan_node(ACPI_RIMT_NODE_TYPE_PLAT_DEVICE, dev);
  407. if (!node)
  408. return -ENODEV;
  409. err = id_in ? rimt_plat_iommu_map_id(dev, node, id_in) :
  410. rimt_plat_iommu_map(dev, node);
  411. }
  412. return err;
  413. }
  414. #endif
  415. void __init riscv_acpi_rimt_init(void)
  416. {
  417. acpi_status status;
  418. /* rimt_table will be used at runtime after the rimt init,
  419. * so we don't need to call acpi_put_table() to release
  420. * the RIMT table mapping.
  421. */
  422. status = acpi_get_table(ACPI_SIG_RIMT, 0, &rimt_table);
  423. if (ACPI_FAILURE(status)) {
  424. if (status != AE_NOT_FOUND) {
  425. const char *msg = acpi_format_exception(status);
  426. pr_err("Failed to get table, %s\n", msg);
  427. }
  428. return;
  429. }
  430. }