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