|
|
1.1 ! root 1: #ifndef __KERNEL_X86IO_H__ ! 2: #define __KERNEL_X86IO_H__ ! 3: ! 4: /* ! 5: * The system V DDI/DKI for Intel processors defines a C-language interface to ! 6: * the machine I/O instructions available through <sys/types.h>. ! 7: * ! 8: * For simplicity, this has been factored out into a separate file for this ! 9: * implementation, and <sys/types.h> pulls this file in. ! 10: */ ! 11: /* ! 12: *-IMPORTS: ! 13: * <common/ccompat.h> ! 14: * __EXTERN_C_BEGIN__ ! 15: * __EXTERN_C_END__ ! 16: * __PROTO () ! 17: * __NON_ISO () ! 18: * __INLINE__ ! 19: * <common/xdebug.h> ! 20: * __LOCAL__ ! 21: * <common/__types.h> ! 22: * __uchar_t ! 23: * __ushort_t ! 24: * __ulong_t ! 25: */ ! 26: ! 27: #include <common/ccompat.h> ! 28: #include <common/xdebug.h> ! 29: #include <common/__types.h> ! 30: ! 31: ! 32: /* ! 33: * Get these into a useful form in a similar manner to the way the spl... () ! 34: * functions are defined in <sys/inline.h> ! 35: */ ! 36: ! 37: #if __GNUC__ && (defined (i386) || _I386) /* 80386 with GNU CC */ ! 38: ! 39: /* ! 40: * The Coherent 'as' assembler is a little stupid about which instruction ! 41: * forms it will accept. ! 42: */ ! 43: ! 44: # define __GAS_OR_AS(g,a) g ! 45: ! 46: ! 47: /* ! 48: * Note that the definitions for the string-input instructions assume that ! 49: * ES: is equivalent to DS:. ! 50: */ ! 51: ! 52: __LOCAL__ __INLINE__ __uchar_t __inb (int _port) { ! 53: __uchar_t _result; ! 54: __NON_ISO (asm) volatile (__GAS_OR_AS ("in %1,%0", "inb (%1)") : ! 55: "=a" (_result) : "d" ((__ushort_t) _port)); ! 56: return _result; ! 57: } ! 58: ! 59: __LOCAL__ __INLINE__ __ulong_t __inl (int _port) { ! 60: __ulong_t _result; ! 61: __NON_ISO (asm) volatile (__GAS_OR_AS ("in %1,%0", "inl (%1)") : ! 62: "=a" (_result) : "d" ((__ushort_t) _port)); ! 63: return _result; ! 64: } ! 65: ! 66: __LOCAL__ __INLINE__ __ushort_t __inw (int _port) { ! 67: __ushort_t _result; ! 68: __NON_ISO (asm) volatile (__GAS_OR_AS ("in %1,%0", "inw (%1)") : ! 69: "=a" (_result) : "d" ((__ushort_t) _port)); ! 70: return _result; ! 71: } ! 72: ! 73: __LOCAL__ __INLINE__ void __outb (int _port, __uchar_t value) { ! 74: __NON_ISO (asm) volatile (__GAS_OR_AS ("out %1,%0", "outb (%0)") : : ! 75: "d" ((__ushort_t) _port), "a" (value)); ! 76: } ! 77: ! 78: __LOCAL__ __INLINE__ void __outl (int _port, __ulong_t value) { ! 79: __NON_ISO (asm) volatile (__GAS_OR_AS ("out %1,%0", "outl (%0)") : : ! 80: "d" ((__ushort_t) _port), "a" (value)); ! 81: } ! 82: ! 83: __LOCAL__ __INLINE__ void __outw (int _port, __ushort_t value) { ! 84: __NON_ISO (asm) volatile (__GAS_OR_AS ("out %1,%0", "outw (%0)") : : ! 85: "d" ((__ushort_t) _port), "a" (value)); ! 86: } ! 87: ! 88: __LOCAL__ __INLINE__ ! 89: void __repinsb (int _port, __uchar_t * _addr, int _cnt) { ! 90: __NON_ISO (asm) volatile ("mov %1,%%edi;rep;insb" : : ! 91: "d" ((__ushort_t) _port), "g" (_addr), ! 92: "c" (_cnt) : "di"); ! 93: } ! 94: ! 95: __LOCAL__ __INLINE__ ! 96: void __repinsd (int _port, __ulong_t * _addr, int _cnt) { ! 97: __NON_ISO (asm) volatile ("mov %1,%%edi;rep;insl" : : ! 98: "d" ((__ushort_t) _port), "g" (_addr), ! 99: "c" (_cnt) : "di"); ! 100: } ! 101: ! 102: __LOCAL__ __INLINE__ ! 103: void __repinsw (int _port, __ushort_t * _addr, int _cnt) { ! 104: __NON_ISO (asm) volatile ("mov %1,%%edi;rep;insw" : : ! 105: "d" ((__ushort_t) _port), "g" (_addr), ! 106: "c" (_cnt) : "di"); ! 107: } ! 108: ! 109: __LOCAL__ __INLINE__ ! 110: void __repoutsb (int _port, __uchar_t * _addr, int _cnt) { ! 111: __NON_ISO (asm) volatile ("mov %1,%%esi;rep;outsb" : : ! 112: "d" ((__ushort_t) _port), "g" (_addr), ! 113: "c" (_cnt) : "si"); ! 114: } ! 115: ! 116: __LOCAL__ __INLINE__ ! 117: void __repoutsd (int _port, __ulong_t * _addr, int _cnt) { ! 118: __NON_ISO (asm) volatile ("movl %1,%%esi;rep;outsl" : : ! 119: "d" ((__ushort_t) _port), "g" (_addr), ! 120: "c" (_cnt) : "si"); ! 121: } ! 122: ! 123: __LOCAL__ __INLINE__ ! 124: void __repoutsw (int _port, __ushort_t * _addr, int _cnt) { ! 125: __NON_ISO (asm) volatile ("movl %1,%%esi;rep;outsw" : : ! 126: "d" ((__ushort_t) _port), "g" (_addr), ! 127: "c" (_cnt) : "si"); ! 128: } ! 129: ! 130: #define __FORWARD_inb__ ! 131: #define __FORWARD_inl__ ! 132: #define __FORWARD_inw__ ! 133: #define __FORWARD_outb__ ! 134: #define __FORWARD_outl__ ! 135: #define __FORWARD_outw__ ! 136: #define __FORWARD_repinsb__ ! 137: #define __FORWARD_repinsd__ ! 138: #define __FORWARD_repinsw__ ! 139: #define __FORWARD_repoutsb__ ! 140: #define __FORWARD_repoutsd__ ! 141: #define __FORWARD_repoutsw__ ! 142: ! 143: #elif __BORLANDC__ ! 144: ! 145: void __emit__ (unsigned char __byte, ...); ! 146: ! 147: /* ! 148: * Note the use of the 0x66 operand-size override prefix below, which is built ! 149: * on the assumption that Borland generates 16-bit code segments. ! 150: */ ! 151: ! 152: #define __REP__ 0xF3 /* repeat-prefix */ ! 153: ! 154: #define __INB__ 0xEC ! 155: #define __INW__ 0xED ! 156: #define __INL__ 0x66, __INW__ /* size-override for 32-bit form */ ! 157: ! 158: #define __OUTB__ 0xEE ! 159: #define __OUTW__ 0xEF ! 160: #define __OUTL__ 0x66, __OUTW__ /* size-override for 32-bit form */ ! 161: ! 162: #define __INSB__ 0x6C ! 163: #define __INSW__ 0x6D ! 164: #define __INSL__ 0x65, __INSW__ ! 165: ! 166: #define __OUTSB__ 0x6E ! 167: #define __OUTSW__ 0x6F /* word/long depending on CS: */ ! 168: #define __OUTSL__ 0x66, __OUTSW__ ! 169: ! 170: ! 171: /* ! 172: * If we are willing to restrict ourselves to i386's, Borland C++ 3.1 allows ! 173: * support for 32-bit register-pseudovariables if 386 code generation has ! 174: * been enabled. ! 175: * ! 176: * As it turns out, there are all kinds of bugs in the 386 support in BC++ 3.1 ! 177: * but enough works that we can even get a far pointer into ES:whatever via ! 178: * a 32-bit register, as long as the intermediate register isn't _ESI or _EDI ! 179: * since _EAX = _ESI or _EAX = _EDI only moves the low 16 bits. Being able to ! 180: * load ES:whatever via a 32-bit register allows us to write macros that only ! 181: * reference each argument exactly once. ! 182: * ! 183: * While the 32-bit-pointer version still works in the near models, it's not ! 184: * exactly optimal, so we use a more straightforward version there. ! 185: */ ! 186: ! 187: #define __inb(port) (_DX = (port), __emit__ (__INB__),\ ! 188: (__uchar_t) _AL) ! 189: #define __inl(port) (_DX = (port), __emit__ (__INL__), _EAX) ! 190: #define __inw(port) (_DX = (port), __emit__ (__INW__), \ ! 191: (__ushort_t) _AX) ! 192: ! 193: #define __outb(port,value) (_DX = (port), _AL = (value), \ ! 194: __emit__ (__OUTB__)) ! 195: #define __outl(port,value) (_DX = (port), _EAX = (value), \ ! 196: __emit__ (__OUTL__)) ! 197: #define __outw(port,value) (_DX = (port), _AX = (value), \ ! 198: __emit__ (__OUTW__)) ! 199: ! 200: #if defined (__LARGE__) || defined (__HUGE__) || defined (__COMPACT__) ! 201: ! 202: #define __repins(p,a,c) (_EDX = (long) (void __far *) (a), _EAX = _EDX,\ ! 203: _ES = (unsigned) (_EAX >> 16),\ ! 204: _DI = _DX, _CX = (c), _DX = (p)) ! 205: #define __repouts(p,a,c) (_EDX = (long) (void _far *) (a), _EAX = _EDX,\ ! 206: _ES = (unsigned) (_EAX >> 16),\ ! 207: _SI = _DX, _CX = (c), _DX = (p)) ! 208: ! 209: #else /* use simpler small-data versions */ ! 210: ! 211: #define __repins(p,a,c) (_ES = _DS, _DI = (unsigned) (a), \ ! 212: _CX = (c), _DX = (p)) ! 213: #define __repouts(p,a,c) (_ES = _DS, _SI = (unsigned) (a), \ ! 214: _CX = (c), _DX = (p)) ! 215: ! 216: #endif ! 217: ! 218: #define __repinsb(p,a,c) (__repins (p, a, c),\ ! 219: __emit__ (__REP__, __INSB__)) ! 220: #define __repinsd(p,a,c) (__repins (p, a, c),\ ! 221: __emit__ (__REP__, __INSL__)) ! 222: #define __repinsw(p,a,c) (__repins (p, a, c),\ ! 223: __emit__ (__REP__, __INSW__)) ! 224: ! 225: #define __repoutsb(p,a,c) (__repouts (p, a, c),\ ! 226: __emit__ (__REP__, __OUTSB__)) ! 227: #define __repoutsd(p,a,c) (__repouts (p, a, c),\ ! 228: __emit__ (__REP__, __OUTSL__)) ! 229: #define __repoutsw(p,a,c) (__repouts (p, a, c),\ ! 230: __emit__ (__REP__, __OUTSW__)) ! 231: ! 232: ! 233: #define __FORWARD_inb__ ! 234: #define __FORWARD_inl__ ! 235: #define __FORWARD_inw__ ! 236: #define __FORWARD_outb__ ! 237: #define __FORWARD_outl__ ! 238: #define __FORWARD_outw__ ! 239: #define __FORWARD_repinsb__ ! 240: #define __FORWARD_repinsd__ ! 241: #define __FORWARD_repinsw__ ! 242: #define __FORWARD_repoutsb__ ! 243: #define __FORWARD_repoutsd__ ! 244: #define __FORWARD_repoutsw__ ! 245: ! 246: #elif __COHERENT__ ! 247: ! 248: /* ! 249: * Under Coherent, the inb ()/inw ()/inl () and outb ()/outw ()/outl () ! 250: * operations are already available under those names in the standard system. ! 251: * ! 252: * The rep... () operations are provided in a supplemental file that should be ! 253: * linked in if you are building a DDI/DKI kernel. ! 254: */ ! 255: ! 256: #endif ! 257: ! 258: ! 259: __EXTERN_C_BEGIN__ ! 260: ! 261: __uchar_t inb __PROTO ((int _port)); ! 262: __ulong_t inl __PROTO ((int _port)); ! 263: __ushort_t inw __PROTO ((int _port)); ! 264: void outb __PROTO ((int _port, __uchar_t _value)); ! 265: void outl __PROTO ((int _port, __ulong_t _value)); ! 266: void outw __PROTO ((int _port, __ushort_t _value)); ! 267: void repinsb __PROTO ((int _port, __uchar_t * _addr, ! 268: int _cnt)); ! 269: void repinsd __PROTO ((int _port, __ulong_t * _addr, ! 270: int _cnt)); ! 271: void repinsw __PROTO ((int _port, __ushort_t * _addr, ! 272: int _cnt)); ! 273: void repoutsb __PROTO ((int _port, __uchar_t * _addr, ! 274: int _cnt)); ! 275: void repoutsd __PROTO ((int _port, __ulong_t * _addr, ! 276: int _cnt)); ! 277: void repoutsw __PROTO ((int _port, __ushort_t * _addr, ! 278: int _cnt)); ! 279: ! 280: __EXTERN_C_END__ ! 281: ! 282: ! 283: #ifdef __FORWARD_inb__ ! 284: # define inb(port) __inb (port) ! 285: #endif ! 286: ! 287: #ifdef __FORWARD_inl__ ! 288: # define inl(port) __inl (port) ! 289: #endif ! 290: ! 291: #ifdef __FORWARD_inw__ ! 292: # define inw(port) __inw (port) ! 293: #endif ! 294: ! 295: #ifdef __FORWARD_outb__ ! 296: # define outb(port,val) __outb (port, val) ! 297: #endif ! 298: ! 299: #ifdef __FORWARD_outl__ ! 300: # define outl(port,val) __outl (port, val) ! 301: #endif ! 302: ! 303: #ifdef __FORWARD_outw__ ! 304: # define outw(port,val) __outw (port, val) ! 305: #endif ! 306: ! 307: #ifdef __FORWARD_repinsb__ ! 308: # define repinsb(p,a,c) __repinsb (p, a, c) ! 309: #endif ! 310: ! 311: #ifdef __FORWARD_repinsd__ ! 312: # define repinsd(p,a,c) __repinsd (p, a, c) ! 313: #endif ! 314: ! 315: #ifdef __FORWARD_repinsw__ ! 316: # define repinsw(p,a,c) __repinsw (p, a, c) ! 317: #endif ! 318: ! 319: #ifdef __FORWARD_repoutsb__ ! 320: # define repoutsb(p,a,c) __repoutsb (p, a, c) ! 321: #endif ! 322: ! 323: #ifdef __FORWARD_repoutsd__ ! 324: # define repoutsd(p,a,c) __repoutsd (p, a, c) ! 325: #endif ! 326: ! 327: #ifdef __FORWARD_repoutsw__ ! 328: # define repoutsw(p,a,c) __repoutsw (p, a, c) ! 329: #endif ! 330: ! 331: ! 332: #undef __FORWARD_inb__ ! 333: #undef __FORWARD_inl__ ! 334: #undef __FORWARD_inw__ ! 335: #undef __FORWARD_outb__ ! 336: #undef __FORWARD_outl__ ! 337: #undef __FORWARD_outw__ ! 338: #undef __FORWARD_repinsb__ ! 339: #undef __FORWARD_repinsd__ ! 340: #undef __FORWARD_repinsw__ ! 341: #undef __FORWARD_repoutsb__ ! 342: #undef __FORWARD_repoutsd__ ! 343: #undef __FORWARD_repoutsw__ ! 344: ! 345: #endif /* ! defined (__KERNEL_X86IO_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.