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 /** 65 * rimt_get_fwnode() - Retrieve fwnode associated with an RIMT node 66 * 67 * @node: RIMT table node to be looked-up 68 * 69 * Returns: fwnode_handle pointer on success, NULL on failure 70 */ 71 static struct fwnode_handle *rimt_get_fwnode(struct acpi_rimt_node *node) 72 { 73 struct fwnode_handle *fwnode = NULL; 74 struct rimt_fwnode *curr; 75 76 spin_lock(&rimt_fwnode_lock); 77 list_for_each_entry(curr, &rimt_fwnode_list, list) { 78 if (curr->rimt_node == node) { 79 fwnode = curr->fwnode; 80 break; 81 } 82 } 83 spin_unlock(&rimt_fwnode_lock); 84 85 return fwnode; 86 } 87 88 static acpi_status rimt_match_node_callback(struct acpi_rimt_node *node, 89 void *context) 90 { 91 acpi_status status = AE_NOT_FOUND; 92 struct device *dev = context; 93 94 if (node->type == ACPI_RIMT_NODE_TYPE_IOMMU) { 95 struct acpi_rimt_iommu *iommu_node = (struct acpi_rimt_iommu *)&node->node_data; 96 97 if (dev_is_pci(dev)) { 98 struct pci_dev *pdev; 99 u16 bdf; 100 101 pdev = to_pci_dev(dev); 102 bdf = PCI_DEVID(pdev->bus->number, pdev->devfn); 103 if ((pci_domain_nr(pdev->bus) == iommu_node->pcie_segment_number) && 104 bdf == iommu_node->pcie_bdf) { 105 status = AE_OK; 106 } else { 107 status = AE_NOT_FOUND; 108 } 109 } else { 110 struct platform_device *pdev = to_platform_device(dev); 111 struct resource *res; 112 113 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 114 if (res && res->start == iommu_node->base_address) 115 status = AE_OK; 116 else 117 status = AE_NOT_FOUND; 118 } 119 } else if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { 120 struct acpi_rimt_pcie_rc *pci_rc; 121 struct pci_bus *bus; 122 123 bus = to_pci_bus(dev); 124 pci_rc = (struct acpi_rimt_pcie_rc *)node->node_data; 125 126 /* 127 * It is assumed that PCI segment numbers maps one-to-one 128 * with root complexes. Each segment number can represent only 129 * one root complex. 130 */ 131 status = pci_rc->pcie_segment_number == pci_domain_nr(bus) ? 132 AE_OK : AE_NOT_FOUND; 133 } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { 134 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; 135 struct acpi_rimt_platform_device *ncomp; 136 struct device *plat_dev = dev; 137 struct acpi_device *adev; 138 139 /* 140 * Walk the device tree to find a device with an 141 * ACPI companion; there is no point in scanning 142 * RIMT for a device matching a platform device if 143 * the device does not have an ACPI companion to 144 * start with. 145 */ 146 do { 147 adev = ACPI_COMPANION(plat_dev); 148 if (adev) 149 break; 150 151 plat_dev = plat_dev->parent; 152 } while (plat_dev); 153 154 if (!adev) 155 return status; 156 157 status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf); 158 if (ACPI_FAILURE(status)) { 159 dev_warn(plat_dev, "Can't get device full path name\n"); 160 return status; 161 } 162 163 ncomp = (struct acpi_rimt_platform_device *)node->node_data; 164 status = !strcmp(ncomp->device_name, buf.pointer) ? 165 AE_OK : AE_NOT_FOUND; 166 acpi_os_free(buf.pointer); 167 } 168 169 return status; 170 } 171 172 static struct acpi_rimt_node *rimt_scan_node(enum acpi_rimt_node_type type, 173 void *context) 174 { 175 struct acpi_rimt_node *rimt_node, *rimt_end; 176 struct acpi_table_rimt *rimt; 177 int i; 178 179 if (!rimt_table) 180 return NULL; 181 182 /* Get the first RIMT node */ 183 rimt = (struct acpi_table_rimt *)rimt_table; 184 rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt, 185 rimt->node_offset); 186 rimt_end = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table, 187 rimt_table->length); 188 189 for (i = 0; i < rimt->num_nodes; i++) { 190 if (WARN_TAINT(rimt_node >= rimt_end, TAINT_FIRMWARE_WORKAROUND, 191 "RIMT node pointer overflows, bad table!\n")) 192 return NULL; 193 194 if (rimt_node->type == type && 195 ACPI_SUCCESS(rimt_match_node_callback(rimt_node, context))) 196 return rimt_node; 197 198 rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_node, 199 rimt_node->length); 200 } 201 202 return NULL; 203 } 204 205 static bool rimt_pcie_rc_supports_ats(struct acpi_rimt_node *node) 206 { 207 struct acpi_rimt_pcie_rc *pci_rc; 208 209 pci_rc = (struct acpi_rimt_pcie_rc *)node->node_data; 210 return pci_rc->flags & ACPI_RIMT_PCIE_ATS_SUPPORTED; 211 } 212 213 static int rimt_iommu_xlate(struct device *dev, struct acpi_rimt_node *node, u32 deviceid) 214 { 215 struct fwnode_handle *rimt_fwnode; 216 217 if (!node) 218 return -ENODEV; 219 220 rimt_fwnode = rimt_get_fwnode(node); 221 222 /* 223 * The IOMMU drivers may not be probed yet. 224 * Defer the IOMMU configuration 225 */ 226 if (!rimt_fwnode) 227 return -EPROBE_DEFER; 228 229 return acpi_iommu_fwspec_init(dev, deviceid, rimt_fwnode); 230 } 231 232 struct rimt_pci_alias_info { 233 struct device *dev; 234 struct acpi_rimt_node *node; 235 const struct iommu_ops *ops; 236 }; 237 238 static int rimt_id_map(struct acpi_rimt_id_mapping *map, u8 type, u32 rid_in, u32 *rid_out) 239 { 240 if (rid_in < map->source_id_base || 241 (rid_in > map->source_id_base + map->num_ids)) 242 return -ENXIO; 243 244 *rid_out = map->dest_id_base + (rid_in - map->source_id_base); 245 return 0; 246 } 247 248 static struct acpi_rimt_node *rimt_node_get_id(struct acpi_rimt_node *node, 249 u32 *id_out, int index) 250 { 251 struct acpi_rimt_platform_device *plat_node; 252 u32 id_mapping_offset, num_id_mapping; 253 struct acpi_rimt_pcie_rc *pci_node; 254 struct acpi_rimt_id_mapping *map; 255 struct acpi_rimt_node *parent; 256 257 if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { 258 pci_node = (struct acpi_rimt_pcie_rc *)&node->node_data; 259 id_mapping_offset = pci_node->id_mapping_offset; 260 num_id_mapping = pci_node->num_id_mappings; 261 } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { 262 plat_node = (struct acpi_rimt_platform_device *)&node->node_data; 263 id_mapping_offset = plat_node->id_mapping_offset; 264 num_id_mapping = plat_node->num_id_mappings; 265 } else { 266 return NULL; 267 } 268 269 if (!id_mapping_offset || !num_id_mapping || index >= num_id_mapping) 270 return NULL; 271 272 map = ACPI_ADD_PTR(struct acpi_rimt_id_mapping, node, 273 id_mapping_offset + index * sizeof(*map)); 274 275 /* Firmware bug! */ 276 if (!map->dest_offset) { 277 pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", 278 node, node->type); 279 return NULL; 280 } 281 282 parent = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table, map->dest_offset); 283 284 if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE || 285 node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { 286 *id_out = map->dest_id_base; 287 return parent; 288 } 289 290 return NULL; 291 } 292 293 /* 294 * RISC-V supports IOMMU as a PCI device or a platform device. 295 * When it is a platform device, there should be a namespace device as 296 * well along with RIMT. To create the link between RIMT information and 297 * the platform device, the IOMMU driver should register itself with the 298 * RIMT module. This is true for PCI based IOMMU as well. 299 */ 300 int rimt_iommu_register(struct device *dev) 301 { 302 struct fwnode_handle *rimt_fwnode; 303 struct acpi_rimt_node *node; 304 305 node = rimt_scan_node(ACPI_RIMT_NODE_TYPE_IOMMU, dev); 306 if (!node) { 307 pr_err("Could not find IOMMU node in RIMT\n"); 308 return -ENODEV; 309 } 310 311 if (dev_is_pci(dev)) { 312 rimt_fwnode = acpi_alloc_fwnode_static(); 313 if (!rimt_fwnode) 314 return -ENOMEM; 315 316 rimt_fwnode->dev = dev; 317 if (!dev->fwnode) 318 dev->fwnode = rimt_fwnode; 319 320 rimt_set_fwnode(node, rimt_fwnode); 321 } else { 322 rimt_set_fwnode(node, dev->fwnode); 323 } 324 325 return 0; 326 } 327 328 #ifdef CONFIG_IOMMU_API 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