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_MATCH_ANY { BHND_HWREV_INVALID, BHND_HWREV_INVALID } 171 172 173 /** A core match descriptor. */ 174 struct bhnd_core_match { 175 uint16_t vendor; /**< required JEP106 device vendor or BHND_MFGID_INVALID. */ 176 uint16_t device; /**< required core ID or BHND_COREID_INVALID */ 177 struct bhnd_hwrev_match hwrev; /**< matching revisions. */ 178 bhnd_devclass_t class; /**< required class or BHND_DEVCLASS_INVALID */ 179 int unit; /**< required core unit, or -1 */ 180 }; 181 182 183 /** 184 * Revision-specific hardware quirk descriptor. 185 * 186 * Defines a set of quirk flags applicable to a range of hardware 187 * revisions. 188 */ 189 struct bhnd_device_quirk { 190 struct bhnd_hwrev_match hwrev; /**< applicable hardware revisions */ 191 uint32_t quirks; /**< applicable quirk flags */ 192 }; 193 194 /** 195 * Define a bhnd_device_quirk over a range of hardware revisions. 196 * 197 * @param _start The first applicable hardware revision. 198 * @param _end The last applicable hardware revision, or BHND_HWREV_INVALID 199 * to match on any revision. 200 * @param _quirks Quirk flags applicable to this revision range. 201 */ 202 #define BHND_QUIRK_HWREV_RANGE(_start, _end, _quirks) \ 203 { .hwrev = { _start, _end }, .quirks = _quirks } 204 205 /** 206 * Define a bhnd_device_quirk for a specific hardware revision. 207 * 208 * @param _hwrev The hardware revision to match on. 209 * @param _quirks Quirk flags applicable to this revision. 210 */ 211 #define BHND_QUIRK_HWREV_EQ(_hwrev, _quirks) \ 212 BHND_QUIRK_HWREV_RANGE(_hwrev, _hwrev, _quirks) 213 214 /** 215 * Define a bhnd_device_quirk for any hardware revision equal or greater 216 * than @p _start. 217 * 218 * @param _start The first hardware revision to match on. 219 * @param _quirks Quirk flags applicable to this revision. 220 */ 221 #define BHND_QUIRK_HWREV_GTE(_start, _quirks) \ 222 BHND_QUIRK_HWREV_RANGE(_start, BHND_HWREV_INVALID, _quirks) 223 224 /** 225 * Define a bhnd_device_quirk for any hardware revision equal or less 226 * than @p _end. 227 * 228 * @param _end The last hardware revision to match on. 229 * @param _quirks Quirk flags applicable to this revision. 230 */ 231 #define BHND_QUIRK_HWREV_LTE(_end, _quirks) \ 232 BHND_QUIRK_HWREV_RANGE(0, _end, _quirks) 233 234 /** Mark the end of a bhnd_device_quirk table. */ 235 #define BHND_QUIRK_HWREV_END { BHND_HWREV_MATCH_ANY, 0 } 236 237 const char *bhnd_vendor_name(uint16_t vendor); 238 const char *bhnd_port_type_name(bhnd_port_type port_type); 239 240 const char *bhnd_find_core_name(uint16_t vendor, 241 uint16_t device); 242 bhnd_devclass_t bhnd_find_core_class(uint16_t vendor, 243 uint16_t device); 244 245 const char *bhnd_core_name(const struct bhnd_core_info *ci); 246 bhnd_devclass_t bhnd_core_class(const struct bhnd_core_info *ci); 247 248 249 device_t bhnd_match_child(device_t dev, 250 const struct bhnd_core_match *desc); 251 252 device_t bhnd_find_child(device_t dev, 253 bhnd_devclass_t class, int unit); 254 255 const struct bhnd_core_info *bhnd_match_core( 256 const struct bhnd_core_info *cores, 257 u_int num_cores, 258 const struct bhnd_core_match *desc); 259 260 const struct bhnd_core_info *bhnd_find_core( 261 const struct bhnd_core_info *cores, 262 u_int num_cores, bhnd_devclass_t class); 263 264 bool bhnd_core_matches( 265 const struct bhnd_core_info *core, 266 const struct bhnd_core_match *desc); 267 268 bool bhnd_hwrev_matches(uint16_t hwrev, 269 const struct bhnd_hwrev_match *desc); 270 271 bool bhnd_device_matches(device_t dev, 272 const struct bhnd_core_match *desc); 273 274 struct bhnd_core_info bhnd_get_core_info(device_t dev); 275 276 277 int bhnd_alloc_resources(device_t dev, 278 struct resource_spec *rs, 279 struct bhnd_resource **res); 280 281 void bhnd_release_resources(device_t dev, 282 const struct resource_spec *rs, 283 struct bhnd_resource **res); 284 285 struct bhnd_chipid bhnd_parse_chipid(uint32_t idreg, 286 bhnd_addr_t enum_addr); 287 288 int bhnd_read_chipid(device_t dev, 289 struct resource_spec *rs, 290 bus_size_t chipc_offset, 291 struct bhnd_chipid *result); 292 293 void bhnd_set_generic_core_desc(device_t dev); 294 295 296 /** 297 * Return true if @p dev is serving as a host bridge for its parent bhnd 298 * bus. 299 * 300 * @param dev A bhnd bus child device. 301 */ 302 static inline bool 303 bhnd_is_hostb_device(device_t dev) { 304 return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev), dev)); 305 } 306 307 /** 308 * Return true if the hardware components required by @p dev are known to be 309 * unpopulated or otherwise unusable. 310 * 311 * In some cases, enumerated devices may have pins that are left floating, or 312 * the hardware may otherwise be non-functional; this method allows a parent 313 * device to explicitly specify if a successfully enumerated @p dev should 314 * be disabled. 315 * 316 * @param dev A bhnd bus child device. 317 */ 318 static inline bool 319 bhnd_is_hw_disabled(device_t dev) { 320 return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev)); 321 } 322 323 /** 324 * Allocate a resource from a device's parent bhnd(4) bus. 325 * 326 * @param dev The device requesting resource ownership. 327 * @param type The type of resource to allocate. This may be any type supported 328 * by the standard bus APIs. 329 * @param rid The bus-specific handle identifying the resource being allocated. 330 * @param start The start address of the resource. 331 * @param end The end address of the resource. 332 * @param count The size of the resource. 333 * @param flags The flags for the resource to be allocated. These may be any 334 * values supported by the standard bus APIs. 335 * 336 * To request the resource's default addresses, pass @p start and 337 * @p end values of @c 0UL and @c ~0UL, respectively, and 338 * a @p count of @c 1. 339 * 340 * @retval NULL The resource could not be allocated. 341 * @retval resource The allocated resource. 342 */ 343 static inline struct bhnd_resource * 344 bhnd_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, 345 rman_res_t end, rman_res_t count, u_int flags) 346 { 347 return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid, 348 start, end, count, flags); 349 } 350 351 352 /** 353 * Allocate a resource from a device's parent bhnd(4) bus, using the 354 * resource's default start, end, and count values. 355 * 356 * @param dev The device requesting resource ownership. 357 * @param type The type of resource to allocate. This may be any type supported 358 * by the standard bus APIs. 359 * @param rid The bus-specific handle identifying the resource being allocated. 360 * @param flags The flags for the resource to be allocated. These may be any 361 * values supported by the standard bus APIs. 362 * 363 * @retval NULL The resource could not be allocated. 364 * @retval resource The allocated resource. 365 */ 366 static inline struct bhnd_resource * 367 bhnd_alloc_resource_any(device_t dev, int type, int *rid, u_int flags) 368 { 369 return bhnd_alloc_resource(dev, type, rid, 0UL, ~0UL, 1, flags); 370 } 371 372 /** 373 * Activate a previously allocated bhnd resource. 374 * 375 * @param dev The device holding ownership of the allocated resource. 376 * @param type The type of the resource. 377 * @param rid The bus-specific handle identifying the resource. 378 * @param r A pointer to the resource returned by bhnd_alloc_resource or 379 * BHND_BUS_ALLOC_RESOURCE. 380 * 381 * @retval 0 success 382 * @retval non-zero an error occured while activating the resource. 383 */ 384 static inline int 385 bhnd_activate_resource(device_t dev, int type, int rid, 386 struct bhnd_resource *r) 387 { 388 return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 389 rid, r); 390 } 391 392 /** 393 * Deactivate a previously activated bhnd resource. 394 * 395 * @param dev The device holding ownership of the activated resource. 396 * @param type The type of the resource. 397 * @param rid The bus-specific handle identifying the resource. 398 * @param r A pointer to the resource returned by bhnd_alloc_resource or 399 * BHND_BUS_ALLOC_RESOURCE. 400 * 401 * @retval 0 success 402 * @retval non-zero an error occured while activating the resource. 403 */ 404 static inline int 405 bhnd_deactivate_resource(device_t dev, int type, int rid, 406 struct bhnd_resource *r) 407 { 408 return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 409 rid, r); 410 } 411 412 /** 413 * Free a resource allocated by bhnd_alloc_resource(). 414 * 415 * @param dev The device holding ownership of the resource. 416 * @param type The type of the resource. 417 * @param rid The bus-specific handle identifying the resource. 418 * @param r A pointer to the resource returned by bhnd_alloc_resource or 419 * BHND_ALLOC_RESOURCE. 420 * 421 * @retval 0 success 422 * @retval non-zero an error occured while activating the resource. 423 */ 424 static inline int 425 bhnd_release_resource(device_t dev, int type, int rid, 426 struct bhnd_resource *r) 427 { 428 return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type, 429 rid, r); 430 } 431 432 /** 433 * Return true if @p region_num is a valid region on @p port_num of 434 * @p type attached to @p dev. 435 * 436 * @param dev A bhnd bus child device. 437 * @param type The port type being queried. 438 * @param port_num The port number being queried. 439 * @param region_num The region number being queried. 440 */ 441 static inline bool 442 bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port_num, 443 u_int region_num) 444 { 445 return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type, 446 port_num, region_num)); 447 } 448 449 /** 450 * Return the number of ports of type @p type attached to @p def. 451 * 452 * @param dev A bhnd bus child device. 453 * @param type The port type being queried. 454 */ 455 static inline u_int 456 bhnd_get_port_count(device_t dev, bhnd_port_type type) { 457 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type)); 458 } 459 460 /** 461 * Return the number of memory regions mapped to @p child @p port of 462 * type @p type. 463 * 464 * @param dev A bhnd bus child device. 465 * @param port The port number being queried. 466 * @param type The port type being queried. 467 */ 468 static inline u_int 469 bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) { 470 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type, 471 port)); 472 } 473 474 /** 475 * Return the resource-ID for a memory region on the given device port. 476 * 477 * @param dev A bhnd bus child device. 478 * @param type The port type. 479 * @param port The port identifier. 480 * @param region The identifier of the memory region on @p port. 481 * 482 * @retval int The RID for the given @p port and @p region on @p device. 483 * @retval -1 No such port/region found. 484 */ 485 static inline int 486 bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region) 487 { 488 return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port, 489 region); 490 } 491 492 /** 493 * Decode a port / region pair on @p dev defined by @p rid. 494 * 495 * @param dev A bhnd bus child device. 496 * @param type The resource type. 497 * @param rid The resource identifier. 498 * @param[out] port_type The decoded port type. 499 * @param[out] port The decoded port identifier. 500 * @param[out] region The decoded region identifier. 501 * 502 * @retval 0 success 503 * @retval non-zero No matching port/region found. 504 */ 505 static inline int 506 bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type, 507 u_int *port, u_int *region) 508 { 509 return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid, 510 port_type, port, region); 511 } 512 513 /** 514 * Get the address and size of @p region on @p port. 515 * 516 * @param dev A bhnd bus child device. 517 * @param port_type The port type. 518 * @param port The port identifier. 519 * @param region The identifier of the memory region on @p port. 520 * @param[out] region_addr The region's base address. 521 * @param[out] region_size The region's size. 522 * 523 * @retval 0 success 524 * @retval non-zero No matching port/region found. 525 */ 526 static inline int 527 bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, 528 u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size) 529 { 530 return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type, 531 port, region, region_addr, region_size); 532 } 533 534 /* 535 * bhnd bus-level equivalents of the bus_(read|write|set|barrier|...) 536 * macros (compatible with bhnd_resource). 537 * 538 * Generated with bhnd/tools/bus_macro.sh 539 */ 540 #define bhnd_bus_barrier(r, o, l, f) \ 541 ((r)->direct) ? \ 542 bus_barrier((r)->res, (o), (l), (f)) : \ 543 BHND_BUS_BARRIER(device_get_parent(rman_get_device((r)->res)), \ 544 rman_get_device((r)->res), (r), (o), (l), (f)) 545 #define bhnd_bus_read_1(r, o) \ 546 ((r)->direct) ? \ 547 bus_read_1((r)->res, (o)) : \ 548 BHND_BUS_READ_1(device_get_parent(rman_get_device((r)->res)), \ 549 rman_get_device((r)->res), (r), (o)) 550 #define bhnd_bus_write_1(r, o, v) \ 551 ((r)->direct) ? \ 552 bus_write_1((r)->res, (o), (v)) : \ 553 BHND_BUS_WRITE_1(device_get_parent(rman_get_device((r)->res)), \ 554 rman_get_device((r)->res), (r), (o), (v)) 555 #define bhnd_bus_read_2(r, o) \ 556 ((r)->direct) ? \ 557 bus_read_2((r)->res, (o)) : \ 558 BHND_BUS_READ_2(device_get_parent(rman_get_device((r)->res)), \ 559 rman_get_device((r)->res), (r), (o)) 560 #define bhnd_bus_write_2(r, o, v) \ 561 ((r)->direct) ? \ 562 bus_write_2((r)->res, (o), (v)) : \ 563 BHND_BUS_WRITE_2(device_get_parent(rman_get_device((r)->res)), \ 564 rman_get_device((r)->res), (r), (o), (v)) 565 #define bhnd_bus_read_4(r, o) \ 566 ((r)->direct) ? \ 567 bus_read_4((r)->res, (o)) : \ 568 BHND_BUS_READ_4(device_get_parent(rman_get_device((r)->res)), \ 569 rman_get_device((r)->res), (r), (o)) 570 #define bhnd_bus_write_4(r, o, v) \ 571 ((r)->direct) ? \ 572 bus_write_4((r)->res, (o), (v)) : \ 573 BHND_BUS_WRITE_4(device_get_parent(rman_get_device((r)->res)), \ 574 rman_get_device((r)->res), (r), (o), (v)) 575 576 #endif /* _BHND_BHND_H_ */ 577