minor corrections by M.Taguchi
[reactos.git] / freeldr / freeldr / arch / i386 / portio.c
1 /* $Id: portio.c,v 1.1 2003/01/19 01:03:58 bpalmer Exp $
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 VOID /*STDCALL*/
55 READ_PORT_BUFFER_UCHAR (PUCHAR Port,
56 PUCHAR Buffer,
57 U32 Count)
58 {
59 __asm__ __volatile__ ("cld ; rep ; insb\n\t"
60 : "=D" (Buffer), "=c" (Count)
61 : "d" (Port),"0" (Buffer),"1" (Count));
62 }
63
64 VOID /*STDCALL*/
65 READ_PORT_BUFFER_USHORT (U16* Port,
66 U16* Buffer,
67 U32 Count)
68 {
69 __asm__ __volatile__ ("cld ; rep ; insw"
70 : "=D" (Buffer), "=c" (Count)
71 : "d" (Port),"0" (Buffer),"1" (Count));
72 }
73
74 VOID /*STDCALL*/
75 READ_PORT_BUFFER_ULONG (U32* Port,
76 U32* Buffer,
77 U32 Count)
78 {
79 __asm__ __volatile__ ("cld ; rep ; insl"
80 : "=D" (Buffer), "=c" (Count)
81 : "d" (Port),"0" (Buffer),"1" (Count));
82 }
83
84 UCHAR /*STDCALL*/
85 READ_PORT_UCHAR (PUCHAR Port)
86 {
87 UCHAR Value;
88
89 __asm__("inb %w1, %0\n\t"
90 : "=a" (Value)
91 : "d" (Port));
92 SLOW_DOWN_IO;
93 return(Value);
94 }
95
96 U16 /*STDCALL*/
97 READ_PORT_USHORT (U16* Port)
98 {
99 U16 Value;
100
101 __asm__("inw %w1, %0\n\t"
102 : "=a" (Value)
103 : "d" (Port));
104 SLOW_DOWN_IO;
105 return(Value);
106 }
107
108 U32 /*STDCALL*/
109 READ_PORT_ULONG (U32* Port)
110 {
111 U32 Value;
112
113 __asm__("inl %w1, %0\n\t"
114 : "=a" (Value)
115 : "d" (Port));
116 SLOW_DOWN_IO;
117 return(Value);
118 }
119
120 VOID /*STDCALL*/
121 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
122 PUCHAR Buffer,
123 U32 Count)
124 {
125 __asm__ __volatile__ ("cld ; rep ; outsb"
126 : "=S" (Buffer), "=c" (Count)
127 : "d" (Port),"0" (Buffer),"1" (Count));
128 }
129
130 VOID /*STDCALL*/
131 WRITE_PORT_BUFFER_USHORT (U16* Port,
132 U16* Buffer,
133 U32 Count)
134 {
135 __asm__ __volatile__ ("cld ; rep ; outsw"
136 : "=S" (Buffer), "=c" (Count)
137 : "d" (Port),"0" (Buffer),"1" (Count));
138 }
139
140 VOID /*STDCALL*/
141 WRITE_PORT_BUFFER_ULONG (U32* Port,
142 U32* Buffer,
143 U32 Count)
144 {
145 __asm__ __volatile__ ("cld ; rep ; outsl"
146 : "=S" (Buffer), "=c" (Count)
147 : "d" (Port),"0" (Buffer),"1" (Count));
148 }
149
150 VOID /*STDCALL*/
151 WRITE_PORT_UCHAR (PUCHAR Port,
152 UCHAR Value)
153 {
154 __asm__("outb %0, %w1\n\t"
155 :
156 : "a" (Value),
157 "d" (Port));
158 SLOW_DOWN_IO;
159 }
160
161 VOID /*STDCALL*/
162 WRITE_PORT_USHORT (U16* Port,
163 U16 Value)
164 {
165 __asm__("outw %0, %w1\n\t"
166 :
167 : "a" (Value),
168 "d" (Port));
169 SLOW_DOWN_IO;
170 }
171
172 VOID /*STDCALL*/
173 WRITE_PORT_ULONG (U32* Port,
174 U32 Value)
175 {
176 __asm__("outl %0, %w1\n\t"
177 :
178 : "a" (Value),
179 "d" (Port));
180 SLOW_DOWN_IO;
181 }
182
183 /* EOF */