bus.h revision 202031
1/* $NetBSD: bus.h,v 1.11 2003/07/28 17:35:54 thorpej 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 * from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter 71 * $FreeBSD: head/sys/mips/include/bus.h 202031 2010-01-10 19:50:24Z imp $ 72*/ 73 74#ifndef _MACHINE_BUS_H_ 75#define _MACHINE_BUS_H_ 76 77#ifdef TARGET_OCTEON 78#include <machine/bus_octeon.h> 79#else 80#include <machine/_bus.h> 81#include <machine/cpufunc.h> 82 83/* 84 * Values for the mips bus space tag, not to be used directly by MI code. 85 */ 86#define MIPS_BUS_SPACE_IO 0 /* space is i/o space */ 87#define MIPS_BUS_SPACE_MEM 1 /* space is mem space */ 88 89 90#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF 91#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF 92#define BUS_SPACE_MAXSIZE 0xFFFFFFFF /* Maximum supported size */ 93#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF 94#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF 95#define BUS_SPACE_MAXADDR 0xFFFFFFFF 96 97#define BUS_SPACE_UNRESTRICTED (~0) 98 99/* 100 * Map a region of device bus space into CPU virtual address space. 101 */ 102 103static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 104 bus_size_t size, int flags, 105 bus_space_handle_t *bshp); 106 107static __inline int 108bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, 109 bus_size_t size __unused, int flags __unused, 110 bus_space_handle_t *bshp) 111{ 112 113 *bshp = addr; 114 return (0); 115} 116 117/* 118 * Unmap a region of device bus space. 119 */ 120 121void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 122 bus_size_t size); 123 124/* 125 * Get a new handle for a subregion of an already-mapped area of bus space. 126 */ 127 128int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 129 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 130 131/* 132 * Allocate a region of memory that is accessible to devices in bus space. 133 */ 134 135int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 136 bus_addr_t rend, bus_size_t size, bus_size_t align, 137 bus_size_t boundary, int flags, bus_addr_t *addrp, 138 bus_space_handle_t *bshp); 139 140/* 141 * Free a region of bus space accessible memory. 142 */ 143 144void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 145 bus_size_t size); 146 147 148/* 149 * Read a 1, 2, 4, or 8 byte quantity from bus space 150 * described by tag/handle/offset. 151 */ 152static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag, 153 bus_space_handle_t handle, 154 bus_size_t offset); 155 156static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, 157 bus_space_handle_t handle, 158 bus_size_t offset); 159 160static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, 161 bus_space_handle_t handle, 162 bus_size_t offset); 163 164static __inline u_int8_t 165bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, 166 bus_size_t offset) 167{ 168 169 if (tag == MIPS_BUS_SPACE_IO) 170 return (inb(handle + offset)); 171 return (readb(handle + offset)); 172} 173 174static __inline u_int16_t 175bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, 176 bus_size_t offset) 177{ 178 179 if (tag == MIPS_BUS_SPACE_IO) 180 return (inw(handle + offset)); 181 return (readw(handle + offset)); 182} 183 184static __inline u_int32_t 185bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, 186 bus_size_t offset) 187{ 188 189 if (tag == MIPS_BUS_SPACE_IO) 190 return (inl(handle + offset)); 191 return (readl(handle + offset)); 192} 193 194#if 0 /* Cause a link error for bus_space_read_8 */ 195#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 196#endif 197 198/* 199 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 200 * described by tag/handle/offset and copy into buffer provided. 201 */ 202static __inline void bus_space_read_multi_1(bus_space_tag_t tag, 203 bus_space_handle_t bsh, 204 bus_size_t offset, u_int8_t *addr, 205 size_t count); 206 207static __inline void bus_space_read_multi_2(bus_space_tag_t tag, 208 bus_space_handle_t bsh, 209 bus_size_t offset, u_int16_t *addr, 210 size_t count); 211 212static __inline void bus_space_read_multi_4(bus_space_tag_t tag, 213 bus_space_handle_t bsh, 214 bus_size_t offset, u_int32_t *addr, 215 size_t count); 216 217static __inline void 218bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 219 bus_size_t offset, u_int8_t *addr, size_t count) 220{ 221 222 if (tag == MIPS_BUS_SPACE_IO) 223 while (count--) 224 *addr++ = inb(bsh + offset); 225 else 226 while (count--) 227 *addr++ = readb(bsh + offset); 228} 229 230static __inline void 231bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 232 bus_size_t offset, u_int16_t *addr, size_t count) 233{ 234 bus_addr_t baddr = bsh + offset; 235 236 if (tag == MIPS_BUS_SPACE_IO) 237 while (count--) 238 *addr++ = inw(baddr); 239 else 240 while (count--) 241 *addr++ = readw(baddr); 242} 243 244static __inline void 245bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 246 bus_size_t offset, u_int32_t *addr, size_t count) 247{ 248 bus_addr_t baddr = bsh + offset; 249 250 if (tag == MIPS_BUS_SPACE_IO) 251 while (count--) 252 *addr++ = inl(baddr); 253 else 254 while (count--) 255 *addr++ = readl(baddr); 256} 257 258#if 0 /* Cause a link error for bus_space_read_multi_8 */ 259#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 260#endif 261 262/* 263 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 264 * described by tag/handle and starting at `offset' and copy into 265 * buffer provided. 266 */ 267static __inline void bus_space_read_region_1(bus_space_tag_t tag, 268 bus_space_handle_t bsh, 269 bus_size_t offset, u_int8_t *addr, 270 size_t count); 271 272static __inline void bus_space_read_region_2(bus_space_tag_t tag, 273 bus_space_handle_t bsh, 274 bus_size_t offset, u_int16_t *addr, 275 size_t count); 276 277static __inline void bus_space_read_region_4(bus_space_tag_t tag, 278 bus_space_handle_t bsh, 279 bus_size_t offset, u_int32_t *addr, 280 size_t count); 281 282 283static __inline void 284bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 285 bus_size_t offset, u_int8_t *addr, size_t count) 286{ 287 bus_addr_t baddr = bsh + offset; 288 289 if (tag == MIPS_BUS_SPACE_IO) 290 while (count--) { 291 *addr++ = inb(baddr); 292 baddr += 1; 293 } 294 else 295 while (count--) { 296 *addr++ = readb(baddr); 297 baddr += 1; 298 } 299} 300 301static __inline void 302bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 303 bus_size_t offset, u_int16_t *addr, size_t count) 304{ 305 bus_addr_t baddr = bsh + offset; 306 307 if (tag == MIPS_BUS_SPACE_IO) 308 while (count--) { 309 *addr++ = inw(baddr); 310 baddr += 2; 311 } 312 else 313 while (count--) { 314 *addr++ = readw(baddr); 315 baddr += 2; 316 } 317} 318 319static __inline void 320bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 321 bus_size_t offset, u_int32_t *addr, size_t count) 322{ 323 bus_addr_t baddr = bsh + offset; 324 325 if (tag == MIPS_BUS_SPACE_IO) 326 while (count--) { 327 *addr++ = inl(baddr); 328 baddr += 4; 329 } 330 else 331 while (count--) { 332 *addr++ = readb(baddr); 333 baddr += 4; 334 } 335} 336 337#if 0 /* Cause a link error for bus_space_read_region_8 */ 338#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 339#endif 340 341/* 342 * Write the 1, 2, 4, or 8 byte value `value' to bus space 343 * described by tag/handle/offset. 344 */ 345 346static __inline void bus_space_write_1(bus_space_tag_t tag, 347 bus_space_handle_t bsh, 348 bus_size_t offset, u_int8_t value); 349 350static __inline void bus_space_write_2(bus_space_tag_t tag, 351 bus_space_handle_t bsh, 352 bus_size_t offset, u_int16_t value); 353 354static __inline void bus_space_write_4(bus_space_tag_t tag, 355 bus_space_handle_t bsh, 356 bus_size_t offset, u_int32_t value); 357 358static __inline void 359bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, 360 bus_size_t offset, u_int8_t value) 361{ 362 363 if (tag == MIPS_BUS_SPACE_IO) 364 outb(bsh + offset, value); 365 else 366 writeb(bsh + offset, value); 367} 368 369static __inline void 370bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, 371 bus_size_t offset, u_int16_t value) 372{ 373 374 if (tag == MIPS_BUS_SPACE_IO) 375 outw(bsh + offset, value); 376 else 377 writew(bsh + offset, value); 378} 379 380static __inline void 381bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, 382 bus_size_t offset, u_int32_t value) 383{ 384 385 if (tag == MIPS_BUS_SPACE_IO) 386 outl(bsh + offset, value); 387 else 388 writel(bsh + offset, value); 389} 390 391#if 0 /* Cause a link error for bus_space_write_8 */ 392#define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 393#endif 394 395/* 396 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 397 * provided to bus space described by tag/handle/offset. 398 */ 399 400static __inline void bus_space_write_multi_1(bus_space_tag_t tag, 401 bus_space_handle_t bsh, 402 bus_size_t offset, 403 const u_int8_t *addr, 404 size_t count); 405static __inline void bus_space_write_multi_2(bus_space_tag_t tag, 406 bus_space_handle_t bsh, 407 bus_size_t offset, 408 const u_int16_t *addr, 409 size_t count); 410 411static __inline void bus_space_write_multi_4(bus_space_tag_t tag, 412 bus_space_handle_t bsh, 413 bus_size_t offset, 414 const u_int32_t *addr, 415 size_t count); 416 417static __inline void 418bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 419 bus_size_t offset, const u_int8_t *addr, size_t count) 420{ 421 bus_addr_t baddr = bsh + offset; 422 423 if (tag == MIPS_BUS_SPACE_IO) 424 while (count--) 425 outb(baddr, *addr++); 426 else 427 while (count--) 428 writeb(baddr, *addr++); 429} 430 431static __inline void 432bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 433 bus_size_t offset, const u_int16_t *addr, size_t count) 434{ 435 bus_addr_t baddr = bsh + offset; 436 437 if (tag == MIPS_BUS_SPACE_IO) 438 while (count--) 439 outw(baddr, *addr++); 440 else 441 while (count--) 442 writew(baddr, *addr++); 443} 444 445static __inline void 446bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 447 bus_size_t offset, const u_int32_t *addr, size_t count) 448{ 449 bus_addr_t baddr = bsh + offset; 450 451 if (tag == MIPS_BUS_SPACE_IO) 452 while (count--) 453 outl(baddr, *addr++); 454 else 455 while (count--) 456 writel(baddr, *addr++); 457} 458 459#if 0 /* Cause a link error for bus_space_write_multi_8 */ 460#define bus_space_write_multi_8(t, h, o, a, c) \ 461 !!! bus_space_write_multi_8 unimplemented !!! 462#endif 463 464/* 465 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 466 * to bus space described by tag/handle starting at `offset'. 467 */ 468 469static __inline void bus_space_write_region_1(bus_space_tag_t tag, 470 bus_space_handle_t bsh, 471 bus_size_t offset, 472 const u_int8_t *addr, 473 size_t count); 474static __inline void bus_space_write_region_2(bus_space_tag_t tag, 475 bus_space_handle_t bsh, 476 bus_size_t offset, 477 const u_int16_t *addr, 478 size_t count); 479static __inline void bus_space_write_region_4(bus_space_tag_t tag, 480 bus_space_handle_t bsh, 481 bus_size_t offset, 482 const u_int32_t *addr, 483 size_t count); 484 485static __inline void 486bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 487 bus_size_t offset, const u_int8_t *addr, size_t count) 488{ 489 bus_addr_t baddr = bsh + offset; 490 491 if (tag == MIPS_BUS_SPACE_IO) 492 while (count--) { 493 outb(baddr, *addr++); 494 baddr += 1; 495 } 496 else 497 while (count--) { 498 writeb(baddr, *addr++); 499 baddr += 1; 500 } 501} 502 503static __inline void 504bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 505 bus_size_t offset, const u_int16_t *addr, size_t count) 506{ 507 bus_addr_t baddr = bsh + offset; 508 509 if (tag == MIPS_BUS_SPACE_IO) 510 while (count--) { 511 outw(baddr, *addr++); 512 baddr += 2; 513 } 514 else 515 while (count--) { 516 writew(baddr, *addr++); 517 baddr += 2; 518 } 519} 520 521static __inline void 522bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 523 bus_size_t offset, const u_int32_t *addr, size_t count) 524{ 525 bus_addr_t baddr = bsh + offset; 526 527 if (tag == MIPS_BUS_SPACE_IO) 528 while (count--) { 529 outl(baddr, *addr++); 530 baddr += 4; 531 } 532 else 533 while (count--) { 534 writel(baddr, *addr++); 535 baddr += 4; 536 } 537} 538 539#if 0 /* Cause a link error for bus_space_write_region_8 */ 540#define bus_space_write_region_8 \ 541 !!! bus_space_write_region_8 unimplemented !!! 542#endif 543 544/* 545 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 546 * by tag/handle/offset `count' times. 547 */ 548 549static __inline void bus_space_set_multi_1(bus_space_tag_t tag, 550 bus_space_handle_t bsh, 551 bus_size_t offset, 552 u_int8_t value, size_t count); 553static __inline void bus_space_set_multi_2(bus_space_tag_t tag, 554 bus_space_handle_t bsh, 555 bus_size_t offset, 556 u_int16_t value, size_t count); 557static __inline void bus_space_set_multi_4(bus_space_tag_t tag, 558 bus_space_handle_t bsh, 559 bus_size_t offset, 560 u_int32_t value, size_t count); 561 562static __inline void 563bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 564 bus_size_t offset, u_int8_t value, size_t count) 565{ 566 bus_addr_t addr = bsh + offset; 567 568 if (tag == MIPS_BUS_SPACE_IO) 569 while (count--) 570 outb(addr, value); 571 else 572 while (count--) 573 writeb(addr, value); 574} 575 576static __inline void 577bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 578 bus_size_t offset, u_int16_t value, size_t count) 579{ 580 bus_addr_t addr = bsh + offset; 581 582 if (tag == MIPS_BUS_SPACE_IO) 583 while (count--) 584 outw(addr, value); 585 else 586 while (count--) 587 writew(addr, value); 588} 589 590static __inline void 591bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 592 bus_size_t offset, u_int32_t value, size_t count) 593{ 594 bus_addr_t addr = bsh + offset; 595 596 if (tag == MIPS_BUS_SPACE_IO) 597 while (count--) 598 outl(addr, value); 599 else 600 while (count--) 601 writel(addr, value); 602} 603 604#if 0 /* Cause a link error for bus_space_set_multi_8 */ 605#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! 606#endif 607 608/* 609 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 610 * by tag/handle starting at `offset'. 611 */ 612 613static __inline void bus_space_set_region_1(bus_space_tag_t tag, 614 bus_space_handle_t bsh, 615 bus_size_t offset, u_int8_t value, 616 size_t count); 617static __inline void bus_space_set_region_2(bus_space_tag_t tag, 618 bus_space_handle_t bsh, 619 bus_size_t offset, u_int16_t value, 620 size_t count); 621static __inline void bus_space_set_region_4(bus_space_tag_t tag, 622 bus_space_handle_t bsh, 623 bus_size_t offset, u_int32_t value, 624 size_t count); 625 626static __inline void 627bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 628 bus_size_t offset, u_int8_t value, size_t count) 629{ 630 bus_addr_t addr = bsh + offset; 631 632 if (tag == MIPS_BUS_SPACE_IO) 633 for (; count != 0; count--, addr++) 634 outb(addr, value); 635 else 636 for (; count != 0; count--, addr++) 637 writeb(addr, value); 638} 639 640static __inline void 641bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 642 bus_size_t offset, u_int16_t value, size_t count) 643{ 644 bus_addr_t addr = bsh + offset; 645 646 if (tag == MIPS_BUS_SPACE_IO) 647 for (; count != 0; count--, addr += 2) 648 outw(addr, value); 649 else 650 for (; count != 0; count--, addr += 2) 651 writew(addr, value); 652} 653 654static __inline void 655bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 656 bus_size_t offset, u_int32_t value, size_t count) 657{ 658 bus_addr_t addr = bsh + offset; 659 660 if (tag == MIPS_BUS_SPACE_IO) 661 for (; count != 0; count--, addr += 4) 662 outl(addr, value); 663 else 664 for (; count != 0; count--, addr += 4) 665 writel(addr, value); 666} 667 668#if 0 /* Cause a link error for bus_space_set_region_8 */ 669#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! 670#endif 671 672/* 673 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 674 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 675 */ 676 677static __inline void bus_space_copy_region_1(bus_space_tag_t tag, 678 bus_space_handle_t bsh1, 679 bus_size_t off1, 680 bus_space_handle_t bsh2, 681 bus_size_t off2, size_t count); 682 683static __inline void bus_space_copy_region_2(bus_space_tag_t tag, 684 bus_space_handle_t bsh1, 685 bus_size_t off1, 686 bus_space_handle_t bsh2, 687 bus_size_t off2, size_t count); 688 689static __inline void bus_space_copy_region_4(bus_space_tag_t tag, 690 bus_space_handle_t bsh1, 691 bus_size_t off1, 692 bus_space_handle_t bsh2, 693 bus_size_t off2, size_t count); 694 695static __inline void 696bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1, 697 bus_size_t off1, bus_space_handle_t bsh2, 698 bus_size_t off2, size_t count) 699{ 700 bus_addr_t addr1 = bsh1 + off1; 701 bus_addr_t addr2 = bsh2 + off2; 702 703 if (tag == MIPS_BUS_SPACE_IO) 704 { 705 if (addr1 >= addr2) { 706 /* src after dest: copy forward */ 707 for (; count != 0; count--, addr1++, addr2++) 708 outb(addr2, inb(addr1)); 709 } else { 710 /* dest after src: copy backwards */ 711 for (addr1 += (count - 1), addr2 += (count - 1); 712 count != 0; count--, addr1--, addr2--) 713 outb(addr2, inb(addr1)); 714 } 715 } else { 716 if (addr1 >= addr2) { 717 /* src after dest: copy forward */ 718 for (; count != 0; count--, addr1++, addr2++) 719 writeb(addr2, readb(addr1)); 720 } else { 721 /* dest after src: copy backwards */ 722 for (addr1 += (count - 1), addr2 += (count - 1); 723 count != 0; count--, addr1--, addr2--) 724 writeb(addr2, readb(addr1)); 725 } 726 } 727} 728 729static __inline void 730bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1, 731 bus_size_t off1, bus_space_handle_t bsh2, 732 bus_size_t off2, size_t count) 733{ 734 bus_addr_t addr1 = bsh1 + off1; 735 bus_addr_t addr2 = bsh2 + off2; 736 737 if (tag == MIPS_BUS_SPACE_IO) 738 { 739 if (addr1 >= addr2) { 740 /* src after dest: copy forward */ 741 for (; count != 0; count--, addr1 += 2, addr2 += 2) 742 outw(addr2, inw(addr1)); 743 } else { 744 /* dest after src: copy backwards */ 745 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 746 count != 0; count--, addr1 -= 2, addr2 -= 2) 747 outw(addr2, inw(addr1)); 748 } 749 } else { 750 if (addr1 >= addr2) { 751 /* src after dest: copy forward */ 752 for (; count != 0; count--, addr1 += 2, addr2 += 2) 753 writew(addr2, readw(addr1)); 754 } else { 755 /* dest after src: copy backwards */ 756 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 757 count != 0; count--, addr1 -= 2, addr2 -= 2) 758 writew(addr2, readw(addr1)); 759 } 760 } 761} 762 763static __inline void 764bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, 765 bus_size_t off1, bus_space_handle_t bsh2, 766 bus_size_t off2, size_t count) 767{ 768 bus_addr_t addr1 = bsh1 + off1; 769 bus_addr_t addr2 = bsh2 + off2; 770 771 if (tag == MIPS_BUS_SPACE_IO) 772 { 773 if (addr1 >= addr2) { 774 /* src after dest: copy forward */ 775 for (; count != 0; count--, addr1 += 4, addr2 += 4) 776 outl(addr2, inl(addr1)); 777 } else { 778 /* dest after src: copy backwards */ 779 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 780 count != 0; count--, addr1 -= 4, addr2 -= 4) 781 outl(addr2, inl(addr1)); 782 } 783 } else { 784 if (addr1 >= addr2) { 785 /* src after dest: copy forward */ 786 for (; count != 0; count--, addr1 += 4, addr2 += 4) 787 writel(addr2, readl(addr1)); 788 } else { 789 /* dest after src: copy backwards */ 790 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 791 count != 0; count--, addr1 -= 4, addr2 -= 4) 792 writel(addr2, readl(addr1)); 793 } 794 } 795} 796 797 798#if 0 /* Cause a link error for bus_space_copy_8 */ 799#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! 800#endif 801 802 803/* 804 * Bus read/write barrier methods. 805 * 806 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, 807 * bus_size_t offset, bus_size_t len, int flags); 808 * 809 * 810 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than 811 * prevent reordering by the compiler; all Intel x86 processors currently 812 * retire operations outside the CPU in program order. 813 */ 814#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 815#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 816 817static __inline void 818bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused, 819 bus_size_t offset __unused, bus_size_t len __unused, int flags) 820{ 821#if 0 822#ifdef __GNUCLIKE_ASM 823 if (flags & BUS_SPACE_BARRIER_READ) 824 __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory"); 825 else 826 __asm __volatile("" : : : "memory"); 827#endif 828#endif 829} 830 831#ifdef BUS_SPACE_NO_LEGACY 832#undef inb 833#undef outb 834#define inb(a) compiler_error 835#define inw(a) compiler_error 836#define inl(a) compiler_error 837#define outb(a, b) compiler_error 838#define outw(a, b) compiler_error 839#define outl(a, b) compiler_error 840#endif 841 842#include <machine/bus_dma.h> 843 844/* 845 * Stream accesses are the same as normal accesses on amd64; there are no 846 * supported bus systems with an endianess different from the host one. 847 */ 848#define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o)) 849#define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o)) 850#define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o)) 851 852#define bus_space_read_multi_stream_1(t, h, o, a, c) \ 853 bus_space_read_multi_1((t), (h), (o), (a), (c)) 854#define bus_space_read_multi_stream_2(t, h, o, a, c) \ 855 bus_space_read_multi_2((t), (h), (o), (a), (c)) 856#define bus_space_read_multi_stream_4(t, h, o, a, c) \ 857 bus_space_read_multi_4((t), (h), (o), (a), (c)) 858 859#define bus_space_write_stream_1(t, h, o, v) \ 860 bus_space_write_1((t), (h), (o), (v)) 861#define bus_space_write_stream_2(t, h, o, v) \ 862 bus_space_write_2((t), (h), (o), (v)) 863#define bus_space_write_stream_4(t, h, o, v) \ 864 bus_space_write_4((t), (h), (o), (v)) 865 866#define bus_space_write_multi_stream_1(t, h, o, a, c) \ 867 bus_space_write_multi_1((t), (h), (o), (a), (c)) 868#define bus_space_write_multi_stream_2(t, h, o, a, c) \ 869 bus_space_write_multi_2((t), (h), (o), (a), (c)) 870#define bus_space_write_multi_stream_4(t, h, o, a, c) \ 871 bus_space_write_multi_4((t), (h), (o), (a), (c)) 872 873#define bus_space_set_multi_stream_1(t, h, o, v, c) \ 874 bus_space_set_multi_1((t), (h), (o), (v), (c)) 875#define bus_space_set_multi_stream_2(t, h, o, v, c) \ 876 bus_space_set_multi_2((t), (h), (o), (v), (c)) 877#define bus_space_set_multi_stream_4(t, h, o, v, c) \ 878 bus_space_set_multi_4((t), (h), (o), (v), (c)) 879 880#define bus_space_read_region_stream_1(t, h, o, a, c) \ 881 bus_space_read_region_1((t), (h), (o), (a), (c)) 882#define bus_space_read_region_stream_2(t, h, o, a, c) \ 883 bus_space_read_region_2((t), (h), (o), (a), (c)) 884#define bus_space_read_region_stream_4(t, h, o, a, c) \ 885 bus_space_read_region_4((t), (h), (o), (a), (c)) 886 887#define bus_space_write_region_stream_1(t, h, o, a, c) \ 888 bus_space_write_region_1((t), (h), (o), (a), (c)) 889#define bus_space_write_region_stream_2(t, h, o, a, c) \ 890 bus_space_write_region_2((t), (h), (o), (a), (c)) 891#define bus_space_write_region_stream_4(t, h, o, a, c) \ 892 bus_space_write_region_4((t), (h), (o), (a), (c)) 893 894#define bus_space_set_region_stream_1(t, h, o, v, c) \ 895 bus_space_set_region_1((t), (h), (o), (v), (c)) 896#define bus_space_set_region_stream_2(t, h, o, v, c) \ 897 bus_space_set_region_2((t), (h), (o), (v), (c)) 898#define bus_space_set_region_stream_4(t, h, o, v, c) \ 899 bus_space_set_region_4((t), (h), (o), (v), (c)) 900 901#define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \ 902 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c)) 903#define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \ 904 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c)) 905#define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \ 906 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c)) 907 908#endif /* !TARGET_OCTEON */ 909#endif /* !_MACHINE_BUS_H_ */ 910