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