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 0xFFFFFFFF 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 1 91 92 /* 93 * Values for the ppc bus space tag, not to be used directly by MI code. 94 * Low byte contains the shift value 95 */ 96 #define PPC_BUS_SPACE_MEM 0x100 /* space is mem space */ 97 #define PPC_BUS_MEM_MASK 0x0ff 98 99 /* 100 * Flags for bus_resource_alloc(MEM|IOPORT). XXX this is very bad: it's 101 * assumed that this won't conflict with resource flags :-( 102 */ 103 #define PPC_BUS_SPARSE4 0x800000 /* shift offset left 4 bits */ 104 105 /* 106 * Bus address and size types 107 */ 108 typedef u_int32_t bus_addr_t; 109 typedef u_int32_t bus_size_t; 110 111 /* 112 * Access methods for bus resources and address space. 113 */ 114 typedef u_int32_t bus_space_tag_t; 115 typedef u_int32_t bus_space_handle_t; 116 117 static __inline void * 118 __ppc_ba(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset) 119 { 120 return ((void *)(handle + (offset << (tag & PPC_BUS_MEM_MASK)))); 121 } 122 123 124 /* 125 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 126 * bus_size_t size, int flags, bus_space_handle_t *bshp)); 127 * 128 * Map a region of bus space. 129 */ 130 #if 0 131 bus_space_map(t, addr, size, flags, bshp) ! not implemented ! 132 #endif 133 134 /* 135 * int bus_space_unmap(bus_space_tag_t t, 136 * bus_space_handle_t bsh, bus_size_t size)); 137 * 138 * Unmap a region of bus space. 139 */ 140 141 #define bus_space_unmap(t, bsh, size) 142 143 /* 144 * int bus_space_subregion(bus_space_tag_t t, 145 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 146 * bus_space_handle_t *nbshp)); 147 * 148 * Get a new handle for a subregion of an already-mapped area of bus space. 149 */ 150 151 #define bus_space_subregion(t, bsh, offset, size, bshp) \ 152 ((*(bshp) = (bus_space_handle_t)__ppc_ba( \ 153 (t & ~PPC_BUS_MEM_MASK), bsh, offset)), 0) 154 /* 155 * int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 156 * bus_addr_t rend, bus_size_t size, bus_size_t align, 157 * bus_size_t boundary, int flags, bus_addr_t *addrp, 158 * bus_space_handle_t *bshp)); 159 * 160 * Allocate a region of bus space. 161 */ 162 163 #if 0 164 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) !!! unimplemented !!! 165 #endif 166 167 /* 168 * int bus_space_free(bus_space_tag_t t, 169 * bus_space_handle_t bsh, bus_size_t size)); 170 * 171 * Free a region of bus space. 172 */ 173 #if 0 174 #define bus_space_free(t, h, s) !!! unimplemented !!! 175 #endif 176 177 /* 178 * u_intN_t bus_space_read_N(bus_space_tag_t tag, 179 * bus_space_handle_t bsh, bus_size_t offset)); 180 * 181 * Read a 1, 2, 4, or 8 byte quantity from bus space 182 * described by tag/handle/offset. 183 */ 184 185 #define bus_space_read_1(t, h, o) (in8(__ppc_ba(t, h, o))) 186 #define bus_space_read_2(t, h, o) (in16rb(__ppc_ba(t, h, o))) 187 #define bus_space_read_4(t, h, o) (in32rb(__ppc_ba(t, h, o))) 188 #if 0 /* Cause a link error for bus_space_read_8 */ 189 #define bus_space_read_8(t, h, o) !!! unimplemented !!! 190 #endif 191 192 #define bus_space_read_stream_1(t, h, o) (in8(__ppc_ba(t, h, o))) 193 #define bus_space_read_stream_2(t, h, o) (in16(__ppc_ba(t, h, o))) 194 #define bus_space_read_stream_4(t, h, o) (in32(__ppc_ba(t, h, o))) 195 #if 0 /* Cause a link error for bus_space_read_stream_8 */ 196 #define bus_space_read_stream_8(t, h, o) !!! unimplemented !!! 197 #endif 198 199 /* 200 * void bus_space_read_multi_N(bus_space_tag_t tag, 201 * bus_space_handle_t bsh, bus_size_t offset, 202 * u_intN_t *addr, size_t count)); 203 * 204 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 205 * described by tag/handle/offset and copy into buffer provided. 206 */ 207 208 #define bus_space_read_multi_1(t, h, o, a, c) do { \ 209 ins8(__ppc_ba(t, h, o), (a), (c)); \ 210 } while (0) 211 212 #define bus_space_read_multi_2(t, h, o, a, c) do { \ 213 ins16rb(__ppc_ba(t, h, o), (a), (c)); \ 214 } while (0) 215 216 #define bus_space_read_multi_4(t, h, o, a, c) do { \ 217 ins32rb(__ppc_ba(t, h, o), (a), (c)); \ 218 } while (0) 219 220 #if 0 /* Cause a link error for bus_space_read_multi_8 */ 221 #define bus_space_read_multi_8 !!! unimplemented !!! 222 #endif 223 224 #define bus_space_read_multi_stream_1(t, h, o, a, c) do { \ 225 ins8(__ppc_ba(t, h, o), (a), (c)); \ 226 } while (0) 227 228 #define bus_space_read_multi_stream_2(t, h, o, a, c) do { \ 229 ins16(__ppc_ba(t, h, o), (a), (c)); \ 230 } while (0) 231 232 #define bus_space_read_multi_stream_4(t, h, o, a, c) do { \ 233 ins32(__ppc_ba(t, h, o), (a), (c)); \ 234 } while (0) 235 236 #if 0 /* Cause a link error for bus_space_read_multi_stream_8 */ 237 #define bus_space_read_multi_stream_8 !!! unimplemented !!! 238 #endif 239 240 /* 241 * void bus_space_read_region_N(bus_space_tag_t tag, 242 * bus_space_handle_t bsh, bus_size_t offset, 243 * u_intN_t *addr, size_t count)); 244 * 245 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 246 * described by tag/handle and starting at `offset' and copy into 247 * buffer provided. 248 */ 249 250 static __inline void 251 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 252 bus_size_t offset, u_int8_t *addr, size_t count) 253 { 254 volatile u_int8_t *s = __ppc_ba(tag, bsh, offset); 255 256 while (count--) 257 *addr++ = *s++; 258 __asm __volatile("eieio; sync"); 259 } 260 261 static __inline void 262 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 263 bus_size_t offset, u_int16_t *addr, size_t count) 264 { 265 volatile u_int16_t *s = __ppc_ba(tag, bsh, offset); 266 267 while (count--) 268 __asm __volatile("lhbrx %0, 0, %1" : 269 "=r"(*addr++) : "r"(s++)); 270 __asm __volatile("eieio; sync"); 271 } 272 273 static __inline void 274 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 275 bus_size_t offset, u_int32_t *addr, size_t count) 276 { 277 volatile u_int32_t *s = __ppc_ba(tag, bsh, offset); 278 279 while (count--) 280 __asm __volatile("lwbrx %0, 0, %1" : 281 "=r"(*addr++) : "r"(s++)); 282 __asm __volatile("eieio; sync"); 283 } 284 285 #if 0 /* Cause a link error for bus_space_read_region_8 */ 286 #define bus_space_read_region_8 !!! unimplemented !!! 287 #endif 288 289 static __inline void 290 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 291 bus_size_t offset, u_int16_t *addr, size_t count) 292 { 293 volatile u_int16_t *s = __ppc_ba(tag, bsh, offset); 294 295 while (count--) 296 *addr++ = *s++; 297 __asm __volatile("eieio; sync"); 298 } 299 300 static __inline void 301 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 302 bus_size_t offset, u_int32_t *addr, size_t count) 303 { 304 volatile u_int32_t *s = __ppc_ba(tag, bsh, offset); 305 306 while (count--) 307 *addr++ = *s++; 308 __asm __volatile("eieio; sync"); 309 } 310 311 #if 0 /* Cause a link error */ 312 #define bus_space_read_region_stream_8 !!! unimplemented !!! 313 #endif 314 315 /* 316 * void bus_space_write_N(bus_space_tag_t tag, 317 * bus_space_handle_t bsh, bus_size_t offset, 318 * u_intN_t value)); 319 * 320 * Write the 1, 2, 4, or 8 byte value `value' to bus space 321 * described by tag/handle/offset. 322 */ 323 324 #define bus_space_write_1(t, h, o, v) out8(__ppc_ba(t, h, o), (v)) 325 #define bus_space_write_2(t, h, o, v) out16rb(__ppc_ba(t, h, o), (v)) 326 #define bus_space_write_4(t, h, o, v) out32rb(__ppc_ba(t, h, o), (v)) 327 328 #define bus_space_write_stream_1(t, h, o, v) out8(__ppc_ba(t, h, o), (v)) 329 #define bus_space_write_stream_2(t, h, o, v) out16(__ppc_ba(t, h, o), (v)) 330 #define bus_space_write_stream_4(t, h, o, v) out32(__ppc_ba(t, h, o), (v)) 331 332 #if 0 /* Cause a link error for bus_space_write_8 */ 333 #define bus_space_write_8 !!! unimplemented !!! 334 #endif 335 336 /* 337 * void bus_space_write_multi_N(bus_space_tag_t tag, 338 * bus_space_handle_t bsh, bus_size_t offset, 339 * const u_intN_t *addr, size_t count)); 340 * 341 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 342 * provided to bus space described by tag/handle/offset. 343 */ 344 345 #define bus_space_write_multi_1(t, h, o, a, c) do { \ 346 outsb(__ppc_ba(t, h, o), (a), (c)); \ 347 } while (0) 348 349 #define bus_space_write_multi_2(t, h, o, a, c) do { \ 350 outsw(__ppc_ba(t, h, o), (a), (c)); \ 351 } while (0) 352 353 #define bus_space_write_multi_4(t, h, o, a, c) do { \ 354 outsl(__ppc_ba(t, h, o), (a), (c)); \ 355 } while (0) 356 357 #if 0 358 #define bus_space_write_multi_8 !!! unimplemented !!! 359 #endif 360 361 #define bus_space_write_multi_stream_2(t, h, o, a, c) do { \ 362 outsw(__ppc_ba(t, h, o), (a), (c)); \ 363 } while (0) 364 365 #define bus_space_write_multi_stream_4(t, h, o, a, c) do { \ 366 outsl(__ppc_ba(t, h, o), (a), (c)); \ 367 } while (0) 368 369 #if 0 370 #define bus_space_write_multi_stream_8 !!! unimplemented !!! 371 #endif 372 373 /* 374 * void bus_space_write_region_N(bus_space_tag_t tag, 375 * bus_space_handle_t bsh, bus_size_t offset, 376 * const u_intN_t *addr, size_t count)); 377 * 378 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 379 * to bus space described by tag/handle starting at `offset'. 380 */ 381 382 static __inline void 383 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 384 bus_size_t offset, const u_int8_t *addr, size_t count) 385 { 386 volatile u_int8_t *d = __ppc_ba(tag, bsh, offset); 387 388 while (count--) 389 *d++ = *addr++; 390 __asm __volatile("eieio; sync"); 391 } 392 393 static __inline void 394 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 395 bus_size_t offset, const u_int16_t *addr, size_t count) 396 { 397 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 398 399 while (count--) 400 __asm __volatile("sthbrx %0, 0, %1" :: 401 "r"(*addr++), "r"(d++)); 402 __asm __volatile("eieio; sync"); 403 } 404 405 static __inline void 406 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 407 bus_size_t offset, const u_int32_t *addr, size_t count) 408 { 409 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 410 411 while (count--) 412 __asm __volatile("stwbrx %0, 0, %1" :: 413 "r"(*addr++), "r"(d++)); 414 __asm __volatile("eieio; sync"); 415 } 416 417 #if 0 418 #define bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!! 419 #endif 420 421 static __inline void 422 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 423 bus_size_t offset, const u_int16_t *addr, size_t count) 424 { 425 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 426 427 while (count--) 428 *d++ = *addr++; 429 __asm __volatile("eieio; sync"); 430 } 431 432 static __inline void 433 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 434 bus_size_t offset, const u_int32_t *addr, size_t count) 435 { 436 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 437 438 while (count--) 439 *d++ = *addr++; 440 __asm __volatile("eieio; sync"); 441 } 442 443 #if 0 444 #define bus_space_write_region_stream_8 !!! unimplemented !!! 445 #endif 446 447 /* 448 * void bus_space_set_multi_N(bus_space_tag_t tag, 449 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 450 * size_t count)); 451 * 452 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 453 * by tag/handle/offset `count' times. 454 */ 455 456 static __inline void 457 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 458 bus_size_t offset, u_int8_t val, size_t count) 459 { 460 volatile u_int8_t *d = __ppc_ba(tag, bsh, offset); 461 462 while (count--) 463 *d = val; 464 __asm __volatile("eieio; sync"); 465 } 466 467 static __inline void 468 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 469 bus_size_t offset, u_int16_t val, size_t count) 470 { 471 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 472 473 while (count--) 474 __asm __volatile("sthbrx %0, 0, %1" :: 475 "r"(val), "r"(d)); 476 __asm __volatile("eieio; sync"); 477 } 478 479 static __inline void 480 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 481 bus_size_t offset, u_int32_t val, size_t count) 482 { 483 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 484 485 while (count--) 486 __asm __volatile("stwbrx %0, 0, %1" :: 487 "r"(val), "r"(d)); 488 __asm __volatile("eieio; sync"); 489 } 490 491 #if 0 492 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! 493 #endif 494 495 static __inline void 496 bus_space_set_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 497 bus_size_t offset, u_int16_t val, size_t count) 498 { 499 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 500 501 while (count--) 502 *d = val; 503 __asm __volatile("eieio; sync"); 504 } 505 506 static __inline void 507 bus_space_set_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 508 bus_size_t offset, u_int32_t val, size_t count) 509 { 510 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 511 512 while (count--) 513 *d = val; 514 __asm __volatile("eieio; sync"); 515 } 516 517 #if 0 518 #define bus_space_set_multi_stream_8 !!! unimplemented !!! 519 #endif 520 521 /* 522 * void bus_space_set_region_N(bus_space_tag_t tag, 523 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 524 * size_t count)); 525 * 526 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 527 * by tag/handle starting at `offset'. 528 */ 529 530 static __inline void 531 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 532 bus_size_t offset, u_int8_t val, size_t count) 533 { 534 volatile u_int8_t *d = __ppc_ba(tag, bsh, offset); 535 536 while (count--) 537 *d++ = val; 538 __asm __volatile("eieio; sync"); 539 } 540 541 static __inline void 542 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 543 bus_size_t offset, u_int16_t val, size_t count) 544 { 545 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 546 547 while (count--) 548 __asm __volatile("sthbrx %0, 0, %1" :: 549 "r"(val), "r"(d++)); 550 __asm __volatile("eieio; sync"); 551 } 552 553 static __inline void 554 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 555 bus_size_t offset, u_int32_t val, size_t count) 556 { 557 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 558 559 while (count--) 560 __asm __volatile("stwbrx %0, 0, %1" :: 561 "r"(val), "r"(d++)); 562 __asm __volatile("eieio; sync"); 563 } 564 565 #if 0 566 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! 567 #endif 568 569 static __inline void 570 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh, 571 bus_size_t offset, u_int16_t val, size_t count) 572 { 573 volatile u_int16_t *d = __ppc_ba(tag, bsh, offset); 574 575 while (count--) 576 *d++ = val; 577 __asm __volatile("eieio; sync"); 578 } 579 580 static __inline void 581 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh, 582 bus_size_t offset, u_int32_t val, size_t count) 583 { 584 volatile u_int32_t *d = __ppc_ba(tag, bsh, offset); 585 586 while (count--) 587 *d++ = val; 588 __asm __volatile("eieio; sync"); 589 } 590 591 #if 0 592 #define bus_space_set_region_stream_8 !!! unimplemented !!! 593 #endif 594 595 /* 596 * void bus_space_copy_region_N(bus_space_tag_t tag, 597 * bus_space_handle_t bsh1, bus_size_t off1, 598 * bus_space_handle_t bsh2, bus_size_t off2, 599 * size_t count)); 600 * 601 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 602 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 603 */ 604 605 /* XXX IMPLEMENT bus_space_copy_N() XXX */ 606 607 /* 608 * Bus read/write barrier methods. 609 * 610 * void bus_space_barrier(bus_space_tag_t tag, 611 * bus_space_handle_t bsh, bus_size_t offset, 612 * bus_size_t len, int flags)); 613 * 614 * Note: the macppc does not currently require barriers, but we must 615 * provide the flags to MI code. 616 */ 617 618 #define bus_space_barrier(t, h, o, l, f) \ 619 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 620 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 621 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 622 623 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 624 625 /* 626 * Bus DMA methods. 627 */ 628 629 /* 630 * Flags used in various bus DMA methods. 631 */ 632 #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ 633 #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ 634 #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ 635 #define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */ 636 #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ 637 #define BUS_DMA_BUS2 0x20 638 #define BUS_DMA_BUS3 0x40 639 #define BUS_DMA_BUS4 0x80 640 641 /* Forwards needed by prototypes below. */ 642 struct mbuf; 643 struct uio; 644 645 /* 646 * bus_dmasync_op_t 647 * 648 * Operations performed by bus_dmamap_sync(). 649 */ 650 typedef enum { 651 BUS_DMASYNC_PREREAD, 652 BUS_DMASYNC_POSTREAD, 653 BUS_DMASYNC_PREWRITE, 654 BUS_DMASYNC_POSTWRITE 655 } bus_dmasync_op_t; 656 657 /* 658 * bus_dma_tag_t 659 * 660 * A machine-dependent opaque type describing the characteristics 661 * of how to perform DMA mappings. This structure encapsultes 662 * information concerning address and alignment restrictions, number 663 * of S/G segments, amount of data per S/G segment, etc. 664 */ 665 typedef struct bus_dma_tag *bus_dma_tag_t; 666 667 /* 668 * bus_dmamap_t 669 * 670 * DMA mapping instance information. 671 */ 672 typedef struct bus_dmamap *bus_dmamap_t; 673 674 /* 675 * bus_dma_segment_t 676 * 677 * Describes a single contiguous DMA transaction. Values 678 * are suitable for programming into DMA registers. 679 */ 680 typedef struct bus_dma_segment { 681 bus_addr_t ds_addr; /* DMA address */ 682 bus_size_t ds_len; /* length of transfer */ 683 } bus_dma_segment_t; 684 685 /* 686 * A function that returns 1 if the address cannot be accessed by 687 * a device and 0 if it can be. 688 */ 689 typedef int bus_dma_filter_t(void *, bus_addr_t); 690 691 /* 692 * Allocate a device specific dma_tag encapsulating the constraints of 693 * the parent tag in addition to other restrictions specified: 694 * 695 * alignment: alignment for segments. 696 * boundary: Boundary that segments cannot cross. 697 * lowaddr: Low restricted address that cannot appear in a mapping. 698 * highaddr: High restricted address that cannot appear in a mapping. 699 * filtfunc: An optional function to further test if an address 700 * within the range of lowaddr and highaddr cannot appear 701 * in a mapping. 702 * filtfuncarg: An argument that will be passed to filtfunc in addition 703 * to the address to test. 704 * maxsize: Maximum mapping size supported by this tag. 705 * nsegments: Number of discontinuities allowed in maps. 706 * maxsegsz: Maximum size of a segment in the map. 707 * flags: Bus DMA flags. 708 * dmat: A pointer to set to a valid dma tag should the return 709 * value of this function indicate success. 710 */ 711 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, 712 bus_size_t boundary, bus_addr_t lowaddr, 713 bus_addr_t highaddr, bus_dma_filter_t *filtfunc, 714 void *filtfuncarg, bus_size_t maxsize, int nsegments, 715 bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat); 716 717 int bus_dma_tag_destroy(bus_dma_tag_t dmat); 718 719 /* 720 * Allocate a handle for mapping from kva/uva/physical 721 * address space into bus device space. 722 */ 723 int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); 724 725 /* 726 * Destroy a handle for mapping from kva/uva/physical 727 * address space into bus device space. 728 */ 729 int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); 730 731 /* 732 * Allocate a piece of memory that can be efficiently mapped into 733 * bus device space based on the constraints lited in the dma tag. 734 * A dmamap to for use with dmamap_load is also allocated. 735 */ 736 int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, 737 bus_dmamap_t *mapp); 738 739 /* 740 * Free a piece of memory and it's allociated dmamap, that was allocated 741 * via bus_dmamem_alloc. 742 */ 743 void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); 744 745 /* 746 * A function that processes a successfully loaded dma map or an error 747 * from a delayed load map. 748 */ 749 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); 750 751 /* 752 * Map the buffer buf into bus space using the dmamap map. 753 */ 754 int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 755 bus_size_t buflen, bus_dmamap_callback_t *callback, 756 void *callback_arg, int flags); 757 758 /* 759 * Like bus_dmamap_callback but includes map size in bytes. This is 760 * defined as a separate interface to maintain compatiiblity for users 761 * of bus_dmamap_callback_t--at some point these interfaces should be merged. 762 */ 763 typedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int); 764 /* 765 * Like bus_dmamap_load but for mbufs. Note the use of the 766 * bus_dmamap_callback2_t interface. 767 */ 768 int bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, 769 struct mbuf *mbuf, 770 bus_dmamap_callback2_t *callback, void *callback_arg, 771 int flags); 772 /* 773 * Like bus_dmamap_load but for uios. Note the use of the 774 * bus_dmamap_callback2_t interface. 775 */ 776 int bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, 777 struct uio *ui, 778 bus_dmamap_callback2_t *callback, void *callback_arg, 779 int flags); 780 781 /* 782 * Perform a syncronization operation on the given map. 783 */ 784 void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); 785 786 /* 787 * Release the mapping held by map. 788 */ 789 void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map); 790 791 #endif /* _MACPPC_BUS_H_ */ 792