1 /* 2 * Copyright (C) 2016, Semihalf 3 * Author: Tomasz Nowicki <tn@semihalf.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * This file implements early detection/parsing of I/O mapping 15 * reported to OS through firmware via I/O Remapping Table (IORT) 16 * IORT document number: ARM DEN 0049A 17 */ 18 19 #define pr_fmt(fmt) "ACPI: IORT: " fmt 20 21 #include <linux/acpi_iort.h> 22 #include <linux/kernel.h> 23 #include <linux/pci.h> 24 25 struct iort_its_msi_chip { 26 struct list_head list; 27 struct fwnode_handle *fw_node; 28 u32 translation_id; 29 }; 30 31 typedef acpi_status (*iort_find_node_callback) 32 (struct acpi_iort_node *node, void *context); 33 34 /* Root pointer to the mapped IORT table */ 35 static struct acpi_table_header *iort_table; 36 37 static LIST_HEAD(iort_msi_chip_list); 38 static DEFINE_SPINLOCK(iort_msi_chip_lock); 39 40 /** 41 * iort_register_domain_token() - register domain token and related ITS ID 42 * to the list from where we can get it back later on. 43 * @trans_id: ITS ID. 44 * @fw_node: Domain token. 45 * 46 * Returns: 0 on success, -ENOMEM if no memory when allocating list element 47 */ 48 int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node) 49 { 50 struct iort_its_msi_chip *its_msi_chip; 51 52 its_msi_chip = kzalloc(sizeof(*its_msi_chip), GFP_KERNEL); 53 if (!its_msi_chip) 54 return -ENOMEM; 55 56 its_msi_chip->fw_node = fw_node; 57 its_msi_chip->translation_id = trans_id; 58 59 spin_lock(&iort_msi_chip_lock); 60 list_add(&its_msi_chip->list, &iort_msi_chip_list); 61 spin_unlock(&iort_msi_chip_lock); 62 63 return 0; 64 } 65 66 /** 67 * iort_deregister_domain_token() - Deregister domain token based on ITS ID 68 * @trans_id: ITS ID. 69 * 70 * Returns: none. 71 */ 72 void iort_deregister_domain_token(int trans_id) 73 { 74 struct iort_its_msi_chip *its_msi_chip, *t; 75 76 spin_lock(&iort_msi_chip_lock); 77 list_for_each_entry_safe(its_msi_chip, t, &iort_msi_chip_list, list) { 78 if (its_msi_chip->translation_id == trans_id) { 79 list_del(&its_msi_chip->list); 80 kfree(its_msi_chip); 81 break; 82 } 83 } 84 spin_unlock(&iort_msi_chip_lock); 85 } 86 87 /** 88 * iort_find_domain_token() - Find domain token based on given ITS ID 89 * @trans_id: ITS ID. 90 * 91 * Returns: domain token when find on the list, NULL otherwise 92 */ 93 struct fwnode_handle *iort_find_domain_token(int trans_id) 94 { 95 struct fwnode_handle *fw_node = NULL; 96 struct iort_its_msi_chip *its_msi_chip; 97 98 spin_lock(&iort_msi_chip_lock); 99 list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) { 100 if (its_msi_chip->translation_id == trans_id) { 101 fw_node = its_msi_chip->fw_node; 102 break; 103 } 104 } 105 spin_unlock(&iort_msi_chip_lock); 106 107 return fw_node; 108 } 109 110 static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type, 111 iort_find_node_callback callback, 112 void *context) 113 { 114 struct acpi_iort_node *iort_node, *iort_end; 115 struct acpi_table_iort *iort; 116 int i; 117 118 if (!iort_table) 119 return NULL; 120 121 /* Get the first IORT node */ 122 iort = (struct acpi_table_iort *)iort_table; 123 iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort, 124 iort->node_offset); 125 iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, 126 iort_table->length); 127 128 for (i = 0; i < iort->node_count; i++) { 129 if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND, 130 "IORT node pointer overflows, bad table!\n")) 131 return NULL; 132 133 if (iort_node->type == type && 134 ACPI_SUCCESS(callback(iort_node, context))) 135 return iort_node; 136 137 iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node, 138 iort_node->length); 139 } 140 141 return NULL; 142 } 143 144 static acpi_status iort_match_node_callback(struct acpi_iort_node *node, 145 void *context) 146 { 147 struct device *dev = context; 148 acpi_status status; 149 150 if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) { 151 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; 152 struct acpi_device *adev = to_acpi_device_node(dev->fwnode); 153 struct acpi_iort_named_component *ncomp; 154 155 if (!adev) { 156 status = AE_NOT_FOUND; 157 goto out; 158 } 159 160 status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf); 161 if (ACPI_FAILURE(status)) { 162 dev_warn(dev, "Can't get device full path name\n"); 163 goto out; 164 } 165 166 ncomp = (struct acpi_iort_named_component *)node->node_data; 167 status = !strcmp(ncomp->device_name, buf.pointer) ? 168 AE_OK : AE_NOT_FOUND; 169 acpi_os_free(buf.pointer); 170 } else if (node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { 171 struct acpi_iort_root_complex *pci_rc; 172 struct pci_bus *bus; 173 174 bus = to_pci_bus(dev); 175 pci_rc = (struct acpi_iort_root_complex *)node->node_data; 176 177 /* 178 * It is assumed that PCI segment numbers maps one-to-one 179 * with root complexes. Each segment number can represent only 180 * one root complex. 181 */ 182 status = pci_rc->pci_segment_number == pci_domain_nr(bus) ? 183 AE_OK : AE_NOT_FOUND; 184 } else { 185 status = AE_NOT_FOUND; 186 } 187 out: 188 return status; 189 } 190 191 static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in, 192 u32 *rid_out) 193 { 194 /* Single mapping does not care for input id */ 195 if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) { 196 if (type == ACPI_IORT_NODE_NAMED_COMPONENT || 197 type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { 198 *rid_out = map->output_base; 199 return 0; 200 } 201 202 pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n", 203 map, type); 204 return -ENXIO; 205 } 206 207 if (rid_in < map->input_base || 208 (rid_in >= map->input_base + map->id_count)) 209 return -ENXIO; 210 211 *rid_out = map->output_base + (rid_in - map->input_base); 212 return 0; 213 } 214 215 static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node, 216 u32 rid_in, u32 *rid_out, 217 u8 type) 218 { 219 u32 rid = rid_in; 220 221 /* Parse the ID mapping tree to find specified node type */ 222 while (node) { 223 struct acpi_iort_id_mapping *map; 224 int i; 225 226 if (node->type == type) { 227 if (rid_out) 228 *rid_out = rid; 229 return node; 230 } 231 232 if (!node->mapping_offset || !node->mapping_count) 233 goto fail_map; 234 235 map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, 236 node->mapping_offset); 237 238 /* Firmware bug! */ 239 if (!map->output_reference) { 240 pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", 241 node, node->type); 242 goto fail_map; 243 } 244 245 /* Do the RID translation */ 246 for (i = 0; i < node->mapping_count; i++, map++) { 247 if (!iort_id_map(map, node->type, rid, &rid)) 248 break; 249 } 250 251 if (i == node->mapping_count) 252 goto fail_map; 253 254 node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, 255 map->output_reference); 256 } 257 258 fail_map: 259 /* Map input RID to output RID unchanged on mapping failure*/ 260 if (rid_out) 261 *rid_out = rid_in; 262 263 return NULL; 264 } 265 266 static struct acpi_iort_node *iort_find_dev_node(struct device *dev) 267 { 268 struct pci_bus *pbus; 269 270 if (!dev_is_pci(dev)) 271 return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, 272 iort_match_node_callback, dev); 273 274 /* Find a PCI root bus */ 275 pbus = to_pci_dev(dev)->bus; 276 while (!pci_is_root_bus(pbus)) 277 pbus = pbus->parent; 278 279 return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, 280 iort_match_node_callback, &pbus->dev); 281 } 282 283 /** 284 * iort_msi_map_rid() - Map a MSI requester ID for a device 285 * @dev: The device for which the mapping is to be done. 286 * @req_id: The device requester ID. 287 * 288 * Returns: mapped MSI RID on success, input requester ID otherwise 289 */ 290 u32 iort_msi_map_rid(struct device *dev, u32 req_id) 291 { 292 struct acpi_iort_node *node; 293 u32 dev_id; 294 295 node = iort_find_dev_node(dev); 296 if (!node) 297 return req_id; 298 299 iort_node_map_rid(node, req_id, &dev_id, ACPI_IORT_NODE_ITS_GROUP); 300 return dev_id; 301 } 302 303 /** 304 * iort_dev_find_its_id() - Find the ITS identifier for a device 305 * @dev: The device. 306 * @idx: Index of the ITS identifier list. 307 * @its_id: ITS identifier. 308 * 309 * Returns: 0 on success, appropriate error value otherwise 310 */ 311 static int iort_dev_find_its_id(struct device *dev, u32 req_id, 312 unsigned int idx, int *its_id) 313 { 314 struct acpi_iort_its_group *its; 315 struct acpi_iort_node *node; 316 317 node = iort_find_dev_node(dev); 318 if (!node) 319 return -ENXIO; 320 321 node = iort_node_map_rid(node, req_id, NULL, ACPI_IORT_NODE_ITS_GROUP); 322 if (!node) 323 return -ENXIO; 324 325 /* Move to ITS specific data */ 326 its = (struct acpi_iort_its_group *)node->node_data; 327 if (idx > its->its_count) { 328 dev_err(dev, "requested ITS ID index [%d] is greater than available [%d]\n", 329 idx, its->its_count); 330 return -ENXIO; 331 } 332 333 *its_id = its->identifiers[idx]; 334 return 0; 335 } 336 337 /** 338 * iort_get_device_domain() - Find MSI domain related to a device 339 * @dev: The device. 340 * @req_id: Requester ID for the device. 341 * 342 * Returns: the MSI domain for this device, NULL otherwise 343 */ 344 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) 345 { 346 struct fwnode_handle *handle; 347 int its_id; 348 349 if (iort_dev_find_its_id(dev, req_id, 0, &its_id)) 350 return NULL; 351 352 handle = iort_find_domain_token(its_id); 353 if (!handle) 354 return NULL; 355 356 return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI); 357 } 358 359 void __init acpi_iort_init(void) 360 { 361 acpi_status status; 362 363 status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table); 364 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 365 const char *msg = acpi_format_exception(status); 366 pr_err("Failed to get table, %s\n", msg); 367 } 368 } 369