1 /*
2  * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Thomas Roell not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Thomas Roell makes no representations
11  * about the suitability of this software for any purpose.  It is provided
12  * "as is" without express or implied warranty.
13  *
14  * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  *
22  */
23 /*
24  * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
25  *
26  * Permission is hereby granted, free of charge, to any person obtaining a
27  * copy of this software and associated documentation files (the "Software"),
28  * to deal in the Software without restriction, including without limitation
29  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
30  * and/or sell copies of the Software, and to permit persons to whom the
31  * Software is furnished to do so, subject to the following conditions:
32  *
33  * The above copyright notice and this permission notice shall be included in
34  * all copies or substantial portions of the Software.
35  *
36  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
39  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
40  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
41  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
42  * OTHER DEALINGS IN THE SOFTWARE.
43  *
44  * Except as contained in this notice, the name of the copyright holder(s)
45  * and author(s) shall not be used in advertising or otherwise to promote
46  * the sale, use or other dealings in this Software without prior written
47  * authorization from the copyright holder(s) and author(s).
48  */
49 
50 #ifndef _COMPILER_H
51 
52 #define _COMPILER_H
53 
54 #if defined(__SUNPRO_C)
55 #define DO_PROTOTYPES
56 #endif
57 
58 /* Map Sun compiler platform defines to gcc-style used in the code */
59 #if defined(__amd64) && !defined(__amd64__)
60 #define __amd64__
61 #endif
62 #if defined(__i386) && !defined(__i386__)
63 #define __i386__
64 #endif
65 #if defined(__sparc) && !defined(__sparc__)
66 #define __sparc__
67 #endif
68 #if defined(__sparcv9) && !defined(__sparc64__)
69 #define __sparc64__
70 #endif
71 
72 #ifndef _X_EXPORT
73 #include <X11/Xfuncproto.h>
74 #endif
75 
76 #include <pixman.h>             /* for uint*_t types */
77 
78 /* Allow drivers to use the GCC-supported __inline__ and/or __inline. */
79 #ifndef __inline__
80 #if defined(__GNUC__)
81     /* gcc has __inline__ */
82 #else
83 #define __inline__ /**/
84 #endif
85 #endif                          /* __inline__ */
86 #ifndef __inline
87 #if defined(__GNUC__)
88     /* gcc has __inline */
89 #else
90 #define __inline /**/
91 #endif
92 #endif                          /* __inline */
93 /* Support gcc's __FUNCTION__ for people using other compilers */
94 #if !defined(__GNUC__) && !defined(__FUNCTION__)
95 #define __FUNCTION__ __func__   /* C99 */
96 #endif
97 
98 #if defined(DO_PROTOTYPES)
99 #if !defined(__arm__)
100 #if !defined(__sparc__) && !defined(__arm32__) && !defined(__nds32__) \
101       && !(defined(__alpha__) && defined(__linux__)) \
102       && !(defined(__ia64__) && defined(__linux__)) \
103       && !(defined(__mips64) && defined(__linux__)) \
104 
105 extern _X_EXPORT void outb(unsigned short, unsigned char);
106 extern _X_EXPORT void outw(unsigned short, unsigned short);
107 extern _X_EXPORT void outl(unsigned short, unsigned int);
108 extern _X_EXPORT unsigned int inb(unsigned short);
109 extern _X_EXPORT unsigned int inw(unsigned short);
110 extern _X_EXPORT unsigned int inl(unsigned short);
111 
112 #else                           /* __sparc__,  __arm32__, __alpha__, __nds32__ */
113 extern _X_EXPORT void outb(unsigned long, unsigned char);
114 extern _X_EXPORT void outw(unsigned long, unsigned short);
115 extern _X_EXPORT void outl(unsigned long, unsigned int);
116 extern _X_EXPORT unsigned int inb(unsigned long);
117 extern _X_EXPORT unsigned int inw(unsigned long);
118 extern _X_EXPORT unsigned int inl(unsigned long);
119 
120 #ifdef __SUNPRO_C
121 extern _X_EXPORT unsigned char  xf86ReadMmio8    (void *, unsigned long);
122 extern _X_EXPORT unsigned short xf86ReadMmio16Be (void *, unsigned long);
123 extern _X_EXPORT unsigned short xf86ReadMmio16Le (void *, unsigned long);
124 extern _X_EXPORT unsigned int   xf86ReadMmio32Be (void *, unsigned long);
125 extern _X_EXPORT unsigned int   xf86ReadMmio32Le (void *, unsigned long);
126 extern _X_EXPORT void xf86WriteMmio8    (void *, unsigned long, unsigned int);
127 extern _X_EXPORT void xf86WriteMmio16Be (void *, unsigned long, unsigned int);
128 extern _X_EXPORT void xf86WriteMmio16Le (void *, unsigned long, unsigned int);
129 extern _X_EXPORT void xf86WriteMmio32Be (void *, unsigned long, unsigned int);
130 extern _X_EXPORT void xf86WriteMmio32Le (void *, unsigned long, unsigned int);
131 #endif                          /* _SUNPRO_C */
132 #endif                          /* __sparc__,  __arm32__, __alpha__, __nds32__ */
133 #endif                          /* __arm__ */
134 
135 #endif                          /* NO_INLINE || DO_PROTOTYPES */
136 
137 #ifdef __GNUC__
138 #ifdef __i386__
139 
140 #ifdef __SSE__
141 #define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory")
142 #else
143 #define write_mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory")
144 #endif
145 
146 #ifdef __SSE2__
147 #define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory")
148 #else
149 #define mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory")
150 #endif
151 
152 #elif defined __alpha__
153 
154 #define mem_barrier() __asm__ __volatile__ ("mb" : : : "memory")
155 #define write_mem_barrier() __asm__ __volatile__ ("wmb" : : : "memory")
156 
157 #elif defined __amd64__
158 
159 #define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory")
160 #define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory")
161 
162 #elif defined __ia64__
163 
164 #ifndef __INTEL_COMPILER
165 #define mem_barrier()        __asm__ __volatile__ ("mf" : : : "memory")
166 #define write_mem_barrier()  __asm__ __volatile__ ("mf" : : : "memory")
167 #else
168 #include "ia64intrin.h"
169 #define mem_barrier() __mf()
170 #define write_mem_barrier() __mf()
171 #endif
172 
173 #elif defined __mips__
174      /* Note: sync instruction requires MIPS II instruction set */
175 #define mem_barrier()		\
176 	__asm__ __volatile__(		\
177 		".set   push\n\t"	\
178 		".set   noreorder\n\t"	\
179 		".set   mips2\n\t"	\
180 		"sync\n\t"		\
181 		".set   pop"		\
182 		: /* no output */	\
183 		: /* no input */	\
184 		: "memory")
185 #define write_mem_barrier() mem_barrier()
186 
187 #elif defined __powerpc__
188 
189 #ifndef eieio
190 #define eieio() __asm__ __volatile__ ("eieio" ::: "memory")
191 #endif                          /* eieio */
192 #define mem_barrier()	eieio()
193 #define write_mem_barrier()	eieio()
194 
195 #elif defined __sparc__
196 
197 #define barrier() __asm__ __volatile__ (".word 0x8143e00a" : : : "memory")
198 #define mem_barrier()           /* XXX: nop for now */
199 #define write_mem_barrier()     /* XXX: nop for now */
200 #endif
201 #endif                          /* __GNUC__ */
202 
203 #ifndef barrier
204 #define barrier()
205 #endif
206 
207 #ifndef mem_barrier
208 #define mem_barrier()           /* NOP */
209 #endif
210 
211 #ifndef write_mem_barrier
212 #define write_mem_barrier()     /* NOP */
213 #endif
214 
215 #ifdef __GNUC__
216 #if defined(__alpha__)
217 
218 #ifdef __linux__
219 /* for Linux on Alpha, we use the LIBC _inx/_outx routines */
220 /* note that the appropriate setup via "ioperm" needs to be done */
221 /*  *before* any inx/outx is done. */
222 
223 extern _X_EXPORT void _outb(unsigned char val, unsigned long port);
224 extern _X_EXPORT void _outw(unsigned short val, unsigned long port);
225 extern _X_EXPORT void _outl(unsigned int val, unsigned long port);
226 extern _X_EXPORT unsigned int _inb(unsigned long port);
227 extern _X_EXPORT unsigned int _inw(unsigned long port);
228 extern _X_EXPORT unsigned int _inl(unsigned long port);
229 
230 static __inline__ void
outb(unsigned long port,unsigned char val)231 outb(unsigned long port, unsigned char val)
232 {
233     _outb(val, port);
234 }
235 
236 static __inline__ void
outw(unsigned long port,unsigned short val)237 outw(unsigned long port, unsigned short val)
238 {
239     _outw(val, port);
240 }
241 
242 static __inline__ void
outl(unsigned long port,unsigned int val)243 outl(unsigned long port, unsigned int val)
244 {
245     _outl(val, port);
246 }
247 
248 static __inline__ unsigned int
inb(unsigned long port)249 inb(unsigned long port)
250 {
251     return _inb(port);
252 }
253 
254 static __inline__ unsigned int
inw(unsigned long port)255 inw(unsigned long port)
256 {
257     return _inw(port);
258 }
259 
260 static __inline__ unsigned int
inl(unsigned long port)261 inl(unsigned long port)
262 {
263     return _inl(port);
264 }
265 
266 #endif                          /* __linux__ */
267 
268 #if (defined(__FreeBSD__) || defined(__OpenBSD__)) \
269       && !defined(DO_PROTOTYPES)
270 
271 /* for FreeBSD and OpenBSD on Alpha, we use the libio (resp. libalpha) */
272 /*  inx/outx routines */
273 /* note that the appropriate setup via "ioperm" needs to be done */
274 /*  *before* any inx/outx is done. */
275 
276 extern _X_EXPORT void outb(unsigned int port, unsigned char val);
277 extern _X_EXPORT void outw(unsigned int port, unsigned short val);
278 extern _X_EXPORT void outl(unsigned int port, unsigned int val);
279 extern _X_EXPORT unsigned char inb(unsigned int port);
280 extern _X_EXPORT unsigned short inw(unsigned int port);
281 extern _X_EXPORT unsigned int inl(unsigned int port);
282 
283 #endif                          /* (__FreeBSD__ || __OpenBSD__ ) && !DO_PROTOTYPES */
284 
285 #if defined(__NetBSD__)
286 #include <machine/pio.h>
287 #endif                          /* __NetBSD__ */
288 
289 #elif defined(__amd64__) || defined(__i386__) || defined(__ia64__)
290 
291 #include <inttypes.h>
292 
293 static __inline__ void
outb(unsigned short port,unsigned char val)294 outb(unsigned short port, unsigned char val)
295 {
296     __asm__ __volatile__("outb %0,%1"::"a"(val), "d"(port));
297 }
298 
299 static __inline__ void
outw(unsigned short port,unsigned short val)300 outw(unsigned short port, unsigned short val)
301 {
302     __asm__ __volatile__("outw %0,%1"::"a"(val), "d"(port));
303 }
304 
305 static __inline__ void
outl(unsigned short port,unsigned int val)306 outl(unsigned short port, unsigned int val)
307 {
308     __asm__ __volatile__("outl %0,%1"::"a"(val), "d"(port));
309 }
310 
311 static __inline__ unsigned int
inb(unsigned short port)312 inb(unsigned short port)
313 {
314     unsigned char ret;
315     __asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port));
316 
317     return ret;
318 }
319 
320 static __inline__ unsigned int
inw(unsigned short port)321 inw(unsigned short port)
322 {
323     unsigned short ret;
324     __asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port));
325 
326     return ret;
327 }
328 
329 static __inline__ unsigned int
inl(unsigned short port)330 inl(unsigned short port)
331 {
332     unsigned int ret;
333     __asm__ __volatile__("inl %1,%0":"=a"(ret):"d"(port));
334 
335     return ret;
336 }
337 
338 #elif defined(__sparc__)
339 
340 #ifndef ASI_PL
341 #define ASI_PL 0x88
342 #endif
343 
344 static __inline__ void
outb(unsigned long port,unsigned char val)345 outb(unsigned long port, unsigned char val)
346 {
347     __asm__ __volatile__("stba %0, [%1] %2":    /* No outputs */
348                          :"r"(val), "r"(port), "i"(ASI_PL));
349 
350     barrier();
351 }
352 
353 static __inline__ void
outw(unsigned long port,unsigned short val)354 outw(unsigned long port, unsigned short val)
355 {
356     __asm__ __volatile__("stha %0, [%1] %2":    /* No outputs */
357                          :"r"(val), "r"(port), "i"(ASI_PL));
358 
359     barrier();
360 }
361 
362 static __inline__ void
outl(unsigned long port,unsigned int val)363 outl(unsigned long port, unsigned int val)
364 {
365     __asm__ __volatile__("sta %0, [%1] %2":     /* No outputs */
366                          :"r"(val), "r"(port), "i"(ASI_PL));
367 
368     barrier();
369 }
370 
371 static __inline__ unsigned int
inb(unsigned long port)372 inb(unsigned long port)
373 {
374     unsigned int ret;
375     __asm__ __volatile__("lduba [%1] %2, %0":"=r"(ret)
376                          :"r"(port), "i"(ASI_PL));
377 
378     return ret;
379 }
380 
381 static __inline__ unsigned int
inw(unsigned long port)382 inw(unsigned long port)
383 {
384     unsigned int ret;
385     __asm__ __volatile__("lduha [%1] %2, %0":"=r"(ret)
386                          :"r"(port), "i"(ASI_PL));
387 
388     return ret;
389 }
390 
391 static __inline__ unsigned int
inl(unsigned long port)392 inl(unsigned long port)
393 {
394     unsigned int ret;
395     __asm__ __volatile__("lda [%1] %2, %0":"=r"(ret)
396                          :"r"(port), "i"(ASI_PL));
397 
398     return ret;
399 }
400 
401 static __inline__ unsigned char
xf86ReadMmio8(__volatile__ void * base,const unsigned long offset)402 xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
403 {
404     unsigned long addr = ((unsigned long) base) + offset;
405     unsigned char ret;
406 
407     __asm__ __volatile__("lduba [%1] %2, %0":"=r"(ret)
408                          :"r"(addr), "i"(ASI_PL));
409 
410     return ret;
411 }
412 
413 static __inline__ unsigned short
xf86ReadMmio16Be(__volatile__ void * base,const unsigned long offset)414 xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset)
415 {
416     unsigned long addr = ((unsigned long) base) + offset;
417     unsigned short ret;
418 
419     __asm__ __volatile__("lduh [%1], %0":"=r"(ret)
420                          :"r"(addr));
421 
422     return ret;
423 }
424 
425 static __inline__ unsigned short
xf86ReadMmio16Le(__volatile__ void * base,const unsigned long offset)426 xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset)
427 {
428     unsigned long addr = ((unsigned long) base) + offset;
429     unsigned short ret;
430 
431     __asm__ __volatile__("lduha [%1] %2, %0":"=r"(ret)
432                          :"r"(addr), "i"(ASI_PL));
433 
434     return ret;
435 }
436 
437 static __inline__ unsigned int
xf86ReadMmio32Be(__volatile__ void * base,const unsigned long offset)438 xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
439 {
440     unsigned long addr = ((unsigned long) base) + offset;
441     unsigned int ret;
442 
443     __asm__ __volatile__("ld [%1], %0":"=r"(ret)
444                          :"r"(addr));
445 
446     return ret;
447 }
448 
449 static __inline__ unsigned int
xf86ReadMmio32Le(__volatile__ void * base,const unsigned long offset)450 xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset)
451 {
452     unsigned long addr = ((unsigned long) base) + offset;
453     unsigned int ret;
454 
455     __asm__ __volatile__("lda [%1] %2, %0":"=r"(ret)
456                          :"r"(addr), "i"(ASI_PL));
457 
458     return ret;
459 }
460 
461 static __inline__ void
xf86WriteMmio8(__volatile__ void * base,const unsigned long offset,const unsigned int val)462 xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
463                const unsigned int val)
464 {
465     unsigned long addr = ((unsigned long) base) + offset;
466 
467     __asm__ __volatile__("stba %0, [%1] %2":    /* No outputs */
468                          :"r"(val), "r"(addr), "i"(ASI_PL));
469 
470     barrier();
471 }
472 
473 static __inline__ void
xf86WriteMmio16Be(__volatile__ void * base,const unsigned long offset,const unsigned int val)474 xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset,
475                   const unsigned int val)
476 {
477     unsigned long addr = ((unsigned long) base) + offset;
478 
479     __asm__ __volatile__("sth %0, [%1]":        /* No outputs */
480                          :"r"(val), "r"(addr));
481 
482     barrier();
483 }
484 
485 static __inline__ void
xf86WriteMmio16Le(__volatile__ void * base,const unsigned long offset,const unsigned int val)486 xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset,
487                   const unsigned int val)
488 {
489     unsigned long addr = ((unsigned long) base) + offset;
490 
491     __asm__ __volatile__("stha %0, [%1] %2":    /* No outputs */
492                          :"r"(val), "r"(addr), "i"(ASI_PL));
493 
494     barrier();
495 }
496 
497 static __inline__ void
xf86WriteMmio32Be(__volatile__ void * base,const unsigned long offset,const unsigned int val)498 xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
499                   const unsigned int val)
500 {
501     unsigned long addr = ((unsigned long) base) + offset;
502 
503     __asm__ __volatile__("st %0, [%1]": /* No outputs */
504                          :"r"(val), "r"(addr));
505 
506     barrier();
507 }
508 
509 static __inline__ void
xf86WriteMmio32Le(__volatile__ void * base,const unsigned long offset,const unsigned int val)510 xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset,
511                   const unsigned int val)
512 {
513     unsigned long addr = ((unsigned long) base) + offset;
514 
515     __asm__ __volatile__("sta %0, [%1] %2":     /* No outputs */
516                          :"r"(val), "r"(addr), "i"(ASI_PL));
517 
518     barrier();
519 }
520 
521 #elif defined(__mips__) || (defined(__arm32__) && !defined(__linux__))
522 #if defined(__arm32__) || defined(__mips64)
523 #define PORT_SIZE long
524 #else
525 #define PORT_SIZE short
526 #endif
527 
528 _X_EXPORT unsigned int IOPortBase;      /* Memory mapped I/O port area */
529 
530 static __inline__ void
outb(unsigned PORT_SIZE port,unsigned char val)531 outb(unsigned PORT_SIZE port, unsigned char val)
532 {
533     *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) + IOPortBase) =
534         val;
535 }
536 
537 static __inline__ void
outw(unsigned PORT_SIZE port,unsigned short val)538 outw(unsigned PORT_SIZE port, unsigned short val)
539 {
540     *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) + IOPortBase) =
541         val;
542 }
543 
544 static __inline__ void
outl(unsigned PORT_SIZE port,unsigned int val)545 outl(unsigned PORT_SIZE port, unsigned int val)
546 {
547     *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)) + IOPortBase) =
548         val;
549 }
550 
551 static __inline__ unsigned int
inb(unsigned PORT_SIZE port)552 inb(unsigned PORT_SIZE port)
553 {
554     return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)) +
555                                         IOPortBase);
556 }
557 
558 static __inline__ unsigned int
inw(unsigned PORT_SIZE port)559 inw(unsigned PORT_SIZE port)
560 {
561     return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)) +
562                                          IOPortBase);
563 }
564 
565 static __inline__ unsigned int
inl(unsigned PORT_SIZE port)566 inl(unsigned PORT_SIZE port)
567 {
568     return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)) +
569                                        IOPortBase);
570 }
571 
572 #if defined(__mips__)
573 #ifdef __linux__                    /* don't mess with other OSs */
574 #if X_BYTE_ORDER == X_BIG_ENDIAN
575 static __inline__ unsigned int
xf86ReadMmio32Be(__volatile__ void * base,const unsigned long offset)576 xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
577 {
578     unsigned long addr = ((unsigned long) base) + offset;
579     unsigned int ret;
580 
581     __asm__ __volatile__("lw %0, 0(%1)":"=r"(ret)
582                          :"r"(addr));
583 
584     return ret;
585 }
586 
587 static __inline__ void
xf86WriteMmio32Be(__volatile__ void * base,const unsigned long offset,const unsigned int val)588 xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
589                   const unsigned int val)
590 {
591     unsigned long addr = ((unsigned long) base) + offset;
592 
593     __asm__ __volatile__("sw %0, 0(%1)":        /* No outputs */
594                          :"r"(val), "r"(addr));
595 }
596 #endif
597 #endif                          /* !__linux__ */
598 #endif                          /* __mips__ */
599 
600 #elif defined(__powerpc__)
601 
602 #ifndef MAP_FAILED
603 #define MAP_FAILED ((void *)-1)
604 #endif
605 
606 extern _X_EXPORT volatile unsigned char *ioBase;
607 
608 static __inline__ unsigned char
xf86ReadMmio8(__volatile__ void * base,const unsigned long offset)609 xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
610 {
611     register unsigned char val;
612     __asm__ __volatile__("lbzx %0,%1,%2\n\t" "eieio":"=r"(val)
613                          :"b"(base), "r"(offset),
614                          "m"(*((volatile unsigned char *) base + offset)));
615     return val;
616 }
617 
618 static __inline__ unsigned short
xf86ReadMmio16Be(__volatile__ void * base,const unsigned long offset)619 xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset)
620 {
621     register unsigned short val;
622     __asm__ __volatile__("lhzx %0,%1,%2\n\t" "eieio":"=r"(val)
623                          :"b"(base), "r"(offset),
624                          "m"(*((volatile unsigned char *) base + offset)));
625     return val;
626 }
627 
628 static __inline__ unsigned short
xf86ReadMmio16Le(__volatile__ void * base,const unsigned long offset)629 xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset)
630 {
631     register unsigned short val;
632     __asm__ __volatile__("lhbrx %0,%1,%2\n\t" "eieio":"=r"(val)
633                          :"b"(base), "r"(offset),
634                          "m"(*((volatile unsigned char *) base + offset)));
635     return val;
636 }
637 
638 static __inline__ unsigned int
xf86ReadMmio32Be(__volatile__ void * base,const unsigned long offset)639 xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
640 {
641     register unsigned int val;
642     __asm__ __volatile__("lwzx %0,%1,%2\n\t" "eieio":"=r"(val)
643                          :"b"(base), "r"(offset),
644                          "m"(*((volatile unsigned char *) base + offset)));
645     return val;
646 }
647 
648 static __inline__ unsigned int
xf86ReadMmio32Le(__volatile__ void * base,const unsigned long offset)649 xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset)
650 {
651     register unsigned int val;
652     __asm__ __volatile__("lwbrx %0,%1,%2\n\t" "eieio":"=r"(val)
653                          :"b"(base), "r"(offset),
654                          "m"(*((volatile unsigned char *) base + offset)));
655     return val;
656 }
657 
658 static __inline__ void
xf86WriteMmio8(__volatile__ void * base,const unsigned long offset,const unsigned char val)659 xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
660                const unsigned char val)
661 {
662     __asm__
663         __volatile__("stbx %1,%2,%3\n\t":"=m"
664                      (*((volatile unsigned char *) base + offset))
665                      :"r"(val), "b"(base), "r"(offset));
666     eieio();
667 }
668 
669 static __inline__ void
xf86WriteMmio16Le(__volatile__ void * base,const unsigned long offset,const unsigned short val)670 xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset,
671                   const unsigned short val)
672 {
673     __asm__
674         __volatile__("sthbrx %1,%2,%3\n\t":"=m"
675                      (*((volatile unsigned char *) base + offset))
676                      :"r"(val), "b"(base), "r"(offset));
677     eieio();
678 }
679 
680 static __inline__ void
xf86WriteMmio16Be(__volatile__ void * base,const unsigned long offset,const unsigned short val)681 xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset,
682                   const unsigned short val)
683 {
684     __asm__
685         __volatile__("sthx %1,%2,%3\n\t":"=m"
686                      (*((volatile unsigned char *) base + offset))
687                      :"r"(val), "b"(base), "r"(offset));
688     eieio();
689 }
690 
691 static __inline__ void
xf86WriteMmio32Le(__volatile__ void * base,const unsigned long offset,const unsigned int val)692 xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset,
693                   const unsigned int val)
694 {
695     __asm__
696         __volatile__("stwbrx %1,%2,%3\n\t":"=m"
697                      (*((volatile unsigned char *) base + offset))
698                      :"r"(val), "b"(base), "r"(offset));
699     eieio();
700 }
701 
702 static __inline__ void
xf86WriteMmio32Be(__volatile__ void * base,const unsigned long offset,const unsigned int val)703 xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
704                   const unsigned int val)
705 {
706     __asm__
707         __volatile__("stwx %1,%2,%3\n\t":"=m"
708                      (*((volatile unsigned char *) base + offset))
709                      :"r"(val), "b"(base), "r"(offset));
710     eieio();
711 }
712 
713 static __inline__ void
outb(unsigned short port,unsigned char value)714 outb(unsigned short port, unsigned char value)
715 {
716     if (ioBase == MAP_FAILED)
717         return;
718     xf86WriteMmio8((void *) ioBase, port, value);
719 }
720 
721 static __inline__ void
outw(unsigned short port,unsigned short value)722 outw(unsigned short port, unsigned short value)
723 {
724     if (ioBase == MAP_FAILED)
725         return;
726     xf86WriteMmio16Le((void *) ioBase, port, value);
727 }
728 
729 static __inline__ void
outl(unsigned short port,unsigned int value)730 outl(unsigned short port, unsigned int value)
731 {
732     if (ioBase == MAP_FAILED)
733         return;
734     xf86WriteMmio32Le((void *) ioBase, port, value);
735 }
736 
737 static __inline__ unsigned int
inb(unsigned short port)738 inb(unsigned short port)
739 {
740     if (ioBase == MAP_FAILED)
741         return 0;
742     return xf86ReadMmio8((void *) ioBase, port);
743 }
744 
745 static __inline__ unsigned int
inw(unsigned short port)746 inw(unsigned short port)
747 {
748     if (ioBase == MAP_FAILED)
749         return 0;
750     return xf86ReadMmio16Le((void *) ioBase, port);
751 }
752 
753 static __inline__ unsigned int
inl(unsigned short port)754 inl(unsigned short port)
755 {
756     if (ioBase == MAP_FAILED)
757         return 0;
758     return xf86ReadMmio32Le((void *) ioBase, port);
759 }
760 
761 #elif defined(__nds32__)
762 
763 /*
764  * Assume all port access are aligned.  We need to revise this implementation
765  * if there is unaligned port access.
766  */
767 
768 #define PORT_SIZE long
769 
770 static __inline__ unsigned char
xf86ReadMmio8(__volatile__ void * base,const unsigned long offset)771 xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
772 {
773     return *(volatile unsigned char *) ((unsigned char *) base + offset);
774 }
775 
776 static __inline__ void
xf86WriteMmio8(__volatile__ void * base,const unsigned long offset,const unsigned int val)777 xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
778                const unsigned int val)
779 {
780     *(volatile unsigned char *) ((unsigned char *) base + offset) = val;
781     barrier();
782 }
783 
784 static __inline__ unsigned short
xf86ReadMmio16Swap(__volatile__ void * base,const unsigned long offset)785 xf86ReadMmio16Swap(__volatile__ void *base, const unsigned long offset)
786 {
787     unsigned long addr = ((unsigned long) base) + offset;
788     unsigned short ret;
789 
790     __asm__ __volatile__("lhi %0, [%1];\n\t" "wsbh %0, %0;\n\t":"=r"(ret)
791                          :"r"(addr));
792 
793     return ret;
794 }
795 
796 static __inline__ unsigned short
xf86ReadMmio16(__volatile__ void * base,const unsigned long offset)797 xf86ReadMmio16(__volatile__ void *base, const unsigned long offset)
798 {
799     return *(volatile unsigned short *) ((char *) base + offset);
800 }
801 
802 static __inline__ void
xf86WriteMmio16Swap(__volatile__ void * base,const unsigned long offset,const unsigned int val)803 xf86WriteMmio16Swap(__volatile__ void *base, const unsigned long offset,
804                     const unsigned int val)
805 {
806     unsigned long addr = ((unsigned long) base) + offset;
807 
808     __asm__ __volatile__("wsbh %0, %0;\n\t" "shi %0, [%1];\n\t":        /* No outputs */
809                          :"r"(val), "r"(addr));
810 
811     barrier();
812 }
813 
814 static __inline__ void
xf86WriteMmio16(__volatile__ void * base,const unsigned long offset,const unsigned int val)815 xf86WriteMmio16(__volatile__ void *base, const unsigned long offset,
816                 const unsigned int val)
817 {
818     *(volatile unsigned short *) ((unsigned char *) base + offset) = val;
819     barrier();
820 }
821 
822 static __inline__ unsigned int
xf86ReadMmio32Swap(__volatile__ void * base,const unsigned long offset)823 xf86ReadMmio32Swap(__volatile__ void *base, const unsigned long offset)
824 {
825     unsigned long addr = ((unsigned long) base) + offset;
826     unsigned int ret;
827 
828     __asm__ __volatile__("lwi %0, [%1];\n\t"
829                          "wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t":"=r"(ret)
830                          :"r"(addr));
831 
832     return ret;
833 }
834 
835 static __inline__ unsigned int
xf86ReadMmio32(__volatile__ void * base,const unsigned long offset)836 xf86ReadMmio32(__volatile__ void *base, const unsigned long offset)
837 {
838     return *(volatile unsigned int *) ((unsigned char *) base + offset);
839 }
840 
841 static __inline__ void
xf86WriteMmio32Swap(__volatile__ void * base,const unsigned long offset,const unsigned int val)842 xf86WriteMmio32Swap(__volatile__ void *base, const unsigned long offset,
843                     const unsigned int val)
844 {
845     unsigned long addr = ((unsigned long) base) + offset;
846 
847     __asm__ __volatile__("wsbh %0, %0;\n\t" "rotri %0, %0, 16;\n\t" "swi %0, [%1];\n\t":        /* No outputs */
848                          :"r"(val), "r"(addr));
849 
850     barrier();
851 }
852 
853 static __inline__ void
xf86WriteMmio32(__volatile__ void * base,const unsigned long offset,const unsigned int val)854 xf86WriteMmio32(__volatile__ void *base, const unsigned long offset,
855                 const unsigned int val)
856 {
857     *(volatile unsigned int *) ((unsigned char *) base + offset) = val;
858     barrier();
859 }
860 
861 #if defined(NDS32_MMIO_SWAP)
862 static __inline__ void
outb(unsigned PORT_SIZE port,unsigned char val)863 outb(unsigned PORT_SIZE port, unsigned char val)
864 {
865     xf86WriteMmio8(IOPortBase, port, val);
866 }
867 
868 static __inline__ void
outw(unsigned PORT_SIZE port,unsigned short val)869 outw(unsigned PORT_SIZE port, unsigned short val)
870 {
871     xf86WriteMmio16Swap(IOPortBase, port, val);
872 }
873 
874 static __inline__ void
outl(unsigned PORT_SIZE port,unsigned int val)875 outl(unsigned PORT_SIZE port, unsigned int val)
876 {
877     xf86WriteMmio32Swap(IOPortBase, port, val);
878 }
879 
880 static __inline__ unsigned int
inb(unsigned PORT_SIZE port)881 inb(unsigned PORT_SIZE port)
882 {
883     return xf86ReadMmio8(IOPortBase, port);
884 }
885 
886 static __inline__ unsigned int
inw(unsigned PORT_SIZE port)887 inw(unsigned PORT_SIZE port)
888 {
889     return xf86ReadMmio16Swap(IOPortBase, port);
890 }
891 
892 static __inline__ unsigned int
inl(unsigned PORT_SIZE port)893 inl(unsigned PORT_SIZE port)
894 {
895     return xf86ReadMmio32Swap(IOPortBase, port);
896 }
897 
898 #else                           /* !NDS32_MMIO_SWAP */
899 static __inline__ void
outb(unsigned PORT_SIZE port,unsigned char val)900 outb(unsigned PORT_SIZE port, unsigned char val)
901 {
902     *(volatile unsigned char *) (((unsigned PORT_SIZE) (port))) = val;
903     barrier();
904 }
905 
906 static __inline__ void
outw(unsigned PORT_SIZE port,unsigned short val)907 outw(unsigned PORT_SIZE port, unsigned short val)
908 {
909     *(volatile unsigned short *) (((unsigned PORT_SIZE) (port))) = val;
910     barrier();
911 }
912 
913 static __inline__ void
outl(unsigned PORT_SIZE port,unsigned int val)914 outl(unsigned PORT_SIZE port, unsigned int val)
915 {
916     *(volatile unsigned int *) (((unsigned PORT_SIZE) (port))) = val;
917     barrier();
918 }
919 
920 static __inline__ unsigned int
inb(unsigned PORT_SIZE port)921 inb(unsigned PORT_SIZE port)
922 {
923     return *(volatile unsigned char *) (((unsigned PORT_SIZE) (port)));
924 }
925 
926 static __inline__ unsigned int
inw(unsigned PORT_SIZE port)927 inw(unsigned PORT_SIZE port)
928 {
929     return *(volatile unsigned short *) (((unsigned PORT_SIZE) (port)));
930 }
931 
932 static __inline__ unsigned int
inl(unsigned PORT_SIZE port)933 inl(unsigned PORT_SIZE port)
934 {
935     return *(volatile unsigned int *) (((unsigned PORT_SIZE) (port)));
936 }
937 
938 #endif                          /* NDS32_MMIO_SWAP */
939 
940 #endif                          /* arch madness */
941 
942 #else                           /* !GNUC */
943 #if defined(__STDC__) && (__STDC__ == 1)
944 #ifndef asm
945 #define asm __asm
946 #endif
947 #endif
948 #if !defined(__SUNPRO_C)
949 #include <sys/inline.h>
950 #endif
951 #endif                          /* __GNUC__ */
952 
953 #if !defined(MMIO_IS_BE) && \
954     (defined(SPARC_MMIO_IS_BE) || defined(PPC_MMIO_IS_BE))
955 #define MMIO_IS_BE
956 #endif
957 
958 #ifdef __alpha__
959 static inline int
xf86ReadMmio8(void * Base,unsigned long Offset)960 xf86ReadMmio8(void *Base, unsigned long Offset)
961 {
962     mem_barrier();
963     return *(CARD8 *) ((unsigned long) Base + (Offset));
964 }
965 
966 static inline int
xf86ReadMmio16(void * Base,unsigned long Offset)967 xf86ReadMmio16(void *Base, unsigned long Offset)
968 {
969     mem_barrier();
970     return *(CARD16 *) ((unsigned long) Base + (Offset));
971 }
972 
973 static inline int
xf86ReadMmio32(void * Base,unsigned long Offset)974 xf86ReadMmio32(void *Base, unsigned long Offset)
975 {
976     mem_barrier();
977     return *(CARD32 *) ((unsigned long) Base + (Offset));
978 }
979 
980 static inline void
xf86WriteMmio8(int Value,void * Base,unsigned long Offset)981 xf86WriteMmio8(int Value, void *Base, unsigned long Offset)
982 {
983     write_mem_barrier();
984     *(CARD8 *) ((unsigned long) Base + (Offset)) = Value;
985 }
986 
987 static inline void
xf86WriteMmio16(int Value,void * Base,unsigned long Offset)988 xf86WriteMmio16(int Value, void *Base, unsigned long Offset)
989 {
990     write_mem_barrier();
991     *(CARD16 *) ((unsigned long) Base + (Offset)) = Value;
992 }
993 
994 static inline void
xf86WriteMmio32(int Value,void * Base,unsigned long Offset)995 xf86WriteMmio32(int Value, void *Base, unsigned long Offset)
996 {
997     write_mem_barrier();
998     *(CARD32 *) ((unsigned long) Base + (Offset)) = Value;
999 }
1000 
1001 extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *,
1002                                            int);
1003 extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int);
1004 
1005 /* Some macros to hide the system dependencies for MMIO accesses */
1006 /* Changed to kill noise generated by gcc's -Wcast-align */
1007 #define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
1008 #define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset)
1009 #define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset)
1010 
1011 #define MMIO_OUT8(base, offset, val) \
1012     xf86WriteMmio8((CARD8)(val), base, offset)
1013 #define MMIO_OUT16(base, offset, val) \
1014     xf86WriteMmio16((CARD16)(val), base, offset)
1015 #define MMIO_OUT32(base, offset, val) \
1016     xf86WriteMmio32((CARD32)(val), base, offset)
1017 
1018 #elif defined(__powerpc__) || defined(__sparc__)
1019  /*
1020   * we provide byteswapping and no byteswapping functions here
1021   * with byteswapping as default,
1022   * drivers that don't need byteswapping should define MMIO_IS_BE
1023   */
1024 #define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
1025 #define MMIO_OUT8(base, offset, val) \
1026     xf86WriteMmio8(base, offset, (CARD8)(val))
1027 
1028 #if defined(MMIO_IS_BE)     /* No byteswapping */
1029 #define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset)
1030 #define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset)
1031 #define MMIO_OUT16(base, offset, val) \
1032     xf86WriteMmio16Be(base, offset, (CARD16)(val))
1033 #define MMIO_OUT32(base, offset, val) \
1034     xf86WriteMmio32Be(base, offset, (CARD32)(val))
1035 #else                           /* byteswapping is the default */
1036 #define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset)
1037 #define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset)
1038 #define MMIO_OUT16(base, offset, val) \
1039      xf86WriteMmio16Le(base, offset, (CARD16)(val))
1040 #define MMIO_OUT32(base, offset, val) \
1041      xf86WriteMmio32Le(base, offset, (CARD32)(val))
1042 #endif
1043 
1044 #elif defined(__nds32__)
1045  /*
1046   * we provide byteswapping and no byteswapping functions here
1047   * with no byteswapping as default; when endianness of CPU core
1048   * and I/O devices don't match, byte swapping is necessary
1049   * drivers that need byteswapping should define NDS32_MMIO_SWAP
1050   */
1051 #define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
1052 #define MMIO_OUT8(base, offset, val) \
1053     xf86WriteMmio8(base, offset, (CARD8)(val))
1054 
1055 #if defined(NDS32_MMIO_SWAP)    /* byteswapping */
1056 #define MMIO_IN16(base, offset) xf86ReadMmio16Swap(base, offset)
1057 #define MMIO_IN32(base, offset) xf86ReadMmio32Swap(base, offset)
1058 #define MMIO_OUT16(base, offset, val) \
1059     xf86WriteMmio16Swap(base, offset, (CARD16)(val))
1060 #define MMIO_OUT32(base, offset, val) \
1061     xf86WriteMmio32Swap(base, offset, (CARD32)(val))
1062 #else                           /* no byteswapping is the default */
1063 #define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset)
1064 #define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset)
1065 #define MMIO_OUT16(base, offset, val) \
1066      xf86WriteMmio16(base, offset, (CARD16)(val))
1067 #define MMIO_OUT32(base, offset, val) \
1068      xf86WriteMmio32(base, offset, (CARD32)(val))
1069 #endif
1070 
1071 #else                           /* !__alpha__ && !__powerpc__ && !__sparc__ */
1072 
1073 #define MMIO_IN8(base, offset) \
1074 	*(volatile CARD8 *)(((CARD8*)(base)) + (offset))
1075 #define MMIO_IN16(base, offset) \
1076 	*(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset))
1077 #define MMIO_IN32(base, offset) \
1078 	*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
1079 #define MMIO_OUT8(base, offset, val) \
1080 	*(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val)
1081 #define MMIO_OUT16(base, offset, val) \
1082 	*(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
1083 #define MMIO_OUT32(base, offset, val) \
1084 	*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
1085 
1086 #endif                          /* __alpha__ */
1087 
1088 /*
1089  * With Intel, the version in os-support/misc/SlowBcopy.s is used.
1090  * This avoids port I/O during the copy (which causes problems with
1091  * some hardware).
1092  */
1093 #ifdef __alpha__
1094 #define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count)
1095 #define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count)
1096 #else                           /* __alpha__ */
1097 #define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count)
1098 #define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count)
1099 #endif                          /* __alpha__ */
1100 
1101 #endif                          /* _COMPILER_H */
1102