FreeLdr Patch. Now fully loads ntoskrnl using a PE Loader, supports /3gb dynamically...
[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 <ddk/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 VOID
56 STDCALL
57 READ_PORT_BUFFER_UCHAR (PUCHAR Port,
58 PUCHAR Buffer,
59 ULONG Count)
60 {
61 __asm__ __volatile__ ("cld ; rep ; insb\n\t"
62 : "=D" (Buffer), "=c" (Count)
63 : "d" (Port),"0" (Buffer),"1" (Count));
64 }
65
66 #undef READ_PORT_BUFFER_USHORT
67 VOID
68 STDCALL
69 READ_PORT_BUFFER_USHORT (USHORT* Port,
70 USHORT* Buffer,
71 ULONG Count)
72 {
73 __asm__ __volatile__ ("cld ; rep ; insw"
74 : "=D" (Buffer), "=c" (Count)
75 : "d" (Port),"0" (Buffer),"1" (Count));
76 }
77
78 #undef READ_PORT_BUFFER_ULONG
79 VOID
80 STDCALL
81 READ_PORT_BUFFER_ULONG (ULONG* Port,
82 ULONG* Buffer,
83 ULONG Count)
84 {
85 __asm__ __volatile__ ("cld ; rep ; insl"
86 : "=D" (Buffer), "=c" (Count)
87 : "d" (Port),"0" (Buffer),"1" (Count));
88 }
89
90 #undef READ_PORT_UCHAR
91 UCHAR
92 STDCALL
93 READ_PORT_UCHAR (PUCHAR Port)
94 {
95 UCHAR Value;
96
97 __asm__("inb %w1, %0\n\t"
98 : "=a" (Value)
99 : "d" (Port));
100 SLOW_DOWN_IO;
101 return(Value);
102 }
103
104 #undef READ_PORT_USHORT
105 USHORT
106 STDCALL
107 READ_PORT_USHORT (USHORT* Port)
108 {
109 USHORT Value;
110
111 __asm__("inw %w1, %0\n\t"
112 : "=a" (Value)
113 : "d" (Port));
114 SLOW_DOWN_IO;
115 return(Value);
116 }
117
118 #undef READ_PORT_ULONG
119 ULONG
120 STDCALL
121 READ_PORT_ULONG (ULONG* Port)
122 {
123 ULONG Value;
124
125 __asm__("inl %w1, %0\n\t"
126 : "=a" (Value)
127 : "d" (Port));
128 SLOW_DOWN_IO;
129 return(Value);
130 }
131
132 #undef WRITE_PORT_BUFFER_UCHAR
133 VOID
134 STDCALL
135 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
136 PUCHAR Buffer,
137 ULONG Count)
138 {
139 __asm__ __volatile__ ("cld ; rep ; outsb"
140 : "=S" (Buffer), "=c" (Count)
141 : "d" (Port),"0" (Buffer),"1" (Count));
142 }
143
144 #undef WRITE_PORT_BUFFER_USHORT
145 VOID
146 STDCALL
147 WRITE_PORT_BUFFER_USHORT (USHORT* Port,
148 USHORT* Buffer,
149 ULONG Count)
150 {
151 __asm__ __volatile__ ("cld ; rep ; outsw"
152 : "=S" (Buffer), "=c" (Count)
153 : "d" (Port),"0" (Buffer),"1" (Count));
154 }
155
156 #undef WRITE_PORT_BUFFER_ULONG
157 VOID
158 STDCALL
159 WRITE_PORT_BUFFER_ULONG (ULONG* Port,
160 ULONG* Buffer,
161 ULONG Count)
162 {
163 __asm__ __volatile__ ("cld ; rep ; outsl"
164 : "=S" (Buffer), "=c" (Count)
165 : "d" (Port),"0" (Buffer),"1" (Count));
166 }
167
168 #undef WRITE_PORT_UCHAR
169 VOID
170 STDCALL
171 WRITE_PORT_UCHAR (PUCHAR Port,
172 UCHAR Value)
173 {
174 __asm__("outb %0, %w1\n\t"
175 :
176 : "a" (Value),
177 "d" (Port));
178 SLOW_DOWN_IO;
179 }
180
181 #undef WRITE_PORT_USHORT
182 VOID
183 STDCALL
184 WRITE_PORT_USHORT (USHORT* Port,
185 USHORT Value)
186 {
187 __asm__("outw %0, %w1\n\t"
188 :
189 : "a" (Value),
190 "d" (Port));
191 SLOW_DOWN_IO;
192 }
193
194 #undef WRITE_PORT_ULONG
195 VOID
196 STDCALL
197 WRITE_PORT_ULONG (ULONG* Port,
198 ULONG Value)
199 {
200 __asm__("outl %0, %w1\n\t"
201 :
202 : "a" (Value),
203 "d" (Port));
204 SLOW_DOWN_IO;
205 }
206
207 /* EOF */