bus.h revision 66458
1/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ 2 3/*- 4 * Copyright (c) 1996, 1997 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/* $FreeBSD: head/sys/ia64/include/bus.h 66458 2000-09-29 13:46:07Z dfr $ */ 71 72#ifndef _MACHINE_BUS_H_ 73#define _MACHINE_BUS_H_ 74 75#include <machine/cpufunc.h> 76 77/* 78 * To remain compatible with NetBSD's interface, default to both memio and 79 * pio when neither of them is defined. 80 */ 81#if !defined(_MACHINE_BUS_PIO_H_) && !defined(_IA64_BUS_MEMIO_H_) 82#define _MACHINE_BUS_PIO_H_ 83#define _MACHINE_BUS_MEMIO_H_ 84#endif 85 86/* 87 * Values for the ia64 bus space tag, not to be used directly by MI code. 88 */ 89#define IA64_BUS_SPACE_IO 0 /* space is i/o space */ 90#define IA64_BUS_SPACE_MEM 1 /* space is mem space */ 91 92/* 93 * Bus address and size types 94 */ 95typedef u_long bus_addr_t; 96typedef u_long bus_size_t; 97 98#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF 99#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF 100#define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */ 101#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF 102#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF 103#define BUS_SPACE_MAXADDR 0xFFFFFFFF 104 105#define BUS_SPACE_UNRESTRICTED (~0) 106 107/* 108 * Access methods for bus resources and address space. 109 */ 110typedef int bus_space_tag_t; 111typedef u_long bus_space_handle_t; 112 113/* 114 * Map a region of device bus space into CPU virtual address space. 115 */ 116 117#define BUS_SPACE_MAP_CACHEABLE 0x01 118#define BUS_SPACE_MAP_LINEAR 0x02 119 120int bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 121 int flags, bus_space_handle_t *bshp); 122 123/* 124 * Unmap a region of device bus space. 125 */ 126 127void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 128 bus_size_t size); 129 130/* 131 * Get a new handle for a subregion of an already-mapped area of bus space. 132 */ 133 134int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 135 bus_size_t offset, bus_size_t size, 136 bus_space_handle_t *nbshp); 137 138/* 139 * Allocate a region of memory that is accessible to devices in bus space. 140 */ 141 142int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 143 bus_addr_t rend, bus_size_t size, bus_size_t align, 144 bus_size_t boundary, int flags, bus_addr_t *addrp, 145 bus_space_handle_t *bshp); 146 147/* 148 * Free a region of bus space accessible memory. 149 */ 150 151void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 152 bus_size_t size); 153 154#if defined(_MACHINE_BUS_PIO_H_) || defined(_MACHINE_BUS_MEMIO_H_) 155 156/* 157 * Read a 1, 2, 4, or 8 byte quantity from bus space 158 * described by tag/handle/offset. 159 */ 160static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag, 161 bus_space_handle_t handle, 162 bus_size_t offset); 163 164static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, 165 bus_space_handle_t handle, 166 bus_size_t offset); 167 168static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, 169 bus_space_handle_t handle, 170 bus_size_t offset); 171 172static __inline u_int8_t 173bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, 174 bus_size_t offset) 175{ 176#if defined (_MACHINE_BUS_PIO_H_) 177#if defined (_MACHINE_BUS_MEMIO_H_) 178 if (tag == IA64_BUS_SPACE_IO) 179#endif 180 return (inb(handle + offset)); 181#endif 182#if defined (_MACHINE_BUS_MEMIO_H_) 183 return (readb(handle + offset)); 184#endif 185} 186 187static __inline u_int16_t 188bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, 189 bus_size_t offset) 190{ 191#if defined(_MACHINE_BUS_PIO_H_) 192#if defined(_MACHINE_BUS_MEMIO_H_) 193 if (tag == IA64_BUS_SPACE_IO) 194#endif 195 return (inw(handle + offset)); 196#endif 197#if defined(_MACHINE_BUS_MEMIO_H_) 198 return (readw(handle + offset)); 199#endif 200} 201 202static __inline u_int32_t 203bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, 204 bus_size_t offset) 205{ 206#if defined(_MACHINE_BUS_PIO_H_) 207#if defined(_MACHINE_BUS_MEMIO_H_) 208 if (tag == IA64_BUS_SPACE_IO) 209#endif 210 return (inl(handle + offset)); 211#endif 212#if defined(_MACHINE_BUS_MEMIO_H_) 213 return (readl(handle + offset)); 214#endif 215} 216 217#if 0 /* Cause a link error for bus_space_read_8 */ 218#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 219#endif 220 221/* 222 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 223 * described by tag/handle/offset and copy into buffer provided. 224 */ 225static __inline void bus_space_read_multi_1(bus_space_tag_t tag, 226 bus_space_handle_t bsh, 227 bus_size_t offset, u_int8_t *addr, 228 size_t count); 229 230static __inline void bus_space_read_multi_2(bus_space_tag_t tag, 231 bus_space_handle_t bsh, 232 bus_size_t offset, u_int16_t *addr, 233 size_t count); 234 235static __inline void bus_space_read_multi_4(bus_space_tag_t tag, 236 bus_space_handle_t bsh, 237 bus_size_t offset, u_int32_t *addr, 238 size_t count); 239 240static __inline void 241bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 242 bus_size_t offset, u_int8_t *addr, size_t count) 243{ 244#if defined(_MACHINE_BUS_PIO_H_) 245#if defined(_MACHINE_BUS_MEMIO_H_) 246 if (tag == IA64_BUS_SPACE_IO) 247#endif 248 while (count--) 249 *addr++ = inb(bsh + offset); 250#endif 251#if defined(_MACHINE_BUS_MEMIO_H_) 252#if defined(_MACHINE_BUS_PIO_H_) 253 else 254#endif 255 while (count--) 256 *addr++ = readb(bsh + offset); 257#endif 258} 259 260static __inline void 261bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 262 bus_size_t offset, u_int16_t *addr, size_t count) 263{ 264 bus_addr_t baddr = bsh + offset; 265#if defined(_MACHINE_BUS_PIO_H_) 266#if defined(_MACHINE_BUS_MEMIO_H_) 267 if (tag == IA64_BUS_SPACE_IO) 268#endif 269 while (count--) 270 *addr++ = inw(baddr); 271#endif 272#if defined(_MACHINE_BUS_MEMIO_H_) 273#if defined(_MACHINE_BUS_PIO_H_) 274 else 275#endif 276 while (count--) 277 *addr++ = readw(baddr); 278#endif 279} 280 281static __inline void 282bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 283 bus_size_t offset, u_int32_t *addr, size_t count) 284{ 285 bus_addr_t baddr = bsh + offset; 286#if defined(_MACHINE_BUS_PIO_H_) 287#if defined(_MACHINE_BUS_MEMIO_H_) 288 if (tag == IA64_BUS_SPACE_IO) 289#endif 290 while (count--) 291 *addr++ = inl(baddr); 292#endif 293#if defined(_MACHINE_BUS_MEMIO_H_) 294#if defined(_MACHINE_BUS_PIO_H_) 295 else 296#endif 297 while (count--) 298 *addr++ = readl(baddr); 299#endif 300} 301 302#if 0 /* Cause a link error for bus_space_read_multi_8 */ 303#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 304#endif 305 306/* 307 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 308 * described by tag/handle and starting at `offset' and copy into 309 * buffer provided. 310 */ 311static __inline void bus_space_read_region_1(bus_space_tag_t tag, 312 bus_space_handle_t bsh, 313 bus_size_t offset, u_int8_t *addr, 314 size_t count); 315 316static __inline void bus_space_read_region_2(bus_space_tag_t tag, 317 bus_space_handle_t bsh, 318 bus_size_t offset, u_int16_t *addr, 319 size_t count); 320 321static __inline void bus_space_read_region_4(bus_space_tag_t tag, 322 bus_space_handle_t bsh, 323 bus_size_t offset, u_int32_t *addr, 324 size_t count); 325 326 327static __inline void 328bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 329 bus_size_t offset, u_int8_t *addr, size_t count) 330{ 331 bus_addr_t baddr = bsh + offset; 332#if defined(_MACHINE_BUS_PIO_H_) 333#if defined(_MACHINE_BUS_MEMIO_H_) 334 if (tag == IA64_BUS_SPACE_IO) 335#endif 336 while (count--) { 337 *addr++ = inb(baddr); 338 baddr += 1; 339 } 340#endif 341#if defined(_MACHINE_BUS_MEMIO_H_) 342#if defined(_MACHINE_BUS_PIO_H_) 343 else 344#endif 345 while (count--) { 346 *addr++ = readb(baddr); 347 baddr += 1; 348 } 349#endif 350} 351 352static __inline void 353bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 354 bus_size_t offset, u_int16_t *addr, size_t count) 355{ 356 bus_addr_t baddr = bsh + offset; 357#if defined(_MACHINE_BUS_PIO_H_) 358#if defined(_MACHINE_BUS_MEMIO_H_) 359 if (tag == IA64_BUS_SPACE_IO) 360#endif 361 while (count--) { 362 *addr++ = inw(baddr); 363 baddr += 2; 364 } 365#endif 366#if defined(_MACHINE_BUS_MEMIO_H_) 367#if defined(_MACHINE_BUS_PIO_H_) 368 else 369#endif 370 while (count--) { 371 *addr++ = readw(baddr); 372 baddr += 2; 373 } 374#endif 375} 376 377static __inline void 378bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 379 bus_size_t offset, u_int32_t *addr, size_t count) 380{ 381 bus_addr_t baddr = bsh + offset; 382#if defined(_MACHINE_BUS_PIO_H_) 383#if defined(_MACHINE_BUS_MEMIO_H_) 384 if (tag == IA64_BUS_SPACE_IO) 385#endif 386 while (count--) { 387 *addr++ = inl(baddr); 388 baddr += 4; 389 } 390#endif 391#if defined(_MACHINE_BUS_MEMIO_H_) 392#if defined(_MACHINE_BUS_PIO_H_) 393 else 394#endif 395 while (count--) { 396 *addr++ = readb(baddr); 397 baddr += 4; 398 } 399#endif 400} 401 402#if 0 /* Cause a link error for bus_space_read_region_8 */ 403#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 404#endif 405 406/* 407 * Write the 1, 2, 4, or 8 byte value `value' to bus space 408 * described by tag/handle/offset. 409 */ 410 411static __inline void bus_space_write_1(bus_space_tag_t tag, 412 bus_space_handle_t bsh, 413 bus_size_t offset, u_int8_t value); 414 415static __inline void bus_space_write_2(bus_space_tag_t tag, 416 bus_space_handle_t bsh, 417 bus_size_t offset, u_int16_t value); 418 419static __inline void bus_space_write_4(bus_space_tag_t tag, 420 bus_space_handle_t bsh, 421 bus_size_t offset, u_int32_t value); 422 423static __inline void 424bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, 425 bus_size_t offset, u_int8_t value) 426{ 427#if defined(_MACHINE_BUS_PIO_H_) 428#if defined(_MACHINE_BUS_MEMIO_H_) 429 if (tag == IA64_BUS_SPACE_IO) 430#endif 431 outb(bsh + offset, value); 432#endif 433#if defined(_MACHINE_BUS_MEMIO_H_) 434#if defined(_MACHINE_BUS_PIO_H_) 435 else 436#endif 437 writeb(bsh + offset, value); 438#endif 439} 440 441static __inline void 442bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, 443 bus_size_t offset, u_int16_t value) 444{ 445#if defined(_MACHINE_BUS_PIO_H_) 446#if defined(_MACHINE_BUS_MEMIO_H_) 447 if (tag == IA64_BUS_SPACE_IO) 448#endif 449 outw(bsh + offset, value); 450#endif 451#if defined(_MACHINE_BUS_MEMIO_H_) 452#if defined(_MACHINE_BUS_PIO_H_) 453 else 454#endif 455 writew(bsh + offset, value); 456#endif 457} 458 459static __inline void 460bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, 461 bus_size_t offset, u_int32_t value) 462{ 463#if defined(_MACHINE_BUS_PIO_H_) 464#if defined(_MACHINE_BUS_MEMIO_H_) 465 if (tag == IA64_BUS_SPACE_IO) 466#endif 467 outl(bsh + offset, value); 468#endif 469#if defined(_MACHINE_BUS_MEMIO_H_) 470#if defined(_MACHINE_BUS_PIO_H_) 471 else 472#endif 473 writel(bsh + offset, value); 474#endif 475} 476 477#if 0 /* Cause a link error for bus_space_write_8 */ 478#define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 479#endif 480 481/* 482 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 483 * provided to bus space described by tag/handle/offset. 484 */ 485 486static __inline void bus_space_write_multi_1(bus_space_tag_t tag, 487 bus_space_handle_t bsh, 488 bus_size_t offset, 489 const u_int8_t *addr, 490 size_t count); 491static __inline void bus_space_write_multi_2(bus_space_tag_t tag, 492 bus_space_handle_t bsh, 493 bus_size_t offset, 494 const u_int16_t *addr, 495 size_t count); 496 497static __inline void bus_space_write_multi_4(bus_space_tag_t tag, 498 bus_space_handle_t bsh, 499 bus_size_t offset, 500 const u_int32_t *addr, 501 size_t count); 502 503static __inline void 504bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 505 bus_size_t offset, const u_int8_t *addr, size_t count) 506{ 507 bus_addr_t baddr = bsh + offset; 508#if defined(_MACHINE_BUS_PIO_H_) 509#if defined(_MACHINE_BUS_MEMIO_H_) 510 if (tag == IA64_BUS_SPACE_IO) 511#endif 512 while (count--) 513 outb(baddr, *addr++); 514#endif 515#if defined(_MACHINE_BUS_MEMIO_H_) 516#if defined(_MACHINE_BUS_PIO_H_) 517 else 518#endif 519 while (count--) 520 writeb(baddr, *addr++); 521#endif 522} 523 524static __inline void 525bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 526 bus_size_t offset, const u_int16_t *addr, size_t count) 527{ 528 bus_addr_t baddr = bsh + offset; 529#if defined(_MACHINE_BUS_PIO_H_) 530#if defined(_MACHINE_BUS_MEMIO_H_) 531 if (tag == IA64_BUS_SPACE_IO) 532#endif 533 while (count--) 534 outw(baddr, *addr++); 535#endif 536#if defined(_MACHINE_BUS_MEMIO_H_) 537#if defined(_MACHINE_BUS_PIO_H_) 538 else 539#endif 540 while (count--) 541 writew(baddr, *addr++); 542#endif 543} 544 545static __inline void 546bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 547 bus_size_t offset, const u_int32_t *addr, size_t count) 548{ 549 bus_addr_t baddr = bsh + offset; 550#if defined(_MACHINE_BUS_PIO_H_) 551#if defined(_MACHINE_BUS_MEMIO_H_) 552 if (tag == IA64_BUS_SPACE_IO) 553#endif 554 while (count--) 555 outl(baddr, *addr++); 556#endif 557#if defined(_MACHINE_BUS_MEMIO_H_) 558#if defined(_MACHINE_BUS_PIO_H_) 559 else 560#endif 561 while (count--) 562 writel(baddr, *addr++); 563#endif 564} 565 566#if 0 /* Cause a link error for bus_space_write_multi_8 */ 567#define bus_space_write_multi_8(t, h, o, a, c) \ 568 !!! bus_space_write_multi_8 unimplemented !!! 569#endif 570 571/* 572 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 573 * to bus space described by tag/handle starting at `offset'. 574 */ 575 576static __inline void bus_space_write_region_1(bus_space_tag_t tag, 577 bus_space_handle_t bsh, 578 bus_size_t offset, 579 const u_int8_t *addr, 580 size_t count); 581static __inline void bus_space_write_region_2(bus_space_tag_t tag, 582 bus_space_handle_t bsh, 583 bus_size_t offset, 584 const u_int16_t *addr, 585 size_t count); 586static __inline void bus_space_write_region_4(bus_space_tag_t tag, 587 bus_space_handle_t bsh, 588 bus_size_t offset, 589 const u_int32_t *addr, 590 size_t count); 591 592static __inline void 593bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 594 bus_size_t offset, const u_int8_t *addr, size_t count) 595{ 596 bus_addr_t baddr = bsh + offset; 597#if defined(_MACHINE_BUS_PIO_H_) 598#if defined(_MACHINE_BUS_MEMIO_H_) 599 if (tag == IA64_BUS_SPACE_IO) 600#endif 601 while (count--) { 602 outb(baddr, *addr++); 603 baddr += 1; 604 } 605#endif 606#if defined(_MACHINE_BUS_MEMIO_H_) 607#if defined(_MACHINE_BUS_PIO_H_) 608 else 609#endif 610 while (count--) { 611 writeb(baddr, *addr++); 612 baddr += 1; 613 } 614#endif 615} 616 617static __inline void 618bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 619 bus_size_t offset, const u_int16_t *addr, size_t count) 620{ 621 bus_addr_t baddr = bsh + offset; 622#if defined(_MACHINE_BUS_PIO_H_) 623#if defined(_MACHINE_BUS_MEMIO_H_) 624 if (tag == IA64_BUS_SPACE_IO) 625#endif 626 while (count--) { 627 outw(baddr, *addr++); 628 baddr += 2; 629 } 630#endif 631#if defined(_MACHINE_BUS_MEMIO_H_) 632#if defined(_MACHINE_BUS_PIO_H_) 633 else 634#endif 635 while (count--) { 636 writew(baddr, *addr++); 637 baddr += 2; 638 } 639#endif 640} 641 642static __inline void 643bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 644 bus_size_t offset, const u_int32_t *addr, size_t count) 645{ 646 bus_addr_t baddr = bsh + offset; 647#if defined(_MACHINE_BUS_PIO_H_) 648#if defined(_MACHINE_BUS_MEMIO_H_) 649 if (tag == IA64_BUS_SPACE_IO) 650#endif 651 while (count--) { 652 outl(baddr, *addr++); 653 baddr += 4; 654 } 655#endif 656#if defined(_MACHINE_BUS_MEMIO_H_) 657#if defined(_MACHINE_BUS_PIO_H_) 658 else 659#endif 660 while (count--) { 661 writel(baddr, *addr++); 662 baddr += 4; 663 } 664#endif 665} 666 667#if 0 /* Cause a link error for bus_space_write_region_8 */ 668#define bus_space_write_region_8 \ 669 !!! bus_space_write_region_8 unimplemented !!! 670#endif 671 672/* 673 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 674 * by tag/handle/offset `count' times. 675 */ 676 677static __inline void bus_space_set_multi_1(bus_space_tag_t tag, 678 bus_space_handle_t bsh, 679 bus_size_t offset, 680 u_int8_t value, size_t count); 681static __inline void bus_space_set_multi_2(bus_space_tag_t tag, 682 bus_space_handle_t bsh, 683 bus_size_t offset, 684 u_int16_t value, size_t count); 685static __inline void bus_space_set_multi_4(bus_space_tag_t tag, 686 bus_space_handle_t bsh, 687 bus_size_t offset, 688 u_int32_t value, size_t count); 689 690static __inline void 691bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 692 bus_size_t offset, u_int8_t value, size_t count) 693{ 694 bus_addr_t addr = bsh + offset; 695 696#if defined(_MACHINE_BUS_PIO_H_) 697#if defined(_MACHINE_BUS_MEMIO_H_) 698 if (tag == IA64_BUS_SPACE_IO) 699#endif 700 while (count--) 701 outb(addr, value); 702#endif 703#if defined(_MACHINE_BUS_MEMIO_H_) 704#if defined(_MACHINE_BUS_PIO_H_) 705 else 706#endif 707 while (count--) 708 writeb(addr, value); 709#endif 710} 711 712static __inline void 713bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 714 bus_size_t offset, u_int16_t value, size_t count) 715{ 716 bus_addr_t addr = bsh + offset; 717 718#if defined(_MACHINE_BUS_PIO_H_) 719#if defined(_MACHINE_BUS_MEMIO_H_) 720 if (tag == IA64_BUS_SPACE_IO) 721#endif 722 while (count--) 723 outw(addr, value); 724#endif 725#if defined(_MACHINE_BUS_MEMIO_H_) 726#if defined(_MACHINE_BUS_PIO_H_) 727 else 728#endif 729 while (count--) 730 writew(addr, value); 731#endif 732} 733 734static __inline void 735bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 736 bus_size_t offset, u_int32_t value, size_t count) 737{ 738 bus_addr_t addr = bsh + offset; 739 740#if defined(_MACHINE_BUS_PIO_H_) 741#if defined(_MACHINE_BUS_MEMIO_H_) 742 if (tag == IA64_BUS_SPACE_IO) 743#endif 744 while (count--) 745 outl(addr, value); 746#endif 747#if defined(_MACHINE_BUS_MEMIO_H_) 748#if defined(_MACHINE_BUS_PIO_H_) 749 else 750#endif 751 while (count--) 752 writel(addr, value); 753#endif 754} 755 756#if 0 /* Cause a link error for bus_space_set_multi_8 */ 757#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! 758#endif 759 760/* 761 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 762 * by tag/handle starting at `offset'. 763 */ 764 765static __inline void bus_space_set_region_1(bus_space_tag_t tag, 766 bus_space_handle_t bsh, 767 bus_size_t offset, u_int8_t value, 768 size_t count); 769static __inline void bus_space_set_region_2(bus_space_tag_t tag, 770 bus_space_handle_t bsh, 771 bus_size_t offset, u_int16_t value, 772 size_t count); 773static __inline void bus_space_set_region_4(bus_space_tag_t tag, 774 bus_space_handle_t bsh, 775 bus_size_t offset, u_int32_t value, 776 size_t count); 777 778static __inline void 779bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 780 bus_size_t offset, u_int8_t value, size_t count) 781{ 782 bus_addr_t addr = bsh + offset; 783 784#if defined(_MACHINE_BUS_PIO_H_) 785#if defined(_MACHINE_BUS_MEMIO_H_) 786 if (tag == IA64_BUS_SPACE_IO) 787#endif 788 for (; count != 0; count--, addr++) 789 outb(addr, value); 790#endif 791#if defined(_MACHINE_BUS_MEMIO_H_) 792#if defined(_MACHINE_BUS_PIO_H_) 793 else 794#endif 795 for (; count != 0; count--, addr++) 796 writeb(addr, value); 797#endif 798} 799 800static __inline void 801bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 802 bus_size_t offset, u_int16_t value, size_t count) 803{ 804 bus_addr_t addr = bsh + offset; 805 806#if defined(_MACHINE_BUS_PIO_H_) 807#if defined(_MACHINE_BUS_MEMIO_H_) 808 if (tag == IA64_BUS_SPACE_IO) 809#endif 810 for (; count != 0; count--, addr += 2) 811 outw(addr, value); 812#endif 813#if defined(_MACHINE_BUS_MEMIO_H_) 814#if defined(_MACHINE_BUS_PIO_H_) 815 else 816#endif 817 for (; count != 0; count--, addr += 2) 818 writew(addr, value); 819#endif 820} 821 822static __inline void 823bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 824 bus_size_t offset, u_int32_t value, size_t count) 825{ 826 bus_addr_t addr = bsh + offset; 827 828#if defined(_MACHINE_BUS_PIO_H_) 829#if defined(_MACHINE_BUS_MEMIO_H_) 830 if (tag == IA64_BUS_SPACE_IO) 831#endif 832 for (; count != 0; count--, addr += 4) 833 outl(addr, value); 834#endif 835#if defined(_MACHINE_BUS_MEMIO_H_) 836#if defined(_MACHINE_BUS_PIO_H_) 837 else 838#endif 839 for (; count != 0; count--, addr += 4) 840 writel(addr, value); 841#endif 842} 843 844#if 0 /* Cause a link error for bus_space_set_region_8 */ 845#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! 846#endif 847 848/* 849 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 850 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 851 */ 852 853static __inline void bus_space_copy_region_1(bus_space_tag_t tag, 854 bus_space_handle_t bsh1, 855 bus_size_t off1, 856 bus_space_handle_t bsh2, 857 bus_size_t off2, size_t count); 858 859static __inline void bus_space_copy_region_2(bus_space_tag_t tag, 860 bus_space_handle_t bsh1, 861 bus_size_t off1, 862 bus_space_handle_t bsh2, 863 bus_size_t off2, size_t count); 864 865static __inline void bus_space_copy_region_4(bus_space_tag_t tag, 866 bus_space_handle_t bsh1, 867 bus_size_t off1, 868 bus_space_handle_t bsh2, 869 bus_size_t off2, size_t count); 870 871static __inline void 872bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1, 873 bus_size_t off1, bus_space_handle_t bsh2, 874 bus_size_t off2, size_t count) 875{ 876 bus_addr_t addr1 = bsh1 + off1; 877 bus_addr_t addr2 = bsh2 + off2; 878 879#if defined(_MACHINE_BUS_PIO_H_) 880#if defined(_MACHINE_BUS_MEMIO_H_) 881 if (tag == IA64_BUS_SPACE_IO) 882#endif 883 { 884 if (addr1 >= addr2) { 885 /* src after dest: copy forward */ 886 for (; count != 0; count--, addr1++, addr2++) 887 outb(addr2, inb(addr1)); 888 } else { 889 /* dest after src: copy backwards */ 890 for (addr1 += (count - 1), addr2 += (count - 1); 891 count != 0; count--, addr1--, addr2--) 892 outb(addr2, inb(addr1)); 893 } 894 } 895#endif 896#if defined(_MACHINE_BUS_MEMIO_H_) 897#if defined(_MACHINE_BUS_PIO_H_) 898 else 899#endif 900 { 901 if (addr1 >= addr2) { 902 /* src after dest: copy forward */ 903 for (; count != 0; count--, addr1++, addr2++) 904 writeb(addr2, readb(addr1)); 905 } else { 906 /* dest after src: copy backwards */ 907 for (addr1 += (count - 1), addr2 += (count - 1); 908 count != 0; count--, addr1--, addr2--) 909 writeb(addr2, readb(addr1)); 910 } 911 } 912#endif 913} 914 915static __inline void 916bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1, 917 bus_size_t off1, bus_space_handle_t bsh2, 918 bus_size_t off2, size_t count) 919{ 920 bus_addr_t addr1 = bsh1 + off1; 921 bus_addr_t addr2 = bsh2 + off2; 922 923#if defined(_MACHINE_BUS_PIO_H_) 924#if defined(_MACHINE_BUS_MEMIO_H_) 925 if (tag == IA64_BUS_SPACE_IO) 926#endif 927 { 928 if (addr1 >= addr2) { 929 /* src after dest: copy forward */ 930 for (; count != 0; count--, addr1 += 2, addr2 += 2) 931 outw(addr2, inw(addr1)); 932 } else { 933 /* dest after src: copy backwards */ 934 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 935 count != 0; count--, addr1 -= 2, addr2 -= 2) 936 outw(addr2, inw(addr1)); 937 } 938 } 939#endif 940#if defined(_MACHINE_BUS_MEMIO_H_) 941#if defined(_MACHINE_BUS_PIO_H_) 942 else 943#endif 944 { 945 if (addr1 >= addr2) { 946 /* src after dest: copy forward */ 947 for (; count != 0; count--, addr1 += 2, addr2 += 2) 948 writew(addr2, readw(addr1)); 949 } else { 950 /* dest after src: copy backwards */ 951 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 952 count != 0; count--, addr1 -= 2, addr2 -= 2) 953 writew(addr2, readw(addr1)); 954 } 955 } 956#endif 957} 958 959static __inline void 960bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, 961 bus_size_t off1, bus_space_handle_t bsh2, 962 bus_size_t off2, size_t count) 963{ 964 bus_addr_t addr1 = bsh1 + off1; 965 bus_addr_t addr2 = bsh2 + off2; 966 967#if defined(_MACHINE_BUS_PIO_H_) 968#if defined(_MACHINE_BUS_MEMIO_H_) 969 if (tag == IA64_BUS_SPACE_IO) 970#endif 971 { 972 if (addr1 >= addr2) { 973 /* src after dest: copy forward */ 974 for (; count != 0; count--, addr1 += 4, addr2 += 4) 975 outl(addr2, inl(addr1)); 976 } else { 977 /* dest after src: copy backwards */ 978 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 979 count != 0; count--, addr1 -= 4, addr2 -= 4) 980 outl(addr2, inl(addr1)); 981 } 982 } 983#endif 984#if defined(_MACHINE_BUS_MEMIO_H_) 985#if defined(_MACHINE_BUS_PIO_H_) 986 else 987#endif 988 { 989 if (addr1 >= addr2) { 990 /* src after dest: copy forward */ 991 for (; count != 0; count--, addr1 += 4, addr2 += 4) 992 writel(addr2, readl(addr1)); 993 } else { 994 /* dest after src: copy backwards */ 995 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 996 count != 0; count--, addr1 -= 4, addr2 -= 4) 997 writel(addr2, readl(addr1)); 998 } 999 } 1000#endif 1001} 1002 1003#endif /* defined(_MACHINE_BUS_PIO_H_) || defined(_MACHINE_BUS_MEMIO_H_) */ 1004 1005#if 0 /* Cause a link error for bus_space_copy_8 */ 1006#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! 1007#endif 1008 1009/* 1010 * Bus read/write barrier methods. 1011 * 1012 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, 1013 * bus_size_t offset, bus_size_t len, int flags); 1014 * 1015 */ 1016#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 1017#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 1018 1019static __inline void 1020bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, 1021 bus_size_t offset, bus_size_t len, int flags) 1022{ 1023 ia64_mf(); 1024} 1025 1026 1027/* 1028 * Flags used in various bus DMA methods. 1029 */ 1030#define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ 1031#define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ 1032#define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ 1033#define BUS_DMAMEM_NOSYNC 0x04 /* map memory to not require sync */ 1034#define BUS_DMA_ISA 0x10 /* map memory for ISA dma */ 1035#define BUS_DMA_BUS2 0x20 /* placeholders for bus functions... */ 1036#define BUS_DMA_BUS3 0x40 1037#define BUS_DMA_BUS4 0x80 1038 1039/* Forwards needed by prototypes below. */ 1040struct mbuf; 1041struct uio; 1042 1043/* 1044 * bus_dmasync_op_t 1045 * 1046 * Operations performed by bus_dmamap_sync(). 1047 */ 1048typedef enum { 1049 BUS_DMASYNC_PREREAD, 1050 BUS_DMASYNC_POSTREAD, 1051 BUS_DMASYNC_PREWRITE, 1052 BUS_DMASYNC_POSTWRITE 1053} bus_dmasync_op_t; 1054 1055/* 1056 * bus_dma_tag_t 1057 * 1058 * A machine-dependent opaque type describing the characteristics 1059 * of how to perform DMA mappings. This structure encapsultes 1060 * information concerning address and alignment restrictions, number 1061 * of S/G segments, amount of data per S/G segment, etc. 1062 */ 1063typedef struct bus_dma_tag *bus_dma_tag_t; 1064 1065/* 1066 * bus_dmamap_t 1067 * 1068 * DMA mapping instance information. 1069 */ 1070typedef struct bus_dmamap *bus_dmamap_t; 1071 1072/* 1073 * bus_dma_segment_t 1074 * 1075 * Describes a single contiguous DMA transaction. Values 1076 * are suitable for programming into DMA registers. 1077 */ 1078typedef struct bus_dma_segment { 1079 bus_addr_t ds_addr; /* DMA address */ 1080 bus_size_t ds_len; /* length of transfer */ 1081} bus_dma_segment_t; 1082 1083/* 1084 * A function that returns 1 if the address cannot be accessed by 1085 * a device and 0 if it can be. 1086 */ 1087typedef int bus_dma_filter_t(void *, bus_addr_t); 1088 1089/* 1090 * Allocate a device specific dma_tag encapsulating the constraints of 1091 * the parent tag in addition to other restrictions specified: 1092 * 1093 * alignment: alignment for segments. 1094 * boundary: Boundary that segments cannot cross. 1095 * lowaddr: Low restricted address that cannot appear in a mapping. 1096 * highaddr: High restricted address that cannot appear in a mapping. 1097 * filtfunc: An optional function to further test if an address 1098 * within the range of lowaddr and highaddr cannot appear 1099 * in a mapping. 1100 * filtfuncarg: An argument that will be passed to filtfunc in addition 1101 * to the address to test. 1102 * maxsize: Maximum mapping size supported by this tag. 1103 * nsegments: Number of discontinuities allowed in maps. 1104 * maxsegsz: Maximum size of a segment in the map. 1105 * flags: Bus DMA flags. 1106 * dmat: A pointer to set to a valid dma tag should the return 1107 * value of this function indicate success. 1108 */ 1109/* XXX Should probably allow specification of alignment */ 1110int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignemnt, 1111 bus_size_t boundary, bus_addr_t lowaddr, 1112 bus_addr_t highaddr, bus_dma_filter_t *filtfunc, 1113 void *filtfuncarg, bus_size_t maxsize, int nsegments, 1114 bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat); 1115 1116int bus_dma_tag_destroy(bus_dma_tag_t dmat); 1117 1118/* 1119 * Allocate a handle for mapping from kva/uva/physical 1120 * address space into bus device space. 1121 */ 1122int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); 1123 1124/* 1125 * Destroy a handle for mapping from kva/uva/physical 1126 * address space into bus device space. 1127 */ 1128int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); 1129 1130/* 1131 * Allocate a piece of memory that can be efficiently mapped into 1132 * bus device space based on the constraints lited in the dma tag. 1133 * A dmamap to for use with dmamap_load is also allocated. 1134 */ 1135int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, 1136 bus_dmamap_t *mapp); 1137 1138/* 1139 * Free a piece of memory and it's allociated dmamap, that was allocated 1140 * via bus_dmamem_alloc. 1141 */ 1142void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); 1143 1144/* 1145 * A function that processes a successfully loaded dma map or an error 1146 * from a delayed load map. 1147 */ 1148typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); 1149 1150/* 1151 * Map the buffer buf into bus space using the dmamap map. 1152 */ 1153int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 1154 bus_size_t buflen, bus_dmamap_callback_t *callback, 1155 void *callback_arg, int flags); 1156 1157/* 1158 * Perform a syncronization operation on the given map. 1159 */ 1160void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); 1161#define bus_dmamap_sync(dmat, dmamap, op) \ 1162 if ((dmamap) != NULL) \ 1163 _bus_dmamap_sync(dmat, dmamap, op) 1164 1165/* 1166 * Release the mapping held by map. 1167 */ 1168void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map); 1169#define bus_dmamap_unload(dmat, dmamap) \ 1170 if ((dmamap) != NULL) \ 1171 _bus_dmamap_unload(dmat, dmamap) 1172 1173#endif /* _MACHINE_BUS_H_ */ 1174