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>
16 /* FUNCTIONS ****************************************************************/
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/..).
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
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.
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)
42 #ifdef SLOW_IO_BY_JUMPING
43 #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
45 #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
49 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
51 #define SLOW_DOWN_IO __SLOW_DOWN_IO
54 #undef READ_PORT_BUFFER_UCHAR
57 READ_PORT_BUFFER_UCHAR (PUCHAR Port
,
61 __asm__
__volatile__ ("cld ; rep ; insb\n\t"
62 : "=D" (Buffer
), "=c" (Count
)
63 : "d" (Port
),"0" (Buffer
),"1" (Count
));
66 #undef READ_PORT_BUFFER_USHORT
69 READ_PORT_BUFFER_USHORT (USHORT
* Port
,
73 __asm__
__volatile__ ("cld ; rep ; insw"
74 : "=D" (Buffer
), "=c" (Count
)
75 : "d" (Port
),"0" (Buffer
),"1" (Count
));
78 #undef READ_PORT_BUFFER_ULONG
81 READ_PORT_BUFFER_ULONG (ULONG
* Port
,
85 __asm__
__volatile__ ("cld ; rep ; insl"
86 : "=D" (Buffer
), "=c" (Count
)
87 : "d" (Port
),"0" (Buffer
),"1" (Count
));
90 #undef READ_PORT_UCHAR
93 READ_PORT_UCHAR (PUCHAR Port
)
97 __asm__("inb %w1, %0\n\t"
104 #undef READ_PORT_USHORT
107 READ_PORT_USHORT (USHORT
* Port
)
111 __asm__("inw %w1, %0\n\t"
118 #undef READ_PORT_ULONG
121 READ_PORT_ULONG (ULONG
* Port
)
125 __asm__("inl %w1, %0\n\t"
132 #undef WRITE_PORT_BUFFER_UCHAR
135 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port
,
139 __asm__
__volatile__ ("cld ; rep ; outsb"
140 : "=S" (Buffer
), "=c" (Count
)
141 : "d" (Port
),"0" (Buffer
),"1" (Count
));
144 #undef WRITE_PORT_BUFFER_USHORT
147 WRITE_PORT_BUFFER_USHORT (USHORT
* Port
,
151 __asm__
__volatile__ ("cld ; rep ; outsw"
152 : "=S" (Buffer
), "=c" (Count
)
153 : "d" (Port
),"0" (Buffer
),"1" (Count
));
156 #undef WRITE_PORT_BUFFER_ULONG
159 WRITE_PORT_BUFFER_ULONG (ULONG
* Port
,
163 __asm__
__volatile__ ("cld ; rep ; outsl"
164 : "=S" (Buffer
), "=c" (Count
)
165 : "d" (Port
),"0" (Buffer
),"1" (Count
));
168 #undef WRITE_PORT_UCHAR
171 WRITE_PORT_UCHAR (PUCHAR Port
,
174 __asm__("outb %0, %w1\n\t"
181 #undef WRITE_PORT_USHORT
184 WRITE_PORT_USHORT (USHORT
* Port
,
187 __asm__("outw %0, %w1\n\t"
194 #undef WRITE_PORT_ULONG
197 WRITE_PORT_ULONG (ULONG
* Port
,
200 __asm__("outl %0, %w1\n\t"