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