1 /* $NetBSD: bus.h,v 1.25 2012/10/13 06:44:24 tsutsui Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * bus_space(9) and bus_dma(9) interface for NetBSD/x68k. 35 */ 36 37 #ifndef _X68K_BUS_H_ 38 #define _X68K_BUS_H_ 39 40 /* 41 * Bus address and size types 42 */ 43 typedef u_long bus_addr_t; 44 typedef u_long bus_size_t; 45 typedef u_long bus_space_handle_t; 46 47 /* 48 * Bus space descripter 49 */ 50 typedef struct x68k_bus_space *bus_space_tag_t; 51 52 struct x68k_bus_space { 53 #if 0 54 enum { 55 X68K_INTIO_BUS, 56 X68K_PCI_BUS, 57 X68K_NEPTUNE_BUS 58 } x68k_bus_type; 59 #endif 60 61 int (*x68k_bus_space_map)( 62 bus_space_tag_t, 63 bus_addr_t, 64 bus_size_t, 65 int, /* flags */ 66 bus_space_handle_t *); 67 void (*x68k_bus_space_unmap)( 68 bus_space_tag_t, 69 bus_space_handle_t, 70 bus_size_t); 71 int (*x68k_bus_space_subregion)( 72 bus_space_tag_t, 73 bus_space_handle_t, 74 bus_size_t, /* offset */ 75 bus_size_t, /* size */ 76 bus_space_handle_t *); 77 78 int (*x68k_bus_space_alloc)( 79 bus_space_tag_t, 80 bus_addr_t, /* reg_start */ 81 bus_addr_t, /* reg_end */ 82 bus_size_t, 83 bus_size_t, /* alignment */ 84 bus_size_t, /* boundary */ 85 int, /* flags */ 86 bus_addr_t *, 87 bus_space_handle_t *); 88 void (*x68k_bus_space_free)( 89 bus_space_tag_t, 90 bus_space_handle_t, 91 bus_size_t); 92 93 #if 0 94 void (*x68k_bus_space_barrier)( 95 bus_space_tag_t, 96 bus_space_handle_t, 97 bus_size_t, /* offset */ 98 bus_size_t, /* length */ 99 int); /* flags */ 100 #endif 101 102 device_t x68k_bus_device; 103 }; 104 105 int x68k_bus_space_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t, 106 bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *); 107 void x68k_bus_space_free(bus_space_tag_t, bus_space_handle_t, bus_size_t); 108 109 /* 110 * bus_space(9) interface 111 */ 112 113 #define bus_space_map(t, a, s, f, h) \ 114 ((*((t)->x68k_bus_space_map)) ((t), (a), (s), (f), (h))) 115 #define bus_space_unmap(t, h, s) \ 116 ((*((t)->x68k_bus_space_unmap)) ((t), (h), (s))) 117 #define bus_space_subregion(t, h, o, s, p) \ 118 ((*((t)->x68k_bus_space_subregion)) ((t), (h), (o), (s), (p))) 119 #define BUS_SPACE_MAP_CACHEABLE 0x0001 120 #define BUS_SPACE_MAP_LINEAR 0x0002 121 #define BUS_SPACE_MAP_PREFETCHABLE 0x0004 122 /* 123 * For simpler hardware, many x68k devices are mapped with shifted address 124 * i.e. only on even or odd addresses. 125 */ 126 #define BUS_SPACE_MAP_SHIFTED_MASK 0x1001 127 #define BUS_SPACE_MAP_SHIFTED_ODD 0x1001 128 #define BUS_SPACE_MAP_SHIFTED_EVEN 0x1000 129 #define BUS_SPACE_MAP_SHIFTED BUS_SPACE_MAP_SHIFTED_ODD 130 131 #define bus_space_alloc(t, rs, re, s, a, b, f, r, h) \ 132 ((*((t)->x68k_bus_space_alloc)) ((t), \ 133 (rs), (re), (s), (a), (b), (f), (r), (h))) 134 #define bus_space_free(t, h, s) \ 135 ((*((t)->x68k_bus_space_free)) ((t), (h), (s))) 136 137 /* 138 * Note: the 680x0 does not currently require barriers, but we must 139 * provide the flags to MI code. 140 */ 141 #define bus_space_barrier(t, h, o, l, f) \ 142 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 143 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 144 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 145 146 #define bus_space_read_1(t,h,o) _bus_space_read_1(t,h,o) 147 #define bus_space_read_2(t,h,o) _bus_space_read_2(t,h,o) 148 #define bus_space_read_4(t,h,o) _bus_space_read_4(t,h,o) 149 150 #define bus_space_read_multi_1(t,h,o,p,c) _bus_space_read_multi_1(t,h,o,p,c) 151 #define bus_space_read_multi_2(t,h,o,p,c) _bus_space_read_multi_2(t,h,o,p,c) 152 #define bus_space_read_multi_4(t,h,o,p,c) _bus_space_read_multi_4(t,h,o,p,c) 153 154 #define bus_space_read_region_1(t,h,o,p,c) _bus_space_read_region_1(t,h,o,p,c) 155 #define bus_space_read_region_2(t,h,o,p,c) _bus_space_read_region_2(t,h,o,p,c) 156 #define bus_space_read_region_4(t,h,o,p,c) _bus_space_read_region_4(t,h,o,p,c) 157 158 #define bus_space_write_1(t,h,o,v) _bus_space_write_1(t,h,o,v) 159 #define bus_space_write_2(t,h,o,v) _bus_space_write_2(t,h,o,v) 160 #define bus_space_write_4(t,h,o,v) _bus_space_write_4(t,h,o,v) 161 162 #define bus_space_write_multi_1(t,h,o,p,c) _bus_space_write_multi_1(t,h,o,p,c) 163 #define bus_space_write_multi_2(t,h,o,p,c) _bus_space_write_multi_2(t,h,o,p,c) 164 #define bus_space_write_multi_4(t,h,o,p,c) _bus_space_write_multi_4(t,h,o,p,c) 165 166 #define bus_space_write_region_1(t,h,o,p,c) \ 167 _bus_space_write_region_1(t,h,o,p,c) 168 #define bus_space_write_region_2(t,h,o,p,c) \ 169 _bus_space_write_region_2(t,h,o,p,c) 170 #define bus_space_write_region_4(t,h,o,p,c) \ 171 _bus_space_write_region_4(t,h,o,p,c) 172 173 #define bus_space_set_region_1(t,h,o,v,c) _bus_space_set_region_1(t,h,o,v,c) 174 #define bus_space_set_region_2(t,h,o,v,c) _bus_space_set_region_2(t,h,o,v,c) 175 #define bus_space_set_region_4(t,h,o,v,c) _bus_space_set_region_4(t,h,o,v,c) 176 177 #define bus_space_copy_region_1(t,sh,so,dh,do,c) \ 178 _bus_space_copy_region_1(t,sh,so,dh,do,c) 179 #define bus_space_copy_region_2(t,sh,so,dh,do,c) \ 180 _bus_space_copy_region_2(t,sh,so,dh,do,c) 181 #define bus_space_copy_region_4(t,sh,so,dh,do,c) \ 182 _bus_space_copy_region_4(t,sh,so,dh,do,c) 183 184 static __inline uint8_t _bus_space_read_1 185 (bus_space_tag_t, bus_space_handle_t bsh, bus_size_t offset); 186 static __inline uint16_t _bus_space_read_2 187 (bus_space_tag_t, bus_space_handle_t, bus_size_t); 188 static __inline uint32_t _bus_space_read_4 189 (bus_space_tag_t, bus_space_handle_t, bus_size_t); 190 191 static __inline void _bus_space_read_multi_1 192 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 193 uint8_t *, bus_size_t); 194 static __inline void _bus_space_read_multi_2 195 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 196 uint16_t *, bus_size_t); 197 static __inline void _bus_space_read_multi_4 198 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 199 uint32_t *, bus_size_t); 200 201 static __inline void _bus_space_read_region_1 202 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 203 uint8_t *, bus_size_t); 204 static __inline void _bus_space_read_region_2 205 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 206 uint16_t *, bus_size_t); 207 static __inline void _bus_space_read_region_4 208 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 209 uint32_t *, bus_size_t); 210 211 static __inline void _bus_space_write_1 212 (bus_space_tag_t, bus_space_handle_t, bus_size_t, uint8_t); 213 static __inline void _bus_space_write_2 214 (bus_space_tag_t, bus_space_handle_t, bus_size_t, uint16_t); 215 static __inline void _bus_space_write_4 216 (bus_space_tag_t, bus_space_handle_t, bus_size_t, uint32_t); 217 218 static __inline void _bus_space_write_multi_1 219 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 220 const uint8_t *, bus_size_t); 221 static __inline void _bus_space_write_multi_2 222 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 223 const uint16_t *, bus_size_t); 224 static __inline void _bus_space_write_multi_4 225 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 226 const uint32_t *, bus_size_t); 227 228 static __inline void _bus_space_write_region_1 229 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 230 const uint8_t *, bus_size_t); 231 static __inline void _bus_space_write_region_2 232 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 233 const uint16_t *, bus_size_t); 234 static __inline void _bus_space_write_region_4 235 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 236 const uint32_t *, bus_size_t); 237 238 static __inline void _bus_space_set_region_1 239 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 240 uint8_t, bus_size_t); 241 static __inline void _bus_space_set_region_2 242 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 243 uint16_t, bus_size_t); 244 static __inline void _bus_space_set_region_4 245 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 246 uint32_t, bus_size_t); 247 248 static __inline void _bus_space_copy_region_1 249 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 250 bus_space_handle_t, bus_size_t, bus_size_t); 251 static __inline void _bus_space_copy_region_2 252 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 253 bus_space_handle_t, bus_size_t, bus_size_t); 254 static __inline void _bus_space_copy_region_4 255 (bus_space_tag_t, bus_space_handle_t, bus_size_t, 256 bus_space_handle_t, bus_size_t, bus_size_t); 257 258 259 #define __X68K_BUS_ADDR(tag, handle, offset) \ 260 (((long)(handle) < 0 ? (offset) * 2 : (offset)) \ 261 + ((handle) & 0x7fffffff)) 262 263 static __inline uint8_t 264 _bus_space_read_1(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset) 265 { 266 267 return *((volatile uint8_t *) __X68K_BUS_ADDR(t, bsh, offset)); 268 } 269 270 static __inline uint16_t 271 _bus_space_read_2(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset) 272 { 273 274 return *((volatile uint16_t *) __X68K_BUS_ADDR(t, bsh, offset)); 275 } 276 277 static __inline uint32_t 278 _bus_space_read_4(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset) 279 { 280 281 return *((volatile uint32_t *) __X68K_BUS_ADDR(t, bsh, offset)); 282 } 283 284 static __inline void 285 _bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t bsh, 286 bus_size_t offset, uint8_t *datap, bus_size_t count) 287 { 288 volatile uint8_t *regadr; 289 290 regadr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset); 291 292 for (; count; count--) 293 *datap++ = *regadr; 294 } 295 296 static __inline void 297 _bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t bsh, 298 bus_size_t offset, uint16_t *datap, bus_size_t count) 299 { 300 volatile uint16_t *regadr; 301 302 regadr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset); 303 304 for (; count; count--) 305 *datap++ = *regadr; 306 } 307 308 static __inline void 309 _bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t bsh, 310 bus_size_t offset, uint32_t *datap, bus_size_t count) 311 { 312 volatile uint32_t *regadr; 313 314 regadr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset); 315 316 for (; count; count--) 317 *datap++ = *regadr; 318 } 319 320 static __inline void 321 _bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t bsh, 322 bus_size_t offset, uint8_t *datap, bus_size_t count) 323 { 324 volatile uint8_t *addr; 325 326 addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset); 327 328 for (; count; count--) 329 *datap++ = *addr++; 330 } 331 332 static __inline void 333 _bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t bsh, 334 bus_size_t offset, uint16_t *datap, bus_size_t count) 335 { 336 volatile uint16_t *addr; 337 338 addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset); 339 340 for (; count; count--) 341 *datap++ = *addr++; 342 } 343 344 static __inline void 345 _bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t bsh, 346 bus_size_t offset, uint32_t *datap, bus_size_t count) 347 { 348 volatile uint32_t *addr; 349 350 addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset); 351 352 for (; count; count--) 353 *datap++ = *addr++; 354 } 355 356 static __inline void 357 _bus_space_write_1(bus_space_tag_t t, bus_space_handle_t bsh, 358 bus_size_t offset, uint8_t value) 359 { 360 361 *(volatile uint8_t *) __X68K_BUS_ADDR(t, bsh, offset) = value; 362 } 363 364 static __inline void 365 _bus_space_write_2(bus_space_tag_t t, bus_space_handle_t bsh, 366 bus_size_t offset, uint16_t value) 367 { 368 369 *(volatile uint16_t *) __X68K_BUS_ADDR(t, bsh, offset) = value; 370 } 371 372 static __inline void 373 _bus_space_write_4(bus_space_tag_t t, bus_space_handle_t bsh, 374 bus_size_t offset, uint32_t value) 375 { 376 377 *(volatile uint32_t *) __X68K_BUS_ADDR(t, bsh, offset) = value; 378 } 379 380 static __inline void 381 _bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t bsh, 382 bus_size_t offset, const uint8_t *datap, bus_size_t count) 383 { 384 volatile uint8_t *regadr; 385 386 regadr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset); 387 388 for (; count; count--) 389 *regadr = *datap++; 390 } 391 392 static __inline void 393 _bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t bsh, 394 bus_size_t offset, const uint16_t *datap, bus_size_t count) 395 { 396 volatile uint16_t *regadr; 397 398 regadr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset); 399 400 for (; count; count--) 401 *regadr = *datap++; 402 } 403 404 static __inline void 405 _bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t bsh, 406 bus_size_t offset, const uint32_t *datap, bus_size_t count) 407 { 408 volatile uint32_t *regadr; 409 410 regadr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset); 411 412 for (; count; count--) 413 *regadr = *datap++; 414 } 415 416 static __inline void 417 _bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t bsh, 418 bus_size_t offset, const uint8_t *datap, bus_size_t count) 419 { 420 volatile uint8_t *addr; 421 422 addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset); 423 424 for (; count; count--) 425 *addr++ = *datap++; 426 } 427 428 static __inline void 429 _bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t bsh, 430 bus_size_t offset, const uint16_t *datap, bus_size_t count) 431 { 432 volatile uint16_t *addr; 433 434 addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset); 435 436 for (; count; count--) 437 *addr++ = *datap++; 438 } 439 440 static __inline void 441 _bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t bsh, 442 bus_size_t offset, const uint32_t *datap, bus_size_t count) 443 { 444 volatile uint32_t *addr; 445 446 addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset); 447 448 for (; count; count--) 449 *addr++ = *datap++; 450 } 451 452 static __inline void 453 _bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t bsh, 454 bus_size_t offset, uint8_t value, bus_size_t count) 455 { 456 volatile uint8_t *addr; 457 458 addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset); 459 460 for (; count; count--) 461 *addr++ = value; 462 } 463 464 static __inline void 465 _bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t bsh, 466 bus_size_t offset, uint16_t value, bus_size_t count) 467 { 468 volatile uint16_t *addr; 469 470 addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset); 471 472 for (; count; count--) 473 *addr++ = value; 474 } 475 476 static __inline void 477 _bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t bsh, 478 bus_size_t offset, uint32_t value, bus_size_t count) 479 { 480 volatile uint32_t *addr; 481 482 addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset); 483 484 for (; count; count--) 485 *addr++ = value; 486 } 487 488 static __inline void 489 _bus_space_copy_region_1(bus_space_tag_t t, 490 bus_space_handle_t sbsh, bus_size_t soffset, 491 bus_space_handle_t dbsh, bus_size_t doffset, 492 bus_size_t count) 493 { 494 volatile uint8_t *saddr = (void *) (sbsh + soffset); 495 volatile uint8_t *daddr = (void *) (dbsh + doffset); 496 497 if ((uint32_t) saddr >= (uint32_t) daddr) 498 while (count-- > 0) 499 *daddr++ = *saddr++; 500 else { 501 saddr += count; 502 daddr += count; 503 while (count-- > 0) 504 *--daddr = *--saddr; 505 } 506 } 507 508 static __inline void 509 _bus_space_copy_region_2(bus_space_tag_t t, 510 bus_space_handle_t sbsh, bus_size_t soffset, 511 bus_space_handle_t dbsh, bus_size_t doffset, 512 bus_size_t count) 513 { 514 volatile uint16_t *saddr = (void *) (sbsh + soffset); 515 volatile uint16_t *daddr = (void *) (dbsh + doffset); 516 517 if ((uint32_t) saddr >= (uint32_t) daddr) 518 while (count-- > 0) 519 *daddr++ = *saddr++; 520 else { 521 saddr += count; 522 daddr += count; 523 while (count-- > 0) 524 *--daddr = *--saddr; 525 } 526 } 527 528 static __inline void 529 _bus_space_copy_region_4(bus_space_tag_t t, 530 bus_space_handle_t sbsh, bus_size_t soffset, 531 bus_space_handle_t dbsh, bus_size_t doffset, 532 bus_size_t count) 533 { 534 volatile uint32_t *saddr = (void *) (sbsh + soffset); 535 volatile uint32_t *daddr = (void *) (dbsh + doffset); 536 537 if ((uint32_t) saddr >= (uint32_t) daddr) 538 while (count-- > 0) 539 *daddr++ = *saddr++; 540 else { 541 saddr += count; 542 daddr += count; 543 while (count-- > 0) 544 *--daddr = *--saddr; 545 } 546 } 547 548 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 549 550 /* 551 * DMA segment 552 */ 553 struct x68k_bus_dma_segment { 554 bus_addr_t ds_addr; 555 bus_size_t ds_len; 556 }; 557 typedef struct x68k_bus_dma_segment bus_dma_segment_t; 558 559 /* 560 * DMA descriptor 561 */ 562 /* Forwards needed by prototypes below. */ 563 struct mbuf; 564 struct uio; 565 566 typedef struct x68k_bus_dma *bus_dma_tag_t; 567 typedef struct x68k_bus_dmamap *bus_dmamap_t; 568 569 #define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0) 570 571 struct x68k_bus_dma { 572 /* 573 * The `bounce threshold' is checked while we are loading 574 * the DMA map. If the physical address of the segment 575 * exceeds the threshold, an error will be returned. The 576 * caller can then take whatever action is necessary to 577 * bounce the transfer. If this value is 0, it will be 578 * ignored. 579 */ 580 bus_addr_t _bounce_thresh; 581 582 /* 583 * DMA mapping methods. 584 */ 585 int (*x68k_dmamap_create)(bus_dma_tag_t, bus_size_t, int, 586 bus_size_t, bus_size_t, int, bus_dmamap_t *); 587 void (*x68k_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t); 588 int (*x68k_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *, 589 bus_size_t, struct proc *, int); 590 int (*x68k_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t, 591 struct mbuf *, int); 592 int (*x68k_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, 593 struct uio *, int); 594 int (*x68k_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t, 595 bus_dma_segment_t *, int, bus_size_t, int); 596 void (*x68k_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t); 597 void (*x68k_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t, 598 bus_addr_t, bus_size_t, int); 599 600 /* 601 * DMA memory utility functions. 602 */ 603 int (*x68k_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t, 604 bus_size_t, bus_dma_segment_t *, int, int *, int); 605 void (*x68k_dmamem_free)(bus_dma_tag_t, 606 bus_dma_segment_t *, int); 607 int (*x68k_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *, 608 int, size_t, void **, int); 609 void (*x68k_dmamem_unmap)(bus_dma_tag_t, void *, size_t); 610 paddr_t (*x68k_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *, 611 int, off_t, int, int); 612 }; 613 614 /* 615 * bus_dmamap_t 616 * 617 * Describes a DMA mapping. 618 */ 619 struct x68k_bus_dmamap { 620 /* 621 * PRIVATE MEMBERS: not for use my machine-independent code. 622 */ 623 bus_size_t x68k_dm_size; /* largest DMA transfer mappable */ 624 int x68k_dm_segcnt; /* number of segs this map can map */ 625 bus_size_t x68k_dm_maxmaxsegsz; /* fixed largest possible segment*/ 626 bus_size_t x68k_dm_boundary; /* don't cross this */ 627 bus_addr_t x68k_dm_bounce_thresh; /* bounce threshold */ 628 int x68k_dm_flags; /* misc. flags */ 629 630 void *x68k_dm_cookie; /* cookie for bus-specific functions */ 631 632 /* 633 * PUBLIC MEMBERS: these are used by machine-independent code. 634 */ 635 bus_size_t dm_maxsegsz; /* largest possible segment */ 636 bus_size_t dm_mapsize; /* size of the mapping */ 637 int dm_nsegs; /* # valid segments in mapping */ 638 bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 639 }; 640 641 int x68k_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 642 bus_size_t, int, bus_dmamap_t *); 643 void x68k_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t); 644 int x68k_bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, 645 bus_size_t, struct proc *, int); 646 int x68k_bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t, 647 struct mbuf *, int); 648 int x68k_bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t, 649 struct uio *, int); 650 int x68k_bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, 651 bus_dma_segment_t *, int, bus_size_t, int); 652 void x68k_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 653 void x68k_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 654 bus_size_t, int); 655 656 int x68k_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, 657 bus_size_t alignment, bus_size_t boundary, 658 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); 659 void x68k_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, 660 int nsegs); 661 int x68k_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, 662 int nsegs, size_t size, void **kvap, int flags); 663 void x68k_bus_dmamem_unmap(bus_dma_tag_t tag, void *kva, 664 size_t size); 665 paddr_t x68k_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs, 666 int nsegs, off_t off, int prot, int flags); 667 668 int x68k_bus_dmamap_load_buffer(bus_dmamap_t, void *, 669 bus_size_t buflen, struct proc *, int, paddr_t *, int *, int); 670 int x68k_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size, 671 bus_size_t alignment, bus_size_t boundary, 672 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 673 paddr_t low, paddr_t high); 674 675 #define bus_dmamap_create(t,s,n,m,b,f,p) \ 676 ((*((t)->x68k_dmamap_create)) ((t),(s),(n),(m),(b),(f),(p))) 677 #define bus_dmamap_destroy(t,p) \ 678 ((*((t)->x68k_dmamap_destroy)) ((t),(p))) 679 #define bus_dmamap_load(t,m,b,s,p,f) \ 680 ((*((t)->x68k_dmamap_load)) ((t),(m),(b),(s),(p),(f))) 681 #define bus_dmamap_load_mbuf(t,m,b,f) \ 682 ((*((t)->x68k_dmamap_load_mbuf)) ((t),(m),(b),(f))) 683 #define bus_dmamap_load_uio(t,m,u,f) \ 684 ((*((t)->x68k_dmamap_load_uio)) ((t),(m),(u),(f))) 685 #define bus_dmamap_load_raw(t,m,sg,n,s,f) \ 686 ((*((t)->x68k_dmamap_load_raw)) ((t),(m),(sg),(n),(s),(f))) 687 #define bus_dmamap_unload(t,p) \ 688 ((*((t)->x68k_dmamap_unload)) ((t),(p))) 689 #define bus_dmamap_sync(t,p,o,l,ops) \ 690 ((*((t)->x68k_dmamap_sync)) ((t),(p),(o),(l),(ops))) 691 692 #define bus_dmamem_alloc(t,s,a,b,sg,n,r,f) \ 693 ((*((t)->x68k_dmamem_alloc)) ((t),(s),(a),(b),(sg),(n),(r),(f))) 694 #define bus_dmamem_free(t,sg,n) \ 695 ((*((t)->x68k_dmamem_free)) ((t),(sg),(n))) 696 #define bus_dmamem_map(t,sg,n,s,k,f) \ 697 ((*((t)->x68k_dmamem_map)) ((t),(sg),(n),(s),(k),(f))) 698 #define bus_dmamem_unmap(t,k,s) \ 699 ((*((t)->x68k_dmamem_unmap)) ((t),(k),(s))) 700 #define bus_dmamem_mmap(t,sg,n,o,p,f) \ 701 ((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f))) 702 703 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP 704 #define bus_dmatag_destroy(t) 705 706 /* 707 * Flags used in various bus DMA methods. 708 */ 709 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */ 710 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */ 711 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */ 712 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */ 713 #define BUS_DMA_STREAMING 0x008 /* hint: sequential, unidirectional */ 714 #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */ 715 #define BUS_DMA_BUS2 0x020 716 #define BUS_DMA_BUS3 0x040 717 #define BUS_DMA_BUS4 0x080 718 #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */ 719 #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */ 720 #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */ 721 722 /* 723 * Operations performed by bus_dmamap_sync(). 724 */ 725 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ 726 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ 727 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ 728 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ 729 730 #endif /* _X68K_BUS_H_ */ 731