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 bool 59 bhnd_bus_null_is_hostb_device(device_t dev, device_t child) 60 { 61 panic("bhnd_bus_is_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_read_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 * Returns true if @p child is serving as a host bridge for the bhnd 109 * bus. 110 * 111 * The default implementation will walk the parent device tree until 112 * the root node is hit, returning false. 113 * 114 * @param dev The device whose child is being examined. 115 * @param child The child device. 116 */ 117METHOD bool is_hostb_device { 118 device_t dev; 119 device_t child; 120} DEFAULT bhnd_bus_null_is_hostb_device; 121 122/** 123 * Return true if the hardware components required by @p child are unpopulated 124 * or otherwise unusable. 125 * 126 * In some cases, enumerated devices may have pins that are left floating, or 127 * the hardware may otherwise be non-functional; this method allows a parent 128 * device to explicitly specify if a successfully enumerated @p child should 129 * be disabled. 130 * 131 * @param dev The device whose child is being examined. 132 * @param child The child device. 133 */ 134METHOD bool is_hw_disabled { 135 device_t dev; 136 device_t child; 137} DEFAULT bhnd_bus_null_is_hw_disabled; 138 139/** 140 * Return the probe (and attach) order for @p child. 141 * 142 * All devices on the bhnd(4) bus will be probed, attached, or resumed in 143 * ascending order; they will be suspended, shutdown, and detached in 144 * descending order. 145 * 146 * The following device methods will be dispatched in ascending probe order 147 * by the bus: 148 * 149 * - DEVICE_PROBE() 150 * - DEVICE_ATTACH() 151 * - DEVICE_RESUME() 152 * 153 * The following device methods will be dispatched in descending probe order 154 * by the bus: 155 * 156 * - DEVICE_SHUTDOWN() 157 * - DEVICE_DETACH() 158 * - DEVICE_SUSPEND() 159 * 160 * @param dev The device whose child is being examined. 161 * @param child The child device. 162 * 163 * Refer to BHND_PROBE_* and BHND_PROBE_ORDER_* for the standard set of 164 * priorities. 165 */ 166METHOD int get_probe_order { 167 device_t dev; 168 device_t child; 169} DEFAULT bhnd_bus_null_get_probe_order; 170 171/** 172 * Return the BHND chip identification for the parent bus. 173 * 174 * @param dev The device whose child is being examined. 175 * @param child The child device. 176 */ 177METHOD const struct bhnd_chipid * get_chipid { 178 device_t dev; 179 device_t child; 180} DEFAULT bhnd_bus_null_get_chipid; 181 182/** 183 * Reset the device's hardware core. 184 * 185 * @param dev The parent of @p child. 186 * @param child The device to be reset. 187 * @param flags Device-specific core flags to be supplied on reset. 188 * 189 * @retval 0 success 190 * @retval non-zero error 191 */ 192METHOD int reset_core { 193 device_t dev; 194 device_t child; 195 uint16_t flags; 196} 197 198/** 199 * Suspend a device hardware core. 200 * 201 * @param dev The parent of @p child. 202 * @param child The device to be reset. 203 * 204 * @retval 0 success 205 * @retval non-zero error 206 */ 207METHOD int suspend_core { 208 device_t dev; 209 device_t child; 210} 211 212/** 213 * Allocate a bhnd resource. 214 * 215 * This method's semantics are functionally identical to the bus API of the same 216 * name; refer to BUS_ALLOC_RESOURCE for complete documentation. 217 */ 218METHOD struct bhnd_resource * alloc_resource { 219 device_t dev; 220 device_t child; 221 int type; 222 int *rid; 223 rman_res_t start; 224 rman_res_t end; 225 rman_res_t count; 226 u_int flags; 227} DEFAULT bhnd_bus_generic_alloc_resource; 228 229/** 230 * Release a bhnd resource. 231 * 232 * This method's semantics are functionally identical to the bus API of the same 233 * name; refer to BUS_RELEASE_RESOURCE for complete documentation. 234 */ 235METHOD int release_resource { 236 device_t dev; 237 device_t child; 238 int type; 239 int rid; 240 struct bhnd_resource *res; 241} DEFAULT bhnd_bus_generic_release_resource; 242 243/** 244 * Activate a bhnd resource. 245 * 246 * This method's semantics are functionally identical to the bus API of the same 247 * name; refer to BUS_ACTIVATE_RESOURCE for complete documentation. 248 */ 249METHOD int activate_resource { 250 device_t dev; 251 device_t child; 252 int type; 253 int rid; 254 struct bhnd_resource *r; 255} DEFAULT bhnd_bus_generic_activate_resource; 256 257/** 258 * Deactivate a bhnd resource. 259 * 260 * This method's semantics are functionally identical to the bus API of the same 261 * name; refer to BUS_DEACTIVATE_RESOURCE for complete documentation. 262 */ 263METHOD int deactivate_resource { 264 device_t dev; 265 device_t child; 266 int type; 267 int rid; 268 struct bhnd_resource *r; 269} DEFAULT bhnd_bus_generic_deactivate_resource; 270 271/** 272 * Return true if @p region_num is a valid region on @p port_num of 273 * @p type attached to @p child. 274 * 275 * @param dev The device whose child is being examined. 276 * @param child The child device. 277 * @param type The port type being queried. 278 * @param port_num The port number being queried. 279 * @param region_num The region number being queried. 280 */ 281METHOD bool is_region_valid { 282 device_t dev; 283 device_t child; 284 bhnd_port_type type; 285 u_int port_num; 286 u_int region_num; 287}; 288 289/** 290 * Return the number of ports of type @p type attached to @p child. 291 * 292 * @param dev The device whose child is being examined. 293 * @param child The child device. 294 * @param type The port type being queried. 295 */ 296METHOD u_int get_port_count { 297 device_t dev; 298 device_t child; 299 bhnd_port_type type; 300}; 301 302/** 303 * Return the number of memory regions mapped to @p child @p port of 304 * type @p type. 305 * 306 * @param dev The device whose child is being examined. 307 * @param child The child device. 308 * @param port The port number being queried. 309 * @param type The port type being queried. 310 */ 311METHOD u_int get_region_count { 312 device_t dev; 313 device_t child; 314 bhnd_port_type type; 315 u_int port; 316}; 317 318/** 319 * Return the SYS_RES_MEMORY resource-ID for a port/region pair attached to 320 * @p child. 321 * 322 * @param dev The bus device. 323 * @param child The bhnd child. 324 * @param port_type The port type. 325 * @param port_num The index of the child interconnect port. 326 * @param region_num The index of the port-mapped address region. 327 * 328 * @retval -1 No such port/region found. 329 */ 330METHOD int get_port_rid { 331 device_t dev; 332 device_t child; 333 bhnd_port_type port_type; 334 u_int port_num; 335 u_int region_num; 336} DEFAULT bhnd_bus_null_get_port_rid; 337 338 339/** 340 * Decode a port / region pair on @p child defined by @p type and @p rid. 341 * 342 * @param dev The bus device. 343 * @param child The bhnd child. 344 * @param type The resource type. 345 * @param rid The resource ID. 346 * @param[out] port_type The port's type. 347 * @param[out] port The port identifier. 348 * @param[out] region The identifier of the memory region on @p port. 349 * 350 * @retval 0 success 351 * @retval non-zero No matching type/rid found. 352 */ 353METHOD int decode_port_rid { 354 device_t dev; 355 device_t child; 356 int type; 357 int rid; 358 bhnd_port_type *port_type; 359 u_int *port; 360 u_int *region; 361} DEFAULT bhnd_bus_null_decode_port_rid; 362 363/** 364 * Get the address and size of @p region on @p port. 365 * 366 * @param dev The bus device. 367 * @param child The bhnd child. 368 * @param port_type The port type. 369 * @param port The port identifier. 370 * @param region The identifier of the memory region on @p port. 371 * @param[out] region_addr The region's base address. 372 * @param[out] region_size The region's size. 373 * 374 * @retval 0 success 375 * @retval non-zero No matching port/region found. 376 */ 377METHOD int get_region_addr { 378 device_t dev; 379 device_t child; 380 bhnd_port_type port_type; 381 u_int port; 382 u_int region; 383 bhnd_addr_t *region_addr; 384 bhnd_size_t *region_size; 385} DEFAULT bhnd_bus_null_get_region_addr; 386 387/** 388 * Read an NVRAM variable. 389 * 390 * It is the responsibility of the bus to delegate this request to 391 * the appropriate NVRAM child device, or to a parent bus implementation. 392 * 393 * @param dev The bus device. 394 * @param child The requesting device. 395 * @param name The NVRAM variable name. 396 * @param[out] buf On success, the requested value will be written 397 * to this buffer. This argment may be NULL if 398 * the value is not desired. 399 * @param[in,out] size The capacity of @p buf. On success, will be set 400 * to the actual size of the requested value. 401 * 402 * @retval 0 success 403 * @retval ENOENT The requested variable was not found. 404 * @retval ENOMEM If @p buf is non-NULL and a buffer of @p size is too 405 * small to hold the requested value. 406 * @retval non-zero If reading @p name otherwise fails, a regular unix 407 * error code will be returned. 408 */ 409METHOD int read_nvram_var { 410 device_t dev; 411 device_t child; 412 const char *name; 413 void *buf; 414 size_t *size; 415} DEFAULT bhnd_bus_null_read_nvram_var; 416 417 418/** An implementation of bus_read_1() compatible with bhnd_resource */ 419METHOD uint8_t read_1 { 420 device_t dev; 421 device_t child; 422 struct bhnd_resource *r; 423 bus_size_t offset; 424} 425 426/** An implementation of bus_read_2() compatible with bhnd_resource */ 427METHOD uint16_t read_2 { 428 device_t dev; 429 device_t child; 430 struct bhnd_resource *r; 431 bus_size_t offset; 432} 433 434/** An implementation of bus_read_4() compatible with bhnd_resource */ 435METHOD uint32_t read_4 { 436 device_t dev; 437 device_t child; 438 struct bhnd_resource *r; 439 bus_size_t offset; 440} 441 442/** An implementation of bus_write_1() compatible with bhnd_resource */ 443METHOD void write_1 { 444 device_t dev; 445 device_t child; 446 struct bhnd_resource *r; 447 bus_size_t offset; 448 uint8_t value; 449} 450 451/** An implementation of bus_write_2() compatible with bhnd_resource */ 452METHOD void write_2 { 453 device_t dev; 454 device_t child; 455 struct bhnd_resource *r; 456 bus_size_t offset; 457 uint16_t value; 458} 459 460/** An implementation of bus_write_4() compatible with bhnd_resource */ 461METHOD void write_4 { 462 device_t dev; 463 device_t child; 464 struct bhnd_resource *r; 465 bus_size_t offset; 466 uint32_t value; 467} 468 469/** An implementation of bus_barrier() compatible with bhnd_resource */ 470METHOD void barrier { 471 device_t dev; 472 device_t child; 473 struct bhnd_resource *r; 474 bus_size_t offset; 475 bus_size_t length; 476 int flags; 477} 478