1 /* $OpenBSD: bus.h,v 1.52 2010/04/08 00:55:25 oga 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 _I386_BUS_H_ 67 #define _I386_BUS_H_ 68 69 #include <sys/mutex.h> 70 #include <sys/tree.h> 71 72 #include <machine/pio.h> 73 74 /* 75 * Values for the i386 bus space tag, not to be used directly by MI code. 76 */ 77 #define I386_BUS_SPACE_IO 0 /* space is i/o space */ 78 #define I386_BUS_SPACE_MEM 1 /* space is mem space */ 79 80 /* 81 * Bus address and size types 82 */ 83 typedef u_long bus_addr_t; 84 typedef u_long bus_size_t; 85 86 /* 87 * Access methods for bus resources and address space. 88 */ 89 typedef int bus_space_tag_t; 90 typedef u_long bus_space_handle_t; 91 92 int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 93 bus_size_t size, int flags, bus_space_handle_t *bshp); 94 /* like bus_space_map(), but without extent map checking/allocation */ 95 int _bus_space_map(bus_space_tag_t t, bus_addr_t addr, 96 bus_size_t size, int flags, bus_space_handle_t *bshp); 97 void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 98 bus_size_t size); 99 /* like bus_space_unmap(), but without extent map deallocation */ 100 void _bus_space_unmap(bus_space_tag_t, bus_space_handle_t, 101 bus_size_t, bus_addr_t *); 102 int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 103 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 104 105 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 106 bus_addr_t rend, bus_size_t size, bus_size_t align, 107 bus_size_t boundary, int flags, bus_addr_t *addrp, 108 bus_space_handle_t *bshp); 109 void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 110 bus_size_t size); 111 112 /* 113 * u_intN_t bus_space_read_N(bus_space_tag_t tag, 114 * bus_space_handle_t bsh, bus_size_t offset); 115 * 116 * Read a 1, 2, 4, or 8 byte quantity from bus space 117 * described by tag/handle/offset. 118 */ 119 u_int8_t bus_space_read_1(bus_space_tag_t, bus_space_handle_t, 120 bus_size_t); 121 122 u_int16_t bus_space_read_2(bus_space_tag_t, bus_space_handle_t, 123 bus_size_t); 124 125 u_int32_t bus_space_read_4(bus_space_tag_t, bus_space_handle_t, 126 bus_size_t); 127 128 #if 0 /* Cause a link error for bus_space_read_8 */ 129 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 130 #endif 131 132 #if 0 /* Cause a link error for bus_space_read_8 */ 133 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 134 #endif 135 136 /* 137 * void bus_space_read_multi_N(bus_space_tag_t tag, 138 * bus_space_handle_t bsh, bus_size_t offset, 139 * u_intN_t *addr, size_t count); 140 * 141 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 142 * described by tag/handle/offset and copy into buffer provided. 143 */ 144 145 #define bus_space_read_raw_multi_2(t, h, o, a, c) \ 146 bus_space_read_multi_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1) 147 #define bus_space_read_raw_multi_4(t, h, o, a, c) \ 148 bus_space_read_multi_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2) 149 150 void bus_space_read_multi_1(bus_space_tag_t, bus_space_handle_t, bus_size_t, 151 u_int8_t *, bus_size_t); 152 void bus_space_read_multi_2(bus_space_tag_t, bus_space_handle_t, bus_size_t, 153 u_int16_t *, bus_size_t); 154 void bus_space_read_multi_4(bus_space_tag_t, bus_space_handle_t, bus_size_t, 155 u_int32_t *, bus_size_t); 156 157 #if 0 /* Cause a link error for bus_space_read_multi_8 */ 158 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 159 #endif 160 161 /* 162 * void bus_space_read_raw_multi_N(bus_space_tag_t tag, 163 * bus_space_handle_t bsh, bus_size_t offset, 164 * u_int8_t *addr, size_t count); 165 * 166 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 167 * described by tag/handle/offset and copy into buffer provided. The buffer 168 * must have proper alignment for the N byte wide entities. Furthermore 169 * possible byte-swapping should be done by these functions. 170 */ 171 172 #define bus_space_read_raw_multi_2(t, h, o, a, c) \ 173 bus_space_read_multi_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1) 174 #define bus_space_read_raw_multi_4(t, h, o, a, c) \ 175 bus_space_read_multi_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2) 176 177 #if 0 /* Cause a link error for bus_space_read_raw_multi_8 */ 178 #define bus_space_read_raw_multi_8 \ 179 !!! bus_space_read_raw_multi_8 unimplemented !!! 180 #endif 181 182 /* 183 * void bus_space_read_region_N(bus_space_tag_t tag, 184 * bus_space_handle_t bsh, bus_size_t offset, 185 * u_intN_t *addr, size_t count); 186 * 187 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 188 * described by tag/handle and starting at `offset' and copy into 189 * buffer provided. 190 */ 191 192 void bus_space_read_region_1(bus_space_tag_t, bus_space_handle_t, 193 bus_size_t, u_int8_t *, bus_size_t); 194 void bus_space_read_region_2(bus_space_tag_t, bus_space_handle_t, 195 bus_size_t, u_int16_t *, bus_size_t); 196 void bus_space_read_region_4(bus_space_tag_t, bus_space_handle_t, 197 bus_size_t, u_int32_t *, bus_size_t); 198 199 #if 0 /* Cause a link error for bus_space_read_region_8 */ 200 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 201 #endif 202 203 /* 204 * void bus_space_read_raw_region_N(bus_space_tag_t tag, 205 * bus_space_handle_t bsh, bus_size_t offset, 206 * u_int8_t *addr, size_t count); 207 * 208 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 209 * described by tag/handle and starting at `offset' and copy into 210 * buffer provided. The buffer must have proper alignment for the N byte 211 * wide entities. Furthermore possible byte-swapping should be done by 212 * these functions. 213 */ 214 215 #define bus_space_read_raw_region_2(t, h, o, a, c) \ 216 bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1) 217 #define bus_space_read_raw_region_4(t, h, o, a, c) \ 218 bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2) 219 220 #if 0 /* Cause a link error for bus_space_read_raw_region_8 */ 221 #define bus_space_read_raw_region_8 \ 222 !!! bus_space_read_raw_region_8 unimplemented !!! 223 #endif 224 225 /* 226 * void bus_space_write_N(bus_space_tag_t tag, 227 * bus_space_handle_t bsh, bus_size_t offset, 228 * u_intN_t value); 229 * 230 * Write the 1, 2, 4, or 8 byte value `value' to bus space 231 * described by tag/handle/offset. 232 */ 233 234 void bus_space_write_1(bus_space_tag_t, bus_space_handle_t, 235 bus_size_t, u_int8_t); 236 void bus_space_write_2(bus_space_tag_t, bus_space_handle_t, 237 bus_size_t, u_int16_t); 238 void bus_space_write_4(bus_space_tag_t, bus_space_handle_t, 239 bus_size_t, u_int32_t); 240 241 #if 0 /* Cause a link error for bus_space_write_8 */ 242 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 243 #endif 244 245 /* 246 * void bus_space_write_multi_N(bus_space_tag_t tag, 247 * bus_space_handle_t bsh, bus_size_t offset, 248 * const u_intN_t *addr, size_t count); 249 * 250 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 251 * provided to bus space described by tag/handle/offset. 252 */ 253 254 void bus_space_write_multi_1(bus_space_tag_t, bus_space_handle_t, 255 bus_size_t, const u_int8_t *, bus_size_t); 256 void bus_space_write_multi_2(bus_space_tag_t, bus_space_handle_t, 257 bus_size_t, const u_int16_t *, bus_size_t); 258 void bus_space_write_multi_4(bus_space_tag_t, bus_space_handle_t, 259 bus_size_t, const u_int32_t *, bus_size_t); 260 261 #if 0 /* Cause a link error for bus_space_write_multi_8 */ 262 #define bus_space_write_multi_8(t, h, o, a, c) \ 263 !!! bus_space_write_multi_8 unimplemented !!! 264 #endif 265 266 /* 267 * void bus_space_write_raw_multi_N(bus_space_tag_t tag, 268 * bus_space_handle_t bsh, bus_size_t offset, 269 * const u_int8_t *addr, size_t count); 270 * 271 * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer 272 * provided to bus space described by tag/handle/offset. The buffer 273 * must have proper alignment for the N byte wide entities. Furthermore 274 * possible byte-swapping should be done by these functions. 275 */ 276 277 #define bus_space_write_raw_multi_2(t, h, o, a, c) \ 278 bus_space_write_multi_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1) 279 #define bus_space_write_raw_multi_4(t, h, o, a, c) \ 280 bus_space_write_multi_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2) 281 282 #if 0 /* Cause a link error for bus_space_write_raw_multi_8 */ 283 #define bus_space_write_raw_multi_8 \ 284 !!! bus_space_write_raw_multi_8 unimplemented !!! 285 #endif 286 287 /* 288 * void bus_space_write_region_N(bus_space_tag_t tag, 289 * bus_space_handle_t bsh, bus_size_t offset, 290 * const u_intN_t *addr, size_t count); 291 * 292 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 293 * to bus space described by tag/handle starting at `offset'. 294 */ 295 296 void bus_space_write_region_1(bus_space_tag_t, bus_space_handle_t, 297 bus_size_t, const u_int8_t *, bus_size_t); 298 void bus_space_write_region_2(bus_space_tag_t, bus_space_handle_t, 299 bus_size_t, const u_int16_t *, bus_size_t); 300 void bus_space_write_region_4(bus_space_tag_t, bus_space_handle_t, 301 bus_size_t, const u_int32_t *, bus_size_t); 302 303 #if 0 /* Cause a link error for bus_space_write_region_8 */ 304 #define bus_space_write_region_8 \ 305 !!! bus_space_write_region_8 unimplemented !!! 306 #endif 307 308 /* 309 * void bus_space_write_raw_region_N(bus_space_tag_t tag, 310 * bus_space_handle_t bsh, bus_size_t offset, 311 * const u_int8_t *addr, size_t count); 312 * 313 * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space 314 * described by tag/handle and starting at `offset' from the 315 * buffer provided. The buffer must have proper alignment for the N byte 316 * wide entities. Furthermore possible byte-swapping should be done by 317 * these functions. 318 */ 319 320 #define bus_space_write_raw_region_2(t, h, o, a, c) \ 321 bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1) 322 #define bus_space_write_raw_region_4(t, h, o, a, c) \ 323 bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2) 324 325 #if 0 /* Cause a link error for bus_space_write_raw_region_8 */ 326 #define bus_space_write_raw_region_8 \ 327 !!! bus_space_write_raw_region_8 unimplemented !!! 328 #endif 329 330 /* 331 * void bus_space_set_multi_N(bus_space_tag_t tag, 332 * bus_space_handle_t bsh, bus_size_t offset, 333 * u_intN_t val, size_t count); 334 * 335 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 336 * by tag/handle/offset `count' times. 337 */ 338 339 void bus_space_set_multi_1(bus_space_tag_t, bus_space_handle_t, 340 bus_size_t, u_int8_t, size_t); 341 void bus_space_set_multi_2(bus_space_tag_t, bus_space_handle_t, 342 bus_size_t, u_int16_t, size_t); 343 void bus_space_set_multi_4(bus_space_tag_t, bus_space_handle_t, 344 bus_size_t, u_int32_t, size_t); 345 346 #if 0 /* Cause a link error for bus_space_set_multi_8 */ 347 #define bus_space_set_multi_8 \ 348 !!! bus_space_set_multi_8 unimplemented !!! 349 #endif 350 351 /* 352 * void bus_space_set_region_N(bus_space_tag_t tag, 353 * bus_space_handle_t bsh, bus_size_t offset, 354 * u_intN_t val, size_t count); 355 * 356 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 357 * by tag/handle starting at `offset'. 358 */ 359 void bus_space_set_region_1(bus_space_tag_t, bus_space_handle_t, 360 bus_size_t, u_int8_t, size_t); 361 void bus_space_set_region_2(bus_space_tag_t, bus_space_handle_t, 362 bus_size_t, u_int16_t, size_t); 363 void bus_space_set_region_4(bus_space_tag_t, bus_space_handle_t, 364 bus_size_t, u_int32_t, size_t); 365 366 367 #if 0 /* Cause a link error for bus_space_set_region_8 */ 368 #define bus_space_set_region_8 \ 369 !!! bus_space_set_region_8 unimplemented !!! 370 #endif 371 372 /* 373 * void bus_space_copy_N(bus_space_tag_t tag, 374 * bus_space_handle_t bsh1, bus_size_t off1, 375 * bus_space_handle_t bsh2, bus_size_t off2, 376 * size_t count); 377 * 378 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 379 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 380 */ 381 382 void bus_space_copy_1(bus_space_tag_t, bus_space_handle_t, bus_size_t, 383 bus_space_handle_t, bus_size_t, bus_size_t); 384 void bus_space_copy_2(bus_space_tag_t, bus_space_handle_t, bus_size_t, 385 bus_space_handle_t, bus_size_t, bus_size_t); 386 void bus_space_copy_4(bus_space_tag_t, bus_space_handle_t, bus_size_t, 387 bus_space_handle_t, bus_size_t, bus_size_t); 388 389 #if 0 /* Cause a link error for bus_space_copy_8 */ 390 #define bus_space_copy_8 \ 391 !!! bus_space_copy_8 unimplemented !!! 392 #endif 393 394 #define i386_space_copy1(a1, a2, cnt, movs, df) \ 395 __asm __volatile(df "\n\trep\n\t" movs : \ 396 "+S" (a1), "+D" (a2), "+c" (cnt) :: "memory", "cc"); 397 398 #define i386_space_copy(a1, a2, sz, cnt) do { \ 399 if ((void *)(a1) < (void *)(a2)) { \ 400 a1 += ((cnt) - 1) * (sz); a2 += ((cnt) - 1) * (sz); \ 401 switch (sz) { \ 402 case 1: i386_space_copy1(a1,a2,cnt,"movsb","std");break;\ 403 case 2: i386_space_copy1(a1,a2,cnt,"movsw","std");break;\ 404 case 4: i386_space_copy1(a1,a2,cnt,"movsl","std");break;\ 405 } \ 406 } else \ 407 switch (sz) { \ 408 case 1: i386_space_copy1(a1,a2,cnt,"movsb","cld");break;\ 409 case 2: i386_space_copy1(a1,a2,cnt,"movsw","cld");break;\ 410 case 4: i386_space_copy1(a1,a2,cnt,"movsl","cld");break;\ 411 } \ 412 } while (0) 413 414 /* 415 * Bus read/write barrier methods. 416 * 417 * void bus_space_barrier(bus_space_tag_t tag, 418 * bus_space_handle_t bsh, bus_size_t offset, 419 * bus_size_t len, int flags); 420 * 421 * Note: the i386 does not currently require barriers, but we must 422 * provide the flags to MI code. 423 */ 424 #define bus_space_barrier(t, h, o, l, f) \ 425 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 426 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 427 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 428 429 #define BUS_SPACE_MAP_CACHEABLE 0x0001 430 #define BUS_SPACE_MAP_LINEAR 0x0002 431 #define BUS_SPACE_MAP_PREFETCHABLE 0x0008 432 433 /* 434 * void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t); 435 * 436 * Get the kernel virtual address for the mapped bus space. 437 * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR. 438 */ 439 #define bus_space_vaddr(t, h) \ 440 ((t) == I386_BUS_SPACE_IO ? (void *)(NULL) : (void *)(h)) 441 442 /* 443 * Flags used in various bus DMA methods. 444 */ 445 #define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */ 446 #define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */ 447 #define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */ 448 #define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */ 449 #define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */ 450 #define BUS_DMA_BUS2 0x0020 451 #define BUS_DMA_BUS3 0x0040 452 #define BUS_DMA_24BIT 0x0080 /* isadma map */ 453 #define BUS_DMA_STREAMING 0x0100 /* hint: sequential, unidirectional */ 454 #define BUS_DMA_READ 0x0200 /* mapping is device -> memory only */ 455 #define BUS_DMA_WRITE 0x0400 /* mapping is memory -> device only */ 456 #define BUS_DMA_NOCACHE 0x0800 /* map memory uncached */ 457 #define BUS_DMA_ZERO 0x1000 /* dmamem_alloc return zeroed mem */ 458 #define BUS_DMA_SG 0x2000 /* Internal. memory is for SG map */ 459 460 /* types for _dm_buftype */ 461 #define BUS_BUFTYPE_INVALID 0 462 #define BUS_BUFTYPE_LINEAR 1 463 #define BUS_BUFTYPE_MBUF 2 464 #define BUS_BUFTYPE_UIO 3 465 #define BUS_BUFTYPE_RAW 4 466 467 /* Forwards needed by prototypes below. */ 468 struct mbuf; 469 struct proc; 470 struct uio; 471 472 /* 473 * Operations performed by bus_dmamap_sync(). 474 */ 475 #define BUS_DMASYNC_PREREAD 0x01 476 #define BUS_DMASYNC_POSTREAD 0x02 477 #define BUS_DMASYNC_PREWRITE 0x04 478 #define BUS_DMASYNC_POSTWRITE 0x08 479 480 typedef struct bus_dma_tag *bus_dma_tag_t; 481 typedef struct bus_dmamap *bus_dmamap_t; 482 483 /* 484 * bus_dma_segment_t 485 * 486 * Describes a single contiguous DMA transaction. Values 487 * are suitable for programming into DMA registers. 488 */ 489 struct bus_dma_segment { 490 bus_addr_t ds_addr; /* DMA address */ 491 bus_size_t ds_len; /* length of transfer */ 492 /* 493 * Ugh. need this so can pass alignment down from bus_dmamem_alloc 494 * to scatter gather maps. only the first one is used so the rest is 495 * wasted space. bus_dma could do with fixing the api for this. 496 */ 497 bus_size_t _ds_boundary; /* don't cross */ 498 bus_size_t _ds_align; /* align to me */ 499 }; 500 typedef struct bus_dma_segment bus_dma_segment_t; 501 502 /* 503 * bus_dma_tag_t 504 * 505 * A machine-dependent opaque type describing the implementation of 506 * DMA for a given bus. 507 */ 508 509 struct bus_dma_tag { 510 void *_cookie; /* cookie used in the guts */ 511 512 /* 513 * DMA mapping methods. 514 */ 515 int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int, 516 bus_size_t, bus_size_t, int, bus_dmamap_t *); 517 void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t); 518 int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *, 519 bus_size_t, struct proc *, int); 520 int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t, 521 struct mbuf *, int); 522 int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, 523 struct uio *, int); 524 int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t, 525 bus_dma_segment_t *, int, bus_size_t, int); 526 void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t); 527 void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t, 528 bus_addr_t, bus_size_t, int); 529 530 /* 531 * DMA memory utility functions. 532 */ 533 int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t, 534 bus_size_t, bus_dma_segment_t *, int, int *, int); 535 void (*_dmamem_free)(bus_dma_tag_t, 536 bus_dma_segment_t *, int); 537 int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *, 538 int, size_t, caddr_t *, int); 539 void (*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t); 540 paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *, 541 int, off_t, int, int); 542 }; 543 544 #define bus_dmamap_create(t, s, n, m, b, f, p) \ 545 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 546 #define bus_dmamap_destroy(t, p) \ 547 (*(t)->_dmamap_destroy)((t), (p)) 548 #define bus_dmamap_load(t, m, b, s, p, f) \ 549 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 550 #define bus_dmamap_load_mbuf(t, m, b, f) \ 551 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 552 #define bus_dmamap_load_uio(t, m, u, f) \ 553 (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 554 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 555 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 556 #define bus_dmamap_unload(t, p) \ 557 (*(t)->_dmamap_unload)((t), (p)) 558 #define bus_dmamap_sync(t, p, o, l, ops) \ 559 (void)((t)->_dmamap_sync ? \ 560 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0) 561 562 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 563 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 564 #define bus_dmamem_free(t, sg, n) \ 565 (*(t)->_dmamem_free)((t), (sg), (n)) 566 #define bus_dmamem_map(t, sg, n, s, k, f) \ 567 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 568 #define bus_dmamem_unmap(t, k, s) \ 569 (*(t)->_dmamem_unmap)((t), (k), (s)) 570 #define bus_dmamem_mmap(t, sg, n, o, p, f) \ 571 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 572 573 /* 574 * bus_dmamap_t 575 * 576 * Describes a DMA mapping. 577 */ 578 struct bus_dmamap { 579 /* 580 * PRIVATE MEMBERS: not for use by machine-independent code. 581 */ 582 bus_size_t _dm_size; /* largest DMA transfer mappable */ 583 int _dm_segcnt; /* number of segs this map can map */ 584 bus_size_t _dm_maxsegsz; /* largest possible segment */ 585 bus_size_t _dm_boundary; /* don't cross this */ 586 int _dm_flags; /* misc. flags */ 587 588 void *_dm_cookie; /* cookie for bus-specific functions */ 589 590 /* 591 * PUBLIC MEMBERS: these are used by machine-independent code. 592 */ 593 bus_size_t dm_mapsize; /* size of the mapping */ 594 int dm_nsegs; /* # valid segments in mapping */ 595 bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 596 }; 597 598 int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 599 bus_size_t, int, bus_dmamap_t *); 600 void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t); 601 int _bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, 602 bus_size_t, struct proc *, int); 603 int _bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t, 604 struct mbuf *, int); 605 int _bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t, 606 struct uio *, int); 607 int _bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, 608 bus_dma_segment_t *, int, bus_size_t, int); 609 void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 610 void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 611 bus_size_t, int); 612 613 int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, 614 bus_size_t alignment, bus_size_t boundary, 615 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); 616 void _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, 617 int nsegs); 618 int _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, 619 int nsegs, size_t size, caddr_t *kvap, int flags); 620 void _bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva, 621 size_t size); 622 paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs, 623 int nsegs, off_t off, int prot, int flags); 624 625 int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size, 626 bus_size_t alignment, bus_size_t boundary, 627 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 628 paddr_t low, paddr_t high); 629 630 struct extent; 631 632 /* Scatter gather bus_dma functions. */ 633 struct sg_cookie { 634 struct mutex sg_mtx; 635 struct extent *sg_ex; 636 void *sg_hdl; 637 void (*bind_page)(void *, bus_addr_t, paddr_t, int); 638 void (*unbind_page)(void *, bus_addr_t); 639 void (*flush_tlb)(void *); 640 }; 641 642 /* 643 * per-map DVMA page table 644 */ 645 struct sg_page_entry { 646 SPLAY_ENTRY(sg_page_entry) spe_node; 647 paddr_t spe_pa; 648 bus_addr_t spe_va; 649 }; 650 651 /* for sg_dma this will be in the map's dm_cookie. */ 652 struct sg_page_map { 653 SPLAY_HEAD(sg_page_tree, sg_page_entry) spm_tree; 654 655 void *spm_origbuf; /* pointer to original data */ 656 int spm_buftype; /* type of data */ 657 struct proc *spm_proc; /* proc that owns the mapping */ 658 659 int spm_maxpage; /* Size of allocated page map */ 660 int spm_pagecnt; /* Number of entries in use */ 661 bus_addr_t spm_start; /* dva when bound */ 662 bus_size_t spm_size; /* size of bound map */ 663 struct sg_page_entry spm_map[1]; 664 }; 665 666 struct sg_cookie *sg_dmatag_init(char *, void *, bus_addr_t, bus_size_t, 667 void (*)(void *, vaddr_t, paddr_t, int), 668 void (*)(void *, vaddr_t), void (*)(void *)); 669 void sg_dmatag_destroy(struct sg_cookie *); 670 int sg_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 671 bus_size_t, int, bus_dmamap_t *); 672 void sg_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t); 673 void sg_dmamap_set_alignment(bus_dma_tag_t, bus_dmamap_t, u_long); 674 int sg_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, 675 struct proc *, int); 676 int sg_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t, 677 struct mbuf *, int); 678 int sg_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t, struct uio *, int); 679 int sg_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, bus_dma_segment_t *, 680 int, bus_size_t, int); 681 void sg_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 682 int sg_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, 683 struct proc *, int, int *, int); 684 int sg_dmamap_load_physarray(bus_dma_tag_t, bus_dmamap_t, paddr_t *, 685 int, int, int *, int); 686 int sg_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t, 687 bus_dma_segment_t *, int, int *, int); 688 689 690 #endif /* _I386_BUS_H_ */ 691