-revert janderwalds change until because it breaks the gcc 4.x build
[reactos.git] / reactos / boot / freeldr / freeldr / arch / i386 / portio.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/hal/x86/portio.c
6 * PURPOSE: Port I/O functions
7 * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
8 * UPDATE HISTORY:
9 * Created 18/10/99
10 */
11
12 //#include <ntddk.h>
13 #include <freeldr.h>
14
15
16 /* FUNCTIONS ****************************************************************/
17
18 /*
19 * This file contains the definitions for the x86 IO instructions
20 * inb/inw/inl/outb/outw/outl and the "string versions" of the same
21 * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
22 * versions of the single-IO instructions (inb_p/inw_p/..).
23 *
24 * This file is not meant to be obfuscating: it's just complicated
25 * to (a) handle it all in a way that makes gcc able to optimize it
26 * as well as possible and (b) trying to avoid writing the same thing
27 * over and over again with slight variations and possibly making a
28 * mistake somewhere.
29 */
30
31 /*
32 * Thanks to James van Artsdalen for a better timing-fix than
33 * the two short jumps: using outb's to a nonexistent port seems
34 * to guarantee better timings even on fast machines.
35 *
36 * On the other hand, I'd like to be sure of a non-existent port:
37 * I feel a bit unsafe about using 0x80 (should be safe, though)
38 *
39 * Linus
40 */
41
42 #ifdef SLOW_IO_BY_JUMPING
43 #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
44 #else
45 #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
46 #endif
47
48 #ifdef REALLY_SLOW_IO
49 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
50 #else
51 #define SLOW_DOWN_IO __SLOW_DOWN_IO
52 #endif
53
54 #undef READ_PORT_BUFFER_UCHAR
55 NTHALAPI
56 VOID
57 DDKAPI
58 READ_PORT_BUFFER_UCHAR (PUCHAR Port,
59 PUCHAR Buffer,
60 ULONG Count)
61 {
62 __asm__ __volatile__ ("cld ; rep ; insb\n\t"
63 : "=D" (Buffer), "=c" (Count)
64 : "d" (Port),"0" (Buffer),"1" (Count));
65 }
66
67 #undef READ_PORT_BUFFER_USHORT
68 NTHALAPI
69 VOID
70 DDKAPI
71 READ_PORT_BUFFER_USHORT (USHORT* Port,
72 USHORT* Buffer,
73 ULONG Count)
74 {
75 __asm__ __volatile__ ("cld ; rep ; insw"
76 : "=D" (Buffer), "=c" (Count)
77 : "d" (Port),"0" (Buffer),"1" (Count));
78 }
79
80 #undef READ_PORT_BUFFER_ULONG
81 NTHALAPI
82 VOID
83 DDKAPI
84 READ_PORT_BUFFER_ULONG (ULONG* Port,
85 ULONG* Buffer,
86 ULONG Count)
87 {
88 __asm__ __volatile__ ("cld ; rep ; insl"
89 : "=D" (Buffer), "=c" (Count)
90 : "d" (Port),"0" (Buffer),"1" (Count));
91 }
92
93 #undef READ_PORT_UCHAR
94 NTHALAPI
95 UCHAR
96 DDKAPI
97 READ_PORT_UCHAR (PUCHAR Port)
98 {
99 UCHAR Value;
100
101 __asm__("inb %w1, %0\n\t"
102 : "=a" (Value)
103 : "d" (Port));
104 SLOW_DOWN_IO;
105 return(Value);
106 }
107
108 #undef READ_PORT_USHORT
109 NTHALAPI
110 USHORT
111 DDKAPI
112 READ_PORT_USHORT (USHORT* Port)
113 {
114 USHORT Value;
115
116 __asm__("inw %w1, %0\n\t"
117 : "=a" (Value)
118 : "d" (Port));
119 SLOW_DOWN_IO;
120 return(Value);
121 }
122
123 #undef READ_PORT_ULONG
124 NTHALAPI
125 ULONG
126 DDKAPI
127 READ_PORT_ULONG (ULONG* Port)
128 {
129 ULONG Value;
130
131 __asm__("inl %w1, %0\n\t"
132 : "=a" (Value)
133 : "d" (Port));
134 SLOW_DOWN_IO;
135 return(Value);
136 }
137
138 #undef WRITE_PORT_BUFFER_UCHAR
139 NTHALAPI
140 VOID
141 DDKAPI
142 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
143 PUCHAR Buffer,
144 ULONG Count)
145 {
146 __asm__ __volatile__ ("cld ; rep ; outsb"
147 : "=S" (Buffer), "=c" (Count)
148 : "d" (Port),"0" (Buffer),"1" (Count));
149 }
150
151 #undef WRITE_PORT_BUFFER_USHORT
152 NTHALAPI
153 VOID
154 DDKAPI
155 WRITE_PORT_BUFFER_USHORT (USHORT* Port,
156 USHORT* Buffer,
157 ULONG Count)
158 {
159 __asm__ __volatile__ ("cld ; rep ; outsw"
160 : "=S" (Buffer), "=c" (Count)
161 : "d" (Port),"0" (Buffer),"1" (Count));
162 }
163
164 #undef WRITE_PORT_BUFFER_ULONG
165 NTHALAPI
166 VOID
167 DDKAPI
168 WRITE_PORT_BUFFER_ULONG (ULONG* Port,
169 ULONG* Buffer,
170 ULONG Count)
171 {
172 __asm__ __volatile__ ("cld ; rep ; outsl"
173 : "=S" (Buffer), "=c" (Count)
174 : "d" (Port),"0" (Buffer),"1" (Count));
175 }
176
177 #undef WRITE_PORT_UCHAR
178 NTHALAPI
179 VOID
180 DDKAPI
181 WRITE_PORT_UCHAR (PUCHAR Port,
182 UCHAR Value)
183 {
184 __asm__("outb %0, %w1\n\t"
185 :
186 : "a" (Value),
187 "d" (Port));
188 SLOW_DOWN_IO;
189 }
190
191 #undef WRITE_PORT_USHORT
192 NTHALAPI
193 VOID
194 DDKAPI
195 WRITE_PORT_USHORT (USHORT* Port,
196 USHORT Value)
197 {
198 __asm__("outw %0, %w1\n\t"
199 :
200 : "a" (Value),
201 "d" (Port));
202 SLOW_DOWN_IO;
203 }
204
205 #undef WRITE_PORT_ULONG
206 NTHALAPI
207 VOID
208 DDKAPI
209 WRITE_PORT_ULONG (ULONG* Port,
210 ULONG Value)
211 {
212 __asm__("outl %0, %w1\n\t"
213 :
214 : "a" (Value),
215 "d" (Port));
216 SLOW_DOWN_IO;
217 }
218
219 /* EOF */