compiler.h revision 4202a189
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# elif defined(__HIGHC__) 83# define __inline__ _Inline 84# else 85# define __inline__ /**/ 86# endif 87# endif /* __inline__ */ 88# ifndef __inline 89# if defined(__GNUC__) 90 /* gcc has __inline */ 91# elif defined(__HIGHC__) 92# define __inline _Inline 93# else 94# define __inline /**/ 95# endif 96# endif /* __inline */ 97 98/* Support gcc's __FUNCTION__ for people using other compilers */ 99#if !defined(__GNUC__) && !defined(__FUNCTION__) 100# define __FUNCTION__ __func__ /* C99 */ 101#endif 102 103# if defined(NO_INLINE) || defined(DO_PROTOTYPES) 104 105# if !defined(__arm__) 106# if !defined(__sparc__) && !defined(__sparc) && !defined(__arm32__) && !defined(__nds32__) \ 107 && !(defined(__alpha__) && defined(linux)) \ 108 && !(defined(__ia64__) && defined(linux)) \ 109 110extern _X_EXPORT void outb(unsigned short, unsigned char); 111extern _X_EXPORT void outw(unsigned short, unsigned short); 112extern _X_EXPORT void outl(unsigned short, unsigned int); 113extern _X_EXPORT unsigned int inb(unsigned short); 114extern _X_EXPORT unsigned int inw(unsigned short); 115extern _X_EXPORT unsigned int inl(unsigned short); 116 117# else /* __sparc__, __arm32__, __alpha__, __nds32__ */ 118 119extern _X_EXPORT void outb(unsigned long, unsigned char); 120extern _X_EXPORT void outw(unsigned long, unsigned short); 121extern _X_EXPORT void outl(unsigned long, unsigned int); 122extern _X_EXPORT unsigned int inb(unsigned long); 123extern _X_EXPORT unsigned int inw(unsigned long); 124extern _X_EXPORT unsigned int inl(unsigned long); 125 126# endif /* __sparc__, __arm32__, __alpha__, __nds32__ */ 127# endif /* __arm__ */ 128 129# if defined(__powerpc__) && !defined(__OpenBSD__) 130extern unsigned long ldq_u(unsigned long *); 131extern unsigned long ldl_u(unsigned int *); 132extern unsigned long ldw_u(unsigned short *); 133extern void stq_u(unsigned long, unsigned long *); 134extern void stl_u(unsigned long, unsigned int *); 135extern void stw_u(unsigned long, unsigned short *); 136extern void mem_barrier(void); 137extern void write_mem_barrier(void); 138extern void stl_brx(unsigned long, volatile unsigned char *, int); 139extern void stw_brx(unsigned short, volatile unsigned char *, int); 140extern unsigned long ldl_brx(volatile unsigned char *, int); 141extern unsigned short ldw_brx(volatile unsigned char *, int); 142# endif /* __powerpc__ && !__OpenBSD */ 143 144# endif /* NO_INLINE || DO_PROTOTYPES */ 145 146# ifndef NO_INLINE 147# ifdef __GNUC__ 148# ifdef __i386__ 149 150# ifdef __SSE__ 151# define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory") 152# else 153# define write_mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") 154# endif 155 156# ifdef __SSE2__ 157# define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory") 158# else 159# define mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") 160# endif 161 162# elif defined __alpha__ 163 164# define mem_barrier() __asm__ __volatile__ ("mb" : : : "memory") 165# define write_mem_barrier() __asm__ __volatile__ ("wmb" : : : "memory") 166 167# elif defined __amd64__ 168 169# define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory") 170# define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory") 171 172# elif defined __ia64__ 173 174# ifndef __INTEL_COMPILER 175# define mem_barrier() __asm__ __volatile__ ("mf" : : : "memory") 176# define write_mem_barrier() __asm__ __volatile__ ("mf" : : : "memory") 177# else 178# include "ia64intrin.h" 179# define mem_barrier() __mf() 180# define write_mem_barrier() __mf() 181# endif 182 183# elif defined __mips__ 184 /* Note: sync instruction requires MIPS II instruction set */ 185# define mem_barrier() \ 186 __asm__ __volatile__( \ 187 ".set push\n\t" \ 188 ".set noreorder\n\t" \ 189 ".set mips2\n\t" \ 190 "sync\n\t" \ 191 ".set pop" \ 192 : /* no output */ \ 193 : /* no input */ \ 194 : "memory") 195# define write_mem_barrier() mem_barrier() 196 197# elif defined __powerpc__ 198 199# if defined(linux) && defined(__powerpc64__) 200# include <linux/version.h> 201# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 202# include <asm/memory.h> 203# endif 204# endif /* defined(linux) && defined(__powerpc64__) */ 205 206# ifndef eieio /* We deal with arch-specific eieio() routines above... */ 207# define eieio() __asm__ __volatile__ ("eieio" ::: "memory") 208# endif /* eieio */ 209# define mem_barrier() eieio() 210# define write_mem_barrier() eieio() 211 212# elif defined __sparc__ 213 214# define barrier() __asm__ __volatile__ (".word 0x8143e00a" : : : "memory") 215# define mem_barrier() /* XXX: nop for now */ 216# define write_mem_barrier() /* XXX: nop for now */ 217# endif 218# endif /* __GNUC__ */ 219# endif /* NO_INLINE */ 220 221# ifndef mem_barrier 222# define mem_barrier() /* NOP */ 223# endif 224 225# ifndef write_mem_barrier 226# define write_mem_barrier() /* NOP */ 227# endif 228 229 230# ifndef NO_INLINE 231# ifdef __GNUC__ 232 233/* Define some packed structures to use with unaligned accesses */ 234 235struct __una_u64 { uint64_t x __attribute__((packed)); }; 236struct __una_u32 { uint32_t x __attribute__((packed)); }; 237struct __una_u16 { uint16_t x __attribute__((packed)); }; 238 239/* Elemental unaligned loads */ 240 241static __inline__ uint64_t ldq_u(uint64_t *p) 242{ 243 const struct __una_u64 *ptr = (const struct __una_u64 *) p; 244 return ptr->x; 245} 246 247static __inline__ uint32_t ldl_u(uint32_t *p) 248{ 249 const struct __una_u32 *ptr = (const struct __una_u32 *) p; 250 return ptr->x; 251} 252 253static __inline__ uint16_t ldw_u(uint16_t *p) 254{ 255 const struct __una_u16 *ptr = (const struct __una_u16 *) p; 256 return ptr->x; 257} 258 259/* Elemental unaligned stores */ 260 261static __inline__ void stq_u(uint64_t val, uint64_t *p) 262{ 263 struct __una_u64 *ptr = (struct __una_u64 *) p; 264 ptr->x = val; 265} 266 267static __inline__ void stl_u(uint32_t val, uint32_t *p) 268{ 269 struct __una_u32 *ptr = (struct __una_u32 *) p; 270 ptr->x = val; 271} 272 273static __inline__ void stw_u(uint16_t val, uint16_t *p) 274{ 275 struct __una_u16 *ptr = (struct __una_u16 *) p; 276 ptr->x = val; 277} 278# else /* !__GNUC__ */ 279 280#include <string.h> /* needed for memmove */ 281 282static __inline__ uint64_t ldq_u(uint64_t *p) 283{ 284 uint64_t ret; 285 memmove(&ret, p, sizeof(*p)); 286 return ret; 287} 288 289static __inline__ uint32_t ldl_u(uint32_t *p) 290{ 291 uint32_t ret; 292 memmove(&ret, p, sizeof(*p)); 293 return ret; 294} 295 296static __inline__ uint16_t ldw_u(uint16_t *p) 297{ 298 uint16_t ret; 299 memmove(&ret, p, sizeof(*p)); 300 return ret; 301} 302 303static __inline__ void stq_u(uint64_t val, uint64_t *p) 304{ 305 uint64_t tmp = val; 306 memmove(p, &tmp, sizeof(*p)); 307} 308 309static __inline__ void stl_u(uint32_t val, uint32_t *p) 310{ 311 uint32_t tmp = val; 312 memmove(p, &tmp, sizeof(*p)); 313} 314 315static __inline__ void stw_u(uint16_t val, uint16_t *p) 316{ 317 uint16_t tmp = val; 318 memmove(p, &tmp, sizeof(*p)); 319} 320 321# endif /* __GNUC__ */ 322# endif /* NO_INLINE */ 323 324# ifndef NO_INLINE 325# ifdef __GNUC__ 326# if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && (defined(__alpha__)) 327 328# ifdef linux 329/* for Linux on Alpha, we use the LIBC _inx/_outx routines */ 330/* note that the appropriate setup via "ioperm" needs to be done */ 331/* *before* any inx/outx is done. */ 332 333extern _X_EXPORT void _outb(unsigned char val, unsigned long port); 334extern _X_EXPORT void _outw(unsigned short val, unsigned long port); 335extern _X_EXPORT void _outl(unsigned int val, unsigned long port); 336extern _X_EXPORT unsigned int _inb(unsigned long port); 337extern _X_EXPORT unsigned int _inw(unsigned long port); 338extern _X_EXPORT unsigned int _inl(unsigned long port); 339 340static __inline__ void 341outb(unsigned long port, unsigned char val) 342{ 343 _outb(val, port); 344} 345 346static __inline__ void 347outw(unsigned long port, unsigned short val) 348{ 349 _outw(val, port); 350} 351 352static __inline__ void 353outl(unsigned long port, unsigned int val) 354{ 355 _outl(val, port); 356} 357 358static __inline__ unsigned int 359inb(unsigned long port) 360{ 361 return _inb(port); 362} 363 364static __inline__ unsigned int 365inw(unsigned long port) 366{ 367 return _inw(port); 368} 369 370static __inline__ unsigned int 371inl(unsigned long port) 372{ 373 return _inl(port); 374} 375 376# endif /* linux */ 377 378# if (defined(__FreeBSD__) || defined(__OpenBSD__)) \ 379 && !defined(DO_PROTOTYPES) 380 381/* for FreeBSD and OpenBSD on Alpha, we use the libio (resp. libalpha) */ 382/* inx/outx routines */ 383/* note that the appropriate setup via "ioperm" needs to be done */ 384/* *before* any inx/outx is done. */ 385 386extern _X_EXPORT void outb(unsigned int port, unsigned char val); 387extern _X_EXPORT void outw(unsigned int port, unsigned short val); 388extern _X_EXPORT void outl(unsigned int port, unsigned int val); 389extern _X_EXPORT unsigned char inb(unsigned int port); 390extern _X_EXPORT unsigned short inw(unsigned int port); 391extern _X_EXPORT unsigned int inl(unsigned int port); 392 393# endif /* (__FreeBSD__ || __OpenBSD__ ) && !DO_PROTOTYPES */ 394 395 396#if defined(__NetBSD__) 397#include <machine/pio.h> 398#endif /* __NetBSD__ */ 399 400# elif defined(linux) && defined(__ia64__) 401 402# include <inttypes.h> 403 404# include <sys/io.h> 405 406# undef outb 407# undef outw 408# undef outl 409# undef inb 410# undef inw 411# undef inl 412extern _X_EXPORT void outb(unsigned long port, unsigned char val); 413extern _X_EXPORT void outw(unsigned long port, unsigned short val); 414extern _X_EXPORT void outl(unsigned long port, unsigned int val); 415extern _X_EXPORT unsigned int inb(unsigned long port); 416extern _X_EXPORT unsigned int inw(unsigned long port); 417extern _X_EXPORT unsigned int inl(unsigned long port); 418 419# elif (defined(linux) || defined(__FreeBSD__)) && defined(__amd64__) 420 421# include <inttypes.h> 422 423static __inline__ void 424outb(unsigned short port, unsigned char val) 425{ 426 __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port)); 427} 428 429 430static __inline__ void 431outw(unsigned short port, unsigned short val) 432{ 433 __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port)); 434} 435 436static __inline__ void 437outl(unsigned short port, unsigned int val) 438{ 439 __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port)); 440} 441 442static __inline__ unsigned int 443inb(unsigned short port) 444{ 445 unsigned char ret; 446 __asm__ __volatile__("inb %1,%0" : 447 "=a" (ret) : 448 "d" (port)); 449 return ret; 450} 451 452static __inline__ unsigned int 453inw(unsigned short port) 454{ 455 unsigned short ret; 456 __asm__ __volatile__("inw %1,%0" : 457 "=a" (ret) : 458 "d" (port)); 459 return ret; 460} 461 462static __inline__ unsigned int 463inl(unsigned short port) 464{ 465 unsigned int ret; 466 __asm__ __volatile__("inl %1,%0" : 467 "=a" (ret) : 468 "d" (port)); 469 return ret; 470} 471 472# elif (defined(linux) || defined(sun) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)) && defined(__sparc__) 473 474# ifndef ASI_PL 475# define ASI_PL 0x88 476# endif 477 478static __inline__ void 479outb(unsigned long port, unsigned char val) 480{ 481 __asm__ __volatile__("stba %0, [%1] %2" 482 : /* No outputs */ 483 : "r" (val), "r" (port), "i" (ASI_PL)); 484 barrier(); 485} 486 487static __inline__ void 488outw(unsigned long port, unsigned short val) 489{ 490 __asm__ __volatile__("stha %0, [%1] %2" 491 : /* No outputs */ 492 : "r" (val), "r" (port), "i" (ASI_PL)); 493 barrier(); 494} 495 496static __inline__ void 497outl(unsigned long port, unsigned int val) 498{ 499 __asm__ __volatile__("sta %0, [%1] %2" 500 : /* No outputs */ 501 : "r" (val), "r" (port), "i" (ASI_PL)); 502 barrier(); 503} 504 505static __inline__ unsigned int 506inb(unsigned long port) 507{ 508 unsigned int ret; 509 __asm__ __volatile__("lduba [%1] %2, %0" 510 : "=r" (ret) 511 : "r" (port), "i" (ASI_PL)); 512 return ret; 513} 514 515static __inline__ unsigned int 516inw(unsigned long port) 517{ 518 unsigned int ret; 519 __asm__ __volatile__("lduha [%1] %2, %0" 520 : "=r" (ret) 521 : "r" (port), "i" (ASI_PL)); 522 return ret; 523} 524 525static __inline__ unsigned int 526inl(unsigned long port) 527{ 528 unsigned int ret; 529 __asm__ __volatile__("lda [%1] %2, %0" 530 : "=r" (ret) 531 : "r" (port), "i" (ASI_PL)); 532 return ret; 533} 534 535static __inline__ unsigned char 536xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 537{ 538 unsigned long addr = ((unsigned long)base) + offset; 539 unsigned char ret; 540 541 __asm__ __volatile__("lduba [%1] %2, %0" 542 : "=r" (ret) 543 : "r" (addr), "i" (ASI_PL)); 544 return ret; 545} 546 547static __inline__ unsigned short 548xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset) 549{ 550 unsigned long addr = ((unsigned long)base) + offset; 551 unsigned short ret; 552 553 __asm__ __volatile__("lduh [%1], %0" 554 : "=r" (ret) 555 : "r" (addr)); 556 return ret; 557} 558 559static __inline__ unsigned short 560xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset) 561{ 562 unsigned long addr = ((unsigned long)base) + offset; 563 unsigned short ret; 564 565 __asm__ __volatile__("lduha [%1] %2, %0" 566 : "=r" (ret) 567 : "r" (addr), "i" (ASI_PL)); 568 return ret; 569} 570 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__("ld [%1], %0" 578 : "=r" (ret) 579 : "r" (addr)); 580 return ret; 581} 582 583static __inline__ unsigned int 584xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset) 585{ 586 unsigned long addr = ((unsigned long)base) + offset; 587 unsigned int ret; 588 589 __asm__ __volatile__("lda [%1] %2, %0" 590 : "=r" (ret) 591 : "r" (addr), "i" (ASI_PL)); 592 return ret; 593} 594 595static __inline__ void 596xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 597 const unsigned int val) 598{ 599 unsigned long addr = ((unsigned long)base) + offset; 600 601 __asm__ __volatile__("stba %0, [%1] %2" 602 : /* No outputs */ 603 : "r" (val), "r" (addr), "i" (ASI_PL)); 604 barrier(); 605} 606 607static __inline__ void 608xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset, 609 const unsigned int val) 610{ 611 unsigned long addr = ((unsigned long)base) + offset; 612 613 __asm__ __volatile__("sth %0, [%1]" 614 : /* No outputs */ 615 : "r" (val), "r" (addr)); 616 barrier(); 617} 618 619static __inline__ void 620xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset, 621 const unsigned int val) 622{ 623 unsigned long addr = ((unsigned long)base) + offset; 624 625 __asm__ __volatile__("stha %0, [%1] %2" 626 : /* No outputs */ 627 : "r" (val), "r" (addr), "i" (ASI_PL)); 628 barrier(); 629} 630 631static __inline__ void 632xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 633 const unsigned int val) 634{ 635 unsigned long addr = ((unsigned long)base) + offset; 636 637 __asm__ __volatile__("st %0, [%1]" 638 : /* No outputs */ 639 : "r" (val), "r" (addr)); 640 barrier(); 641} 642 643static __inline__ void 644xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset, 645 const unsigned int val) 646{ 647 unsigned long addr = ((unsigned long)base) + offset; 648 649 __asm__ __volatile__("sta %0, [%1] %2" 650 : /* No outputs */ 651 : "r" (val), "r" (addr), "i" (ASI_PL)); 652 barrier(); 653} 654 655static __inline__ void 656xf86WriteMmio8NB(__volatile__ void *base, const unsigned long offset, 657 const unsigned int val) 658{ 659 unsigned long addr = ((unsigned long)base) + offset; 660 661 __asm__ __volatile__("stba %0, [%1] %2" 662 : /* No outputs */ 663 : "r" (val), "r" (addr), "i" (ASI_PL)); 664} 665 666static __inline__ void 667xf86WriteMmio16BeNB(__volatile__ void *base, const unsigned long offset, 668 const unsigned int val) 669{ 670 unsigned long addr = ((unsigned long)base) + offset; 671 672 __asm__ __volatile__("sth %0, [%1]" 673 : /* No outputs */ 674 : "r" (val), "r" (addr)); 675} 676 677static __inline__ void 678xf86WriteMmio16LeNB(__volatile__ void *base, const unsigned long offset, 679 const unsigned int val) 680{ 681 unsigned long addr = ((unsigned long)base) + offset; 682 683 __asm__ __volatile__("stha %0, [%1] %2" 684 : /* No outputs */ 685 : "r" (val), "r" (addr), "i" (ASI_PL)); 686} 687 688static __inline__ void 689xf86WriteMmio32BeNB(__volatile__ void *base, const unsigned long offset, 690 const unsigned int val) 691{ 692 unsigned long addr = ((unsigned long)base) + offset; 693 694 __asm__ __volatile__("st %0, [%1]" 695 : /* No outputs */ 696 : "r" (val), "r" (addr)); 697} 698 699static __inline__ void 700xf86WriteMmio32LeNB(__volatile__ void *base, const unsigned long offset, 701 const unsigned int val) 702{ 703 unsigned long addr = ((unsigned long)base) + offset; 704 705 __asm__ __volatile__("sta %0, [%1] %2" 706 : /* No outputs */ 707 : "r" (val), "r" (addr), "i" (ASI_PL)); 708} 709 710# elif defined(__mips__) || (defined(__arm32__) && !defined(__linux__)) 711# ifdef __arm32__ 712# define PORT_SIZE long 713# else 714# define PORT_SIZE short 715# endif 716 717_X_EXPORT unsigned int IOPortBase; /* Memory mapped I/O port area */ 718 719static __inline__ void 720outb(unsigned PORT_SIZE port, unsigned char val) 721{ 722 *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; 723} 724 725static __inline__ void 726outw(unsigned PORT_SIZE port, unsigned short val) 727{ 728 *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; 729} 730 731static __inline__ void 732outl(unsigned PORT_SIZE port, unsigned int val) 733{ 734 *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; 735} 736 737static __inline__ unsigned int 738inb(unsigned PORT_SIZE port) 739{ 740 return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase); 741} 742 743static __inline__ unsigned int 744inw(unsigned PORT_SIZE port) 745{ 746 return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase); 747} 748 749#if 0 750static __inline__ void stw_u(unsigned long val, unsigned short *p) 751{ 752# if defined(__GNUC__) 753 struct __una_u16 *ptr = (struct __una_u16 *) p; 754 ptr->x = val; 755# else 756 unsigned short tmp = val; 757 memmove(p, &tmp, sizeof(*p)); 758# endif 759} 760 761# define mem_barrier() /* XXX: nop for now */ 762# define write_mem_barrier() /* XXX: nop for now */ 763 764# elif defined(__mips__) || ((defined(__arm32__) || defined(__arm__)) && !defined(__linux__)) 765# if defined(__arm32__) || defined(__arm__) 766# define PORT_SIZE long 767# else 768# define PORT_SIZE short 769# endif 770 771unsigned int IOPortBase; /* Memory mapped I/O port area */ 772 773static __inline__ void 774outb(unsigned PORT_SIZE port, unsigned char val) 775{ 776 *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; 777} 778 779static __inline__ void 780outw(unsigned PORT_SIZE port, unsigned short val) 781{ 782 *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; 783} 784 785static __inline__ void 786outl(unsigned PORT_SIZE port, unsigned int val) 787{ 788 *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; 789} 790 791static __inline__ unsigned int 792inb(unsigned PORT_SIZE port) 793{ 794 return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase); 795} 796 797static __inline__ unsigned int 798inw(unsigned PORT_SIZE port) 799{ 800 return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase); 801} 802#enif 803 804static __inline__ unsigned int 805inl(unsigned PORT_SIZE port) 806{ 807 return *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase); 808} 809 810 811# if defined(__mips__) 812# ifdef linux /* don't mess with other OSs */ 813# if X_BYTE_ORDER == X_BIG_ENDIAN 814static __inline__ unsigned int 815xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) 816{ 817 unsigned long addr = ((unsigned long)base) + offset; 818 unsigned int ret; 819 820 __asm__ __volatile__("lw %0, 0(%1)" 821 : "=r" (ret) 822 : "r" (addr)); 823 return ret; 824} 825 826static __inline__ void 827xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 828 const unsigned int val) 829{ 830 unsigned long addr = ((unsigned long)base) + offset; 831 832 __asm__ __volatile__("sw %0, 0(%1)" 833 : /* No outputs */ 834 : "r" (val), "r" (addr)); 835} 836# endif 837# endif /* !linux */ 838# endif /* __mips__ */ 839 840#if 0 841# if defined(__arm32__) || defined(__arm__) 842# define ldq_u(p) (*((unsigned long *)(p))) 843# define ldl_u(p) (*((unsigned int *)(p))) 844# define ldw_u(p) (*((unsigned short *)(p))) 845# define stq_u(v,p) (*(unsigned long *)(p)) = (v) 846# define stl_u(v,p) (*(unsigned int *)(p)) = (v) 847# define stw_u(v,p) (*(unsigned short *)(p)) = (v) 848# define mem_barrier() /* NOP */ 849# define write_mem_barrier() /* NOP */ 850# endif /* __arm32__ || __arm__ */ 851#endif 852 853# elif (defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)) && defined(__powerpc__) 854 855# ifndef MAP_FAILED 856# define MAP_FAILED ((void *)-1) 857# endif 858 859extern _X_EXPORT volatile unsigned char *ioBase; 860 861static __inline__ unsigned char 862xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 863{ 864 register unsigned char val; 865 __asm__ __volatile__( 866 "lbzx %0,%1,%2\n\t" 867 "eieio" 868 : "=r" (val) 869 : "b" (base), "r" (offset), 870 "m" (*((volatile unsigned char *)base+offset))); 871 return val; 872} 873 874static __inline__ unsigned short 875xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset) 876{ 877 register unsigned short val; 878 __asm__ __volatile__( 879 "lhzx %0,%1,%2\n\t" 880 "eieio" 881 : "=r" (val) 882 : "b" (base), "r" (offset), 883 "m" (*((volatile unsigned char *)base+offset))); 884 return val; 885} 886 887static __inline__ unsigned short 888xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset) 889{ 890 register unsigned short val; 891 __asm__ __volatile__( 892 "lhbrx %0,%1,%2\n\t" 893 "eieio" 894 : "=r" (val) 895 : "b" (base), "r" (offset), 896 "m" (*((volatile unsigned char *)base+offset))); 897 return val; 898} 899 900static __inline__ unsigned int 901xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) 902{ 903 register unsigned int val; 904 __asm__ __volatile__( 905 "lwzx %0,%1,%2\n\t" 906 "eieio" 907 : "=r" (val) 908 : "b" (base), "r" (offset), 909 "m" (*((volatile unsigned char *)base+offset))); 910 return val; 911} 912 913static __inline__ unsigned int 914xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset) 915{ 916 register unsigned int val; 917 __asm__ __volatile__( 918 "lwbrx %0,%1,%2\n\t" 919 "eieio" 920 : "=r" (val) 921 : "b" (base), "r" (offset), 922 "m" (*((volatile unsigned char *)base+offset))); 923 return val; 924} 925 926static __inline__ void 927xf86WriteMmioNB8(__volatile__ void *base, const unsigned long offset, 928 const unsigned char val) 929{ 930 __asm__ __volatile__( 931 "stbx %1,%2,%3\n\t" 932 : "=m" (*((volatile unsigned char *)base+offset)) 933 : "r" (val), "b" (base), "r" (offset)); 934} 935 936static __inline__ void 937xf86WriteMmioNB16Le(__volatile__ void *base, const unsigned long offset, 938 const unsigned short val) 939{ 940 __asm__ __volatile__( 941 "sthbrx %1,%2,%3\n\t" 942 : "=m" (*((volatile unsigned char *)base+offset)) 943 : "r" (val), "b" (base), "r" (offset)); 944} 945 946static __inline__ void 947xf86WriteMmioNB16Be(__volatile__ void *base, const unsigned long offset, 948 const unsigned short val) 949{ 950 __asm__ __volatile__( 951 "sthx %1,%2,%3\n\t" 952 : "=m" (*((volatile unsigned char *)base+offset)) 953 : "r" (val), "b" (base), "r" (offset)); 954} 955 956static __inline__ void 957xf86WriteMmioNB32Le(__volatile__ void *base, const unsigned long offset, 958 const unsigned int val) 959{ 960 __asm__ __volatile__( 961 "stwbrx %1,%2,%3\n\t" 962 : "=m" (*((volatile unsigned char *)base+offset)) 963 : "r" (val), "b" (base), "r" (offset)); 964} 965 966static __inline__ void 967xf86WriteMmioNB32Be(__volatile__ void *base, const unsigned long offset, 968 const unsigned int val) 969{ 970 __asm__ __volatile__( 971 "stwx %1,%2,%3\n\t" 972 : "=m" (*((volatile unsigned char *)base+offset)) 973 : "r" (val), "b" (base), "r" (offset)); 974} 975 976static __inline__ void 977xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 978 const unsigned char val) 979{ 980 xf86WriteMmioNB8(base, offset, val); 981 eieio(); 982} 983 984static __inline__ void 985xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset, 986 const unsigned short val) 987{ 988 xf86WriteMmioNB16Le(base, offset, val); 989 eieio(); 990} 991 992static __inline__ void 993xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset, 994 const unsigned short val) 995{ 996 xf86WriteMmioNB16Be(base, offset, val); 997 eieio(); 998} 999 1000static __inline__ void 1001xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset, 1002 const unsigned int val) 1003{ 1004 xf86WriteMmioNB32Le(base, offset, val); 1005 eieio(); 1006} 1007 1008static __inline__ void 1009xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, 1010 const unsigned int val) 1011{ 1012 xf86WriteMmioNB32Be(base, offset, val); 1013 eieio(); 1014} 1015 1016 1017static __inline__ void 1018outb(unsigned short port, unsigned char value) 1019{ 1020 if(ioBase == MAP_FAILED) return; 1021 xf86WriteMmio8((void *)ioBase, port, value); 1022} 1023 1024static __inline__ void 1025outw(unsigned short port, unsigned short value) 1026{ 1027 if(ioBase == MAP_FAILED) return; 1028 xf86WriteMmio16Le((void *)ioBase, port, value); 1029} 1030 1031static __inline__ void 1032outl(unsigned short port, unsigned int value) 1033{ 1034 if(ioBase == MAP_FAILED) return; 1035 xf86WriteMmio32Le((void *)ioBase, port, value); 1036} 1037 1038static __inline__ unsigned int 1039inb(unsigned short port) 1040{ 1041 if(ioBase == MAP_FAILED) return 0; 1042 return xf86ReadMmio8((void *)ioBase, port); 1043} 1044 1045static __inline__ unsigned int 1046inw(unsigned short port) 1047{ 1048 if(ioBase == MAP_FAILED) return 0; 1049 return xf86ReadMmio16Le((void *)ioBase, port); 1050} 1051 1052static __inline__ unsigned int 1053inl(unsigned short port) 1054{ 1055 if(ioBase == MAP_FAILED) return 0; 1056 return xf86ReadMmio32Le((void *)ioBase, port); 1057} 1058 1059#elif defined(__arm__) && defined(__linux__) 1060 1061/* for Linux on ARM, we use the LIBC inx/outx routines */ 1062/* note that the appropriate setup via "ioperm" needs to be done */ 1063/* *before* any inx/outx is done. */ 1064 1065#include <sys/io.h> 1066 1067static __inline__ void 1068xf_outb(unsigned short port, unsigned char val) 1069{ 1070 outb(val, port); 1071} 1072 1073static __inline__ void 1074xf_outw(unsigned short port, unsigned short val) 1075{ 1076 outw(val, port); 1077} 1078 1079static __inline__ void 1080xf_outl(unsigned short port, unsigned int val) 1081{ 1082 outl(val, port); 1083} 1084 1085#define outb xf_outb 1086#define outw xf_outw 1087#define outl xf_outl 1088 1089# elif defined(__nds32__) 1090 1091/* 1092 * Assume all port access are aligned. We need to revise this implementation 1093 * if there is unaligned port access. For ldq_u, ldl_u, ldw_u, stq_u, stl_u and 1094 * stw_u, they are assumed unaligned. 1095 */ 1096 1097#define barrier() /* no barrier */ 1098 1099#define PORT_SIZE long 1100 1101static __inline__ unsigned char 1102xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) 1103{ 1104 return *(volatile unsigned char *)((unsigned char *)base + offset) ; 1105} 1106 1107static __inline__ void 1108xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, 1109 const unsigned int val) 1110{ 1111 *(volatile unsigned char *)((unsigned char *)base + offset) = val ; 1112 barrier(); 1113} 1114 1115static __inline__ void 1116xf86WriteMmio8NB(__volatile__ void *base, const unsigned long offset, 1117 const unsigned int val) 1118{ 1119 *(volatile unsigned char *)((unsigned char *)base + offset) = val ; 1120} 1121 1122static __inline__ unsigned short 1123xf86ReadMmio16Swap(__volatile__ void *base, const unsigned long offset) 1124{ 1125 unsigned long addr = ((unsigned long)base) + offset; 1126 unsigned short ret; 1127 1128 __asm__ __volatile__( 1129 "lhi %0, [%1];\n\t" 1130 "wsbh %0, %0;\n\t" 1131 : "=r" (ret) 1132 : "r" (addr)); 1133 return ret; 1134} 1135 1136static __inline__ unsigned short 1137xf86ReadMmio16(__volatile__ void *base, const unsigned long offset) 1138{ 1139 return *(volatile unsigned short *)((char *)base + offset) ; 1140} 1141 1142static __inline__ void 1143xf86WriteMmio16Swap(__volatile__ void *base, const unsigned long offset, 1144 const unsigned int val) 1145{ 1146 unsigned long addr = ((unsigned long)base) + offset; 1147 1148 __asm__ __volatile__( 1149 "wsbh %0, %0;\n\t" 1150 "shi %0, [%1];\n\t" 1151 : /* No outputs */ 1152 : "r" (val), "r" (addr)); 1153 barrier(); 1154} 1155 1156static __inline__ void 1157xf86WriteMmio16(__volatile__ void *base, const unsigned long offset, 1158 const unsigned int val) 1159{ 1160 *(volatile unsigned short *)((unsigned char *)base + offset) = val ; 1161 barrier(); 1162} 1163 1164static __inline__ void 1165xf86WriteMmio16SwapNB(__volatile__ void *base, const unsigned long offset, 1166 const unsigned int val) 1167{ 1168 unsigned long addr = ((unsigned long)base) + offset; 1169 1170 __asm__ __volatile__( 1171 "wsbh %0, %0;\n\t" 1172 "shi %0, [%1];\n\t" 1173 : /* No outputs */ 1174 : "r" (val), "r" (addr)); 1175} 1176 1177static __inline__ void 1178xf86WriteMmio16NB(__volatile__ void *base, const unsigned long offset, 1179 const unsigned int val) 1180{ 1181 *(volatile unsigned short *)((unsigned char *)base + offset) = val ; 1182} 1183 1184static __inline__ unsigned int 1185xf86ReadMmio32Swap(__volatile__ void *base, const unsigned long offset) 1186{ 1187 unsigned long addr = ((unsigned long)base) + offset; 1188 unsigned int ret; 1189 1190 __asm__ __volatile__( 1191 "lwi %0, [%1];\n\t" 1192 "wsbh %0, %0;\n\t" 1193 "rotri %0, %0, 16;\n\t" 1194 : "=r" (ret) 1195 : "r" (addr)); 1196 return ret; 1197} 1198 1199static __inline__ unsigned int 1200xf86ReadMmio32(__volatile__ void *base, const unsigned long offset) 1201{ 1202 return *(volatile unsigned int *)((unsigned char *)base + offset) ; 1203} 1204 1205static __inline__ void 1206xf86WriteMmio32Swap(__volatile__ void *base, const unsigned long offset, 1207 const unsigned int val) 1208{ 1209 unsigned long addr = ((unsigned long)base) + offset; 1210 1211 __asm__ __volatile__( 1212 "wsbh %0, %0;\n\t" 1213 "rotri %0, %0, 16;\n\t" 1214 "swi %0, [%1];\n\t" 1215 : /* No outputs */ 1216 : "r" (val), "r" (addr)); 1217 barrier(); 1218} 1219 1220static __inline__ void 1221xf86WriteMmio32(__volatile__ void *base, const unsigned long offset, 1222 const unsigned int val) 1223{ 1224 *(volatile unsigned int *)((unsigned char *)base + offset) = val ; 1225 barrier(); 1226} 1227 1228static __inline__ void 1229xf86WriteMmio32SwapNB(__volatile__ void *base, const unsigned long offset, 1230 const unsigned int val) 1231{ 1232 unsigned long addr = ((unsigned long)base) + offset; 1233 1234 __asm__ __volatile__( 1235 "wsbh %0, %0;\n\t" 1236 "rotri %0, %0, 16;\n\t" 1237 "swi %0, [%1];\n\t" 1238 : /* No outputs */ 1239 : "r" (val), "r" (addr)); 1240} 1241 1242static __inline__ void 1243xf86WriteMmio32NB(__volatile__ void *base, const unsigned long offset, 1244 const unsigned int val) 1245{ 1246 *(volatile unsigned int *)((unsigned char *)base + offset) = val ; 1247} 1248 1249# if defined(NDS32_MMIO_SWAP) 1250static __inline__ void 1251outb(unsigned PORT_SIZE port, unsigned char val) 1252{ 1253 xf86WriteMmio8(IOPortBase, port, val); 1254} 1255 1256static __inline__ void 1257outw(unsigned PORT_SIZE port, unsigned short val) 1258{ 1259 xf86WriteMmio16Swap(IOPortBase, port, val); 1260} 1261 1262static __inline__ void 1263outl(unsigned PORT_SIZE port, unsigned int val) 1264{ 1265 xf86WriteMmio32Swap(IOPortBase, port, val); 1266} 1267 1268static __inline__ unsigned int 1269inb(unsigned PORT_SIZE port) 1270{ 1271 return xf86ReadMmio8(IOPortBase, port); 1272} 1273 1274static __inline__ unsigned int 1275inw(unsigned PORT_SIZE port) 1276{ 1277 return xf86ReadMmio16Swap(IOPortBase, port); 1278} 1279 1280static __inline__ unsigned int 1281inl(unsigned PORT_SIZE port) 1282{ 1283 return xf86ReadMmio32Swap(IOPortBase, port); 1284} 1285 1286static __inline__ unsigned long ldq_u(unsigned long *p) 1287{ 1288 unsigned long addr = (unsigned long)p; 1289 unsigned int ret; 1290 1291 __asm__ __volatile__( 1292 "lmw.bi %0, [%1], %0, 0;\n\t" 1293 "wsbh %0, %0;\n\t" 1294 "rotri %0, %0, 16;\n\t" 1295 : "=r" (ret) 1296 : "r" (addr)); 1297 return ret; 1298} 1299 1300static __inline__ unsigned long ldl_u(unsigned int *p) 1301{ 1302 unsigned long addr = (unsigned long)p; 1303 unsigned int ret; 1304 1305 __asm__ __volatile__( 1306 "lmw.bi %0, [%1], %0, 0;\n\t" 1307 "wsbh %0, %0;\n\t" 1308 "rotri %0, %0, 16;\n\t" 1309 : "=r" (ret) 1310 : "r" (addr)); 1311 return ret; 1312} 1313 1314static __inline__ void stq_u(unsigned long val, unsigned long *p) 1315{ 1316 unsigned long addr = (unsigned long)p; 1317 1318 __asm__ __volatile__( 1319 "wsbh %0, %0;\n\t" 1320 "rotri %0, %0, 16;\n\t" 1321 "smw.bi %0, [%1], %0, 0;\n\t" 1322 : /* No outputs */ 1323 : "r" (val), "r" (addr)); 1324} 1325 1326static __inline__ void stl_u(unsigned long val, unsigned int *p) 1327{ 1328 unsigned long addr = (unsigned long)p; 1329 1330 __asm__ __volatile__( 1331 "wsbh %0, %0;\n\t" 1332 "rotri %0, %0, 16;\n\t" 1333 "smw.bi %0, [%1], %0, 0;\n\t" 1334 : /* No outputs */ 1335 : "r" (val), "r" (addr)); 1336} 1337 1338# else /* !NDS32_MMIO_SWAP */ 1339static __inline__ void 1340outb(unsigned PORT_SIZE port, unsigned char val) 1341{ 1342 *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))) = val; 1343 barrier(); 1344} 1345 1346static __inline__ void 1347outw(unsigned PORT_SIZE port, unsigned short val) 1348{ 1349 *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))) = val; 1350 barrier(); 1351} 1352 1353static __inline__ void 1354outl(unsigned PORT_SIZE port, unsigned int val) 1355{ 1356 *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))) = val; 1357 barrier(); 1358} 1359static __inline__ unsigned int 1360inb(unsigned PORT_SIZE port) 1361{ 1362 return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))); 1363} 1364 1365static __inline__ unsigned int 1366inw(unsigned PORT_SIZE port) 1367{ 1368 return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))); 1369} 1370 1371static __inline__ unsigned int 1372inl(unsigned PORT_SIZE port) 1373{ 1374 return *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))); 1375} 1376 1377static __inline__ unsigned long ldq_u(unsigned long *p) 1378{ 1379 unsigned long addr = (unsigned long)p; 1380 unsigned int ret; 1381 1382 __asm__ __volatile__( 1383 "lmw.bi %0, [%1], %0, 0;\n\t" 1384 : "=r" (ret) 1385 : "r" (addr)); 1386 return ret; 1387} 1388 1389static __inline__ unsigned long ldl_u(unsigned int *p) 1390{ 1391 unsigned long addr = (unsigned long)p; 1392 unsigned int ret; 1393 1394 __asm__ __volatile__( 1395 "lmw.bi %0, [%1], %0, 0;\n\t" 1396 : "=r" (ret) 1397 : "r" (addr)); 1398 return ret; 1399} 1400 1401 1402static __inline__ void stq_u(unsigned long val, unsigned long *p) 1403{ 1404 unsigned long addr = (unsigned long)p; 1405 1406 __asm__ __volatile__( 1407 "smw.bi %0, [%1], %0, 0;\n\t" 1408 : /* No outputs */ 1409 : "r" (val), "r" (addr)); 1410} 1411 1412static __inline__ void stl_u(unsigned long val, unsigned int *p) 1413{ 1414 unsigned long addr = (unsigned long)p; 1415 1416 __asm__ __volatile__( 1417 "smw.bi %0, [%1], %0, 0;\n\t" 1418 : /* No outputs */ 1419 : "r" (val), "r" (addr)); 1420} 1421# endif /* NDS32_MMIO_SWAP */ 1422 1423# if (((X_BYTE_ORDER == X_BIG_ENDIAN) && !defined(NDS32_MMIO_SWAP)) || ((X_BYTE_ORDER != X_BIG_ENDIAN) && defined(NDS32_MMIO_SWAP))) 1424# define ldw_u(p) ((*(unsigned char *)(p)) << 8 | \ 1425 (*((unsigned char *)(p)+1))) 1426# define stw_u(v,p) (*(unsigned char *)(p)) = ((v) >> 8); \ 1427 (*((unsigned char *)(p)+1)) = (v) 1428# else 1429# define ldw_u(p) ((*(unsigned char *)(p)) | \ 1430 (*((unsigned char *)(p)+1)<<8)) 1431# define stw_u(v,p) (*(unsigned char *)(p)) = (v); \ 1432 (*((unsigned char *)(p)+1)) = ((v) >> 8) 1433# endif 1434 1435# define mem_barrier() /* XXX: nop for now */ 1436# define write_mem_barrier() /* XXX: nop for now */ 1437 1438# else /* ix86 */ 1439 1440# if !defined(__SUNPRO_C) 1441# if !defined(FAKEIT) && !defined(__mc68000__) && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__s390__) && !defined(__m32r__) 1442# ifdef GCCUSESGAS 1443 1444/* 1445 * If gcc uses gas rather than the native assembler, the syntax of these 1446 * inlines has to be different. DHD 1447 */ 1448 1449static __inline__ void 1450outb(unsigned short port, unsigned char val) 1451{ 1452 __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port)); 1453} 1454 1455 1456static __inline__ void 1457outw(unsigned short port, unsigned short val) 1458{ 1459 __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port)); 1460} 1461 1462static __inline__ void 1463outl(unsigned short port, unsigned int val) 1464{ 1465 __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port)); 1466} 1467 1468static __inline__ unsigned int 1469inb(unsigned short port) 1470{ 1471 unsigned char ret; 1472 __asm__ __volatile__("inb %1,%0" : 1473 "=a" (ret) : 1474 "d" (port)); 1475 return ret; 1476} 1477 1478static __inline__ unsigned int 1479inw(unsigned short port) 1480{ 1481 unsigned short ret; 1482 __asm__ __volatile__("inw %1,%0" : 1483 "=a" (ret) : 1484 "d" (port)); 1485 return ret; 1486} 1487 1488static __inline__ unsigned int 1489inl(unsigned short port) 1490{ 1491 unsigned int ret; 1492 __asm__ __volatile__("inl %1,%0" : 1493 "=a" (ret) : 1494 "d" (port)); 1495 return ret; 1496} 1497 1498# else /* GCCUSESGAS */ 1499 1500static __inline__ void 1501outb(unsigned short port, unsigned char val) 1502{ 1503 __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port)); 1504} 1505 1506static __inline__ void 1507outw(unsigned short port, unsigned short val) 1508{ 1509 __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port)); 1510} 1511 1512static __inline__ void 1513outl(unsigned short port, unsigned int val) 1514{ 1515 __asm__ __volatile__("out%L0 (%1)" : :"a" (val), "d" (port)); 1516} 1517 1518static __inline__ unsigned int 1519inb(unsigned short port) 1520{ 1521 unsigned char ret; 1522 __asm__ __volatile__("in%B0 (%1)" : 1523 "=a" (ret) : 1524 "d" (port)); 1525 return ret; 1526} 1527 1528static __inline__ unsigned int 1529inw(unsigned short port) 1530{ 1531 unsigned short ret; 1532 __asm__ __volatile__("in%W0 (%1)" : 1533 "=a" (ret) : 1534 "d" (port)); 1535 return ret; 1536} 1537 1538static __inline__ unsigned int 1539inl(unsigned short port) 1540{ 1541 unsigned int ret; 1542 __asm__ __volatile__("in%L0 (%1)" : 1543 "=a" (ret) : 1544 "d" (port)); 1545 return ret; 1546} 1547 1548# endif /* GCCUSESGAS */ 1549 1550# else /* !defined(FAKEIT) && !defined(__mc68000__) && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__m32r__) */ 1551 1552static __inline__ void 1553outb(unsigned short port, unsigned char val) 1554{ 1555} 1556 1557static __inline__ void 1558outw(unsigned short port, unsigned short val) 1559{ 1560} 1561 1562static __inline__ void 1563outl(unsigned short port, unsigned int val) 1564{ 1565} 1566 1567static __inline__ unsigned int 1568inb(unsigned short port) 1569{ 1570 return 0; 1571} 1572 1573static __inline__ unsigned int 1574inw(unsigned short port) 1575{ 1576 return 0; 1577} 1578 1579static __inline__ unsigned int 1580inl(unsigned short port) 1581{ 1582 return 0; 1583} 1584 1585# endif /* FAKEIT */ 1586# endif /* __SUNPRO_C */ 1587 1588# endif /* ix86 */ 1589 1590# else /* !GNUC */ 1591# if defined(__STDC__) && (__STDC__ == 1) 1592# ifndef asm 1593# define asm __asm 1594# endif 1595# endif 1596# ifndef SCO325 1597# if defined(__UNIXWARE__) 1598# /* avoid including <sys/types.h> for <sys/inline.h> on UnixWare */ 1599# define ushort unsigned short 1600# define ushort_t unsigned short 1601# define ulong unsigned long 1602# define ulong_t unsigned long 1603# define uint_t unsigned int 1604# define uchar_t unsigned char 1605# endif /* __UNIXWARE__ */ 1606# if !defined(__SUNPRO_C) 1607# include <sys/inline.h> 1608# endif 1609# else 1610# include "scoasm.h" 1611# endif 1612# if !defined(__HIGHC__) && !defined(__SUNPRO_C) || \ 1613 defined(__USLC__) 1614# pragma asm partial_optimization outl 1615# pragma asm partial_optimization outw 1616# pragma asm partial_optimization outb 1617# pragma asm partial_optimization inl 1618# pragma asm partial_optimization inw 1619# pragma asm partial_optimization inb 1620# endif 1621# endif /* __GNUC__ */ 1622 1623# endif /* NO_INLINE */ 1624 1625# ifdef __alpha__ 1626/* entry points for Mmio memory access routines */ 1627extern _X_EXPORT int (*xf86ReadMmio8)(void *, unsigned long); 1628extern _X_EXPORT int (*xf86ReadMmio16)(void *, unsigned long); 1629# ifndef STANDALONE_MMIO 1630extern _X_EXPORT int (*xf86ReadMmio32)(void *, unsigned long); 1631# else 1632/* Some DRI 3D drivers need MMIO_IN32. */ 1633static __inline__ int 1634xf86ReadMmio32(void *Base, unsigned long Offset) 1635{ 1636 mem_barrier(); 1637 return *(volatile unsigned int*)((unsigned long)Base+(Offset)); 1638} 1639# endif 1640extern _X_EXPORT void (*xf86WriteMmio8)(int, void *, unsigned long); 1641extern _X_EXPORT void (*xf86WriteMmio16)(int, void *, unsigned long); 1642extern _X_EXPORT void (*xf86WriteMmio32)(int, void *, unsigned long); 1643extern _X_EXPORT void (*xf86WriteMmioNB8)(int, void *, unsigned long); 1644extern _X_EXPORT void (*xf86WriteMmioNB16)(int, void *, unsigned long); 1645extern _X_EXPORT void (*xf86WriteMmioNB32)(int, void *, unsigned long); 1646extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int); 1647extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); 1648 1649/* Some macros to hide the system dependencies for MMIO accesses */ 1650/* Changed to kill noise generated by gcc's -Wcast-align */ 1651# define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset) 1652# define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset) 1653# ifndef STANDALONE_MMIO 1654# define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset) 1655# else 1656# define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) 1657# endif 1658 1659# define MMIO_OUT32(base, offset, val) \ 1660 do { \ 1661 write_mem_barrier(); \ 1662 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \ 1663 } while (0) 1664# define MMIO_ONB32(base, offset, val) \ 1665 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1666 1667# define MMIO_OUT8(base, offset, val) \ 1668 (*xf86WriteMmio8)((CARD8)(val), base, offset) 1669# define MMIO_OUT16(base, offset, val) \ 1670 (*xf86WriteMmio16)((CARD16)(val), base, offset) 1671# define MMIO_ONB8(base, offset, val) \ 1672 (*xf86WriteMmioNB8)((CARD8)(val), base, offset) 1673# define MMIO_ONB16(base, offset, val) \ 1674 (*xf86WriteMmioNB16)((CARD16)(val), base, offset) 1675# define MMIO_MOVE32(base, offset, val) \ 1676 MMIO_OUT32(base, offset, val) 1677 1678# elif defined(__powerpc__) 1679 /* 1680 * we provide byteswapping and no byteswapping functions here 1681 * with byteswapping as default, 1682 * drivers that don't need byteswapping should define PPC_MMIO_IS_BE 1683 */ 1684# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1685# define MMIO_OUT8(base, offset, val) \ 1686 xf86WriteMmio8(base, offset, (CARD8)(val)) 1687# define MMIO_ONB8(base, offset, val) \ 1688 xf86WriteMmioNB8(base, offset, (CARD8)(val)) 1689 1690# if defined(PPC_MMIO_IS_BE) /* No byteswapping */ 1691# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset) 1692# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset) 1693# define MMIO_OUT16(base, offset, val) \ 1694 xf86WriteMmio16Be(base, offset, (CARD16)(val)) 1695# define MMIO_OUT32(base, offset, val) \ 1696 xf86WriteMmio32Be(base, offset, (CARD32)(val)) 1697# define MMIO_ONB16(base, offset, val) \ 1698 xf86WriteMmioNB16Be(base, offset, (CARD16)(val)) 1699# define MMIO_ONB32(base, offset, val) \ 1700 xf86WriteMmioNB32Be(base, offset, (CARD32)(val)) 1701# else /* byteswapping is the default */ 1702# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset) 1703# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset) 1704# define MMIO_OUT16(base, offset, val) \ 1705 xf86WriteMmio16Le(base, offset, (CARD16)(val)) 1706# define MMIO_OUT32(base, offset, val) \ 1707 xf86WriteMmio32Le(base, offset, (CARD32)(val)) 1708# define MMIO_ONB16(base, offset, val) \ 1709 xf86WriteMmioNB16Le(base, offset, (CARD16)(val)) 1710# define MMIO_ONB32(base, offset, val) \ 1711 xf86WriteMmioNB32Le(base, offset, (CARD32)(val)) 1712# endif 1713 1714# define MMIO_MOVE32(base, offset, val) \ 1715 xf86WriteMmio32Be(base, offset, (CARD32)(val)) 1716 1717# elif defined(__sparc__) || defined(sparc) || defined(__sparc) 1718 /* 1719 * Like powerpc, we provide byteswapping and no byteswapping functions 1720 * here with byteswapping as default, drivers that don't need byteswapping 1721 * should define SPARC_MMIO_IS_BE (perhaps create a generic macro so that we 1722 * do not need to use PPC_MMIO_IS_BE and the sparc one in all the same places 1723 * of drivers?). 1724 */ 1725# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1726# define MMIO_OUT8(base, offset, val) \ 1727 xf86WriteMmio8(base, offset, (CARD8)(val)) 1728# define MMIO_ONB8(base, offset, val) \ 1729 xf86WriteMmio8NB(base, offset, (CARD8)(val)) 1730 1731# if defined(SPARC_MMIO_IS_BE) /* No byteswapping */ 1732# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset) 1733# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset) 1734# define MMIO_OUT16(base, offset, val) \ 1735 xf86WriteMmio16Be(base, offset, (CARD16)(val)) 1736# define MMIO_OUT32(base, offset, val) \ 1737 xf86WriteMmio32Be(base, offset, (CARD32)(val)) 1738# define MMIO_ONB16(base, offset, val) \ 1739 xf86WriteMmio16BeNB(base, offset, (CARD16)(val)) 1740# define MMIO_ONB32(base, offset, val) \ 1741 xf86WriteMmio32BeNB(base, offset, (CARD32)(val)) 1742# else /* byteswapping is the default */ 1743# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset) 1744# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset) 1745# define MMIO_OUT16(base, offset, val) \ 1746 xf86WriteMmio16Le(base, offset, (CARD16)(val)) 1747# define MMIO_OUT32(base, offset, val) \ 1748 xf86WriteMmio32Le(base, offset, (CARD32)(val)) 1749# define MMIO_ONB16(base, offset, val) \ 1750 xf86WriteMmio16LeNB(base, offset, (CARD16)(val)) 1751# define MMIO_ONB32(base, offset, val) \ 1752 xf86WriteMmio32LeNB(base, offset, (CARD32)(val)) 1753# endif 1754 1755# define MMIO_MOVE32(base, offset, val) \ 1756 xf86WriteMmio32Be(base, offset, (CARD32)(val)) 1757 1758# elif defined(__nds32__) 1759 /* 1760 * we provide byteswapping and no byteswapping functions here 1761 * with no byteswapping as default; when endianness of CPU core 1762 * and I/O devices don't match, byte swapping is necessary 1763 * drivers that need byteswapping should define NDS32_MMIO_SWAP 1764 */ 1765# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) 1766# define MMIO_OUT8(base, offset, val) \ 1767 xf86WriteMmio8(base, offset, (CARD8)(val)) 1768# define MMIO_ONB8(base, offset, val) \ 1769 xf86WriteMmioNB8(base, offset, (CARD8)(val)) 1770 1771# if defined(NDS32_MMIO_SWAP) /* byteswapping */ 1772# define MMIO_IN16(base, offset) xf86ReadMmio16Swap(base, offset) 1773# define MMIO_IN32(base, offset) xf86ReadMmio32Swap(base, offset) 1774# define MMIO_OUT16(base, offset, val) \ 1775 xf86WriteMmio16Swap(base, offset, (CARD16)(val)) 1776# define MMIO_OUT32(base, offset, val) \ 1777 xf86WriteMmio32Swap(base, offset, (CARD32)(val)) 1778# define MMIO_ONB16(base, offset, val) \ 1779 xf86WriteMmioNB16Swap(base, offset, (CARD16)(val)) 1780# define MMIO_ONB32(base, offset, val) \ 1781 xf86WriteMmioNB32Swap(base, offset, (CARD32)(val)) 1782# else /* no byteswapping is the default */ 1783# define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) 1784# define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) 1785# define MMIO_OUT16(base, offset, val) \ 1786 xf86WriteMmio16(base, offset, (CARD16)(val)) 1787# define MMIO_OUT32(base, offset, val) \ 1788 xf86WriteMmio32(base, offset, (CARD32)(val)) 1789# define MMIO_ONB16(base, offset, val) \ 1790 xf86WriteMmioNB16(base, offset, (CARD16)(val)) 1791# define MMIO_ONB32(base, offset, val) \ 1792 xf86WriteMmioNB32(base, offset, (CARD32)(val)) 1793# endif 1794 1795# define MMIO_MOVE32(base, offset, val) \ 1796 xf86WriteMmio32(base, offset, (CARD32)(val)) 1797 1798#ifdef N1213_HC /* for NDS32 N1213 hardcore */ 1799static __inline__ void nds32_flush_icache(char *addr) 1800{ 1801 __asm__ volatile ( 1802 "isync %0;" 1803 "msync;" 1804 "isb;" 1805 "cctl %0,L1I_VA_INVAL;" 1806 "isb;" 1807 : : "r"(addr) : "memory"); 1808} 1809#else 1810static __inline__ void nds32_flush_icache(char *addr) 1811{ 1812 __asm__ volatile ( 1813 "isync %0;" 1814 "isb;" 1815 : : "r"(addr) : "memory"); 1816} 1817#endif 1818 1819# else /* !__alpha__ && !__powerpc__ && !__sparc__ */ 1820 1821# define MMIO_IN8(base, offset) \ 1822 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) 1823# define MMIO_IN16(base, offset) \ 1824 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) 1825# define MMIO_IN32(base, offset) \ 1826 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) 1827# define MMIO_OUT8(base, offset, val) \ 1828 *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val) 1829# define MMIO_OUT16(base, offset, val) \ 1830 *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1831# define MMIO_OUT32(base, offset, val) \ 1832 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val) 1833# define MMIO_ONB8(base, offset, val) MMIO_OUT8(base, offset, val) 1834# define MMIO_ONB16(base, offset, val) MMIO_OUT16(base, offset, val) 1835# define MMIO_ONB32(base, offset, val) MMIO_OUT32(base, offset, val) 1836 1837# define MMIO_MOVE32(base, offset, val) MMIO_OUT32(base, offset, val) 1838 1839# endif /* __alpha__ */ 1840 1841/* 1842 * With Intel, the version in os-support/misc/SlowBcopy.s is used. 1843 * This avoids port I/O during the copy (which causes problems with 1844 * some hardware). 1845 */ 1846# ifdef __alpha__ 1847# define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count) 1848# define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count) 1849# else /* __alpha__ */ 1850# define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count) 1851# define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count) 1852# endif /* __alpha__ */ 1853 1854#endif /* _COMPILER_H */ 1855