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