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