ReactOS  0.4.14-dev-1034-g1e60116
portio.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: hal/halppc/generic/portio.c
5  * PURPOSE: Port I/O functions
6  * PROGRAMMER: Eric Kohl
7  * UPDATE HISTORY:
8  * Created 18/10/99
9  */
10 
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS ****************************************************************/
16 
17 /*
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/..).
22  *
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
27  * mistake somewhere.
28  */
29 
30 /*
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.
34  *
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)
37  *
38  * Linus
39  */
40 
41 #if defined(__GNUC__)
42 
43 #ifdef SLOW_IO_BY_JUMPING
44 #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
45 #else
46 #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
47 #endif
48 
49 #elif defined(_MSC_VER)
50 
51 #ifdef SLOW_IO_BY_JUMPING
52 #define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f:
53 #else
54 #define __SLOW_DOWN_IO __asm out 0x80, al
55 #endif
56 
57 #else
58 #error Unknown compiler for inline assembler
59 #endif
60 
61 
62 #ifdef REALLY_SLOW_IO
63 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
64 #else
65 #define SLOW_DOWN_IO __SLOW_DOWN_IO
66 #endif
67 
68 extern int GetPhysByte(int Addr);
69 extern void SetPhysByte(int Addr, int Val);
70 extern int GetPhysWord(int Addr);
71 extern void SetPhysWord(int Addr, int Val);
72 extern int GetPhys(int Addr);
73 extern void SetPhys(int Addr, int Val);
74 
75 __asm__("\t.globl GetPhys\n"
76  "GetPhys:\t\n"
77  "mflr 0\n\t"
78  "stwu 0,-16(1)\n\t"
79  "mfmsr 5\n\t"
80  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
81  "mtmsr 6\n\t"
82  "isync\n\t"
83  "sync\n\t"
84  "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
85  "mtmsr 5\n\t"
86  "isync\n\t"
87  "sync\n\t"
88  "lwz 0,0(1)\n\t"
89  "addi 1,1,16\n\t"
90  "mtlr 0\n\t"
91  "blr"
92  );
93 
94 __asm__("\t.globl GetPhysWord\n"
95  "GetPhysWord:\t\n"
96  "mflr 0\n\t"
97  "stwu 0,-16(1)\n\t"
98  "mfmsr 5\n\t"
99  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
100  "mtmsr 6\n\t"
101  "isync\n\t"
102  "sync\n\t"
103  "lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
104  "mtmsr 5\n\t"
105  "isync\n\t"
106  "sync\n\t"
107  "lwz 0,0(1)\n\t"
108  "addi 1,1,16\n\t"
109  "mtlr 0\n\t"
110  "blr"
111  );
112 
113 __asm__("\t.globl GetPhysByte\n"
114  "GetPhysByte:\t\n"
115  "mflr 0\n\t"
116  "stwu 0,-16(1)\n\t"
117  "mfmsr 5\n\t"
118  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
119  "mtmsr 6\n\t"
120  "isync\n\t"
121  "sync\n\t"
122  "lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
123  "mtmsr 5\n\t"
124  "isync\n\t"
125  "sync\n\t"
126  "lwz 0,0(1)\n\t"
127  "addi 1,1,16\n\t"
128  "mtlr 0\n\t"
129  "blr"
130  );
131 
132 __asm__("\t.globl SetPhys\n"
133  "SetPhys:\t\n"
134  "mflr 0\n\t"
135  "stwu 0,-16(1)\n\t"
136  "mfmsr 5\n\t"
137  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
138  "mtmsr 6\n\t"
139  "sync\n\t"
140  "eieio\n\t"
141  "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
142  "dcbst 0,3\n\t"
143  "mtmsr 5\n\t"
144  "sync\n\t"
145  "eieio\n\t"
146  "mr 3,4\n\t"
147  "lwz 0,0(1)\n\t"
148  "addi 1,1,16\n\t"
149  "mtlr 0\n\t"
150  "blr"
151  );
152 
153 __asm__("\t.globl SetPhysWord\n"
154  "SetPhysWord:\t\n"
155  "mflr 0\n\t"
156  "stwu 0,-16(1)\n\t"
157  "mfmsr 5\n\t"
158  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
159  "mtmsr 6\n\t"
160  "sync\n\t"
161  "eieio\n\t"
162  "sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */
163  "dcbst 0,3\n\t"
164  "mtmsr 5\n\t"
165  "sync\n\t"
166  "eieio\n\t"
167  "mr 3,4\n\t"
168  "lwz 0,0(1)\n\t"
169  "addi 1,1,16\n\t"
170  "mtlr 0\n\t"
171  "blr"
172  );
173 
174 __asm__("\t.globl SetPhysByte\n"
175  "SetPhysByte:\t\n"
176  "mflr 0\n\t"
177  "stwu 0,-16(1)\n\t"
178  "mfmsr 5\n\t"
179  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
180  "mtmsr 6\n\t"
181  "sync\n\t"
182  "eieio\n\t"
183  "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
184  "dcbst 0,3\n\t"
185  "mtmsr 5\n\t"
186  "sync\n\t"
187  "eieio\n\t"
188  "mr 3,4\n\t"
189  "lwz 0,0(1)\n\t"
190  "addi 1,1,16\n\t"
191  "mtlr 0\n\t"
192  "blr"
193  );
194 
195 VOID NTAPI
197  PUCHAR Buffer,
198  ULONG Count)
199 {
200  while(Count--) { *Buffer++ = GetPhysByte((ULONG)Port); }
201 }
202 
203 VOID NTAPI
205  PUSHORT Buffer,
206  ULONG Count)
207 {
208  while(Count--) { *Buffer++ = GetPhysWord((ULONG)Port); }
209 }
210 
211 VOID NTAPI
213  PULONG Buffer,
214  ULONG Count)
215 {
216  while(Count--) { *Buffer++ = GetPhys((ULONG)Port); }
217 }
218 
219 UCHAR NTAPI
221 {
222  return GetPhys((ULONG)Port);
223 }
224 
227 {
228  return GetPhysWord((ULONG)Port);
229 }
230 
231 ULONG NTAPI
233 {
234  return GetPhys((ULONG)Port);
235 }
236 
237 VOID NTAPI
239  PUCHAR Buffer,
240  ULONG Count)
241 {
242  while(Count--) { SetPhysByte((ULONG)Port, *Buffer++); }
243 }
244 
245 VOID NTAPI
247  PUSHORT Buffer,
248  ULONG Count)
249 {
250  while(Count--) { SetPhysWord((ULONG)Port, *Buffer++); }
251 }
252 
253 VOID NTAPI
255  PULONG Buffer,
256  ULONG Count)
257 {
258  while(Count--) { SetPhys((ULONG)Port, *Buffer++); }
259 }
260 
261 VOID NTAPI
263  UCHAR Value)
264 {
266 }
267 
268 VOID NTAPI
270  USHORT Value)
271 {
273 }
274 
275 VOID NTAPI
277  ULONG Value)
278 {
279  SetPhys((ULONG)Port, Value);
280 }
281 
282 /* EOF */
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
int GetPhys(int Addr)
CPPORT Port[4]
Definition: headless.c:34
int GetPhysByte(int Addr)
VOID NTAPI WRITE_PORT_USHORT(IN PUSHORT Port, IN USHORT Value)
Definition: portio.c:115
VOID NTAPI WRITE_PORT_BUFFER_UCHAR(IN PUCHAR Port, IN PUCHAR Buffer, IN ULONG Count)
Definition: portio.c:77
UCHAR NTAPI READ_PORT_UCHAR(IN PUCHAR Port)
Definition: portio.c:56
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG NTAPI READ_PORT_ULONG(IN PULONG Port)
Definition: portio.c:70
VOID NTAPI READ_PORT_BUFFER_UCHAR(IN PUCHAR Port, OUT PUCHAR Buffer, IN ULONG Count)
Definition: portio.c:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
void SetPhysWord(int Addr, int Val)
VOID NTAPI WRITE_PORT_ULONG(IN PULONG Port, IN ULONG Value)
Definition: portio.c:123
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
int GetPhysWord(int Addr)
Definition: bufpool.h:45
VOID NTAPI READ_PORT_BUFFER_USHORT(IN PUSHORT Port, OUT PUSHORT Buffer, IN ULONG Count)
Definition: portio.c:36
unsigned char UCHAR
Definition: xmlstorage.h:181
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI READ_PORT_BUFFER_ULONG(IN PULONG Port, OUT PULONG Buffer, IN ULONG Count)
Definition: portio.c:46
void SetPhys(int Addr, int Val)
unsigned int ULONG
Definition: retypes.h:1
void SetPhysByte(int Addr, int Val)
VOID NTAPI WRITE_PORT_UCHAR(IN PUCHAR Port, IN UCHAR Value)
Definition: portio.c:107
USHORT NTAPI READ_PORT_USHORT(IN PUSHORT Port)
Definition: portio.c:63
VOID NTAPI WRITE_PORT_BUFFER_ULONG(IN PULONG Port, IN PULONG Buffer, IN ULONG Count)
Definition: portio.c:97
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI WRITE_PORT_BUFFER_USHORT(IN PUSHORT Port, IN PUSHORT Buffer, IN ULONG Count)
Definition: portio.c:87