VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/x11include/7.0/xorg/compiler.h@ 18709

Last change on this file since 18709 was 17236, checked in by vboxsync, 16 years ago

Additions/x11/x11include: blast! Reverted r43555 and r43556

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette