1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org> 3 * Copyright (c) 2017 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Landon Fuller 7 * under sponsorship from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer, 14 * without modification. 15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 16 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 17 * redistribution must be conditioned upon including a substantially 18 * similar Disclaimer requirement for further binary redistribution. 19 * 20 * NO WARRANTY 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 25 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 26 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 29 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGES. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include <sys/param.h> 38 #include <sys/bus.h> 39 #include <sys/refcount.h> 40 #include <sys/systm.h> 41 42 #include <machine/bus.h> 43 #include <sys/rman.h> 44 #include <machine/resource.h> 45 46 #include <dev/bhnd/siba/sibareg.h> 47 48 #include <dev/bhnd/cores/chipc/chipcreg.h> 49 50 #include "nvram/bhnd_nvram.h" 51 52 #include "bhnd_chipc_if.h" 53 54 #include "bhnd_nvram_if.h" 55 #include "bhnd_nvram_map.h" 56 57 #include "bhndreg.h" 58 #include "bhndvar.h" 59 #include "bhnd_private.h" 60 61 static void bhnd_service_registry_free_entry( 62 struct bhnd_service_entry *entry); 63 64 static int compare_ascending_probe_order(const void *lhs, const void *rhs); 65 static int compare_descending_probe_order(const void *lhs, 66 const void *rhs); 67 68 /* BHND core device description table. */ 69 static const struct bhnd_core_desc { 70 uint16_t vendor; 71 uint16_t device; 72 bhnd_devclass_t class; 73 const char *desc; 74 } bhnd_core_descs[] = { 75 #define BHND_CDESC(_mfg, _cid, _cls, _desc) \ 76 { BHND_MFGID_ ## _mfg, BHND_COREID_ ## _cid, \ 77 BHND_DEVCLASS_ ## _cls, _desc } 78 79 BHND_CDESC(BCM, CC, CC, "ChipCommon I/O Controller"), 80 BHND_CDESC(BCM, ILINE20, OTHER, "iLine20 HPNA"), 81 BHND_CDESC(BCM, SRAM, RAM, "SRAM"), 82 BHND_CDESC(BCM, SDRAM, RAM, "SDRAM"), 83 BHND_CDESC(BCM, PCI, PCI, "PCI Bridge"), 84 BHND_CDESC(BCM, MIPS, CPU, "BMIPS CPU"), 85 BHND_CDESC(BCM, ENET, ENET_MAC, "Fast Ethernet MAC"), 86 BHND_CDESC(BCM, CODEC, OTHER, "V.90 Modem Codec"), 87 BHND_CDESC(BCM, USB, USB_DUAL, "USB 1.1 Device/Host Controller"), 88 BHND_CDESC(BCM, ADSL, OTHER, "ADSL Core"), 89 BHND_CDESC(BCM, ILINE100, OTHER, "iLine100 HPNA"), 90 BHND_CDESC(BCM, IPSEC, OTHER, "IPsec Accelerator"), 91 BHND_CDESC(BCM, UTOPIA, OTHER, "UTOPIA ATM Core"), 92 BHND_CDESC(BCM, PCMCIA, PCCARD, "PCMCIA Bridge"), 93 BHND_CDESC(BCM, SOCRAM, RAM, "Internal Memory"), 94 BHND_CDESC(BCM, MEMC, MEMC, "MEMC SDRAM Controller"), 95 BHND_CDESC(BCM, OFDM, OTHER, "OFDM PHY"), 96 BHND_CDESC(BCM, EXTIF, OTHER, "External Interface"), 97 BHND_CDESC(BCM, D11, WLAN, "802.11 MAC/PHY/Radio"), 98 BHND_CDESC(BCM, APHY, WLAN_PHY, "802.11a PHY"), 99 BHND_CDESC(BCM, BPHY, WLAN_PHY, "802.11b PHY"), 100 BHND_CDESC(BCM, GPHY, WLAN_PHY, "802.11g PHY"), 101 BHND_CDESC(BCM, MIPS33, CPU, "BMIPS33 CPU"), 102 BHND_CDESC(BCM, USB11H, USB_HOST, "USB 1.1 Host Controller"), 103 BHND_CDESC(BCM, USB11D, USB_DEV, "USB 1.1 Device Controller"), 104 BHND_CDESC(BCM, USB20H, USB_HOST, "USB 2.0 Host Controller"), 105 BHND_CDESC(BCM, USB20D, USB_DEV, "USB 2.0 Device Controller"), 106 BHND_CDESC(BCM, SDIOH, OTHER, "SDIO Host Controller"), 107 BHND_CDESC(BCM, ROBO, OTHER, "RoboSwitch"), 108 BHND_CDESC(BCM, ATA100, OTHER, "Parallel ATA Controller"), 109 BHND_CDESC(BCM, SATAXOR, OTHER, "SATA DMA/XOR Controller"), 110 BHND_CDESC(BCM, GIGETH, ENET_MAC, "Gigabit Ethernet MAC"), 111 BHND_CDESC(BCM, PCIE, PCIE, "PCIe Bridge"), 112 BHND_CDESC(BCM, NPHY, WLAN_PHY, "802.11n 2x2 PHY"), 113 BHND_CDESC(BCM, SRAMC, MEMC, "SRAM Controller"), 114 BHND_CDESC(BCM, MINIMAC, OTHER, "MINI MAC/PHY"), 115 BHND_CDESC(BCM, ARM11, CPU, "ARM1176 CPU"), 116 BHND_CDESC(BCM, ARM7S, CPU, "ARM7TDMI-S CPU"), 117 BHND_CDESC(BCM, LPPHY, WLAN_PHY, "802.11a/b/g PHY"), 118 BHND_CDESC(BCM, PMU, PMU, "PMU"), 119 BHND_CDESC(BCM, SSNPHY, WLAN_PHY, "802.11n Single-Stream PHY"), 120 BHND_CDESC(BCM, SDIOD, OTHER, "SDIO Device Core"), 121 BHND_CDESC(BCM, ARMCM3, CPU, "ARM Cortex-M3 CPU"), 122 BHND_CDESC(BCM, HTPHY, WLAN_PHY, "802.11n 4x4 PHY"), 123 BHND_CDESC(MIPS,MIPS74K, CPU, "MIPS74k CPU"), 124 BHND_CDESC(BCM, GMAC, ENET_MAC, "Gigabit MAC core"), 125 BHND_CDESC(BCM, DMEMC, MEMC, "DDR1/DDR2 Memory Controller"), 126 BHND_CDESC(BCM, PCIERC, OTHER, "PCIe Root Complex"), 127 BHND_CDESC(BCM, OCP, SOC_BRIDGE, "OCP to OCP Bridge"), 128 BHND_CDESC(BCM, SC, OTHER, "Shared Common Core"), 129 BHND_CDESC(BCM, AHB, SOC_BRIDGE, "OCP to AHB Bridge"), 130 BHND_CDESC(BCM, SPIH, OTHER, "SPI Host Controller"), 131 BHND_CDESC(BCM, I2S, OTHER, "I2S Digital Audio Interface"), 132 BHND_CDESC(BCM, DMEMS, MEMC, "SDR/DDR1 Memory Controller"), 133 BHND_CDESC(BCM, UBUS_SHIM, OTHER, "BCM6362/UBUS WLAN SHIM"), 134 BHND_CDESC(BCM, PCIE2, PCIE, "PCIe Bridge (Gen2)"), 135 136 BHND_CDESC(ARM, APB_BRIDGE, SOC_BRIDGE, "BP135 AMBA3 AXI to APB Bridge"), 137 BHND_CDESC(ARM, PL301, SOC_ROUTER, "PL301 AMBA3 Interconnect"), 138 BHND_CDESC(ARM, EROM, EROM, "PL366 Device Enumeration ROM"), 139 BHND_CDESC(ARM, OOB_ROUTER, OTHER, "PL367 OOB Interrupt Router"), 140 BHND_CDESC(ARM, AXI_UNMAPPED, OTHER, "Unmapped Address Ranges"), 141 142 BHND_CDESC(BCM, 4706_CC, CC, "ChipCommon I/O Controller"), 143 BHND_CDESC(BCM, NS_PCIE2, PCIE, "PCIe Bridge (Gen2)"), 144 BHND_CDESC(BCM, NS_DMA, OTHER, "DMA engine"), 145 BHND_CDESC(BCM, NS_SDIO, OTHER, "SDIO 3.0 Host Controller"), 146 BHND_CDESC(BCM, NS_USB20H, USB_HOST, "USB 2.0 Host Controller"), 147 BHND_CDESC(BCM, NS_USB30H, USB_HOST, "USB 3.0 Host Controller"), 148 BHND_CDESC(BCM, NS_A9JTAG, OTHER, "ARM Cortex A9 JTAG Interface"), 149 BHND_CDESC(BCM, NS_DDR23_MEMC, MEMC, "Denali DDR2/DD3 Memory Controller"), 150 BHND_CDESC(BCM, NS_ROM, NVRAM, "System ROM"), 151 BHND_CDESC(BCM, NS_NAND, NVRAM, "NAND Flash Controller"), 152 BHND_CDESC(BCM, NS_QSPI, NVRAM, "QSPI Flash Controller"), 153 BHND_CDESC(BCM, NS_CC_B, CC_B, "ChipCommon B Auxiliary I/O Controller"), 154 BHND_CDESC(BCM, 4706_SOCRAM, RAM, "Internal Memory"), 155 BHND_CDESC(BCM, IHOST_ARMCA9, CPU, "ARM Cortex A9 CPU"), 156 BHND_CDESC(BCM, 4706_GMAC_CMN, ENET, "Gigabit MAC (Common)"), 157 BHND_CDESC(BCM, 4706_GMAC, ENET_MAC, "Gigabit MAC"), 158 BHND_CDESC(BCM, AMEMC, MEMC, "Denali DDR1/DDR2 Memory Controller"), 159 #undef BHND_CDESC 160 161 /* Derived from inspection of the BCM4331 cores that provide PrimeCell 162 * IDs. Due to lack of documentation, the surmised device name/purpose 163 * provided here may be incorrect. */ 164 { BHND_MFGID_ARM, BHND_PRIMEID_EROM, BHND_DEVCLASS_OTHER, 165 "PL364 Device Enumeration ROM" }, 166 { BHND_MFGID_ARM, BHND_PRIMEID_SWRAP, BHND_DEVCLASS_OTHER, 167 "PL368 Device Management Interface" }, 168 { BHND_MFGID_ARM, BHND_PRIMEID_MWRAP, BHND_DEVCLASS_OTHER, 169 "PL369 Device Management Interface" }, 170 171 { 0, 0, 0, NULL } 172 }; 173 174 static const struct bhnd_device_quirk bhnd_chipc_clkctl_quirks[]; 175 static const struct bhnd_device_quirk bhnd_pcmcia_clkctl_quirks[]; 176 177 /** 178 * Device table entries for core-specific CLKCTL quirk lookup. 179 */ 180 static const struct bhnd_device bhnd_clkctl_devices[] = { 181 BHND_DEVICE(BCM, CC, NULL, bhnd_chipc_clkctl_quirks), 182 BHND_DEVICE(BCM, PCMCIA, NULL, bhnd_pcmcia_clkctl_quirks), 183 BHND_DEVICE_END, 184 }; 185 186 /** ChipCommon CLKCTL quirks */ 187 static const struct bhnd_device_quirk bhnd_chipc_clkctl_quirks[] = { 188 /* HTAVAIL/ALPAVAIL are bitswapped in chipc's CLKCTL */ 189 BHND_CHIP_QUIRK(4328, HWREV_ANY, BHND_CLKCTL_QUIRK_CCS0), 190 BHND_CHIP_QUIRK(5354, HWREV_ANY, BHND_CLKCTL_QUIRK_CCS0), 191 BHND_DEVICE_QUIRK_END 192 }; 193 194 /** PCMCIA CLKCTL quirks */ 195 static const struct bhnd_device_quirk bhnd_pcmcia_clkctl_quirks[] = { 196 /* HTAVAIL/ALPAVAIL are bitswapped in pcmcia's CLKCTL */ 197 BHND_CHIP_QUIRK(4328, HWREV_ANY, BHND_CLKCTL_QUIRK_CCS0), 198 BHND_CHIP_QUIRK(5354, HWREV_ANY, BHND_CLKCTL_QUIRK_CCS0), 199 BHND_DEVICE_QUIRK_END 200 }; 201 202 /** 203 * Return the name for a given JEP106 manufacturer ID. 204 * 205 * @param vendor A JEP106 Manufacturer ID, including the non-standard ARM 4-bit 206 * JEP106 continuation code. 207 */ 208 const char * 209 bhnd_vendor_name(uint16_t vendor) 210 { 211 switch (vendor) { 212 case BHND_MFGID_ARM: 213 return "ARM"; 214 case BHND_MFGID_BCM: 215 return "Broadcom"; 216 case BHND_MFGID_MIPS: 217 return "MIPS"; 218 default: 219 return "unknown"; 220 } 221 } 222 223 /** 224 * Return the name of a port type. 225 */ 226 const char * 227 bhnd_port_type_name(bhnd_port_type port_type) 228 { 229 switch (port_type) { 230 case BHND_PORT_DEVICE: 231 return ("device"); 232 case BHND_PORT_BRIDGE: 233 return ("bridge"); 234 case BHND_PORT_AGENT: 235 return ("agent"); 236 default: 237 return "unknown"; 238 } 239 } 240 241 /** 242 * Return the name of an NVRAM source. 243 */ 244 const char * 245 bhnd_nvram_src_name(bhnd_nvram_src nvram_src) 246 { 247 switch (nvram_src) { 248 case BHND_NVRAM_SRC_FLASH: 249 return ("flash"); 250 case BHND_NVRAM_SRC_OTP: 251 return ("OTP"); 252 case BHND_NVRAM_SRC_SPROM: 253 return ("SPROM"); 254 case BHND_NVRAM_SRC_UNKNOWN: 255 return ("none"); 256 default: 257 return ("unknown"); 258 } 259 } 260 261 static const struct bhnd_core_desc * 262 bhnd_find_core_desc(uint16_t vendor, uint16_t device) 263 { 264 for (u_int i = 0; bhnd_core_descs[i].desc != NULL; i++) { 265 if (bhnd_core_descs[i].vendor != vendor) 266 continue; 267 268 if (bhnd_core_descs[i].device != device) 269 continue; 270 271 return (&bhnd_core_descs[i]); 272 } 273 274 return (NULL); 275 } 276 277 /** 278 * Return a human-readable name for a BHND core. 279 * 280 * @param vendor The core designer's JEDEC-106 Manufacturer ID 281 * @param device The core identifier. 282 */ 283 const char * 284 bhnd_find_core_name(uint16_t vendor, uint16_t device) 285 { 286 const struct bhnd_core_desc *desc; 287 288 if ((desc = bhnd_find_core_desc(vendor, device)) == NULL) 289 return ("unknown"); 290 291 return desc->desc; 292 } 293 294 /** 295 * Return the device class for a BHND core. 296 * 297 * @param vendor The core designer's JEDEC-106 Manufacturer ID 298 * @param device The core identifier. 299 */ 300 bhnd_devclass_t 301 bhnd_find_core_class(uint16_t vendor, uint16_t device) 302 { 303 const struct bhnd_core_desc *desc; 304 305 if ((desc = bhnd_find_core_desc(vendor, device)) == NULL) 306 return (BHND_DEVCLASS_OTHER); 307 308 return desc->class; 309 } 310 311 /** 312 * Return a human-readable name for a BHND core. 313 * 314 * @param ci The core's info record. 315 */ 316 const char * 317 bhnd_core_name(const struct bhnd_core_info *ci) 318 { 319 return bhnd_find_core_name(ci->vendor, ci->device); 320 } 321 322 /** 323 * Return the device class for a BHND core. 324 * 325 * @param ci The core's info record. 326 */ 327 bhnd_devclass_t 328 bhnd_core_class(const struct bhnd_core_info *ci) 329 { 330 return bhnd_find_core_class(ci->vendor, ci->device); 331 } 332 333 /** 334 * Write a human readable name representation of the given 335 * BHND_CHIPID_* constant to @p buffer. 336 * 337 * @param buffer Output buffer, or NULL to compute the required size. 338 * @param size Capacity of @p buffer, in bytes. 339 * @param chip_id Chip ID to be formatted. 340 * 341 * @return Returns the required number of bytes on success, or a negative 342 * integer on failure. No more than @p size-1 characters be written, with 343 * the @p size'th set to '\0'. 344 * 345 * @sa BHND_CHIPID_MAX_NAMELEN 346 */ 347 int 348 bhnd_format_chip_id(char *buffer, size_t size, uint16_t chip_id) 349 { 350 /* All hex formatted IDs are within the range of 0x4000-0x9C3F (40000-1) */ 351 if (chip_id >= 0x4000 && chip_id <= 0x9C3F) 352 return (snprintf(buffer, size, "BCM%hX", chip_id)); 353 else 354 return (snprintf(buffer, size, "BCM%hu", chip_id)); 355 } 356 357 /** 358 * Initialize a core info record with data from from a bhnd-attached @p dev. 359 * 360 * @param dev A bhnd device. 361 * @param core The record to be initialized. 362 */ 363 struct bhnd_core_info 364 bhnd_get_core_info(device_t dev) { 365 return (struct bhnd_core_info) { 366 .vendor = bhnd_get_vendor(dev), 367 .device = bhnd_get_device(dev), 368 .hwrev = bhnd_get_hwrev(dev), 369 .core_idx = bhnd_get_core_index(dev), 370 .unit = bhnd_get_core_unit(dev) 371 }; 372 } 373 374 /** 375 * Find a @p class child device with @p unit on @p bus. 376 * 377 * @param bus The bhnd-compatible bus to be searched. 378 * @param class The device class to match on. 379 * @param unit The core unit number; specify -1 to return the first match 380 * regardless of unit number. 381 * 382 * @retval device_t if a matching child device is found. 383 * @retval NULL if no matching child device is found. 384 */ 385 device_t 386 bhnd_bus_find_child(device_t bus, bhnd_devclass_t class, int unit) 387 { 388 struct bhnd_core_match md = { 389 BHND_MATCH_CORE_CLASS(class), 390 BHND_MATCH_CORE_UNIT(unit) 391 }; 392 393 if (unit == -1) 394 md.m.match.core_unit = 0; 395 396 return bhnd_bus_match_child(bus, &md); 397 } 398 399 /** 400 * Find the first child device on @p bus that matches @p desc. 401 * 402 * @param bus The bhnd-compatible bus to be searched. 403 * @param desc A match descriptor. 404 * 405 * @retval device_t if a matching child device is found. 406 * @retval NULL if no matching child device is found. 407 */ 408 device_t 409 bhnd_bus_match_child(device_t bus, const struct bhnd_core_match *desc) 410 { 411 device_t *devlistp; 412 device_t match; 413 int devcnt; 414 int error; 415 416 error = device_get_children(bus, &devlistp, &devcnt); 417 if (error != 0) 418 return (NULL); 419 420 match = NULL; 421 for (int i = 0; i < devcnt; i++) { 422 struct bhnd_core_info ci = bhnd_get_core_info(devlistp[i]); 423 424 if (bhnd_core_matches(&ci, desc)) { 425 match = devlistp[i]; 426 goto done; 427 } 428 } 429 430 done: 431 free(devlistp, M_TEMP); 432 return match; 433 } 434 435 /** 436 * Retrieve an ordered list of all device instances currently connected to 437 * @p bus, returning a pointer to the array in @p devlistp and the count 438 * in @p ndevs. 439 * 440 * The memory allocated for the table must be freed via 441 * bhnd_bus_free_children(). 442 * 443 * @param bus The bhnd-compatible bus to be queried. 444 * @param[out] devlist The array of devices. 445 * @param[out] devcount The number of devices in @p devlistp 446 * @param order The order in which devices will be returned 447 * in @p devlist. 448 * 449 * @retval 0 success 450 * @retval non-zero if an error occurs, a regular unix error code will 451 * be returned. 452 */ 453 int 454 bhnd_bus_get_children(device_t bus, device_t **devlist, int *devcount, 455 bhnd_device_order order) 456 { 457 int error; 458 459 /* Fetch device array */ 460 if ((error = device_get_children(bus, devlist, devcount))) 461 return (error); 462 463 /* Perform requested sorting */ 464 if ((error = bhnd_sort_devices(*devlist, *devcount, order))) { 465 bhnd_bus_free_children(*devlist); 466 return (error); 467 } 468 469 return (0); 470 } 471 472 /** 473 * Free any memory allocated in a previous call to bhnd_bus_get_children(). 474 * 475 * @param devlist The device array returned by bhnd_bus_get_children(). 476 */ 477 void 478 bhnd_bus_free_children(device_t *devlist) 479 { 480 free(devlist, M_TEMP); 481 } 482 483 /** 484 * Perform in-place sorting of an array of bhnd device instances. 485 * 486 * @param devlist An array of bhnd devices. 487 * @param devcount The number of devices in @p devs. 488 * @param order The sort order to be used. 489 */ 490 int 491 bhnd_sort_devices(device_t *devlist, size_t devcount, bhnd_device_order order) 492 { 493 int (*compare)(const void *, const void *); 494 495 switch (order) { 496 case BHND_DEVICE_ORDER_ATTACH: 497 compare = compare_ascending_probe_order; 498 break; 499 case BHND_DEVICE_ORDER_DETACH: 500 compare = compare_descending_probe_order; 501 break; 502 default: 503 printf("unknown sort order: %d\n", order); 504 return (EINVAL); 505 } 506 507 qsort(devlist, devcount, sizeof(*devlist), compare); 508 return (0); 509 } 510 511 /* 512 * Ascending comparison of bhnd device's probe order. 513 */ 514 static int 515 compare_ascending_probe_order(const void *lhs, const void *rhs) 516 { 517 device_t ldev, rdev; 518 int lorder, rorder; 519 520 ldev = (*(const device_t *) lhs); 521 rdev = (*(const device_t *) rhs); 522 523 lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 524 rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 525 526 if (lorder < rorder) { 527 return (-1); 528 } else if (lorder > rorder) { 529 return (1); 530 } else { 531 return (0); 532 } 533 } 534 535 /* 536 * Descending comparison of bhnd device's probe order. 537 */ 538 static int 539 compare_descending_probe_order(const void *lhs, const void *rhs) 540 { 541 return (compare_ascending_probe_order(rhs, lhs)); 542 } 543 544 /** 545 * Call device_probe_and_attach() for each of the bhnd bus device's 546 * children, in bhnd attach order. 547 * 548 * @param bus The bhnd-compatible bus for which all children should be probed 549 * and attached. 550 */ 551 int 552 bhnd_bus_probe_children(device_t bus) 553 { 554 device_t *devs; 555 int ndevs; 556 int error; 557 558 /* Fetch children in attach order */ 559 error = bhnd_bus_get_children(bus, &devs, &ndevs, 560 BHND_DEVICE_ORDER_ATTACH); 561 if (error) 562 return (error); 563 564 /* Probe and attach all children */ 565 for (int i = 0; i < ndevs; i++) { 566 device_t child = devs[i]; 567 device_probe_and_attach(child); 568 } 569 570 bhnd_bus_free_children(devs); 571 572 return (0); 573 } 574 575 /** 576 * Walk up the bhnd device hierarchy to locate the root device 577 * to which the bhndb bridge is attached. 578 * 579 * This can be used from within bhnd host bridge drivers to locate the 580 * actual upstream host device. 581 * 582 * @param dev A bhnd device. 583 * @param bus_class The expected bus (e.g. "pci") to which the bridge root 584 * should be attached. 585 * 586 * @retval device_t if a matching parent device is found. 587 * @retval NULL @p dev is not attached via a bhndb bus 588 * @retval NULL no parent device is attached via @p bus_class. 589 */ 590 device_t 591 bhnd_find_bridge_root(device_t dev, devclass_t bus_class) 592 { 593 devclass_t bhndb_class; 594 device_t parent; 595 596 KASSERT(device_get_devclass(device_get_parent(dev)) == bhnd_devclass, 597 ("%s not a bhnd device", device_get_nameunit(dev))); 598 599 bhndb_class = devclass_find("bhndb"); 600 601 /* Walk the device tree until we hit a bridge */ 602 parent = dev; 603 while ((parent = device_get_parent(parent)) != NULL) { 604 if (device_get_devclass(parent) == bhndb_class) 605 break; 606 } 607 608 /* No bridge? */ 609 if (parent == NULL) 610 return (NULL); 611 612 /* Search for a parent attached to the expected bus class */ 613 while ((parent = device_get_parent(parent)) != NULL) { 614 device_t bus; 615 616 bus = device_get_parent(parent); 617 if (bus != NULL && device_get_devclass(bus) == bus_class) 618 return (parent); 619 } 620 621 /* Not found */ 622 return (NULL); 623 } 624 625 /** 626 * Find the first core in @p cores that matches @p desc. 627 * 628 * @param cores The table to search. 629 * @param num_cores The length of @p cores. 630 * @param desc A match descriptor. 631 * 632 * @retval bhnd_core_info if a matching core is found. 633 * @retval NULL if no matching core is found. 634 */ 635 const struct bhnd_core_info * 636 bhnd_match_core(const struct bhnd_core_info *cores, u_int num_cores, 637 const struct bhnd_core_match *desc) 638 { 639 for (u_int i = 0; i < num_cores; i++) { 640 if (bhnd_core_matches(&cores[i], desc)) 641 return &cores[i]; 642 } 643 644 return (NULL); 645 } 646 647 648 /** 649 * Find the first core in @p cores with the given @p class. 650 * 651 * @param cores The table to search. 652 * @param num_cores The length of @p cores. 653 * @param desc A match descriptor. 654 * 655 * @retval bhnd_core_info if a matching core is found. 656 * @retval NULL if no matching core is found. 657 */ 658 const struct bhnd_core_info * 659 bhnd_find_core(const struct bhnd_core_info *cores, u_int num_cores, 660 bhnd_devclass_t class) 661 { 662 struct bhnd_core_match md = { 663 BHND_MATCH_CORE_CLASS(class) 664 }; 665 666 return bhnd_match_core(cores, num_cores, &md); 667 } 668 669 670 /** 671 * Create an equality match descriptor for @p core. 672 * 673 * @param core The core info to be matched on. 674 * @param desc On return, will be populated with a match descriptor for @p core. 675 */ 676 struct bhnd_core_match 677 bhnd_core_get_match_desc(const struct bhnd_core_info *core) 678 { 679 return ((struct bhnd_core_match) { 680 BHND_MATCH_CORE_VENDOR(core->vendor), 681 BHND_MATCH_CORE_ID(core->device), 682 BHND_MATCH_CORE_REV(HWREV_EQ(core->hwrev)), 683 BHND_MATCH_CORE_CLASS(bhnd_core_class(core)), 684 BHND_MATCH_CORE_IDX(core->core_idx), 685 BHND_MATCH_CORE_UNIT(core->unit) 686 }); 687 } 688 689 690 /** 691 * Return true if the @p lhs is equal to @p rhs 692 * 693 * @param lhs The first bhnd core descriptor to compare. 694 * @param rhs The second bhnd core descriptor to compare. 695 * 696 * @retval true if @p lhs is equal to @p rhs 697 * @retval false if @p lhs is not equal to @p rhs 698 */ 699 bool 700 bhnd_cores_equal(const struct bhnd_core_info *lhs, 701 const struct bhnd_core_info *rhs) 702 { 703 struct bhnd_core_match md; 704 705 /* Use an equality match descriptor to perform the comparison */ 706 md = bhnd_core_get_match_desc(rhs); 707 return (bhnd_core_matches(lhs, &md)); 708 } 709 710 /** 711 * Return true if the @p core matches @p desc. 712 * 713 * @param core A bhnd core descriptor. 714 * @param desc A match descriptor to compare against @p core. 715 * 716 * @retval true if @p core matches @p match 717 * @retval false if @p core does not match @p match. 718 */ 719 bool 720 bhnd_core_matches(const struct bhnd_core_info *core, 721 const struct bhnd_core_match *desc) 722 { 723 if (desc->m.match.core_vendor && desc->core_vendor != core->vendor) 724 return (false); 725 726 if (desc->m.match.core_id && desc->core_id != core->device) 727 return (false); 728 729 if (desc->m.match.core_unit && desc->core_unit != core->unit) 730 return (false); 731 732 if (desc->m.match.core_rev && 733 !bhnd_hwrev_matches(core->hwrev, &desc->core_rev)) 734 return (false); 735 736 if (desc->m.match.core_idx && desc->core_idx != core->core_idx) 737 return (false); 738 739 if (desc->m.match.core_class && 740 desc->core_class != bhnd_core_class(core)) 741 return (false); 742 743 return true; 744 } 745 746 /** 747 * Return true if the @p chip matches @p desc. 748 * 749 * @param chip A bhnd chip identifier. 750 * @param desc A match descriptor to compare against @p chip. 751 * 752 * @retval true if @p chip matches @p match 753 * @retval false if @p chip does not match @p match. 754 */ 755 bool 756 bhnd_chip_matches(const struct bhnd_chipid *chip, 757 const struct bhnd_chip_match *desc) 758 { 759 if (desc->m.match.chip_id && chip->chip_id != desc->chip_id) 760 return (false); 761 762 if (desc->m.match.chip_pkg && chip->chip_pkg != desc->chip_pkg) 763 return (false); 764 765 if (desc->m.match.chip_rev && 766 !bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev)) 767 return (false); 768 769 if (desc->m.match.chip_type && chip->chip_type != desc->chip_type) 770 return (false); 771 772 return (true); 773 } 774 775 /** 776 * Return true if the @p board matches @p desc. 777 * 778 * @param board The bhnd board info. 779 * @param desc A match descriptor to compare against @p board. 780 * 781 * @retval true if @p chip matches @p match 782 * @retval false if @p chip does not match @p match. 783 */ 784 bool 785 bhnd_board_matches(const struct bhnd_board_info *board, 786 const struct bhnd_board_match *desc) 787 { 788 if (desc->m.match.board_srom_rev && 789 !bhnd_hwrev_matches(board->board_srom_rev, &desc->board_srom_rev)) 790 return (false); 791 792 if (desc->m.match.board_vendor && 793 board->board_vendor != desc->board_vendor) 794 return (false); 795 796 if (desc->m.match.board_type && board->board_type != desc->board_type) 797 return (false); 798 799 if (desc->m.match.board_rev && 800 !bhnd_hwrev_matches(board->board_rev, &desc->board_rev)) 801 return (false); 802 803 return (true); 804 } 805 806 /** 807 * Return true if the @p hwrev matches @p desc. 808 * 809 * @param hwrev A bhnd hardware revision. 810 * @param desc A match descriptor to compare against @p core. 811 * 812 * @retval true if @p hwrev matches @p match 813 * @retval false if @p hwrev does not match @p match. 814 */ 815 bool 816 bhnd_hwrev_matches(uint16_t hwrev, const struct bhnd_hwrev_match *desc) 817 { 818 if (desc->start != BHND_HWREV_INVALID && 819 desc->start > hwrev) 820 return false; 821 822 if (desc->end != BHND_HWREV_INVALID && 823 desc->end < hwrev) 824 return false; 825 826 return true; 827 } 828 829 /** 830 * Return true if the @p dev matches @p desc. 831 * 832 * @param dev A bhnd device. 833 * @param desc A match descriptor to compare against @p dev. 834 * 835 * @retval true if @p dev matches @p match 836 * @retval false if @p dev does not match @p match. 837 */ 838 bool 839 bhnd_device_matches(device_t dev, const struct bhnd_device_match *desc) 840 { 841 struct bhnd_core_info core; 842 const struct bhnd_chipid *chip; 843 struct bhnd_board_info board; 844 device_t parent; 845 int error; 846 847 /* Construct individual match descriptors */ 848 struct bhnd_core_match m_core = { _BHND_CORE_MATCH_COPY(desc) }; 849 struct bhnd_chip_match m_chip = { _BHND_CHIP_MATCH_COPY(desc) }; 850 struct bhnd_board_match m_board = { _BHND_BOARD_MATCH_COPY(desc) }; 851 852 /* Fetch and match core info */ 853 if (m_core.m.match_flags) { 854 /* Only applicable to bhnd-attached cores */ 855 parent = device_get_parent(dev); 856 if (device_get_devclass(parent) != bhnd_devclass) { 857 device_printf(dev, "attempting to match core " 858 "attributes against non-core device\n"); 859 return (false); 860 } 861 862 core = bhnd_get_core_info(dev); 863 if (!bhnd_core_matches(&core, &m_core)) 864 return (false); 865 } 866 867 /* Fetch and match chip info */ 868 if (m_chip.m.match_flags) { 869 chip = bhnd_get_chipid(dev); 870 871 if (!bhnd_chip_matches(chip, &m_chip)) 872 return (false); 873 } 874 875 /* Fetch and match board info. 876 * 877 * This is not available until after NVRAM is up; earlier device 878 * matches should not include board requirements */ 879 if (m_board.m.match_flags) { 880 if ((error = bhnd_read_board_info(dev, &board))) { 881 device_printf(dev, "failed to read required board info " 882 "during device matching: %d\n", error); 883 return (false); 884 } 885 886 if (!bhnd_board_matches(&board, &m_board)) 887 return (false); 888 } 889 890 /* All matched */ 891 return (true); 892 } 893 894 /** 895 * Search @p table for an entry matching @p dev. 896 * 897 * @param dev A bhnd device to match against @p table. 898 * @param table The device table to search. 899 * @param entry_size The @p table entry size, in bytes. 900 * 901 * @retval bhnd_device the first matching device, if any. 902 * @retval NULL if no matching device is found in @p table. 903 */ 904 const struct bhnd_device * 905 bhnd_device_lookup(device_t dev, const struct bhnd_device *table, 906 size_t entry_size) 907 { 908 const struct bhnd_device *entry; 909 device_t hostb, parent; 910 bhnd_attach_type attach_type; 911 uint32_t dflags; 912 913 parent = device_get_parent(dev); 914 hostb = bhnd_bus_find_hostb_device(parent); 915 attach_type = bhnd_get_attach_type(dev); 916 917 for (entry = table; !BHND_DEVICE_IS_END(entry); entry = 918 (const struct bhnd_device *) ((const char *) entry + entry_size)) 919 { 920 /* match core info */ 921 if (!bhnd_device_matches(dev, &entry->core)) 922 continue; 923 924 /* match device flags */ 925 dflags = entry->device_flags; 926 927 /* hostb implies BHND_ATTACH_ADAPTER requirement */ 928 if (dflags & BHND_DF_HOSTB) 929 dflags |= BHND_DF_ADAPTER; 930 931 if (dflags & BHND_DF_ADAPTER) 932 if (attach_type != BHND_ATTACH_ADAPTER) 933 continue; 934 935 if (dflags & BHND_DF_HOSTB) 936 if (dev != hostb) 937 continue; 938 939 if (dflags & BHND_DF_SOC) 940 if (attach_type != BHND_ATTACH_NATIVE) 941 continue; 942 943 /* device found */ 944 return (entry); 945 } 946 947 /* not found */ 948 return (NULL); 949 } 950 951 /** 952 * Scan the device @p table for all quirk flags applicable to @p dev. 953 * 954 * @param dev A bhnd device to match against @p table. 955 * @param table The device table to search. 956 * 957 * @return returns all matching quirk flags. 958 */ 959 uint32_t 960 bhnd_device_quirks(device_t dev, const struct bhnd_device *table, 961 size_t entry_size) 962 { 963 const struct bhnd_device *dent; 964 const struct bhnd_device_quirk *qent, *qtable; 965 uint32_t quirks; 966 967 /* Locate the device entry */ 968 if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL) 969 return (0); 970 971 /* Quirks table is optional */ 972 qtable = dent->quirks_table; 973 if (qtable == NULL) 974 return (0); 975 976 /* Collect matching device quirk entries */ 977 quirks = 0; 978 for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) { 979 if (bhnd_device_matches(dev, &qent->desc)) 980 quirks |= qent->quirks; 981 } 982 983 return (quirks); 984 } 985 986 987 /** 988 * Allocate bhnd(4) resources defined in @p rs from a parent bus. 989 * 990 * @param dev The device requesting ownership of the resources. 991 * @param rs A standard bus resource specification. This will be updated 992 * with the allocated resource's RIDs. 993 * @param res On success, the allocated bhnd resources. 994 * 995 * @retval 0 success 996 * @retval non-zero if allocation of any non-RF_OPTIONAL resource fails, 997 * all allocated resources will be released and a regular 998 * unix error code will be returned. 999 */ 1000 int 1001 bhnd_alloc_resources(device_t dev, struct resource_spec *rs, 1002 struct bhnd_resource **res) 1003 { 1004 /* Initialize output array */ 1005 for (u_int i = 0; rs[i].type != -1; i++) 1006 res[i] = NULL; 1007 1008 for (u_int i = 0; rs[i].type != -1; i++) { 1009 res[i] = bhnd_alloc_resource_any(dev, rs[i].type, &rs[i].rid, 1010 rs[i].flags); 1011 1012 /* Clean up all allocations on failure */ 1013 if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) { 1014 bhnd_release_resources(dev, rs, res); 1015 return (ENXIO); 1016 } 1017 } 1018 1019 return (0); 1020 } 1021 1022 /** 1023 * Release bhnd(4) resources defined in @p rs from a parent bus. 1024 * 1025 * @param dev The device that owns the resources. 1026 * @param rs A standard bus resource specification previously initialized 1027 * by @p bhnd_alloc_resources. 1028 * @param res The bhnd resources to be released. 1029 */ 1030 void 1031 bhnd_release_resources(device_t dev, const struct resource_spec *rs, 1032 struct bhnd_resource **res) 1033 { 1034 for (u_int i = 0; rs[i].type != -1; i++) { 1035 if (res[i] == NULL) 1036 continue; 1037 1038 bhnd_release_resource(dev, rs[i].type, rs[i].rid, res[i]); 1039 res[i] = NULL; 1040 } 1041 } 1042 1043 /** 1044 * Parse the CHIPC_ID_* fields from the ChipCommon CHIPC_ID 1045 * register, returning its bhnd_chipid representation. 1046 * 1047 * @param idreg The CHIPC_ID register value. 1048 * @param enum_addr The enumeration address to include in the result. 1049 * 1050 * @warning 1051 * On early siba(4) devices, the ChipCommon core does not provide 1052 * a valid CHIPC_ID_NUMCORE field. On these ChipCommon revisions 1053 * (see CHIPC_NCORES_MIN_HWREV()), this function will parse and return 1054 * an invalid `ncores` value. 1055 */ 1056 struct bhnd_chipid 1057 bhnd_parse_chipid(uint32_t idreg, bhnd_addr_t enum_addr) 1058 { 1059 struct bhnd_chipid result; 1060 1061 /* Fetch the basic chip info */ 1062 result.chip_id = CHIPC_GET_BITS(idreg, CHIPC_ID_CHIP); 1063 result.chip_pkg = CHIPC_GET_BITS(idreg, CHIPC_ID_PKG); 1064 result.chip_rev = CHIPC_GET_BITS(idreg, CHIPC_ID_REV); 1065 result.chip_type = CHIPC_GET_BITS(idreg, CHIPC_ID_BUS); 1066 result.ncores = CHIPC_GET_BITS(idreg, CHIPC_ID_NUMCORE); 1067 1068 result.enum_addr = enum_addr; 1069 1070 return (result); 1071 } 1072 1073 1074 /** 1075 * Determine the correct core count for a chip identification value that 1076 * may contain an invalid core count. 1077 * 1078 * On some early siba(4) devices (see CHIPC_NCORES_MIN_HWREV()), the ChipCommon 1079 * core does not provide a valid CHIPC_ID_NUMCORE field. 1080 * 1081 * @param cid The chip identification to be queried. 1082 * @param chipc_hwrev The hardware revision of the ChipCommon core from which 1083 * @p cid was parsed. 1084 * @param[out] ncores On success, will be set to the correct core count. 1085 * 1086 * @retval 0 If the core count is already correct, or was mapped to a 1087 * a correct value. 1088 * @retval EINVAL If the core count is incorrect, but the chip was not 1089 * recognized. 1090 */ 1091 int 1092 bhnd_chipid_fixed_ncores(const struct bhnd_chipid *cid, uint16_t chipc_hwrev, 1093 uint8_t *ncores) 1094 { 1095 /* bcma(4), and most siba(4) devices */ 1096 if (CHIPC_NCORES_MIN_HWREV(chipc_hwrev)) { 1097 *ncores = cid->ncores; 1098 return (0); 1099 } 1100 1101 /* broken siba(4) chipsets */ 1102 switch (cid->chip_id) { 1103 case BHND_CHIPID_BCM4306: 1104 *ncores = 6; 1105 break; 1106 case BHND_CHIPID_BCM4704: 1107 *ncores = 9; 1108 break; 1109 case BHND_CHIPID_BCM5365: 1110 /* 1111 * BCM5365 does support ID_NUMCORE in at least 1112 * some of its revisions, but for unknown 1113 * reasons, Broadcom's drivers always exclude 1114 * the ChipCommon revision (0x5) used by BCM5365 1115 * from the set of revisions supporting 1116 * ID_NUMCORE, and instead supply a fixed value. 1117 * 1118 * Presumably, at least some of these devices 1119 * shipped with a broken ID_NUMCORE value. 1120 */ 1121 *ncores = 7; 1122 break; 1123 default: 1124 return (EINVAL); 1125 } 1126 1127 return (0); 1128 } 1129 1130 /** 1131 * Allocate the resource defined by @p rs via @p dev, use it 1132 * to read the ChipCommon ID register relative to @p chipc_offset, 1133 * then release the resource. 1134 * 1135 * @param dev The device owning @p rs. 1136 * @param rs A resource spec that encompasses the ChipCommon register block. 1137 * @param chipc_offset The offset of the ChipCommon registers within @p rs. 1138 * @param[out] result the chip identification data. 1139 * 1140 * @retval 0 success 1141 * @retval non-zero if the ChipCommon identification data could not be read. 1142 */ 1143 int 1144 bhnd_read_chipid(device_t dev, struct resource_spec *rs, 1145 bus_size_t chipc_offset, struct bhnd_chipid *result) 1146 { 1147 struct resource *res; 1148 bhnd_addr_t enum_addr; 1149 uint32_t reg; 1150 uint8_t chip_type; 1151 int error, rid, rtype; 1152 1153 rid = rs->rid; 1154 rtype = rs->type; 1155 error = 0; 1156 1157 /* Allocate the ChipCommon window resource and fetch the chipid data */ 1158 res = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE); 1159 if (res == NULL) { 1160 device_printf(dev, 1161 "failed to allocate bhnd chipc resource\n"); 1162 return (ENXIO); 1163 } 1164 1165 /* Fetch the basic chip info */ 1166 reg = bus_read_4(res, chipc_offset + CHIPC_ID); 1167 chip_type = CHIPC_GET_BITS(reg, CHIPC_ID_BUS); 1168 1169 /* Fetch the EROMPTR */ 1170 if (BHND_CHIPTYPE_HAS_EROM(chip_type)) { 1171 enum_addr = bus_read_4(res, chipc_offset + CHIPC_EROMPTR); 1172 } else if (chip_type == BHND_CHIPTYPE_SIBA) { 1173 /* siba(4) uses the ChipCommon base address as the enumeration 1174 * address */ 1175 enum_addr = BHND_DEFAULT_CHIPC_ADDR; 1176 } else { 1177 device_printf(dev, "unknown chip type %hhu\n", chip_type); 1178 error = ENODEV; 1179 goto cleanup; 1180 } 1181 1182 *result = bhnd_parse_chipid(reg, enum_addr); 1183 1184 /* Fix the core count on early siba(4) devices */ 1185 if (chip_type == BHND_CHIPTYPE_SIBA) { 1186 uint32_t idh; 1187 uint16_t chipc_hwrev; 1188 1189 /* 1190 * We need the ChipCommon revision to determine whether 1191 * the ncore field is valid. 1192 * 1193 * We can safely assume the siba IDHIGH register is mapped 1194 * within the chipc register block. 1195 */ 1196 idh = bus_read_4(res, SB0_REG_ABS(SIBA_CFG0_IDHIGH)); 1197 chipc_hwrev = SIBA_IDH_CORE_REV(idh); 1198 1199 error = bhnd_chipid_fixed_ncores(result, chipc_hwrev, 1200 &result->ncores); 1201 if (error) 1202 goto cleanup; 1203 } 1204 1205 cleanup: 1206 /* Clean up */ 1207 bus_release_resource(dev, rtype, rid, res); 1208 return (error); 1209 } 1210 1211 /** 1212 * Allocate and return a new per-core PMU clock control/status (clkctl) 1213 * instance for @p dev. 1214 * 1215 * @param dev The bhnd(4) core device mapped by @p r. 1216 * @param pmu_dev The bhnd(4) PMU device, implmenting the bhnd_pmu_if 1217 * interface. The caller is responsible for ensuring that 1218 * this reference remains valid for the lifetime of the 1219 * returned clkctl instance. 1220 * @param r A resource mapping the core's clock control register 1221 * (see BHND_CLK_CTL_ST). The caller is responsible for 1222 * ensuring that this resource remains valid for the 1223 * lifetime of the returned clkctl instance. 1224 * @param offset The offset to the clock control register within @p r. 1225 * @param max_latency The PMU's maximum state transition latency in 1226 * microseconds; this upper bound will be used to busy-wait 1227 * on PMU state transitions. 1228 * 1229 * @retval non-NULL success 1230 * @retval NULL if allocation fails. 1231 * 1232 */ 1233 struct bhnd_core_clkctl * 1234 bhnd_alloc_core_clkctl(device_t dev, device_t pmu_dev, struct bhnd_resource *r, 1235 bus_size_t offset, u_int max_latency) 1236 { 1237 struct bhnd_core_clkctl *clkctl; 1238 1239 clkctl = malloc(sizeof(*clkctl), M_BHND, M_ZERO | M_NOWAIT); 1240 if (clkctl == NULL) 1241 return (NULL); 1242 1243 clkctl->cc_dev = dev; 1244 clkctl->cc_pmu_dev = pmu_dev; 1245 clkctl->cc_res = r; 1246 clkctl->cc_res_offset = offset; 1247 clkctl->cc_max_latency = max_latency; 1248 clkctl->cc_quirks = bhnd_device_quirks(dev, bhnd_clkctl_devices, 1249 sizeof(bhnd_clkctl_devices[0])); 1250 1251 BHND_CLKCTL_LOCK_INIT(clkctl); 1252 1253 return (clkctl); 1254 } 1255 1256 /** 1257 * Free a clkctl instance previously allocated via bhnd_alloc_core_clkctl(). 1258 * 1259 * @param clkctl The clkctl instance to be freed. 1260 */ 1261 void 1262 bhnd_free_core_clkctl(struct bhnd_core_clkctl *clkctl) 1263 { 1264 BHND_CLKCTL_LOCK_DESTROY(clkctl); 1265 1266 free(clkctl, M_BHND); 1267 } 1268 1269 /** 1270 * Wait for the per-core clock status to be equal to @p value after 1271 * applying @p mask, timing out after the maximum transition latency is reached. 1272 * 1273 * @param clkctl Per-core clkctl state to be queryied. 1274 * @param value Value to wait for. 1275 * @param mask Mask to apply prior to value comparison. 1276 * 1277 * @retval 0 success 1278 * @retval ETIMEDOUT if the PMU's maximum transition delay is reached before 1279 * the clock status matches @p value and @p mask. 1280 */ 1281 int 1282 bhnd_core_clkctl_wait(struct bhnd_core_clkctl *clkctl, uint32_t value, 1283 uint32_t mask) 1284 { 1285 uint32_t clkst; 1286 1287 BHND_CLKCTL_LOCK_ASSERT(clkctl, MA_OWNED); 1288 1289 /* Bitswapped HTAVAIL/ALPAVAIL work-around */ 1290 if (clkctl->cc_quirks & BHND_CLKCTL_QUIRK_CCS0) { 1291 uint32_t fmask, fval; 1292 1293 fmask = mask & ~(BHND_CCS_HTAVAIL | BHND_CCS_ALPAVAIL); 1294 fval = value & ~(BHND_CCS_HTAVAIL | BHND_CCS_ALPAVAIL); 1295 1296 if (mask & BHND_CCS_HTAVAIL) 1297 fmask |= BHND_CCS0_HTAVAIL; 1298 if (value & BHND_CCS_HTAVAIL) 1299 fval |= BHND_CCS0_HTAVAIL; 1300 1301 if (mask & BHND_CCS_ALPAVAIL) 1302 fmask |= BHND_CCS0_ALPAVAIL; 1303 if (value & BHND_CCS_ALPAVAIL) 1304 fval |= BHND_CCS0_ALPAVAIL; 1305 1306 mask = fmask; 1307 value = fval; 1308 } 1309 1310 for (u_int i = 0; i < clkctl->cc_max_latency; i += 10) { 1311 clkst = bhnd_bus_read_4(clkctl->cc_res, clkctl->cc_res_offset); 1312 if ((clkst & mask) == (value & mask)) 1313 return (0); 1314 1315 DELAY(10); 1316 } 1317 1318 device_printf(clkctl->cc_dev, "clkst wait timeout (value=%#x, " 1319 "mask=%#x)\n", value, mask); 1320 1321 return (ETIMEDOUT); 1322 } 1323 1324 /** 1325 * Read an NVRAM variable's NUL-terminated string value. 1326 * 1327 * @param dev A bhnd bus child device. 1328 * @param name The NVRAM variable name. 1329 * @param[out] buf A buffer large enough to hold @p len bytes. On 1330 * success, the NUL-terminated string value will be 1331 * written to this buffer. This argment may be NULL if 1332 * the value is not desired. 1333 * @param len The maximum capacity of @p buf. 1334 * @param[out] rlen On success, will be set to the actual size of 1335 * the requested value (including NUL termination). This 1336 * argment may be NULL if the size is not desired. 1337 * 1338 * @retval 0 success 1339 * @retval ENOENT The requested variable was not found. 1340 * @retval ENODEV No valid NVRAM source could be found. 1341 * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too 1342 * small to hold the requested value. 1343 * @retval EFTYPE If the variable data cannot be coerced to a valid 1344 * string representation. 1345 * @retval ERANGE If value coercion would overflow @p type. 1346 * @retval non-zero If reading @p name otherwise fails, a regular unix 1347 * error code will be returned. 1348 */ 1349 int 1350 bhnd_nvram_getvar_str(device_t dev, const char *name, char *buf, size_t len, 1351 size_t *rlen) 1352 { 1353 size_t larg; 1354 int error; 1355 1356 larg = len; 1357 error = bhnd_nvram_getvar(dev, name, buf, &larg, 1358 BHND_NVRAM_TYPE_STRING); 1359 if (rlen != NULL) 1360 *rlen = larg; 1361 1362 return (error); 1363 } 1364 1365 /** 1366 * Read an NVRAM variable's unsigned integer value. 1367 * 1368 * @param dev A bhnd bus child device. 1369 * @param name The NVRAM variable name. 1370 * @param[out] value On success, the requested value will be written 1371 * to this pointer. 1372 * @param width The output integer type width (1, 2, or 1373 * 4 bytes). 1374 * 1375 * @retval 0 success 1376 * @retval ENOENT The requested variable was not found. 1377 * @retval ENODEV No valid NVRAM source could be found. 1378 * @retval EFTYPE If the variable data cannot be coerced to a 1379 * a valid unsigned integer representation. 1380 * @retval ERANGE If value coercion would overflow (or underflow) an 1381 * unsigned representation of the given @p width. 1382 * @retval non-zero If reading @p name otherwise fails, a regular unix 1383 * error code will be returned. 1384 */ 1385 int 1386 bhnd_nvram_getvar_uint(device_t dev, const char *name, void *value, int width) 1387 { 1388 bhnd_nvram_type type; 1389 size_t len; 1390 1391 switch (width) { 1392 case 1: 1393 type = BHND_NVRAM_TYPE_UINT8; 1394 break; 1395 case 2: 1396 type = BHND_NVRAM_TYPE_UINT16; 1397 break; 1398 case 4: 1399 type = BHND_NVRAM_TYPE_UINT32; 1400 break; 1401 default: 1402 device_printf(dev, "unsupported NVRAM integer width: %d\n", 1403 width); 1404 return (EINVAL); 1405 } 1406 1407 len = width; 1408 return (bhnd_nvram_getvar(dev, name, value, &len, type)); 1409 } 1410 1411 /** 1412 * Read an NVRAM variable's unsigned 8-bit integer value. 1413 * 1414 * @param dev A bhnd bus child device. 1415 * @param name The NVRAM variable name. 1416 * @param[out] value On success, the requested value will be written 1417 * to this pointer. 1418 * 1419 * @retval 0 success 1420 * @retval ENOENT The requested variable was not found. 1421 * @retval ENODEV No valid NVRAM source could be found. 1422 * @retval EFTYPE If the variable data cannot be coerced to a 1423 * a valid unsigned integer representation. 1424 * @retval ERANGE If value coercion would overflow (or underflow) uint8_t. 1425 * @retval non-zero If reading @p name otherwise fails, a regular unix 1426 * error code will be returned. 1427 */ 1428 int 1429 bhnd_nvram_getvar_uint8(device_t dev, const char *name, uint8_t *value) 1430 { 1431 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value))); 1432 } 1433 1434 /** 1435 * Read an NVRAM variable's unsigned 16-bit integer value. 1436 * 1437 * @param dev A bhnd bus child device. 1438 * @param name The NVRAM variable name. 1439 * @param[out] value On success, the requested value will be written 1440 * to this pointer. 1441 * 1442 * @retval 0 success 1443 * @retval ENOENT The requested variable was not found. 1444 * @retval ENODEV No valid NVRAM source could be found. 1445 * @retval EFTYPE If the variable data cannot be coerced to a 1446 * a valid unsigned integer representation. 1447 * @retval ERANGE If value coercion would overflow (or underflow) 1448 * uint16_t. 1449 * @retval non-zero If reading @p name otherwise fails, a regular unix 1450 * error code will be returned. 1451 */ 1452 int 1453 bhnd_nvram_getvar_uint16(device_t dev, const char *name, uint16_t *value) 1454 { 1455 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value))); 1456 } 1457 1458 /** 1459 * Read an NVRAM variable's unsigned 32-bit integer value. 1460 * 1461 * @param dev A bhnd bus child device. 1462 * @param name The NVRAM variable name. 1463 * @param[out] value On success, the requested value will be written 1464 * to this pointer. 1465 * 1466 * @retval 0 success 1467 * @retval ENOENT The requested variable was not found. 1468 * @retval ENODEV No valid NVRAM source could be found. 1469 * @retval EFTYPE If the variable data cannot be coerced to a 1470 * a valid unsigned integer representation. 1471 * @retval ERANGE If value coercion would overflow (or underflow) 1472 * uint32_t. 1473 * @retval non-zero If reading @p name otherwise fails, a regular unix 1474 * error code will be returned. 1475 */ 1476 int 1477 bhnd_nvram_getvar_uint32(device_t dev, const char *name, uint32_t *value) 1478 { 1479 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value))); 1480 } 1481 1482 /** 1483 * Read an NVRAM variable's signed integer value. 1484 * 1485 * @param dev A bhnd bus child device. 1486 * @param name The NVRAM variable name. 1487 * @param[out] value On success, the requested value will be written 1488 * to this pointer. 1489 * @param width The output integer type width (1, 2, or 1490 * 4 bytes). 1491 * 1492 * @retval 0 success 1493 * @retval ENOENT The requested variable was not found. 1494 * @retval ENODEV No valid NVRAM source could be found. 1495 * @retval EFTYPE If the variable data cannot be coerced to a 1496 * a valid integer representation. 1497 * @retval ERANGE If value coercion would overflow (or underflow) an 1498 * signed representation of the given @p width. 1499 * @retval non-zero If reading @p name otherwise fails, a regular unix 1500 * error code will be returned. 1501 */ 1502 int 1503 bhnd_nvram_getvar_int(device_t dev, const char *name, void *value, int width) 1504 { 1505 bhnd_nvram_type type; 1506 size_t len; 1507 1508 switch (width) { 1509 case 1: 1510 type = BHND_NVRAM_TYPE_INT8; 1511 break; 1512 case 2: 1513 type = BHND_NVRAM_TYPE_INT16; 1514 break; 1515 case 4: 1516 type = BHND_NVRAM_TYPE_INT32; 1517 break; 1518 default: 1519 device_printf(dev, "unsupported NVRAM integer width: %d\n", 1520 width); 1521 return (EINVAL); 1522 } 1523 1524 len = width; 1525 return (bhnd_nvram_getvar(dev, name, value, &len, type)); 1526 } 1527 1528 /** 1529 * Read an NVRAM variable's signed 8-bit integer value. 1530 * 1531 * @param dev A bhnd bus child device. 1532 * @param name The NVRAM variable name. 1533 * @param[out] value On success, the requested value will be written 1534 * to this pointer. 1535 * 1536 * @retval 0 success 1537 * @retval ENOENT The requested variable was not found. 1538 * @retval ENODEV No valid NVRAM source could be found. 1539 * @retval EFTYPE If the variable data cannot be coerced to a 1540 * a valid integer representation. 1541 * @retval ERANGE If value coercion would overflow (or underflow) int8_t. 1542 * @retval non-zero If reading @p name otherwise fails, a regular unix 1543 * error code will be returned. 1544 */ 1545 int 1546 bhnd_nvram_getvar_int8(device_t dev, const char *name, int8_t *value) 1547 { 1548 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value))); 1549 } 1550 1551 /** 1552 * Read an NVRAM variable's signed 16-bit integer value. 1553 * 1554 * @param dev A bhnd bus child device. 1555 * @param name The NVRAM variable name. 1556 * @param[out] value On success, the requested value will be written 1557 * to this pointer. 1558 * 1559 * @retval 0 success 1560 * @retval ENOENT The requested variable was not found. 1561 * @retval ENODEV No valid NVRAM source could be found. 1562 * @retval EFTYPE If the variable data cannot be coerced to a 1563 * a valid integer representation. 1564 * @retval ERANGE If value coercion would overflow (or underflow) 1565 * int16_t. 1566 * @retval non-zero If reading @p name otherwise fails, a regular unix 1567 * error code will be returned. 1568 */ 1569 int 1570 bhnd_nvram_getvar_int16(device_t dev, const char *name, int16_t *value) 1571 { 1572 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value))); 1573 } 1574 1575 /** 1576 * Read an NVRAM variable's signed 32-bit integer value. 1577 * 1578 * @param dev A bhnd bus child device. 1579 * @param name The NVRAM variable name. 1580 * @param[out] value On success, the requested value will be written 1581 * to this pointer. 1582 * 1583 * @retval 0 success 1584 * @retval ENOENT The requested variable was not found. 1585 * @retval ENODEV No valid NVRAM source could be found. 1586 * @retval EFTYPE If the variable data cannot be coerced to a 1587 * a valid integer representation. 1588 * @retval ERANGE If value coercion would overflow (or underflow) 1589 * int32_t. 1590 * @retval non-zero If reading @p name otherwise fails, a regular unix 1591 * error code will be returned. 1592 */ 1593 int 1594 bhnd_nvram_getvar_int32(device_t dev, const char *name, int32_t *value) 1595 { 1596 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value))); 1597 } 1598 1599 1600 /** 1601 * Read an NVRAM variable's array value. 1602 * 1603 * @param dev A bhnd bus child device. 1604 * @param name The NVRAM variable name. 1605 * @param[out] buf A buffer large enough to hold @p size bytes. 1606 * On success, the requested value will be written 1607 * to this buffer. 1608 * @param[in,out] size The required number of bytes to write to 1609 * @p buf. 1610 * @param type The desired array element data representation. 1611 * 1612 * @retval 0 success 1613 * @retval ENOENT The requested variable was not found. 1614 * @retval ENODEV No valid NVRAM source could be found. 1615 * @retval ENXIO If less than @p size bytes are available. 1616 * @retval ENOMEM If a buffer of @p size is too small to hold the 1617 * requested value. 1618 * @retval EFTYPE If the variable data cannot be coerced to a 1619 * a valid instance of @p type. 1620 * @retval ERANGE If value coercion would overflow (or underflow) a 1621 * representation of @p type. 1622 * @retval non-zero If reading @p name otherwise fails, a regular unix 1623 * error code will be returned. 1624 */ 1625 int 1626 bhnd_nvram_getvar_array(device_t dev, const char *name, void *buf, size_t size, 1627 bhnd_nvram_type type) 1628 { 1629 size_t nbytes; 1630 int error; 1631 1632 /* Attempt read */ 1633 nbytes = size; 1634 if ((error = bhnd_nvram_getvar(dev, name, buf, &nbytes, type))) 1635 return (error); 1636 1637 /* Verify that the expected number of bytes were fetched */ 1638 if (nbytes < size) 1639 return (ENXIO); 1640 1641 return (0); 1642 } 1643 1644 /** 1645 * Initialize a service provider registry. 1646 * 1647 * @param bsr The service registry to initialize. 1648 * 1649 * @retval 0 success 1650 * @retval non-zero if an error occurs initializing the service registry, 1651 * a regular unix error code will be returned. 1652 1653 */ 1654 int 1655 bhnd_service_registry_init(struct bhnd_service_registry *bsr) 1656 { 1657 STAILQ_INIT(&bsr->entries); 1658 mtx_init(&bsr->lock, "bhnd_service_registry lock", NULL, MTX_DEF); 1659 1660 return (0); 1661 } 1662 1663 /** 1664 * Release all resources held by @p bsr. 1665 * 1666 * @param bsr A service registry instance previously successfully 1667 * initialized via bhnd_service_registry_init(). 1668 * 1669 * @retval 0 success 1670 * @retval EBUSY if active references to service providers registered 1671 * with @p bsr exist. 1672 */ 1673 int 1674 bhnd_service_registry_fini(struct bhnd_service_registry *bsr) 1675 { 1676 struct bhnd_service_entry *entry, *enext; 1677 1678 /* Remove everthing we can */ 1679 mtx_lock(&bsr->lock); 1680 STAILQ_FOREACH_SAFE(entry, &bsr->entries, link, enext) { 1681 if (entry->refs > 0) 1682 continue; 1683 1684 STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, link); 1685 free(entry, M_BHND); 1686 } 1687 1688 if (!STAILQ_EMPTY(&bsr->entries)) { 1689 mtx_unlock(&bsr->lock); 1690 return (EBUSY); 1691 } 1692 mtx_unlock(&bsr->lock); 1693 1694 mtx_destroy(&bsr->lock); 1695 return (0); 1696 } 1697 1698 /** 1699 * Register a @p provider for the given @p service. 1700 * 1701 * @param bsr Service registry to be modified. 1702 * @param provider Service provider to register. 1703 * @param service Service for which @p provider will be registered. 1704 * @param flags Service provider flags (see BHND_SPF_*). 1705 * 1706 * @retval 0 success 1707 * @retval EEXIST if an entry for @p service already exists. 1708 * @retval EINVAL if @p service is BHND_SERVICE_ANY. 1709 * @retval non-zero if registering @p provider otherwise fails, a regular 1710 * unix error code will be returned. 1711 */ 1712 int 1713 bhnd_service_registry_add(struct bhnd_service_registry *bsr, device_t provider, 1714 bhnd_service_t service, uint32_t flags) 1715 { 1716 struct bhnd_service_entry *entry; 1717 1718 if (service == BHND_SERVICE_ANY) 1719 return (EINVAL); 1720 1721 mtx_lock(&bsr->lock); 1722 1723 /* Is a service provider already registered? */ 1724 STAILQ_FOREACH(entry, &bsr->entries, link) { 1725 if (entry->service == service) { 1726 mtx_unlock(&bsr->lock); 1727 return (EEXIST); 1728 } 1729 } 1730 1731 /* Initialize and insert our new entry */ 1732 entry = malloc(sizeof(*entry), M_BHND, M_NOWAIT); 1733 if (entry == NULL) { 1734 mtx_unlock(&bsr->lock); 1735 return (ENOMEM); 1736 } 1737 1738 entry->provider = provider; 1739 entry->service = service; 1740 entry->flags = flags; 1741 refcount_init(&entry->refs, 0); 1742 1743 STAILQ_INSERT_HEAD(&bsr->entries, entry, link); 1744 1745 mtx_unlock(&bsr->lock); 1746 return (0); 1747 } 1748 1749 /** 1750 * Free an unreferenced registry entry. 1751 * 1752 * @param entry The entry to be deallocated. 1753 */ 1754 static void 1755 bhnd_service_registry_free_entry(struct bhnd_service_entry *entry) 1756 { 1757 KASSERT(entry->refs == 0, ("provider has active references")); 1758 free(entry, M_BHND); 1759 } 1760 1761 /** 1762 * Attempt to remove the @p service provider registration for @p provider. 1763 * 1764 * @param bsr The service registry to be modified. 1765 * @param provider The service provider to be deregistered. 1766 * @param service The service for which @p provider will be deregistered, 1767 * or BHND_SERVICE_ANY to remove all service 1768 * registrations for @p provider. 1769 * 1770 * @retval 0 success 1771 * @retval EBUSY if active references to @p provider exist; @see 1772 * bhnd_service_registry_retain() and 1773 * bhnd_service_registry_release(). 1774 */ 1775 int 1776 bhnd_service_registry_remove(struct bhnd_service_registry *bsr, 1777 device_t provider, bhnd_service_t service) 1778 { 1779 struct bhnd_service_entry *entry, *enext; 1780 1781 mtx_lock(&bsr->lock); 1782 1783 #define BHND_PROV_MATCH(_e) \ 1784 ((_e)->provider == provider && \ 1785 (service == BHND_SERVICE_ANY || (_e)->service == service)) 1786 1787 /* Validate matching provider entries before making any 1788 * modifications */ 1789 STAILQ_FOREACH(entry, &bsr->entries, link) { 1790 /* Skip non-matching entries */ 1791 if (!BHND_PROV_MATCH(entry)) 1792 continue; 1793 1794 /* Entry is in use? */ 1795 if (entry->refs > 0) { 1796 mtx_unlock(&bsr->lock); 1797 return (EBUSY); 1798 } 1799 } 1800 1801 /* We can now safely remove matching entries */ 1802 STAILQ_FOREACH_SAFE(entry, &bsr->entries, link, enext) { 1803 /* Skip non-matching entries */ 1804 if (!BHND_PROV_MATCH(entry)) 1805 continue; 1806 1807 /* Remove from list */ 1808 STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, link); 1809 1810 /* Free provider entry */ 1811 bhnd_service_registry_free_entry(entry); 1812 } 1813 #undef BHND_PROV_MATCH 1814 1815 mtx_unlock(&bsr->lock); 1816 return (0); 1817 } 1818 1819 /** 1820 * Retain and return a reference to a registered @p service provider, if any. 1821 * 1822 * @param bsr The service registry to be queried. 1823 * @param service The service for which a provider should be returned. 1824 * 1825 * On success, the caller assumes ownership the returned provider, and 1826 * is responsible for releasing this reference via 1827 * bhnd_service_registry_release(). 1828 * 1829 * @retval device_t success 1830 * @retval NULL if no provider is registered for @p service. 1831 */ 1832 device_t 1833 bhnd_service_registry_retain(struct bhnd_service_registry *bsr, 1834 bhnd_service_t service) 1835 { 1836 struct bhnd_service_entry *entry; 1837 1838 mtx_lock(&bsr->lock); 1839 STAILQ_FOREACH(entry, &bsr->entries, link) { 1840 if (entry->service != service) 1841 continue; 1842 1843 /* With a live refcount, entry is gauranteed to remain alive 1844 * after we release our lock */ 1845 refcount_acquire(&entry->refs); 1846 1847 mtx_unlock(&bsr->lock); 1848 return (entry->provider); 1849 } 1850 mtx_unlock(&bsr->lock); 1851 1852 /* Not found */ 1853 return (NULL); 1854 } 1855 1856 /** 1857 * Release a reference to a service provider previously returned by 1858 * bhnd_service_registry_retain(). 1859 * 1860 * If this is the last reference to an inherited service provider registration 1861 * (@see BHND_SPF_INHERITED), the registration will also be removed, and 1862 * true will be returned. 1863 * 1864 * @param bsr The service registry from which @p provider 1865 * was returned. 1866 * @param provider The provider to be released. 1867 * @param service The service for which @p provider was previously 1868 * retained. 1869 * @retval true The inherited service provider registration was removed; 1870 * the caller should release its own reference to the 1871 * provider. 1872 * @retval false The service provider was not inherited, or active 1873 * references to the provider remain. 1874 */ 1875 bool 1876 bhnd_service_registry_release(struct bhnd_service_registry *bsr, 1877 device_t provider, bhnd_service_t service) 1878 { 1879 struct bhnd_service_entry *entry; 1880 1881 /* Exclusive lock, as we need to prevent any new references to the 1882 * entry from being taken if it's to be removed */ 1883 mtx_lock(&bsr->lock); 1884 STAILQ_FOREACH(entry, &bsr->entries, link) { 1885 bool removed; 1886 1887 if (entry->provider != provider) 1888 continue; 1889 1890 if (entry->service != service) 1891 continue; 1892 1893 if (refcount_release(&entry->refs) && 1894 (entry->flags & BHND_SPF_INHERITED)) 1895 { 1896 /* If an inherited entry is no longer actively 1897 * referenced, remove the local registration and inform 1898 * the caller. */ 1899 STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, 1900 link); 1901 bhnd_service_registry_free_entry(entry); 1902 removed = true; 1903 } else { 1904 removed = false; 1905 } 1906 1907 mtx_unlock(&bsr->lock); 1908 return (removed); 1909 } 1910 1911 /* Caller owns a reference, but no such provider is registered? */ 1912 panic("invalid service provider reference"); 1913 } 1914 1915 /** 1916 * Using the bhnd(4) bus-level core information and a custom core name, 1917 * populate @p dev's device description. 1918 * 1919 * @param dev A bhnd-bus attached device. 1920 * @param dev_name The core's name (e.g. "SDIO Device Core") 1921 */ 1922 void 1923 bhnd_set_custom_core_desc(device_t dev, const char *dev_name) 1924 { 1925 const char *vendor_name; 1926 char *desc; 1927 1928 vendor_name = bhnd_get_vendor_name(dev); 1929 asprintf(&desc, M_BHND, "%s %s, rev %hhu", vendor_name, dev_name, 1930 bhnd_get_hwrev(dev)); 1931 1932 if (desc != NULL) { 1933 device_set_desc_copy(dev, desc); 1934 free(desc, M_BHND); 1935 } else { 1936 device_set_desc(dev, dev_name); 1937 } 1938 } 1939 1940 /** 1941 * Using the bhnd(4) bus-level core information, populate @p dev's device 1942 * description. 1943 * 1944 * @param dev A bhnd-bus attached device. 1945 */ 1946 void 1947 bhnd_set_default_core_desc(device_t dev) 1948 { 1949 bhnd_set_custom_core_desc(dev, bhnd_get_device_name(dev)); 1950 } 1951 1952 1953 /** 1954 * Using the bhnd @p chip_id, populate the bhnd(4) bus @p dev's device 1955 * description. 1956 * 1957 * @param dev A bhnd-bus attached device. 1958 */ 1959 void 1960 bhnd_set_default_bus_desc(device_t dev, const struct bhnd_chipid *chip_id) 1961 { 1962 const char *bus_name; 1963 char *desc; 1964 char chip_name[BHND_CHIPID_MAX_NAMELEN]; 1965 1966 /* Determine chip type's bus name */ 1967 switch (chip_id->chip_type) { 1968 case BHND_CHIPTYPE_SIBA: 1969 bus_name = "SIBA bus"; 1970 break; 1971 case BHND_CHIPTYPE_BCMA: 1972 case BHND_CHIPTYPE_BCMA_ALT: 1973 bus_name = "BCMA bus"; 1974 break; 1975 case BHND_CHIPTYPE_UBUS: 1976 bus_name = "UBUS bus"; 1977 break; 1978 default: 1979 bus_name = "Unknown Type"; 1980 break; 1981 } 1982 1983 /* Format chip name */ 1984 bhnd_format_chip_id(chip_name, sizeof(chip_name), 1985 chip_id->chip_id); 1986 1987 /* Format and set device description */ 1988 asprintf(&desc, M_BHND, "%s %s", chip_name, bus_name); 1989 if (desc != NULL) { 1990 device_set_desc_copy(dev, desc); 1991 free(desc, M_BHND); 1992 } else { 1993 device_set_desc(dev, bus_name); 1994 } 1995 1996 } 1997 1998 /** 1999 * Helper function for implementing BHND_BUS_REGISTER_PROVIDER(). 2000 * 2001 * This implementation delegates the request to the BHND_BUS_REGISTER_PROVIDER() 2002 * method on the parent of @p dev. If no parent exists, the implementation 2003 * will return an error. 2004 */ 2005 int 2006 bhnd_bus_generic_register_provider(device_t dev, device_t child, 2007 device_t provider, bhnd_service_t service) 2008 { 2009 device_t parent = device_get_parent(dev); 2010 2011 if (parent != NULL) { 2012 return (BHND_BUS_REGISTER_PROVIDER(parent, child, 2013 provider, service)); 2014 } 2015 2016 return (ENXIO); 2017 } 2018 2019 /** 2020 * Helper function for implementing BHND_BUS_DEREGISTER_PROVIDER(). 2021 * 2022 * This implementation delegates the request to the 2023 * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent 2024 * exists, the implementation will panic. 2025 */ 2026 int 2027 bhnd_bus_generic_deregister_provider(device_t dev, device_t child, 2028 device_t provider, bhnd_service_t service) 2029 { 2030 device_t parent = device_get_parent(dev); 2031 2032 if (parent != NULL) { 2033 return (BHND_BUS_DEREGISTER_PROVIDER(parent, child, 2034 provider, service)); 2035 } 2036 2037 panic("missing BHND_BUS_DEREGISTER_PROVIDER()"); 2038 } 2039 2040 /** 2041 * Helper function for implementing BHND_BUS_RETAIN_PROVIDER(). 2042 * 2043 * This implementation delegates the request to the 2044 * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent 2045 * exists, the implementation will return NULL. 2046 */ 2047 device_t 2048 bhnd_bus_generic_retain_provider(device_t dev, device_t child, 2049 bhnd_service_t service) 2050 { 2051 device_t parent = device_get_parent(dev); 2052 2053 if (parent != NULL) { 2054 return (BHND_BUS_RETAIN_PROVIDER(parent, child, 2055 service)); 2056 } 2057 2058 return (NULL); 2059 } 2060 2061 /** 2062 * Helper function for implementing BHND_BUS_RELEASE_PROVIDER(). 2063 * 2064 * This implementation delegates the request to the 2065 * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent 2066 * exists, the implementation will panic. 2067 */ 2068 void 2069 bhnd_bus_generic_release_provider(device_t dev, device_t child, 2070 device_t provider, bhnd_service_t service) 2071 { 2072 device_t parent = device_get_parent(dev); 2073 2074 if (parent != NULL) { 2075 return (BHND_BUS_RELEASE_PROVIDER(parent, child, 2076 provider, service)); 2077 } 2078 2079 panic("missing BHND_BUS_RELEASE_PROVIDER()"); 2080 } 2081 2082 /** 2083 * Helper function for implementing BHND_BUS_REGISTER_PROVIDER(). 2084 * 2085 * This implementation uses the bhnd_service_registry_add() function to 2086 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 2087 * a suitable service registry to edit. 2088 */ 2089 int 2090 bhnd_bus_generic_sr_register_provider(device_t dev, device_t child, 2091 device_t provider, bhnd_service_t service) 2092 { 2093 struct bhnd_service_registry *bsr; 2094 2095 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 2096 2097 KASSERT(bsr != NULL, ("NULL service registry")); 2098 2099 return (bhnd_service_registry_add(bsr, provider, service, 0)); 2100 } 2101 2102 /** 2103 * Helper function for implementing BHND_BUS_DEREGISTER_PROVIDER(). 2104 * 2105 * This implementation uses the bhnd_service_registry_remove() function to 2106 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 2107 * a suitable service registry to edit. 2108 */ 2109 int 2110 bhnd_bus_generic_sr_deregister_provider(device_t dev, device_t child, 2111 device_t provider, bhnd_service_t service) 2112 { 2113 struct bhnd_service_registry *bsr; 2114 2115 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 2116 2117 KASSERT(bsr != NULL, ("NULL service registry")); 2118 2119 return (bhnd_service_registry_remove(bsr, provider, service)); 2120 } 2121 2122 /** 2123 * Helper function for implementing BHND_BUS_RETAIN_PROVIDER(). 2124 * 2125 * This implementation uses the bhnd_service_registry_retain() function to 2126 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 2127 * a suitable service registry. 2128 * 2129 * If a local provider for the service is not available, and a parent device is 2130 * available, this implementation will attempt to fetch and locally register 2131 * a service provider reference from the parent of @p dev. 2132 */ 2133 device_t 2134 bhnd_bus_generic_sr_retain_provider(device_t dev, device_t child, 2135 bhnd_service_t service) 2136 { 2137 struct bhnd_service_registry *bsr; 2138 device_t parent, provider; 2139 int error; 2140 2141 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 2142 KASSERT(bsr != NULL, ("NULL service registry")); 2143 2144 /* 2145 * Attempt to fetch a service provider reference from either the local 2146 * service registry, or if not found, from our parent. 2147 * 2148 * If we fetch a provider from our parent, we register the provider 2149 * with the local service registry to prevent conflicting local 2150 * registrations from being added. 2151 */ 2152 while (1) { 2153 /* Check the local service registry first */ 2154 provider = bhnd_service_registry_retain(bsr, service); 2155 if (provider != NULL) 2156 return (provider); 2157 2158 /* Otherwise, try to delegate to our parent (if any) */ 2159 if ((parent = device_get_parent(dev)) == NULL) 2160 return (NULL); 2161 2162 provider = BHND_BUS_RETAIN_PROVIDER(parent, dev, service); 2163 if (provider == NULL) 2164 return (NULL); 2165 2166 /* Register the inherited service registration with the local 2167 * registry */ 2168 error = bhnd_service_registry_add(bsr, provider, service, 2169 BHND_SPF_INHERITED); 2170 if (error) { 2171 BHND_BUS_RELEASE_PROVIDER(parent, dev, provider, 2172 service); 2173 if (error == EEXIST) { 2174 /* A valid service provider was registered 2175 * concurrently; retry fetching from the local 2176 * registry */ 2177 continue; 2178 } 2179 2180 device_printf(dev, "failed to register service " 2181 "provider: %d\n", error); 2182 return (NULL); 2183 } 2184 } 2185 } 2186 2187 /** 2188 * Helper function for implementing BHND_BUS_RELEASE_PROVIDER(). 2189 * 2190 * This implementation uses the bhnd_service_registry_release() function to 2191 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 2192 * a suitable service registry. 2193 */ 2194 void 2195 bhnd_bus_generic_sr_release_provider(device_t dev, device_t child, 2196 device_t provider, bhnd_service_t service) 2197 { 2198 struct bhnd_service_registry *bsr; 2199 2200 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 2201 KASSERT(bsr != NULL, ("NULL service registry")); 2202 2203 /* Release the provider reference; if the refcount hits zero on an 2204 * inherited reference, true will be returned, and we need to drop 2205 * our own bus reference to the provider */ 2206 if (!bhnd_service_registry_release(bsr, provider, service)) 2207 return; 2208 2209 /* Drop our reference to the borrowed provider */ 2210 BHND_BUS_RELEASE_PROVIDER(device_get_parent(dev), dev, provider, 2211 service); 2212 } 2213 2214 /** 2215 * Helper function for implementing BHND_BUS_IS_HW_DISABLED(). 2216 * 2217 * If a parent device is available, this implementation delegates the 2218 * request to the BHND_BUS_IS_HW_DISABLED() method on the parent of @p dev. 2219 * 2220 * If no parent device is available (i.e. on a the bus root), the hardware 2221 * is assumed to be usable and false is returned. 2222 */ 2223 bool 2224 bhnd_bus_generic_is_hw_disabled(device_t dev, device_t child) 2225 { 2226 if (device_get_parent(dev) != NULL) 2227 return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), child)); 2228 2229 return (false); 2230 } 2231 2232 /** 2233 * Helper function for implementing BHND_BUS_GET_CHIPID(). 2234 * 2235 * This implementation delegates the request to the BHND_BUS_GET_CHIPID() 2236 * method on the parent of @p dev. If no parent exists, the implementation 2237 * will panic. 2238 */ 2239 const struct bhnd_chipid * 2240 bhnd_bus_generic_get_chipid(device_t dev, device_t child) 2241 { 2242 if (device_get_parent(dev) != NULL) 2243 return (BHND_BUS_GET_CHIPID(device_get_parent(dev), child)); 2244 2245 panic("missing BHND_BUS_GET_CHIPID()"); 2246 } 2247 2248 /** 2249 * Helper function for implementing BHND_BUS_GET_DMA_TRANSLATION(). 2250 * 2251 * If a parent device is available, this implementation delegates the 2252 * request to the BHND_BUS_GET_DMA_TRANSLATION() method on the parent of @p dev. 2253 * 2254 * If no parent device is available, this implementation will panic. 2255 */ 2256 int 2257 bhnd_bus_generic_get_dma_translation(device_t dev, device_t child, u_int width, 2258 uint32_t flags, bus_dma_tag_t *dmat, 2259 struct bhnd_dma_translation *translation) 2260 { 2261 if (device_get_parent(dev) != NULL) { 2262 return (BHND_BUS_GET_DMA_TRANSLATION(device_get_parent(dev), 2263 child, width, flags, dmat, translation)); 2264 } 2265 2266 panic("missing BHND_BUS_GET_DMA_TRANSLATION()"); 2267 } 2268 2269 /* nvram board_info population macros for bhnd_bus_generic_read_board_info() */ 2270 #define BHND_GV(_dest, _name) \ 2271 bhnd_nvram_getvar_uint(child, BHND_NVAR_ ## _name, &_dest, \ 2272 sizeof(_dest)) 2273 2274 #define REQ_BHND_GV(_dest, _name) do { \ 2275 if ((error = BHND_GV(_dest, _name))) { \ 2276 device_printf(dev, \ 2277 "error reading " __STRING(_name) ": %d\n", error); \ 2278 return (error); \ 2279 } \ 2280 } while(0) 2281 2282 #define OPT_BHND_GV(_dest, _name, _default) do { \ 2283 if ((error = BHND_GV(_dest, _name))) { \ 2284 if (error != ENOENT) { \ 2285 device_printf(dev, \ 2286 "error reading " \ 2287 __STRING(_name) ": %d\n", error); \ 2288 return (error); \ 2289 } \ 2290 _dest = _default; \ 2291 } \ 2292 } while(0) 2293 2294 /** 2295 * Helper function for implementing BHND_BUS_READ_BOARDINFO(). 2296 * 2297 * This implementation populates @p info with information from NVRAM, 2298 * defaulting board_vendor and board_type fields to 0 if the 2299 * requested variables cannot be found. 2300 * 2301 * This behavior is correct for most SoCs, but must be overridden on 2302 * bridged (PCI, PCMCIA, etc) devices to produce a complete bhnd_board_info 2303 * result. 2304 */ 2305 int 2306 bhnd_bus_generic_read_board_info(device_t dev, device_t child, 2307 struct bhnd_board_info *info) 2308 { 2309 int error; 2310 2311 OPT_BHND_GV(info->board_vendor, BOARDVENDOR, 0); 2312 OPT_BHND_GV(info->board_type, BOARDTYPE, 0); /* srom >= 2 */ 2313 REQ_BHND_GV(info->board_rev, BOARDREV); 2314 OPT_BHND_GV(info->board_srom_rev,SROMREV, 0); /* missing in 2315 some SoC 2316 NVRAM */ 2317 REQ_BHND_GV(info->board_flags, BOARDFLAGS); 2318 OPT_BHND_GV(info->board_flags2, BOARDFLAGS2, 0); /* srom >= 4 */ 2319 OPT_BHND_GV(info->board_flags3, BOARDFLAGS3, 0); /* srom >= 11 */ 2320 2321 return (0); 2322 } 2323 2324 #undef BHND_GV 2325 #undef BHND_GV_REQ 2326 #undef BHND_GV_OPT 2327 2328 /** 2329 * Helper function for implementing BHND_BUS_GET_NVRAM_VAR(). 2330 * 2331 * This implementation searches @p dev for a usable NVRAM child device. 2332 * 2333 * If no usable child device is found on @p dev, the request is delegated to 2334 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. 2335 */ 2336 int 2337 bhnd_bus_generic_get_nvram_var(device_t dev, device_t child, const char *name, 2338 void *buf, size_t *size, bhnd_nvram_type type) 2339 { 2340 device_t nvram; 2341 device_t parent; 2342 2343 /* Make sure we're holding Giant for newbus */ 2344 GIANT_REQUIRED; 2345 2346 /* Look for a directly-attached NVRAM child */ 2347 if ((nvram = device_find_child(dev, "bhnd_nvram", -1)) != NULL) 2348 return BHND_NVRAM_GETVAR(nvram, name, buf, size, type); 2349 2350 /* Try to delegate to parent */ 2351 if ((parent = device_get_parent(dev)) == NULL) 2352 return (ENODEV); 2353 2354 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child, 2355 name, buf, size, type)); 2356 } 2357 2358 /** 2359 * Helper function for implementing BHND_BUS_ALLOC_RESOURCE(). 2360 * 2361 * This implementation of BHND_BUS_ALLOC_RESOURCE() delegates allocation 2362 * of the underlying resource to BUS_ALLOC_RESOURCE(), and activation 2363 * to @p dev's BHND_BUS_ACTIVATE_RESOURCE(). 2364 */ 2365 struct bhnd_resource * 2366 bhnd_bus_generic_alloc_resource(device_t dev, device_t child, int type, 2367 int *rid, rman_res_t start, rman_res_t end, rman_res_t count, 2368 u_int flags) 2369 { 2370 struct bhnd_resource *br; 2371 struct resource *res; 2372 int error; 2373 2374 br = NULL; 2375 res = NULL; 2376 2377 /* Allocate the real bus resource (without activating it) */ 2378 res = BUS_ALLOC_RESOURCE(dev, child, type, rid, start, end, count, 2379 (flags & ~RF_ACTIVE)); 2380 if (res == NULL) 2381 return (NULL); 2382 2383 /* Allocate our bhnd resource wrapper. */ 2384 br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT); 2385 if (br == NULL) 2386 goto failed; 2387 2388 br->direct = false; 2389 br->res = res; 2390 2391 /* Attempt activation */ 2392 if (flags & RF_ACTIVE) { 2393 error = BHND_BUS_ACTIVATE_RESOURCE(dev, child, type, *rid, br); 2394 if (error) 2395 goto failed; 2396 } 2397 2398 return (br); 2399 2400 failed: 2401 if (res != NULL) 2402 BUS_RELEASE_RESOURCE(dev, child, type, *rid, res); 2403 2404 free(br, M_BHND); 2405 return (NULL); 2406 } 2407 2408 /** 2409 * Helper function for implementing BHND_BUS_RELEASE_RESOURCE(). 2410 * 2411 * This implementation of BHND_BUS_RELEASE_RESOURCE() delegates release of 2412 * the backing resource to BUS_RELEASE_RESOURCE(). 2413 */ 2414 int 2415 bhnd_bus_generic_release_resource(device_t dev, device_t child, int type, 2416 int rid, struct bhnd_resource *r) 2417 { 2418 int error; 2419 2420 if ((error = BUS_RELEASE_RESOURCE(dev, child, type, rid, r->res))) 2421 return (error); 2422 2423 free(r, M_BHND); 2424 return (0); 2425 } 2426 2427 2428 /** 2429 * Helper function for implementing BHND_BUS_ACTIVATE_RESOURCE(). 2430 * 2431 * This implementation of BHND_BUS_ACTIVATE_RESOURCE() first calls the 2432 * BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev. 2433 * 2434 * If this fails, and if @p dev is the direct parent of @p child, standard 2435 * resource activation is attempted via bus_activate_resource(). This enables 2436 * direct use of the bhnd(4) resource APIs on devices that may not be attached 2437 * to a parent bhnd bus or bridge. 2438 */ 2439 int 2440 bhnd_bus_generic_activate_resource(device_t dev, device_t child, int type, 2441 int rid, struct bhnd_resource *r) 2442 { 2443 int error; 2444 bool passthrough; 2445 2446 passthrough = (device_get_parent(child) != dev); 2447 2448 /* Try to delegate to the parent */ 2449 if (device_get_parent(dev) != NULL) { 2450 error = BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), 2451 child, type, rid, r); 2452 } else { 2453 error = ENODEV; 2454 } 2455 2456 /* If bhnd(4) activation has failed and we're the child's direct 2457 * parent, try falling back on standard resource activation. 2458 */ 2459 if (error && !passthrough) { 2460 error = bus_activate_resource(child, type, rid, r->res); 2461 if (!error) 2462 r->direct = true; 2463 } 2464 2465 return (error); 2466 } 2467 2468 /** 2469 * Helper function for implementing BHND_BUS_DEACTIVATE_RESOURCE(). 2470 * 2471 * This implementation of BHND_BUS_ACTIVATE_RESOURCE() simply calls the 2472 * BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev. 2473 */ 2474 int 2475 bhnd_bus_generic_deactivate_resource(device_t dev, device_t child, 2476 int type, int rid, struct bhnd_resource *r) 2477 { 2478 if (device_get_parent(dev) != NULL) 2479 return (BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), 2480 child, type, rid, r)); 2481 2482 return (EINVAL); 2483 } 2484 2485 /** 2486 * Helper function for implementing BHND_BUS_GET_INTR_DOMAIN(). 2487 * 2488 * This implementation simply returns the address of nearest bhnd(4) bus, 2489 * which may be @p dev; this behavior may be incompatible with FDT/OFW targets. 2490 */ 2491 uintptr_t 2492 bhnd_bus_generic_get_intr_domain(device_t dev, device_t child, bool self) 2493 { 2494 return ((uintptr_t)dev); 2495 } 2496