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