1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.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 /* 38 * Broadcom Home Networking Division (HND) Bus Driver. 39 * 40 * The Broadcom HND family of devices consists of both SoCs and host-connected 41 * networking chipsets containing a common family of Broadcom IP cores, 42 * including an integrated MIPS and/or ARM cores. 43 * 44 * HND devices expose a nearly identical interface whether accessible over a 45 * native SoC interconnect, or when connected via a host interface such as 46 * PCIe. As a result, the majority of hardware support code should be re-usable 47 * across host drivers for HND networking chipsets, as well as FreeBSD support 48 * for Broadcom MIPS/ARM HND SoCs. 49 * 50 * Earlier HND models used the siba(4) on-chip interconnect, while later models 51 * use bcma(4); the programming model is almost entirely independent 52 * of the actual underlying interconect. 53 */ 54 55 #include <sys/param.h> 56 #include <sys/kernel.h> 57 #include <sys/bus.h> 58 #include <sys/module.h> 59 #include <sys/systm.h> 60 61 #include <machine/bus.h> 62 #include <sys/rman.h> 63 #include <machine/resource.h> 64 65 #include <dev/bhnd/cores/chipc/chipcvar.h> 66 67 #include <dev/bhnd/cores/pmu/bhnd_pmu.h> 68 #include <dev/bhnd/cores/pmu/bhnd_pmureg.h> 69 70 #include "bhnd_chipc_if.h" 71 #include "bhnd_nvram_if.h" 72 73 #include "bhnd.h" 74 #include "bhndvar.h" 75 76 #include "bhnd_private.h" 77 78 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 79 80 /** 81 * bhnd_generic_probe_nomatch() reporting configuration. 82 */ 83 static const struct bhnd_nomatch { 84 uint16_t vendor; /**< core designer */ 85 uint16_t device; /**< core id */ 86 bool if_verbose; /**< print when bootverbose is set. */ 87 } bhnd_nomatch_table[] = { 88 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 89 { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 90 { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 91 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 92 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 93 94 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 95 }; 96 97 static int bhnd_delete_children(struct bhnd_softc *sc); 98 99 /** 100 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 101 * 102 * This implementation calls device_probe_and_attach() for each of the device's 103 * children, in bhnd probe order. 104 */ 105 int 106 bhnd_generic_attach(device_t dev) 107 { 108 struct bhnd_softc *sc; 109 int error; 110 111 if (device_is_attached(dev)) 112 return (EBUSY); 113 114 sc = device_get_softc(dev); 115 sc->dev = dev; 116 117 /* Probe and attach all children */ 118 if ((error = bhnd_bus_probe_children(dev))) { 119 bhnd_delete_children(sc); 120 return (error); 121 } 122 123 return (0); 124 } 125 126 /** 127 * Detach and delete all children, in reverse of their attach order. 128 */ 129 static int 130 bhnd_delete_children(struct bhnd_softc *sc) 131 { 132 device_t *devs; 133 int ndevs; 134 int error; 135 136 /* Fetch children in detach order */ 137 error = bhnd_bus_get_children(sc->dev, &devs, &ndevs, 138 BHND_DEVICE_ORDER_DETACH); 139 if (error) 140 return (error); 141 142 /* Perform detach */ 143 for (int i = 0; i < ndevs; i++) { 144 device_t child = devs[i]; 145 146 /* Terminate on first error */ 147 if ((error = device_delete_child(sc->dev, child))) 148 goto cleanup; 149 } 150 151 cleanup: 152 bhnd_bus_free_children(devs); 153 return (error); 154 } 155 156 /** 157 * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 158 * 159 * This implementation calls device_detach() for each of the device's 160 * children, in reverse bhnd probe order, terminating if any call to 161 * device_detach() fails. 162 */ 163 int 164 bhnd_generic_detach(device_t dev) 165 { 166 struct bhnd_softc *sc; 167 int error; 168 169 if (!device_is_attached(dev)) 170 return (EBUSY); 171 172 sc = device_get_softc(dev); 173 174 if ((error = bhnd_delete_children(sc))) 175 return (error); 176 177 return (0); 178 } 179 180 /** 181 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 182 * 183 * This implementation calls device_shutdown() for each of the device's 184 * children, in reverse bhnd probe order, terminating if any call to 185 * device_shutdown() fails. 186 */ 187 int 188 bhnd_generic_shutdown(device_t dev) 189 { 190 device_t *devs; 191 int ndevs; 192 int error; 193 194 if (!device_is_attached(dev)) 195 return (EBUSY); 196 197 /* Fetch children in detach order */ 198 error = bhnd_bus_get_children(dev, &devs, &ndevs, 199 BHND_DEVICE_ORDER_DETACH); 200 if (error) 201 return (error); 202 203 /* Perform shutdown */ 204 for (int i = 0; i < ndevs; i++) { 205 device_t child = devs[i]; 206 207 /* Terminate on first error */ 208 if ((error = device_shutdown(child))) 209 goto cleanup; 210 } 211 212 cleanup: 213 bhnd_bus_free_children(devs); 214 return (error); 215 } 216 217 /** 218 * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 219 * 220 * This implementation calls BUS_RESUME_CHILD() for each of the device's 221 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 222 * fails. 223 */ 224 int 225 bhnd_generic_resume(device_t dev) 226 { 227 device_t *devs; 228 int ndevs; 229 int error; 230 231 if (!device_is_attached(dev)) 232 return (EBUSY); 233 234 /* Fetch children in attach order */ 235 error = bhnd_bus_get_children(dev, &devs, &ndevs, 236 BHND_DEVICE_ORDER_ATTACH); 237 if (error) 238 return (error); 239 240 /* Perform resume */ 241 for (int i = 0; i < ndevs; i++) { 242 device_t child = devs[i]; 243 244 /* Terminate on first error */ 245 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 246 goto cleanup; 247 } 248 249 cleanup: 250 bhnd_bus_free_children(devs); 251 return (error); 252 } 253 254 /** 255 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 256 * 257 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 258 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 259 * fails, the suspend operation is terminated and any devices that were 260 * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 261 * methods. 262 */ 263 int 264 bhnd_generic_suspend(device_t dev) 265 { 266 device_t *devs; 267 int ndevs; 268 int error; 269 270 if (!device_is_attached(dev)) 271 return (EBUSY); 272 273 /* Fetch children in detach order */ 274 error = bhnd_bus_get_children(dev, &devs, &ndevs, 275 BHND_DEVICE_ORDER_DETACH); 276 if (error) 277 return (error); 278 279 /* Perform suspend */ 280 for (int i = 0; i < ndevs; i++) { 281 device_t child = devs[i]; 282 error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 283 284 /* On error, resume suspended devices and then terminate */ 285 if (error) { 286 for (int j = 0; j < i; j++) { 287 BUS_RESUME_CHILD(device_get_parent(devs[j]), 288 devs[j]); 289 } 290 291 goto cleanup; 292 } 293 } 294 295 cleanup: 296 bhnd_bus_free_children(devs); 297 return (error); 298 } 299 300 /** 301 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 302 * 303 * This implementation determines probe ordering based on the device's class 304 * and other properties, including whether the device is serving as a host 305 * bridge. 306 */ 307 int 308 bhnd_generic_get_probe_order(device_t dev, device_t child) 309 { 310 switch (bhnd_get_class(child)) { 311 case BHND_DEVCLASS_CC: 312 /* Must be early enough to provide NVRAM access to the 313 * host bridge */ 314 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST); 315 316 case BHND_DEVCLASS_CC_B: 317 /* fall through */ 318 case BHND_DEVCLASS_PMU: 319 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 320 321 case BHND_DEVCLASS_SOC_ROUTER: 322 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 323 324 case BHND_DEVCLASS_SOC_BRIDGE: 325 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 326 327 case BHND_DEVCLASS_CPU: 328 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 329 330 case BHND_DEVCLASS_RAM: 331 /* fall through */ 332 case BHND_DEVCLASS_MEMC: 333 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 334 335 case BHND_DEVCLASS_NVRAM: 336 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 337 338 case BHND_DEVCLASS_PCI: 339 case BHND_DEVCLASS_PCIE: 340 case BHND_DEVCLASS_PCCARD: 341 case BHND_DEVCLASS_ENET: 342 case BHND_DEVCLASS_ENET_MAC: 343 case BHND_DEVCLASS_ENET_PHY: 344 case BHND_DEVCLASS_WLAN: 345 case BHND_DEVCLASS_WLAN_MAC: 346 case BHND_DEVCLASS_WLAN_PHY: 347 case BHND_DEVCLASS_EROM: 348 case BHND_DEVCLASS_OTHER: 349 case BHND_DEVCLASS_INVALID: 350 if (bhnd_bus_find_hostb_device(dev) == child) 351 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 352 353 return (BHND_PROBE_DEFAULT); 354 default: 355 return (BHND_PROBE_DEFAULT); 356 } 357 } 358 359 /** 360 * Default bhnd(4) bus driver implementation of BHND_BUS_ALLOC_PMU(). 361 */ 362 int 363 bhnd_generic_alloc_pmu(device_t dev, device_t child) 364 { 365 struct bhnd_softc *sc; 366 struct bhnd_resource *br; 367 struct bhnd_core_pmu_info *pm; 368 struct resource_list *rl; 369 struct resource_list_entry *rle; 370 device_t pmu_dev; 371 bhnd_addr_t r_addr; 372 bhnd_size_t r_size; 373 bus_size_t pmu_regs; 374 int error; 375 376 GIANT_REQUIRED; /* for newbus */ 377 378 sc = device_get_softc(dev); 379 pm = bhnd_get_pmu_info(child); 380 pmu_regs = BHND_CLK_CTL_ST; 381 382 /* already allocated? */ 383 if (pm != NULL) { 384 panic("duplicate PMU allocation for %s", 385 device_get_nameunit(child)); 386 } 387 388 /* Determine address+size of the core's PMU register block */ 389 error = bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &r_addr, 390 &r_size); 391 if (error) { 392 device_printf(sc->dev, "error fetching register block info for " 393 "%s: %d\n", device_get_nameunit(child), error); 394 return (error); 395 } 396 397 if (r_size < (pmu_regs + sizeof(uint32_t))) { 398 device_printf(sc->dev, "pmu offset %#jx would overrun %s " 399 "register block\n", (uintmax_t)pmu_regs, 400 device_get_nameunit(child)); 401 return (ENODEV); 402 } 403 404 /* Locate actual resource containing the core's register block */ 405 if ((rl = BUS_GET_RESOURCE_LIST(dev, child)) == NULL) { 406 device_printf(dev, "NULL resource list returned for %s\n", 407 device_get_nameunit(child)); 408 return (ENXIO); 409 } 410 411 if ((rle = resource_list_find(rl, SYS_RES_MEMORY, 0)) == NULL) { 412 device_printf(dev, "cannot locate core register resource " 413 "for %s\n", device_get_nameunit(child)); 414 return (ENXIO); 415 } 416 417 if (rle->res == NULL) { 418 device_printf(dev, "core register resource unallocated for " 419 "%s\n", device_get_nameunit(child)); 420 return (ENXIO); 421 } 422 423 if (r_addr+pmu_regs < rman_get_start(rle->res) || 424 r_addr+pmu_regs >= rman_get_end(rle->res)) 425 { 426 device_printf(dev, "core register resource does not map PMU " 427 "registers at %#jx\n for %s\n", r_addr+pmu_regs, 428 device_get_nameunit(child)); 429 return (ENXIO); 430 } 431 432 /* Adjust PMU register offset relative to the actual start address 433 * of the core's register block allocation. 434 * 435 * XXX: The saved offset will be invalid if bus_adjust_resource is 436 * used to modify the resource's start address. 437 */ 438 if (rman_get_start(rle->res) > r_addr) 439 pmu_regs -= rman_get_start(rle->res) - r_addr; 440 else 441 pmu_regs -= r_addr - rman_get_start(rle->res); 442 443 /* Retain PMU reference on behalf of our caller */ 444 pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU); 445 if (pmu_dev == NULL) { 446 device_printf(sc->dev, 447 "pmu unavailable; cannot allocate request state\n"); 448 return (ENXIO); 449 } 450 451 /* Allocate and initialize PMU info */ 452 br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT); 453 if (br == NULL) { 454 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU); 455 return (ENOMEM); 456 } 457 458 br->res = rle->res; 459 br->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0); 460 461 pm = malloc(sizeof(*pm), M_BHND, M_NOWAIT); 462 if (pm == NULL) { 463 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU); 464 free(br, M_BHND); 465 return (ENOMEM); 466 } 467 pm->pm_dev = child; 468 pm->pm_res = br; 469 pm->pm_regs = pmu_regs; 470 pm->pm_pmu = pmu_dev; 471 472 bhnd_set_pmu_info(child, pm); 473 return (0); 474 } 475 476 /** 477 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_PMU(). 478 */ 479 int 480 bhnd_generic_release_pmu(device_t dev, device_t child) 481 { 482 struct bhnd_softc *sc; 483 struct bhnd_core_pmu_info *pm; 484 int error; 485 486 GIANT_REQUIRED; /* for newbus */ 487 488 sc = device_get_softc(dev); 489 490 /* dispatch release request */ 491 pm = bhnd_get_pmu_info(child); 492 if (pm == NULL) 493 panic("pmu over-release for %s", device_get_nameunit(child)); 494 495 if ((error = BHND_PMU_CORE_RELEASE(pm->pm_pmu, pm))) 496 return (error); 497 498 /* free PMU info */ 499 bhnd_set_pmu_info(child, NULL); 500 501 bhnd_release_provider(pm->pm_dev, pm->pm_pmu, BHND_SERVICE_PMU); 502 free(pm->pm_res, M_BHND); 503 free(pm, M_BHND); 504 505 return (0); 506 } 507 508 /** 509 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_CLOCK(). 510 */ 511 int 512 bhnd_generic_request_clock(device_t dev, device_t child, bhnd_clock clock) 513 { 514 struct bhnd_softc *sc; 515 struct bhnd_core_pmu_info *pm; 516 517 sc = device_get_softc(dev); 518 519 if ((pm = bhnd_get_pmu_info(child)) == NULL) 520 panic("no active PMU request state"); 521 522 /* dispatch request to PMU */ 523 return (BHND_PMU_CORE_REQ_CLOCK(pm->pm_pmu, pm, clock)); 524 } 525 526 /** 527 * Default bhnd(4) bus driver implementation of BHND_BUS_ENABLE_CLOCKS(). 528 */ 529 int 530 bhnd_generic_enable_clocks(device_t dev, device_t child, uint32_t clocks) 531 { 532 struct bhnd_softc *sc; 533 struct bhnd_core_pmu_info *pm; 534 535 sc = device_get_softc(dev); 536 537 if ((pm = bhnd_get_pmu_info(child)) == NULL) 538 panic("no active PMU request state"); 539 540 /* dispatch request to PMU */ 541 return (BHND_PMU_CORE_EN_CLOCKS(pm->pm_pmu, pm, clocks)); 542 } 543 544 /** 545 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC(). 546 */ 547 int 548 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc) 549 { 550 struct bhnd_softc *sc; 551 struct bhnd_core_pmu_info *pm; 552 553 sc = device_get_softc(dev); 554 555 if ((pm = bhnd_get_pmu_info(child)) == NULL) 556 panic("no active PMU request state"); 557 558 /* dispatch request to PMU */ 559 return (BHND_PMU_CORE_REQ_EXT_RSRC(pm->pm_pmu, pm, rsrc)); 560 } 561 562 /** 563 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC(). 564 */ 565 int 566 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc) 567 { 568 struct bhnd_softc *sc; 569 struct bhnd_core_pmu_info *pm; 570 571 sc = device_get_softc(dev); 572 573 if ((pm = bhnd_get_pmu_info(child)) == NULL) 574 panic("no active PMU request state"); 575 576 /* dispatch request to PMU */ 577 return (BHND_PMU_CORE_RELEASE_EXT_RSRC(pm->pm_pmu, pm, rsrc)); 578 } 579 580 581 /** 582 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 583 * 584 * This implementation assumes that port and region numbers are 0-indexed and 585 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 586 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 587 * within the defined range. 588 */ 589 static bool 590 bhnd_generic_is_region_valid(device_t dev, device_t child, 591 bhnd_port_type type, u_int port, u_int region) 592 { 593 if (port >= bhnd_get_port_count(child, type)) 594 return (false); 595 596 if (region >= bhnd_get_region_count(child, type, port)) 597 return (false); 598 599 return (true); 600 } 601 602 /** 603 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR(). 604 * 605 * This implementation searches @p dev for a registered NVRAM child device. 606 * 607 * If no NVRAM device is registered with @p dev, the request is delegated to 608 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. 609 */ 610 int 611 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name, 612 void *buf, size_t *size, bhnd_nvram_type type) 613 { 614 struct bhnd_softc *sc; 615 device_t nvram, parent; 616 int error; 617 618 sc = device_get_softc(dev); 619 620 /* If a NVRAM device is available, consult it first */ 621 nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM); 622 if (nvram != NULL) { 623 error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type); 624 bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM); 625 return (error); 626 } 627 628 /* Otherwise, try to delegate to parent */ 629 if ((parent = device_get_parent(dev)) == NULL) 630 return (ENODEV); 631 632 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child, 633 name, buf, size, type)); 634 } 635 636 /** 637 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 638 * 639 * This implementation requests the device's struct resource_list via 640 * BUS_GET_RESOURCE_LIST. 641 */ 642 int 643 bhnd_generic_print_child(device_t dev, device_t child) 644 { 645 struct resource_list *rl; 646 int retval = 0; 647 648 retval += bus_print_child_header(dev, child); 649 650 rl = BUS_GET_RESOURCE_LIST(dev, child); 651 652 653 if (rl != NULL) { 654 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 655 "%#jx"); 656 657 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, 658 "%#jd"); 659 } 660 661 retval += printf(" at core %u", bhnd_get_core_index(child)); 662 663 retval += bus_print_child_domain(dev, child); 664 retval += bus_print_child_footer(dev, child); 665 666 return (retval); 667 } 668 669 /** 670 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 671 * 672 * This implementation requests the device's struct resource_list via 673 * BUS_GET_RESOURCE_LIST. 674 */ 675 void 676 bhnd_generic_probe_nomatch(device_t dev, device_t child) 677 { 678 struct resource_list *rl; 679 const struct bhnd_nomatch *nm; 680 bool report; 681 682 /* Fetch reporting configuration for this device */ 683 report = true; 684 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 685 if (nm->vendor != bhnd_get_vendor(child)) 686 continue; 687 688 if (nm->device != bhnd_get_device(child)) 689 continue; 690 691 report = false; 692 if (bootverbose && nm->if_verbose) 693 report = true; 694 break; 695 } 696 697 if (!report) 698 return; 699 700 /* Print the non-matched device info */ 701 device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child), 702 bhnd_get_device_name(child)); 703 704 rl = BUS_GET_RESOURCE_LIST(dev, child); 705 if (rl != NULL) { 706 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 707 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd"); 708 } 709 710 printf(" at core %u (no driver attached)\n", 711 bhnd_get_core_index(child)); 712 } 713 714 /** 715 * Default implementation of BUS_CHILD_PNPINFO_STR(). 716 */ 717 static int 718 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 719 size_t buflen) 720 { 721 if (device_get_parent(child) != dev) { 722 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 723 buf, buflen)); 724 } 725 726 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 727 bhnd_get_vendor(child), bhnd_get_device(child), 728 bhnd_get_hwrev(child)); 729 730 return (0); 731 } 732 733 /** 734 * Default implementation of BUS_CHILD_LOCATION_STR(). 735 */ 736 static int 737 bhnd_child_location_str(device_t dev, device_t child, char *buf, 738 size_t buflen) 739 { 740 bhnd_addr_t addr; 741 bhnd_size_t size; 742 743 if (device_get_parent(child) != dev) { 744 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 745 buf, buflen)); 746 } 747 748 749 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 750 /* No device default port/region */ 751 if (buflen > 0) 752 *buf = '\0'; 753 return (0); 754 } 755 756 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 757 return (0); 758 } 759 760 /** 761 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED(). 762 * 763 * This implementation manages internal bhnd(4) state, and must be called 764 * by subclassing drivers. 765 */ 766 void 767 bhnd_generic_child_deleted(device_t dev, device_t child) 768 { 769 struct bhnd_softc *sc; 770 771 sc = device_get_softc(dev); 772 773 /* Free device info */ 774 if (bhnd_get_pmu_info(child) != NULL) { 775 /* Releasing PMU requests automatically would be nice, 776 * but we can't reference per-core PMU register 777 * resource after driver detach */ 778 panic("%s leaked device pmu state\n", 779 device_get_nameunit(child)); 780 } 781 } 782 783 /** 784 * Helper function for implementing BUS_SUSPEND_CHILD(). 785 * 786 * TODO: Power management 787 * 788 * If @p child is not a direct child of @p dev, suspension is delegated to 789 * the @p dev parent. 790 */ 791 int 792 bhnd_generic_suspend_child(device_t dev, device_t child) 793 { 794 if (device_get_parent(child) != dev) 795 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 796 797 return bus_generic_suspend_child(dev, child); 798 } 799 800 /** 801 * Helper function for implementing BUS_RESUME_CHILD(). 802 * 803 * TODO: Power management 804 * 805 * If @p child is not a direct child of @p dev, suspension is delegated to 806 * the @p dev parent. 807 */ 808 int 809 bhnd_generic_resume_child(device_t dev, device_t child) 810 { 811 if (device_get_parent(child) != dev) 812 BUS_RESUME_CHILD(device_get_parent(dev), child); 813 814 return bus_generic_resume_child(dev, child); 815 } 816 817 /* 818 * Delegate all indirect I/O to the parent device. When inherited by 819 * non-bridged bus implementations, resources will never be marked as 820 * indirect, and these methods will never be called. 821 */ 822 #define BHND_IO_READ(_type, _name, _method) \ 823 static _type \ 824 bhnd_read_ ## _name (device_t dev, device_t child, \ 825 struct bhnd_resource *r, bus_size_t offset) \ 826 { \ 827 return (BHND_BUS_READ_ ## _method( \ 828 device_get_parent(dev), child, r, offset)); \ 829 } 830 831 #define BHND_IO_WRITE(_type, _name, _method) \ 832 static void \ 833 bhnd_write_ ## _name (device_t dev, device_t child, \ 834 struct bhnd_resource *r, bus_size_t offset, _type value) \ 835 { \ 836 return (BHND_BUS_WRITE_ ## _method( \ 837 device_get_parent(dev), child, r, offset, \ 838 value)); \ 839 } 840 841 #define BHND_IO_MISC(_type, _op, _method) \ 842 static void \ 843 bhnd_ ## _op (device_t dev, device_t child, \ 844 struct bhnd_resource *r, bus_size_t offset, _type datap, \ 845 bus_size_t count) \ 846 { \ 847 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 848 offset, datap, count); \ 849 } 850 851 #define BHND_IO_METHODS(_type, _size) \ 852 BHND_IO_READ(_type, _size, _size) \ 853 BHND_IO_WRITE(_type, _size, _size) \ 854 \ 855 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 856 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 857 \ 858 BHND_IO_MISC(_type*, read_multi_ ## _size, \ 859 READ_MULTI_ ## _size) \ 860 BHND_IO_MISC(_type*, write_multi_ ## _size, \ 861 WRITE_MULTI_ ## _size) \ 862 \ 863 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \ 864 READ_MULTI_STREAM_ ## _size) \ 865 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \ 866 WRITE_MULTI_STREAM_ ## _size) \ 867 \ 868 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \ 869 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \ 870 \ 871 BHND_IO_MISC(_type*, read_region_ ## _size, \ 872 READ_REGION_ ## _size) \ 873 BHND_IO_MISC(_type*, write_region_ ## _size, \ 874 WRITE_REGION_ ## _size) \ 875 \ 876 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \ 877 READ_REGION_STREAM_ ## _size) \ 878 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \ 879 WRITE_REGION_STREAM_ ## _size) \ 880 881 BHND_IO_METHODS(uint8_t, 1); 882 BHND_IO_METHODS(uint16_t, 2); 883 BHND_IO_METHODS(uint32_t, 4); 884 885 static void 886 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 887 bus_size_t offset, bus_size_t length, int flags) 888 { 889 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 890 flags); 891 } 892 893 static device_method_t bhnd_methods[] = { 894 /* Device interface */ \ 895 DEVMETHOD(device_attach, bhnd_generic_attach), 896 DEVMETHOD(device_detach, bhnd_generic_detach), 897 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 898 DEVMETHOD(device_suspend, bhnd_generic_suspend), 899 DEVMETHOD(device_resume, bhnd_generic_resume), 900 901 /* Bus interface */ 902 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted), 903 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 904 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 905 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 906 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 907 908 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 909 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 910 911 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 912 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 913 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 914 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 915 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 916 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 917 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 918 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 919 920 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 921 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 922 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 923 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 924 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 925 926 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 927 928 /* BHND interface */ 929 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 930 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 931 DEVMETHOD(bhnd_bus_read_board_info, bhnd_bus_generic_read_board_info), 932 933 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 934 935 DEVMETHOD(bhnd_bus_alloc_pmu, bhnd_generic_alloc_pmu), 936 DEVMETHOD(bhnd_bus_release_pmu, bhnd_generic_release_pmu), 937 DEVMETHOD(bhnd_bus_request_clock, bhnd_generic_request_clock), 938 DEVMETHOD(bhnd_bus_enable_clocks, bhnd_generic_enable_clocks), 939 DEVMETHOD(bhnd_bus_request_ext_rsrc, bhnd_generic_request_ext_rsrc), 940 DEVMETHOD(bhnd_bus_release_ext_rsrc, bhnd_generic_release_ext_rsrc), 941 942 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 943 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var), 944 945 /* BHND interface (bus I/O) */ 946 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 947 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 948 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 949 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 950 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 951 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 952 953 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 954 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 955 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 956 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 957 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 958 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 959 960 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 961 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 962 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 963 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 964 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 965 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 966 967 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 968 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 969 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 970 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 971 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 972 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 973 974 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1), 975 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2), 976 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4), 977 978 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1), 979 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2), 980 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4), 981 982 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1), 983 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2), 984 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4), 985 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1), 986 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2), 987 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4), 988 989 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1), 990 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2), 991 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4), 992 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1), 993 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2), 994 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4), 995 996 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 997 998 DEVMETHOD_END 999 }; 1000 1001 devclass_t bhnd_devclass; /**< bhnd bus. */ 1002 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 1003 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 1004 1005 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 1006 MODULE_VERSION(bhnd, 1); 1007