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