1 /*- 2 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 7 * NASA Ames Research Center. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the NetBSD 20 * Foundation, Inc. and its contributors. 21 * 4. Neither the name of The NetBSD Foundation nor the names of its 22 * contributors may be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 40 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by Christopher G. Demetriou 53 * for the NetBSD Project. 54 * 4. The name of the author may not be used to endorse or promote products 55 * derived from this software without specific prior written permission 56 * 57 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 58 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 59 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 60 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 61 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 62 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 63 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 64 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 65 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 66 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 67 * 68 * $NetBSD: bus.h,v 1.9.4.1 2000/06/30 16:27:30 simonb Exp $ 69 * $FreeBSD$ 70 */ 71 72 #ifndef _MACPPC_BUS_H_ 73 #define _MACPPC_BUS_H_ 74 75 #include <machine/pio.h> 76 77 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF 78 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF 79 #define BUS_SPACE_MAXSIZE (128 * 1024) /* Maximum supported size */ 80 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF 81 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF 82 #define BUS_SPACE_MAXADDR 0xFFFFFFFF 83 84 #define BUS_SPACE_UNRESTRICTED (~0) 85 86 /* 87 * Values for the macppc bus space tag, not to be used directly by MI code. 88 */ 89 90 #define __BUS_SPACE_HAS_STREAM_METHODS 91 92 /* 93 * Values for the ppc bus space tag, not to be used directly by MI code. 94 */ 95 #define PPC_BUS_SPACE_MEM 1 /* space is mem space */ 96 97 98 #define __BA(t, h, o) ((void *)((h) + (o))) 99 100 /* 101 * Bus address and size types 102 */ 103 typedef u_int32_t bus_addr_t; 104 typedef u_int32_t bus_size_t; 105 106 /* 107 * Access methods for bus resources and address space. 108 */ 109 typedef u_int32_t bus_space_tag_t; 110 typedef u_int32_t bus_space_handle_t; 111 112 static __inline void * 113 __ppc_ba(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset) 114 { 115 return ((void *)(handle + offset)); 116 } 117 118 119 /* 120 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 121 * bus_size_t size, int flags, bus_space_handle_t *bshp)); 122 * 123 * Map a region of bus space. 124 */ 125 #if 0 126 bus_space_map(t, addr, size, flags, bshp) ! not implemented ! 127 #endif 128 129 /* 130 * int bus_space_unmap(bus_space_tag_t t, 131 * bus_space_handle_t bsh, bus_size_t size)); 132 * 133 * Unmap a region of bus space. 134 */ 135 136 #define bus_space_unmap(t, bsh, size) 137 138 /* 139 * int bus_space_subregion(bus_space_tag_t t, 140 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 141 * bus_space_handle_t *nbshp)); 142 * 143 * Get a new handle for a subregion of an already-mapped area of bus space. 144 */ 145 146 #define bus_space_subregion(t, bsh, offset, size, bshp) \ 147 ((*(bshp) = (bus_space_handle_t)__ppc_ba(t, bsh, offset)), 0) 148 149 /* 150 * int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 151 * bus_addr_t rend, bus_size_t size, bus_size_t align, 152 * bus_size_t boundary, int flags, bus_addr_t *addrp, 153 * bus_space_handle_t *bshp)); 154 * 155 * Allocate a region of bus space. 156 */ 157 158 #if 0 159 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) !!! unimplemented !!! 160 #endif 161 162 /* 163 * int bus_space_free(bus_space_tag_t t, 164 * bus_space_handle_t bsh, bus_size_t size)); 165 * 166 * Free a region of bus space. 167 */ 168 #if 0 169 #define bus_space_free(t, h, s) !!! unimplemented !!! 170 #endif 171 172 /* 173 * u_intN_t bus_space_read_N(bus_space_tag_t tag, 174 * bus_space_handle_t bsh, bus_size_t offset)); 175 * 176 * Read a 1, 2, 4, or 8 byte quantity from bus space 177 * described by tag/handle/offset. 178 */ 179 180 #define bus_space_read_1(t, h, o) (in8(__ppc_ba(t, h, o))) 181 #define bus_space_read_2(t, h, o) (in16rb(__ppc_ba(t, h, o))) 182 #define bus_space_read_4(t, h, o) (in32rb(__ppc_ba(t, h, o))) 183 #if 0 /* Cause a link error for bus_space_read_8 */ 184 #define bus_space_read_8(t, h, o) !!! unimplemented !!! 185 #endif 186 187 #define bus_space_read_stream_1(t, h, o) (in8(__ppc_ba(t, h, o))) 188 #define bus_space_read_stream_2(t, h, o) (in16(__ppc_ba(t, h, o))) 189 #define bus_space_read_stream_4(t, h, o) (in32(__ppc_ba(t, h, o))) 190 #if 0 /* Cause a link error for bus_space_read_stream_8 */ 191 #define bus_space_read_8(t, h, o) !!! unimplemented !!! 192 #endif 193 194 /* 195 * void bus_space_read_multi_N(bus_space_tag_t tag, 196 * bus_space_handle_t bsh, bus_size_t offset, 197 * u_intN_t *addr, size_t count)); 198 * 199 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 200 * described by tag/handle/offset and copy into buffer provided. 201 */ 202 203 #define bus_space_read_multi_1(t, h, o, a, c) do { \ 204 ins8(__ppc_ba(t, h, o), (a), (c)); \ 205 } while (0) 206 207 #define bus_space_read_multi_2(t, h, o, a, c) do { \ 208 ins16rb(__ppc_ba(t, h, o), (a), (c)); \ 209 } while (0) 210 211 #define bus_space_read_multi_4(t, h, o, a, c) do { \ 212 ins32rb(__ppc_ba(t, h, o), (a), (c)); \ 213 } while (0) 214 215 #if 0 /* Cause a link error for bus_space_read_multi_8 */ 216 #define bus_space_read_multi_8 !!! unimplemented !!! 217 #endif 218 219 #define bus_space_read_multi_stream_1(t, h, o, a, c) do { \ 220 ins8(__ppc_ba(t, h, o), (a), (c)); \ 221 } while (0) 222 223 #define bus_space_read_multi_stream_2(t, h, o, a, c) do { \ 224 ins16(__ppc_ba(t, h, o), (a), (c)); \ 225 } while (0) 226 227 #define bus_space_read_multi_stream_4(t, h, o, a, c) do { \ 228 ins32(__ppc_ba(t, h, o), (a), (c)); \ 229 } while (0) 230 231 #if 0 /* Cause a link error for bus_space_read_multi_stream_8 */ 232 #define bus_space_read_multi_stream_8 !!! unimplemented !!! 233 #endif 234 235 /* 236 * void bus_space_read_region_N(bus_space_tag_t tag, 237 * bus_space_handle_t bsh, bus_size_t offset, 238 * u_intN_t *addr, size_t count)); 239 * 240 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 241 * described by tag/handle and starting at `offset' and copy into 242 * buffer provided. 243 */ 244 245 static __inline void 246 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 247 bus_size_t offset, u_int8_t *addr, size_t count) 248 { 249 volatile u_int8_t *s = __ppc_ba(tag, bsh, offset); 250 251 while (count--) 252 *addr++ = *s++; 253 __asm __volatile("eieio; sync"); 254 } 255 256 static __inline void 257 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 258 bus_size_t offset, u_int16_t *addr, size_t count) 259 { 260 volatile u_int16_t *s = __ppc_ba(tag, bsh, offset); 261 262 while (count--) 263 __asm __volatile("lhbrx %0, 0, %1" : 264 "=r"(*addr++) : "r"(s++)); 265 __asm __volatile("eieio; sync"); 266 } 267 268 static __inline void 269 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 270 bus_size_t offset, u_int32_t *addr, size_t count) 271 { 272 volatile u_int32_t *s = __ppc_ba(tag, bsh, offset); 273 274 while (count--) 275 __asm __volatile("lwbrx %0, 0, %1" : 276 "=r"(*addr++) : "r"(s++)); 277 __asm __volatile("eieio; sync"); 278 } 279 280 #if 0 /* Cause a link error for bus_space_read_region_8 */ 281 #define bus_space_read_region_8 !!! unimplemented !!! 282 #endif 283 284 static __inline void 285 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 286 bus_size_t offset, u_int16_t *addr, size_t count) 287 { 288 volatile u_int16_t *s = __ppc_ba(tag, bsh, offset); 289 290 while (count--) 291 *addr++ = *s++; 292 __asm __volatile("eieio; sync"); 293 } 294 295 static __inline void 296 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 297 bus_size_t offset, u_int32_t *addr, size_t count) 298 { 299 volatile u_int32_t *s = __ppc_ba(tag, bsh, offset); 300 301 while (count--) 302 *addr++ = *s++; 303 __asm __volatile("eieio; sync"); 304 } 305 306 #if 0 /* Cause a link error */ 307 #define bus_space_read_region_stream_8 !!! unimplemented !!! 308 #endif 309 310 /* 311 * void bus_space_write_N(bus_space_tag_t tag, 312 * bus_space_handle_t bsh, bus_size_t offset, 313 * u_intN_t value)); 314 * 315 * Write the 1, 2, 4, or 8 byte value `value' to bus space 316 * described by tag/handle/offset. 317 */ 318 319 #define bus_space_write_1(t, h, o, v) out8(__ppc_ba(t, h, o), (v)) 320 #define bus_space_write_2(t, h, o, v) out16rb(__ppc_ba(t, h, o), (v)) 321 #define bus_space_write_4(t, h, o, v) out32rb(__ppc_ba(t, h, o), (v)) 322 323 #define bus_space_write_stream_1(t, h, o, v) out8(__ppc_ba(t, h, o), (v)) 324 #define bus_space_write_stream_2(t, h, o, v) out16(__ppc_ba(t, h, o), (v)) 325 #define bus_space_write_stream_4(t, h, o, v) out32(__ppc_ba(t, h, o), (v)) 326 327 #if 0 /* Cause a link error for bus_space_write_8 */ 328 #define bus_space_write_8 !!! unimplemented !!! 329 #endif 330 331 /* 332 * void bus_space_write_multi_N(bus_space_tag_t tag, 333 * bus_space_handle_t bsh, bus_size_t offset, 334 * const u_intN_t *addr, size_t count)); 335 * 336 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 337 * provided to bus space described by tag/handle/offset. 338 */ 339 340 #define bus_space_write_multi_1(t, h, o, a, c) do { \ 341 outsb(__ppc_ba(t, h, o), (a), (c)); \ 342 } while (0) 343 344 #define bus_space_write_multi_2(t, h, o, a, c) do { \ 345 outsw(__ppc_ba(t, h, o), (a), (c)); \ 346 } while (0) 347 348 #define bus_space_write_multi_4(t, h, o, a, c) do { \ 349 outsl(__ppc_ba(t, h, o), (a), (c)); \ 350 } while (0) 351 352 #if 0 353 #define bus_space_write_multi_8 !!! unimplemented !!! 354 #endif 355 356 #define bus_space_write_multi_stream_2(t, h, o, a, c) do { \ 357 outsw(__ppc_ba(t, h, o), (a), (c)); \ 358 } while (0) 359 360 #define bus_space_write_multi_stream_4(t, h, o, a, c) do { \ 361 outsl(__ppc_ba(t, h, o), (a), (c)); \ 362 } while (0) 363 364 #if 0 365 #define bus_space_write_multi_stream_8 !!! unimplemented !!! 366 #endif 367 368 /* 369 * void bus_space_write_region_N(bus_space_tag_t tag, 370 * bus_space_handle_t bsh, bus_size_t offset, 371 * const u_intN_t *addr, size_t count)); 372 * 373 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 374 * to bus space described by tag/handle starting at `offset'. 375 */ 376 377 static __inline void 378 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 379 bus_size_t offset, const u_int8_t *addr, size_t count) 380 { 381 volatile u_int8_t *d = __ppc_ba(tag, bsh, offset); 382 383 while (count--) 384 *d++ = *addr++; 385 __asm __volatile("eieio; sync"); 386 } 387 388 static __inline void 389 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 390 bus_size_t offset, const u_int16_t *addr, size_t count) 391 { 392 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 393 394 while (count--) 395 __asm __volatile("sthbrx %0, 0, %1" :: 396 "r"(*addr++), "r"(d++)); 397 __asm __volatile("eieio; sync"); 398 } 399 400 static __inline void 401 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 402 bus_size_t offset, const u_int32_t *addr, size_t count) 403 { 404 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 405 406 while (count--) 407 __asm __volatile("stwbrx %0, 0, %1" :: 408 "r"(*addr++), "r"(d++)); 409 __asm __volatile("eieio; sync"); 410 } 411 412 #if 0 413 #define bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!! 414 #endif 415 416 static __inline void 417 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 418 bus_size_t offset, const u_int16_t *addr, size_t count) 419 { 420 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 421 422 while (count--) 423 *d++ = *addr++; 424 __asm __volatile("eieio; sync"); 425 } 426 427 static __inline void 428 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 429 bus_size_t offset, const u_int32_t *addr, size_t count) 430 { 431 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 432 433 while (count--) 434 *d++ = *addr++; 435 __asm __volatile("eieio; sync"); 436 } 437 438 #if 0 439 #define bus_space_write_region_stream_8 !!! unimplemented !!! 440 #endif 441 442 /* 443 * void bus_space_set_multi_N(bus_space_tag_t tag, 444 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 445 * size_t count)); 446 * 447 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 448 * by tag/handle/offset `count' times. 449 */ 450 451 static __inline void 452 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 453 bus_size_t offset, u_int8_t val, size_t count) 454 { 455 volatile u_int8_t *d = __ppc_ba(tag, bsh, offset); 456 457 while (count--) 458 *d = val; 459 __asm __volatile("eieio; sync"); 460 } 461 462 static __inline void 463 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 464 bus_size_t offset, u_int16_t val, size_t count) 465 { 466 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 467 468 while (count--) 469 __asm __volatile("sthbrx %0, 0, %1" :: 470 "r"(val), "r"(d)); 471 __asm __volatile("eieio; sync"); 472 } 473 474 static __inline void 475 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 476 bus_size_t offset, u_int32_t val, size_t count) 477 { 478 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 479 480 while (count--) 481 __asm __volatile("stwbrx %0, 0, %1" :: 482 "r"(val), "r"(d)); 483 __asm __volatile("eieio; sync"); 484 } 485 486 #if 0 487 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! 488 #endif 489 490 static __inline void 491 bus_space_set_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 492 bus_size_t offset, u_int16_t val, size_t count) 493 { 494 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 495 496 while (count--) 497 *d = val; 498 __asm __volatile("eieio; sync"); 499 } 500 501 static __inline void 502 bus_space_set_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 503 bus_size_t offset, u_int32_t val, size_t count) 504 { 505 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 506 507 while (count--) 508 *d = val; 509 __asm __volatile("eieio; sync"); 510 } 511 512 #if 0 513 #define bus_space_set_multi_stream_8 !!! unimplemented !!! 514 #endif 515 516 /* 517 * void bus_space_set_region_N(bus_space_tag_t tag, 518 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 519 * size_t count)); 520 * 521 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 522 * by tag/handle starting at `offset'. 523 */ 524 525 static __inline void 526 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 527 bus_size_t offset, u_int8_t val, size_t count) 528 { 529 volatile u_int8_t *d = __ppc_ba(tag, bsh, offset); 530 531 while (count--) 532 *d++ = val; 533 __asm __volatile("eieio; sync"); 534 } 535 536 static __inline void 537 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 538 bus_size_t offset, u_int16_t val, size_t count) 539 { 540 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 541 542 while (count--) 543 __asm __volatile("sthbrx %0, 0, %1" :: 544 "r"(val), "r"(d++)); 545 __asm __volatile("eieio; sync"); 546 } 547 548 static __inline void 549 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 550 bus_size_t offset, u_int32_t val, size_t count) 551 { 552 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 553 554 while (count--) 555 __asm __volatile("stwbrx %0, 0, %1" :: 556 "r"(val), "r"(d++)); 557 __asm __volatile("eieio; sync"); 558 } 559 560 #if 0 561 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! 562 #endif 563 564 static __inline void 565 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 566 bus_size_t offset, u_int16_t val, size_t count) 567 { 568 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 569 570 while (count--) 571 *d++ = val; 572 __asm __volatile("eieio; sync"); 573 } 574 575 static __inline void 576 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 577 bus_size_t offset, u_int32_t val, size_t count) 578 { 579 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 580 581 while (count--) 582 *d++ = val; 583 __asm __volatile("eieio; sync"); 584 } 585 586 #if 0 587 #define bus_space_set_region_stream_8 !!! unimplemented !!! 588 #endif 589 590 /* 591 * void bus_space_copy_region_N(bus_space_tag_t tag, 592 * bus_space_handle_t bsh1, bus_size_t off1, 593 * bus_space_handle_t bsh2, bus_size_t off2, 594 * size_t count)); 595 * 596 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 597 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 598 */ 599 600 /* XXX IMPLEMENT bus_space_copy_N() XXX */ 601 602 /* 603 * Bus read/write barrier methods. 604 * 605 * void bus_space_barrier(bus_space_tag_t tag, 606 * bus_space_handle_t bsh, bus_size_t offset, 607 * bus_size_t len, int flags)); 608 * 609 * Note: the macppc does not currently require barriers, but we must 610 * provide the flags to MI code. 611 */ 612 613 #define bus_space_barrier(t, h, o, l, f) \ 614 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 615 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 616 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 617 618 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 619 620 /* 621 * Bus DMA methods. 622 */ 623 624 /* 625 * Flags used in various bus DMA methods. 626 */ 627 #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ 628 #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ 629 #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ 630 #define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */ 631 #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ 632 #define BUS_DMA_BUS2 0x20 633 #define BUS_DMA_BUS3 0x40 634 #define BUS_DMA_BUS4 0x80 635 636 /* Forwards needed by prototypes below. */ 637 struct mbuf; 638 struct uio; 639 640 /* 641 * bus_dmasync_op_t 642 * 643 * Operations performed by bus_dmamap_sync(). 644 */ 645 typedef enum { 646 BUS_DMASYNC_PREREAD, 647 BUS_DMASYNC_POSTREAD, 648 BUS_DMASYNC_PREWRITE, 649 BUS_DMASYNC_POSTWRITE 650 } bus_dmasync_op_t; 651 652 /* 653 * bus_dma_tag_t 654 * 655 * A machine-dependent opaque type describing the characteristics 656 * of how to perform DMA mappings. This structure encapsultes 657 * information concerning address and alignment restrictions, number 658 * of S/G segments, amount of data per S/G segment, etc. 659 */ 660 typedef struct bus_dma_tag *bus_dma_tag_t; 661 662 /* 663 * bus_dmamap_t 664 * 665 * DMA mapping instance information. 666 */ 667 typedef struct bus_dmamap *bus_dmamap_t; 668 669 /* 670 * bus_dma_segment_t 671 * 672 * Describes a single contiguous DMA transaction. Values 673 * are suitable for programming into DMA registers. 674 */ 675 typedef struct bus_dma_segment { 676 bus_addr_t ds_addr; /* DMA address */ 677 bus_size_t ds_len; /* length of transfer */ 678 } bus_dma_segment_t; 679 680 /* 681 * A function that returns 1 if the address cannot be accessed by 682 * a device and 0 if it can be. 683 */ 684 typedef int bus_dma_filter_t(void *, bus_addr_t); 685 686 /* 687 * Allocate a device specific dma_tag encapsulating the constraints of 688 * the parent tag in addition to other restrictions specified: 689 * 690 * alignment: alignment for segments. 691 * boundary: Boundary that segments cannot cross. 692 * lowaddr: Low restricted address that cannot appear in a mapping. 693 * highaddr: High restricted address that cannot appear in a mapping. 694 * filtfunc: An optional function to further test if an address 695 * within the range of lowaddr and highaddr cannot appear 696 * in a mapping. 697 * filtfuncarg: An argument that will be passed to filtfunc in addition 698 * to the address to test. 699 * maxsize: Maximum mapping size supported by this tag. 700 * nsegments: Number of discontinuities allowed in maps. 701 * maxsegsz: Maximum size of a segment in the map. 702 * flags: Bus DMA flags. 703 * dmat: A pointer to set to a valid dma tag should the return 704 * value of this function indicate success. 705 */ 706 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, 707 bus_size_t boundary, bus_addr_t lowaddr, 708 bus_addr_t highaddr, bus_dma_filter_t *filtfunc, 709 void *filtfuncarg, bus_size_t maxsize, int nsegments, 710 bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat); 711 712 int bus_dma_tag_destroy(bus_dma_tag_t dmat); 713 714 /* 715 * Allocate a handle for mapping from kva/uva/physical 716 * address space into bus device space. 717 */ 718 int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); 719 720 /* 721 * Destroy a handle for mapping from kva/uva/physical 722 * address space into bus device space. 723 */ 724 int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); 725 726 /* 727 * Allocate a piece of memory that can be efficiently mapped into 728 * bus device space based on the constraints lited in the dma tag. 729 * A dmamap to for use with dmamap_load is also allocated. 730 */ 731 int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, 732 bus_dmamap_t *mapp); 733 734 /* 735 * Free a piece of memory and it's allociated dmamap, that was allocated 736 * via bus_dmamem_alloc. 737 */ 738 void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); 739 740 /* 741 * A function that processes a successfully loaded dma map or an error 742 * from a delayed load map. 743 */ 744 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); 745 746 /* 747 * Map the buffer buf into bus space using the dmamap map. 748 */ 749 int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 750 bus_size_t buflen, bus_dmamap_callback_t *callback, 751 void *callback_arg, int flags); 752 753 /* 754 * Perform a syncronization operation on the given map. 755 */ 756 void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); 757 758 /* 759 * Release the mapping held by map. 760 */ 761 void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map); 762 763 #endif /* _MACPPC_BUS_H_ */ 764