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