1 /* $NetBSD: acpi_pci.c,v 1.29 2020/05/08 14:42:38 jmcneill Exp $ */ 2 3 /* 4 * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christoph Egger and Gregoire Sutre. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.29 2020/05/08 14:42:38 jmcneill Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/device.h> 36 #include <sys/kmem.h> 37 #include <sys/systm.h> 38 39 #include <dev/pci/pcireg.h> 40 #include <dev/pci/pcivar.h> 41 #include <dev/pci/pcidevs.h> 42 #include <dev/pci/ppbreg.h> 43 44 #include <dev/acpi/acpireg.h> 45 #include <dev/acpi/acpivar.h> 46 #include <dev/acpi/acpi_pci.h> 47 48 #include "locators.h" 49 50 #define _COMPONENT ACPI_BUS_COMPONENT 51 ACPI_MODULE_NAME ("acpi_pci") 52 53 #define ACPI_HILODWORD(x) ACPI_HIWORD(ACPI_LODWORD((x))) 54 #define ACPI_LOLODWORD(x) ACPI_LOWORD(ACPI_LODWORD((x))) 55 56 static ACPI_STATUS acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *, 57 void *); 58 59 /* 60 * UUID for _DSM control method, from PCI Firmware Specification. 61 */ 62 static UINT8 acpi_pci_dsm_uuid[ACPI_UUID_LENGTH] = { 63 0xd0, 0x37, 0xc9, 0xe5, 0x53, 0x35, 0x7a, 0x4d, 64 0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d 65 }; 66 67 /* 68 * Regarding PCI Segment Groups (ACPI 4.0, p. 277): 69 * 70 * "The optional _SEG object is located under a PCI host bridge and 71 * evaluates to an integer that describes the PCI Segment Group (see PCI 72 * Firmware Specification v3.0)." 73 * 74 * "PCI Segment Group is purely a software concept managed by system 75 * firmware and used by OSPM. It is a logical collection of PCI buses 76 * (or bus segments). It is a way to logically group the PCI bus segments 77 * and PCI Express Hierarchies. _SEG is a level higher than _BBN." 78 * 79 * "PCI Segment Group supports more than 256 buses in a system by allowing 80 * the reuse of the PCI bus numbers. Within each PCI Segment Group, the bus 81 * numbers for the PCI buses must be unique. PCI buses in different PCI 82 * Segment Group are permitted to have the same bus number." 83 */ 84 85 /* 86 * Regarding PCI Base Bus Numbers (ACPI 4.0, p. 277): 87 * 88 * "For multi-root PCI platforms, the _BBN object evaluates to the PCI bus 89 * number that the BIOS assigns. This is needed to access a PCI_Config 90 * operation region for the specified bus. The _BBN object is located under 91 * a PCI host bridge and must be unique for every host bridge within a 92 * segment since it is the PCI bus number." 93 * 94 * Moreover, the ACPI FAQ (http://www.acpi.info/acpi_faq.htm) says: 95 * 96 * "For a multiple root bus machine, _BBN is required for each bus. _BBN 97 * should provide the bus number assigned to this bus by the BIOS at boot 98 * time." 99 */ 100 101 /* 102 * acpi_pcidev_pciroot_bus: 103 * 104 * Derive the PCI bus number of a PCI root bridge from its resources. 105 * If successful, return AE_OK and fill *busp. Otherwise, return an 106 * exception code and leave *busp unchanged. 107 */ 108 ACPI_STATUS 109 acpi_pcidev_pciroot_bus(ACPI_HANDLE handle, uint16_t *busp) 110 { 111 ACPI_STATUS rv; 112 int32_t bus; 113 114 bus = -1; 115 116 /* 117 * XXX: Use the ACPI resource parsing functions (acpi_resource.c) 118 * once bus number ranges have been implemented there. 119 */ 120 rv = AcpiWalkResources(handle, "_CRS", 121 acpi_pcidev_pciroot_bus_callback, &bus); 122 123 if (ACPI_FAILURE(rv)) 124 return rv; 125 126 if (bus == -1) 127 return AE_NOT_EXIST; 128 129 /* Here it holds that 0 <= bus <= 0xFFFF. */ 130 *busp = (uint16_t)bus; 131 132 return rv; 133 } 134 135 static ACPI_STATUS 136 acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *res, void *context) 137 { 138 ACPI_RESOURCE_ADDRESS64 addr64; 139 int32_t *bus = context; 140 141 /* Always continue the walk by returning AE_OK. */ 142 if ((res->Type != ACPI_RESOURCE_TYPE_ADDRESS16) && 143 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS32) && 144 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS64)) 145 return AE_OK; 146 147 if (ACPI_FAILURE(AcpiResourceToAddress64(res, &addr64))) 148 return AE_OK; 149 150 if (addr64.ResourceType != ACPI_BUS_NUMBER_RANGE) 151 return AE_OK; 152 153 if (*bus != -1) 154 return AE_ALREADY_EXISTS; 155 156 if (addr64.Address.Minimum > 0xFFFF) 157 return AE_BAD_DATA; 158 159 *bus = (int32_t)addr64.Address.Minimum; 160 161 return AE_OK; 162 } 163 164 /* 165 * acpi_pcidev_scan: 166 * 167 * Scan the ACPI device tree for PCI devices. A node is detected as a 168 * PCI device if it has an ancestor that is a PCI root bridge and such 169 * that all intermediate nodes are PCI-to-PCI bridges. Depth-first 170 * recursive implementation. 171 * 172 * PCI root bridges do not necessarily contain an _ADR, since they already 173 * contain an _HID (ACPI 4.0a, p. 197). However we require an _ADR for 174 * all non-root PCI devices. 175 */ 176 ACPI_STATUS 177 acpi_pcidev_scan(struct acpi_devnode *ad) 178 { 179 struct acpi_devnode *child; 180 struct acpi_pci_info *ap; 181 ACPI_INTEGER val; 182 ACPI_STATUS rv; 183 184 ad->ad_pciinfo = NULL; 185 186 /* 187 * We attach PCI information only to devices that are present, 188 * enabled, and functioning properly. 189 * Note: there is a possible race condition, because _STA may 190 * have changed since ad->ad_devinfo->CurrentStatus was set. 191 */ 192 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE) 193 goto rec; 194 195 if (!acpi_device_present(ad->ad_handle)) 196 goto rec; 197 198 if (ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) { 199 200 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); 201 202 /* 203 * If no _SEG exist, all PCI bus segments are assumed 204 * to be in the PCI segment group 0 (ACPI 4.0, p. 277). 205 * The segment group number is conveyed in the lower 206 * 16 bits of _SEG (the other bits are all reserved). 207 */ 208 rv = acpi_eval_integer(ad->ad_handle, "_SEG", &val); 209 210 if (ACPI_SUCCESS(rv)) 211 ap->ap_segment = ACPI_LOWORD(val); 212 213 /* Try to get downstream bus number using _CRS first. */ 214 rv = acpi_pcidev_pciroot_bus(ad->ad_handle, &ap->ap_downbus); 215 216 if (ACPI_FAILURE(rv)) { 217 rv = acpi_eval_integer(ad->ad_handle, "_BBN", &val); 218 219 if (ACPI_SUCCESS(rv)) 220 ap->ap_downbus = ACPI_LOWORD(val); 221 } 222 223 if (ap->ap_downbus > 255) { 224 aprint_error_dev(ad->ad_root, 225 "invalid PCI downstream bus for %s\n", ad->ad_name); 226 kmem_free(ap, sizeof(*ap)); 227 goto rec; 228 } 229 230 ap->ap_flags |= ACPI_PCI_INFO_BRIDGE; 231 232 ap->ap_pc = acpi_get_pci_chipset_tag(acpi_softc, ap->ap_segment, ap->ap_downbus); 233 234 /* 235 * This ACPI node denotes a PCI root bridge, but it may also 236 * denote a PCI device on the bridge's downstream bus segment. 237 */ 238 if (ad->ad_devinfo->Valid & ACPI_VALID_ADR) { 239 ap->ap_bus = ap->ap_downbus; 240 ap->ap_device = 241 ACPI_HILODWORD(ad->ad_devinfo->Address); 242 ap->ap_function = 243 ACPI_LOLODWORD(ad->ad_devinfo->Address); 244 245 if (ap->ap_device > 31 || 246 (ap->ap_function > 7 && ap->ap_function != 0xFFFF)) 247 aprint_error_dev(ad->ad_root, 248 "invalid PCI address for %s\n", ad->ad_name); 249 else 250 ap->ap_flags |= ACPI_PCI_INFO_DEVICE; 251 } 252 253 ad->ad_pciinfo = ap; 254 255 goto rec; 256 } 257 258 if ((ad->ad_parent != NULL) && 259 (ad->ad_parent->ad_pciinfo != NULL) && 260 (ad->ad_parent->ad_pciinfo->ap_flags & ACPI_PCI_INFO_BRIDGE) && 261 (ad->ad_devinfo->Valid & ACPI_VALID_ADR)) { 262 263 /* 264 * Our parent is a PCI root bridge or a PCI-to-PCI 265 * bridge. We have the same PCI segment number, and 266 * our bus number is its downstream bus number. 267 */ 268 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); 269 270 ap->ap_pc = ad->ad_parent->ad_pciinfo->ap_pc; 271 ap->ap_segment = ad->ad_parent->ad_pciinfo->ap_segment; 272 ap->ap_bus = ad->ad_parent->ad_pciinfo->ap_downbus; 273 274 ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address); 275 ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address); 276 277 if (ap->ap_device > 31 || 278 (ap->ap_function > 7 && ap->ap_function != 0xFFFF)) { 279 aprint_error_dev(ad->ad_root, 280 "invalid PCI address for %s\n", ad->ad_name); 281 kmem_free(ap, sizeof(*ap)); 282 goto rec; 283 } 284 285 ap->ap_flags |= ACPI_PCI_INFO_DEVICE; 286 287 if (ap->ap_function == 0xFFFF) { 288 /* 289 * Assume that this device is not a PCI-to-PCI bridge. 290 * XXX: Do we need to be smarter? 291 */ 292 } else { 293 /* 294 * Check whether this device is a PCI-to-PCI 295 * bridge and get its secondary bus number. 296 */ 297 rv = acpi_pcidev_ppb_downbus( 298 ad->ad_parent->ad_pciinfo->ap_pc, 299 ap->ap_segment, ap->ap_bus, ap->ap_device, 300 ap->ap_function, &ap->ap_downbus); 301 302 if (ACPI_SUCCESS(rv)) 303 ap->ap_flags |= ACPI_PCI_INFO_BRIDGE; 304 } 305 306 ad->ad_pciinfo = ap; 307 308 goto rec; 309 } 310 311 rec: 312 SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list) { 313 rv = acpi_pcidev_scan(child); 314 315 if (ACPI_FAILURE(rv)) 316 return rv; 317 } 318 319 return AE_OK; 320 } 321 322 /* 323 * acpi_pcidev_ppb_downbus: 324 * 325 * Retrieve the secondary bus number of the PCI-to-PCI bridge having the 326 * given PCI id. If successful, return AE_OK and fill *downbus. 327 * Otherwise, return an exception code and leave *downbus unchanged. 328 * 329 * XXX Need to deal with PCI segment groups (see also acpica/OsdHardware.c). 330 */ 331 ACPI_STATUS 332 acpi_pcidev_ppb_downbus(pci_chipset_tag_t pc, uint16_t segment, uint16_t bus, 333 uint16_t device, uint16_t function, uint16_t *downbus) 334 { 335 pcitag_t tag; 336 pcireg_t val; 337 338 if (bus > 255 || device > 31 || function > 7) 339 return AE_BAD_PARAMETER; 340 341 tag = pci_make_tag(pc, bus, device, function); 342 343 /* Check that this device exists. */ 344 val = pci_conf_read(pc, tag, PCI_ID_REG); 345 346 if (PCI_VENDOR(val) == PCI_VENDOR_INVALID || 347 PCI_VENDOR(val) == 0) 348 return AE_NOT_EXIST; 349 350 /* Check that this device is a PCI-to-PCI bridge. */ 351 val = pci_conf_read(pc, tag, PCI_BHLC_REG); 352 353 if (PCI_HDRTYPE_TYPE(val) != PCI_HDRTYPE_PPB) 354 return AE_TYPE; 355 356 /* This is a PCI-to-PCI bridge. Get its secondary bus#. */ 357 val = pci_conf_read(pc, tag, PCI_BRIDGE_BUS_REG); 358 *downbus = PCI_BRIDGE_BUS_NUM_SECONDARY(val); 359 360 return AE_OK; 361 } 362 363 /* 364 * acpi_pcidev_find: 365 * 366 * Finds a PCI device in the ACPI name space. 367 * 368 * Returns an ACPI device node on success and NULL on failure. 369 */ 370 struct acpi_devnode * 371 acpi_pcidev_find(uint16_t segment, uint16_t bus, 372 uint16_t device, uint16_t function) 373 { 374 struct acpi_softc *sc = acpi_softc; 375 struct acpi_devnode *ad; 376 377 if (sc == NULL) 378 return NULL; 379 380 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 381 382 if (ad->ad_pciinfo != NULL && 383 (ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_DEVICE) && 384 ad->ad_pciinfo->ap_segment == segment && 385 ad->ad_pciinfo->ap_bus == bus && 386 ad->ad_pciinfo->ap_device == device && 387 ad->ad_pciinfo->ap_function == function) 388 return ad; 389 } 390 391 return NULL; 392 } 393 394 /* 395 * acpi_pcidev_get_tag: 396 * 397 * Returns a PCI chipset tag for a PCI device in the ACPI name space. 398 */ 399 pci_chipset_tag_t 400 acpi_pcidev_get_tag(uint16_t segment, uint16_t bus, 401 uint16_t device, uint16_t function) 402 { 403 struct acpi_devnode *ad; 404 405 ad = acpi_pcidev_find(segment, bus, device, function); 406 if (ad == NULL || ad->ad_pciinfo == NULL) 407 return NULL; 408 409 return ad->ad_pciinfo->ap_pc; 410 } 411 412 /* 413 * acpi_pciroot_find: 414 * 415 * Finds a PCI root bridge in the ACPI name space. 416 * 417 * Returns an ACPI device node on success and NULL on failure. 418 */ 419 struct acpi_devnode * 420 acpi_pciroot_find(uint16_t segment, uint16_t bus) 421 { 422 struct acpi_softc *sc = acpi_softc; 423 struct acpi_devnode *ad; 424 425 if (sc == NULL) 426 return NULL; 427 428 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 429 430 if (ad->ad_pciinfo != NULL && 431 (ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_BRIDGE) && 432 ad->ad_pciinfo->ap_segment == segment && 433 ad->ad_pciinfo->ap_bus == bus) 434 return ad; 435 } 436 437 return NULL; 438 } 439 440 /* 441 * acpi_pcidev_find_dev: 442 * 443 * Returns the device corresponding to the given PCI info, or NULL 444 * if it doesn't exist. 445 */ 446 device_t 447 acpi_pcidev_find_dev(struct acpi_devnode *ad) 448 { 449 struct acpi_pci_info *ap; 450 struct pci_softc *pci; 451 device_t dv, pr; 452 deviter_t di; 453 454 if (ad == NULL) 455 return NULL; 456 457 if (ad->ad_pciinfo == NULL) 458 return NULL; 459 460 ap = ad->ad_pciinfo; 461 462 if (ap->ap_function == 0xFFFF) 463 return NULL; 464 465 for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); 466 dv != NULL; dv = deviter_next(&di)) { 467 468 pr = device_parent(dv); 469 470 if (pr == NULL || device_is_a(pr, "pci") != true) 471 continue; 472 473 if (dv->dv_locators == NULL) /* This should not happen. */ 474 continue; 475 476 pci = device_private(pr); 477 478 if (pci->sc_bus == ap->ap_bus && 479 device_locator(dv, PCICF_DEV) == ap->ap_device && 480 device_locator(dv, PCICF_FUNCTION) == ap->ap_function) 481 break; 482 } 483 484 deviter_release(&di); 485 486 return dv; 487 } 488 489 /* 490 * acpi_pci_ignore_boot_config: 491 * 492 * Returns 1 if the operating system may ignore the boot configuration 493 * of PCI resources. 494 */ 495 ACPI_INTEGER 496 acpi_pci_ignore_boot_config(ACPI_HANDLE handle) 497 { 498 ACPI_OBJECT_LIST objs; 499 ACPI_OBJECT obj[4], *pobj; 500 ACPI_BUFFER buf; 501 ACPI_INTEGER ret; 502 503 objs.Count = 4; 504 objs.Pointer = obj; 505 obj[0].Type = ACPI_TYPE_BUFFER; 506 obj[0].Buffer.Length = ACPI_UUID_LENGTH; 507 obj[0].Buffer.Pointer = acpi_pci_dsm_uuid; 508 obj[1].Type = ACPI_TYPE_INTEGER; 509 obj[1].Integer.Value = 1; 510 obj[2].Type = ACPI_TYPE_INTEGER; 511 obj[2].Integer.Value = 5; 512 obj[3].Type = ACPI_TYPE_PACKAGE; 513 obj[3].Package.Count = 0; 514 obj[3].Package.Elements = NULL; 515 516 buf.Pointer = NULL; 517 buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 518 519 if (ACPI_FAILURE(AcpiEvaluateObject(handle, "_DSM", &objs, &buf)) || buf.Pointer == NULL) 520 return 1; 521 522 ret = 1; 523 524 pobj = buf.Pointer; 525 switch (pobj->Type) { 526 case ACPI_TYPE_INTEGER: 527 ret = pobj->Integer.Value; 528 break; 529 case ACPI_TYPE_PACKAGE: 530 if (pobj->Package.Count == 1 && pobj->Package.Elements[0].Type == ACPI_TYPE_INTEGER) 531 ret = pobj->Package.Elements[0].Integer.Value; 532 break; 533 } 534 535 ACPI_FREE(buf.Pointer); 536 537 return ret; 538 } 539