1 /*- 2 * Copyright (c) 2015 Landon Fuller <landon@landonf.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * Broadcom Home Networking Division (HND) Bus Driver. 35 * 36 * The Broadcom HND family of devices consists of both SoCs and host-connected 37 * networking chipsets containing a common family of Broadcom IP cores, 38 * including an integrated MIPS and/or ARM cores. 39 * 40 * HND devices expose a nearly identical interface whether accessible over a 41 * native SoC interconnect, or when connected via a host interface such as 42 * PCIe. As a result, the majority of hardware support code should be re-usable 43 * across host drivers for HND networking chipsets, as well as FreeBSD support 44 * for Broadcom MIPS/ARM HND SoCs. 45 * 46 * Earlier HND models used the siba(4) on-chip interconnect, while later models 47 * use bcma(4); the programming model is almost entirely independent 48 * of the actual underlying interconect. 49 */ 50 51 #include <sys/param.h> 52 #include <sys/kernel.h> 53 #include <sys/bus.h> 54 #include <sys/module.h> 55 #include <sys/systm.h> 56 57 #include <machine/bus.h> 58 #include <sys/rman.h> 59 #include <machine/resource.h> 60 61 #include <dev/bhnd/cores/chipc/chipcvar.h> 62 63 #include "bhnd_chipc_if.h" 64 #include "bhnd_nvram_if.h" 65 66 #include "bhnd.h" 67 #include "bhndvar.h" 68 69 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 70 71 /* Bus pass at which all bus-required children must be available, and 72 * attachment may be finalized. */ 73 #define BHND_FINISH_ATTACH_PASS BUS_PASS_DEFAULT 74 75 /** 76 * bhnd_generic_probe_nomatch() reporting configuration. 77 */ 78 static const struct bhnd_nomatch { 79 uint16_t vendor; /**< core designer */ 80 uint16_t device; /**< core id */ 81 bool if_verbose; /**< print when bootverbose is set. */ 82 } bhnd_nomatch_table[] = { 83 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 84 { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 85 { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 86 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 87 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 88 89 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 90 }; 91 92 93 static int bhnd_delete_children(struct bhnd_softc *sc); 94 95 static int bhnd_finish_attach(struct bhnd_softc *sc); 96 97 static device_t bhnd_find_chipc(struct bhnd_softc *sc); 98 static struct chipc_caps *bhnd_find_chipc_caps(struct bhnd_softc *sc); 99 static device_t bhnd_find_platform_dev(struct bhnd_softc *sc, 100 const char *classname); 101 static device_t bhnd_find_pmu(struct bhnd_softc *sc); 102 static device_t bhnd_find_nvram(struct bhnd_softc *sc); 103 104 static int compare_ascending_probe_order(const void *lhs, 105 const void *rhs); 106 static int compare_descending_probe_order(const void *lhs, 107 const void *rhs); 108 109 /** 110 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 111 * 112 * This implementation calls device_probe_and_attach() for each of the device's 113 * children, in bhnd probe order. 114 */ 115 int 116 bhnd_generic_attach(device_t dev) 117 { 118 struct bhnd_softc *sc; 119 device_t *devs; 120 int ndevs; 121 int error; 122 123 if (device_is_attached(dev)) 124 return (EBUSY); 125 126 sc = device_get_softc(dev); 127 sc->dev = dev; 128 129 if ((error = device_get_children(dev, &devs, &ndevs))) 130 return (error); 131 132 /* Probe and attach all children */ 133 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 134 for (int i = 0; i < ndevs; i++) { 135 device_t child = devs[i]; 136 device_probe_and_attach(child); 137 } 138 139 /* Try to finalize attachment */ 140 if (bus_current_pass >= BHND_FINISH_ATTACH_PASS) { 141 if ((error = bhnd_finish_attach(sc))) 142 goto cleanup; 143 } 144 145 cleanup: 146 free(devs, M_TEMP); 147 148 if (error) 149 bhnd_delete_children(sc); 150 151 return (error); 152 } 153 154 /** 155 * Detach and delete all children, in reverse of their attach order. 156 */ 157 static int 158 bhnd_delete_children(struct bhnd_softc *sc) 159 { 160 device_t *devs; 161 int ndevs; 162 int error; 163 164 if ((error = device_get_children(sc->dev, &devs, &ndevs))) 165 return (error); 166 167 /* Detach in the reverse of attach order */ 168 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 169 for (int i = 0; i < ndevs; i++) { 170 device_t child = devs[i]; 171 172 /* Terminate on first error */ 173 if ((error = device_delete_child(sc->dev, child))) 174 goto cleanup; 175 } 176 177 cleanup: 178 free(devs, M_TEMP); 179 return (error); 180 } 181 182 /** 183 * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 184 * 185 * This implementation calls device_detach() for each of the device's 186 * children, in reverse bhnd probe order, terminating if any call to 187 * device_detach() fails. 188 */ 189 int 190 bhnd_generic_detach(device_t dev) 191 { 192 struct bhnd_softc *sc; 193 194 if (!device_is_attached(dev)) 195 return (EBUSY); 196 197 sc = device_get_softc(dev); 198 return (bhnd_delete_children(sc)); 199 } 200 201 /** 202 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 203 * 204 * This implementation calls device_shutdown() for each of the device's 205 * children, in reverse bhnd probe order, terminating if any call to 206 * device_shutdown() fails. 207 */ 208 int 209 bhnd_generic_shutdown(device_t dev) 210 { 211 device_t *devs; 212 int ndevs; 213 int error; 214 215 if (!device_is_attached(dev)) 216 return (EBUSY); 217 218 if ((error = device_get_children(dev, &devs, &ndevs))) 219 return (error); 220 221 /* Shutdown in the reverse of attach order */ 222 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 223 for (int i = 0; i < ndevs; i++) { 224 device_t child = devs[i]; 225 226 /* Terminate on first error */ 227 if ((error = device_shutdown(child))) 228 goto cleanup; 229 } 230 231 cleanup: 232 free(devs, M_TEMP); 233 return (error); 234 } 235 236 /** 237 * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 238 * 239 * This implementation calls BUS_RESUME_CHILD() for each of the device's 240 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 241 * fails. 242 */ 243 int 244 bhnd_generic_resume(device_t dev) 245 { 246 device_t *devs; 247 int ndevs; 248 int error; 249 250 if (!device_is_attached(dev)) 251 return (EBUSY); 252 253 if ((error = device_get_children(dev, &devs, &ndevs))) 254 return (error); 255 256 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 257 for (int i = 0; i < ndevs; i++) { 258 device_t child = devs[i]; 259 260 /* Terminate on first error */ 261 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 262 goto cleanup; 263 } 264 265 cleanup: 266 free(devs, M_TEMP); 267 return (error); 268 } 269 270 /** 271 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 272 * 273 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 274 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 275 * fails, the suspend operation is terminated and any devices that were 276 * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 277 * methods. 278 */ 279 int 280 bhnd_generic_suspend(device_t dev) 281 { 282 device_t *devs; 283 int ndevs; 284 int error; 285 286 if (!device_is_attached(dev)) 287 return (EBUSY); 288 289 if ((error = device_get_children(dev, &devs, &ndevs))) 290 return (error); 291 292 /* Suspend in the reverse of attach order */ 293 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 294 for (int i = 0; i < ndevs; i++) { 295 device_t child = devs[i]; 296 error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 297 298 /* On error, resume suspended devices and then terminate */ 299 if (error) { 300 for (int j = 0; j < i; j++) { 301 BUS_RESUME_CHILD(device_get_parent(devs[j]), 302 devs[j]); 303 } 304 305 goto cleanup; 306 } 307 } 308 309 cleanup: 310 free(devs, M_TEMP); 311 return (error); 312 } 313 314 static void 315 bhnd_new_pass(device_t dev) 316 { 317 struct bhnd_softc *sc; 318 int error; 319 320 sc = device_get_softc(dev); 321 322 /* Attach any permissible children */ 323 bus_generic_new_pass(dev); 324 325 /* Finalize attachment */ 326 if (!sc->attach_done && bus_current_pass >= BHND_FINISH_ATTACH_PASS) { 327 if ((error = bhnd_finish_attach(sc))) { 328 panic("bhnd_finish_attach() failed: %d", error); 329 } 330 } 331 } 332 333 /* 334 * Finish any pending bus attachment operations. 335 * 336 * When attached as a SoC bus (as opposed to a bridged WiFi device), our 337 * platform devices may not be attached until later bus passes, necessitating 338 * delayed initialization on our part. 339 */ 340 static int 341 bhnd_finish_attach(struct bhnd_softc *sc) 342 { 343 struct chipc_caps *ccaps; 344 345 GIANT_REQUIRED; /* newbus */ 346 347 KASSERT(bus_current_pass >= BHND_FINISH_ATTACH_PASS, 348 ("bhnd_finish_attach() called in pass %d", bus_current_pass)); 349 350 KASSERT(!sc->attach_done, ("duplicate call to bhnd_finish_attach()")); 351 352 /* Locate chipc device */ 353 if ((sc->chipc_dev = bhnd_find_chipc(sc)) == NULL) { 354 device_printf(sc->dev, "error: ChipCommon device not found\n"); 355 return (ENXIO); 356 } 357 358 ccaps = BHND_CHIPC_GET_CAPS(sc->chipc_dev); 359 360 /* Look for NVRAM device */ 361 if (ccaps->nvram_src != BHND_NVRAM_SRC_UNKNOWN) { 362 if ((sc->nvram_dev = bhnd_find_nvram(sc)) == NULL) { 363 device_printf(sc->dev, 364 "warning: %s NVRAM device not found\n", 365 bhnd_nvram_src_name(ccaps->nvram_src)); 366 } 367 } 368 369 /* Look for a PMU */ 370 if (ccaps->pmu) { 371 if ((sc->pmu_dev = bhnd_find_pmu(sc)) == NULL) { 372 device_printf(sc->dev, 373 "warning: PMU device not found\n"); 374 } 375 } 376 377 /* Mark attach as completed */ 378 sc->attach_done = true; 379 380 return (0); 381 } 382 383 /* Locate the ChipCommon core. */ 384 static device_t 385 bhnd_find_chipc(struct bhnd_softc *sc) 386 { 387 device_t chipc; 388 389 /* Make sure we're holding Giant for newbus */ 390 GIANT_REQUIRED; 391 392 /* chipc_dev is initialized during attachment */ 393 if (sc->attach_done) { 394 if ((chipc = sc->chipc_dev) == NULL) 395 return (NULL); 396 397 goto found; 398 } 399 400 /* Locate chipc core with a core unit of 0 */ 401 chipc = bhnd_find_child(sc->dev, BHND_DEVCLASS_CC, 0); 402 if (chipc == NULL) 403 return (NULL); 404 405 found: 406 if (device_get_state(chipc) < DS_ATTACHING) { 407 device_printf(sc->dev, "chipc found, but did not attach\n"); 408 return (NULL); 409 } 410 411 return (chipc); 412 } 413 414 /* Locate the ChipCommon core and return the device capabilities */ 415 static struct chipc_caps * 416 bhnd_find_chipc_caps(struct bhnd_softc *sc) 417 { 418 device_t chipc; 419 420 if ((chipc = bhnd_find_chipc(sc)) == NULL) { 421 device_printf(sc->dev, 422 "chipc unavailable; cannot fetch capabilities\n"); 423 return (NULL); 424 } 425 426 return (BHND_CHIPC_GET_CAPS(chipc)); 427 } 428 429 /** 430 * Find an attached platform device on @p dev, searching first for cores 431 * matching @p classname, and if not found, searching the children of the first 432 * bhnd_chipc device on the bus. 433 * 434 * @param sc Driver state. 435 * @param chipc Attached ChipCommon device. 436 * @param classname Device class to search for. 437 * 438 * @retval device_t A matching device. 439 * @retval NULL If no matching device is found. 440 */ 441 static device_t 442 bhnd_find_platform_dev(struct bhnd_softc *sc, const char *classname) 443 { 444 device_t chipc, child; 445 446 /* Make sure we're holding Giant for newbus */ 447 GIANT_REQUIRED; 448 449 /* Look for a directly-attached child */ 450 child = device_find_child(sc->dev, classname, -1); 451 if (child != NULL) 452 goto found; 453 454 /* Look for the first matching ChipCommon child */ 455 if ((chipc = bhnd_find_chipc(sc)) == NULL) { 456 device_printf(sc->dev, 457 "chipc unavailable; cannot locate %s\n", classname); 458 return (NULL); 459 } 460 461 child = device_find_child(chipc, classname, -1); 462 if (child == NULL) 463 return (NULL); 464 465 found: 466 if (device_get_state(child) < DS_ATTACHING) 467 return (NULL); 468 469 return (child); 470 } 471 472 /* Locate the PMU device, if any */ 473 static device_t 474 bhnd_find_pmu(struct bhnd_softc *sc) 475 { 476 struct chipc_caps *ccaps; 477 478 /* Make sure we're holding Giant for newbus */ 479 GIANT_REQUIRED; 480 481 /* pmu_dev is initialized during attachment */ 482 if (sc->attach_done) { 483 if (sc->pmu_dev == NULL) 484 return (NULL); 485 486 if (device_get_state(sc->pmu_dev) < DS_ATTACHING) 487 return (NULL); 488 489 return (sc->pmu_dev); 490 } 491 492 if ((ccaps = bhnd_find_chipc_caps(sc)) == NULL) 493 return (NULL); 494 495 if (!ccaps->pmu) 496 return (NULL); 497 498 return (bhnd_find_platform_dev(sc, "bhnd_pmu")); 499 } 500 501 /* Locate the NVRAM device, if any */ 502 static device_t 503 bhnd_find_nvram(struct bhnd_softc *sc) 504 { 505 struct chipc_caps *ccaps; 506 507 /* Make sure we're holding Giant for newbus */ 508 GIANT_REQUIRED; 509 510 511 /* nvram_dev is initialized during attachment */ 512 if (sc->attach_done) { 513 if (sc->nvram_dev == NULL) 514 return (NULL); 515 516 if (device_get_state(sc->nvram_dev) < DS_ATTACHING) 517 return (NULL); 518 519 return (sc->nvram_dev); 520 } 521 522 if ((ccaps = bhnd_find_chipc_caps(sc)) == NULL) 523 return (NULL); 524 525 if (ccaps->nvram_src == BHND_NVRAM_SRC_UNKNOWN) 526 return (NULL); 527 528 return (bhnd_find_platform_dev(sc, "bhnd_nvram")); 529 } 530 531 /* 532 * Ascending comparison of bhnd device's probe order. 533 */ 534 static int 535 compare_ascending_probe_order(const void *lhs, const void *rhs) 536 { 537 device_t ldev, rdev; 538 int lorder, rorder; 539 540 ldev = (*(const device_t *) lhs); 541 rdev = (*(const device_t *) rhs); 542 543 lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 544 rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 545 546 if (lorder < rorder) { 547 return (-1); 548 } else if (lorder > rorder) { 549 return (1); 550 } else { 551 return (0); 552 } 553 } 554 555 /* 556 * Descending comparison of bhnd device's probe order. 557 */ 558 static int 559 compare_descending_probe_order(const void *lhs, const void *rhs) 560 { 561 return (compare_ascending_probe_order(rhs, lhs)); 562 } 563 564 /** 565 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 566 * 567 * This implementation determines probe ordering based on the device's class 568 * and other properties, including whether the device is serving as a host 569 * bridge. 570 */ 571 int 572 bhnd_generic_get_probe_order(device_t dev, device_t child) 573 { 574 switch (bhnd_get_class(child)) { 575 case BHND_DEVCLASS_CC: 576 /* Must be early enough to provide NVRAM access to the 577 * host bridge */ 578 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST); 579 580 case BHND_DEVCLASS_CC_B: 581 /* fall through */ 582 case BHND_DEVCLASS_PMU: 583 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 584 585 case BHND_DEVCLASS_SOC_ROUTER: 586 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 587 588 case BHND_DEVCLASS_SOC_BRIDGE: 589 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 590 591 case BHND_DEVCLASS_CPU: 592 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 593 594 case BHND_DEVCLASS_RAM: 595 /* fall through */ 596 case BHND_DEVCLASS_MEMC: 597 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 598 599 case BHND_DEVCLASS_NVRAM: 600 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 601 602 case BHND_DEVCLASS_PCI: 603 case BHND_DEVCLASS_PCIE: 604 case BHND_DEVCLASS_PCCARD: 605 case BHND_DEVCLASS_ENET: 606 case BHND_DEVCLASS_ENET_MAC: 607 case BHND_DEVCLASS_ENET_PHY: 608 case BHND_DEVCLASS_WLAN: 609 case BHND_DEVCLASS_WLAN_MAC: 610 case BHND_DEVCLASS_WLAN_PHY: 611 case BHND_DEVCLASS_EROM: 612 case BHND_DEVCLASS_OTHER: 613 case BHND_DEVCLASS_INVALID: 614 if (bhnd_find_hostb_device(dev) == child) 615 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 616 617 return (BHND_PROBE_DEFAULT); 618 default: 619 return (BHND_PROBE_DEFAULT); 620 } 621 } 622 623 /** 624 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 625 * 626 * This implementation assumes that port and region numbers are 0-indexed and 627 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 628 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 629 * within the defined range. 630 */ 631 static bool 632 bhnd_generic_is_region_valid(device_t dev, device_t child, 633 bhnd_port_type type, u_int port, u_int region) 634 { 635 if (port >= bhnd_get_port_count(child, type)) 636 return (false); 637 638 if (region >= bhnd_get_region_count(child, type, port)) 639 return (false); 640 641 return (true); 642 } 643 644 /** 645 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR(). 646 * 647 * This implementation searches @p dev for a usable NVRAM child device. 648 * 649 * If no usable child device is found on @p dev, the request is delegated to 650 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. 651 */ 652 int 653 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name, 654 void *buf, size_t *size) 655 { 656 struct bhnd_softc *sc; 657 device_t nvram, parent; 658 659 sc = device_get_softc(dev); 660 661 /* If a NVRAM device is available, consult it first */ 662 if ((nvram = bhnd_find_nvram(sc)) != NULL) 663 return BHND_NVRAM_GETVAR(nvram, name, buf, size); 664 665 /* Otherwise, try to delegate to parent */ 666 if ((parent = device_get_parent(dev)) == NULL) 667 return (ENODEV); 668 669 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child, 670 name, buf, size)); 671 } 672 673 /** 674 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 675 * 676 * This implementation requests the device's struct resource_list via 677 * BUS_GET_RESOURCE_LIST. 678 */ 679 int 680 bhnd_generic_print_child(device_t dev, device_t child) 681 { 682 struct resource_list *rl; 683 int retval = 0; 684 685 retval += bus_print_child_header(dev, child); 686 687 rl = BUS_GET_RESOURCE_LIST(dev, child); 688 if (rl != NULL) { 689 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 690 "%#jx"); 691 } 692 693 retval += printf(" at core %u", bhnd_get_core_index(child)); 694 695 retval += bus_print_child_domain(dev, child); 696 retval += bus_print_child_footer(dev, child); 697 698 return (retval); 699 } 700 701 /** 702 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 703 * 704 * This implementation requests the device's struct resource_list via 705 * BUS_GET_RESOURCE_LIST. 706 */ 707 void 708 bhnd_generic_probe_nomatch(device_t dev, device_t child) 709 { 710 struct resource_list *rl; 711 const struct bhnd_nomatch *nm; 712 bool report; 713 714 /* Fetch reporting configuration for this device */ 715 report = true; 716 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 717 if (nm->vendor != bhnd_get_vendor(child)) 718 continue; 719 720 if (nm->device != bhnd_get_device(child)) 721 continue; 722 723 report = false; 724 if (bootverbose && nm->if_verbose) 725 report = true; 726 break; 727 } 728 729 if (!report) 730 return; 731 732 /* Print the non-matched device info */ 733 device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child), 734 bhnd_get_device_name(child)); 735 736 rl = BUS_GET_RESOURCE_LIST(dev, child); 737 if (rl != NULL) 738 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 739 740 printf(" at core %u (no driver attached)\n", 741 bhnd_get_core_index(child)); 742 } 743 744 /** 745 * Default implementation of BUS_CHILD_PNPINFO_STR(). 746 */ 747 static int 748 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 749 size_t buflen) 750 { 751 if (device_get_parent(child) != dev) { 752 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 753 buf, buflen)); 754 } 755 756 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 757 bhnd_get_vendor(child), bhnd_get_device(child), 758 bhnd_get_hwrev(child)); 759 760 return (0); 761 } 762 763 /** 764 * Default implementation of BUS_CHILD_LOCATION_STR(). 765 */ 766 static int 767 bhnd_child_location_str(device_t dev, device_t child, char *buf, 768 size_t buflen) 769 { 770 bhnd_addr_t addr; 771 bhnd_size_t size; 772 773 if (device_get_parent(child) != dev) { 774 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 775 buf, buflen)); 776 } 777 778 779 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 780 /* No device default port/region */ 781 if (buflen > 0) 782 *buf = '\0'; 783 return (0); 784 } 785 786 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 787 return (0); 788 } 789 790 /** 791 * Default bhnd(4) bus driver implementation of BUS_ADD_CHILD(). 792 * 793 * This implementation manages internal bhnd(4) state, and must be called 794 * by subclassing drivers. 795 */ 796 device_t 797 bhnd_generic_add_child(device_t dev, u_int order, const char *name, int unit) 798 { 799 struct bhnd_devinfo *dinfo; 800 device_t child; 801 802 child = device_add_child_ordered(dev, order, name, unit); 803 if (child == NULL) 804 return (NULL); 805 806 if ((dinfo = BHND_BUS_ALLOC_DEVINFO(dev)) == NULL) { 807 device_delete_child(dev, child); 808 return (NULL); 809 } 810 811 device_set_ivars(child, dinfo); 812 813 /* Inform concrete bus driver. */ 814 BHND_BUS_CHILD_ADDED(dev, child); 815 816 return (child); 817 } 818 819 /** 820 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED(). 821 * 822 * This implementation manages internal bhnd(4) state, and must be called 823 * by subclassing drivers. 824 */ 825 void 826 bhnd_generic_child_deleted(device_t dev, device_t child) 827 { 828 struct bhnd_softc *sc; 829 struct bhnd_devinfo *dinfo; 830 831 sc = device_get_softc(dev); 832 833 /* Free device info */ 834 if ((dinfo = device_get_ivars(child)) != NULL) 835 BHND_BUS_FREE_DEVINFO(dev, dinfo); 836 837 /* Clean up platform device references */ 838 if (sc->chipc_dev == child) { 839 sc->chipc_dev = NULL; 840 } else if (sc->nvram_dev == child) { 841 sc->nvram_dev = NULL; 842 } else if (sc->pmu_dev == child) { 843 sc->pmu_dev = NULL; 844 } 845 } 846 847 /** 848 * Helper function for implementing BUS_SUSPEND_CHILD(). 849 * 850 * TODO: Power management 851 * 852 * If @p child is not a direct child of @p dev, suspension is delegated to 853 * the @p dev parent. 854 */ 855 int 856 bhnd_generic_suspend_child(device_t dev, device_t child) 857 { 858 if (device_get_parent(child) != dev) 859 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 860 861 return bus_generic_suspend_child(dev, child); 862 } 863 864 /** 865 * Helper function for implementing BUS_RESUME_CHILD(). 866 * 867 * TODO: Power management 868 * 869 * If @p child is not a direct child of @p dev, suspension is delegated to 870 * the @p dev parent. 871 */ 872 int 873 bhnd_generic_resume_child(device_t dev, device_t child) 874 { 875 if (device_get_parent(child) != dev) 876 BUS_RESUME_CHILD(device_get_parent(dev), child); 877 878 return bus_generic_resume_child(dev, child); 879 } 880 881 /* 882 * Delegate all indirect I/O to the parent device. When inherited by 883 * non-bridged bus implementations, resources will never be marked as 884 * indirect, and these methods will never be called. 885 */ 886 #define BHND_IO_READ(_type, _name, _method) \ 887 static _type \ 888 bhnd_read_ ## _name (device_t dev, device_t child, \ 889 struct bhnd_resource *r, bus_size_t offset) \ 890 { \ 891 return (BHND_BUS_READ_ ## _method( \ 892 device_get_parent(dev), child, r, offset)); \ 893 } 894 895 #define BHND_IO_WRITE(_type, _name, _method) \ 896 static void \ 897 bhnd_write_ ## _name (device_t dev, device_t child, \ 898 struct bhnd_resource *r, bus_size_t offset, _type value) \ 899 { \ 900 return (BHND_BUS_WRITE_ ## _method( \ 901 device_get_parent(dev), child, r, offset, \ 902 value)); \ 903 } 904 905 #define BHND_IO_MISC(_type, _op, _method) \ 906 static void \ 907 bhnd_ ## _op (device_t dev, device_t child, \ 908 struct bhnd_resource *r, bus_size_t offset, _type datap, \ 909 bus_size_t count) \ 910 { \ 911 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 912 offset, datap, count); \ 913 } 914 915 #define BHND_IO_METHODS(_type, _size) \ 916 BHND_IO_READ(_type, _size, _size) \ 917 BHND_IO_WRITE(_type, _size, _size) \ 918 \ 919 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 920 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 921 \ 922 BHND_IO_MISC(_type*, read_multi_ ## _size, \ 923 READ_MULTI_ ## _size) \ 924 BHND_IO_MISC(_type*, write_multi_ ## _size, \ 925 WRITE_MULTI_ ## _size) \ 926 \ 927 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \ 928 READ_MULTI_STREAM_ ## _size) \ 929 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \ 930 WRITE_MULTI_STREAM_ ## _size) \ 931 \ 932 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \ 933 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \ 934 \ 935 BHND_IO_MISC(_type*, read_region_ ## _size, \ 936 READ_REGION_ ## _size) \ 937 BHND_IO_MISC(_type*, write_region_ ## _size, \ 938 WRITE_REGION_ ## _size) \ 939 \ 940 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \ 941 READ_REGION_STREAM_ ## _size) \ 942 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \ 943 WRITE_REGION_STREAM_ ## _size) \ 944 945 BHND_IO_METHODS(uint8_t, 1); 946 BHND_IO_METHODS(uint16_t, 2); 947 BHND_IO_METHODS(uint32_t, 4); 948 949 static void 950 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 951 bus_size_t offset, bus_size_t length, int flags) 952 { 953 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 954 flags); 955 } 956 957 static device_method_t bhnd_methods[] = { 958 /* Device interface */ \ 959 DEVMETHOD(device_attach, bhnd_generic_attach), 960 DEVMETHOD(device_detach, bhnd_generic_detach), 961 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 962 DEVMETHOD(device_suspend, bhnd_generic_suspend), 963 DEVMETHOD(device_resume, bhnd_generic_resume), 964 965 /* Bus interface */ 966 DEVMETHOD(bus_new_pass, bhnd_new_pass), 967 DEVMETHOD(bus_add_child, bhnd_generic_add_child), 968 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted), 969 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 970 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 971 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 972 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 973 974 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 975 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 976 977 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 978 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 979 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 980 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 981 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 982 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 983 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 984 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 985 986 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 987 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 988 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 989 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 990 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 991 992 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 993 994 /* BHND interface */ 995 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 996 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 997 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 998 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 999 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var), 1000 1001 /* BHND interface (bus I/O) */ 1002 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 1003 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 1004 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 1005 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 1006 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 1007 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 1008 1009 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 1010 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 1011 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 1012 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 1013 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 1014 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 1015 1016 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 1017 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 1018 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 1019 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 1020 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 1021 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 1022 1023 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 1024 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 1025 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 1026 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 1027 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 1028 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 1029 1030 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1), 1031 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2), 1032 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4), 1033 1034 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1), 1035 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2), 1036 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4), 1037 1038 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1), 1039 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2), 1040 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4), 1041 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1), 1042 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2), 1043 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4), 1044 1045 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1), 1046 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2), 1047 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4), 1048 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1), 1049 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2), 1050 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4), 1051 1052 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 1053 1054 DEVMETHOD_END 1055 }; 1056 1057 devclass_t bhnd_devclass; /**< bhnd bus. */ 1058 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 1059 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 1060 1061 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 1062 MODULE_VERSION(bhnd, 1); 1063