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