1 /* $OpenBSD: bus.h,v 1.2 2001/08/20 20:23:52 jason Exp $ */ 2 /* $NetBSD: bus.h,v 1.28 2001/07/19 15:32:19 thorpej Exp $ */ 3 4 /*- 5 * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 /* 42 * Copyright (c) 1997-1999 Eduardo E. Horvath. All rights reserved. 43 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 44 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by Christopher G. Demetriou 57 * for the NetBSD Project. 58 * 4. The name of the author may not be used to endorse or promote products 59 * derived from this software without specific prior written permission 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 62 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 63 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 64 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 65 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 66 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 67 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 68 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 69 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 70 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 71 */ 72 73 #ifndef _SPARC_BUS_H_ 74 #define _SPARC_BUS_H_ 75 76 #include <machine/types.h> 77 #include <machine/ctlreg.h> 78 79 /* 80 * Debug hooks 81 */ 82 83 #define BSDB_ACCESS 0x01 84 #define BSDB_MAP 0x02 85 extern int bus_space_debug; 86 87 /* 88 * UPA and SBUS spaces are non-cached and big endian 89 * (except for RAM and PROM) 90 * 91 * PCI spaces are non-cached and little endian 92 */ 93 94 enum bus_type { 95 UPA_BUS_SPACE, 96 SBUS_BUS_SPACE, 97 PCI_CONFIG_BUS_SPACE, 98 PCI_IO_BUS_SPACE, 99 PCI_MEMORY_BUS_SPACE, 100 LAST_BUS_SPACE 101 }; 102 extern int bus_type_asi[]; 103 extern int bus_stream_asi[]; 104 /* For backwards compatibility */ 105 #define SPARC_BUS_SPACE UPA_BUS_SPACE 106 107 #define __BUS_SPACE_HAS_STREAM_METHODS 1 108 109 /* 110 * Bus address and size types 111 */ 112 typedef u_int64_t bus_space_handle_t; 113 typedef enum bus_type bus_type_t; 114 typedef u_int64_t bus_addr_t; 115 typedef u_int64_t bus_size_t; 116 117 /* 118 * Access methods for bus resources and address space. 119 */ 120 typedef struct sparc_bus_space_tag *bus_space_tag_t; 121 122 struct sparc_bus_space_tag { 123 void *cookie; 124 bus_space_tag_t parent; 125 int type; 126 127 int (*sparc_bus_map) __P(( 128 bus_space_tag_t, 129 bus_type_t, 130 bus_addr_t, 131 bus_size_t, 132 int, /*flags*/ 133 vaddr_t, /*preferred vaddr*/ 134 bus_space_handle_t *)); 135 int (*sparc_bus_unmap) __P(( 136 bus_space_tag_t, 137 bus_space_handle_t, 138 bus_size_t)); 139 int (*sparc_bus_subregion) __P(( 140 bus_space_tag_t, 141 bus_space_handle_t, 142 bus_size_t, /*offset*/ 143 bus_size_t, /*size*/ 144 bus_space_handle_t *)); 145 146 void (*sparc_bus_barrier) __P(( 147 bus_space_tag_t, 148 bus_space_handle_t, 149 bus_size_t, /*offset*/ 150 bus_size_t, /*size*/ 151 int)); /*flags*/ 152 153 int (*sparc_bus_mmap) __P(( 154 bus_space_tag_t, 155 bus_type_t, /**/ 156 bus_addr_t, /**/ 157 int, /*flags*/ 158 bus_space_handle_t *)); 159 160 void *(*sparc_intr_establish) __P(( 161 bus_space_tag_t, 162 int, /*bus-specific intr*/ 163 int, /*device class level, 164 see machine/intr.h*/ 165 int, /*flags*/ 166 int (*) __P((void *)), /*handler*/ 167 void *)); /*handler arg*/ 168 169 }; 170 171 #if 0 172 /* 173 * The following macro could be used to generate the bus_space*() functions 174 * but it uses a gcc extension and is ANSI-only. 175 #define PROTO_bus_space_xxx __P((bus_space_tag_t t, ...)) 176 #define RETURNTYPE_bus_space_xxx void * 177 #define BUSFUN(name, returntype, t, args...) \ 178 __inline__ RETURNTYPE_##name \ 179 bus_##name PROTO_##name \ 180 { \ 181 while (t->sparc_##name == NULL) \ 182 t = t->parent; \ 183 return (*(t)->sparc_##name)(t, args); \ 184 } 185 */ 186 #endif 187 188 /* 189 * Bus space function prototypes. 190 */ 191 static int bus_space_map __P(( 192 bus_space_tag_t, 193 bus_addr_t, 194 bus_size_t, 195 int, /*flags*/ 196 bus_space_handle_t *)); 197 static int bus_space_map2 __P(( 198 bus_space_tag_t, 199 bus_type_t, 200 bus_addr_t, 201 bus_size_t, 202 int, /*flags*/ 203 vaddr_t, /*preferred vaddr*/ 204 bus_space_handle_t *)); 205 static int bus_space_unmap __P(( 206 bus_space_tag_t, 207 bus_space_handle_t, 208 bus_size_t)); 209 static int bus_space_subregion __P(( 210 bus_space_tag_t, 211 bus_space_handle_t, 212 bus_size_t, 213 bus_size_t, 214 bus_space_handle_t *)); 215 static void bus_space_barrier __P(( 216 bus_space_tag_t, 217 bus_space_handle_t, 218 bus_size_t, 219 bus_size_t, 220 int)); 221 static int bus_space_mmap __P(( 222 bus_space_tag_t, 223 bus_type_t, /**/ 224 bus_addr_t, /**/ 225 int, /*flags*/ 226 bus_space_handle_t *)); 227 static void *bus_intr_establish __P(( 228 bus_space_tag_t, 229 int, /*bus-specific intr*/ 230 int, /*device class level, 231 see machine/intr.h*/ 232 int, /*flags*/ 233 int (*) __P((void *)), /*handler*/ 234 void *)); /*handler arg*/ 235 236 237 /* This macro finds the first "upstream" implementation of method `f' */ 238 #define _BS_CALL(t,f) \ 239 while (t->f == NULL) \ 240 t = t->parent; \ 241 return (*(t)->f) 242 243 __inline__ int 244 bus_space_map(t, a, s, f, hp) 245 bus_space_tag_t t; 246 bus_addr_t a; 247 bus_size_t s; 248 int f; 249 bus_space_handle_t *hp; 250 { 251 _BS_CALL(t, sparc_bus_map)((t), 0, (a), (s), (f), 0, (hp)); 252 } 253 254 __inline__ int 255 bus_space_map2(t, bt, a, s, f, v, hp) 256 bus_space_tag_t t; 257 bus_type_t bt; 258 bus_addr_t a; 259 bus_size_t s; 260 int f; 261 vaddr_t v; 262 bus_space_handle_t *hp; 263 { 264 _BS_CALL(t, sparc_bus_map)(t, bt, a, s, f, v, hp); 265 } 266 267 __inline__ int 268 bus_space_unmap(t, h, s) 269 bus_space_tag_t t; 270 bus_space_handle_t h; 271 bus_size_t s; 272 { 273 _BS_CALL(t, sparc_bus_unmap)(t, h, s); 274 } 275 276 __inline__ int 277 bus_space_subregion(t, h, o, s, hp) 278 bus_space_tag_t t; 279 bus_space_handle_t h; 280 bus_size_t o; 281 bus_size_t s; 282 bus_space_handle_t *hp; 283 { 284 _BS_CALL(t, sparc_bus_subregion)(t, h, o, s, hp); 285 } 286 287 __inline__ int 288 bus_space_mmap(t, bt, a, f, hp) 289 bus_space_tag_t t; 290 bus_type_t bt; 291 bus_addr_t a; 292 int f; 293 bus_space_handle_t *hp; 294 { 295 _BS_CALL(t, sparc_bus_mmap)(t, bt, a, f, hp); 296 } 297 298 __inline__ void * 299 bus_intr_establish(t, p, l, f, h, a) 300 bus_space_tag_t t; 301 int p; 302 int l; 303 int f; 304 int (*h)__P((void *)); 305 void *a; 306 { 307 _BS_CALL(t, sparc_intr_establish)(t, p, l, f, h, a); 308 } 309 310 __inline__ void 311 bus_space_barrier(t, h, o, s, f) 312 bus_space_tag_t t; 313 bus_space_handle_t h; 314 bus_size_t o; 315 bus_size_t s; 316 int f; 317 { 318 _BS_CALL(t, sparc_bus_barrier)(t, h, o, s, f); 319 } 320 321 322 #if 0 323 int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart, 324 bus_addr_t rend, bus_size_t size, bus_size_t align, 325 bus_size_t boundary, int flags, bus_addr_t *addrp, 326 bus_space_handle_t *bshp)); 327 void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh, 328 bus_size_t size)); 329 #endif 330 331 /* flags for bus space map functions */ 332 #define BUS_SPACE_MAP_CACHEABLE 0x0001 333 #define BUS_SPACE_MAP_LINEAR 0x0002 334 #define BUS_SPACE_MAP_READONLY 0x0004 335 #define BUS_SPACE_MAP_PREFETCHABLE 0x0008 336 #define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */ 337 #define BUS_SPACE_MAP_BUS2 0x0200 338 #define BUS_SPACE_MAP_BUS3 0x0400 339 #define BUS_SPACE_MAP_BUS4 0x0800 340 341 342 /* flags for intr_establish() */ 343 #define BUS_INTR_ESTABLISH_FASTTRAP 1 344 #define BUS_INTR_ESTABLISH_SOFTINTR 2 345 346 /* flags for bus_space_barrier() */ 347 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 348 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 349 350 /* 351 * Device space probe assistant. 352 * The optional callback function's arguments are: 353 * the temporary virtual address 354 * the passed `arg' argument 355 */ 356 int bus_space_probe __P(( 357 bus_space_tag_t, 358 bus_type_t, 359 bus_addr_t, 360 bus_size_t, /* probe size */ 361 size_t, /* offset */ 362 int, /* flags */ 363 int (*) __P((void *, void *)), /* callback function */ 364 void *)); /* callback arg */ 365 366 367 /* 368 * u_intN_t bus_space_read_N __P((bus_space_tag_t tag, 369 * bus_space_handle_t bsh, bus_size_t offset)); 370 * 371 * Read a 1, 2, 4, or 8 byte quantity from bus space 372 * described by tag/handle/offset. 373 */ 374 #ifndef BUS_SPACE_DEBUG 375 #define bus_space_read_1(t, h, o) \ 376 lduba((h) + (o), bus_type_asi[(t)->type]) 377 378 #define bus_space_read_2(t, h, o) \ 379 lduha((h) + (o), bus_type_asi[(t)->type]) 380 381 #define bus_space_read_4(t, h, o) \ 382 lda((h) + (o), bus_type_asi[(t)->type]) 383 384 #define bus_space_read_8(t, h, o) \ 385 ldxa((h) + (o), bus_type_asi[(t)->type]) 386 #else 387 #define bus_space_read_1(t, h, o) ({ \ 388 unsigned char __bv = \ 389 lduba((h) + (o), bus_type_asi[(t)->type]); \ 390 if (bus_space_debug & BSDB_ACCESS) \ 391 printf("bsr1(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \ 392 (u_int64_t)(o), \ 393 bus_type_asi[(t)->type], (unsigned int) __bv); \ 394 __bv; }) 395 396 #define bus_space_read_2(t, h, o) ({ \ 397 unsigned short __bv = \ 398 lduha((h) + (o), bus_type_asi[(t)->type]); \ 399 if (bus_space_debug & BSDB_ACCESS) \ 400 printf("bsr2(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \ 401 (u_int64_t)(o), \ 402 bus_type_asi[(t)->type], (unsigned int)__bv); \ 403 __bv; }) 404 405 #define bus_space_read_4(t, h, o) ({ \ 406 unsigned int __bv = \ 407 lda((h) + (o), bus_type_asi[(t)->type]); \ 408 if (bus_space_debug & BSDB_ACCESS) \ 409 printf("bsr4(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \ 410 (u_int64_t)(o), \ 411 bus_type_asi[(t)->type], __bv); \ 412 __bv; }) 413 414 #define bus_space_read_8(t, h, o) ({ \ 415 u_int64_t __bv = \ 416 ldxa((h) + (o), bus_type_asi[(t)->type]); \ 417 if (bus_space_debug & BSDB_ACCESS) \ 418 printf("bsr8(%llx + %llx, %x) -> %llx\n", (u_int64_t)(h), \ 419 (u_int64_t)(o), \ 420 bus_type_asi[(t)->type], __bv); \ 421 __bv; }) 422 #endif 423 /* 424 * void bus_space_read_multi_N __P((bus_space_tag_t tag, 425 * bus_space_handle_t bsh, bus_size_t offset, 426 * u_intN_t *addr, size_t count)); 427 * 428 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 429 * described by tag/handle/offset and copy into buffer provided. 430 */ 431 432 #define bus_space_read_multi_1(t, h, o, a, c) do { \ 433 int i = c; \ 434 u_int8_t *p = (u_int8_t *)a; \ 435 while (i-- > 0) \ 436 *p++ = bus_space_read_1(t, h, o); \ 437 } while (0) 438 439 #define bus_space_read_multi_2(t, h, o, a, c) do { \ 440 int i = c; \ 441 u_int16_t *p = (u_int16_t *)a; \ 442 while (i-- > 0) \ 443 *p++ = bus_space_read_2(t, h, o); \ 444 } while (0) 445 446 #define bus_space_read_multi_4(t, h, o, a, c) do { \ 447 int i = c; \ 448 u_int32_t *p = (u_int32_t *)a; \ 449 while (i-- > 0) \ 450 *p++ = bus_space_read_4(t, h, o); \ 451 } while (0) 452 453 #define bus_space_read_multi_8(t, h, o, a, c) do { \ 454 int i = c; \ 455 u_int64_t *p = (u_int64_t *)a; \ 456 while (i-- > 0) \ 457 *p++ = bus_space_read_8(t, h, o); \ 458 } while (0) 459 460 /* 461 * void bus_space_write_N __P((bus_space_tag_t tag, 462 * bus_space_handle_t bsh, bus_size_t offset, 463 * u_intN_t value)); 464 * 465 * Write the 1, 2, 4, or 8 byte value `value' to bus space 466 * described by tag/handle/offset. 467 */ 468 #ifndef BUS_SPACE_DEBUG 469 #define bus_space_write_1(t, h, o, v) \ 470 ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v)))) 471 472 #define bus_space_write_2(t, h, o, v) \ 473 ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v)))) 474 475 #define bus_space_write_4(t, h, o, v) \ 476 ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v)))) 477 478 #define bus_space_write_8(t, h, o, v) \ 479 ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v)))) 480 #else 481 #define bus_space_write_1(t, h, o, v) ({ \ 482 if (bus_space_debug & BSDB_ACCESS) \ 483 printf("bsw1(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \ 484 (u_int64_t)(o), \ 485 bus_type_asi[(t)->type], (unsigned int) v); \ 486 ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v)))); }) 487 488 #define bus_space_write_2(t, h, o, v) ({ \ 489 if (bus_space_debug & BSDB_ACCESS) \ 490 printf("bsw2(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \ 491 (u_int64_t)(o), \ 492 bus_type_asi[(t)->type], (unsigned int) v); \ 493 ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v)))); }) 494 495 #define bus_space_write_4(t, h, o, v) ({ \ 496 if (bus_space_debug & BSDB_ACCESS) \ 497 printf("bsw4(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \ 498 (u_int64_t)(o), \ 499 bus_type_asi[(t)->type], (unsigned int) v); \ 500 ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v)))); }) 501 502 #define bus_space_write_8(t, h, o, v) ({ \ 503 if (bus_space_debug & BSDB_ACCESS) \ 504 printf("bsw8(%llx + %llx, %x) <- %llx\n", (u_int64_t)(h), \ 505 (u_int64_t)(o), \ 506 bus_type_asi[(t)->type], (u_int64_t) v); \ 507 ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v)))); }) 508 #endif 509 /* 510 * void bus_space_write_multi_N __P((bus_space_tag_t tag, 511 * bus_space_handle_t bsh, bus_size_t offset, 512 * const u_intN_t *addr, size_t count)); 513 * 514 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 515 * provided to bus space described by tag/handle/offset. 516 */ 517 518 #define bus_space_write_multi_1(t, h, o, a, c) do { \ 519 int i = c; \ 520 u_int8_t *p = (u_int8_t *)a; \ 521 while (i-- > 0) \ 522 bus_space_write_1(t, h, o, *p++); \ 523 } while (0) 524 525 #define bus_space_write_multi_2(t, h, o, a, c) do { \ 526 int i = c; \ 527 u_int16_t *p = (u_int16_t *)a; \ 528 while (i-- > 0) \ 529 bus_space_write_2(t, h, o, *p++); \ 530 } while (0) 531 532 #define bus_space_write_multi_4(t, h, o, a, c) do { \ 533 int i = c; \ 534 u_int32_t *p = (u_int32_t *)a; \ 535 while (i-- > 0) \ 536 bus_space_write_4(t, h, o, *p++); \ 537 } while (0) 538 539 #define bus_space_write_multi_8(t, h, o, a, c) do { \ 540 int i = c; \ 541 u_int64_t *p = (u_int64_t *)a; \ 542 while (i-- > 0) \ 543 bus_space_write_8(t, h, o, *p++); \ 544 } while (0) 545 546 /* 547 * void bus_space_set_multi_N __P((bus_space_tag_t tag, 548 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 549 * size_t count)); 550 * 551 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 552 * by tag/handle/offset `count' times. 553 */ 554 555 #define bus_space_set_multi_1(t, h, o, v, c) do { \ 556 int i = c; \ 557 while (i-- > 0) \ 558 bus_space_write_1(t, h, o, v); \ 559 } while (0) 560 561 #define bus_space_set_multi_2(t, h, o, v, c) do { \ 562 int i = c; \ 563 while (i-- > 0) \ 564 bus_space_write_2(t, h, o, v); \ 565 } while (0) 566 567 #define bus_space_set_multi_4(t, h, o, v, c) do { \ 568 int i = c; \ 569 while (i-- > 0) \ 570 bus_space_write_4(t, h, o, v); \ 571 } while (0) 572 573 #define bus_space_set_multi_8(t, h, o, v, c) do { \ 574 int i = c; \ 575 while (i-- > 0) \ 576 bus_space_write_8(t, h, o, v); \ 577 } while (0) 578 579 /* 580 * void bus_space_read_region_N __P((bus_space_tag_t tag, 581 * bus_space_handle_t bsh, bus_size_t off, 582 * u_intN_t *addr, bus_size_t count)); 583 * 584 */ 585 static void bus_space_read_region_1 __P((bus_space_tag_t, 586 bus_space_handle_t, 587 bus_size_t, 588 u_int8_t *, 589 bus_size_t)); 590 static void bus_space_read_region_2 __P((bus_space_tag_t, 591 bus_space_handle_t, 592 bus_size_t, 593 u_int16_t *, 594 bus_size_t)); 595 static void bus_space_read_region_4 __P((bus_space_tag_t, 596 bus_space_handle_t, 597 bus_size_t, 598 u_int32_t *, 599 bus_size_t)); 600 static void bus_space_read_region_8 __P((bus_space_tag_t, 601 bus_space_handle_t, 602 bus_size_t, 603 u_int64_t *, 604 bus_size_t)); 605 606 static __inline__ void 607 bus_space_read_region_1(t, h, o, a, c) 608 bus_space_tag_t t; 609 bus_space_handle_t h; 610 bus_size_t o, c; 611 u_int8_t *a; 612 { 613 for (; c; a++, c--, o++) 614 *a = bus_space_read_1(t, h, o); 615 } 616 static __inline__ void 617 bus_space_read_region_2(t, h, o, a, c) 618 bus_space_tag_t t; 619 bus_space_handle_t h; 620 bus_size_t o, c; 621 u_int16_t *a; 622 { 623 for (; c; a++, c--, o+=2) 624 *a = bus_space_read_2(t, h, o); 625 } 626 static __inline__ void 627 bus_space_read_region_4(t, h, o, a, c) 628 bus_space_tag_t t; 629 bus_space_handle_t h; 630 bus_size_t o, c; 631 u_int32_t *a; 632 { 633 for (; c; a++, c--, o+=4) 634 *a = bus_space_read_4(t, h, o); 635 } 636 static __inline__ void 637 bus_space_read_region_8(t, h, o, a, c) 638 bus_space_tag_t t; 639 bus_space_handle_t h; 640 bus_size_t o, c; 641 u_int64_t *a; 642 { 643 for (; c; a++, c--, o+=8) 644 *a = bus_space_read_8(t, h, o); 645 } 646 647 /* 648 * void bus_space_write_region_N __P((bus_space_tag_t tag, 649 * bus_space_handle_t bsh, bus_size_t off, 650 * u_intN_t *addr, bus_size_t count)); 651 * 652 */ 653 static void bus_space_write_region_1 __P((bus_space_tag_t, 654 bus_space_handle_t, 655 bus_size_t, 656 const u_int8_t *, 657 bus_size_t)); 658 static void bus_space_write_region_2 __P((bus_space_tag_t, 659 bus_space_handle_t, 660 bus_size_t, 661 const u_int16_t *, 662 bus_size_t)); 663 static void bus_space_write_region_4 __P((bus_space_tag_t, 664 bus_space_handle_t, 665 bus_size_t, 666 const u_int32_t *, 667 bus_size_t)); 668 static void bus_space_write_region_8 __P((bus_space_tag_t, 669 bus_space_handle_t, 670 bus_size_t, 671 const u_int64_t *, 672 bus_size_t)); 673 static __inline__ void 674 bus_space_write_region_1(t, h, o, a, c) 675 bus_space_tag_t t; 676 bus_space_handle_t h; 677 bus_size_t o, c; 678 const u_int8_t *a; 679 { 680 for (; c; a++, c--, o++) 681 bus_space_write_1(t, h, o, *a); 682 } 683 684 static __inline__ void 685 bus_space_write_region_2(t, h, o, a, c) 686 bus_space_tag_t t; 687 bus_space_handle_t h; 688 bus_size_t o, c; 689 const u_int16_t *a; 690 { 691 for (; c; a++, c--, o+=2) 692 bus_space_write_2(t, h, o, *a); 693 } 694 695 static __inline__ void 696 bus_space_write_region_4(t, h, o, a, c) 697 bus_space_tag_t t; 698 bus_space_handle_t h; 699 bus_size_t o, c; 700 const u_int32_t *a; 701 { 702 for (; c; a++, c--, o+=4) 703 bus_space_write_4(t, h, o, *a); 704 } 705 706 static __inline__ void 707 bus_space_write_region_8(t, h, o, a, c) 708 bus_space_tag_t t; 709 bus_space_handle_t h; 710 bus_size_t o, c; 711 const u_int64_t *a; 712 { 713 for (; c; a++, c--, o+=8) 714 bus_space_write_8(t, h, o, *a); 715 } 716 717 718 /* 719 * void bus_space_set_region_N __P((bus_space_tag_t tag, 720 * bus_space_handle_t bsh, bus_size_t off, 721 * u_intN_t *addr, bus_size_t count)); 722 * 723 */ 724 static void bus_space_set_region_1 __P((bus_space_tag_t, 725 bus_space_handle_t, 726 bus_size_t, 727 const u_int8_t, 728 bus_size_t)); 729 static void bus_space_set_region_2 __P((bus_space_tag_t, 730 bus_space_handle_t, 731 bus_size_t, 732 const u_int16_t, 733 bus_size_t)); 734 static void bus_space_set_region_4 __P((bus_space_tag_t, 735 bus_space_handle_t, 736 bus_size_t, 737 const u_int32_t, 738 bus_size_t)); 739 static void bus_space_set_region_8 __P((bus_space_tag_t, 740 bus_space_handle_t, 741 bus_size_t, 742 const u_int64_t, 743 bus_size_t)); 744 745 static __inline__ void 746 bus_space_set_region_1(t, h, o, v, c) 747 bus_space_tag_t t; 748 bus_space_handle_t h; 749 bus_size_t o, c; 750 const u_int8_t v; 751 { 752 for (; c; c--, o++) 753 bus_space_write_1(t, h, o, v); 754 } 755 756 static __inline__ void 757 bus_space_set_region_2(t, h, o, v, c) 758 bus_space_tag_t t; 759 bus_space_handle_t h; 760 bus_size_t o, c; 761 const u_int16_t v; 762 { 763 for (; c; c--, o+=2) 764 bus_space_write_2(t, h, o, v); 765 } 766 767 static __inline__ void 768 bus_space_set_region_4(t, h, o, v, c) 769 bus_space_tag_t t; 770 bus_space_handle_t h; 771 bus_size_t o, c; 772 const u_int32_t v; 773 { 774 for (; c; c--, o+=4) 775 bus_space_write_4(t, h, o, v); 776 } 777 778 static __inline__ void 779 bus_space_set_region_8(t, h, o, v, c) 780 bus_space_tag_t t; 781 bus_space_handle_t h; 782 bus_size_t o, c; 783 const u_int64_t v; 784 { 785 for (; c; c--, o+=8) 786 bus_space_write_8(t, h, o, v); 787 } 788 789 790 /* 791 * void bus_space_copy_region_N __P((bus_space_tag_t tag, 792 * bus_space_handle_t bsh1, bus_size_t off1, 793 * bus_space_handle_t bsh2, bus_size_t off2, 794 * bus_size_t count)); 795 * 796 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 797 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 798 */ 799 static void bus_space_copy_region_1 __P((bus_space_tag_t, 800 bus_space_handle_t, 801 bus_size_t, 802 bus_space_handle_t, 803 bus_size_t, 804 bus_size_t)); 805 static void bus_space_copy_region_2 __P((bus_space_tag_t, 806 bus_space_handle_t, 807 bus_size_t, 808 bus_space_handle_t, 809 bus_size_t, 810 bus_size_t)); 811 static void bus_space_copy_region_4 __P((bus_space_tag_t, 812 bus_space_handle_t, 813 bus_size_t, 814 bus_space_handle_t, 815 bus_size_t, 816 bus_size_t)); 817 static void bus_space_copy_region_8 __P((bus_space_tag_t, 818 bus_space_handle_t, 819 bus_size_t, 820 bus_space_handle_t, 821 bus_size_t, 822 bus_size_t)); 823 824 825 static __inline__ void 826 bus_space_copy_region_1(t, h1, o1, h2, o2, c) 827 bus_space_tag_t t; 828 bus_space_handle_t h1, h2; 829 bus_size_t o1, o2; 830 bus_size_t c; 831 { 832 for (; c; c--, o1++, o2++) 833 bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2)); 834 } 835 836 static __inline__ void 837 bus_space_copy_region_2(t, h1, o1, h2, o2, c) 838 bus_space_tag_t t; 839 bus_space_handle_t h1, h2; 840 bus_size_t o1, o2; 841 bus_size_t c; 842 { 843 for (; c; c--, o1+=2, o2+=2) 844 bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2)); 845 } 846 847 static __inline__ void 848 bus_space_copy_region_4(t, h1, o1, h2, o2, c) 849 bus_space_tag_t t; 850 bus_space_handle_t h1, h2; 851 bus_size_t o1, o2; 852 bus_size_t c; 853 { 854 for (; c; c--, o1+=4, o2+=4) 855 bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2)); 856 } 857 858 static __inline__ void 859 bus_space_copy_region_8(t, h1, o1, h2, o2, c) 860 bus_space_tag_t t; 861 bus_space_handle_t h1, h2; 862 bus_size_t o1, o2; 863 bus_size_t c; 864 { 865 for (; c; c--, o1+=8, o2+=8) 866 bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2)); 867 } 868 869 /* 870 * u_intN_t bus_space_read_stream_N __P((bus_space_tag_t tag, 871 * bus_space_handle_t bsh, bus_size_t offset)); 872 * 873 * Read a 1, 2, 4, or 8 byte quantity from bus space 874 * described by tag/handle/offset. 875 */ 876 #ifndef BUS_SPACE_DEBUG 877 #define bus_space_read_stream_1(t, h, o) \ 878 lduba((h) + (o), bus_stream_asi[(t)->type]) 879 880 #define bus_space_read_stream_2(t, h, o) \ 881 lduha((h) + (o), bus_stream_asi[(t)->type]) 882 883 #define bus_space_read_stream_4(t, h, o) \ 884 lda((h) + (o), bus_stream_asi[(t)->type]) 885 886 #define bus_space_read_stream_8(t, h, o) \ 887 ldxa((h) + (o), bus_stream_asi[(t)->type]) 888 #else 889 #define bus_space_read_stream_1(t, h, o) ({ \ 890 unsigned char __bv = \ 891 lduba((h) + (o), bus_stream_asi[(t)->type]); \ 892 if (bus_space_debug & BSDB_ACCESS) \ 893 printf("bsr1(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \ 894 (u_int64_t)(o), \ 895 bus_stream_asi[(t)->type], (unsigned int) __bv); \ 896 __bv; }) 897 898 #define bus_space_read_stream_2(t, h, o) ({ \ 899 unsigned short __bv = \ 900 lduha((h) + (o), bus_stream_asi[(t)->type]); \ 901 if (bus_space_debug & BSDB_ACCESS) \ 902 printf("bsr2(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \ 903 (u_int64_t)(o), \ 904 bus_stream_asi[(t)->type], (unsigned int)__bv); \ 905 __bv; }) 906 907 #define bus_space_read_stream_4(t, h, o) ({ \ 908 unsigned int __bv = \ 909 lda((h) + (o), bus_stream_asi[(t)->type]); \ 910 if (bus_space_debug & BSDB_ACCESS) \ 911 printf("bsr4(%llx + %llx, %x) -> %x\n", (u_int64_t)(h), \ 912 (u_int64_t)(o), \ 913 bus_stream_asi[(t)->type], __bv); \ 914 __bv; }) 915 916 #define bus_space_read_stream_8(t, h, o) ({ \ 917 u_int64_t __bv = \ 918 ldxa((h) + (o), bus_stream_asi[(t)->type]); \ 919 if (bus_space_debug & BSDB_ACCESS) \ 920 printf("bsr8(%llx + %llx, %x) -> %llx\n", (u_int64_t)(h), \ 921 (u_int64_t)(o), \ 922 bus_stream_asi[(t)->type], __bv); \ 923 __bv; }) 924 #endif 925 /* 926 * void bus_space_read_multi_stream_N __P((bus_space_tag_t tag, 927 * bus_space_handle_t bsh, bus_size_t offset, 928 * u_intN_t *addr, size_t count)); 929 * 930 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 931 * described by tag/handle/offset and copy into buffer provided. 932 */ 933 934 #define bus_space_read_multi_stream_1(t, h, o, a, c) do { \ 935 int i = c; \ 936 u_int8_t *p = (u_int8_t *)a; \ 937 while (i-- > 0) \ 938 *p++ = bus_space_read_stream_1(t, h, o); \ 939 } while (0) 940 941 #define bus_space_read_multi_stream_2(t, h, o, a, c) do { \ 942 int i = c; \ 943 u_int16_t *p = (u_int16_t *)a; \ 944 while (i-- > 0) \ 945 *p++ = bus_space_read_stream_2(t, h, o); \ 946 } while (0) 947 948 #define bus_space_read_multi_stream_4(t, h, o, a, c) do { \ 949 int i = c; \ 950 u_int32_t *p = (u_int32_t *)a; \ 951 while (i-- > 0) \ 952 *p++ = bus_space_read_stream_4(t, h, o); \ 953 } while (0) 954 955 #define bus_space_read_multi_stream_8(t, h, o, a, c) do { \ 956 int i = c; \ 957 u_int64_t *p = (u_int64_t *)a; \ 958 while (i-- > 0) \ 959 *p++ = bus_space_read_stream_8(t, h, o); \ 960 } while (0) 961 962 /* 963 * void bus_space_write_stream_N __P((bus_space_tag_t tag, 964 * bus_space_handle_t bsh, bus_size_t offset, 965 * u_intN_t value)); 966 * 967 * Write the 1, 2, 4, or 8 byte value `value' to bus space 968 * described by tag/handle/offset. 969 */ 970 #ifndef BUS_SPACE_DEBUG 971 #define bus_space_write_stream_1(t, h, o, v) \ 972 ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v)))) 973 974 #define bus_space_write_stream_2(t, h, o, v) \ 975 ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v)))) 976 977 #define bus_space_write_stream_4(t, h, o, v) \ 978 ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v)))) 979 980 #define bus_space_write_stream_8(t, h, o, v) \ 981 ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v)))) 982 #else 983 #define bus_space_write_stream_1(t, h, o, v) ({ \ 984 if (bus_space_debug & BSDB_ACCESS) \ 985 printf("bsw1(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \ 986 (u_int64_t)(o), \ 987 bus_stream_asi[(t)->type], (unsigned int) v); \ 988 ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v)))); }) 989 990 #define bus_space_write_stream_2(t, h, o, v) ({ \ 991 if (bus_space_debug & BSDB_ACCESS) \ 992 printf("bsw2(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \ 993 (u_int64_t)(o), \ 994 bus_stream_asi[(t)->type], (unsigned int) v); \ 995 ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v)))); }) 996 997 #define bus_space_write_stream_4(t, h, o, v) ({ \ 998 if (bus_space_debug & BSDB_ACCESS) \ 999 printf("bsw4(%llx + %llx, %x) <- %x\n", (u_int64_t)(h), \ 1000 (u_int64_t)(o), \ 1001 bus_stream_asi[(t)->type], (unsigned int) v); \ 1002 ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v)))); }) 1003 1004 #define bus_space_write_stream_8(t, h, o, v) ({ \ 1005 if (bus_space_debug & BSDB_ACCESS) \ 1006 printf("bsw8(%llx + %llx, %x) <- %llx\n", (u_int64_t)(h), \ 1007 (u_int64_t)(o), \ 1008 bus_stream_asi[(t)->type], (u_int64_t) v); \ 1009 ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v)))); }) 1010 #endif 1011 /* 1012 * void bus_space_write_multi_stream_N __P((bus_space_tag_t tag, 1013 * bus_space_handle_t bsh, bus_size_t offset, 1014 * const u_intN_t *addr, size_t count)); 1015 * 1016 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 1017 * provided to bus space described by tag/handle/offset. 1018 */ 1019 1020 #define bus_space_write_multi_stream_1(t, h, o, a, c) do { \ 1021 int i = c; \ 1022 u_int8_t *p = (u_int8_t *)a; \ 1023 while (i-- > 0) \ 1024 bus_space_write_stream_1(t, h, o, *p++); \ 1025 } while (0) 1026 1027 #define bus_space_write_multi_stream_2(t, h, o, a, c) do { \ 1028 int i = c; \ 1029 u_int16_t *p = (u_int16_t *)a; \ 1030 while (i-- > 0) \ 1031 bus_space_write_stream_2(t, h, o, *p++); \ 1032 } while (0) 1033 1034 #define bus_space_write_multi_stream_4(t, h, o, a, c) do { \ 1035 int i = c; \ 1036 u_int32_t *p = (u_int32_t *)a; \ 1037 while (i-- > 0) \ 1038 bus_space_write_stream_4(t, h, o, *p++); \ 1039 } while (0) 1040 1041 #define bus_space_write_multi_stream_8(t, h, o, a, c) do { \ 1042 int i = c; \ 1043 u_int64_t *p = (u_int64_t *)a; \ 1044 while (i-- > 0) \ 1045 bus_space_write_stream_8(t, h, o, *p++); \ 1046 } while (0) 1047 1048 /* 1049 * void bus_space_set_multi_stream_N __P((bus_space_tag_t tag, 1050 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 1051 * size_t count)); 1052 * 1053 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 1054 * by tag/handle/offset `count' times. 1055 */ 1056 1057 #define bus_space_set_multi_stream_1(t, h, o, v, c) do { \ 1058 int i = c; \ 1059 while (i-- > 0) \ 1060 bus_space_write_stream_1(t, h, o, v); \ 1061 } while (0) 1062 1063 #define bus_space_set_multi_stream_2(t, h, o, v, c) do { \ 1064 int i = c; \ 1065 while (i-- > 0) \ 1066 bus_space_write_stream_2(t, h, o, v); \ 1067 } while (0) 1068 1069 #define bus_space_set_multi_stream_4(t, h, o, v, c) do { \ 1070 int i = c; \ 1071 while (i-- > 0) \ 1072 bus_space_write_stream_4(t, h, o, v); \ 1073 } while (0) 1074 1075 #define bus_space_set_multi_stream_8(t, h, o, v, c) do { \ 1076 int i = c; \ 1077 while (i-- > 0) \ 1078 bus_space_write_stream_8(t, h, o, v); \ 1079 } while (0) 1080 1081 /* 1082 * void bus_space_read_region_stream_N __P((bus_space_tag_t tag, 1083 * bus_space_handle_t bsh, bus_size_t off, 1084 * u_intN_t *addr, bus_size_t count)); 1085 * 1086 */ 1087 static void bus_space_read_region_stream_1 __P((bus_space_tag_t, 1088 bus_space_handle_t, 1089 bus_size_t, 1090 u_int8_t *, 1091 bus_size_t)); 1092 static void bus_space_read_region_stream_2 __P((bus_space_tag_t, 1093 bus_space_handle_t, 1094 bus_size_t, 1095 u_int16_t *, 1096 bus_size_t)); 1097 static void bus_space_read_region_stream_4 __P((bus_space_tag_t, 1098 bus_space_handle_t, 1099 bus_size_t, 1100 u_int32_t *, 1101 bus_size_t)); 1102 static void bus_space_read_region_stream_8 __P((bus_space_tag_t, 1103 bus_space_handle_t, 1104 bus_size_t, 1105 u_int64_t *, 1106 bus_size_t)); 1107 1108 static __inline__ void 1109 bus_space_read_region_stream_1(t, h, o, a, c) 1110 bus_space_tag_t t; 1111 bus_space_handle_t h; 1112 bus_size_t o, c; 1113 u_int8_t *a; 1114 { 1115 for (; c; a++, c--, o++) 1116 *a = bus_space_read_stream_1(t, h, o); 1117 } 1118 static __inline__ void 1119 bus_space_read_region_stream_2(t, h, o, a, c) 1120 bus_space_tag_t t; 1121 bus_space_handle_t h; 1122 bus_size_t o, c; 1123 u_int16_t *a; 1124 { 1125 for (; c; a++, c--, o+=2) 1126 *a = bus_space_read_stream_2(t, h, o); 1127 } 1128 static __inline__ void 1129 bus_space_read_region_stream_4(t, h, o, a, c) 1130 bus_space_tag_t t; 1131 bus_space_handle_t h; 1132 bus_size_t o, c; 1133 u_int32_t *a; 1134 { 1135 for (; c; a++, c--, o+=4) 1136 *a = bus_space_read_stream_4(t, h, o); 1137 } 1138 static __inline__ void 1139 bus_space_read_region_stream_8(t, h, o, a, c) 1140 bus_space_tag_t t; 1141 bus_space_handle_t h; 1142 bus_size_t o, c; 1143 u_int64_t *a; 1144 { 1145 for (; c; a++, c--, o+=8) 1146 *a = bus_space_read_stream_8(t, h, o); 1147 } 1148 1149 /* 1150 * void bus_space_write_region_stream_N __P((bus_space_tag_t tag, 1151 * bus_space_handle_t bsh, bus_size_t off, 1152 * u_intN_t *addr, bus_size_t count)); 1153 * 1154 */ 1155 static void bus_space_write_region_stream_1 __P((bus_space_tag_t, 1156 bus_space_handle_t, 1157 bus_size_t, 1158 const u_int8_t *, 1159 bus_size_t)); 1160 static void bus_space_write_region_stream_2 __P((bus_space_tag_t, 1161 bus_space_handle_t, 1162 bus_size_t, 1163 const u_int16_t *, 1164 bus_size_t)); 1165 static void bus_space_write_region_stream_4 __P((bus_space_tag_t, 1166 bus_space_handle_t, 1167 bus_size_t, 1168 const u_int32_t *, 1169 bus_size_t)); 1170 static void bus_space_write_region_stream_8 __P((bus_space_tag_t, 1171 bus_space_handle_t, 1172 bus_size_t, 1173 const u_int64_t *, 1174 bus_size_t)); 1175 static __inline__ void 1176 bus_space_write_region_stream_1(t, h, o, a, c) 1177 bus_space_tag_t t; 1178 bus_space_handle_t h; 1179 bus_size_t o, c; 1180 const u_int8_t *a; 1181 { 1182 for (; c; a++, c--, o++) 1183 bus_space_write_stream_1(t, h, o, *a); 1184 } 1185 1186 static __inline__ void 1187 bus_space_write_region_stream_2(t, h, o, a, c) 1188 bus_space_tag_t t; 1189 bus_space_handle_t h; 1190 bus_size_t o, c; 1191 const u_int16_t *a; 1192 { 1193 for (; c; a++, c--, o+=2) 1194 bus_space_write_stream_2(t, h, o, *a); 1195 } 1196 1197 static __inline__ void 1198 bus_space_write_region_stream_4(t, h, o, a, c) 1199 bus_space_tag_t t; 1200 bus_space_handle_t h; 1201 bus_size_t o, c; 1202 const u_int32_t *a; 1203 { 1204 for (; c; a++, c--, o+=4) 1205 bus_space_write_stream_4(t, h, o, *a); 1206 } 1207 1208 static __inline__ void 1209 bus_space_write_region_stream_8(t, h, o, a, c) 1210 bus_space_tag_t t; 1211 bus_space_handle_t h; 1212 bus_size_t o, c; 1213 const u_int64_t *a; 1214 { 1215 for (; c; a++, c--, o+=8) 1216 bus_space_write_stream_8(t, h, o, *a); 1217 } 1218 1219 1220 /* 1221 * void bus_space_set_region_stream_N __P((bus_space_tag_t tag, 1222 * bus_space_handle_t bsh, bus_size_t off, 1223 * u_intN_t *addr, bus_size_t count)); 1224 * 1225 */ 1226 static void bus_space_set_region_stream_1 __P((bus_space_tag_t, 1227 bus_space_handle_t, 1228 bus_size_t, 1229 const u_int8_t, 1230 bus_size_t)); 1231 static void bus_space_set_region_stream_2 __P((bus_space_tag_t, 1232 bus_space_handle_t, 1233 bus_size_t, 1234 const u_int16_t, 1235 bus_size_t)); 1236 static void bus_space_set_region_stream_4 __P((bus_space_tag_t, 1237 bus_space_handle_t, 1238 bus_size_t, 1239 const u_int32_t, 1240 bus_size_t)); 1241 static void bus_space_set_region_stream_8 __P((bus_space_tag_t, 1242 bus_space_handle_t, 1243 bus_size_t, 1244 const u_int64_t, 1245 bus_size_t)); 1246 1247 static __inline__ void 1248 bus_space_set_region_stream_1(t, h, o, v, c) 1249 bus_space_tag_t t; 1250 bus_space_handle_t h; 1251 bus_size_t o, c; 1252 const u_int8_t v; 1253 { 1254 for (; c; c--, o++) 1255 bus_space_write_stream_1(t, h, o, v); 1256 } 1257 1258 static __inline__ void 1259 bus_space_set_region_stream_2(t, h, o, v, c) 1260 bus_space_tag_t t; 1261 bus_space_handle_t h; 1262 bus_size_t o, c; 1263 const u_int16_t v; 1264 { 1265 for (; c; c--, o+=2) 1266 bus_space_write_stream_2(t, h, o, v); 1267 } 1268 1269 static __inline__ void 1270 bus_space_set_region_stream_4(t, h, o, v, c) 1271 bus_space_tag_t t; 1272 bus_space_handle_t h; 1273 bus_size_t o, c; 1274 const u_int32_t v; 1275 { 1276 for (; c; c--, o+=4) 1277 bus_space_write_stream_4(t, h, o, v); 1278 } 1279 1280 static __inline__ void 1281 bus_space_set_region_stream_8(t, h, o, v, c) 1282 bus_space_tag_t t; 1283 bus_space_handle_t h; 1284 bus_size_t o, c; 1285 const u_int64_t v; 1286 { 1287 for (; c; c--, o+=8) 1288 bus_space_write_stream_8(t, h, o, v); 1289 } 1290 1291 1292 /* 1293 * void bus_space_copy_region_stream_N __P((bus_space_tag_t tag, 1294 * bus_space_handle_t bsh1, bus_size_t off1, 1295 * bus_space_handle_t bsh2, bus_size_t off2, 1296 * bus_size_t count)); 1297 * 1298 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 1299 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 1300 */ 1301 static void bus_space_copy_region_stream_1 __P((bus_space_tag_t, 1302 bus_space_handle_t, 1303 bus_size_t, 1304 bus_space_handle_t, 1305 bus_size_t, 1306 bus_size_t)); 1307 static void bus_space_copy_region_stream_2 __P((bus_space_tag_t, 1308 bus_space_handle_t, 1309 bus_size_t, 1310 bus_space_handle_t, 1311 bus_size_t, 1312 bus_size_t)); 1313 static void bus_space_copy_region_stream_4 __P((bus_space_tag_t, 1314 bus_space_handle_t, 1315 bus_size_t, 1316 bus_space_handle_t, 1317 bus_size_t, 1318 bus_size_t)); 1319 static void bus_space_copy_region_stream_8 __P((bus_space_tag_t, 1320 bus_space_handle_t, 1321 bus_size_t, 1322 bus_space_handle_t, 1323 bus_size_t, 1324 bus_size_t)); 1325 1326 1327 static __inline__ void 1328 bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) 1329 bus_space_tag_t t; 1330 bus_space_handle_t h1, h2; 1331 bus_size_t o1, o2; 1332 bus_size_t c; 1333 { 1334 for (; c; c--, o1++, o2++) 1335 bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2, o2)); 1336 } 1337 1338 static __inline__ void 1339 bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) 1340 bus_space_tag_t t; 1341 bus_space_handle_t h1, h2; 1342 bus_size_t o1, o2; 1343 bus_size_t c; 1344 { 1345 for (; c; c--, o1+=2, o2+=2) 1346 bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2, o2)); 1347 } 1348 1349 static __inline__ void 1350 bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) 1351 bus_space_tag_t t; 1352 bus_space_handle_t h1, h2; 1353 bus_size_t o1, o2; 1354 bus_size_t c; 1355 { 1356 for (; c; c--, o1+=4, o2+=4) 1357 bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2, o2)); 1358 } 1359 1360 static __inline__ void 1361 bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c) 1362 bus_space_tag_t t; 1363 bus_space_handle_t h1, h2; 1364 bus_size_t o1, o2; 1365 bus_size_t c; 1366 { 1367 for (; c; c--, o1+=8, o2+=8) 1368 bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2)); 1369 } 1370 1371 1372 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 1373 1374 /* 1375 * Flags used in various bus DMA methods. 1376 */ 1377 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */ 1378 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */ 1379 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */ 1380 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */ 1381 #define BUS_DMA_NOWRITE 0x008 /* I suppose the following two should default on */ 1382 #define BUS_DMA_BUS1 0x010 1383 #define BUS_DMA_BUS2 0x020 1384 #define BUS_DMA_BUS3 0x040 1385 #define BUS_DMA_BUS4 0x080 1386 #define BUS_DMA_STREAMING 0x100 /* hint: sequential, unidirectional */ 1387 #define BUS_DMA_READ 0x200 /* mapping is device -> memory only */ 1388 #define BUS_DMA_WRITE 0x400 /* mapping is memory -> device only */ 1389 1390 1391 #define BUS_DMA_NOCACHE BUS_DMA_BUS1 1392 #define BUS_DMA_DVMA BUS_DMA_BUS2 /* Don't bother with alignment */ 1393 1394 /* Forwards needed by prototypes below. */ 1395 struct mbuf; 1396 struct uio; 1397 1398 /* 1399 * Operations performed by bus_dmamap_sync(). 1400 */ 1401 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ 1402 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ 1403 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ 1404 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ 1405 1406 typedef struct sparc_bus_dma_tag *bus_dma_tag_t; 1407 typedef struct sparc_bus_dmamap *bus_dmamap_t; 1408 1409 /* 1410 * bus_dma_segment_t 1411 * 1412 * Describes a single contiguous DMA transaction. Values 1413 * are suitable for programming into DMA registers. 1414 */ 1415 struct sparc_bus_dma_segment { 1416 bus_addr_t ds_addr; /* DVMA address */ 1417 bus_size_t ds_len; /* length of transfer */ 1418 bus_size_t _ds_boundary; /* don't cross this */ 1419 bus_size_t _ds_align; /* align to this */ 1420 void *_ds_mlist; /* XXX - dmamap_alloc'ed pages */ 1421 }; 1422 typedef struct sparc_bus_dma_segment bus_dma_segment_t; 1423 1424 1425 /* 1426 * bus_dma_tag_t 1427 * 1428 * A machine-dependent opaque type describing the implementation of 1429 * DMA for a given bus. 1430 */ 1431 struct sparc_bus_dma_tag { 1432 void *_cookie; /* cookie used in the guts */ 1433 struct sparc_bus_dma_tag* _parent; 1434 1435 /* 1436 * DMA mapping methods. 1437 */ 1438 int (*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int, 1439 bus_size_t, bus_size_t, int, bus_dmamap_t *)); 1440 void (*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t)); 1441 int (*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *, 1442 bus_size_t, struct proc *, int)); 1443 int (*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t, 1444 struct mbuf *, int)); 1445 int (*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t, 1446 struct uio *, int)); 1447 int (*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t, 1448 bus_dma_segment_t *, int, bus_size_t, int)); 1449 void (*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t)); 1450 void (*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t, 1451 bus_addr_t, bus_size_t, int)); 1452 1453 /* 1454 * DMA memory utility functions. 1455 */ 1456 int (*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t, 1457 bus_size_t, bus_dma_segment_t *, int, int *, int)); 1458 void (*_dmamem_free) __P((bus_dma_tag_t, 1459 bus_dma_segment_t *, int)); 1460 int (*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *, 1461 int, size_t, caddr_t *, int)); 1462 void (*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t)); 1463 paddr_t (*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *, 1464 int, off_t, int, int)); 1465 }; 1466 1467 #define bus_dmamap_create(t, s, n, m, b, f, p) \ 1468 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 1469 #define bus_dmamap_destroy(t, p) \ 1470 (*(t)->_dmamap_destroy)((t), (p)) 1471 #define bus_dmamap_load(t, m, b, s, p, f) \ 1472 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 1473 #define bus_dmamap_load_mbuf(t, m, b, f) \ 1474 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 1475 #define bus_dmamap_load_uio(t, m, u, f) \ 1476 (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 1477 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 1478 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 1479 #define bus_dmamap_unload(t, p) \ 1480 (*(t)->_dmamap_unload)((t), (p)) 1481 #define bus_dmamap_sync(t, p, o, l, ops) \ 1482 (void)((t)->_dmamap_sync ? \ 1483 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0) 1484 1485 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 1486 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 1487 #define bus_dmamem_free(t, sg, n) \ 1488 (*(t)->_dmamem_free)((t), (sg), (n)) 1489 #define bus_dmamem_map(t, sg, n, s, k, f) \ 1490 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 1491 #define bus_dmamem_unmap(t, k, s) \ 1492 (*(t)->_dmamem_unmap)((t), (k), (s)) 1493 #define bus_dmamem_mmap(t, sg, n, o, p, f) \ 1494 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 1495 1496 /* 1497 * bus_dmamap_t 1498 * 1499 * Describes a DMA mapping. 1500 */ 1501 struct sparc_bus_dmamap { 1502 /* 1503 * PRIVATE MEMBERS: not for use my machine-independent code. 1504 */ 1505 bus_size_t _dm_size; /* largest DMA transfer mappable */ 1506 bus_size_t _dm_maxsegsz; /* largest possible segment */ 1507 bus_size_t _dm_boundary; /* don't cross this */ 1508 int _dm_segcnt; /* number of segs this map can map */ 1509 int _dm_flags; /* misc. flags */ 1510 #define _DM_TYPE_LOAD 0 1511 #define _DM_TYPE_SEGS 1 1512 #define _DM_TYPE_UIO 2 1513 #define _DM_TYPE_MBUF 3 1514 int _dm_type; /* type of mapping: raw, uio, mbuf, etc */ 1515 void *_dm_source; /* source mbuf, uio, etc. needed for unload */////////////////////// 1516 1517 void *_dm_cookie; /* cookie for bus-specific functions */ 1518 1519 /* 1520 * PUBLIC MEMBERS: these are used by machine-independent code. 1521 */ 1522 bus_size_t dm_mapsize; /* size of the mapping */ 1523 int dm_nsegs; /* # valid segments in mapping */ 1524 bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 1525 }; 1526 1527 #ifdef _SPARC_BUS_DMA_PRIVATE 1528 int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t, 1529 bus_size_t, int, bus_dmamap_t *)); 1530 void _bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t)); 1531 int _bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *, 1532 bus_size_t, struct proc *, int)); 1533 int _bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t, 1534 struct mbuf *, int)); 1535 int _bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t, 1536 struct uio *, int)); 1537 int _bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t, 1538 bus_dma_segment_t *, int, bus_size_t, int)); 1539 void _bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t)); 1540 void _bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 1541 bus_size_t, int)); 1542 1543 int _bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size, 1544 bus_size_t alignment, bus_size_t boundary, 1545 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags)); 1546 void _bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1547 int nsegs)); 1548 int _bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1549 int nsegs, size_t size, caddr_t *kvap, int flags)); 1550 void _bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva, 1551 size_t size)); 1552 paddr_t _bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1553 int nsegs, off_t off, int prot, int flags)); 1554 1555 int _bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size, 1556 bus_size_t alignment, bus_size_t boundary, 1557 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 1558 vaddr_t low, vaddr_t high)); 1559 #endif /* _SPARC_BUS_DMA_PRIVATE */ 1560 1561 #endif /* _SPARC_BUS_H_ */ 1562