Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / common / compiler.h
CommitLineData
a09e091a
JB
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
107extern _X_EXPORT void outb(unsigned short, unsigned char);
108extern _X_EXPORT void outw(unsigned short, unsigned short);
109extern _X_EXPORT void outl(unsigned short, unsigned int);
110extern _X_EXPORT unsigned int inb(unsigned short);
111extern _X_EXPORT unsigned int inw(unsigned short);
112extern _X_EXPORT unsigned int inl(unsigned short);
113
114#else /* __sparc__, __arm32__, __alpha__, __nds32__ */
115extern _X_EXPORT void outb(unsigned long, unsigned char);
116extern _X_EXPORT void outw(unsigned long, unsigned short);
117extern _X_EXPORT void outl(unsigned long, unsigned int);
118extern _X_EXPORT unsigned int inb(unsigned long);
119extern _X_EXPORT unsigned int inw(unsigned long);
120extern _X_EXPORT unsigned int inl(unsigned long);
121
122#ifdef __SUNPRO_C
123extern _X_EXPORT unsigned char xf86ReadMmio8 (void *, unsigned long);
124extern _X_EXPORT unsigned short xf86ReadMmio16Be (void *, unsigned long);
125extern _X_EXPORT unsigned short xf86ReadMmio16Le (void *, unsigned long);
126extern _X_EXPORT unsigned int xf86ReadMmio32Be (void *, unsigned long);
127extern _X_EXPORT unsigned int xf86ReadMmio32Le (void *, unsigned long);
128extern _X_EXPORT void xf86WriteMmio8 (void *, unsigned long, unsigned int);
129extern _X_EXPORT void xf86WriteMmio16Be (void *, unsigned long, unsigned int);
130extern _X_EXPORT void xf86WriteMmio16Le (void *, unsigned long, unsigned int);
131extern _X_EXPORT void xf86WriteMmio32Be (void *, unsigned long, unsigned int);
132extern _X_EXPORT void xf86WriteMmio32Le (void *, unsigned long, unsigned int);
133extern _X_EXPORT void xf86WriteMmio8NB (void *, unsigned long, unsigned int);
134extern _X_EXPORT void xf86WriteMmio16BeNB (void *, unsigned long, unsigned int);
135extern _X_EXPORT void xf86WriteMmio16LeNB (void *, unsigned long, unsigned int);
136extern _X_EXPORT void xf86WriteMmio32BeNB (void *, unsigned long, unsigned int);
137extern _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__)
143extern unsigned long ldq_u(unsigned long *);
144extern unsigned long ldl_u(unsigned int *);
145extern unsigned long ldw_u(unsigned short *);
146extern void stq_u(unsigned long, unsigned long *);
147extern void stl_u(unsigned long, unsigned int *);
148extern void stw_u(unsigned long, unsigned short *);
149extern void mem_barrier(void);
150extern void write_mem_barrier(void);
151extern void stl_brx(unsigned long, volatile unsigned char *, int);
152extern void stw_brx(unsigned short, volatile unsigned char *, int);
153extern unsigned long ldl_brx(volatile unsigned char *, int);
154extern 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
247struct __una_u64 {
248 uint64_t x __attribute__ ((packed));
249};
250struct __una_u32 {
251 uint32_t x __attribute__ ((packed));
252};
253struct __una_u16 {
254 uint16_t x __attribute__ ((packed));
255};
256
257/* Elemental unaligned loads */
258
259static __inline__ uint64_t
260ldq_u(uint64_t * p)
261{
262 const struct __una_u64 *ptr = (const struct __una_u64 *) p;
263
264 return ptr->x;
265}
266
267static __inline__ uint32_t
268ldl_u(uint32_t * p)
269{
270 const struct __una_u32 *ptr = (const struct __una_u32 *) p;
271
272 return ptr->x;
273}
274
275static __inline__ uint16_t
276ldw_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
285static __inline__ void
286stq_u(uint64_t val, uint64_t * p)
287{
288 struct __una_u64 *ptr = (struct __una_u64 *) p;
289
290 ptr->x = val;
291}
292
293static __inline__ void
294stl_u(uint32_t val, uint32_t * p)
295{
296 struct __una_u32 *ptr = (struct __una_u32 *) p;
297
298 ptr->x = val;
299}
300
301static __inline__ void
302stw_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
312static __inline__ uint64_t
313ldq_u(uint64_t * p)
314{
315 uint64_t ret;
316
317 memmove(&ret, p, sizeof(*p));
318 return ret;
319}
320
321static __inline__ uint32_t
322ldl_u(uint32_t * p)
323{
324 uint32_t ret;
325
326 memmove(&ret, p, sizeof(*p));
327 return ret;
328}
329
330static __inline__ uint16_t
331ldw_u(uint16_t * p)
332{
333 uint16_t ret;
334
335 memmove(&ret, p, sizeof(*p));
336 return ret;
337}
338
339static __inline__ void
340stq_u(uint64_t val, uint64_t * p)
341{
342 uint64_t tmp = val;
343
344 memmove(p, &tmp, sizeof(*p));
345}
346
347static __inline__ void
348stl_u(uint32_t val, uint32_t * p)
349{
350 uint32_t tmp = val;
351
352 memmove(p, &tmp, sizeof(*p));
353}
354
355static __inline__ void
356stw_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
375extern _X_EXPORT void _outb(unsigned char val, unsigned long port);
376extern _X_EXPORT void _outw(unsigned short val, unsigned long port);
377extern _X_EXPORT void _outl(unsigned int val, unsigned long port);
378extern _X_EXPORT unsigned int _inb(unsigned long port);
379extern _X_EXPORT unsigned int _inw(unsigned long port);
380extern _X_EXPORT unsigned int _inl(unsigned long port);
381
382static __inline__ void
383outb(unsigned long port, unsigned char val)
384{
385 _outb(val, port);
386}
387
388static __inline__ void
389outw(unsigned long port, unsigned short val)
390{
391 _outw(val, port);
392}
393
394static __inline__ void
395outl(unsigned long port, unsigned int val)
396{
397 _outl(val, port);
398}
399
400static __inline__ unsigned int
401inb(unsigned long port)
402{
403 return _inb(port);
404}
405
406static __inline__ unsigned int
407inw(unsigned long port)
408{
409 return _inw(port);
410}
411
412static __inline__ unsigned int
413inl(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
428extern _X_EXPORT void outb(unsigned int port, unsigned char val);
429extern _X_EXPORT void outw(unsigned int port, unsigned short val);
430extern _X_EXPORT void outl(unsigned int port, unsigned int val);
431extern _X_EXPORT unsigned char inb(unsigned int port);
432extern _X_EXPORT unsigned short inw(unsigned int port);
433extern _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
445static __inline__ void
446outb(unsigned short port, unsigned char val)
447{
448 __asm__ __volatile__("outb %0,%1"::"a"(val), "d"(port));
449}
450
451static __inline__ void
452outw(unsigned short port, unsigned short val)
453{
454 __asm__ __volatile__("outw %0,%1"::"a"(val), "d"(port));
455}
456
457static __inline__ void
458outl(unsigned short port, unsigned int val)
459{
460 __asm__ __volatile__("outl %0,%1"::"a"(val), "d"(port));
461}
462
463static __inline__ unsigned int
464inb(unsigned short port)
465{
466 unsigned char ret;
467 __asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port));
468
469 return ret;
470}
471
472static __inline__ unsigned int
473inw(unsigned short port)
474{
475 unsigned short ret;
476 __asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port));
477
478 return ret;
479}
480
481static __inline__ unsigned int
482inl(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
496static __inline__ void
497outb(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
505static __inline__ void
506outw(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
514static __inline__ void
515outl(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
523static __inline__ unsigned int
524inb(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
533static __inline__ unsigned int
534inw(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
543static __inline__ unsigned int
544inl(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
553static __inline__ unsigned char
554xf86ReadMmio8(__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
565static __inline__ unsigned short
566xf86ReadMmio16Be(__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
577static __inline__ unsigned short
578xf86ReadMmio16Le(__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
589static __inline__ unsigned int
590xf86ReadMmio32Be(__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
601static __inline__ unsigned int
602xf86ReadMmio32Le(__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
613static __inline__ void
614xf86WriteMmio8(__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
625static __inline__ void
626xf86WriteMmio16Be(__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
637static __inline__ void
638xf86WriteMmio16Le(__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
649static __inline__ void
650xf86WriteMmio32Be(__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
661static __inline__ void
662xf86WriteMmio32Le(__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
673static __inline__ void
674xf86WriteMmio8NB(__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
683static __inline__ void
684xf86WriteMmio16BeNB(__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
693static __inline__ void
694xf86WriteMmio16LeNB(__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
703static __inline__ void
704xf86WriteMmio32BeNB(__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
713static __inline__ void
714xf86WriteMmio32LeNB(__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
732static __inline__ void
733outb(unsigned PORT_SIZE port, unsigned char val)
734{
735 *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) + IOPortBase) =
736 val;
737}
738
739static __inline__ void
740outw(unsigned PORT_SIZE port, unsigned short val)
741{
742 *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) + IOPortBase) =
743 val;
744}
745
746static __inline__ void
747outl(unsigned PORT_SIZE port, unsigned int val)
748{
749 *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)) + IOPortBase) =
750 val;
751}
752
753static __inline__ unsigned int
754inb(unsigned PORT_SIZE port)
755{
756 return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) +
757 IOPortBase);
758}
759
760static __inline__ unsigned int
761inw(unsigned PORT_SIZE port)
762{
763 return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) +
764 IOPortBase);
765}
766
767static __inline__ unsigned int
768inl(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
777static __inline__ unsigned int
778xf86ReadMmio32Be(__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
789static __inline__ void
790xf86WriteMmio32Be(__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
808extern _X_EXPORT volatile unsigned char *ioBase;
809
810static __inline__ unsigned char
811xf86ReadMmio8(__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
820static __inline__ unsigned short
821xf86ReadMmio16Be(__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
830static __inline__ unsigned short
831xf86ReadMmio16Le(__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
840static __inline__ unsigned int
841xf86ReadMmio32Be(__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
850static __inline__ unsigned int
851xf86ReadMmio32Le(__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
860static __inline__ void
861xf86WriteMmioNB8(__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
870static __inline__ void
871xf86WriteMmioNB16Le(__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
880static __inline__ void
881xf86WriteMmioNB16Be(__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
890static __inline__ void
891xf86WriteMmioNB32Le(__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
900static __inline__ void
901xf86WriteMmioNB32Be(__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
910static __inline__ void
911xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
912 const unsigned char val)
913{
914 xf86WriteMmioNB8(base, offset, val);
915 eieio();
916}
917
918static __inline__ void
919xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset,
920 const unsigned short val)
921{
922 xf86WriteMmioNB16Le(base, offset, val);
923 eieio();
924}
925
926static __inline__ void
927xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset,
928 const unsigned short val)
929{
930 xf86WriteMmioNB16Be(base, offset, val);
931 eieio();
932}
933
934static __inline__ void
935xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset,
936 const unsigned int val)
937{
938 xf86WriteMmioNB32Le(base, offset, val);
939 eieio();
940}
941
942static __inline__ void
943xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
944 const unsigned int val)
945{
946 xf86WriteMmioNB32Be(base, offset, val);
947 eieio();
948}
949
950static __inline__ void
951outb(unsigned short port, unsigned char value)
952{
953 if (ioBase == MAP_FAILED)
954 return;
955 xf86WriteMmio8((void *) ioBase, port, value);
956}
957
958static __inline__ void
959outw(unsigned short port, unsigned short value)
960{
961 if (ioBase == MAP_FAILED)
962 return;
963 xf86WriteMmio16Le((void *) ioBase, port, value);
964}
965
966static __inline__ void
967outl(unsigned short port, unsigned int value)
968{
969 if (ioBase == MAP_FAILED)
970 return;
971 xf86WriteMmio32Le((void *) ioBase, port, value);
972}
973
974static __inline__ unsigned int
975inb(unsigned short port)
976{
977 if (ioBase == MAP_FAILED)
978 return 0;
979 return xf86ReadMmio8((void *) ioBase, port);
980}
981
982static __inline__ unsigned int
983inw(unsigned short port)
984{
985 if (ioBase == MAP_FAILED)
986 return 0;
987 return xf86ReadMmio16Le((void *) ioBase, port);
988}
989
990static __inline__ unsigned int
991inl(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
1006static __inline__ void
1007xf_outb(unsigned short port, unsigned char val)
1008{
1009 outb(val, port);
1010}
1011
1012static __inline__ void
1013xf_outw(unsigned short port, unsigned short val)
1014{
1015 outw(val, port);
1016}
1017
1018static __inline__ void
1019xf_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
1040static __inline__ unsigned char
1041xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
1042{
1043 return *(volatile unsigned char *) ((unsigned char *) base + offset);
1044}
1045
1046static __inline__ void
1047xf86WriteMmio8(__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
1054static __inline__ void
1055xf86WriteMmio8NB(__volatile__ void *base, const unsigned long offset,
1056 const unsigned int val)
1057{
1058 *(volatile unsigned char *) ((unsigned char *) base + offset) = val;
1059}
1060
1061static __inline__ unsigned short
1062xf86ReadMmio16Swap(__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
1073static __inline__ unsigned short
1074xf86ReadMmio16(__volatile__ void *base, const unsigned long offset)
1075{
1076 return *(volatile unsigned short *) ((char *) base + offset);
1077}
1078
1079static __inline__ void
1080xf86WriteMmio16Swap(__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
1091static __inline__ void
1092xf86WriteMmio16(__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
1099static __inline__ void
1100xf86WriteMmio16SwapNB(__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
1109static __inline__ void
1110xf86WriteMmio16NB(__volatile__ void *base, const unsigned long offset,
1111 const unsigned int val)
1112{
1113 *(volatile unsigned short *) ((unsigned char *) base + offset) = val;
1114}
1115
1116static __inline__ unsigned int
1117xf86ReadMmio32Swap(__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
1129static __inline__ unsigned int
1130xf86ReadMmio32(__volatile__ void *base, const unsigned long offset)
1131{
1132 return *(volatile unsigned int *) ((unsigned char *) base + offset);
1133}
1134
1135static __inline__ void
1136xf86WriteMmio32Swap(__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
1147static __inline__ void
1148xf86WriteMmio32(__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
1155static __inline__ void
1156xf86WriteMmio32SwapNB(__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
1165static __inline__ void
1166xf86WriteMmio32NB(__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)
1173static __inline__ void
1174outb(unsigned PORT_SIZE port, unsigned char val)
1175{
1176 xf86WriteMmio8(IOPortBase, port, val);
1177}
1178
1179static __inline__ void
1180outw(unsigned PORT_SIZE port, unsigned short val)
1181{
1182 xf86WriteMmio16Swap(IOPortBase, port, val);
1183}
1184
1185static __inline__ void
1186outl(unsigned PORT_SIZE port, unsigned int val)
1187{
1188 xf86WriteMmio32Swap(IOPortBase, port, val);
1189}
1190
1191static __inline__ unsigned int
1192inb(unsigned PORT_SIZE port)
1193{
1194 return xf86ReadMmio8(IOPortBase, port);
1195}
1196
1197static __inline__ unsigned int
1198inw(unsigned PORT_SIZE port)
1199{
1200 return xf86ReadMmio16Swap(IOPortBase, port);
1201}
1202
1203static __inline__ unsigned int
1204inl(unsigned PORT_SIZE port)
1205{
1206 return xf86ReadMmio32Swap(IOPortBase, port);
1207}
1208
1209static __inline__ unsigned long
1210ldq_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
1222static __inline__ unsigned long
1223ldl_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
1235static __inline__ void
1236stq_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
1244static __inline__ void
1245stl_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 */
1254static __inline__ void
1255outb(unsigned PORT_SIZE port, unsigned char val)
1256{
1257 *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))) = val;
1258 barrier();
1259}
1260
1261static __inline__ void
1262outw(unsigned PORT_SIZE port, unsigned short val)
1263{
1264 *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))) = val;
1265 barrier();
1266}
1267
1268static __inline__ void
1269outl(unsigned PORT_SIZE port, unsigned int val)
1270{
1271 *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))) = val;
1272 barrier();
1273}
1274
1275static __inline__ unsigned int
1276inb(unsigned PORT_SIZE port)
1277{
1278 return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)));
1279}
1280
1281static __inline__ unsigned int
1282inw(unsigned PORT_SIZE port)
1283{
1284 return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)));
1285}
1286
1287static __inline__ unsigned int
1288inl(unsigned PORT_SIZE port)
1289{
1290 return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)));
1291}
1292
1293static __inline__ unsigned long
1294ldq_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
1305static __inline__ unsigned long
1306ldl_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
1317static __inline__ void
1318stq_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
1326static __inline__ void
1327stl_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
1362static __inline__ void
1363outb(unsigned short port, unsigned char val)
1364{
1365 __asm__ __volatile__("outb %0,%1"::"a"(val), "d"(port));
1366}
1367
1368static __inline__ void
1369outw(unsigned short port, unsigned short val)
1370{
1371 __asm__ __volatile__("outw %0,%1"::"a"(val), "d"(port));
1372}
1373
1374static __inline__ void
1375outl(unsigned short port, unsigned int val)
1376{
1377 __asm__ __volatile__("outl %0,%1"::"a"(val), "d"(port));
1378}
1379
1380static __inline__ unsigned int
1381inb(unsigned short port)
1382{
1383 unsigned char ret;
1384 __asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port));
1385
1386 return ret;
1387}
1388
1389static __inline__ unsigned int
1390inw(unsigned short port)
1391{
1392 unsigned short ret;
1393 __asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port));
1394
1395 return ret;
1396}
1397
1398static __inline__ unsigned int
1399inl(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
1409static __inline__ void
1410outb(unsigned short port, unsigned char val)
1411{
1412 __asm__ __volatile__("out%B0 (%1)"::"a"(val), "d"(port));
1413}
1414
1415static __inline__ void
1416outw(unsigned short port, unsigned short val)
1417{
1418 __asm__ __volatile__("out%W0 (%1)"::"a"(val), "d"(port));
1419}
1420
1421static __inline__ void
1422outl(unsigned short port, unsigned int val)
1423{
1424 __asm__ __volatile__("out%L0 (%1)"::"a"(val), "d"(port));
1425}
1426
1427static __inline__ unsigned int
1428inb(unsigned short port)
1429{
1430 unsigned char ret;
1431 __asm__ __volatile__("in%B0 (%1)":"=a"(ret):"d"(port));
1432
1433 return ret;
1434}
1435
1436static __inline__ unsigned int
1437inw(unsigned short port)
1438{
1439 unsigned short ret;
1440 __asm__ __volatile__("in%W0 (%1)":"=a"(ret):"d"(port));
1441
1442 return ret;
1443}
1444
1445static __inline__ unsigned int
1446inl(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
1458static __inline__ void
1459outb(unsigned short port, unsigned char val)
1460{
1461}
1462
1463static __inline__ void
1464outw(unsigned short port, unsigned short val)
1465{
1466}
1467
1468static __inline__ void
1469outl(unsigned short port, unsigned int val)
1470{
1471}
1472
1473static __inline__ unsigned int
1474inb(unsigned short port)
1475{
1476 return 0;
1477}
1478
1479static __inline__ unsigned int
1480inw(unsigned short port)
1481{
1482 return 0;
1483}
1484
1485static __inline__ unsigned int
1486inl(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 */
1520extern _X_EXPORT int (*xf86ReadMmio8) (void *, unsigned long);
1521extern _X_EXPORT int (*xf86ReadMmio16) (void *, unsigned long);
1522
1523#ifndef STANDALONE_MMIO
1524extern _X_EXPORT int (*xf86ReadMmio32) (void *, unsigned long);
1525#else
1526/* Some DRI 3D drivers need MMIO_IN32. */
1527static __inline__ int
1528xf86ReadMmio32(void *Base, unsigned long Offset)
1529{
1530 mem_barrier();
1531 return *(volatile unsigned int *) ((unsigned long) Base + (Offset));
1532}
1533#endif
1534extern _X_EXPORT void (*xf86WriteMmio8) (int, void *, unsigned long);
1535extern _X_EXPORT void (*xf86WriteMmio16) (int, void *, unsigned long);
1536extern _X_EXPORT void (*xf86WriteMmio32) (int, void *, unsigned long);
1537extern _X_EXPORT void (*xf86WriteMmioNB8) (int, void *, unsigned long);
1538extern _X_EXPORT void (*xf86WriteMmioNB16) (int, void *, unsigned long);
1539extern _X_EXPORT void (*xf86WriteMmioNB32) (int, void *, unsigned long);
1540extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *,
1541 int);
1542extern _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 */
1694static __inline__ void
1695nds32_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
1703static __inline__ void
1704nds32_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 */