compiler.h revision 0623337f
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 528_X_EXPORT unsigned int 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(__arm__) && defined(__linux__) 762 763/* for Linux on ARM, we use the LIBC inx/outx routines */ 764/* note that the appropriate setup via "ioperm" needs to be done */ 765/* *before* any inx/outx is done. */ 766 767#include <sys/io.h> 768 769static __inline__ void 770xf_outb(unsigned short port, unsigned char val) 771{ 772 outb(val, port); 773} 774 775static __inline__ void 776xf_outw(unsigned short port, unsigned short val) 777{ 778 outw(val, port); 779} 780 781static __inline__ void 782xf_outl(unsigned short port, unsigned int val) 783{ 784 outl(val, port); 785} 786 787#define outb xf_outb 788#define outw xf_outw 789#define outl xf_outl 790 791#elif defined(__nds32__) 792 793/* 794 * Assume all port access are aligned. We need to revise this implementation 795 * if there is unaligned port access. 796 */ 797 798#define PORT_SIZE long 799 800static __inline__ unsigned char 801xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 802{ 803 return *(volatile unsigned char *) ((unsigned char *) base + offset); 804} 805 806static __inline__ void 807xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 808 const unsigned int val) 809{ 810 *(volatile unsigned char *) ((unsigned char *) base + offset) = val; 811 barrier(); 812} 813 814static __inline__ unsigned short 815xf86ReadMmio16Swap(__volatile__ void *base, const unsigned long offset) 816{ 817 unsigned long addr = ((unsigned long) base) + offset; 818 unsigned short ret; 819 820 __asm__ __volatile__("lhi %0, [%1];\n\t" "wsbh %0, %0;\n\t":"=r"(ret) 821 :"r"(addr)); 822 823 return ret; 824} 825 826static __inline__ unsigned short 827xf86ReadMmio16(__volatile__ void *base, const unsigned long offset) 828{ 829 return *(volatile unsigned short *) ((char *) base + offset); 830} 831 832static __inline__ void 833xf86WriteMmio16Swap(__volatile__ void *base, const unsigned long offset, 834 const unsigned int val) 835{ 836 unsigned long addr = ((unsigned long) base) + offset; 837 838 __asm__ __volatile__("wsbh %0, %0;\n\t" "shi %0, [%1];\n\t": /* No outputs */ 839 :"r"(val), "r"(addr)); 840 841 barrier(); 842} 843 844static __inline__ void 845xf86WriteMmio16(__volatile__ void *base, const unsigned long offset, 846 const unsigned int val) 847{ 848 *(volatile unsigned short *) ((unsigned char *) base + offset) = val; 849 barrier(); 850} 851 852static __inline__ unsigned int 853xf86ReadMmio32Swap(__volatile__ void *base, const unsigned long offset) 854{ 855 unsigned long addr = ((unsigned long) base) + offset; 856 unsigned int ret; 857 858 __asm__ __volatile__("lwi %0, [%1];\n\t" 859 "wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t":"=r"(ret) 860 :"r"(addr)); 861 862 return ret; 863} 864 865static __inline__ unsigned int 866xf86ReadMmio32(__volatile__ void *base, const unsigned long offset) 867{ 868 return *(volatile unsigned int *) ((unsigned char *) base + offset); 869} 870 871static __inline__ void 872xf86WriteMmio32Swap(__volatile__ void *base, const unsigned long offset, 873 const unsigned int val) 874{ 875 unsigned long addr = ((unsigned long) base) + offset; 876 877 __asm__ __volatile__("wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t" "swi %0, [%1];\n\t": /* No outputs */ 878 :"r"(val), "r"(addr)); 879 880 barrier(); 881} 882 883static __inline__ void 884xf86WriteMmio32(__volatile__ void *base, const unsigned long offset, 885 const unsigned int val) 886{ 887 *(volatile unsigned int *) ((unsigned char *) base + offset) = val; 888 barrier(); 889} 890 891#if defined(NDS32_MMIO_SWAP) 892static __inline__ void 893outb(unsigned PORT_SIZE port, unsigned char val) 894{ 895 xf86WriteMmio8(IOPortBase, port, val); 896} 897 898static __inline__ void 899outw(unsigned PORT_SIZE port, unsigned short val) 900{ 901 xf86WriteMmio16Swap(IOPortBase, port, val); 902} 903 904static __inline__ void 905outl(unsigned PORT_SIZE port, unsigned int val) 906{ 907 xf86WriteMmio32Swap(IOPortBase, port, val); 908} 909 910static __inline__ unsigned int 911inb(unsigned PORT_SIZE port) 912{ 913 return xf86ReadMmio8(IOPortBase, port); 914} 915 916static __inline__ unsigned int 917inw(unsigned PORT_SIZE port) 918{ 919 return xf86ReadMmio16Swap(IOPortBase, port); 920} 921 922static __inline__ unsigned int 923inl(unsigned PORT_SIZE port) 924{ 925 return xf86ReadMmio32Swap(IOPortBase, port); 926} 927 928#else /* !NDS32_MMIO_SWAP */ 929static __inline__ void 930outb(unsigned PORT_SIZE port, unsigned char val) 931{ 932 *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))) = val; 933 barrier(); 934} 935 936static __inline__ void 937outw(unsigned PORT_SIZE port, unsigned short val) 938{ 939 *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))) = val; 940 barrier(); 941} 942 943static __inline__ void 944outl(unsigned PORT_SIZE port, unsigned int val) 945{ 946 *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))) = val; 947 barrier(); 948} 949 950static __inline__ unsigned int 951inb(unsigned PORT_SIZE port) 952{ 953 return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))); 954} 955 956static __inline__ unsigned int 957inw(unsigned PORT_SIZE port) 958{ 959 return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))); 960} 961 962static __inline__ unsigned int 963inl(unsigned PORT_SIZE port) 964{ 965 return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))); 966} 967 968#endif /* NDS32_MMIO_SWAP */ 969 970#endif /* arch madness */ 971 972#else /* !GNUC */ 973#if defined(__STDC__) && (__STDC__ == 1) 974#ifndef asm 975#define asm __asm 976#endif 977#endif 978#if !defined(__SUNPRO_C) 979#include <sys/inline.h> 980#endif 981#endif /* __GNUC__ */ 982 983#if !defined(MMIO_IS_BE) && \ 984 (defined(SPARC_MMIO_IS_BE) || defined(PPC_MMIO_IS_BE)) 985#define MMIO_IS_BE 986#endif 987 988#ifdef __alpha__ 989/* entry points for Mmio memory access routines */ 990extern _X_EXPORT int (*xf86ReadMmio8) (void *, unsigned long); 991extern _X_EXPORT int (*xf86ReadMmio16) (void *, unsigned long); 992extern _X_EXPORT int (*xf86ReadMmio32) (void *, unsigned long); 993extern _X_EXPORT void (*xf86WriteMmio8) (int, void *, unsigned long); 994extern _X_EXPORT void (*xf86WriteMmio16) (int, void *, unsigned long); 995extern _X_EXPORT void (*xf86WriteMmio32) (int, void *, unsigned long); 996extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, 997 int); 998extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); 999 1000/* Some macros to hide the system dependencies for MMIO accesses */ 1001/* Changed to kill noise generated by gcc's -Wcast-align */ 1002#define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset) 1003#define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset) 1004#define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset) 1005 1006#define MMIO_OUT32(base, offset, val) \ 1007 do { \ 1008 write_mem_barrier(); \ 1009 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \ 1010 } while (0) 1011 1012#define MMIO_OUT8(base, offset, val) \ 1013 (*xf86WriteMmio8)((CARD8)(val), base, offset) 1014#define MMIO_OUT16(base, offset, val) \ 1015 (*xf86WriteMmio16)((CARD16)(val), base, offset) 1016 1017#elif defined(__powerpc__) || defined(__sparc__) 1018 /* 1019 * we provide byteswapping and no byteswapping functions here 1020 * with byteswapping as default, 1021 * drivers that don't need byteswapping should define MMIO_IS_BE 1022 */ 1023#define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1024#define MMIO_OUT8(base, offset, val) \ 1025 xf86WriteMmio8(base, offset, (CARD8)(val)) 1026 1027#if defined(MMIO_IS_BE) /* No byteswapping */ 1028#define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset) 1029#define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset) 1030#define MMIO_OUT16(base, offset, val) \ 1031 xf86WriteMmio16Be(base, offset, (CARD16)(val)) 1032#define MMIO_OUT32(base, offset, val) \ 1033 xf86WriteMmio32Be(base, offset, (CARD32)(val)) 1034#else /* byteswapping is the default */ 1035#define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset) 1036#define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset) 1037#define MMIO_OUT16(base, offset, val) \ 1038 xf86WriteMmio16Le(base, offset, (CARD16)(val)) 1039#define MMIO_OUT32(base, offset, val) \ 1040 xf86WriteMmio32Le(base, offset, (CARD32)(val)) 1041#endif 1042 1043#elif defined(__nds32__) 1044 /* 1045 * we provide byteswapping and no byteswapping functions here 1046 * with no byteswapping as default; when endianness of CPU core 1047 * and I/O devices don't match, byte swapping is necessary 1048 * drivers that need byteswapping should define NDS32_MMIO_SWAP 1049 */ 1050#define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1051#define MMIO_OUT8(base, offset, val) \ 1052 xf86WriteMmio8(base, offset, (CARD8)(val)) 1053 1054#if defined(NDS32_MMIO_SWAP) /* byteswapping */ 1055#define MMIO_IN16(base, offset) xf86ReadMmio16Swap(base, offset) 1056#define MMIO_IN32(base, offset) xf86ReadMmio32Swap(base, offset) 1057#define MMIO_OUT16(base, offset, val) \ 1058 xf86WriteMmio16Swap(base, offset, (CARD16)(val)) 1059#define MMIO_OUT32(base, offset, val) \ 1060 xf86WriteMmio32Swap(base, offset, (CARD32)(val)) 1061#else /* no byteswapping is the default */ 1062#define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) 1063#define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) 1064#define MMIO_OUT16(base, offset, val) \ 1065 xf86WriteMmio16(base, offset, (CARD16)(val)) 1066#define MMIO_OUT32(base, offset, val) \ 1067 xf86WriteMmio32(base, offset, (CARD32)(val)) 1068#endif 1069 1070#else /* !__alpha__ && !__powerpc__ && !__sparc__ */ 1071 1072#define MMIO_IN8(base, offset) \ 1073 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) 1074#define MMIO_IN16(base, offset) \ 1075 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) 1076#define MMIO_IN32(base, offset) \ 1077 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) 1078#define MMIO_OUT8(base, offset, val) \ 1079 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val) 1080#define MMIO_OUT16(base, offset, val) \ 1081 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1082#define MMIO_OUT32(base, offset, val) \ 1083 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1084 1085#endif /* __alpha__ */ 1086 1087/* 1088 * With Intel, the version in os-support/misc/SlowBcopy.s is used. 1089 * This avoids port I/O during the copy (which causes problems with 1090 * some hardware). 1091 */ 1092#ifdef __alpha__ 1093#define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count) 1094#define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count) 1095#else /* __alpha__ */ 1096#define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count) 1097#define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count) 1098#endif /* __alpha__ */ 1099 1100#endif /* _COMPILER_H */ 1101