implemented some stubs needed by ClamWin
[reactos.git] / reactos / hal / halx86 / generic / 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 <hal.h>
13 #define NDEBUG
14 #include <debug.h>
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 #if defined(__GNUC__)
43
44 #ifdef SLOW_IO_BY_JUMPING
45 #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
46 #else
47 #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
48 #endif
49
50 #elif defined(_MSC_VER)
51
52 #ifdef SLOW_IO_BY_JUMPING
53 #define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f:
54 #else
55 #define __SLOW_DOWN_IO __asm out 0x80, al
56 #endif
57
58 #else
59 #error Unknown compiler for inline assembler
60 #endif
61
62
63 #ifdef REALLY_SLOW_IO
64 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
65 #else
66 #define SLOW_DOWN_IO __SLOW_DOWN_IO
67 #endif
68
69 VOID STDCALL
70 READ_PORT_BUFFER_UCHAR (PUCHAR Port,
71 PUCHAR Buffer,
72 ULONG Count)
73 {
74 #if defined(__GNUC__)
75 __asm__ __volatile__ ("cld ; rep ; insb\n\t"
76 : "=D" (Buffer), "=c" (Count)
77 : "d" (Port),"0" (Buffer),"1" (Count));
78 #elif defined(_MSC_VER)
79 __asm
80 {
81 mov edx, Port
82 mov edi, Buffer
83 mov ecx, Count
84 cld
85 rep ins byte ptr[edi], dx
86 }
87 #else
88 #error Unknown compiler for inline assembler
89 #endif
90 }
91
92 VOID STDCALL
93 READ_PORT_BUFFER_USHORT (PUSHORT Port,
94 PUSHORT Buffer,
95 ULONG Count)
96 {
97 #if defined(__GNUC__)
98 __asm__ __volatile__ ("cld ; rep ; insw"
99 : "=D" (Buffer), "=c" (Count)
100 : "d" (Port),"0" (Buffer),"1" (Count));
101 #elif defined(_MSC_VER)
102 __asm
103 {
104 mov edx, Port
105 mov edi, Buffer
106 mov ecx, Count
107 cld
108 rep ins word ptr[edi], dx
109 }
110 #else
111 #error Unknown compiler for inline assembler
112 #endif
113 }
114
115 VOID STDCALL
116 READ_PORT_BUFFER_ULONG (PULONG Port,
117 PULONG Buffer,
118 ULONG Count)
119 {
120 #if defined(__GNUC__)
121 __asm__ __volatile__ ("cld ; rep ; insl"
122 : "=D" (Buffer), "=c" (Count)
123 : "d" (Port),"0" (Buffer),"1" (Count));
124 #elif defined(_MSC_VER)
125 __asm
126 {
127 mov edx, Port
128 mov edi, Buffer
129 mov ecx, Count
130 cld
131 rep ins dword ptr[edi], dx
132 }
133 #else
134 #error Unknown compiler for inline assembler
135 #endif
136 }
137
138 UCHAR STDCALL
139 READ_PORT_UCHAR (PUCHAR Port)
140 {
141 UCHAR Value;
142
143 #if defined(__GNUC__)
144 __asm__("inb %w1, %0\n\t"
145 : "=a" (Value)
146 : "d" (Port));
147 #elif defined(_MSC_VER)
148 __asm
149 {
150 mov edx, Port
151 in al, dx
152 mov Value, al
153 }
154 #else
155 #error Unknown compiler for inline assembler
156 #endif
157
158 SLOW_DOWN_IO;
159 return(Value);
160 }
161
162 USHORT STDCALL
163 READ_PORT_USHORT (PUSHORT Port)
164 {
165 USHORT Value;
166
167 #if defined(__GNUC__)
168 __asm__("inw %w1, %0\n\t"
169 : "=a" (Value)
170 : "d" (Port));
171 #elif defined(_MSC_VER)
172 __asm
173 {
174 mov edx, Port
175 in ax, dx
176 mov Value, ax
177 }
178 #else
179 #error Unknown compiler for inline assembler
180 #endif
181 SLOW_DOWN_IO;
182 return(Value);
183 }
184
185 ULONG STDCALL
186 READ_PORT_ULONG (PULONG Port)
187 {
188 ULONG Value;
189
190 #if defined(__GNUC__)
191 __asm__("inl %w1, %0\n\t"
192 : "=a" (Value)
193 : "d" (Port));
194 #elif defined(_MSC_VER)
195 __asm
196 {
197 mov edx, Port
198 in eax, dx
199 mov Value, eax
200 }
201 #else
202 #error Unknown compiler for inline assembler
203 #endif
204 SLOW_DOWN_IO;
205 return(Value);
206 }
207
208 VOID STDCALL
209 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
210 PUCHAR Buffer,
211 ULONG Count)
212 {
213 #if defined(__GNUC__)
214 __asm__ __volatile__ ("cld ; rep ; outsb"
215 : "=S" (Buffer), "=c" (Count)
216 : "d" (Port),"0" (Buffer),"1" (Count));
217 #elif defined(_MSC_VER)
218 __asm
219 {
220 mov edx, Port
221 mov esi, Buffer
222 mov ecx, Count
223 cld
224 rep outs
225 }
226 #else
227 #error Unknown compiler for inline assembler
228 #endif
229 }
230
231 VOID STDCALL
232 WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
233 PUSHORT Buffer,
234 ULONG Count)
235 {
236 #if defined(__GNUC__)
237 __asm__ __volatile__ ("cld ; rep ; outsw"
238 : "=S" (Buffer), "=c" (Count)
239 : "d" (Port),"0" (Buffer),"1" (Count));
240 #elif defined(_MSC_VER)
241 __asm
242 {
243 mov edx, Port
244 mov esi, Buffer
245 mov ecx, Count
246 cld
247 rep outsw
248 }
249 #else
250 #error Unknown compiler for inline assembler
251 #endif
252 }
253
254 VOID STDCALL
255 WRITE_PORT_BUFFER_ULONG (PULONG Port,
256 PULONG Buffer,
257 ULONG Count)
258 {
259 #if defined(__GNUC__)
260 __asm__ __volatile__ ("cld ; rep ; outsl"
261 : "=S" (Buffer), "=c" (Count)
262 : "d" (Port),"0" (Buffer),"1" (Count));
263 #elif defined(_MSC_VER)
264 __asm
265 {
266 mov edx, Port
267 mov esi, Buffer
268 mov ecx, Count
269 cld
270 rep outsd
271 }
272 #else
273 #error Unknown compiler for inline assembler
274 #endif
275 }
276
277 VOID STDCALL
278 WRITE_PORT_UCHAR (PUCHAR Port,
279 UCHAR Value)
280 {
281 #if defined(__GNUC__)
282 __asm__("outb %0, %w1\n\t"
283 :
284 : "a" (Value),
285 "d" (Port));
286 #elif defined(_MSC_VER)
287 __asm
288 {
289 mov edx, Port
290 mov al, Value
291 out dx,al
292 }
293 #else
294 #error Unknown compiler for inline assembler
295 #endif
296 SLOW_DOWN_IO;
297 }
298
299 VOID STDCALL
300 WRITE_PORT_USHORT (PUSHORT Port,
301 USHORT Value)
302 {
303 #if defined(__GNUC__)
304 __asm__("outw %0, %w1\n\t"
305 :
306 : "a" (Value),
307 "d" (Port));
308 #elif defined(_MSC_VER)
309 __asm
310 {
311 mov edx, Port
312 mov ax, Value
313 out dx,ax
314 }
315 #else
316 #error Unknown compiler for inline assembler
317 #endif
318 SLOW_DOWN_IO;
319 }
320
321 VOID STDCALL
322 WRITE_PORT_ULONG (PULONG Port,
323 ULONG Value)
324 {
325 #if defined(__GNUC__)
326 __asm__("outl %0, %w1\n\t"
327 :
328 : "a" (Value),
329 "d" (Port));
330 #elif defined(_MSC_VER)
331 __asm
332 {
333 mov edx, Port
334 mov eax, Value
335 out dx,eax
336 }
337 #else
338 #error Unknown compiler for inline assembler
339 #endif
340 SLOW_DOWN_IO;
341 }
342
343 /* EOF */