1 /* $OpenBSD: bus.h,v 1.32 2015/01/24 15:13:55 kettenis Exp $ */ 2 /* $NetBSD: bus.h,v 1.6 1996/11/10 03:19:25 thorpej Exp $ */ 3 4 /*- 5 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 36 * Copyright (c) 1996 Jason R. Thorpe. All rights reserved. 37 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. All advertising materials mentioning features or use of this software 48 * must display the following acknowledgement: 49 * This product includes software developed by Christopher G. Demetriou 50 * for the NetBSD Project. 51 * 4. The name of the author may not be used to endorse or promote products 52 * derived from this software without specific prior written permission 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64 */ 65 66 #ifndef _MACHINE_BUS_H_ 67 #define _MACHINE_BUS_H_ 68 69 #include <sys/mutex.h> 70 #include <sys/tree.h> 71 72 #include <machine/pio.h> 73 74 /* 75 * Bus address and size types 76 */ 77 typedef u_long bus_addr_t; 78 typedef u_long bus_size_t; 79 80 /* 81 * Access methods for bus resources and address space. 82 */ 83 struct x86_bus_space_ops; 84 typedef const struct x86_bus_space_ops *bus_space_tag_t; 85 typedef u_long bus_space_handle_t; 86 87 int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 88 bus_size_t size, int flags, bus_space_handle_t *bshp); 89 /* like map, but without extent map checking/allocation */ 90 int _bus_space_map(bus_space_tag_t t, bus_addr_t addr, 91 bus_size_t size, int flags, bus_space_handle_t *bshp); 92 93 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 94 bus_addr_t rend, bus_size_t size, bus_size_t align, 95 bus_size_t boundary, int flags, bus_addr_t *addrp, 96 bus_space_handle_t *bshp); 97 void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 98 bus_size_t size); 99 100 /* 101 * int bus_space_unmap(bus_space_tag_t t, 102 * bus_space_handle_t bsh, bus_size_t size); 103 * 104 * Unmap a region of bus space. 105 */ 106 107 void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 108 bus_size_t size); 109 void _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 110 bus_size_t size, bus_addr_t *); 111 112 /* like bus_space_map(), but without extent map checking/allocation */ 113 int _bus_space_map(bus_space_tag_t t, bus_addr_t addr, 114 bus_size_t size, int flags, bus_space_handle_t *bshp); 115 116 /* 117 * int bus_space_subregion(bus_space_tag_t t, 118 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 119 * bus_space_handle_t *nbshp); 120 * 121 * Get a new handle for a subregion of an already-mapped area of bus space. 122 */ 123 124 int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 125 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 126 127 struct x86_bus_space_ops { 128 129 /* 130 * u_intN_t bus_space_read_N(bus_space_tag_t tag, 131 * bus_space_handle_t bsh, bus_size_t offset); 132 * 133 * Read a 1, 2, 4, or 8 byte quantity from bus space 134 * described by tag/handle/offset. 135 */ 136 u_int8_t (*read_1)(bus_space_handle_t, bus_size_t); 137 u_int16_t (*read_2)(bus_space_handle_t, bus_size_t); 138 u_int32_t (*read_4)(bus_space_handle_t, bus_size_t); 139 u_int64_t (*read_8)(bus_space_handle_t, bus_size_t); 140 141 #define bus_space_read_1(_t, _h, _o) ((_t)->read_1((_h), (_o))) 142 #define bus_space_read_2(_t, _h, _o) ((_t)->read_2((_h), (_o))) 143 #define bus_space_read_4(_t, _h, _o) ((_t)->read_4((_h), (_o))) 144 #define bus_space_read_8(_t, _h, _o) ((_t)->read_8((_h), (_o))) 145 146 #define bus_space_read_raw_2(_t, _h, _o) ((_t)->read_2((_h), (_o))) 147 #define bus_space_read_raw_4(_t, _h, _o) ((_t)->read_4((_h), (_o))) 148 #define bus_space_read_raw_8(_t, _h, _o) ((_t)->read_8((_h), (_o))) 149 150 /* 151 * void bus_space_read_multi_N(bus_space_tag_t tag, 152 * bus_space_handle_t bsh, bus_size_t offset, 153 * u_intN_t *addr, size_t count); 154 * 155 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 156 * described by tag/handle/offset and copy into buffer provided. 157 */ 158 159 void (*read_multi_1)(bus_space_handle_t, bus_size_t, 160 u_int8_t *, bus_size_t); 161 void (*read_multi_2)(bus_space_handle_t, bus_size_t, 162 u_int16_t *, bus_size_t); 163 void (*read_multi_4)(bus_space_handle_t, bus_size_t, 164 u_int32_t *, bus_size_t); 165 void (*read_multi_8)(bus_space_handle_t, bus_size_t, 166 u_int64_t *, bus_size_t); 167 168 #define bus_space_read_multi_1(_t, _h, _o, _a, _c) \ 169 ((_t)->read_multi_1((_h), (_o), (_a), (_c))) 170 #define bus_space_read_multi_2(_t, _h, _o, _a, _c) \ 171 ((_t)->read_multi_2((_h), (_o), (_a), (_c))) 172 #define bus_space_read_multi_4(_t, _h, _o, _a, _c) \ 173 ((_t)->read_multi_4((_h), (_o), (_a), (_c))) 174 #define bus_space_read_multi_8(_t, _h, _o, _a, _c) \ 175 ((_t)->read_multi_8((_h), (_o), (_a), (_c))) 176 177 /* 178 * void bus_space_read_raw_multi_N(bus_space_tag_t tag, 179 * bus_space_handle_t bsh, bus_size_t offset, 180 * u_int8_t *addr, size_t count); 181 * 182 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 183 * described by tag/handle/offset and copy into buffer provided. The buffer 184 * must have proper alignment for the N byte wide entities. Furthermore 185 * possible byte-swapping should be done by these functions. 186 */ 187 188 #define bus_space_read_raw_multi_2(_t, _h, _o, _a, _c) \ 189 ((_t)->read_multi_2((_h), (_o), (u_int16_t *)(_a), (_c) >> 1)) 190 #define bus_space_read_raw_multi_4(_t, _h, _o, _a, _c) \ 191 ((_t)->read_multi_4((_h), (_o), (u_int32_t *)(_a), (_c) >> 2)) 192 #define bus_space_read_raw_multi_8(_t, _h, _o, _a, _c) \ 193 ((_t)->read_multi_8((_h), (_o), (u_int64_t *)(_a), (_c) >> 3)) 194 195 /* 196 * void bus_space_read_region_N(bus_space_tag_t tag, 197 * bus_space_handle_t bsh, bus_size_t offset, 198 * u_intN_t *addr, size_t count); 199 * 200 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 201 * described by tag/handle and starting at `offset' and copy into 202 * buffer provided. 203 */ 204 205 void (*read_region_1)(bus_space_handle_t, 206 bus_size_t, u_int8_t *, bus_size_t); 207 void (*read_region_2)(bus_space_handle_t, 208 bus_size_t, u_int16_t *, bus_size_t); 209 void (*read_region_4)(bus_space_handle_t, 210 bus_size_t, u_int32_t *, bus_size_t); 211 void (*read_region_8)(bus_space_handle_t, 212 bus_size_t, u_int64_t *, bus_size_t); 213 214 #define bus_space_read_region_1(_t, _h, _o, _a, _c) \ 215 ((_t)->read_region_1((_h), (_o), (_a), (_c))) 216 #define bus_space_read_region_2(_t, _h, _o, _a, _c) \ 217 ((_t)->read_region_2((_h), (_o), (_a), (_c))) 218 #define bus_space_read_region_4(_t, _h, _o, _a, _c) \ 219 ((_t)->read_region_4((_h), (_o), (_a), (_c))) 220 #define bus_space_read_region_8(_t, _h, _o, _a, _c) \ 221 ((_t)->read_region_8((_h), (_o), (_a), (_c))) 222 223 /* 224 * void bus_space_read_raw_region_N(bus_space_tag_t tag, 225 * bus_space_handle_t bsh, bus_size_t offset, 226 * u_int8_t *addr, size_t count); 227 * 228 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 229 * described by tag/handle and starting at `offset' and copy into 230 * buffer provided. The buffer must have proper alignment for the N byte 231 * wide entities. Furthermore possible byte-swapping should be done by 232 * these functions. 233 */ 234 235 #define bus_space_read_raw_region_2(_t, _h, _o, _a, _c) \ 236 ((_t)->read_region_2((_h), (_o), (u_int16_t *)(_a), (_c) >> 1)) 237 #define bus_space_read_raw_region_4(_t, _h, _o, _a, _c) \ 238 ((_t)->read_region_4((_h), (_o), (u_int32_t *)(_a), (_c) >> 2)) 239 #define bus_space_read_raw_region_8(_t, _h, _o, _a, _c) \ 240 ((_t)->read_region_8((_h), (_o), (u_int64_t *)(_a), (_c) >> 3)) 241 242 /* 243 * void bus_space_write_N(bus_space_tag_t tag, 244 * bus_space_handle_t bsh, bus_size_t offset, 245 * u_intN_t value); 246 * 247 * Write the 1, 2, 4, or 8 byte value `value' to bus space 248 * described by tag/handle/offset. 249 */ 250 251 void (*write_1)(bus_space_handle_t, bus_size_t, u_int8_t); 252 void (*write_2)(bus_space_handle_t, bus_size_t, u_int16_t); 253 void (*write_4)(bus_space_handle_t, bus_size_t, u_int32_t); 254 void (*write_8)(bus_space_handle_t, bus_size_t, u_int64_t); 255 256 #define bus_space_write_1(_t, _h, _o, _v) \ 257 ((_t)->write_1((_h), (_o), (_v))) 258 #define bus_space_write_2(_t, _h, _o, _v) \ 259 ((_t)->write_2((_h), (_o), (_v))) 260 #define bus_space_write_4(_t, _h, _o, _v) \ 261 ((_t)->write_4((_h), (_o), (_v))) 262 #define bus_space_write_8(_t, _h, _o, _v) \ 263 ((_t)->write_8((_h), (_o), (_v))) 264 265 #define bus_space_write_raw_2(_t, _h, _o, _v) \ 266 ((_t)->write_2((_h), (_o), (_v))) 267 #define bus_space_write_raw_4(_t, _h, _o, _v) \ 268 ((_t)->write_4((_h), (_o), (_v))) 269 #define bus_space_write_raw_8(_t, _h, _o, _v) \ 270 ((_t)->write_8((_h), (_o), (_v))) 271 272 /* 273 * void bus_space_write_multi_N(bus_space_tag_t tag, 274 * bus_space_handle_t bsh, bus_size_t offset, 275 * const u_intN_t *addr, size_t count); 276 * 277 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 278 * provided to bus space described by tag/handle/offset. 279 */ 280 281 void (*write_multi_1)(bus_space_handle_t, 282 bus_size_t, const u_int8_t *, bus_size_t); 283 void (*write_multi_2)(bus_space_handle_t, 284 bus_size_t, const u_int16_t *, bus_size_t); 285 void (*write_multi_4)(bus_space_handle_t, 286 bus_size_t, const u_int32_t *, bus_size_t); 287 void (*write_multi_8)(bus_space_handle_t, 288 bus_size_t, const u_int64_t *, bus_size_t); 289 290 #define bus_space_write_multi_1(_t, _h, _o, _a, _c) \ 291 ((_t)->write_multi_1((_h), (_o), (_a), (_c))) 292 #define bus_space_write_multi_2(_t, _h, _o, _a, _c) \ 293 ((_t)->write_multi_2((_h), (_o), (_a), (_c))) 294 #define bus_space_write_multi_4(_t, _h, _o, _a, _c) \ 295 ((_t)->write_multi_4((_h), (_o), (_a), (_c))) 296 #define bus_space_write_multi_8(_t, _h, _o, _a, _c) \ 297 ((_t)->write_multi_8((_h), (_o), (_a), (_c))) 298 299 /* 300 * void bus_space_write_raw_multi_N(bus_space_tag_t tag, 301 * bus_space_handle_t bsh, bus_size_t offset, 302 * const u_int8_t *addr, size_t count); 303 * 304 * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer 305 * provided to bus space described by tag/handle/offset. The buffer 306 * must have proper alignment for the N byte wide entities. Furthermore 307 * possible byte-swapping should be done by these functions. 308 */ 309 310 #define bus_space_write_raw_multi_2(_t, _h, _o, _a, _c) \ 311 ((_t)->write_multi_2((_h), (_o), (const u_int16_t *)(_a), (_c) >> 1)) 312 #define bus_space_write_raw_multi_4(_t, _h, _o, _a, _c) \ 313 ((_t)->write_multi_4((_h), (_o), (const u_int32_t *)(_a), (_c) >> 2)) 314 #define bus_space_write_raw_multi_8(_t, _h, _o, _a, _c) \ 315 ((_t)->write_multi_8((_h), (_o), (const u_int64_t *)(_a), (_c) >> 3)) 316 317 /* 318 * void bus_space_write_region_N(bus_space_tag_t tag, 319 * bus_space_handle_t bsh, bus_size_t offset, 320 * const u_intN_t *addr, size_t count); 321 * 322 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 323 * to bus space described by tag/handle starting at `offset'. 324 */ 325 326 void (*write_region_1)(bus_space_handle_t, 327 bus_size_t, const u_int8_t *, bus_size_t); 328 void (*write_region_2)(bus_space_handle_t, 329 bus_size_t, const u_int16_t *, bus_size_t); 330 void (*write_region_4)(bus_space_handle_t, 331 bus_size_t, const u_int32_t *, bus_size_t); 332 void (*write_region_8)(bus_space_handle_t, 333 bus_size_t, const u_int64_t *, bus_size_t); 334 335 #define bus_space_write_region_1(_t, _h, _o, _a, _c) \ 336 ((_t)->write_region_1((_h), (_o), (_a), (_c))) 337 #define bus_space_write_region_2(_t, _h, _o, _a, _c) \ 338 ((_t)->write_region_2((_h), (_o), (_a), (_c))) 339 #define bus_space_write_region_4(_t, _h, _o, _a, _c) \ 340 ((_t)->write_region_4((_h), (_o), (_a), (_c))) 341 #define bus_space_write_region_8(_t, _h, _o, _a, _c) \ 342 ((_t)->write_region_8((_h), (_o), (_a), (_c))) 343 344 /* 345 * void bus_space_write_raw_region_N(bus_space_tag_t tag, 346 * bus_space_handle_t bsh, bus_size_t offset, 347 * const u_int8_t *addr, size_t count); 348 * 349 * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space 350 * described by tag/handle and starting at `offset' from the 351 * buffer provided. The buffer must have proper alignment for the N byte 352 * wide entities. Furthermore possible byte-swapping should be done by 353 * these functions. 354 */ 355 356 #define bus_space_write_raw_region_2(_t, _h, _o, _a, _c) \ 357 ((_t)->write_region_2((_h), (_o), (const u_int16_t *)(_a), (_c) >> 1)) 358 #define bus_space_write_raw_region_4(_t, _h, _o, _a, _c) \ 359 ((_t)->write_region_4((_h), (_o), (const u_int32_t *)(_a), (_c) >> 2)) 360 #define bus_space_write_raw_region_8(_t, _h, _o, _a, _c) \ 361 ((_t)->write_region_8((_h), (_o), (const u_int64_t *)(_a), (_c) >> 3)) 362 363 /* 364 * void bus_space_set_multi_N(bus_space_tag_t tag, 365 * bus_space_handle_t bsh, bus_size_t offset, 366 * u_intN_t val, size_t count); 367 * 368 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 369 * by tag/handle/offset `count' times. 370 */ 371 372 void (*set_multi_1)(bus_space_handle_t, 373 bus_size_t, u_int8_t, size_t); 374 void (*set_multi_2)(bus_space_handle_t, 375 bus_size_t, u_int16_t, size_t); 376 void (*set_multi_4)(bus_space_handle_t, 377 bus_size_t, u_int32_t, size_t); 378 void (*set_multi_8)(bus_space_handle_t, 379 bus_size_t, u_int64_t, size_t); 380 381 #define bus_space_set_multi_1(_t, _h, _o, _a, _c) \ 382 ((_t)->set_multi_1((_h), (_o), (_a), (_c))) 383 #define bus_space_set_multi_2(_t, _h, _o, _a, _c) \ 384 ((_t)->set_multi_2((_h), (_o), (_a), (_c))) 385 #define bus_space_set_multi_4(_t, _h, _o, _a, _c) \ 386 ((_t)->set_multi_4((_h), (_o), (_a), (_c))) 387 #define bus_space_set_multi_8(_t, _h, _o, _a, _c) \ 388 ((_t)->set_multi_8((_h), (_o), (_a), (_c))) 389 390 /* 391 * void bus_space_set_region_N(bus_space_tag_t tag, 392 * bus_space_handle_t bsh, bus_size_t offset, 393 * u_intN_t val, size_t count); 394 * 395 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 396 * by tag/handle starting at `offset'. 397 */ 398 399 void (*set_region_1)(bus_space_handle_t, 400 bus_size_t, u_int8_t, size_t); 401 void (*set_region_2)(bus_space_handle_t, 402 bus_size_t, u_int16_t, size_t); 403 void (*set_region_4)(bus_space_handle_t, 404 bus_size_t, u_int32_t, size_t); 405 void (*set_region_8)(bus_space_handle_t, 406 bus_size_t, u_int64_t, size_t); 407 408 #define bus_space_set_region_1(_t, _h, _o, _a, _c) \ 409 ((_t)->set_region_1((_h), (_o), (_a), (_c))) 410 #define bus_space_set_region_2(_t, _h, _o, _a, _c) \ 411 ((_t)->set_region_2((_h), (_o), (_a), (_c))) 412 #define bus_space_set_region_4(_t, _h, _o, _a, _c) \ 413 ((_t)->set_region_4((_h), (_o), (_a), (_c))) 414 #define bus_space_set_region_8(_t, _h, _o, _a, _c) \ 415 ((_t)->set_region_8((_h), (_o), (_a), (_c))) 416 417 /* 418 * void bus_space_copy_N(bus_space_tag_t tag, 419 * bus_space_handle_t bsh1, bus_size_t off1, 420 * bus_space_handle_t bsh2, bus_size_t off2, 421 * size_t count); 422 * 423 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 424 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 425 */ 426 427 void (*copy_1)(bus_space_handle_t, 428 bus_size_t, bus_space_handle_t, bus_size_t, size_t); 429 void (*copy_2)(bus_space_handle_t, 430 bus_size_t, bus_space_handle_t, bus_size_t, size_t); 431 void (*copy_4)(bus_space_handle_t, 432 bus_size_t, bus_space_handle_t, bus_size_t, size_t); 433 void (*copy_8)(bus_space_handle_t, 434 bus_size_t, bus_space_handle_t, bus_size_t, size_t); 435 436 #define bus_space_copy_1(_t, _h1, _o1, _h2, _o2, _c) \ 437 ((_t)->copy_1((_h1), (_o1), (_h2), (_o2), (_c))) 438 #define bus_space_copy_2(_t, _h1, _o1, _h2, _o2, _c) \ 439 ((_t)->copy_2((_h1), (_o1), (_h2), (_o2), (_c))) 440 #define bus_space_copy_4(_t, _h1, _o1, _h2, _o2, _c) \ 441 ((_t)->copy_4((_h1), (_o1), (_h2), (_o2), (_c))) 442 #define bus_space_copy_8(_t, _h1, _o1, _h2, _o2, _c) \ 443 ((_t)->copy_8((_h1), (_o1), (_h2), (_o2), (_c))) 444 445 /* 446 * void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t); 447 * 448 * Get the kernel virtual address for the mapped bus space. 449 * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR. 450 */ 451 void * (*vaddr)(bus_space_handle_t); 452 453 #define bus_space_vaddr(_t, _h) \ 454 ((_t)->vaddr((_h))) 455 456 /* 457 * paddr_t bus_space_mmap(bus_space_tag_t t, bus_addr_t base, 458 * off_t offset, int prot, int flags); 459 * 460 * Mmap an area of bus space. 461 */ 462 463 paddr_t (*mmap)(bus_addr_t, off_t, int, int); 464 465 #define bus_space_mmap(_t, _a, _o, _p, _f) \ 466 ((_t)->mmap((_a), (_o), (_p), (_f))) 467 }; 468 469 /* 470 * Bus read/write barrier methods. 471 */ 472 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 473 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 474 475 static inline void 476 bus_space_barrier(bus_space_tag_t space, bus_space_handle_t 477 handle, bus_size_t offset, bus_size_t length, int flags) 478 { 479 switch (flags) { 480 case (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE): 481 __asm volatile("mfence"); 482 break; 483 case BUS_SPACE_BARRIER_WRITE: 484 __asm volatile("sfence"); 485 break; 486 default: 487 __asm volatile("lfence"); 488 break; 489 } 490 } 491 492 #define BUS_SPACE_MAP_CACHEABLE 0x0001 493 #define BUS_SPACE_MAP_LINEAR 0x0002 494 #define BUS_SPACE_MAP_PREFETCHABLE 0x0008 495 496 /* 497 * Values for the x86 bus space tag, not to be used directly by MI code. 498 */ 499 500 /* space is i/o space */ 501 extern const struct x86_bus_space_ops x86_bus_space_io_ops; 502 #define X86_BUS_SPACE_IO (&x86_bus_space_io_ops) 503 504 /* space is mem space */ 505 extern const struct x86_bus_space_ops x86_bus_space_mem_ops; 506 #define X86_BUS_SPACE_MEM (&x86_bus_space_mem_ops) 507 508 /* 509 * bus_dma 510 */ 511 512 /* 513 * Flags used in various bus DMA methods. 514 */ 515 #define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */ 516 #define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */ 517 #define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */ 518 #define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */ 519 #define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */ 520 #define BUS_DMA_BUS2 0x0020 521 #define BUS_DMA_32BIT 0x0040 522 #define BUS_DMA_24BIT 0x0080 /* isadma map */ 523 #define BUS_DMA_STREAMING 0x0100 /* hint: sequential, unidirectional */ 524 #define BUS_DMA_READ 0x0200 /* mapping is device -> memory only */ 525 #define BUS_DMA_WRITE 0x0400 /* mapping is memory -> device only */ 526 #define BUS_DMA_NOCACHE 0x0800 /* map memory uncached */ 527 #define BUS_DMA_ZERO 0x1000 /* zero memory in dmamem_alloc */ 528 529 /* Forwards needed by prototypes below. */ 530 struct mbuf; 531 struct proc; 532 struct uio; 533 534 /* 535 * Operations performed by bus_dmamap_sync(). 536 */ 537 #define BUS_DMASYNC_PREREAD 0x01 538 #define BUS_DMASYNC_POSTREAD 0x02 539 #define BUS_DMASYNC_PREWRITE 0x04 540 #define BUS_DMASYNC_POSTWRITE 0x08 541 542 typedef struct bus_dma_tag *bus_dma_tag_t; 543 typedef struct bus_dmamap *bus_dmamap_t; 544 545 /* 546 * bus_dma_segment_t 547 * 548 * Describes a single contiguous DMA transaction. Values 549 * are suitable for programming into DMA registers. 550 */ 551 struct bus_dma_segment { 552 bus_addr_t ds_addr; /* DMA address */ 553 bus_size_t ds_len; /* length of transfer */ 554 /* 555 * Ugh. need this so can pass alignment down from bus_dmamem_alloc 556 * to scatter gather maps. only the first one is used so the rest is 557 * wasted space. bus_dma could do with fixing the api for this. 558 */ 559 bus_size_t _ds_boundary; /* don't cross */ 560 bus_size_t _ds_align; /* align to me */ 561 }; 562 typedef struct bus_dma_segment bus_dma_segment_t; 563 564 /* 565 * bus_dma_tag_t 566 * 567 * A machine-dependent opaque type describing the implementation of 568 * DMA for a given bus. 569 */ 570 571 struct bus_dma_tag { 572 void *_cookie; /* cookie used in the guts */ 573 574 /* 575 * DMA mapping methods. 576 */ 577 int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int, 578 bus_size_t, bus_size_t, int, bus_dmamap_t *); 579 void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t); 580 int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *, 581 bus_size_t, struct proc *, int); 582 int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t, 583 struct mbuf *, int); 584 int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, 585 struct uio *, int); 586 int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t, 587 bus_dma_segment_t *, int, bus_size_t, int); 588 void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t); 589 void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t, 590 bus_addr_t, bus_size_t, int); 591 592 /* 593 * DMA memory utility functions. 594 */ 595 int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t, 596 bus_size_t, bus_dma_segment_t *, int, int *, int); 597 int (*_dmamem_alloc_range)(bus_dma_tag_t, bus_size_t, bus_size_t, 598 bus_size_t, bus_dma_segment_t *, int, int *, int, 599 bus_addr_t, bus_addr_t); 600 void (*_dmamem_free)(bus_dma_tag_t, 601 bus_dma_segment_t *, int); 602 int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *, 603 int, size_t, caddr_t *, int); 604 void (*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t); 605 paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *, 606 int, off_t, int, int); 607 }; 608 609 #define bus_dmamap_create(t, s, n, m, b, f, p) \ 610 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 611 #define bus_dmamap_destroy(t, p) \ 612 (*(t)->_dmamap_destroy)((t), (p)) 613 #define bus_dmamap_load(t, m, b, s, p, f) \ 614 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 615 #define bus_dmamap_load_mbuf(t, m, b, f) \ 616 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 617 #define bus_dmamap_load_uio(t, m, u, f) \ 618 (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 619 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 620 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 621 #define bus_dmamap_unload(t, p) \ 622 (*(t)->_dmamap_unload)((t), (p)) 623 #define bus_dmamap_sync(t, p, o, l, ops) \ 624 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) 625 626 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 627 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 628 #define bus_dmamem_alloc_range(t, s, a, b, sg, n, r, f, l, h) \ 629 (*(t)->_dmamem_alloc_range)((t), (s), (a), (b), (sg), \ 630 (n), (r), (f), (l), (h)) 631 #define bus_dmamem_free(t, sg, n) \ 632 (*(t)->_dmamem_free)((t), (sg), (n)) 633 #define bus_dmamem_map(t, sg, n, s, k, f) \ 634 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 635 #define bus_dmamem_unmap(t, k, s) \ 636 (*(t)->_dmamem_unmap)((t), (k), (s)) 637 #define bus_dmamem_mmap(t, sg, n, o, p, f) \ 638 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 639 640 /* 641 * bus_dmamap_t 642 * 643 * Describes a DMA mapping. 644 */ 645 struct bus_dmamap { 646 /* 647 * PRIVATE MEMBERS: not for use by machine-independent code. 648 */ 649 bus_size_t _dm_size; /* largest DMA transfer mappable */ 650 int _dm_segcnt; /* number of segs this map can map */ 651 bus_size_t _dm_maxsegsz; /* largest possible segment */ 652 bus_size_t _dm_boundary; /* don't cross this */ 653 int _dm_flags; /* misc. flags */ 654 655 void *_dm_cookie; /* cookie for bus-specific functions */ 656 657 /* 658 * PUBLIC MEMBERS: these are used by machine-independent code. 659 */ 660 bus_size_t dm_mapsize; /* size of the mapping */ 661 int dm_nsegs; /* # valid segments in mapping */ 662 bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 663 }; 664 665 int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 666 bus_size_t, int, bus_dmamap_t *); 667 void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t); 668 int _bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, 669 bus_size_t, struct proc *, int); 670 int _bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t, 671 struct mbuf *, int); 672 int _bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t, 673 struct uio *, int); 674 int _bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, 675 bus_dma_segment_t *, int, bus_size_t, int); 676 void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 677 void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 678 bus_size_t, int); 679 680 int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, 681 bus_size_t alignment, bus_size_t boundary, 682 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); 683 void _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, 684 int nsegs); 685 int _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, 686 int nsegs, size_t size, caddr_t *kvap, int flags); 687 void _bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva, 688 size_t size); 689 paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs, 690 int nsegs, off_t off, int prot, int flags); 691 692 int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size, 693 bus_size_t alignment, bus_size_t boundary, 694 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 695 bus_addr_t low, bus_addr_t high); 696 697 #endif /* _MACHINE_BUS_H_ */ 698