1 /* $Id: portio.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
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)
12 #include <ddk/ntddk.h>
15 /* FUNCTIONS ****************************************************************/
18 * This file contains the definitions for the x86 IO instructions
19 * inb/inw/inl/outb/outw/outl and the "string versions" of the same
20 * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
21 * versions of the single-IO instructions (inb_p/inw_p/..).
23 * This file is not meant to be obfuscating: it's just complicated
24 * to (a) handle it all in a way that makes gcc able to optimize it
25 * as well as possible and (b) trying to avoid writing the same thing
26 * over and over again with slight variations and possibly making a
31 * Thanks to James van Artsdalen for a better timing-fix than
32 * the two short jumps: using outb's to a nonexistent port seems
33 * to guarantee better timings even on fast machines.
35 * On the other hand, I'd like to be sure of a non-existent port:
36 * I feel a bit unsafe about using 0x80 (should be safe, though)
43 #ifdef SLOW_IO_BY_JUMPING
44 #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
46 #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
49 #elif defined(_MSC_VER)
51 #ifdef SLOW_IO_BY_JUMPING
52 #define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f:
54 #define __SLOW_DOWN_IO __asm out 0x80, al
58 #error Unknown compiler for inline assembler
63 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
65 #define SLOW_DOWN_IO __SLOW_DOWN_IO
69 READ_PORT_BUFFER_UCHAR (PUCHAR Port
,
74 __asm__
__volatile__ ("cld ; rep ; insb\n\t"
75 : "=D" (Buffer
), "=c" (Count
)
76 : "d" (Port
),"0" (Buffer
),"1" (Count
));
77 #elif defined(_MSC_VER)
84 rep ins byte ptr
[edi
], dx
87 #error Unknown compiler for inline assembler
92 READ_PORT_BUFFER_USHORT (PUSHORT Port
,
97 __asm__
__volatile__ ("cld ; rep ; insw"
98 : "=D" (Buffer
), "=c" (Count
)
99 : "d" (Port
),"0" (Buffer
),"1" (Count
));
100 #elif defined(_MSC_VER)
107 rep ins word ptr
[edi
], dx
110 #error Unknown compiler for inline assembler
115 READ_PORT_BUFFER_ULONG (PULONG Port
,
119 #if defined(__GNUC__)
120 __asm__
__volatile__ ("cld ; rep ; insl"
121 : "=D" (Buffer
), "=c" (Count
)
122 : "d" (Port
),"0" (Buffer
),"1" (Count
));
123 #elif defined(_MSC_VER)
130 rep ins dword ptr
[edi
], dx
133 #error Unknown compiler for inline assembler
138 READ_PORT_UCHAR (PUCHAR Port
)
142 #if defined(__GNUC__)
143 __asm__("inb %w1, %0\n\t"
146 #elif defined(_MSC_VER)
154 #error Unknown compiler for inline assembler
162 READ_PORT_USHORT (PUSHORT Port
)
166 #if defined(__GNUC__)
167 __asm__("inw %w1, %0\n\t"
170 #elif defined(_MSC_VER)
178 #error Unknown compiler for inline assembler
185 READ_PORT_ULONG (PULONG Port
)
189 #if defined(__GNUC__)
190 __asm__("inl %w1, %0\n\t"
193 #elif defined(_MSC_VER)
201 #error Unknown compiler for inline assembler
208 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port
,
212 #if defined(__GNUC__)
213 __asm__
__volatile__ ("cld ; rep ; outsb"
214 : "=S" (Buffer
), "=c" (Count
)
215 : "d" (Port
),"0" (Buffer
),"1" (Count
));
216 #elif defined(_MSC_VER)
226 #error Unknown compiler for inline assembler
231 WRITE_PORT_BUFFER_USHORT (PUSHORT Port
,
235 #if defined(__GNUC__)
236 __asm__
__volatile__ ("cld ; rep ; outsw"
237 : "=S" (Buffer
), "=c" (Count
)
238 : "d" (Port
),"0" (Buffer
),"1" (Count
));
239 #elif defined(_MSC_VER)
249 #error Unknown compiler for inline assembler
254 WRITE_PORT_BUFFER_ULONG (PULONG Port
,
258 #if defined(__GNUC__)
259 __asm__
__volatile__ ("cld ; rep ; outsl"
260 : "=S" (Buffer
), "=c" (Count
)
261 : "d" (Port
),"0" (Buffer
),"1" (Count
));
262 #elif defined(_MSC_VER)
272 #error Unknown compiler for inline assembler
277 WRITE_PORT_UCHAR (PUCHAR Port
,
280 #if defined(__GNUC__)
281 __asm__("outb %0, %w1\n\t"
285 #elif defined(_MSC_VER)
293 #error Unknown compiler for inline assembler
299 WRITE_PORT_USHORT (PUSHORT Port
,
302 #if defined(__GNUC__)
303 __asm__("outw %0, %w1\n\t"
307 #elif defined(_MSC_VER)
315 #error Unknown compiler for inline assembler
321 WRITE_PORT_ULONG (PULONG Port
,
324 #if defined(__GNUC__)
325 __asm__("outl %0, %w1\n\t"
329 #elif defined(_MSC_VER)
337 #error Unknown compiler for inline assembler