bhnd.h revision 299989
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 299989 2016-05-16 23:37:18Z 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_bus_if.h" 43 44extern devclass_t bhnd_devclass; 45extern devclass_t bhnd_hostb_devclass; 46extern devclass_t bhnd_nvram_devclass; 47 48/** 49 * bhnd child instance variables 50 */ 51enum 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 */ 67enum { 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 */ 85enum { 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 100BHND_ACCESSOR(vendor, VENDOR, uint16_t); 101BHND_ACCESSOR(device, DEVICE, uint16_t); 102BHND_ACCESSOR(hwrev, HWREV, uint8_t); 103BHND_ACCESSOR(class, DEVICE_CLASS, bhnd_devclass_t); 104BHND_ACCESSOR(vendor_name, VENDOR_NAME, const char *); 105BHND_ACCESSOR(device_name, DEVICE_NAME, const char *); 106BHND_ACCESSOR(core_index, CORE_INDEX, u_int); 107BHND_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 */ 117struct 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*/ 138struct 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 */ 148struct 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 */ 160struct 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. */ 208struct 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. */ 236struct 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 */ 284struct 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 */ 297struct 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 305enum { 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 */ 312struct 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(_vendor, _device, _desc, _quirks, _flags, ...) \ 320 { BHND_CORE_MATCH(BHND_MFGID_ ## _vendor, BHND_COREID_ ## _device, \ 321 BHND_HWREV_ANY), _desc, _quirks, _flags } 322 323#define BHND_MIPS_DEVICE(_device, _desc, _quirks, ...) \ 324 _BHND_DEVICE(MIPS, _device, _desc, _quirks, ## __VA_ARGS__, 0) 325 326#define BHND_ARM_DEVICE(_device, _desc, _quirks, ...) \ 327 _BHND_DEVICE(ARM, _device, _desc, _quirks, ## __VA_ARGS__, 0) 328 329#define BHND_DEVICE(_device, _desc, _quirks, ...) \ 330 _BHND_DEVICE(BCM, _device, _desc, _quirks, ## __VA_ARGS__, 0) 331 332#define BHND_DEVICE_END { BHND_CORE_MATCH_ANY, NULL, NULL, 0 } 333 334const char *bhnd_vendor_name(uint16_t vendor); 335const char *bhnd_port_type_name(bhnd_port_type port_type); 336 337const char *bhnd_find_core_name(uint16_t vendor, 338 uint16_t device); 339bhnd_devclass_t bhnd_find_core_class(uint16_t vendor, 340 uint16_t device); 341 342const char *bhnd_core_name(const struct bhnd_core_info *ci); 343bhnd_devclass_t bhnd_core_class(const struct bhnd_core_info *ci); 344 345 346device_t bhnd_match_child(device_t dev, 347 const struct bhnd_core_match *desc); 348 349device_t bhnd_find_child(device_t dev, 350 bhnd_devclass_t class, int unit); 351 352const struct bhnd_core_info *bhnd_match_core( 353 const struct bhnd_core_info *cores, 354 u_int num_cores, 355 const struct bhnd_core_match *desc); 356 357const struct bhnd_core_info *bhnd_find_core( 358 const struct bhnd_core_info *cores, 359 u_int num_cores, bhnd_devclass_t class); 360 361bool bhnd_core_matches( 362 const struct bhnd_core_info *core, 363 const struct bhnd_core_match *desc); 364 365bool bhnd_chip_matches( 366 const struct bhnd_chipid *chipid, 367 const struct bhnd_chip_match *desc); 368 369bool bhnd_hwrev_matches(uint16_t hwrev, 370 const struct bhnd_hwrev_match *desc); 371 372uint32_t bhnd_chip_quirks(device_t dev, 373 const struct bhnd_chip_quirk *table); 374 375bool bhnd_device_matches(device_t dev, 376 const struct bhnd_core_match *desc); 377 378const struct bhnd_device *bhnd_device_lookup(device_t dev, 379 const struct bhnd_device *table, 380 size_t entry_size); 381 382uint32_t bhnd_device_quirks(device_t dev, 383 const struct bhnd_device *table, 384 size_t entry_size); 385 386struct bhnd_core_info bhnd_get_core_info(device_t dev); 387 388 389int bhnd_alloc_resources(device_t dev, 390 struct resource_spec *rs, 391 struct bhnd_resource **res); 392 393void bhnd_release_resources(device_t dev, 394 const struct resource_spec *rs, 395 struct bhnd_resource **res); 396 397struct bhnd_chipid bhnd_parse_chipid(uint32_t idreg, 398 bhnd_addr_t enum_addr); 399 400int bhnd_read_chipid(device_t dev, 401 struct resource_spec *rs, 402 bus_size_t chipc_offset, 403 struct bhnd_chipid *result); 404 405void bhnd_set_custom_core_desc(device_t dev, 406 const char *name); 407void bhnd_set_default_core_desc(device_t dev); 408 409 410bool bhnd_bus_generic_is_hw_disabled(device_t dev, 411 device_t child); 412bool bhnd_bus_generic_is_region_valid(device_t dev, 413 device_t child, bhnd_port_type type, 414 u_int port, u_int region); 415int bhnd_bus_generic_read_nvram_var(device_t dev, 416 device_t child, const char *name, 417 void *buf, size_t *size); 418const struct bhnd_chipid *bhnd_bus_generic_get_chipid(device_t dev, 419 device_t child); 420struct bhnd_resource *bhnd_bus_generic_alloc_resource (device_t dev, 421 device_t child, int type, int *rid, 422 rman_res_t start, rman_res_t end, 423 rman_res_t count, u_int flags); 424int bhnd_bus_generic_release_resource (device_t dev, 425 device_t child, int type, int rid, 426 struct bhnd_resource *r); 427int bhnd_bus_generic_activate_resource (device_t dev, 428 device_t child, int type, int rid, 429 struct bhnd_resource *r); 430int bhnd_bus_generic_deactivate_resource (device_t dev, 431 device_t child, int type, int rid, 432 struct bhnd_resource *r); 433 434 435 436/** 437 * Return the active host bridge core for the bhnd bus, if any, or NULL if 438 * not found. 439 * 440 * @param dev A bhnd bus device. 441 */ 442static inline device_t 443bhnd_find_hostb_device(device_t dev) { 444 return (BHND_BUS_FIND_HOSTB_DEVICE(dev)); 445} 446 447/** 448 * Return true if the hardware components required by @p dev are known to be 449 * unpopulated or otherwise unusable. 450 * 451 * In some cases, enumerated devices may have pins that are left floating, or 452 * the hardware may otherwise be non-functional; this method allows a parent 453 * device to explicitly specify if a successfully enumerated @p dev should 454 * be disabled. 455 * 456 * @param dev A bhnd bus child device. 457 */ 458static inline bool 459bhnd_is_hw_disabled(device_t dev) { 460 return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev)); 461} 462 463/** 464 * Return the BHND chip identification info for the bhnd bus. 465 * 466 * @param dev A bhnd bus child device. 467 */ 468static inline const struct bhnd_chipid * 469bhnd_get_chipid(device_t dev) { 470 return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev)); 471}; 472 473/** 474 * Determine an NVRAM variable's expected size. 475 * 476 * @param dev A bhnd bus child device. 477 * @param name The variable name. 478 * @param[out] len On success, the variable's size, in bytes. 479 * 480 * @retval 0 success 481 * @retval ENOENT The requested variable was not found. 482 * @retval non-zero If reading @p name otherwise fails, a regular unix 483 * error code will be returned. 484 */ 485static inline int 486bhnd_nvram_getvarlen(device_t dev, const char *name, size_t *len) 487{ 488 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, NULL, 489 len)); 490} 491 492/** 493 * Read an NVRAM variable. 494 * 495 * @param dev A bhnd bus child device. 496 * @param name The NVRAM variable name. 497 * @param buf A buffer large enough to hold @p len bytes. On success, 498 * the requested value will be written to this buffer. 499 * @param len The required variable length. 500 * 501 * @retval 0 success 502 * @retval ENOENT The requested variable was not found. 503 * @retval EINVAL If @p len does not match the actual variable size. 504 * @retval non-zero If reading @p name otherwise fails, a regular unix 505 * error code will be returned. 506 */ 507static inline int 508bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t len) 509{ 510 size_t var_len; 511 int error; 512 513 if ((error = bhnd_nvram_getvarlen(dev, name, &var_len))) 514 return (error); 515 516 if (len != var_len) 517 return (EINVAL); 518 519 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf, 520 &len)); 521} 522 523/** 524 * Allocate a resource from a device's parent bhnd(4) bus. 525 * 526 * @param dev The device requesting resource ownership. 527 * @param type The type of resource to allocate. This may be any type supported 528 * by the standard bus APIs. 529 * @param rid The bus-specific handle identifying the resource being allocated. 530 * @param start The start address of the resource. 531 * @param end The end address of the resource. 532 * @param count The size of the resource. 533 * @param flags The flags for the resource to be allocated. These may be any 534 * values supported by the standard bus APIs. 535 * 536 * To request the resource's default addresses, pass @p start and 537 * @p end values of @c 0 and @c ~0, respectively, and 538 * a @p count of @c 1. 539 * 540 * @retval NULL The resource could not be allocated. 541 * @retval resource The allocated resource. 542 */ 543static inline struct bhnd_resource * 544bhnd_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, 545 rman_res_t end, rman_res_t count, u_int flags) 546{ 547 return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid, 548 start, end, count, flags); 549} 550 551 552/** 553 * Allocate a resource from a device's parent bhnd(4) bus, using the 554 * resource's default start, end, and count values. 555 * 556 * @param dev The device requesting resource ownership. 557 * @param type The type of resource to allocate. This may be any type supported 558 * by the standard bus APIs. 559 * @param rid The bus-specific handle identifying the resource being allocated. 560 * @param flags The flags for the resource to be allocated. These may be any 561 * values supported by the standard bus APIs. 562 * 563 * @retval NULL The resource could not be allocated. 564 * @retval resource The allocated resource. 565 */ 566static inline struct bhnd_resource * 567bhnd_alloc_resource_any(device_t dev, int type, int *rid, u_int flags) 568{ 569 return bhnd_alloc_resource(dev, type, rid, 0, ~0, 1, flags); 570} 571 572/** 573 * Activate a previously allocated bhnd resource. 574 * 575 * @param dev The device holding ownership of the allocated resource. 576 * @param type The type of the resource. 577 * @param rid The bus-specific handle identifying the resource. 578 * @param r A pointer to the resource returned by bhnd_alloc_resource or 579 * BHND_BUS_ALLOC_RESOURCE. 580 * 581 * @retval 0 success 582 * @retval non-zero an error occurred while activating the resource. 583 */ 584static inline int 585bhnd_activate_resource(device_t dev, int type, int rid, 586 struct bhnd_resource *r) 587{ 588 return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 589 rid, r); 590} 591 592/** 593 * Deactivate a previously activated bhnd resource. 594 * 595 * @param dev The device holding ownership of the activated resource. 596 * @param type The type of the resource. 597 * @param rid The bus-specific handle identifying the resource. 598 * @param r A pointer to the resource returned by bhnd_alloc_resource or 599 * BHND_BUS_ALLOC_RESOURCE. 600 * 601 * @retval 0 success 602 * @retval non-zero an error occurred while activating the resource. 603 */ 604static inline int 605bhnd_deactivate_resource(device_t dev, int type, int rid, 606 struct bhnd_resource *r) 607{ 608 return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 609 rid, r); 610} 611 612/** 613 * Free a resource allocated by bhnd_alloc_resource(). 614 * 615 * @param dev The device holding ownership of the resource. 616 * @param type The type of the resource. 617 * @param rid The bus-specific handle identifying the resource. 618 * @param r A pointer to the resource returned by bhnd_alloc_resource or 619 * BHND_ALLOC_RESOURCE. 620 * 621 * @retval 0 success 622 * @retval non-zero an error occurred while activating the resource. 623 */ 624static inline int 625bhnd_release_resource(device_t dev, int type, int rid, 626 struct bhnd_resource *r) 627{ 628 return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type, 629 rid, r); 630} 631 632/** 633 * Return true if @p region_num is a valid region on @p port_num of 634 * @p type attached to @p dev. 635 * 636 * @param dev A bhnd bus child device. 637 * @param type The port type being queried. 638 * @param port_num The port number being queried. 639 * @param region_num The region number being queried. 640 */ 641static inline bool 642bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port_num, 643 u_int region_num) 644{ 645 return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type, 646 port_num, region_num)); 647} 648 649/** 650 * Return the number of ports of type @p type attached to @p def. 651 * 652 * @param dev A bhnd bus child device. 653 * @param type The port type being queried. 654 */ 655static inline u_int 656bhnd_get_port_count(device_t dev, bhnd_port_type type) { 657 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type)); 658} 659 660/** 661 * Return the number of memory regions mapped to @p child @p port of 662 * type @p type. 663 * 664 * @param dev A bhnd bus child device. 665 * @param port The port number being queried. 666 * @param type The port type being queried. 667 */ 668static inline u_int 669bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) { 670 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type, 671 port)); 672} 673 674/** 675 * Return the resource-ID for a memory region on the given device port. 676 * 677 * @param dev A bhnd bus child device. 678 * @param type The port type. 679 * @param port The port identifier. 680 * @param region The identifier of the memory region on @p port. 681 * 682 * @retval int The RID for the given @p port and @p region on @p device. 683 * @retval -1 No such port/region found. 684 */ 685static inline int 686bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region) 687{ 688 return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port, 689 region); 690} 691 692/** 693 * Decode a port / region pair on @p dev defined by @p rid. 694 * 695 * @param dev A bhnd bus child device. 696 * @param type The resource type. 697 * @param rid The resource identifier. 698 * @param[out] port_type The decoded port type. 699 * @param[out] port The decoded port identifier. 700 * @param[out] region The decoded region identifier. 701 * 702 * @retval 0 success 703 * @retval non-zero No matching port/region found. 704 */ 705static inline int 706bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type, 707 u_int *port, u_int *region) 708{ 709 return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid, 710 port_type, port, region); 711} 712 713/** 714 * Get the address and size of @p region on @p port. 715 * 716 * @param dev A bhnd bus child device. 717 * @param port_type The port type. 718 * @param port The port identifier. 719 * @param region The identifier of the memory region on @p port. 720 * @param[out] region_addr The region's base address. 721 * @param[out] region_size The region's size. 722 * 723 * @retval 0 success 724 * @retval non-zero No matching port/region found. 725 */ 726static inline int 727bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, 728 u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size) 729{ 730 return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type, 731 port, region, region_addr, region_size); 732} 733 734/* 735 * bhnd bus-level equivalents of the bus_(read|write|set|barrier|...) 736 * macros (compatible with bhnd_resource). 737 * 738 * Generated with bhnd/tools/bus_macro.sh 739 */ 740#define bhnd_bus_barrier(r, o, l, f) \ 741 ((r)->direct) ? \ 742 bus_barrier((r)->res, (o), (l), (f)) : \ 743 BHND_BUS_BARRIER( \ 744 device_get_parent(rman_get_device((r)->res)), \ 745 rman_get_device((r)->res), (r), (o), (l), (f)) 746#define bhnd_bus_read_1(r, o) \ 747 ((r)->direct) ? \ 748 bus_read_1((r)->res, (o)) : \ 749 BHND_BUS_READ_1( \ 750 device_get_parent(rman_get_device((r)->res)), \ 751 rman_get_device((r)->res), (r), (o)) 752#define bhnd_bus_read_multi_1(r, o, d, c) \ 753 ((r)->direct) ? \ 754 bus_read_multi_1((r)->res, (o), (d), (c)) : \ 755 BHND_BUS_READ_MULTI_1( \ 756 device_get_parent(rman_get_device((r)->res)), \ 757 rman_get_device((r)->res), (r), (o), (d), (c)) 758#define bhnd_bus_write_1(r, o, v) \ 759 ((r)->direct) ? \ 760 bus_write_1((r)->res, (o), (v)) : \ 761 BHND_BUS_WRITE_1( \ 762 device_get_parent(rman_get_device((r)->res)), \ 763 rman_get_device((r)->res), (r), (o), (v)) 764#define bhnd_bus_write_multi_1(r, o, d, c) \ 765 ((r)->direct) ? \ 766 bus_write_multi_1((r)->res, (o), (d), (c)) : \ 767 BHND_BUS_WRITE_MULTI_1( \ 768 device_get_parent(rman_get_device((r)->res)), \ 769 rman_get_device((r)->res), (r), (o), (d), (c)) 770#define bhnd_bus_read_stream_1(r, o) \ 771 ((r)->direct) ? \ 772 bus_read_stream_1((r)->res, (o)) : \ 773 BHND_BUS_READ_STREAM_1( \ 774 device_get_parent(rman_get_device((r)->res)), \ 775 rman_get_device((r)->res), (r), (o)) 776#define bhnd_bus_read_multi_stream_1(r, o, d, c) \ 777 ((r)->direct) ? \ 778 bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \ 779 BHND_BUS_READ_MULTI_STREAM_1( \ 780 device_get_parent(rman_get_device((r)->res)), \ 781 rman_get_device((r)->res), (r), (o), (d), (c)) 782#define bhnd_bus_write_stream_1(r, o, v) \ 783 ((r)->direct) ? \ 784 bus_write_stream_1((r)->res, (o), (v)) : \ 785 BHND_BUS_WRITE_STREAM_1( \ 786 device_get_parent(rman_get_device((r)->res)), \ 787 rman_get_device((r)->res), (r), (o), (v)) 788#define bhnd_bus_write_multi_stream_1(r, o, d, c) \ 789 ((r)->direct) ? \ 790 bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \ 791 BHND_BUS_WRITE_MULTI_STREAM_1( \ 792 device_get_parent(rman_get_device((r)->res)), \ 793 rman_get_device((r)->res), (r), (o), (d), (c)) 794#define bhnd_bus_read_2(r, o) \ 795 ((r)->direct) ? \ 796 bus_read_2((r)->res, (o)) : \ 797 BHND_BUS_READ_2( \ 798 device_get_parent(rman_get_device((r)->res)), \ 799 rman_get_device((r)->res), (r), (o)) 800#define bhnd_bus_read_multi_2(r, o, d, c) \ 801 ((r)->direct) ? \ 802 bus_read_multi_2((r)->res, (o), (d), (c)) : \ 803 BHND_BUS_READ_MULTI_2( \ 804 device_get_parent(rman_get_device((r)->res)), \ 805 rman_get_device((r)->res), (r), (o), (d), (c)) 806#define bhnd_bus_write_2(r, o, v) \ 807 ((r)->direct) ? \ 808 bus_write_2((r)->res, (o), (v)) : \ 809 BHND_BUS_WRITE_2( \ 810 device_get_parent(rman_get_device((r)->res)), \ 811 rman_get_device((r)->res), (r), (o), (v)) 812#define bhnd_bus_write_multi_2(r, o, d, c) \ 813 ((r)->direct) ? \ 814 bus_write_multi_2((r)->res, (o), (d), (c)) : \ 815 BHND_BUS_WRITE_MULTI_2( \ 816 device_get_parent(rman_get_device((r)->res)), \ 817 rman_get_device((r)->res), (r), (o), (d), (c)) 818#define bhnd_bus_read_stream_2(r, o) \ 819 ((r)->direct) ? \ 820 bus_read_stream_2((r)->res, (o)) : \ 821 BHND_BUS_READ_STREAM_2( \ 822 device_get_parent(rman_get_device((r)->res)), \ 823 rman_get_device((r)->res), (r), (o)) 824#define bhnd_bus_read_multi_stream_2(r, o, d, c) \ 825 ((r)->direct) ? \ 826 bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \ 827 BHND_BUS_READ_MULTI_STREAM_2( \ 828 device_get_parent(rman_get_device((r)->res)), \ 829 rman_get_device((r)->res), (r), (o), (d), (c)) 830#define bhnd_bus_write_stream_2(r, o, v) \ 831 ((r)->direct) ? \ 832 bus_write_stream_2((r)->res, (o), (v)) : \ 833 BHND_BUS_WRITE_STREAM_2( \ 834 device_get_parent(rman_get_device((r)->res)), \ 835 rman_get_device((r)->res), (r), (o), (v)) 836#define bhnd_bus_write_multi_stream_2(r, o, d, c) \ 837 ((r)->direct) ? \ 838 bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \ 839 BHND_BUS_WRITE_MULTI_STREAM_2( \ 840 device_get_parent(rman_get_device((r)->res)), \ 841 rman_get_device((r)->res), (r), (o), (d), (c)) 842#define bhnd_bus_read_4(r, o) \ 843 ((r)->direct) ? \ 844 bus_read_4((r)->res, (o)) : \ 845 BHND_BUS_READ_4( \ 846 device_get_parent(rman_get_device((r)->res)), \ 847 rman_get_device((r)->res), (r), (o)) 848#define bhnd_bus_read_multi_4(r, o, d, c) \ 849 ((r)->direct) ? \ 850 bus_read_multi_4((r)->res, (o), (d), (c)) : \ 851 BHND_BUS_READ_MULTI_4( \ 852 device_get_parent(rman_get_device((r)->res)), \ 853 rman_get_device((r)->res), (r), (o), (d), (c)) 854#define bhnd_bus_write_4(r, o, v) \ 855 ((r)->direct) ? \ 856 bus_write_4((r)->res, (o), (v)) : \ 857 BHND_BUS_WRITE_4( \ 858 device_get_parent(rman_get_device((r)->res)), \ 859 rman_get_device((r)->res), (r), (o), (v)) 860#define bhnd_bus_write_multi_4(r, o, d, c) \ 861 ((r)->direct) ? \ 862 bus_write_multi_4((r)->res, (o), (d), (c)) : \ 863 BHND_BUS_WRITE_MULTI_4( \ 864 device_get_parent(rman_get_device((r)->res)), \ 865 rman_get_device((r)->res), (r), (o), (d), (c)) 866#define bhnd_bus_read_stream_4(r, o) \ 867 ((r)->direct) ? \ 868 bus_read_stream_4((r)->res, (o)) : \ 869 BHND_BUS_READ_STREAM_4( \ 870 device_get_parent(rman_get_device((r)->res)), \ 871 rman_get_device((r)->res), (r), (o)) 872#define bhnd_bus_read_multi_stream_4(r, o, d, c) \ 873 ((r)->direct) ? \ 874 bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \ 875 BHND_BUS_READ_MULTI_STREAM_4( \ 876 device_get_parent(rman_get_device((r)->res)), \ 877 rman_get_device((r)->res), (r), (o), (d), (c)) 878#define bhnd_bus_write_stream_4(r, o, v) \ 879 ((r)->direct) ? \ 880 bus_write_stream_4((r)->res, (o), (v)) : \ 881 BHND_BUS_WRITE_STREAM_4( \ 882 device_get_parent(rman_get_device((r)->res)), \ 883 rman_get_device((r)->res), (r), (o), (v)) 884#define bhnd_bus_write_multi_stream_4(r, o, d, c) \ 885 ((r)->direct) ? \ 886 bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \ 887 BHND_BUS_WRITE_MULTI_STREAM_4( \ 888 device_get_parent(rman_get_device((r)->res)), \ 889 rman_get_device((r)->res), (r), (o), (d), (c)) 890 891#endif /* _BHND_BHND_H_ */ 892