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