Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenportio.c
Go to the documentation of this file.
00001 /* $Id: portio.c 23907 2006-09-04 05:52:23Z arty $ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS kernel 00005 * FILE: ntoskrnl/hal/x86/portio.c 00006 * PURPOSE: Port I/O functions 00007 * PROGRAMMER: Eric Kohl 00008 * UPDATE HISTORY: 00009 * Created 18/10/99 00010 */ 00011 00012 #include <hal.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* FUNCTIONS ****************************************************************/ 00017 00018 /* 00019 * This file contains the definitions for the x86 IO instructions 00020 * inb/inw/inl/outb/outw/outl and the "string versions" of the same 00021 * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" 00022 * versions of the single-IO instructions (inb_p/inw_p/..). 00023 * 00024 * This file is not meant to be obfuscating: it's just complicated 00025 * to (a) handle it all in a way that makes gcc able to optimize it 00026 * as well as possible and (b) trying to avoid writing the same thing 00027 * over and over again with slight variations and possibly making a 00028 * mistake somewhere. 00029 */ 00030 00031 /* 00032 * Thanks to James van Artsdalen for a better timing-fix than 00033 * the two short jumps: using outb's to a nonexistent port seems 00034 * to guarantee better timings even on fast machines. 00035 * 00036 * On the other hand, I'd like to be sure of a non-existent port: 00037 * I feel a bit unsafe about using 0x80 (should be safe, though) 00038 * 00039 * Linus 00040 */ 00041 00042 #if defined(__GNUC__) 00043 00044 #ifdef SLOW_IO_BY_JUMPING 00045 #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:") 00046 #else 00047 #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80") 00048 #endif 00049 00050 #elif defined(_MSC_VER) 00051 00052 #ifdef SLOW_IO_BY_JUMPING 00053 #define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f: 00054 #else 00055 #define __SLOW_DOWN_IO __asm out 0x80, al 00056 #endif 00057 00058 #else 00059 #error Unknown compiler for inline assembler 00060 #endif 00061 00062 00063 #ifdef REALLY_SLOW_IO 00064 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; } 00065 #else 00066 #define SLOW_DOWN_IO __SLOW_DOWN_IO 00067 #endif 00068 00069 extern int GetPhysByte(int Addr); 00070 extern void SetPhysByte(int Addr, int Val); 00071 extern int GetPhysWord(int Addr); 00072 extern void SetPhysWord(int Addr, int Val); 00073 extern int GetPhys(int Addr); 00074 extern void SetPhys(int Addr, int Val); 00075 00076 __asm__("\t.globl GetPhys\n" 00077 "GetPhys:\t\n" 00078 "mflr 0\n\t" 00079 "stwu 0,-16(1)\n\t" 00080 "mfmsr 5\n\t" 00081 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00082 "mtmsr 6\n\t" 00083 "isync\n\t" 00084 "sync\n\t" 00085 "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ 00086 "mtmsr 5\n\t" 00087 "isync\n\t" 00088 "sync\n\t" 00089 "lwz 0,0(1)\n\t" 00090 "addi 1,1,16\n\t" 00091 "mtlr 0\n\t" 00092 "blr" 00093 ); 00094 00095 __asm__("\t.globl GetPhysWord\n" 00096 "GetPhysWord:\t\n" 00097 "mflr 0\n\t" 00098 "stwu 0,-16(1)\n\t" 00099 "mfmsr 5\n\t" 00100 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00101 "mtmsr 6\n\t" 00102 "isync\n\t" 00103 "sync\n\t" 00104 "lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ 00105 "mtmsr 5\n\t" 00106 "isync\n\t" 00107 "sync\n\t" 00108 "lwz 0,0(1)\n\t" 00109 "addi 1,1,16\n\t" 00110 "mtlr 0\n\t" 00111 "blr" 00112 ); 00113 00114 __asm__("\t.globl GetPhysByte\n" 00115 "GetPhysByte:\t\n" 00116 "mflr 0\n\t" 00117 "stwu 0,-16(1)\n\t" 00118 "mfmsr 5\n\t" 00119 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00120 "mtmsr 6\n\t" 00121 "isync\n\t" 00122 "sync\n\t" 00123 "lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ 00124 "mtmsr 5\n\t" 00125 "isync\n\t" 00126 "sync\n\t" 00127 "lwz 0,0(1)\n\t" 00128 "addi 1,1,16\n\t" 00129 "mtlr 0\n\t" 00130 "blr" 00131 ); 00132 00133 __asm__("\t.globl SetPhys\n" 00134 "SetPhys:\t\n" 00135 "mflr 0\n\t" 00136 "stwu 0,-16(1)\n\t" 00137 "mfmsr 5\n\t" 00138 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00139 "mtmsr 6\n\t" 00140 "sync\n\t" 00141 "eieio\n\t" 00142 "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */ 00143 "dcbst 0,3\n\t" 00144 "mtmsr 5\n\t" 00145 "sync\n\t" 00146 "eieio\n\t" 00147 "mr 3,4\n\t" 00148 "lwz 0,0(1)\n\t" 00149 "addi 1,1,16\n\t" 00150 "mtlr 0\n\t" 00151 "blr" 00152 ); 00153 00154 __asm__("\t.globl SetPhysWord\n" 00155 "SetPhysWord:\t\n" 00156 "mflr 0\n\t" 00157 "stwu 0,-16(1)\n\t" 00158 "mfmsr 5\n\t" 00159 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00160 "mtmsr 6\n\t" 00161 "sync\n\t" 00162 "eieio\n\t" 00163 "sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */ 00164 "dcbst 0,3\n\t" 00165 "mtmsr 5\n\t" 00166 "sync\n\t" 00167 "eieio\n\t" 00168 "mr 3,4\n\t" 00169 "lwz 0,0(1)\n\t" 00170 "addi 1,1,16\n\t" 00171 "mtlr 0\n\t" 00172 "blr" 00173 ); 00174 00175 __asm__("\t.globl SetPhysByte\n" 00176 "SetPhysByte:\t\n" 00177 "mflr 0\n\t" 00178 "stwu 0,-16(1)\n\t" 00179 "mfmsr 5\n\t" 00180 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00181 "mtmsr 6\n\t" 00182 "sync\n\t" 00183 "eieio\n\t" 00184 "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */ 00185 "dcbst 0,3\n\t" 00186 "mtmsr 5\n\t" 00187 "sync\n\t" 00188 "eieio\n\t" 00189 "mr 3,4\n\t" 00190 "lwz 0,0(1)\n\t" 00191 "addi 1,1,16\n\t" 00192 "mtlr 0\n\t" 00193 "blr" 00194 ); 00195 00196 VOID NTAPI 00197 READ_PORT_BUFFER_UCHAR (PUCHAR Port, 00198 PUCHAR Buffer, 00199 ULONG Count) 00200 { 00201 while(Count--) { *Buffer++ = GetPhysByte((ULONG)Port); } 00202 } 00203 00204 VOID NTAPI 00205 READ_PORT_BUFFER_USHORT (PUSHORT Port, 00206 PUSHORT Buffer, 00207 ULONG Count) 00208 { 00209 while(Count--) { *Buffer++ = GetPhysWord((ULONG)Port); } 00210 } 00211 00212 VOID NTAPI 00213 READ_PORT_BUFFER_ULONG (PULONG Port, 00214 PULONG Buffer, 00215 ULONG Count) 00216 { 00217 while(Count--) { *Buffer++ = GetPhys((ULONG)Port); } 00218 } 00219 00220 UCHAR NTAPI 00221 READ_PORT_UCHAR (PUCHAR Port) 00222 { 00223 return GetPhys((ULONG)Port); 00224 } 00225 00226 USHORT NTAPI 00227 READ_PORT_USHORT (PUSHORT Port) 00228 { 00229 return GetPhysWord((ULONG)Port); 00230 } 00231 00232 ULONG NTAPI 00233 READ_PORT_ULONG (PULONG Port) 00234 { 00235 return GetPhys((ULONG)Port); 00236 } 00237 00238 VOID NTAPI 00239 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port, 00240 PUCHAR Buffer, 00241 ULONG Count) 00242 { 00243 while(Count--) { SetPhysByte((ULONG)Port, *Buffer++); } 00244 } 00245 00246 VOID NTAPI 00247 WRITE_PORT_BUFFER_USHORT (PUSHORT Port, 00248 PUSHORT Buffer, 00249 ULONG Count) 00250 { 00251 while(Count--) { SetPhysWord((ULONG)Port, *Buffer++); } 00252 } 00253 00254 VOID NTAPI 00255 WRITE_PORT_BUFFER_ULONG (PULONG Port, 00256 PULONG Buffer, 00257 ULONG Count) 00258 { 00259 while(Count--) { SetPhys((ULONG)Port, *Buffer++); } 00260 } 00261 00262 VOID NTAPI 00263 WRITE_PORT_UCHAR (PUCHAR Port, 00264 UCHAR Value) 00265 { 00266 SetPhysByte((ULONG)Port, Value); 00267 } 00268 00269 VOID NTAPI 00270 WRITE_PORT_USHORT (PUSHORT Port, 00271 USHORT Value) 00272 { 00273 SetPhysWord((ULONG)Port, Value); 00274 } 00275 00276 VOID NTAPI 00277 WRITE_PORT_ULONG (PULONG Port, 00278 ULONG Value) 00279 { 00280 SetPhys((ULONG)Port, Value); 00281 } 00282 00283 /* EOF */ Generated on Sat May 26 2012 04:26:34 for ReactOS by
1.7.6.1
|