compiler.h revision f1696b1f
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(__arm__) && !defined(__arm32__) && !defined(__nds32__) \ 101 && !(defined(__alpha__) && defined(__linux__)) \ 102 && !(defined(__ia64__) && defined(__linux__)) \ 103 && !(defined(__mips64) && defined(__linux__)) \ 104 105extern _X_EXPORT void outb(unsigned short, unsigned char); 106extern _X_EXPORT void outw(unsigned short, unsigned short); 107extern _X_EXPORT void outl(unsigned short, unsigned int); 108extern _X_EXPORT unsigned int inb(unsigned short); 109extern _X_EXPORT unsigned int inw(unsigned short); 110extern _X_EXPORT unsigned int inl(unsigned short); 111 112#else /* __sparc__, __arm__, __arm32__, __alpha__, __nds32__ */ 113extern _X_EXPORT void outb(unsigned long, unsigned char); 114extern _X_EXPORT void outw(unsigned long, unsigned short); 115extern _X_EXPORT void outl(unsigned long, unsigned int); 116extern _X_EXPORT unsigned int inb(unsigned long); 117extern _X_EXPORT unsigned int inw(unsigned long); 118extern _X_EXPORT unsigned int inl(unsigned long); 119 120#ifdef __SUNPRO_C 121extern _X_EXPORT unsigned char xf86ReadMmio8 (void *, unsigned long); 122extern _X_EXPORT unsigned short xf86ReadMmio16Be (void *, unsigned long); 123extern _X_EXPORT unsigned short xf86ReadMmio16Le (void *, unsigned long); 124extern _X_EXPORT unsigned int xf86ReadMmio32Be (void *, unsigned long); 125extern _X_EXPORT unsigned int xf86ReadMmio32Le (void *, unsigned long); 126extern _X_EXPORT void xf86WriteMmio8 (void *, unsigned long, unsigned int); 127extern _X_EXPORT void xf86WriteMmio16Be (void *, unsigned long, unsigned int); 128extern _X_EXPORT void xf86WriteMmio16Le (void *, unsigned long, unsigned int); 129extern _X_EXPORT void xf86WriteMmio32Be (void *, unsigned long, unsigned int); 130extern _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 223extern _X_EXPORT void _outb(unsigned char val, unsigned long port); 224extern _X_EXPORT void _outw(unsigned short val, unsigned long port); 225extern _X_EXPORT void _outl(unsigned int val, unsigned long port); 226extern _X_EXPORT unsigned int _inb(unsigned long port); 227extern _X_EXPORT unsigned int _inw(unsigned long port); 228extern _X_EXPORT unsigned int _inl(unsigned long port); 229 230static __inline__ void 231outb(unsigned long port, unsigned char val) 232{ 233 _outb(val, port); 234} 235 236static __inline__ void 237outw(unsigned long port, unsigned short val) 238{ 239 _outw(val, port); 240} 241 242static __inline__ void 243outl(unsigned long port, unsigned int val) 244{ 245 _outl(val, port); 246} 247 248static __inline__ unsigned int 249inb(unsigned long port) 250{ 251 return _inb(port); 252} 253 254static __inline__ unsigned int 255inw(unsigned long port) 256{ 257 return _inw(port); 258} 259 260static __inline__ unsigned int 261inl(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 276extern _X_EXPORT void outb(unsigned int port, unsigned char val); 277extern _X_EXPORT void outw(unsigned int port, unsigned short val); 278extern _X_EXPORT void outl(unsigned int port, unsigned int val); 279extern _X_EXPORT unsigned char inb(unsigned int port); 280extern _X_EXPORT unsigned short inw(unsigned int port); 281extern _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 293static __inline__ void 294outb(unsigned short port, unsigned char val) 295{ 296 __asm__ __volatile__("outb %0,%1"::"a"(val), "d"(port)); 297} 298 299static __inline__ void 300outw(unsigned short port, unsigned short val) 301{ 302 __asm__ __volatile__("outw %0,%1"::"a"(val), "d"(port)); 303} 304 305static __inline__ void 306outl(unsigned short port, unsigned int val) 307{ 308 __asm__ __volatile__("outl %0,%1"::"a"(val), "d"(port)); 309} 310 311static __inline__ unsigned int 312inb(unsigned short port) 313{ 314 unsigned char ret; 315 __asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port)); 316 317 return ret; 318} 319 320static __inline__ unsigned int 321inw(unsigned short port) 322{ 323 unsigned short ret; 324 __asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port)); 325 326 return ret; 327} 328 329static __inline__ unsigned int 330inl(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 344static __inline__ void 345outb(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 353static __inline__ void 354outw(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 362static __inline__ void 363outl(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 371static __inline__ unsigned int 372inb(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 381static __inline__ unsigned int 382inw(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 391static __inline__ unsigned int 392inl(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 401static __inline__ unsigned char 402xf86ReadMmio8(__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 413static __inline__ unsigned short 414xf86ReadMmio16Be(__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 425static __inline__ unsigned short 426xf86ReadMmio16Le(__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 437static __inline__ unsigned int 438xf86ReadMmio32Be(__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 449static __inline__ unsigned int 450xf86ReadMmio32Le(__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 461static __inline__ void 462xf86WriteMmio8(__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 473static __inline__ void 474xf86WriteMmio16Be(__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 485static __inline__ void 486xf86WriteMmio16Le(__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 497static __inline__ void 498xf86WriteMmio32Be(__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 509static __inline__ void 510xf86WriteMmio32Le(__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(__mips__) || ((defined(__arm__) || defined(__arm32__)) && !defined(__linux__)) 522#if defined(__arm__) || defined(__arm32__) || defined(__mips64) 523#define PORT_SIZE long 524#else 525#define PORT_SIZE short 526#endif 527 528extern unsigned PORT_SIZE IOPortBase; /* Memory mapped I/O port area */ 529 530static __inline__ void 531outb(unsigned PORT_SIZE port, unsigned char val) 532{ 533 *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) + IOPortBase) = 534 val; 535} 536 537static __inline__ void 538outw(unsigned PORT_SIZE port, unsigned short val) 539{ 540 *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) + IOPortBase) = 541 val; 542} 543 544static __inline__ void 545outl(unsigned PORT_SIZE port, unsigned int val) 546{ 547 *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)) + IOPortBase) = 548 val; 549} 550 551static __inline__ unsigned int 552inb(unsigned PORT_SIZE port) 553{ 554 return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) + 555 IOPortBase); 556} 557 558static __inline__ unsigned int 559inw(unsigned PORT_SIZE port) 560{ 561 return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) + 562 IOPortBase); 563} 564 565static __inline__ unsigned int 566inl(unsigned PORT_SIZE port) 567{ 568 return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)) + 569 IOPortBase); 570} 571 572#if defined(__mips__) 573#ifdef __linux__ /* don't mess with other OSs */ 574#if X_BYTE_ORDER == X_BIG_ENDIAN 575static __inline__ unsigned int 576xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) 577{ 578 unsigned long addr = ((unsigned long) base) + offset; 579 unsigned int ret; 580 581 __asm__ __volatile__("lw %0, 0(%1)":"=r"(ret) 582 :"r"(addr)); 583 584 return ret; 585} 586 587static __inline__ void 588xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 589 const unsigned int val) 590{ 591 unsigned long addr = ((unsigned long) base) + offset; 592 593 __asm__ __volatile__("sw %0, 0(%1)": /* No outputs */ 594 :"r"(val), "r"(addr)); 595} 596#endif 597#endif /* !__linux__ */ 598#endif /* __mips__ */ 599 600#elif defined(__powerpc__) 601 602#ifndef MAP_FAILED 603#define MAP_FAILED ((void *)-1) 604#endif 605 606extern _X_EXPORT volatile unsigned char *ioBase; 607 608static __inline__ unsigned char 609xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 610{ 611 register unsigned char val; 612 __asm__ __volatile__("lbzx %0,%1,%2\n\t" "eieio":"=r"(val) 613 :"b"(base), "r"(offset), 614 "m"(*((volatile unsigned char *) base + offset))); 615 return val; 616} 617 618static __inline__ unsigned short 619xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset) 620{ 621 register unsigned short val; 622 __asm__ __volatile__("lhzx %0,%1,%2\n\t" "eieio":"=r"(val) 623 :"b"(base), "r"(offset), 624 "m"(*((volatile unsigned char *) base + offset))); 625 return val; 626} 627 628static __inline__ unsigned short 629xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset) 630{ 631 register unsigned short val; 632 __asm__ __volatile__("lhbrx %0,%1,%2\n\t" "eieio":"=r"(val) 633 :"b"(base), "r"(offset), 634 "m"(*((volatile unsigned char *) base + offset))); 635 return val; 636} 637 638static __inline__ unsigned int 639xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) 640{ 641 register unsigned int val; 642 __asm__ __volatile__("lwzx %0,%1,%2\n\t" "eieio":"=r"(val) 643 :"b"(base), "r"(offset), 644 "m"(*((volatile unsigned char *) base + offset))); 645 return val; 646} 647 648static __inline__ unsigned int 649xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset) 650{ 651 register unsigned int val; 652 __asm__ __volatile__("lwbrx %0,%1,%2\n\t" "eieio":"=r"(val) 653 :"b"(base), "r"(offset), 654 "m"(*((volatile unsigned char *) base + offset))); 655 return val; 656} 657 658static __inline__ void 659xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 660 const unsigned char val) 661{ 662 __asm__ 663 __volatile__("stbx %1,%2,%3\n\t":"=m" 664 (*((volatile unsigned char *) base + offset)) 665 :"r"(val), "b"(base), "r"(offset)); 666 eieio(); 667} 668 669static __inline__ void 670xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset, 671 const unsigned short val) 672{ 673 __asm__ 674 __volatile__("sthbrx %1,%2,%3\n\t":"=m" 675 (*((volatile unsigned char *) base + offset)) 676 :"r"(val), "b"(base), "r"(offset)); 677 eieio(); 678} 679 680static __inline__ void 681xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset, 682 const unsigned short val) 683{ 684 __asm__ 685 __volatile__("sthx %1,%2,%3\n\t":"=m" 686 (*((volatile unsigned char *) base + offset)) 687 :"r"(val), "b"(base), "r"(offset)); 688 eieio(); 689} 690 691static __inline__ void 692xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset, 693 const unsigned int val) 694{ 695 __asm__ 696 __volatile__("stwbrx %1,%2,%3\n\t":"=m" 697 (*((volatile unsigned char *) base + offset)) 698 :"r"(val), "b"(base), "r"(offset)); 699 eieio(); 700} 701 702static __inline__ void 703xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 704 const unsigned int val) 705{ 706 __asm__ 707 __volatile__("stwx %1,%2,%3\n\t":"=m" 708 (*((volatile unsigned char *) base + offset)) 709 :"r"(val), "b"(base), "r"(offset)); 710 eieio(); 711} 712 713static __inline__ void 714outb(unsigned short port, unsigned char value) 715{ 716 if (ioBase == MAP_FAILED) 717 return; 718 xf86WriteMmio8((void *) ioBase, port, value); 719} 720 721static __inline__ void 722outw(unsigned short port, unsigned short value) 723{ 724 if (ioBase == MAP_FAILED) 725 return; 726 xf86WriteMmio16Le((void *) ioBase, port, value); 727} 728 729static __inline__ void 730outl(unsigned short port, unsigned int value) 731{ 732 if (ioBase == MAP_FAILED) 733 return; 734 xf86WriteMmio32Le((void *) ioBase, port, value); 735} 736 737static __inline__ unsigned int 738inb(unsigned short port) 739{ 740 if (ioBase == MAP_FAILED) 741 return 0; 742 return xf86ReadMmio8((void *) ioBase, port); 743} 744 745static __inline__ unsigned int 746inw(unsigned short port) 747{ 748 if (ioBase == MAP_FAILED) 749 return 0; 750 return xf86ReadMmio16Le((void *) ioBase, port); 751} 752 753static __inline__ unsigned int 754inl(unsigned short port) 755{ 756 if (ioBase == MAP_FAILED) 757 return 0; 758 return xf86ReadMmio32Le((void *) ioBase, port); 759} 760 761#elif defined(__nds32__) 762 763/* 764 * Assume all port access are aligned. We need to revise this implementation 765 * if there is unaligned port access. 766 */ 767 768#define PORT_SIZE long 769 770static __inline__ unsigned char 771xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 772{ 773 return *(volatile unsigned char *) ((unsigned char *) base + offset); 774} 775 776static __inline__ void 777xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 778 const unsigned int val) 779{ 780 *(volatile unsigned char *) ((unsigned char *) base + offset) = val; 781 barrier(); 782} 783 784static __inline__ unsigned short 785xf86ReadMmio16Swap(__volatile__ void *base, const unsigned long offset) 786{ 787 unsigned long addr = ((unsigned long) base) + offset; 788 unsigned short ret; 789 790 __asm__ __volatile__("lhi %0, [%1];\n\t" "wsbh %0, %0;\n\t":"=r"(ret) 791 :"r"(addr)); 792 793 return ret; 794} 795 796static __inline__ unsigned short 797xf86ReadMmio16(__volatile__ void *base, const unsigned long offset) 798{ 799 return *(volatile unsigned short *) ((char *) base + offset); 800} 801 802static __inline__ void 803xf86WriteMmio16Swap(__volatile__ void *base, const unsigned long offset, 804 const unsigned int val) 805{ 806 unsigned long addr = ((unsigned long) base) + offset; 807 808 __asm__ __volatile__("wsbh %0, %0;\n\t" "shi %0, [%1];\n\t": /* No outputs */ 809 :"r"(val), "r"(addr)); 810 811 barrier(); 812} 813 814static __inline__ void 815xf86WriteMmio16(__volatile__ void *base, const unsigned long offset, 816 const unsigned int val) 817{ 818 *(volatile unsigned short *) ((unsigned char *) base + offset) = val; 819 barrier(); 820} 821 822static __inline__ unsigned int 823xf86ReadMmio32Swap(__volatile__ void *base, const unsigned long offset) 824{ 825 unsigned long addr = ((unsigned long) base) + offset; 826 unsigned int ret; 827 828 __asm__ __volatile__("lwi %0, [%1];\n\t" 829 "wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t":"=r"(ret) 830 :"r"(addr)); 831 832 return ret; 833} 834 835static __inline__ unsigned int 836xf86ReadMmio32(__volatile__ void *base, const unsigned long offset) 837{ 838 return *(volatile unsigned int *) ((unsigned char *) base + offset); 839} 840 841static __inline__ void 842xf86WriteMmio32Swap(__volatile__ void *base, const unsigned long offset, 843 const unsigned int val) 844{ 845 unsigned long addr = ((unsigned long) base) + offset; 846 847 __asm__ __volatile__("wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t" "swi %0, [%1];\n\t": /* No outputs */ 848 :"r"(val), "r"(addr)); 849 850 barrier(); 851} 852 853static __inline__ void 854xf86WriteMmio32(__volatile__ void *base, const unsigned long offset, 855 const unsigned int val) 856{ 857 *(volatile unsigned int *) ((unsigned char *) base + offset) = val; 858 barrier(); 859} 860 861#if defined(NDS32_MMIO_SWAP) 862static __inline__ void 863outb(unsigned PORT_SIZE port, unsigned char val) 864{ 865 xf86WriteMmio8(IOPortBase, port, val); 866} 867 868static __inline__ void 869outw(unsigned PORT_SIZE port, unsigned short val) 870{ 871 xf86WriteMmio16Swap(IOPortBase, port, val); 872} 873 874static __inline__ void 875outl(unsigned PORT_SIZE port, unsigned int val) 876{ 877 xf86WriteMmio32Swap(IOPortBase, port, val); 878} 879 880static __inline__ unsigned int 881inb(unsigned PORT_SIZE port) 882{ 883 return xf86ReadMmio8(IOPortBase, port); 884} 885 886static __inline__ unsigned int 887inw(unsigned PORT_SIZE port) 888{ 889 return xf86ReadMmio16Swap(IOPortBase, port); 890} 891 892static __inline__ unsigned int 893inl(unsigned PORT_SIZE port) 894{ 895 return xf86ReadMmio32Swap(IOPortBase, port); 896} 897 898#else /* !NDS32_MMIO_SWAP */ 899static __inline__ void 900outb(unsigned PORT_SIZE port, unsigned char val) 901{ 902 *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))) = val; 903 barrier(); 904} 905 906static __inline__ void 907outw(unsigned PORT_SIZE port, unsigned short val) 908{ 909 *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))) = val; 910 barrier(); 911} 912 913static __inline__ void 914outl(unsigned PORT_SIZE port, unsigned int val) 915{ 916 *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))) = val; 917 barrier(); 918} 919 920static __inline__ unsigned int 921inb(unsigned PORT_SIZE port) 922{ 923 return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))); 924} 925 926static __inline__ unsigned int 927inw(unsigned PORT_SIZE port) 928{ 929 return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))); 930} 931 932static __inline__ unsigned int 933inl(unsigned PORT_SIZE port) 934{ 935 return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))); 936} 937 938#endif /* NDS32_MMIO_SWAP */ 939 940#endif /* arch madness */ 941 942#else /* !GNUC */ 943#if defined(__STDC__) && (__STDC__ == 1) 944#ifndef asm 945#define asm __asm 946#endif 947#endif 948#if !defined(__SUNPRO_C) 949#include <sys/inline.h> 950#endif 951#endif /* __GNUC__ */ 952 953#if !defined(MMIO_IS_BE) && \ 954 (defined(SPARC_MMIO_IS_BE) || defined(PPC_MMIO_IS_BE)) 955#define MMIO_IS_BE 956#endif 957 958#ifdef __alpha__ 959static inline int 960xf86ReadMmio8(void *Base, unsigned long Offset) 961{ 962 mem_barrier(); 963 return *(CARD8 *) ((unsigned long) Base + (Offset)); 964} 965 966static inline int 967xf86ReadMmio16(void *Base, unsigned long Offset) 968{ 969 mem_barrier(); 970 return *(CARD16 *) ((unsigned long) Base + (Offset)); 971} 972 973static inline int 974xf86ReadMmio32(void *Base, unsigned long Offset) 975{ 976 mem_barrier(); 977 return *(CARD32 *) ((unsigned long) Base + (Offset)); 978} 979 980static inline void 981xf86WriteMmio8(int Value, void *Base, unsigned long Offset) 982{ 983 write_mem_barrier(); 984 *(CARD8 *) ((unsigned long) Base + (Offset)) = Value; 985} 986 987static inline void 988xf86WriteMmio16(int Value, void *Base, unsigned long Offset) 989{ 990 write_mem_barrier(); 991 *(CARD16 *) ((unsigned long) Base + (Offset)) = Value; 992} 993 994static inline void 995xf86WriteMmio32(int Value, void *Base, unsigned long Offset) 996{ 997 write_mem_barrier(); 998 *(CARD32 *) ((unsigned long) Base + (Offset)) = Value; 999} 1000 1001extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, 1002 int); 1003extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); 1004 1005/* Some macros to hide the system dependencies for MMIO accesses */ 1006/* Changed to kill noise generated by gcc's -Wcast-align */ 1007#define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1008#define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) 1009#define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) 1010 1011#define MMIO_OUT8(base, offset, val) \ 1012 xf86WriteMmio8((CARD8)(val), base, offset) 1013#define MMIO_OUT16(base, offset, val) \ 1014 xf86WriteMmio16((CARD16)(val), base, offset) 1015#define MMIO_OUT32(base, offset, val) \ 1016 xf86WriteMmio32((CARD32)(val), base, offset) 1017 1018#elif defined(__powerpc__) || defined(__sparc__) 1019 /* 1020 * we provide byteswapping and no byteswapping functions here 1021 * with byteswapping as default, 1022 * drivers that don't need byteswapping should define MMIO_IS_BE 1023 */ 1024#define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1025#define MMIO_OUT8(base, offset, val) \ 1026 xf86WriteMmio8(base, offset, (CARD8)(val)) 1027 1028#if defined(MMIO_IS_BE) /* No byteswapping */ 1029#define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset) 1030#define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset) 1031#define MMIO_OUT16(base, offset, val) \ 1032 xf86WriteMmio16Be(base, offset, (CARD16)(val)) 1033#define MMIO_OUT32(base, offset, val) \ 1034 xf86WriteMmio32Be(base, offset, (CARD32)(val)) 1035#else /* byteswapping is the default */ 1036#define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset) 1037#define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset) 1038#define MMIO_OUT16(base, offset, val) \ 1039 xf86WriteMmio16Le(base, offset, (CARD16)(val)) 1040#define MMIO_OUT32(base, offset, val) \ 1041 xf86WriteMmio32Le(base, offset, (CARD32)(val)) 1042#endif 1043 1044#elif defined(__nds32__) 1045 /* 1046 * we provide byteswapping and no byteswapping functions here 1047 * with no byteswapping as default; when endianness of CPU core 1048 * and I/O devices don't match, byte swapping is necessary 1049 * drivers that need byteswapping should define NDS32_MMIO_SWAP 1050 */ 1051#define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1052#define MMIO_OUT8(base, offset, val) \ 1053 xf86WriteMmio8(base, offset, (CARD8)(val)) 1054 1055#if defined(NDS32_MMIO_SWAP) /* byteswapping */ 1056#define MMIO_IN16(base, offset) xf86ReadMmio16Swap(base, offset) 1057#define MMIO_IN32(base, offset) xf86ReadMmio32Swap(base, offset) 1058#define MMIO_OUT16(base, offset, val) \ 1059 xf86WriteMmio16Swap(base, offset, (CARD16)(val)) 1060#define MMIO_OUT32(base, offset, val) \ 1061 xf86WriteMmio32Swap(base, offset, (CARD32)(val)) 1062#else /* no byteswapping is the default */ 1063#define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) 1064#define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) 1065#define MMIO_OUT16(base, offset, val) \ 1066 xf86WriteMmio16(base, offset, (CARD16)(val)) 1067#define MMIO_OUT32(base, offset, val) \ 1068 xf86WriteMmio32(base, offset, (CARD32)(val)) 1069#endif 1070 1071#else /* !__alpha__ && !__powerpc__ && !__sparc__ */ 1072 1073#define MMIO_IN8(base, offset) \ 1074 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) 1075#define MMIO_IN16(base, offset) \ 1076 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) 1077#define MMIO_IN32(base, offset) \ 1078 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) 1079#define MMIO_OUT8(base, offset, val) \ 1080 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val) 1081#define MMIO_OUT16(base, offset, val) \ 1082 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1083#define MMIO_OUT32(base, offset, val) \ 1084 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1085 1086#endif /* __alpha__ */ 1087 1088/* 1089 * With Intel, the version in os-support/misc/SlowBcopy.s is used. 1090 * This avoids port I/O during the copy (which causes problems with 1091 * some hardware). 1092 */ 1093#ifdef __alpha__ 1094#define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count) 1095#define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count) 1096#else /* __alpha__ */ 1097#define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count) 1098#define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count) 1099#endif /* __alpha__ */ 1100 1101#endif /* _COMPILER_H */ 1102