1 /* $NetBSD: bus.h,v 1.2 2001/04/06 13:09:10 fredette Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997, 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 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 42 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by Christopher G. Demetriou 55 * for the NetBSD Project. 56 * 4. The name of the author may not be used to endorse or promote products 57 * derived from this software without specific prior written permission 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 60 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 61 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 62 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 63 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 64 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 65 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 66 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 68 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 */ 70 71 #ifndef _SUN2_BUS_H_ 72 #define _SUN2_BUS_H_ 73 74 #define SUN2_BUS_SPACE 0 75 76 /* 77 * Bus address and size types 78 */ 79 typedef u_long bus_space_handle_t; 80 typedef u_long bus_type_t; 81 typedef u_long bus_addr_t; 82 typedef u_long bus_size_t; 83 84 /* 85 * Access methods for bus resources and address space. 86 */ 87 typedef struct sun2_bus_space_tag *bus_space_tag_t; 88 89 struct sun2_bus_space_tag { 90 void *cookie; 91 bus_space_tag_t parent; 92 93 int (*sun2_bus_map) __P(( 94 bus_space_tag_t, 95 bus_type_t, 96 bus_addr_t, 97 bus_size_t, 98 int, /*flags*/ 99 vaddr_t, /*preferred vaddr*/ 100 bus_space_handle_t *)); 101 int (*sun2_bus_unmap) __P(( 102 bus_space_tag_t, 103 bus_space_handle_t, 104 bus_size_t)); 105 int (*sun2_bus_subregion) __P(( 106 bus_space_tag_t, 107 bus_space_handle_t, 108 bus_size_t, /*offset*/ 109 bus_size_t, /*size*/ 110 bus_space_handle_t *)); 111 112 void (*sun2_bus_barrier) __P(( 113 bus_space_tag_t, 114 bus_space_handle_t, 115 bus_size_t, /*offset*/ 116 bus_size_t, /*size*/ 117 int)); /*flags*/ 118 119 int (*sun2_bus_mmap) __P(( 120 bus_space_tag_t, 121 bus_type_t, /**/ 122 bus_addr_t, /**/ 123 int, /*flags*/ 124 bus_space_handle_t *)); 125 126 void *(*sun2_intr_establish) __P(( 127 bus_space_tag_t, 128 int, /*bus-specific intr*/ 129 int, /*device class level, 130 see machine/intr.h*/ 131 int, /*flags*/ 132 int (*) __P((void *)), /*handler*/ 133 void *)); /*handler arg*/ 134 135 }; 136 137 #if 0 138 /* 139 * The following macro could be used to generate the bus_space*() functions 140 * but it uses a gcc extension and is ANSI-only. 141 #define PROTO_bus_space_xxx __P((bus_space_tag_t t, ...)) 142 #define RETURNTYPE_bus_space_xxx void * 143 #define BUSFUN(name, returntype, t, args...) \ 144 __inline__ RETURNTYPE_##name \ 145 bus_##name PROTO_##name \ 146 { \ 147 while (t->sun2_##name == NULL) \ 148 t = t->parent; \ 149 return (*(t)->sun2_##name)(t, args); \ 150 } 151 */ 152 #endif 153 154 /* 155 * Bus space function prototypes. 156 */ 157 static int bus_space_map __P(( 158 bus_space_tag_t, 159 bus_addr_t, 160 bus_size_t, 161 int, /*flags*/ 162 bus_space_handle_t *)); 163 static int bus_space_map2 __P(( 164 bus_space_tag_t, 165 bus_type_t, 166 bus_addr_t, 167 bus_size_t, 168 int, /*flags*/ 169 vaddr_t, /*preferred vaddr*/ 170 bus_space_handle_t *)); 171 static int bus_space_unmap __P(( 172 bus_space_tag_t, 173 bus_space_handle_t, 174 bus_size_t)); 175 static int bus_space_subregion __P(( 176 bus_space_tag_t, 177 bus_space_handle_t, 178 bus_size_t, 179 bus_size_t, 180 bus_space_handle_t *)); 181 static void bus_space_barrier __P(( 182 bus_space_tag_t, 183 bus_space_handle_t, 184 bus_size_t, 185 bus_size_t, 186 int)); 187 static int bus_space_mmap __P(( 188 bus_space_tag_t, 189 bus_type_t, /**/ 190 bus_addr_t, /**/ 191 int, /*flags*/ 192 bus_space_handle_t *)); 193 static void *bus_intr_establish __P(( 194 bus_space_tag_t, 195 int, /*bus-specific intr*/ 196 int, /*device class level, 197 see machine/intr.h*/ 198 int, /*flags*/ 199 int (*) __P((void *)), /*handler*/ 200 void *)); /*handler arg*/ 201 202 203 /* This macro finds the first "upstream" implementation of method `f' */ 204 #define _BS_CALL(t,f) \ 205 while (t->f == NULL) \ 206 t = t->parent; \ 207 return (*(t)->f) 208 209 __inline__ int 210 bus_space_map(t, a, s, f, hp) 211 bus_space_tag_t t; 212 bus_addr_t a; 213 bus_size_t s; 214 int f; 215 bus_space_handle_t *hp; 216 { 217 _BS_CALL(t, sun2_bus_map)((t), 0, (a), (s), (f), 0, (hp)); 218 } 219 220 __inline__ int 221 bus_space_map2(t, bt, a, s, f, v, hp) 222 bus_space_tag_t t; 223 bus_type_t bt; 224 bus_addr_t a; 225 bus_size_t s; 226 int f; 227 vaddr_t v; 228 bus_space_handle_t *hp; 229 { 230 _BS_CALL(t, sun2_bus_map)(t, bt, a, s, f, v, hp); 231 } 232 233 __inline__ int 234 bus_space_unmap(t, h, s) 235 bus_space_tag_t t; 236 bus_space_handle_t h; 237 bus_size_t s; 238 { 239 _BS_CALL(t, sun2_bus_unmap)(t, h, s); 240 } 241 242 __inline__ int 243 bus_space_subregion(t, h, o, s, hp) 244 bus_space_tag_t t; 245 bus_space_handle_t h; 246 bus_size_t o; 247 bus_size_t s; 248 bus_space_handle_t *hp; 249 { 250 _BS_CALL(t, sun2_bus_subregion)(t, h, o, s, hp); 251 } 252 253 __inline__ int 254 bus_space_mmap(t, bt, a, f, hp) 255 bus_space_tag_t t; 256 bus_type_t bt; 257 bus_addr_t a; 258 int f; 259 bus_space_handle_t *hp; 260 { 261 _BS_CALL(t, sun2_bus_mmap)(t, bt, a, f, hp); 262 } 263 264 __inline__ void * 265 bus_intr_establish(t, p, l, f, h, a) 266 bus_space_tag_t t; 267 int p; 268 int l; 269 int f; 270 int (*h)__P((void *)); 271 void *a; 272 { 273 _BS_CALL(t, sun2_intr_establish)(t, p, l, f, h, a); 274 } 275 276 __inline__ void 277 bus_space_barrier(t, h, o, s, f) 278 bus_space_tag_t t; 279 bus_space_handle_t h; 280 bus_size_t o; 281 bus_size_t s; 282 int f; 283 { 284 _BS_CALL(t, sun2_bus_barrier)(t, h, o, s, f); 285 } 286 287 288 #if 0 289 int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart, 290 bus_addr_t rend, bus_size_t size, bus_size_t align, 291 bus_size_t boundary, int flags, bus_addr_t *addrp, 292 bus_space_handle_t *bshp)); 293 void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh, 294 bus_size_t size)); 295 #endif 296 297 /* flags for bus space map functions */ 298 #define BUS_SPACE_MAP_CACHEABLE 0x0001 299 #define BUS_SPACE_MAP_LINEAR 0x0002 300 #define BUS_SPACE_MAP_PREFETCHABLE 0x0004 301 #define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */ 302 #define BUS_SPACE_MAP_BUS2 0x0200 303 #define BUS_SPACE_MAP_BUS3 0x0400 304 #define BUS_SPACE_MAP_BUS4 0x0800 305 306 /* Internal flag: try to find and use a PROM maping for the device. */ 307 #define _SUN2_BUS_MAP_USE_PROM BUS_SPACE_MAP_BUS1 308 309 /* flags for intr_establish() */ 310 #define BUS_INTR_ESTABLISH_FASTTRAP 1 311 #define BUS_INTR_ESTABLISH_SOFTINTR 2 312 313 /* flags for bus_space_barrier() */ 314 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 315 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 316 317 /* 318 * Device space probe assistant. 319 * The optional callback function's arguments are: 320 * the temporary virtual address 321 * the passed `arg' argument 322 */ 323 int bus_space_probe __P(( 324 bus_space_tag_t, 325 bus_type_t, 326 bus_addr_t, 327 bus_size_t, /* probe size */ 328 size_t, /* offset */ 329 int, /* flags */ 330 int (*) __P((void *, void *)), /* callback function */ 331 void *)); /* callback arg */ 332 333 334 /* 335 * u_intN_t bus_space_read_N __P((bus_space_tag_t tag, 336 * bus_space_handle_t bsh, bus_size_t offset)); 337 * 338 * Read a 1, 2, 4, or 8 byte quantity from bus space 339 * described by tag/handle/offset. 340 */ 341 342 #define bus_space_read_1(t, h, o) \ 343 ((void)t, *(volatile u_int8_t *)((h) + (o))) 344 345 #define bus_space_read_2(t, h, o) \ 346 ((void)t, *(volatile u_int16_t *)((h) + (o))) 347 348 #define bus_space_read_4(t, h, o) \ 349 ((void)t, *(volatile u_int32_t *)((h) + (o))) 350 351 #define bus_space_read_8(t, h, o) \ 352 ((void)t, *(volatile u_int64_t *)((h) + (o))) 353 354 355 /* 356 * void bus_space_write_N __P((bus_space_tag_t tag, 357 * bus_space_handle_t bsh, bus_size_t offset, 358 * u_intN_t value)); 359 * 360 * Write the 1, 2, 4, or 8 byte value `value' to bus space 361 * described by tag/handle/offset. 362 */ 363 364 #define bus_space_write_1(t, h, o, v) do { \ 365 ((void)t, (void)(*(volatile u_int8_t *)((h) + (o)) = (v))); \ 366 } while (0) 367 368 #define bus_space_write_2(t, h, o, v) do { \ 369 ((void)t, (void)(*(volatile u_int16_t *)((h) + (o)) = (v))); \ 370 } while (0) 371 372 #define bus_space_write_4(t, h, o, v) do { \ 373 ((void)t, (void)(*(volatile u_int32_t *)((h) + (o)) = (v))); \ 374 } while (0) 375 376 #define bus_space_write_8(t, h, o, v) do { \ 377 ((void)t, (void)(*(volatile u_int64_t *)((h) + (o)) = (v))); \ 378 } while (0) 379 380 381 /* 382 * void bus_space_read_multi_N __P((bus_space_tag_t tag, 383 * bus_space_handle_t bsh, bus_size_t offset, 384 * u_intN_t *addr, bus_size_t count)); 385 * 386 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 387 * described by tag/handle/offset and copy into buffer provided. 388 */ 389 390 void bus_space_read_multi_1 __P((bus_space_tag_t, 391 bus_space_handle_t, 392 bus_size_t, 393 u_int8_t *, 394 bus_size_t)); 395 396 void bus_space_read_multi_2 __P((bus_space_tag_t, 397 bus_space_handle_t, 398 bus_size_t, 399 u_int16_t *, 400 bus_size_t)); 401 402 void bus_space_read_multi_4 __P((bus_space_tag_t, 403 bus_space_handle_t, 404 bus_size_t, 405 u_int32_t *, 406 bus_size_t)); 407 408 void bus_space_read_multi_8 __P((bus_space_tag_t, 409 bus_space_handle_t, 410 bus_size_t, 411 u_int64_t *, 412 bus_size_t)); 413 414 extern __inline__ void 415 bus_space_read_multi_1(t, h, o, a, c) 416 bus_space_tag_t t; 417 bus_space_handle_t h; 418 bus_size_t o, c; 419 u_int8_t *a; 420 { 421 while (c-- > 0) 422 *a++ = bus_space_read_1(t, h, o); 423 } 424 425 extern __inline__ void 426 bus_space_read_multi_2(t, h, o, a, c) 427 bus_space_tag_t t; 428 bus_space_handle_t h; 429 bus_size_t o, c; 430 u_int16_t *a; 431 { 432 while (c-- > 0) 433 *a++ = bus_space_read_2(t, h, o); 434 } 435 436 extern __inline__ void 437 bus_space_read_multi_4(t, h, o, a, c) 438 bus_space_tag_t t; 439 bus_space_handle_t h; 440 bus_size_t o, c; 441 u_int32_t *a; 442 { 443 while (c-- > 0) 444 *a++ = bus_space_read_4(t, h, o); 445 } 446 447 extern __inline__ void 448 bus_space_read_multi_8(t, h, o, a, c) 449 bus_space_tag_t t; 450 bus_space_handle_t h; 451 bus_size_t o, c; 452 u_int64_t *a; 453 { 454 while (c-- > 0) 455 *a++ = bus_space_read_8(t, h, o); 456 } 457 458 459 /* 460 * void bus_space_write_multi_N __P((bus_space_tag_t tag, 461 * bus_space_handle_t bsh, bus_size_t offset, 462 * const u_intN_t *addr, bus_size_t count)); 463 * 464 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 465 * provided to bus space described by tag/handle/offset. 466 */ 467 void bus_space_write_multi_1 __P((bus_space_tag_t, 468 bus_space_handle_t, 469 bus_size_t, 470 const u_int8_t *, 471 bus_size_t)); 472 void bus_space_write_multi_2 __P((bus_space_tag_t, 473 bus_space_handle_t, 474 bus_size_t, 475 const u_int16_t *, 476 bus_size_t)); 477 void bus_space_write_multi_4 __P((bus_space_tag_t, 478 bus_space_handle_t, 479 bus_size_t, 480 const u_int32_t *, 481 bus_size_t)); 482 void bus_space_write_multi_8 __P((bus_space_tag_t, 483 bus_space_handle_t, 484 bus_size_t, 485 const u_int64_t *, 486 bus_size_t)); 487 extern __inline__ void 488 bus_space_write_multi_1(t, h, o, a, c) 489 bus_space_tag_t t; 490 bus_space_handle_t h; 491 bus_size_t o, c; 492 const u_int8_t *a; 493 { 494 while (c-- > 0) 495 bus_space_write_1(t, h, o, *a++); 496 } 497 498 extern __inline__ void 499 bus_space_write_multi_2(t, h, o, a, c) 500 bus_space_tag_t t; 501 bus_space_handle_t h; 502 bus_size_t o, c; 503 const u_int16_t *a; 504 { 505 while (c-- > 0) 506 bus_space_write_2(t, h, o, *a++); 507 } 508 509 extern __inline__ void 510 bus_space_write_multi_4(t, h, o, a, c) 511 bus_space_tag_t t; 512 bus_space_handle_t h; 513 bus_size_t o, c; 514 const u_int32_t *a; 515 { 516 while (c-- > 0) 517 bus_space_write_4(t, h, o, *a++); 518 } 519 520 extern __inline__ void 521 bus_space_write_multi_8(t, h, o, a, c) 522 bus_space_tag_t t; 523 bus_space_handle_t h; 524 bus_size_t o, c; 525 const u_int64_t *a; 526 { 527 while (c-- > 0) 528 bus_space_write_8(t, h, o, *a++); 529 } 530 531 /* 532 * void bus_space_set_multi_N __P((bus_space_tag_t tag, 533 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 534 * bus_size_t count)); 535 * 536 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 537 * by tag/handle/offset `count' times. 538 */ 539 void bus_space_set_multi_1 __P((bus_space_tag_t, 540 bus_space_handle_t, 541 bus_size_t, 542 const u_int8_t, 543 bus_size_t)); 544 void bus_space_set_multi_2 __P((bus_space_tag_t, 545 bus_space_handle_t, 546 bus_size_t, 547 const u_int16_t, 548 bus_size_t)); 549 void bus_space_set_multi_4 __P((bus_space_tag_t, 550 bus_space_handle_t, 551 bus_size_t, 552 const u_int32_t, 553 bus_size_t)); 554 void bus_space_set_multi_8 __P((bus_space_tag_t, 555 bus_space_handle_t, 556 bus_size_t, 557 const u_int64_t, 558 bus_size_t)); 559 560 extern __inline__ void 561 bus_space_set_multi_1(t, h, o, v, c) 562 bus_space_tag_t t; 563 bus_space_handle_t h; 564 bus_size_t o, c; 565 const u_int8_t v; 566 { 567 while (c-- > 0) 568 bus_space_write_1(t, h, o, v); 569 } 570 571 extern __inline__ void 572 bus_space_set_multi_2(t, h, o, v, c) 573 bus_space_tag_t t; 574 bus_space_handle_t h; 575 bus_size_t o, c; 576 const u_int16_t v; 577 { 578 while (c-- > 0) 579 bus_space_write_2(t, h, o, v); 580 } 581 582 extern __inline__ void 583 bus_space_set_multi_4(t, h, o, v, c) 584 bus_space_tag_t t; 585 bus_space_handle_t h; 586 bus_size_t o, c; 587 const u_int32_t v; 588 { 589 while (c-- > 0) 590 bus_space_write_4(t, h, o, v); 591 } 592 593 extern __inline__ void 594 bus_space_set_multi_8(t, h, o, v, c) 595 bus_space_tag_t t; 596 bus_space_handle_t h; 597 bus_size_t o, c; 598 const u_int64_t v; 599 { 600 while (c-- > 0) 601 bus_space_write_8(t, h, o, v); 602 } 603 604 605 /* 606 * void bus_space_read_region_N __P((bus_space_tag_t tag, 607 * bus_space_handle_t bsh, bus_size_t off, 608 * u_intN_t *addr, bus_size_t count)); 609 * 610 */ 611 void bus_space_read_region_1 __P((bus_space_tag_t, 612 bus_space_handle_t, 613 bus_size_t, 614 u_int8_t *, 615 bus_size_t)); 616 void bus_space_read_region_2 __P((bus_space_tag_t, 617 bus_space_handle_t, 618 bus_size_t, 619 u_int16_t *, 620 bus_size_t)); 621 void bus_space_read_region_4 __P((bus_space_tag_t, 622 bus_space_handle_t, 623 bus_size_t, 624 u_int32_t *, 625 bus_size_t)); 626 void bus_space_read_region_8 __P((bus_space_tag_t, 627 bus_space_handle_t, 628 bus_size_t, 629 u_int64_t *, 630 bus_size_t)); 631 632 extern __inline__ void 633 bus_space_read_region_1(t, h, o, a, c) 634 bus_space_tag_t t; 635 bus_space_handle_t h; 636 bus_size_t o, c; 637 u_int8_t *a; 638 { 639 for (; c; a++, c--, o++) 640 *a = bus_space_read_1(t, h, o); 641 } 642 extern __inline__ void 643 bus_space_read_region_2(t, h, o, a, c) 644 bus_space_tag_t t; 645 bus_space_handle_t h; 646 bus_size_t o, c; 647 u_int16_t *a; 648 { 649 for (; c; a++, c--, o+=2) 650 *a = bus_space_read_2(t, h, o); 651 } 652 extern __inline__ void 653 bus_space_read_region_4(t, h, o, a, c) 654 bus_space_tag_t t; 655 bus_space_handle_t h; 656 bus_size_t o, c; 657 u_int32_t *a; 658 { 659 for (; c; a++, c--, o+=4) 660 *a = bus_space_read_4(t, h, o); 661 } 662 extern __inline__ void 663 bus_space_read_region_8(t, h, o, a, c) 664 bus_space_tag_t t; 665 bus_space_handle_t h; 666 bus_size_t o, c; 667 u_int64_t *a; 668 { 669 for (; c; a++, c--, o+=8) 670 *a = bus_space_read_8(t, h, o); 671 } 672 673 /* 674 * void bus_space_write_region_N __P((bus_space_tag_t tag, 675 * bus_space_handle_t bsh, bus_size_t off, 676 * u_intN_t *addr, bus_size_t count)); 677 * 678 */ 679 void bus_space_write_region_1 __P((bus_space_tag_t, 680 bus_space_handle_t, 681 bus_size_t, 682 const u_int8_t *, 683 bus_size_t)); 684 void bus_space_write_region_2 __P((bus_space_tag_t, 685 bus_space_handle_t, 686 bus_size_t, 687 const u_int16_t *, 688 bus_size_t)); 689 void bus_space_write_region_4 __P((bus_space_tag_t, 690 bus_space_handle_t, 691 bus_size_t, 692 const u_int32_t *, 693 bus_size_t)); 694 void bus_space_write_region_8 __P((bus_space_tag_t, 695 bus_space_handle_t, 696 bus_size_t, 697 const u_int64_t *, 698 bus_size_t)); 699 extern __inline__ void 700 bus_space_write_region_1(t, h, o, a, c) 701 bus_space_tag_t t; 702 bus_space_handle_t h; 703 bus_size_t o, c; 704 const u_int8_t *a; 705 { 706 for (; c; a++, c--, o++) 707 bus_space_write_1(t, h, o, *a); 708 } 709 710 extern __inline__ void 711 bus_space_write_region_2(t, h, o, a, c) 712 bus_space_tag_t t; 713 bus_space_handle_t h; 714 bus_size_t o, c; 715 const u_int16_t *a; 716 { 717 for (; c; a++, c--, o+=2) 718 bus_space_write_2(t, h, o, *a); 719 } 720 721 extern __inline__ void 722 bus_space_write_region_4(t, h, o, a, c) 723 bus_space_tag_t t; 724 bus_space_handle_t h; 725 bus_size_t o, c; 726 const u_int32_t *a; 727 { 728 for (; c; a++, c--, o+=4) 729 bus_space_write_4(t, h, o, *a); 730 } 731 732 extern __inline__ void 733 bus_space_write_region_8(t, h, o, a, c) 734 bus_space_tag_t t; 735 bus_space_handle_t h; 736 bus_size_t o, c; 737 const u_int64_t *a; 738 { 739 for (; c; a++, c--, o+=8) 740 bus_space_write_8(t, h, o, *a); 741 } 742 743 744 /* 745 * void bus_space_set_region_N __P((bus_space_tag_t tag, 746 * bus_space_handle_t bsh, bus_size_t off, 747 * u_intN_t *addr, bus_size_t count)); 748 * 749 */ 750 void bus_space_set_region_1 __P((bus_space_tag_t, 751 bus_space_handle_t, 752 bus_size_t, 753 const u_int8_t, 754 bus_size_t)); 755 void bus_space_set_region_2 __P((bus_space_tag_t, 756 bus_space_handle_t, 757 bus_size_t, 758 const u_int16_t, 759 bus_size_t)); 760 void bus_space_set_region_4 __P((bus_space_tag_t, 761 bus_space_handle_t, 762 bus_size_t, 763 const u_int32_t, 764 bus_size_t)); 765 void bus_space_set_region_8 __P((bus_space_tag_t, 766 bus_space_handle_t, 767 bus_size_t, 768 const u_int64_t, 769 bus_size_t)); 770 771 extern __inline__ void 772 bus_space_set_region_1(t, h, o, v, c) 773 bus_space_tag_t t; 774 bus_space_handle_t h; 775 bus_size_t o, c; 776 const u_int8_t v; 777 { 778 for (; c; c--, o++) 779 bus_space_write_1(t, h, o, v); 780 } 781 782 extern __inline__ void 783 bus_space_set_region_2(t, h, o, v, c) 784 bus_space_tag_t t; 785 bus_space_handle_t h; 786 bus_size_t o, c; 787 const u_int16_t v; 788 { 789 for (; c; c--, o+=2) 790 bus_space_write_2(t, h, o, v); 791 } 792 793 extern __inline__ void 794 bus_space_set_region_4(t, h, o, v, c) 795 bus_space_tag_t t; 796 bus_space_handle_t h; 797 bus_size_t o, c; 798 const u_int32_t v; 799 { 800 for (; c; c--, o+=4) 801 bus_space_write_4(t, h, o, v); 802 } 803 804 extern __inline__ void 805 bus_space_set_region_8(t, h, o, v, c) 806 bus_space_tag_t t; 807 bus_space_handle_t h; 808 bus_size_t o, c; 809 const u_int64_t v; 810 { 811 for (; c; c--, o+=8) 812 bus_space_write_8(t, h, o, v); 813 } 814 815 816 /* 817 * void bus_space_copy_region_N __P((bus_space_tag_t tag, 818 * bus_space_handle_t bsh1, bus_size_t off1, 819 * bus_space_handle_t bsh2, bus_size_t off2, 820 * bus_size_t count)); 821 * 822 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 823 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 824 */ 825 void bus_space_copy_region_1 __P((bus_space_tag_t, 826 bus_space_handle_t, 827 bus_size_t, 828 bus_space_handle_t, 829 bus_size_t, 830 bus_size_t)); 831 void bus_space_copy_region_2 __P((bus_space_tag_t, 832 bus_space_handle_t, 833 bus_size_t, 834 bus_space_handle_t, 835 bus_size_t, 836 bus_size_t)); 837 void bus_space_copy_region_4 __P((bus_space_tag_t, 838 bus_space_handle_t, 839 bus_size_t, 840 bus_space_handle_t, 841 bus_size_t, 842 bus_size_t)); 843 void bus_space_copy_region_8 __P((bus_space_tag_t, 844 bus_space_handle_t, 845 bus_size_t, 846 bus_space_handle_t, 847 bus_size_t, 848 bus_size_t)); 849 850 851 extern __inline__ void 852 bus_space_copy_region_1(t, h1, o1, h2, o2, c) 853 bus_space_tag_t t; 854 bus_space_handle_t h1, h2; 855 bus_size_t o1, o2; 856 bus_size_t c; 857 { 858 for (; c; c--, o1++, o2++) 859 bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2)); 860 } 861 862 extern __inline__ void 863 bus_space_copy_region_2(t, h1, o1, h2, o2, c) 864 bus_space_tag_t t; 865 bus_space_handle_t h1, h2; 866 bus_size_t o1, o2; 867 bus_size_t c; 868 { 869 for (; c; c--, o1+=2, o2+=2) 870 bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2)); 871 } 872 873 extern __inline__ void 874 bus_space_copy_region_4(t, h1, o1, h2, o2, c) 875 bus_space_tag_t t; 876 bus_space_handle_t h1, h2; 877 bus_size_t o1, o2; 878 bus_size_t c; 879 { 880 for (; c; c--, o1+=4, o2+=4) 881 bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2)); 882 } 883 884 extern __inline__ void 885 bus_space_copy_region_8(t, h1, o1, h2, o2, c) 886 bus_space_tag_t t; 887 bus_space_handle_t h1, h2; 888 bus_size_t o1, o2; 889 bus_size_t c; 890 { 891 for (; c; c--, o1+=8, o2+=8) 892 bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2)); 893 } 894 895 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 896 897 /*--------------------------------*/ 898 899 /* 900 * Flags used in various bus DMA methods. 901 */ 902 #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ 903 #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ 904 #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ 905 #define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */ 906 #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ 907 #define BUS_DMA_BUS2 0x20 908 #define BUS_DMA_BUS3 0x40 909 #define BUS_DMA_BUS4 0x80 910 911 /* For devices that have a 24-bit address space */ 912 #define BUS_DMA_24BIT BUS_DMA_BUS1 913 914 /* Internal flag: current DVMA address is equal to the KVA buffer address */ 915 #define _BUS_DMA_DIRECTMAP BUS_DMA_BUS2 916 917 /* 918 * Internal flag: current DVMA address has been double-mapped by hand 919 * to the KVA buffer address (without the pmap's help). 920 */ 921 #define _BUS_DMA_NOPMAP BUS_DMA_BUS3 922 923 /* Forwards needed by prototypes below. */ 924 struct mbuf; 925 struct uio; 926 927 /* 928 * Operations performed by bus_dmamap_sync(). 929 */ 930 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ 931 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ 932 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ 933 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ 934 935 typedef struct sun2_bus_dma_tag *bus_dma_tag_t; 936 typedef struct sun2_bus_dmamap *bus_dmamap_t; 937 938 /* 939 * bus_dma_segment_t 940 * 941 * Describes a single contiguous DMA transaction. Values 942 * are suitable for programming into DMA registers. 943 */ 944 struct sun2_bus_dma_segment { 945 bus_addr_t ds_addr; /* DVMA address */ 946 bus_size_t ds_len; /* length of transfer */ 947 bus_size_t _ds_sgsize; /* size of allocated DVMA segment */ 948 void *_ds_mlist; /* page list when dmamem_alloc'ed */ 949 vaddr_t _ds_va; /* VA when dmamem_map'ed */ 950 }; 951 typedef struct sun2_bus_dma_segment bus_dma_segment_t; 952 953 954 /* 955 * bus_dma_tag_t 956 * 957 * A machine-dependent opaque type describing the implementation of 958 * DMA for a given bus. 959 */ 960 struct sun2_bus_dma_tag { 961 void *_cookie; /* cookie used in the guts */ 962 963 /* 964 * DMA mapping methods. 965 */ 966 int (*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int, 967 bus_size_t, bus_size_t, int, bus_dmamap_t *)); 968 void (*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t)); 969 int (*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *, 970 bus_size_t, struct proc *, int)); 971 int (*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t, 972 struct mbuf *, int)); 973 int (*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t, 974 struct uio *, int)); 975 int (*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t, 976 bus_dma_segment_t *, int, bus_size_t, int)); 977 void (*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t)); 978 void (*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t, 979 bus_addr_t, bus_size_t, int)); 980 981 /* 982 * DMA memory utility functions. 983 */ 984 int (*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t, 985 bus_size_t, bus_dma_segment_t *, int, int *, int)); 986 void (*_dmamem_free) __P((bus_dma_tag_t, 987 bus_dma_segment_t *, int)); 988 int (*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *, 989 int, size_t, caddr_t *, int)); 990 void (*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t)); 991 paddr_t (*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *, 992 int, off_t, int, int)); 993 }; 994 995 #define bus_dmamap_create(t, s, n, m, b, f, p) \ 996 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 997 #define bus_dmamap_destroy(t, p) \ 998 (*(t)->_dmamap_destroy)((t), (p)) 999 #define bus_dmamap_load(t, m, b, s, p, f) \ 1000 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 1001 #define bus_dmamap_load_mbuf(t, m, b, f) \ 1002 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 1003 #define bus_dmamap_load_uio(t, m, u, f) \ 1004 (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 1005 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 1006 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 1007 #define bus_dmamap_unload(t, p) \ 1008 (*(t)->_dmamap_unload)((t), (p)) 1009 #define bus_dmamap_sync(t, p, o, l, ops) \ 1010 (void)((t)->_dmamap_sync ? \ 1011 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0) 1012 1013 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 1014 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 1015 #define bus_dmamem_free(t, sg, n) \ 1016 (*(t)->_dmamem_free)((t), (sg), (n)) 1017 #define bus_dmamem_map(t, sg, n, s, k, f) \ 1018 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 1019 #define bus_dmamem_unmap(t, k, s) \ 1020 (*(t)->_dmamem_unmap)((t), (k), (s)) 1021 #define bus_dmamem_mmap(t, sg, n, o, p, f) \ 1022 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 1023 1024 /* 1025 * bus_dmamap_t 1026 * 1027 * Describes a DMA mapping. 1028 */ 1029 struct sun2_bus_dmamap { 1030 /* 1031 * PRIVATE MEMBERS: not for use by machine-independent code. 1032 */ 1033 bus_size_t _dm_size; /* largest DMA transfer mappable */ 1034 int _dm_segcnt; /* number of segs this map can map */ 1035 bus_size_t _dm_maxsegsz; /* largest possible segment */ 1036 bus_size_t _dm_boundary; /* don't cross this */ 1037 int _dm_flags; /* misc. flags */ 1038 1039 void *_dm_cookie; /* cookie for bus-specific functions */ 1040 1041 u_long _dm_align; /* DVMA alignment; must be a 1042 multiple of the page size */ 1043 u_long _dm_ex_start; /* constraints on DVMA map */ 1044 u_long _dm_ex_end; /* allocations; used by the VME bus 1045 driver and by the IOMMU driver 1046 when mapping 24-bit devices */ 1047 1048 /* 1049 * PUBLIC MEMBERS: these are used by machine-independent code. 1050 */ 1051 bus_size_t dm_mapsize; /* size of the mapping */ 1052 int dm_nsegs; /* # valid segments in mapping */ 1053 bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 1054 }; 1055 1056 #ifdef _SUN2_BUS_DMA_PRIVATE 1057 int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t, 1058 bus_size_t, int, bus_dmamap_t *)); 1059 void _bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t)); 1060 int _bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t, 1061 struct mbuf *, int)); 1062 int _bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t, 1063 struct uio *, int)); 1064 int _bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t, 1065 bus_dma_segment_t *, int, bus_size_t, int)); 1066 int _bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *, 1067 bus_size_t, struct proc *, int)); 1068 void _bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t)); 1069 void _bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 1070 bus_size_t, int)); 1071 1072 int _bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size, 1073 bus_size_t alignment, bus_size_t boundary, 1074 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags)); 1075 void _bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1076 int nsegs)); 1077 int _bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1078 int nsegs, size_t size, caddr_t *kvap, 1079 int flags)); 1080 void _bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva, 1081 size_t size)); 1082 paddr_t _bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1083 int nsegs, off_t off, int prot, int flags)); 1084 1085 int _bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size, 1086 bus_size_t alignment, bus_size_t boundary, 1087 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 1088 vaddr_t low, vaddr_t high)); 1089 1090 vaddr_t _bus_dma_valloc_skewed(size_t, u_long, u_long, u_long); 1091 #endif /* _SUN2_BUS_DMA_PRIVATE */ 1092 1093 #endif /* _SUN2_BUS_H_ */ 1094