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 * $FreeBSD$ 30 */ 31 32 #ifndef _BHND_BHND_H_ 33 #define _BHND_BHND_H_ 34 35 #include <sys/types.h> 36 #include <sys/bus.h> 37 38 #include <machine/bus.h> 39 40 #include "bhnd_ids.h" 41 #include "bhnd_types.h" 42 #include "bhnd_bus_if.h" 43 44 extern devclass_t bhnd_devclass; 45 extern devclass_t bhnd_hostb_devclass; 46 extern devclass_t bhnd_nvram_devclass; 47 48 /** 49 * bhnd child instance variables 50 */ 51 enum bhnd_device_vars { 52 BHND_IVAR_VENDOR, /**< Designer's JEP-106 manufacturer ID. */ 53 BHND_IVAR_DEVICE, /**< Part number */ 54 BHND_IVAR_HWREV, /**< Core revision */ 55 BHND_IVAR_DEVICE_CLASS, /**< Core class (@sa bhnd_devclass_t) */ 56 BHND_IVAR_VENDOR_NAME, /**< Core vendor name */ 57 BHND_IVAR_DEVICE_NAME, /**< Core name */ 58 BHND_IVAR_CORE_INDEX, /**< Bus-assigned core number */ 59 BHND_IVAR_CORE_UNIT, /**< Bus-assigned core unit number, 60 assigned sequentially (starting at 0) for 61 each vendor/device pair. */ 62 }; 63 64 /** 65 * bhnd device probe priority bands. 66 */ 67 enum { 68 BHND_PROBE_ROOT = 0, /**< Nexus or host bridge */ 69 BHND_PROBE_BUS = 1000, /**< Busses and bridges */ 70 BHND_PROBE_CPU = 2000, /**< CPU devices */ 71 BHND_PROBE_INTERRUPT = 3000, /**< Interrupt controllers. */ 72 BHND_PROBE_TIMER = 4000, /**< Timers and clocks. */ 73 BHND_PROBE_RESOURCE = 5000, /**< Resource discovery (including NVRAM/SPROM) */ 74 BHND_PROBE_DEFAULT = 6000, /**< Default device priority */ 75 }; 76 77 /** 78 * Constants defining fine grained ordering within a BHND_PROBE_* priority band. 79 * 80 * Example: 81 * @code 82 * BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST 83 * @endcode 84 */ 85 enum { 86 BHND_PROBE_ORDER_FIRST = 0, 87 BHND_PROBE_ORDER_EARLY = 25, 88 BHND_PROBE_ORDER_MIDDLE = 50, 89 BHND_PROBE_ORDER_LATE = 75, 90 BHND_PROBE_ORDER_LAST = 100 91 92 }; 93 94 /* 95 * Simplified accessors for bhnd device ivars 96 */ 97 #define BHND_ACCESSOR(var, ivar, type) \ 98 __BUS_ACCESSOR(bhnd, var, BHND, ivar, type) 99 100 BHND_ACCESSOR(vendor, VENDOR, uint16_t); 101 BHND_ACCESSOR(device, DEVICE, uint16_t); 102 BHND_ACCESSOR(hwrev, HWREV, uint8_t); 103 BHND_ACCESSOR(class, DEVICE_CLASS, bhnd_devclass_t); 104 BHND_ACCESSOR(vendor_name, VENDOR_NAME, const char *); 105 BHND_ACCESSOR(device_name, DEVICE_NAME, const char *); 106 BHND_ACCESSOR(core_index, CORE_INDEX, u_int); 107 BHND_ACCESSOR(core_unit, CORE_UNIT, int); 108 109 #undef BHND_ACCESSOR 110 111 /** 112 * Chip Identification 113 * 114 * This is read from the ChipCommon ID register; on earlier bhnd(4) devices 115 * where ChipCommon is unavailable, known values must be supplied. 116 */ 117 struct bhnd_chipid { 118 uint16_t chip_id; /**< chip id (BHND_CHIPID_*) */ 119 uint8_t chip_rev; /**< chip revision */ 120 uint8_t chip_pkg; /**< chip package (BHND_PKGID_*) */ 121 uint8_t chip_type; /**< chip type (BHND_CHIPTYPE_*) */ 122 123 bhnd_addr_t enum_addr; /**< chip_type-specific enumeration 124 * address; either the siba(4) base 125 * core register block, or the bcma(4) 126 * EROM core address. */ 127 128 uint8_t ncores; /**< number of cores, if known. 0 if 129 * not available. */ 130 }; 131 132 /** 133 * A bhnd(4) bus resource. 134 * 135 * This provides an abstract interface to per-core resources that may require 136 * bus-level remapping of address windows prior to access. 137 */ 138 struct bhnd_resource { 139 struct resource *res; /**< the system resource. */ 140 bool direct; /**< false if the resource requires 141 * bus window remapping before it 142 * is MMIO accessible. */ 143 }; 144 145 /** 146 * A bhnd(4) core descriptor. 147 */ 148 struct bhnd_core_info { 149 uint16_t vendor; /**< vendor */ 150 uint16_t device; /**< device */ 151 uint16_t hwrev; /**< hardware revision */ 152 u_int core_idx; /**< bus-assigned core index */ 153 int unit; /**< bus-assigned core unit */ 154 }; 155 156 157 /** 158 * A hardware revision match descriptor. 159 */ 160 struct bhnd_hwrev_match { 161 uint16_t start; /**< first revision, or BHND_HWREV_INVALID 162 to match on any revision. */ 163 uint16_t end; /**< last revision, or BHND_HWREV_INVALID 164 to match on any revision. */ 165 }; 166 167 /** 168 * Wildcard hardware revision match descriptor. 169 */ 170 #define BHND_HWREV_ANY { BHND_HWREV_INVALID, BHND_HWREV_INVALID } 171 #define BHND_HWREV_IS_ANY(_m) \ 172 ((_m)->start == BHND_HWREV_INVALID && (_m)->end == BHND_HWREV_INVALID) 173 174 /** 175 * Hardware revision match descriptor for an inclusive range. 176 * 177 * @param _start The first applicable hardware revision. 178 * @param _end The last applicable hardware revision, or BHND_HWREV_INVALID 179 * to match on any revision. 180 */ 181 #define BHND_HWREV_RANGE(_start, _end) { _start, _end } 182 183 /** 184 * Hardware revision match descriptor for a single revision. 185 * 186 * @param _hwrev The hardware revision to match on. 187 */ 188 #define BHND_HWREV_EQ(_hwrev) BHND_HWREV_RANGE(_hwrev, _hwrev) 189 190 /** 191 * Hardware revision match descriptor for any revision equal to or greater 192 * than @p _start. 193 * 194 * @param _start The first hardware revision to match on. 195 */ 196 #define BHND_HWREV_GTE(_start) BHND_HWREV_RANGE(_start, BHND_HWREV_INVALID) 197 198 /** 199 * Hardware revision match descriptor for any revision equal to or less 200 * than @p _end. 201 * 202 * @param _end The last hardware revision to match on. 203 */ 204 #define BHND_HWREV_LTE(_end) BHND_HWREV_RANGE(0, _end) 205 206 207 /** A core match descriptor. */ 208 struct bhnd_core_match { 209 uint16_t vendor; /**< required JEP106 device vendor or BHND_MFGID_INVALID. */ 210 uint16_t device; /**< required core ID or BHND_COREID_INVALID */ 211 struct bhnd_hwrev_match hwrev; /**< matching revisions. */ 212 bhnd_devclass_t class; /**< required class or BHND_DEVCLASS_INVALID */ 213 int unit; /**< required core unit, or -1 */ 214 }; 215 216 /** 217 * Core match descriptor matching against the given @p _vendor, @p _device, 218 * and @p _hwrev match descriptors. 219 */ 220 #define BHND_CORE_MATCH(_vendor, _device, _hwrev) \ 221 { _vendor, _device, _hwrev, BHND_DEVCLASS_INVALID, -1 } 222 223 /** 224 * Wildcard core match descriptor. 225 */ 226 #define BHND_CORE_MATCH_ANY \ 227 { \ 228 .vendor = BHND_MFGID_INVALID, \ 229 .device = BHND_COREID_INVALID, \ 230 .hwrev = BHND_HWREV_ANY, \ 231 .class = BHND_DEVCLASS_INVALID, \ 232 .unit = -1 \ 233 } 234 235 /** A chipset match descriptor. */ 236 struct bhnd_chip_match { 237 /** Select fields to be matched */ 238 uint8_t 239 match_id:1, 240 match_rev:1, 241 match_pkg:1, 242 match_flags_unused:5; 243 244 uint16_t chip_id; /**< required chip id */ 245 struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */ 246 uint8_t chip_pkg; /**< required package */ 247 }; 248 249 #define BHND_CHIP_MATCH_ANY \ 250 { .match_id = 0, .match_rev = 0, .match_pkg = 0 } 251 252 #define BHND_CHIP_MATCH_IS_ANY(_m) \ 253 ((_m)->match_id == 0 && (_m)->match_rev == 0 && (_m)->match_pkg == 0) 254 255 /** Set the required chip ID within a bhnd_chip_match instance */ 256 #define BHND_CHIP_ID(_cid) \ 257 .match_id = 1, .chip_id = BHND_CHIPID_BCM ## _cid 258 259 /** Set the required revision range within a bhnd_chip_match instance */ 260 #define BHND_CHIP_REV(_rev) \ 261 .match_rev = 1, .chip_rev = BHND_ ## _rev 262 263 /** Set the required package ID within a bhnd_chip_match instance */ 264 #define BHND_CHIP_PKG(_pkg) \ 265 .match_pkg = 1, .chip_pkg = BHND_PKGID_BCM ## _pkg 266 267 /** Set the required chip and package ID within a bhnd_chip_match instance */ 268 #define BHND_CHIP_IP(_cid, _pkg) \ 269 BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg) 270 271 /** Set the required chip ID, package ID, and revision within a bhnd_chip_match 272 * instance */ 273 #define BHND_CHIP_IPR(_cid, _pkg, _rev) \ 274 BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev) 275 276 /** Set the required chip ID and revision within a bhnd_chip_match 277 * instance */ 278 #define BHND_CHIP_IR(_cid, _rev) \ 279 BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev) 280 281 /** 282 * Chipset quirk table descriptor. 283 */ 284 struct bhnd_chip_quirk { 285 const struct bhnd_chip_match chip; /**< chip match descriptor */ 286 uint32_t quirks; /**< quirk flags */ 287 }; 288 289 #define BHND_CHIP_QUIRK_END { BHND_CHIP_MATCH_ANY, 0 } 290 291 #define BHND_CHIP_QUIRK_IS_END(_q) \ 292 (BHND_CHIP_MATCH_IS_ANY(&(_q)->chip) && (_q)->quirks == 0) 293 294 /** 295 * Device quirk table descriptor. 296 */ 297 struct bhnd_device_quirk { 298 struct bhnd_hwrev_match hwrev; /**< applicable hardware revisions */ 299 uint32_t quirks; /**< quirk flags */ 300 }; 301 #define BHND_DEVICE_QUIRK_END { BHND_HWREV_ANY, 0 } 302 #define BHND_DEVICE_QUIRK_IS_END(_q) \ 303 (BHND_HWREV_IS_ANY(&(_q)->hwrev) && (_q)->quirks == 0) 304 305 enum { 306 BHND_DF_ANY = 0, 307 BHND_DF_HOSTB = (1<<0) /**< core is serving as the bus' 308 * host bridge */ 309 }; 310 311 /** Device probe table descriptor */ 312 struct bhnd_device { 313 const struct bhnd_core_match core; /**< core match descriptor */ 314 const char *desc; /**< device description, or NULL. */ 315 const struct bhnd_device_quirk *quirks_table; /**< quirks table for this device, or NULL */ 316 uint32_t device_flags; /**< required BHND_DF_* flags */ 317 }; 318 319 #define _BHND_DEVICE(_device, _desc, _quirks, _flags, ...) \ 320 { BHND_CORE_MATCH(BHND_MFGID_BCM, BHND_COREID_ ## _device, \ 321 BHND_HWREV_ANY), _desc, _quirks, _flags } 322 323 #define BHND_DEVICE(_device, _desc, _quirks, ...) \ 324 _BHND_DEVICE(_device, _desc, _quirks, ## __VA_ARGS__, 0) 325 326 #define BHND_DEVICE_END { BHND_CORE_MATCH_ANY, NULL, NULL, 0 } 327 328 const char *bhnd_vendor_name(uint16_t vendor); 329 const char *bhnd_port_type_name(bhnd_port_type port_type); 330 331 const char *bhnd_find_core_name(uint16_t vendor, 332 uint16_t device); 333 bhnd_devclass_t bhnd_find_core_class(uint16_t vendor, 334 uint16_t device); 335 336 const char *bhnd_core_name(const struct bhnd_core_info *ci); 337 bhnd_devclass_t bhnd_core_class(const struct bhnd_core_info *ci); 338 339 340 device_t bhnd_match_child(device_t dev, 341 const struct bhnd_core_match *desc); 342 343 device_t bhnd_find_child(device_t dev, 344 bhnd_devclass_t class, int unit); 345 346 const struct bhnd_core_info *bhnd_match_core( 347 const struct bhnd_core_info *cores, 348 u_int num_cores, 349 const struct bhnd_core_match *desc); 350 351 const struct bhnd_core_info *bhnd_find_core( 352 const struct bhnd_core_info *cores, 353 u_int num_cores, bhnd_devclass_t class); 354 355 bool bhnd_core_matches( 356 const struct bhnd_core_info *core, 357 const struct bhnd_core_match *desc); 358 359 bool bhnd_chip_matches( 360 const struct bhnd_chipid *chipid, 361 const struct bhnd_chip_match *desc); 362 363 bool bhnd_hwrev_matches(uint16_t hwrev, 364 const struct bhnd_hwrev_match *desc); 365 366 uint32_t bhnd_chip_quirks(device_t dev, 367 const struct bhnd_chip_quirk *table); 368 369 bool bhnd_device_matches(device_t dev, 370 const struct bhnd_core_match *desc); 371 372 const struct bhnd_device *bhnd_device_lookup(device_t dev, 373 const struct bhnd_device *table, 374 size_t entry_size); 375 376 uint32_t bhnd_device_quirks(device_t dev, 377 const struct bhnd_device *table, 378 size_t entry_size); 379 380 struct bhnd_core_info bhnd_get_core_info(device_t dev); 381 382 383 int bhnd_alloc_resources(device_t dev, 384 struct resource_spec *rs, 385 struct bhnd_resource **res); 386 387 void bhnd_release_resources(device_t dev, 388 const struct resource_spec *rs, 389 struct bhnd_resource **res); 390 391 struct bhnd_chipid bhnd_parse_chipid(uint32_t idreg, 392 bhnd_addr_t enum_addr); 393 394 int bhnd_read_chipid(device_t dev, 395 struct resource_spec *rs, 396 bus_size_t chipc_offset, 397 struct bhnd_chipid *result); 398 399 void bhnd_set_custom_core_desc(device_t dev, 400 const char *name); 401 void bhnd_set_default_core_desc(device_t dev); 402 403 404 bool bhnd_bus_generic_is_hw_disabled(device_t dev, 405 device_t child); 406 bool bhnd_bus_generic_is_region_valid(device_t dev, 407 device_t child, bhnd_port_type type, 408 u_int port, u_int region); 409 int bhnd_bus_generic_read_nvram_var(device_t dev, 410 device_t child, const char *name, 411 void *buf, size_t *size); 412 const struct bhnd_chipid *bhnd_bus_generic_get_chipid(device_t dev, 413 device_t child); 414 struct bhnd_resource *bhnd_bus_generic_alloc_resource (device_t dev, 415 device_t child, int type, int *rid, 416 rman_res_t start, rman_res_t end, 417 rman_res_t count, u_int flags); 418 int bhnd_bus_generic_release_resource (device_t dev, 419 device_t child, int type, int rid, 420 struct bhnd_resource *r); 421 int bhnd_bus_generic_activate_resource (device_t dev, 422 device_t child, int type, int rid, 423 struct bhnd_resource *r); 424 int bhnd_bus_generic_deactivate_resource (device_t dev, 425 device_t child, int type, int rid, 426 struct bhnd_resource *r); 427 428 429 430 /** 431 * Return the active host bridge core for the bhnd bus, if any, or NULL if 432 * not found. 433 * 434 * @param dev A bhnd bus device. 435 */ 436 static inline device_t 437 bhnd_find_hostb_device(device_t dev) { 438 return (BHND_BUS_FIND_HOSTB_DEVICE(dev)); 439 } 440 441 /** 442 * Return true if the hardware components required by @p dev are known to be 443 * unpopulated or otherwise unusable. 444 * 445 * In some cases, enumerated devices may have pins that are left floating, or 446 * the hardware may otherwise be non-functional; this method allows a parent 447 * device to explicitly specify if a successfully enumerated @p dev should 448 * be disabled. 449 * 450 * @param dev A bhnd bus child device. 451 */ 452 static inline bool 453 bhnd_is_hw_disabled(device_t dev) { 454 return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev)); 455 } 456 457 /** 458 * Return the BHND chip identification info for the bhnd bus. 459 * 460 * @param dev A bhnd bus child device. 461 */ 462 static inline const struct bhnd_chipid * 463 bhnd_get_chipid(device_t dev) { 464 return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev)); 465 }; 466 467 /** 468 * Determine an NVRAM variable's expected size. 469 * 470 * @param dev A bhnd bus child device. 471 * @param name The variable name. 472 * @param[out] len On success, the variable's size, in bytes. 473 * 474 * @retval 0 success 475 * @retval ENOENT The requested variable was not found. 476 * @retval non-zero If reading @p name otherwise fails, a regular unix 477 * error code will be returned. 478 */ 479 static inline int 480 bhnd_nvram_getvarlen(device_t dev, const char *name, size_t *len) 481 { 482 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, NULL, 483 len)); 484 } 485 486 /** 487 * Read an NVRAM variable. 488 * 489 * @param dev A bhnd bus child device. 490 * @param name The NVRAM variable name. 491 * @param buf A buffer large enough to hold @p len bytes. On success, 492 * the requested value will be written to this buffer. 493 * @param len The required variable length. 494 * 495 * @retval 0 success 496 * @retval ENOENT The requested variable was not found. 497 * @retval EINVAL If @p len does not match the actual variable size. 498 * @retval non-zero If reading @p name otherwise fails, a regular unix 499 * error code will be returned. 500 */ 501 static inline int 502 bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t len) 503 { 504 size_t var_len; 505 int error; 506 507 if ((error = bhnd_nvram_getvarlen(dev, name, &var_len))) 508 return (error); 509 510 if (len != var_len) 511 return (EINVAL); 512 513 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf, 514 &len)); 515 } 516 517 /** 518 * Allocate a resource from a device's parent bhnd(4) bus. 519 * 520 * @param dev The device requesting resource ownership. 521 * @param type The type of resource to allocate. This may be any type supported 522 * by the standard bus APIs. 523 * @param rid The bus-specific handle identifying the resource being allocated. 524 * @param start The start address of the resource. 525 * @param end The end address of the resource. 526 * @param count The size of the resource. 527 * @param flags The flags for the resource to be allocated. These may be any 528 * values supported by the standard bus APIs. 529 * 530 * To request the resource's default addresses, pass @p start and 531 * @p end values of @c 0 and @c ~0, respectively, and 532 * a @p count of @c 1. 533 * 534 * @retval NULL The resource could not be allocated. 535 * @retval resource The allocated resource. 536 */ 537 static inline struct bhnd_resource * 538 bhnd_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, 539 rman_res_t end, rman_res_t count, u_int flags) 540 { 541 return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid, 542 start, end, count, flags); 543 } 544 545 546 /** 547 * Allocate a resource from a device's parent bhnd(4) bus, using the 548 * resource's default start, end, and count values. 549 * 550 * @param dev The device requesting resource ownership. 551 * @param type The type of resource to allocate. This may be any type supported 552 * by the standard bus APIs. 553 * @param rid The bus-specific handle identifying the resource being allocated. 554 * @param flags The flags for the resource to be allocated. These may be any 555 * values supported by the standard bus APIs. 556 * 557 * @retval NULL The resource could not be allocated. 558 * @retval resource The allocated resource. 559 */ 560 static inline struct bhnd_resource * 561 bhnd_alloc_resource_any(device_t dev, int type, int *rid, u_int flags) 562 { 563 return bhnd_alloc_resource(dev, type, rid, 0, ~0, 1, flags); 564 } 565 566 /** 567 * Activate a previously allocated bhnd resource. 568 * 569 * @param dev The device holding ownership of the allocated resource. 570 * @param type The type of the resource. 571 * @param rid The bus-specific handle identifying the resource. 572 * @param r A pointer to the resource returned by bhnd_alloc_resource or 573 * BHND_BUS_ALLOC_RESOURCE. 574 * 575 * @retval 0 success 576 * @retval non-zero an error occurred while activating the resource. 577 */ 578 static inline int 579 bhnd_activate_resource(device_t dev, int type, int rid, 580 struct bhnd_resource *r) 581 { 582 return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 583 rid, r); 584 } 585 586 /** 587 * Deactivate a previously activated bhnd resource. 588 * 589 * @param dev The device holding ownership of the activated resource. 590 * @param type The type of the resource. 591 * @param rid The bus-specific handle identifying the resource. 592 * @param r A pointer to the resource returned by bhnd_alloc_resource or 593 * BHND_BUS_ALLOC_RESOURCE. 594 * 595 * @retval 0 success 596 * @retval non-zero an error occurred while activating the resource. 597 */ 598 static inline int 599 bhnd_deactivate_resource(device_t dev, int type, int rid, 600 struct bhnd_resource *r) 601 { 602 return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 603 rid, r); 604 } 605 606 /** 607 * Free a resource allocated by bhnd_alloc_resource(). 608 * 609 * @param dev The device holding ownership of the resource. 610 * @param type The type of the resource. 611 * @param rid The bus-specific handle identifying the resource. 612 * @param r A pointer to the resource returned by bhnd_alloc_resource or 613 * BHND_ALLOC_RESOURCE. 614 * 615 * @retval 0 success 616 * @retval non-zero an error occurred while activating the resource. 617 */ 618 static inline int 619 bhnd_release_resource(device_t dev, int type, int rid, 620 struct bhnd_resource *r) 621 { 622 return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type, 623 rid, r); 624 } 625 626 /** 627 * Return true if @p region_num is a valid region on @p port_num of 628 * @p type attached to @p dev. 629 * 630 * @param dev A bhnd bus child device. 631 * @param type The port type being queried. 632 * @param port_num The port number being queried. 633 * @param region_num The region number being queried. 634 */ 635 static inline bool 636 bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port_num, 637 u_int region_num) 638 { 639 return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type, 640 port_num, region_num)); 641 } 642 643 /** 644 * Return the number of ports of type @p type attached to @p def. 645 * 646 * @param dev A bhnd bus child device. 647 * @param type The port type being queried. 648 */ 649 static inline u_int 650 bhnd_get_port_count(device_t dev, bhnd_port_type type) { 651 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type)); 652 } 653 654 /** 655 * Return the number of memory regions mapped to @p child @p port of 656 * type @p type. 657 * 658 * @param dev A bhnd bus child device. 659 * @param port The port number being queried. 660 * @param type The port type being queried. 661 */ 662 static inline u_int 663 bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) { 664 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type, 665 port)); 666 } 667 668 /** 669 * Return the resource-ID for a memory region on the given device port. 670 * 671 * @param dev A bhnd bus child device. 672 * @param type The port type. 673 * @param port The port identifier. 674 * @param region The identifier of the memory region on @p port. 675 * 676 * @retval int The RID for the given @p port and @p region on @p device. 677 * @retval -1 No such port/region found. 678 */ 679 static inline int 680 bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region) 681 { 682 return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port, 683 region); 684 } 685 686 /** 687 * Decode a port / region pair on @p dev defined by @p rid. 688 * 689 * @param dev A bhnd bus child device. 690 * @param type The resource type. 691 * @param rid The resource identifier. 692 * @param[out] port_type The decoded port type. 693 * @param[out] port The decoded port identifier. 694 * @param[out] region The decoded region identifier. 695 * 696 * @retval 0 success 697 * @retval non-zero No matching port/region found. 698 */ 699 static inline int 700 bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type, 701 u_int *port, u_int *region) 702 { 703 return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid, 704 port_type, port, region); 705 } 706 707 /** 708 * Get the address and size of @p region on @p port. 709 * 710 * @param dev A bhnd bus child device. 711 * @param port_type The port type. 712 * @param port The port identifier. 713 * @param region The identifier of the memory region on @p port. 714 * @param[out] region_addr The region's base address. 715 * @param[out] region_size The region's size. 716 * 717 * @retval 0 success 718 * @retval non-zero No matching port/region found. 719 */ 720 static inline int 721 bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, 722 u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size) 723 { 724 return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type, 725 port, region, region_addr, region_size); 726 } 727 728 /* 729 * bhnd bus-level equivalents of the bus_(read|write|set|barrier|...) 730 * macros (compatible with bhnd_resource). 731 * 732 * Generated with bhnd/tools/bus_macro.sh 733 */ 734 #define bhnd_bus_barrier(r, o, l, f) \ 735 ((r)->direct) ? \ 736 bus_barrier((r)->res, (o), (l), (f)) : \ 737 BHND_BUS_BARRIER( \ 738 device_get_parent(rman_get_device((r)->res)), \ 739 rman_get_device((r)->res), (r), (o), (l), (f)) 740 #define bhnd_bus_read_1(r, o) \ 741 ((r)->direct) ? \ 742 bus_read_1((r)->res, (o)) : \ 743 BHND_BUS_READ_1( \ 744 device_get_parent(rman_get_device((r)->res)), \ 745 rman_get_device((r)->res), (r), (o)) 746 #define bhnd_bus_read_multi_1(r, o, d, c) \ 747 ((r)->direct) ? \ 748 bus_read_multi_1((r)->res, (o), (d), (c)) : \ 749 BHND_BUS_READ_MULTI_1( \ 750 device_get_parent(rman_get_device((r)->res)), \ 751 rman_get_device((r)->res), (r), (o), (d), (c)) 752 #define bhnd_bus_write_1(r, o, v) \ 753 ((r)->direct) ? \ 754 bus_write_1((r)->res, (o), (v)) : \ 755 BHND_BUS_WRITE_1( \ 756 device_get_parent(rman_get_device((r)->res)), \ 757 rman_get_device((r)->res), (r), (o), (v)) 758 #define bhnd_bus_write_multi_1(r, o, d, c) \ 759 ((r)->direct) ? \ 760 bus_write_multi_1((r)->res, (o), (d), (c)) : \ 761 BHND_BUS_WRITE_MULTI_1( \ 762 device_get_parent(rman_get_device((r)->res)), \ 763 rman_get_device((r)->res), (r), (o), (d), (c)) 764 #define bhnd_bus_read_stream_1(r, o) \ 765 ((r)->direct) ? \ 766 bus_read_stream_1((r)->res, (o)) : \ 767 BHND_BUS_READ_STREAM_1( \ 768 device_get_parent(rman_get_device((r)->res)), \ 769 rman_get_device((r)->res), (r), (o)) 770 #define bhnd_bus_read_multi_stream_1(r, o, d, c) \ 771 ((r)->direct) ? \ 772 bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \ 773 BHND_BUS_READ_MULTI_STREAM_1( \ 774 device_get_parent(rman_get_device((r)->res)), \ 775 rman_get_device((r)->res), (r), (o), (d), (c)) 776 #define bhnd_bus_write_stream_1(r, o, v) \ 777 ((r)->direct) ? \ 778 bus_write_stream_1((r)->res, (o), (v)) : \ 779 BHND_BUS_WRITE_STREAM_1( \ 780 device_get_parent(rman_get_device((r)->res)), \ 781 rman_get_device((r)->res), (r), (o), (v)) 782 #define bhnd_bus_write_multi_stream_1(r, o, d, c) \ 783 ((r)->direct) ? \ 784 bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \ 785 BHND_BUS_WRITE_MULTI_STREAM_1( \ 786 device_get_parent(rman_get_device((r)->res)), \ 787 rman_get_device((r)->res), (r), (o), (d), (c)) 788 #define bhnd_bus_read_2(r, o) \ 789 ((r)->direct) ? \ 790 bus_read_2((r)->res, (o)) : \ 791 BHND_BUS_READ_2( \ 792 device_get_parent(rman_get_device((r)->res)), \ 793 rman_get_device((r)->res), (r), (o)) 794 #define bhnd_bus_read_multi_2(r, o, d, c) \ 795 ((r)->direct) ? \ 796 bus_read_multi_2((r)->res, (o), (d), (c)) : \ 797 BHND_BUS_READ_MULTI_2( \ 798 device_get_parent(rman_get_device((r)->res)), \ 799 rman_get_device((r)->res), (r), (o), (d), (c)) 800 #define bhnd_bus_write_2(r, o, v) \ 801 ((r)->direct) ? \ 802 bus_write_2((r)->res, (o), (v)) : \ 803 BHND_BUS_WRITE_2( \ 804 device_get_parent(rman_get_device((r)->res)), \ 805 rman_get_device((r)->res), (r), (o), (v)) 806 #define bhnd_bus_write_multi_2(r, o, d, c) \ 807 ((r)->direct) ? \ 808 bus_write_multi_2((r)->res, (o), (d), (c)) : \ 809 BHND_BUS_WRITE_MULTI_2( \ 810 device_get_parent(rman_get_device((r)->res)), \ 811 rman_get_device((r)->res), (r), (o), (d), (c)) 812 #define bhnd_bus_read_stream_2(r, o) \ 813 ((r)->direct) ? \ 814 bus_read_stream_2((r)->res, (o)) : \ 815 BHND_BUS_READ_STREAM_2( \ 816 device_get_parent(rman_get_device((r)->res)), \ 817 rman_get_device((r)->res), (r), (o)) 818 #define bhnd_bus_read_multi_stream_2(r, o, d, c) \ 819 ((r)->direct) ? \ 820 bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \ 821 BHND_BUS_READ_MULTI_STREAM_2( \ 822 device_get_parent(rman_get_device((r)->res)), \ 823 rman_get_device((r)->res), (r), (o), (d), (c)) 824 #define bhnd_bus_write_stream_2(r, o, v) \ 825 ((r)->direct) ? \ 826 bus_write_stream_2((r)->res, (o), (v)) : \ 827 BHND_BUS_WRITE_STREAM_2( \ 828 device_get_parent(rman_get_device((r)->res)), \ 829 rman_get_device((r)->res), (r), (o), (v)) 830 #define bhnd_bus_write_multi_stream_2(r, o, d, c) \ 831 ((r)->direct) ? \ 832 bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \ 833 BHND_BUS_WRITE_MULTI_STREAM_2( \ 834 device_get_parent(rman_get_device((r)->res)), \ 835 rman_get_device((r)->res), (r), (o), (d), (c)) 836 #define bhnd_bus_read_4(r, o) \ 837 ((r)->direct) ? \ 838 bus_read_4((r)->res, (o)) : \ 839 BHND_BUS_READ_4( \ 840 device_get_parent(rman_get_device((r)->res)), \ 841 rman_get_device((r)->res), (r), (o)) 842 #define bhnd_bus_read_multi_4(r, o, d, c) \ 843 ((r)->direct) ? \ 844 bus_read_multi_4((r)->res, (o), (d), (c)) : \ 845 BHND_BUS_READ_MULTI_4( \ 846 device_get_parent(rman_get_device((r)->res)), \ 847 rman_get_device((r)->res), (r), (o), (d), (c)) 848 #define bhnd_bus_write_4(r, o, v) \ 849 ((r)->direct) ? \ 850 bus_write_4((r)->res, (o), (v)) : \ 851 BHND_BUS_WRITE_4( \ 852 device_get_parent(rman_get_device((r)->res)), \ 853 rman_get_device((r)->res), (r), (o), (v)) 854 #define bhnd_bus_write_multi_4(r, o, d, c) \ 855 ((r)->direct) ? \ 856 bus_write_multi_4((r)->res, (o), (d), (c)) : \ 857 BHND_BUS_WRITE_MULTI_4( \ 858 device_get_parent(rman_get_device((r)->res)), \ 859 rman_get_device((r)->res), (r), (o), (d), (c)) 860 #define bhnd_bus_read_stream_4(r, o) \ 861 ((r)->direct) ? \ 862 bus_read_stream_4((r)->res, (o)) : \ 863 BHND_BUS_READ_STREAM_4( \ 864 device_get_parent(rman_get_device((r)->res)), \ 865 rman_get_device((r)->res), (r), (o)) 866 #define bhnd_bus_read_multi_stream_4(r, o, d, c) \ 867 ((r)->direct) ? \ 868 bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \ 869 BHND_BUS_READ_MULTI_STREAM_4( \ 870 device_get_parent(rman_get_device((r)->res)), \ 871 rman_get_device((r)->res), (r), (o), (d), (c)) 872 #define bhnd_bus_write_stream_4(r, o, v) \ 873 ((r)->direct) ? \ 874 bus_write_stream_4((r)->res, (o), (v)) : \ 875 BHND_BUS_WRITE_STREAM_4( \ 876 device_get_parent(rman_get_device((r)->res)), \ 877 rman_get_device((r)->res), (r), (o), (v)) 878 #define bhnd_bus_write_multi_stream_4(r, o, d, c) \ 879 ((r)->direct) ? \ 880 bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \ 881 BHND_BUS_WRITE_MULTI_STREAM_4( \ 882 device_get_parent(rman_get_device((r)->res)), \ 883 rman_get_device((r)->res), (r), (o), (d), (c)) 884 885 #endif /* _BHND_BHND_H_ */ 886