added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / x86_64-pc / include / asm / io.h
blobcd5198ae3dcd1d91e762feb10997249f5199bcda
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id: io.h 13216 2002-02-13 06:22:32Z iaint $
4 */
6 #ifndef ASM_IO_H
7 #define ASM_IO_H
9 /*
10 * This file contains the definitions for the x86 IO instructions
11 * inb/inw/inl/outb/outw/outl and the "string versions" of the same
12 * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
13 * versions of the single-IO instructions (inb_p/inw_p/..).
15 * This file is not meant to be obfuscating: it's just complicated
16 * to (a) handle it all in a way that makes gcc able to optimize it
17 * as well as possible and (b) trying to avoid writing the same thing
18 * over and over again with slight variations and possibly making a
19 * mistake somewhere.
23 * Thanks to James van Artsdalen for a better timing-fix than
24 * the two short jumps: using outb's to a nonexistent port seems
25 * to guarantee better timings even on fast machines.
27 * On the other hand, I'd like to be sure of a non-existent port:
28 * I feel a bit unsafe about using 0x80 (should be safe, though)
30 * Linus
34 * Bit simplified and optimized by Jan Hubicka
37 #ifdef SLOW_IO_BY_JUMPING
38 #define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
39 #else
40 #define __SLOW_DOWN_IO "\noutb %%al,$0x80"
41 #endif
43 #ifdef REALLY_SLOW_IO
44 #define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
45 #else
46 #define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
47 #endif
50 * Talk about misusing macros..
52 #define __OUT1(s,x) \
53 static inline void out##s(unsigned x value, unsigned short port) {
55 #define __OUT2(s,s1,s2) \
56 __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
58 #define __OUT(s,s1,x) \
59 __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
60 __OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
62 #define __IN1(s) \
63 static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
65 #define __IN2(s,s1,s2) \
66 __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
68 #define __IN(s,s1,i...) \
69 __IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
70 __IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
72 #define __INS(s) \
73 static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
74 { __asm__ __volatile__ ("cld ; rep ; ins" #s \
75 : "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
77 #define __OUTS(s) \
78 static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
79 { __asm__ __volatile__ ("cld ; rep ; outs" #s \
80 : "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
82 #define RETURN_TYPE unsigned char
83 __IN(b,"")
84 #undef RETURN_TYPE
85 #define RETURN_TYPE unsigned short
86 __IN(w,"")
87 #undef RETURN_TYPE
88 #define RETURN_TYPE unsigned int
89 __IN(l,"")
90 #undef RETURN_TYPE
92 __OUT(b,"b",char)
93 __OUT(w,"w",short)
94 __OUT(l,,int)
96 __INS(b)
97 __INS(w)
98 __INS(l)
100 __OUTS(b)
101 __OUTS(w)
102 __OUTS(l)
104 #endif