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