compiler.h (32235B)
1 /* 2 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Thomas Roell not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Thomas Roell makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 */ 23 /* 24 * Copyright (c) 1994-2003 by The XFree86 Project, Inc. 25 * 26 * Permission is hereby granted, free of charge, to any person obtaining a 27 * copy of this software and associated documentation files (the "Software"), 28 * to deal in the Software without restriction, including without limitation 29 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 30 * and/or sell copies of the Software, and to permit persons to whom the 31 * Software is furnished to do so, subject to the following conditions: 32 * 33 * The above copyright notice and this permission notice shall be included in 34 * all copies or substantial portions of the Software. 35 * 36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 39 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 40 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 41 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 42 * OTHER DEALINGS IN THE SOFTWARE. 43 * 44 * Except as contained in this notice, the name of the copyright holder(s) 45 * and author(s) shall not be used in advertising or otherwise to promote 46 * the sale, use or other dealings in this Software without prior written 47 * authorization from the copyright holder(s) and author(s). 48 */ 49 50 #ifndef _COMPILER_H 51 52 #define _COMPILER_H 53 54 #if defined(__SUNPRO_C) 55 #define DO_PROTOTYPES 56 #endif 57 58 /* Map Sun compiler platform defines to gcc-style used in the code */ 59 #if defined(__amd64) && !defined(__amd64__) 60 #define __amd64__ 61 #endif 62 #if defined(__i386) && !defined(__i386__) 63 #define __i386__ 64 #endif 65 #if defined(__sparc) && !defined(__sparc__) 66 #define __sparc__ 67 #endif 68 #if defined(__sparcv9) && !defined(__sparc64__) 69 #define __sparc64__ 70 #endif 71 72 #ifndef _X_EXPORT 73 #include <X11/Xfuncproto.h> 74 #endif 75 76 #include <pixman.h> /* for uint*_t types */ 77 78 /* Allow drivers to use the GCC-supported __inline__ and/or __inline. */ 79 #ifndef __inline__ 80 #if defined(__GNUC__) 81 /* gcc has __inline__ */ 82 #else 83 #define __inline__ /**/ 84 #endif 85 #endif /* __inline__ */ 86 #ifndef __inline 87 #if defined(__GNUC__) 88 /* gcc has __inline */ 89 #else 90 #define __inline /**/ 91 #endif 92 #endif /* __inline */ 93 /* Support gcc's __FUNCTION__ for people using other compilers */ 94 #if !defined(__GNUC__) && !defined(__FUNCTION__) 95 #define __FUNCTION__ __func__ /* C99 */ 96 #endif 97 98 #if defined(DO_PROTOTYPES) 99 #if !defined(__arm__) 100 #if !defined(__sparc__) && !defined(__arm32__) && !defined(__nds32__) \ 101 && !(defined(__alpha__) && defined(__linux__)) \ 102 && !(defined(__ia64__) && defined(__linux__)) \ 103 && !(defined(__mips64) && defined(__linux__)) \ 104 105 extern _X_EXPORT void outb(unsigned short, unsigned char); 106 extern _X_EXPORT void outw(unsigned short, unsigned short); 107 extern _X_EXPORT void outl(unsigned short, unsigned int); 108 extern _X_EXPORT unsigned int inb(unsigned short); 109 extern _X_EXPORT unsigned int inw(unsigned short); 110 extern _X_EXPORT unsigned int inl(unsigned short); 111 112 #else /* __sparc__, __arm32__, __alpha__, __nds32__ */ 113 extern _X_EXPORT void outb(unsigned long, unsigned char); 114 extern _X_EXPORT void outw(unsigned long, unsigned short); 115 extern _X_EXPORT void outl(unsigned long, unsigned int); 116 extern _X_EXPORT unsigned int inb(unsigned long); 117 extern _X_EXPORT unsigned int inw(unsigned long); 118 extern _X_EXPORT unsigned int inl(unsigned long); 119 120 #ifdef __SUNPRO_C 121 extern _X_EXPORT unsigned char xf86ReadMmio8 (void *, unsigned long); 122 extern _X_EXPORT unsigned short xf86ReadMmio16Be (void *, unsigned long); 123 extern _X_EXPORT unsigned short xf86ReadMmio16Le (void *, unsigned long); 124 extern _X_EXPORT unsigned int xf86ReadMmio32Be (void *, unsigned long); 125 extern _X_EXPORT unsigned int xf86ReadMmio32Le (void *, unsigned long); 126 extern _X_EXPORT void xf86WriteMmio8 (void *, unsigned long, unsigned int); 127 extern _X_EXPORT void xf86WriteMmio16Be (void *, unsigned long, unsigned int); 128 extern _X_EXPORT void xf86WriteMmio16Le (void *, unsigned long, unsigned int); 129 extern _X_EXPORT void xf86WriteMmio32Be (void *, unsigned long, unsigned int); 130 extern _X_EXPORT void xf86WriteMmio32Le (void *, unsigned long, unsigned int); 131 #endif /* _SUNPRO_C */ 132 #endif /* __sparc__, __arm32__, __alpha__, __nds32__ */ 133 #endif /* __arm__ */ 134 135 #endif /* NO_INLINE || DO_PROTOTYPES */ 136 137 #ifdef __GNUC__ 138 #ifdef __i386__ 139 140 #ifdef __SSE__ 141 #define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory") 142 #else 143 #define write_mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") 144 #endif 145 146 #ifdef __SSE2__ 147 #define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory") 148 #else 149 #define mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") 150 #endif 151 152 #elif defined __alpha__ 153 154 #define mem_barrier() __asm__ __volatile__ ("mb" : : : "memory") 155 #define write_mem_barrier() __asm__ __volatile__ ("wmb" : : : "memory") 156 157 #elif defined __amd64__ 158 159 #define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory") 160 #define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory") 161 162 #elif defined __ia64__ 163 164 #ifndef __INTEL_COMPILER 165 #define mem_barrier() __asm__ __volatile__ ("mf" : : : "memory") 166 #define write_mem_barrier() __asm__ __volatile__ ("mf" : : : "memory") 167 #else 168 #include "ia64intrin.h" 169 #define mem_barrier() __mf() 170 #define write_mem_barrier() __mf() 171 #endif 172 173 #elif defined __mips__ 174 /* Note: sync instruction requires MIPS II instruction set */ 175 #define mem_barrier() \ 176 __asm__ __volatile__( \ 177 ".set push\n\t" \ 178 ".set noreorder\n\t" \ 179 ".set mips2\n\t" \ 180 "sync\n\t" \ 181 ".set pop" \ 182 : /* no output */ \ 183 : /* no input */ \ 184 : "memory") 185 #define write_mem_barrier() mem_barrier() 186 187 #elif defined __powerpc__ 188 189 #ifndef eieio 190 #define eieio() __asm__ __volatile__ ("eieio" ::: "memory") 191 #endif /* eieio */ 192 #define mem_barrier() eieio() 193 #define write_mem_barrier() eieio() 194 195 #elif defined __sparc__ 196 197 #define barrier() __asm__ __volatile__ (".word 0x8143e00a" : : : "memory") 198 #define mem_barrier() /* XXX: nop for now */ 199 #define write_mem_barrier() /* XXX: nop for now */ 200 #endif 201 #endif /* __GNUC__ */ 202 203 #ifndef barrier 204 #define barrier() 205 #endif 206 207 #ifndef mem_barrier 208 #define mem_barrier() /* NOP */ 209 #endif 210 211 #ifndef write_mem_barrier 212 #define write_mem_barrier() /* NOP */ 213 #endif 214 215 #ifdef __GNUC__ 216 #if defined(__alpha__) 217 218 #ifdef __linux__ 219 /* for Linux on Alpha, we use the LIBC _inx/_outx routines */ 220 /* note that the appropriate setup via "ioperm" needs to be done */ 221 /* *before* any inx/outx is done. */ 222 223 extern _X_EXPORT void _outb(unsigned char val, unsigned long port); 224 extern _X_EXPORT void _outw(unsigned short val, unsigned long port); 225 extern _X_EXPORT void _outl(unsigned int val, unsigned long port); 226 extern _X_EXPORT unsigned int _inb(unsigned long port); 227 extern _X_EXPORT unsigned int _inw(unsigned long port); 228 extern _X_EXPORT unsigned int _inl(unsigned long port); 229 230 static __inline__ void 231 outb(unsigned long port, unsigned char val) 232 { 233 _outb(val, port); 234 } 235 236 static __inline__ void 237 outw(unsigned long port, unsigned short val) 238 { 239 _outw(val, port); 240 } 241 242 static __inline__ void 243 outl(unsigned long port, unsigned int val) 244 { 245 _outl(val, port); 246 } 247 248 static __inline__ unsigned int 249 inb(unsigned long port) 250 { 251 return _inb(port); 252 } 253 254 static __inline__ unsigned int 255 inw(unsigned long port) 256 { 257 return _inw(port); 258 } 259 260 static __inline__ unsigned int 261 inl(unsigned long port) 262 { 263 return _inl(port); 264 } 265 266 #endif /* __linux__ */ 267 268 #if (defined(__FreeBSD__) || defined(__OpenBSD__)) \ 269 && !defined(DO_PROTOTYPES) 270 271 /* for FreeBSD and OpenBSD on Alpha, we use the libio (resp. libalpha) */ 272 /* inx/outx routines */ 273 /* note that the appropriate setup via "ioperm" needs to be done */ 274 /* *before* any inx/outx is done. */ 275 276 extern _X_EXPORT void outb(unsigned int port, unsigned char val); 277 extern _X_EXPORT void outw(unsigned int port, unsigned short val); 278 extern _X_EXPORT void outl(unsigned int port, unsigned int val); 279 extern _X_EXPORT unsigned char inb(unsigned int port); 280 extern _X_EXPORT unsigned short inw(unsigned int port); 281 extern _X_EXPORT unsigned int inl(unsigned int port); 282 283 #endif /* (__FreeBSD__ || __OpenBSD__ ) && !DO_PROTOTYPES */ 284 285 #if defined(__NetBSD__) 286 #include <machine/pio.h> 287 #endif /* __NetBSD__ */ 288 289 #elif defined(__amd64__) || defined(__i386__) || defined(__ia64__) 290 291 #include <inttypes.h> 292 293 static __inline__ void 294 outb(unsigned short port, unsigned char val) 295 { 296 __asm__ __volatile__("outb %0,%1"::"a"(val), "d"(port)); 297 } 298 299 static __inline__ void 300 outw(unsigned short port, unsigned short val) 301 { 302 __asm__ __volatile__("outw %0,%1"::"a"(val), "d"(port)); 303 } 304 305 static __inline__ void 306 outl(unsigned short port, unsigned int val) 307 { 308 __asm__ __volatile__("outl %0,%1"::"a"(val), "d"(port)); 309 } 310 311 static __inline__ unsigned int 312 inb(unsigned short port) 313 { 314 unsigned char ret; 315 __asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port)); 316 317 return ret; 318 } 319 320 static __inline__ unsigned int 321 inw(unsigned short port) 322 { 323 unsigned short ret; 324 __asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port)); 325 326 return ret; 327 } 328 329 static __inline__ unsigned int 330 inl(unsigned short port) 331 { 332 unsigned int ret; 333 __asm__ __volatile__("inl %1,%0":"=a"(ret):"d"(port)); 334 335 return ret; 336 } 337 338 #elif defined(__sparc__) 339 340 #ifndef ASI_PL 341 #define ASI_PL 0x88 342 #endif 343 344 static __inline__ void 345 outb(unsigned long port, unsigned char val) 346 { 347 __asm__ __volatile__("stba %0, [%1] %2": /* No outputs */ 348 :"r"(val), "r"(port), "i"(ASI_PL)); 349 350 barrier(); 351 } 352 353 static __inline__ void 354 outw(unsigned long port, unsigned short val) 355 { 356 __asm__ __volatile__("stha %0, [%1] %2": /* No outputs */ 357 :"r"(val), "r"(port), "i"(ASI_PL)); 358 359 barrier(); 360 } 361 362 static __inline__ void 363 outl(unsigned long port, unsigned int val) 364 { 365 __asm__ __volatile__("sta %0, [%1] %2": /* No outputs */ 366 :"r"(val), "r"(port), "i"(ASI_PL)); 367 368 barrier(); 369 } 370 371 static __inline__ unsigned int 372 inb(unsigned long port) 373 { 374 unsigned int ret; 375 __asm__ __volatile__("lduba [%1] %2, %0":"=r"(ret) 376 :"r"(port), "i"(ASI_PL)); 377 378 return ret; 379 } 380 381 static __inline__ unsigned int 382 inw(unsigned long port) 383 { 384 unsigned int ret; 385 __asm__ __volatile__("lduha [%1] %2, %0":"=r"(ret) 386 :"r"(port), "i"(ASI_PL)); 387 388 return ret; 389 } 390 391 static __inline__ unsigned int 392 inl(unsigned long port) 393 { 394 unsigned int ret; 395 __asm__ __volatile__("lda [%1] %2, %0":"=r"(ret) 396 :"r"(port), "i"(ASI_PL)); 397 398 return ret; 399 } 400 401 static __inline__ unsigned char 402 xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 403 { 404 unsigned long addr = ((unsigned long) base) + offset; 405 unsigned char ret; 406 407 __asm__ __volatile__("lduba [%1] %2, %0":"=r"(ret) 408 :"r"(addr), "i"(ASI_PL)); 409 410 return ret; 411 } 412 413 static __inline__ unsigned short 414 xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset) 415 { 416 unsigned long addr = ((unsigned long) base) + offset; 417 unsigned short ret; 418 419 __asm__ __volatile__("lduh [%1], %0":"=r"(ret) 420 :"r"(addr)); 421 422 return ret; 423 } 424 425 static __inline__ unsigned short 426 xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset) 427 { 428 unsigned long addr = ((unsigned long) base) + offset; 429 unsigned short ret; 430 431 __asm__ __volatile__("lduha [%1] %2, %0":"=r"(ret) 432 :"r"(addr), "i"(ASI_PL)); 433 434 return ret; 435 } 436 437 static __inline__ unsigned int 438 xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) 439 { 440 unsigned long addr = ((unsigned long) base) + offset; 441 unsigned int ret; 442 443 __asm__ __volatile__("ld [%1], %0":"=r"(ret) 444 :"r"(addr)); 445 446 return ret; 447 } 448 449 static __inline__ unsigned int 450 xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset) 451 { 452 unsigned long addr = ((unsigned long) base) + offset; 453 unsigned int ret; 454 455 __asm__ __volatile__("lda [%1] %2, %0":"=r"(ret) 456 :"r"(addr), "i"(ASI_PL)); 457 458 return ret; 459 } 460 461 static __inline__ void 462 xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 463 const unsigned int val) 464 { 465 unsigned long addr = ((unsigned long) base) + offset; 466 467 __asm__ __volatile__("stba %0, [%1] %2": /* No outputs */ 468 :"r"(val), "r"(addr), "i"(ASI_PL)); 469 470 barrier(); 471 } 472 473 static __inline__ void 474 xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset, 475 const unsigned int val) 476 { 477 unsigned long addr = ((unsigned long) base) + offset; 478 479 __asm__ __volatile__("sth %0, [%1]": /* No outputs */ 480 :"r"(val), "r"(addr)); 481 482 barrier(); 483 } 484 485 static __inline__ void 486 xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset, 487 const unsigned int val) 488 { 489 unsigned long addr = ((unsigned long) base) + offset; 490 491 __asm__ __volatile__("stha %0, [%1] %2": /* No outputs */ 492 :"r"(val), "r"(addr), "i"(ASI_PL)); 493 494 barrier(); 495 } 496 497 static __inline__ void 498 xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 499 const unsigned int val) 500 { 501 unsigned long addr = ((unsigned long) base) + offset; 502 503 __asm__ __volatile__("st %0, [%1]": /* No outputs */ 504 :"r"(val), "r"(addr)); 505 506 barrier(); 507 } 508 509 static __inline__ void 510 xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset, 511 const unsigned int val) 512 { 513 unsigned long addr = ((unsigned long) base) + offset; 514 515 __asm__ __volatile__("sta %0, [%1] %2": /* No outputs */ 516 :"r"(val), "r"(addr), "i"(ASI_PL)); 517 518 barrier(); 519 } 520 521 #elif defined(__arm32__) && !defined(__linux__) 522 #define PORT_SIZE long 523 524 extern _X_EXPORT unsigned int IOPortBase; /* Memory mapped I/O port area */ 525 526 static __inline__ void 527 outb(unsigned PORT_SIZE port, unsigned char val) 528 { 529 *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) + IOPortBase) = 530 val; 531 } 532 533 static __inline__ void 534 outw(unsigned PORT_SIZE port, unsigned short val) 535 { 536 *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) + IOPortBase) = 537 val; 538 } 539 540 static __inline__ void 541 outl(unsigned PORT_SIZE port, unsigned int val) 542 { 543 *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)) + IOPortBase) = 544 val; 545 } 546 547 static __inline__ unsigned int 548 inb(unsigned PORT_SIZE port) 549 { 550 return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) + 551 IOPortBase); 552 } 553 554 static __inline__ unsigned int 555 inw(unsigned PORT_SIZE port) 556 { 557 return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) + 558 IOPortBase); 559 } 560 561 static __inline__ unsigned int 562 inl(unsigned PORT_SIZE port) 563 { 564 return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)) + 565 IOPortBase); 566 } 567 568 #if defined(__mips__) 569 #ifdef __linux__ /* don't mess with other OSs */ 570 #if X_BYTE_ORDER == X_BIG_ENDIAN 571 static __inline__ unsigned int 572 xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) 573 { 574 unsigned long addr = ((unsigned long) base) + offset; 575 unsigned int ret; 576 577 __asm__ __volatile__("lw %0, 0(%1)":"=r"(ret) 578 :"r"(addr)); 579 580 return ret; 581 } 582 583 static __inline__ void 584 xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 585 const unsigned int val) 586 { 587 unsigned long addr = ((unsigned long) base) + offset; 588 589 __asm__ __volatile__("sw %0, 0(%1)": /* No outputs */ 590 :"r"(val), "r"(addr)); 591 } 592 #endif 593 #endif /* !__linux__ */ 594 #endif /* __mips__ */ 595 596 #elif defined(__powerpc__) 597 598 #ifndef MAP_FAILED 599 #define MAP_FAILED ((void *)-1) 600 #endif 601 602 extern _X_EXPORT volatile unsigned char *ioBase; 603 604 static __inline__ unsigned char 605 xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 606 { 607 register unsigned char val; 608 __asm__ __volatile__("lbzx %0,%1,%2\n\t" "eieio":"=r"(val) 609 :"b"(base), "r"(offset), 610 "m"(*((volatile unsigned char *) base + offset))); 611 return val; 612 } 613 614 static __inline__ unsigned short 615 xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset) 616 { 617 register unsigned short val; 618 __asm__ __volatile__("lhzx %0,%1,%2\n\t" "eieio":"=r"(val) 619 :"b"(base), "r"(offset), 620 "m"(*((volatile unsigned char *) base + offset))); 621 return val; 622 } 623 624 static __inline__ unsigned short 625 xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset) 626 { 627 register unsigned short val; 628 __asm__ __volatile__("lhbrx %0,%1,%2\n\t" "eieio":"=r"(val) 629 :"b"(base), "r"(offset), 630 "m"(*((volatile unsigned char *) base + offset))); 631 return val; 632 } 633 634 static __inline__ unsigned int 635 xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) 636 { 637 register unsigned int val; 638 __asm__ __volatile__("lwzx %0,%1,%2\n\t" "eieio":"=r"(val) 639 :"b"(base), "r"(offset), 640 "m"(*((volatile unsigned char *) base + offset))); 641 return val; 642 } 643 644 static __inline__ unsigned int 645 xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset) 646 { 647 register unsigned int val; 648 __asm__ __volatile__("lwbrx %0,%1,%2\n\t" "eieio":"=r"(val) 649 :"b"(base), "r"(offset), 650 "m"(*((volatile unsigned char *) base + offset))); 651 return val; 652 } 653 654 static __inline__ void 655 xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 656 const unsigned char val) 657 { 658 __asm__ 659 __volatile__("stbx %1,%2,%3\n\t":"=m" 660 (*((volatile unsigned char *) base + offset)) 661 :"r"(val), "b"(base), "r"(offset)); 662 eieio(); 663 } 664 665 static __inline__ void 666 xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset, 667 const unsigned short val) 668 { 669 __asm__ 670 __volatile__("sthbrx %1,%2,%3\n\t":"=m" 671 (*((volatile unsigned char *) base + offset)) 672 :"r"(val), "b"(base), "r"(offset)); 673 eieio(); 674 } 675 676 static __inline__ void 677 xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset, 678 const unsigned short val) 679 { 680 __asm__ 681 __volatile__("sthx %1,%2,%3\n\t":"=m" 682 (*((volatile unsigned char *) base + offset)) 683 :"r"(val), "b"(base), "r"(offset)); 684 eieio(); 685 } 686 687 static __inline__ void 688 xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset, 689 const unsigned int val) 690 { 691 __asm__ 692 __volatile__("stwbrx %1,%2,%3\n\t":"=m" 693 (*((volatile unsigned char *) base + offset)) 694 :"r"(val), "b"(base), "r"(offset)); 695 eieio(); 696 } 697 698 static __inline__ void 699 xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 700 const unsigned int val) 701 { 702 __asm__ 703 __volatile__("stwx %1,%2,%3\n\t":"=m" 704 (*((volatile unsigned char *) base + offset)) 705 :"r"(val), "b"(base), "r"(offset)); 706 eieio(); 707 } 708 709 static __inline__ void 710 outb(unsigned short port, unsigned char value) 711 { 712 if (ioBase == MAP_FAILED) 713 return; 714 xf86WriteMmio8((void *) ioBase, port, value); 715 } 716 717 static __inline__ void 718 outw(unsigned short port, unsigned short value) 719 { 720 if (ioBase == MAP_FAILED) 721 return; 722 xf86WriteMmio16Le((void *) ioBase, port, value); 723 } 724 725 static __inline__ void 726 outl(unsigned short port, unsigned int value) 727 { 728 if (ioBase == MAP_FAILED) 729 return; 730 xf86WriteMmio32Le((void *) ioBase, port, value); 731 } 732 733 static __inline__ unsigned int 734 inb(unsigned short port) 735 { 736 if (ioBase == MAP_FAILED) 737 return 0; 738 return xf86ReadMmio8((void *) ioBase, port); 739 } 740 741 static __inline__ unsigned int 742 inw(unsigned short port) 743 { 744 if (ioBase == MAP_FAILED) 745 return 0; 746 return xf86ReadMmio16Le((void *) ioBase, port); 747 } 748 749 static __inline__ unsigned int 750 inl(unsigned short port) 751 { 752 if (ioBase == MAP_FAILED) 753 return 0; 754 return xf86ReadMmio32Le((void *) ioBase, port); 755 } 756 757 #elif defined(__nds32__) 758 759 /* 760 * Assume all port access are aligned. We need to revise this implementation 761 * if there is unaligned port access. 762 */ 763 764 #define PORT_SIZE long 765 766 static __inline__ unsigned char 767 xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 768 { 769 return *(volatile unsigned char *) ((unsigned char *) base + offset); 770 } 771 772 static __inline__ void 773 xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 774 const unsigned int val) 775 { 776 *(volatile unsigned char *) ((unsigned char *) base + offset) = val; 777 barrier(); 778 } 779 780 static __inline__ unsigned short 781 xf86ReadMmio16Swap(__volatile__ void *base, const unsigned long offset) 782 { 783 unsigned long addr = ((unsigned long) base) + offset; 784 unsigned short ret; 785 786 __asm__ __volatile__("lhi %0, [%1];\n\t" "wsbh %0, %0;\n\t":"=r"(ret) 787 :"r"(addr)); 788 789 return ret; 790 } 791 792 static __inline__ unsigned short 793 xf86ReadMmio16(__volatile__ void *base, const unsigned long offset) 794 { 795 return *(volatile unsigned short *) ((char *) base + offset); 796 } 797 798 static __inline__ void 799 xf86WriteMmio16Swap(__volatile__ void *base, const unsigned long offset, 800 const unsigned int val) 801 { 802 unsigned long addr = ((unsigned long) base) + offset; 803 804 __asm__ __volatile__("wsbh %0, %0;\n\t" "shi %0, [%1];\n\t": /* No outputs */ 805 :"r"(val), "r"(addr)); 806 807 barrier(); 808 } 809 810 static __inline__ void 811 xf86WriteMmio16(__volatile__ void *base, const unsigned long offset, 812 const unsigned int val) 813 { 814 *(volatile unsigned short *) ((unsigned char *) base + offset) = val; 815 barrier(); 816 } 817 818 static __inline__ unsigned int 819 xf86ReadMmio32Swap(__volatile__ void *base, const unsigned long offset) 820 { 821 unsigned long addr = ((unsigned long) base) + offset; 822 unsigned int ret; 823 824 __asm__ __volatile__("lwi %0, [%1];\n\t" 825 "wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t":"=r"(ret) 826 :"r"(addr)); 827 828 return ret; 829 } 830 831 static __inline__ unsigned int 832 xf86ReadMmio32(__volatile__ void *base, const unsigned long offset) 833 { 834 return *(volatile unsigned int *) ((unsigned char *) base + offset); 835 } 836 837 static __inline__ void 838 xf86WriteMmio32Swap(__volatile__ void *base, const unsigned long offset, 839 const unsigned int val) 840 { 841 unsigned long addr = ((unsigned long) base) + offset; 842 843 __asm__ __volatile__("wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t" "swi %0, [%1];\n\t": /* No outputs */ 844 :"r"(val), "r"(addr)); 845 846 barrier(); 847 } 848 849 static __inline__ void 850 xf86WriteMmio32(__volatile__ void *base, const unsigned long offset, 851 const unsigned int val) 852 { 853 *(volatile unsigned int *) ((unsigned char *) base + offset) = val; 854 barrier(); 855 } 856 857 #if defined(NDS32_MMIO_SWAP) 858 static __inline__ void 859 outb(unsigned PORT_SIZE port, unsigned char val) 860 { 861 xf86WriteMmio8(IOPortBase, port, val); 862 } 863 864 static __inline__ void 865 outw(unsigned PORT_SIZE port, unsigned short val) 866 { 867 xf86WriteMmio16Swap(IOPortBase, port, val); 868 } 869 870 static __inline__ void 871 outl(unsigned PORT_SIZE port, unsigned int val) 872 { 873 xf86WriteMmio32Swap(IOPortBase, port, val); 874 } 875 876 static __inline__ unsigned int 877 inb(unsigned PORT_SIZE port) 878 { 879 return xf86ReadMmio8(IOPortBase, port); 880 } 881 882 static __inline__ unsigned int 883 inw(unsigned PORT_SIZE port) 884 { 885 return xf86ReadMmio16Swap(IOPortBase, port); 886 } 887 888 static __inline__ unsigned int 889 inl(unsigned PORT_SIZE port) 890 { 891 return xf86ReadMmio32Swap(IOPortBase, port); 892 } 893 894 #else /* !NDS32_MMIO_SWAP */ 895 static __inline__ void 896 outb(unsigned PORT_SIZE port, unsigned char val) 897 { 898 *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))) = val; 899 barrier(); 900 } 901 902 static __inline__ void 903 outw(unsigned PORT_SIZE port, unsigned short val) 904 { 905 *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))) = val; 906 barrier(); 907 } 908 909 static __inline__ void 910 outl(unsigned PORT_SIZE port, unsigned int val) 911 { 912 *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))) = val; 913 barrier(); 914 } 915 916 static __inline__ unsigned int 917 inb(unsigned PORT_SIZE port) 918 { 919 return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))); 920 } 921 922 static __inline__ unsigned int 923 inw(unsigned PORT_SIZE port) 924 { 925 return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))); 926 } 927 928 static __inline__ unsigned int 929 inl(unsigned PORT_SIZE port) 930 { 931 return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))); 932 } 933 934 #endif /* NDS32_MMIO_SWAP */ 935 936 #endif /* arch madness */ 937 938 #else /* !GNUC */ 939 #if defined(__STDC__) && (__STDC__ == 1) 940 #ifndef asm 941 #define asm __asm 942 #endif 943 #endif 944 #if !defined(__SUNPRO_C) 945 #include <sys/inline.h> 946 #endif 947 #endif /* __GNUC__ */ 948 949 #if !defined(MMIO_IS_BE) && \ 950 (defined(SPARC_MMIO_IS_BE) || defined(PPC_MMIO_IS_BE)) 951 #define MMIO_IS_BE 952 #endif 953 954 #ifdef __alpha__ 955 static inline int 956 xf86ReadMmio8(void *Base, unsigned long Offset) 957 { 958 mem_barrier(); 959 return *(CARD8 *) ((unsigned long) Base + (Offset)); 960 } 961 962 static inline int 963 xf86ReadMmio16(void *Base, unsigned long Offset) 964 { 965 mem_barrier(); 966 return *(CARD16 *) ((unsigned long) Base + (Offset)); 967 } 968 969 static inline int 970 xf86ReadMmio32(void *Base, unsigned long Offset) 971 { 972 mem_barrier(); 973 return *(CARD32 *) ((unsigned long) Base + (Offset)); 974 } 975 976 static inline void 977 xf86WriteMmio8(int Value, void *Base, unsigned long Offset) 978 { 979 write_mem_barrier(); 980 *(CARD8 *) ((unsigned long) Base + (Offset)) = Value; 981 } 982 983 static inline void 984 xf86WriteMmio16(int Value, void *Base, unsigned long Offset) 985 { 986 write_mem_barrier(); 987 *(CARD16 *) ((unsigned long) Base + (Offset)) = Value; 988 } 989 990 static inline void 991 xf86WriteMmio32(int Value, void *Base, unsigned long Offset) 992 { 993 write_mem_barrier(); 994 *(CARD32 *) ((unsigned long) Base + (Offset)) = Value; 995 } 996 997 extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, 998 int); 999 extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); 1000 1001 /* Some macros to hide the system dependencies for MMIO accesses */ 1002 /* Changed to kill noise generated by gcc's -Wcast-align */ 1003 #define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1004 #define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) 1005 #define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) 1006 1007 #define MMIO_OUT8(base, offset, val) \ 1008 xf86WriteMmio8((CARD8)(val), base, offset) 1009 #define MMIO_OUT16(base, offset, val) \ 1010 xf86WriteMmio16((CARD16)(val), base, offset) 1011 #define MMIO_OUT32(base, offset, val) \ 1012 xf86WriteMmio32((CARD32)(val), base, offset) 1013 1014 #elif defined(__powerpc__) || defined(__sparc__) 1015 /* 1016 * we provide byteswapping and no byteswapping functions here 1017 * with byteswapping as default, 1018 * drivers that don't need byteswapping should define MMIO_IS_BE 1019 */ 1020 #define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1021 #define MMIO_OUT8(base, offset, val) \ 1022 xf86WriteMmio8(base, offset, (CARD8)(val)) 1023 1024 #if defined(MMIO_IS_BE) /* No byteswapping */ 1025 #define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset) 1026 #define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset) 1027 #define MMIO_OUT16(base, offset, val) \ 1028 xf86WriteMmio16Be(base, offset, (CARD16)(val)) 1029 #define MMIO_OUT32(base, offset, val) \ 1030 xf86WriteMmio32Be(base, offset, (CARD32)(val)) 1031 #else /* byteswapping is the default */ 1032 #define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset) 1033 #define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset) 1034 #define MMIO_OUT16(base, offset, val) \ 1035 xf86WriteMmio16Le(base, offset, (CARD16)(val)) 1036 #define MMIO_OUT32(base, offset, val) \ 1037 xf86WriteMmio32Le(base, offset, (CARD32)(val)) 1038 #endif 1039 1040 #elif defined(__nds32__) 1041 /* 1042 * we provide byteswapping and no byteswapping functions here 1043 * with no byteswapping as default; when endianness of CPU core 1044 * and I/O devices don't match, byte swapping is necessary 1045 * drivers that need byteswapping should define NDS32_MMIO_SWAP 1046 */ 1047 #define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1048 #define MMIO_OUT8(base, offset, val) \ 1049 xf86WriteMmio8(base, offset, (CARD8)(val)) 1050 1051 #if defined(NDS32_MMIO_SWAP) /* byteswapping */ 1052 #define MMIO_IN16(base, offset) xf86ReadMmio16Swap(base, offset) 1053 #define MMIO_IN32(base, offset) xf86ReadMmio32Swap(base, offset) 1054 #define MMIO_OUT16(base, offset, val) \ 1055 xf86WriteMmio16Swap(base, offset, (CARD16)(val)) 1056 #define MMIO_OUT32(base, offset, val) \ 1057 xf86WriteMmio32Swap(base, offset, (CARD32)(val)) 1058 #else /* no byteswapping is the default */ 1059 #define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) 1060 #define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) 1061 #define MMIO_OUT16(base, offset, val) \ 1062 xf86WriteMmio16(base, offset, (CARD16)(val)) 1063 #define MMIO_OUT32(base, offset, val) \ 1064 xf86WriteMmio32(base, offset, (CARD32)(val)) 1065 #endif 1066 1067 #else /* !__alpha__ && !__powerpc__ && !__sparc__ */ 1068 1069 #define MMIO_IN8(base, offset) \ 1070 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) 1071 #define MMIO_IN16(base, offset) \ 1072 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) 1073 #define MMIO_IN32(base, offset) \ 1074 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) 1075 #define MMIO_OUT8(base, offset, val) \ 1076 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val) 1077 #define MMIO_OUT16(base, offset, val) \ 1078 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1079 #define MMIO_OUT32(base, offset, val) \ 1080 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1081 1082 #endif /* __alpha__ */ 1083 1084 /* 1085 * With Intel, the version in os-support/misc/SlowBcopy.s is used. 1086 * This avoids port I/O during the copy (which causes problems with 1087 * some hardware). 1088 */ 1089 #ifdef __alpha__ 1090 #define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count) 1091 #define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count) 1092 #else /* __alpha__ */ 1093 #define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count) 1094 #define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count) 1095 #endif /* __alpha__ */ 1096 1097 #endif /* _COMPILER_H */