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# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17# IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 23# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24# 25# $FreeBSD$ 26 27#include <sys/types.h> 28#include <sys/bus.h> 29#include <sys/rman.h> 30 31#include <dev/bhnd/bhnd_types.h> 32 33INTERFACE bhnd_bus; 34 35# 36# bhnd(4) bus interface 37# 38 39HEADER { 40 /* forward declarations */ 41 struct bhnd_core_info; 42 struct bhnd_chipid; 43 struct bhnd_resource; 44 struct bhnd_bus_ctx; 45} 46 47CODE { 48 #include <sys/systm.h> 49 50 #include <dev/bhnd/bhndvar.h> 51 52 static struct bhnd_chipid * 53 bhnd_bus_null_get_chipid(device_t dev, device_t child) 54 { 55 panic("bhnd_bus_get_chipid unimplemented"); 56 } 57 58 static device_t 59 bhnd_bus_null_find_hostb_device(device_t dev) 60 { 61 panic("bhnd_bus_find_hostb_device unimplemented"); 62 } 63 64 static bool 65 bhnd_bus_null_is_hw_disabled(device_t dev, device_t child) 66 { 67 panic("bhnd_bus_is_hw_disabled unimplemented"); 68 } 69 70 static int 71 bhnd_bus_null_get_probe_order(device_t dev, device_t child) 72 { 73 panic("bhnd_bus_get_probe_order unimplemented"); 74 } 75 76 static int 77 bhnd_bus_null_get_port_rid(device_t dev, device_t child, 78 bhnd_port_type port_type, u_int port, u_int region) 79 { 80 return (-1); 81 } 82 83 static int 84 bhnd_bus_null_decode_port_rid(device_t dev, device_t child, int type, 85 int rid, bhnd_port_type *port_type, u_int *port, u_int *region) 86 { 87 return (ENOENT); 88 } 89 90 static int 91 bhnd_bus_null_get_region_addr(device_t dev, device_t child, 92 bhnd_port_type type, u_int port, u_int region, bhnd_addr_t *addr, 93 bhnd_size_t *size) 94 { 95 return (ENOENT); 96 } 97 98 static int 99 bhnd_bus_null_get_nvram_var(device_t dev, device_t child, 100 const char *name, void *buf, size_t *size) 101 { 102 return (ENOENT); 103 } 104 105} 106 107/** 108 * Return the active host bridge core for the bhnd bus, if any. 109 * 110 * @param dev The bhnd bus device. 111 * 112 * @retval device_t if a hostb device exists 113 * @retval NULL if no hostb device is found. 114 */ 115METHOD device_t find_hostb_device { 116 device_t dev; 117} DEFAULT bhnd_bus_null_find_hostb_device; 118 119/** 120 * Return true if the hardware components required by @p child are unpopulated 121 * or otherwise unusable. 122 * 123 * In some cases, enumerated devices may have pins that are left floating, or 124 * the hardware may otherwise be non-functional; this method allows a parent 125 * device to explicitly specify if a successfully enumerated @p child should 126 * be disabled. 127 * 128 * @param dev The device whose child is being examined. 129 * @param child The child device. 130 */ 131METHOD bool is_hw_disabled { 132 device_t dev; 133 device_t child; 134} DEFAULT bhnd_bus_null_is_hw_disabled; 135 136/** 137 * Return the probe (and attach) order for @p child. 138 * 139 * All devices on the bhnd(4) bus will be probed, attached, or resumed in 140 * ascending order; they will be suspended, shutdown, and detached in 141 * descending order. 142 * 143 * The following device methods will be dispatched in ascending probe order 144 * by the bus: 145 * 146 * - DEVICE_PROBE() 147 * - DEVICE_ATTACH() 148 * - DEVICE_RESUME() 149 * 150 * The following device methods will be dispatched in descending probe order 151 * by the bus: 152 * 153 * - DEVICE_SHUTDOWN() 154 * - DEVICE_DETACH() 155 * - DEVICE_SUSPEND() 156 * 157 * @param dev The device whose child is being examined. 158 * @param child The child device. 159 * 160 * Refer to BHND_PROBE_* and BHND_PROBE_ORDER_* for the standard set of 161 * priorities. 162 */ 163METHOD int get_probe_order { 164 device_t dev; 165 device_t child; 166} DEFAULT bhnd_bus_null_get_probe_order; 167 168/** 169 * Return the BHND chip identification for the parent bus. 170 * 171 * @param dev The device whose child is being examined. 172 * @param child The child device. 173 */ 174METHOD const struct bhnd_chipid * get_chipid { 175 device_t dev; 176 device_t child; 177} DEFAULT bhnd_bus_null_get_chipid; 178 179/** 180 * Reset the device's hardware core. 181 * 182 * @param dev The parent of @p child. 183 * @param child The device to be reset. 184 * @param flags Device-specific core flags to be supplied on reset. 185 * 186 * @retval 0 success 187 * @retval non-zero error 188 */ 189METHOD int reset_core { 190 device_t dev; 191 device_t child; 192 uint16_t flags; 193} 194 195/** 196 * Suspend a device hardware core. 197 * 198 * @param dev The parent of @p child. 199 * @param child The device to be reset. 200 * 201 * @retval 0 success 202 * @retval non-zero error 203 */ 204METHOD int suspend_core { 205 device_t dev; 206 device_t child; 207} 208 209/** 210 * Allocate a bhnd resource. 211 * 212 * This method's semantics are functionally identical to the bus API of the same 213 * name; refer to BUS_ALLOC_RESOURCE for complete documentation. 214 */ 215METHOD struct bhnd_resource * alloc_resource { 216 device_t dev; 217 device_t child; 218 int type; 219 int *rid; 220 rman_res_t start; 221 rman_res_t end; 222 rman_res_t count; 223 u_int flags; 224} DEFAULT bhnd_bus_generic_alloc_resource; 225 226/** 227 * Release a bhnd resource. 228 * 229 * This method's semantics are functionally identical to the bus API of the same 230 * name; refer to BUS_RELEASE_RESOURCE for complete documentation. 231 */ 232METHOD int release_resource { 233 device_t dev; 234 device_t child; 235 int type; 236 int rid; 237 struct bhnd_resource *res; 238} DEFAULT bhnd_bus_generic_release_resource; 239 240/** 241 * Activate a bhnd resource. 242 * 243 * This method's semantics are functionally identical to the bus API of the same 244 * name; refer to BUS_ACTIVATE_RESOURCE for complete documentation. 245 */ 246METHOD int activate_resource { 247 device_t dev; 248 device_t child; 249 int type; 250 int rid; 251 struct bhnd_resource *r; 252} DEFAULT bhnd_bus_generic_activate_resource; 253 254/** 255 * Deactivate a bhnd resource. 256 * 257 * This method's semantics are functionally identical to the bus API of the same 258 * name; refer to BUS_DEACTIVATE_RESOURCE for complete documentation. 259 */ 260METHOD int deactivate_resource { 261 device_t dev; 262 device_t child; 263 int type; 264 int rid; 265 struct bhnd_resource *r; 266} DEFAULT bhnd_bus_generic_deactivate_resource; 267 268/** 269 * Return true if @p region_num is a valid region on @p port_num of 270 * @p type attached to @p child. 271 * 272 * @param dev The device whose child is being examined. 273 * @param child The child device. 274 * @param type The port type being queried. 275 * @param port_num The port number being queried. 276 * @param region_num The region number being queried. 277 */ 278METHOD bool is_region_valid { 279 device_t dev; 280 device_t child; 281 bhnd_port_type type; 282 u_int port_num; 283 u_int region_num; 284}; 285 286/** 287 * Return the number of ports of type @p type attached to @p child. 288 * 289 * @param dev The device whose child is being examined. 290 * @param child The child device. 291 * @param type The port type being queried. 292 */ 293METHOD u_int get_port_count { 294 device_t dev; 295 device_t child; 296 bhnd_port_type type; 297}; 298 299/** 300 * Return the number of memory regions mapped to @p child @p port of 301 * type @p type. 302 * 303 * @param dev The device whose child is being examined. 304 * @param child The child device. 305 * @param port The port number being queried. 306 * @param type The port type being queried. 307 */ 308METHOD u_int get_region_count { 309 device_t dev; 310 device_t child; 311 bhnd_port_type type; 312 u_int port; 313}; 314 315/** 316 * Return the SYS_RES_MEMORY resource-ID for a port/region pair attached to 317 * @p child. 318 * 319 * @param dev The bus device. 320 * @param child The bhnd child. 321 * @param port_type The port type. 322 * @param port_num The index of the child interconnect port. 323 * @param region_num The index of the port-mapped address region. 324 * 325 * @retval -1 No such port/region found. 326 */ 327METHOD int get_port_rid { 328 device_t dev; 329 device_t child; 330 bhnd_port_type port_type; 331 u_int port_num; 332 u_int region_num; 333} DEFAULT bhnd_bus_null_get_port_rid; 334 335 336/** 337 * Decode a port / region pair on @p child defined by @p type and @p rid. 338 * 339 * @param dev The bus device. 340 * @param child The bhnd child. 341 * @param type The resource type. 342 * @param rid The resource ID. 343 * @param[out] port_type The port's type. 344 * @param[out] port The port identifier. 345 * @param[out] region The identifier of the memory region on @p port. 346 * 347 * @retval 0 success 348 * @retval non-zero No matching type/rid found. 349 */ 350METHOD int decode_port_rid { 351 device_t dev; 352 device_t child; 353 int type; 354 int rid; 355 bhnd_port_type *port_type; 356 u_int *port; 357 u_int *region; 358} DEFAULT bhnd_bus_null_decode_port_rid; 359 360/** 361 * Get the address and size of @p region on @p port. 362 * 363 * @param dev The bus device. 364 * @param child The bhnd child. 365 * @param port_type The port type. 366 * @param port The port identifier. 367 * @param region The identifier of the memory region on @p port. 368 * @param[out] region_addr The region's base address. 369 * @param[out] region_size The region's size. 370 * 371 * @retval 0 success 372 * @retval non-zero No matching port/region found. 373 */ 374METHOD int get_region_addr { 375 device_t dev; 376 device_t child; 377 bhnd_port_type port_type; 378 u_int port; 379 u_int region; 380 bhnd_addr_t *region_addr; 381 bhnd_size_t *region_size; 382} DEFAULT bhnd_bus_null_get_region_addr; 383 384/** 385 * Read an NVRAM variable. 386 * 387 * It is the responsibility of the bus to delegate this request to 388 * the appropriate NVRAM child device, or to a parent bus implementation. 389 * 390 * @param dev The bus device. 391 * @param child The requesting device. 392 * @param name The NVRAM variable name. 393 * @param[out] buf On success, the requested value will be written 394 * to this buffer. This argment may be NULL if 395 * the value is not desired. 396 * @param[in,out] size The capacity of @p buf. On success, will be set 397 * to the actual size of the requested value. 398 * 399 * @retval 0 success 400 * @retval ENOENT The requested variable was not found. 401 * @retval ENOMEM If @p buf is non-NULL and a buffer of @p size is too 402 * small to hold the requested value. 403 * @retval non-zero If reading @p name otherwise fails, a regular unix 404 * error code will be returned. 405 */ 406METHOD int get_nvram_var { 407 device_t dev; 408 device_t child; 409 const char *name; 410 void *buf; 411 size_t *size; 412} DEFAULT bhnd_bus_null_get_nvram_var; 413 414 415/** An implementation of bus_read_1() compatible with bhnd_resource */ 416METHOD uint8_t read_1 { 417 device_t dev; 418 device_t child; 419 struct bhnd_resource *r; 420 bus_size_t offset; 421} 422 423/** An implementation of bus_read_2() compatible with bhnd_resource */ 424METHOD uint16_t read_2 { 425 device_t dev; 426 device_t child; 427 struct bhnd_resource *r; 428 bus_size_t offset; 429} 430 431/** An implementation of bus_read_4() compatible with bhnd_resource */ 432METHOD uint32_t read_4 { 433 device_t dev; 434 device_t child; 435 struct bhnd_resource *r; 436 bus_size_t offset; 437} 438 439/** An implementation of bus_write_1() compatible with bhnd_resource */ 440METHOD void write_1 { 441 device_t dev; 442 device_t child; 443 struct bhnd_resource *r; 444 bus_size_t offset; 445 uint8_t value; 446} 447 448/** An implementation of bus_write_2() compatible with bhnd_resource */ 449METHOD void write_2 { 450 device_t dev; 451 device_t child; 452 struct bhnd_resource *r; 453 bus_size_t offset; 454 uint16_t value; 455} 456 457/** An implementation of bus_write_4() compatible with bhnd_resource */ 458METHOD void write_4 { 459 device_t dev; 460 device_t child; 461 struct bhnd_resource *r; 462 bus_size_t offset; 463 uint32_t value; 464} 465 466/** An implementation of bus_read_stream_1() compatible with bhnd_resource */ 467METHOD uint8_t read_stream_1 { 468 device_t dev; 469 device_t child; 470 struct bhnd_resource *r; 471 bus_size_t offset; 472} 473 474/** An implementation of bus_read_stream_2() compatible with bhnd_resource */ 475METHOD uint16_t read_stream_2 { 476 device_t dev; 477 device_t child; 478 struct bhnd_resource *r; 479 bus_size_t offset; 480} 481 482/** An implementation of bus_read_stream_4() compatible with bhnd_resource */ 483METHOD uint32_t read_stream_4 { 484 device_t dev; 485 device_t child; 486 struct bhnd_resource *r; 487 bus_size_t offset; 488} 489 490/** An implementation of bus_write_stream_1() compatible with bhnd_resource */ 491METHOD void write_stream_1 { 492 device_t dev; 493 device_t child; 494 struct bhnd_resource *r; 495 bus_size_t offset; 496 uint8_t value; 497} 498 499/** An implementation of bus_write_stream_2() compatible with bhnd_resource */ 500METHOD void write_stream_2 { 501 device_t dev; 502 device_t child; 503 struct bhnd_resource *r; 504 bus_size_t offset; 505 uint16_t value; 506} 507 508/** An implementation of bus_write_stream_4() compatible with bhnd_resource */ 509METHOD void write_stream_4 { 510 device_t dev; 511 device_t child; 512 struct bhnd_resource *r; 513 bus_size_t offset; 514 uint32_t value; 515} 516 517/** An implementation of bus_read_multi_1() compatible with bhnd_resource */ 518METHOD void read_multi_1 { 519 device_t dev; 520 device_t child; 521 struct bhnd_resource *r; 522 bus_size_t offset; 523 uint8_t *datap; 524 bus_size_t count; 525} 526 527/** An implementation of bus_read_multi_2() compatible with bhnd_resource */ 528METHOD void read_multi_2 { 529 device_t dev; 530 device_t child; 531 struct bhnd_resource *r; 532 bus_size_t offset; 533 uint16_t *datap; 534 bus_size_t count; 535} 536 537/** An implementation of bus_read_multi_4() compatible with bhnd_resource */ 538METHOD void read_multi_4 { 539 device_t dev; 540 device_t child; 541 struct bhnd_resource *r; 542 bus_size_t offset; 543 uint32_t *datap; 544 bus_size_t count; 545} 546 547/** An implementation of bus_write_multi_1() compatible with bhnd_resource */ 548METHOD void write_multi_1 { 549 device_t dev; 550 device_t child; 551 struct bhnd_resource *r; 552 bus_size_t offset; 553 uint8_t *datap; 554 bus_size_t count; 555} 556 557/** An implementation of bus_write_multi_2() compatible with bhnd_resource */ 558METHOD void write_multi_2 { 559 device_t dev; 560 device_t child; 561 struct bhnd_resource *r; 562 bus_size_t offset; 563 uint16_t *datap; 564 bus_size_t count; 565} 566 567/** An implementation of bus_write_multi_4() compatible with bhnd_resource */ 568METHOD void write_multi_4 { 569 device_t dev; 570 device_t child; 571 struct bhnd_resource *r; 572 bus_size_t offset; 573 uint32_t *datap; 574 bus_size_t count; 575} 576 577/** An implementation of bus_read_multi_stream_1() compatible 578 * bhnd_resource */ 579METHOD void read_multi_stream_1 { 580 device_t dev; 581 device_t child; 582 struct bhnd_resource *r; 583 bus_size_t offset; 584 uint8_t *datap; 585 bus_size_t count; 586} 587 588/** An implementation of bus_read_multi_stream_2() compatible 589 * bhnd_resource */ 590METHOD void read_multi_stream_2 { 591 device_t dev; 592 device_t child; 593 struct bhnd_resource *r; 594 bus_size_t offset; 595 uint16_t *datap; 596 bus_size_t count; 597} 598 599/** An implementation of bus_read_multi_stream_4() compatible 600 * bhnd_resource */ 601METHOD void read_multi_stream_4 { 602 device_t dev; 603 device_t child; 604 struct bhnd_resource *r; 605 bus_size_t offset; 606 uint32_t *datap; 607 bus_size_t count; 608} 609 610/** An implementation of bus_write_multi_stream_1() compatible 611 * bhnd_resource */ 612METHOD void write_multi_stream_1 { 613 device_t dev; 614 device_t child; 615 struct bhnd_resource *r; 616 bus_size_t offset; 617 uint8_t *datap; 618 bus_size_t count; 619} 620 621/** An implementation of bus_write_multi_stream_2() compatible with 622 * bhnd_resource */ 623METHOD void write_multi_stream_2 { 624 device_t dev; 625 device_t child; 626 struct bhnd_resource *r; 627 bus_size_t offset; 628 uint16_t *datap; 629 bus_size_t count; 630} 631 632/** An implementation of bus_write_multi_stream_4() compatible with 633 * bhnd_resource */ 634METHOD void write_multi_stream_4 { 635 device_t dev; 636 device_t child; 637 struct bhnd_resource *r; 638 bus_size_t offset; 639 uint32_t *datap; 640 bus_size_t count; 641} 642 643/** An implementation of bus_barrier() compatible with bhnd_resource */ 644METHOD void barrier { 645 device_t dev; 646 device_t child; 647 struct bhnd_resource *r; 648 bus_size_t offset; 649 bus_size_t length; 650 int flags; 651} 652