|
|
1.1 root 1: #ifndef __SYS_INLINE_H__
2: #define __SYS_INLINE_H__
3:
4: /*
5: * This header file exists for compatibility with the System V DDI/DKI.
6: * This header defines some routines which are commonly kept inlined for
7: * efficiency reasons (although under the full DDI/DKI regime they are not
8: * in fact inlined).
9: */
10:
11: /*
12: *-IMPORTS:
13: * <common/ccompat.h>
14: * __PROTO ()
15: * __EXTERN_C_BEGIN__
16: * __EXTERN_C_END__
17: * __NON_ISO ()
18: * <common/xdebug.h>
19: * __LOCAL__
20: * <kernel/__pl.h>
21: * __pl_t
22: * <kernel/ddi_cpu.h>
23: * intmask_t
24: */
25:
26: #include <common/ccompat.h>
27: #include <common/xdebug.h>
28: #include <kernel/__pl.h>
29: #include <kernel/ddi_cpu.h>
30: #include <kernel/x86io.h>
31:
32:
33: /*
34: * This header is made a little more complex by the fact that we want to
35: * be able to support inlining for those compilers that can do it, yet we
36: * also need to be able to use the #include <sys/ddi.h> mechanism to force
37: * all of these to be bound to regular C functions.
38: *
39: * In order to support this, the initial compiler-dependent part of the
40: * file performs feature tests and sets a __FORWARD_x__ macro for those
41: * definitions that are to be "forwarded" via macro to a version whose name
42: * has some additional leading underscores prepended.
43: *
44: * In this way, for systems that have inlining the #include <sys/ddi.h> will
45: * suppress the forwarding.
46: */
47:
48: /*
49: * Perform feature tests to try and work out how the processor priority
50: * level can be manipulated under this machine/compiler.
51: */
52:
53: /*
54: * The 80x86 processor and the IBM PC have numerous design misfeatures when
55: * it comes to the way interrupt priority works. Some are the result of using
56: * external hardware to deal with interrupt priority level (not in itself a
57: * big deal, but the 8259A on the PC ISA-bus is a problem). Others are a
58: * result of the modality of the various processors in the 80x86 family and
59: * the fact that none of them can emulate the others very well, by design.
60: *
61: * The key features are that the sti/cli instructions used in the CPU to mask
62: * all interrupts are simply too coarse for regular use, plus the fact that
63: * certain instructions which manipulate the processor priority at some
64: * privelege levels may trap (or worse, simply do nothing) at others, meaning
65: * branches and tests are required for reliable operation.
66: *
67: * Programming the 8259A interrupt controller directly gives the necessary
68: * granularity (but may cause problems due to bus issues) and allows the
69: * hard-wired priority levels to be redefined by software.
70: */
71:
72:
73: #if defined (__GNUC__) && defined (i386) /* 80386 running GCC */
74:
75: #define __IBM_PC__
76: #define __PICC__ 0x20
77: #define __PICM__ 0x21
78: #define __SPICC__ 0xA0
79: #define __SPICM__ 0xA1
80:
81: #define __EOI_CMD__ 0x20
82:
83: extern intmask_t _masktab [];
84:
85: __LOCAL__ __INLINE__ void __CHEAP_DISABLE_INTS (void) {
86: __NON_ISO (asm) ("cli");
87: }
88:
89: __LOCAL__ __INLINE__ void __CHEAP_ENABLE_INTS (void) {
90: __NON_ISO (asm) ("sti");
91: }
92:
93: __LOCAL__ __INLINE__ void __OUT_IPL_MASK (intmask_t _mask) {
94: outb (__PICM__, _mask);
95: outb (__SPICM__, _mask >> 8);
96: }
97:
98: __LOCAL__ __INLINE__ intmask_t __GET_BASE_MASK (void) {
99: return ddi_cpu_data ()->dc_base_mask;
100: }
101:
102: __LOCAL__ __INLINE__ void __SET_BASE_MASK (intmask_t _mask) {
103: __OUT_IPL_MASK (ddi_cpu_data ()->dc_base_mask = _mask);
104: }
105:
106: __LOCAL__ __INLINE__ void __SEND_EOI (int _vector) {
107: outb (__PICC__, __EOI_CMD__);
108:
109: if (_vector >= 8)
110: outb (__SPICC__, __EOI_CMD__);
111: }
112:
113: #define __FORWARD_splx__
114: #define __FORWARD_splraise__
115:
116:
117: #elif __BORLANDC__
118:
119:
120: #define __IBM_PC__
121: #define __PICC__ 0x20
122: #define __PICM__ 0x21
123: #define __SPICC__ 0xA0
124: #define __SPICM__ 0xA1
125:
126: #define __EOI_CMD__ 0x20
127:
128: void __emit__ (unsigned char _byte, ...);
129:
130: #define __CLI__ 0xFB
131: #define __STI__ 0xFA
132:
133: extern intmask_t _masktab [];
134:
135: #define __CHEAP_DISABLE_INTS() __emit__ (__CLI__)
136: #define __CHEAP_ENABLE_INTS() __emit__ (__STI__)
137:
138: #define __OUT_IPL_MASK(mask) \
139: (void) (outb (__PICM__, mask), \
140: outb (__SPICM__, mask >> 8))
141:
142: #define __GET_BASE_MASK()\
143: (const intmask_t) (ddi_cpu_data ()->dc_base_mask)
144: #define __SET_BASE_MASK(mask)\
145: (void) (ddi_cpu_data ()->dc_base_mask = (mask), \
146: __OUT_IPL_MASK (ddi_cpu_data ()->dc_base_mask))
147:
148: #define __SEND_EOI(vector) \
149: (outb (__PICC__, __EOI_CMD__), (vector < 8 ? (void) 0 : \
150: outb (__SPICC__, __EOI_CMD__)))
151:
152: /*
153: * Since BC++ 3.1 has outlawed inline functions in C code, to the point of
154: * not even providing an __inline__ keyword, we can only provide in-line
155: * definitions for splx () and splraise () under C++
156: */
157:
158: #ifdef __cplusplus
159:
160: #define __FORWARD_splx__
161: #define __FORWARD_splraise__
162:
163: #endif
164:
165:
166: #elif __COHERENT__
167:
168:
169: /*
170: * Coherent's C compiler has no extensions.
171: */
172:
173: #define __IBM_PC__
174: #define __PICC__ 0x20
175: #define __PICM__ 0x21
176: #define __SPICC__ 0xA0
177: #define __SPICM__ 0xA1
178:
179: #define __EOI_CMD__ 0x20
180:
181:
182: extern intmask_t _masktab [];
183:
184:
185: #define __GET_BASE_MASK()\
186: (const intmask_t) (ddi_cpu_data ()->dc_base_mask)
187:
188: __EXTERN_C_BEGIN__
189:
190: void __CHEAP_DISABLE_INTS __PROTO ((void));
191: void __CHEAP_ENABLE_INTS __PROTO ((void));
192: void __SET_BASE_MASK __PROTO ((intmask_t _newmask));
193:
194: __EXTERN_C_END__
195:
196: #endif /* ! __COHERENT__ */
197:
198:
199: /*
200: * Generic stuff for the 80x86 IBM PC interrupt architecture.
201: */
202:
203: #ifdef __IBM_PC__
204:
205: #ifdef __FORWARD_splx__
206:
207: __LOCAL__ __INLINE__ __pl_t __splx (__pl_t _newpl) {
208: __pl_t _prev_pl;
209: intmask_t _mask = __GET_BASE_MASK () | _masktab [_newpl];
210:
211: __OUT_IPL_MASK (mask);
212:
213: _prev_pl = (__pl_t) ddi_cpu_data ()->dc_ipl;
214: ddi_cpu_data ()->dc_ipl = _newpl;
215:
216: return _prev_pl;
217: }
218:
219: #endif
220:
221: #ifdef __FORWARD_splraise__
222:
223: __LOCAL__ __INLINE__ __pl_t __splraise (__pl_t _newpl) {
224: __pl_t _prev_pl;
225:
226: if (_newpl > (_prev_pl = (__pl_t) ddi_cpu_data ()->dc_ipl)) {
227: intmask_t _mask = __GET_BASE_MASK () |
228: _masktab [_newpl];
229:
230: __OUT_IPL_MASK (mask);
231: ddi_cpu_data ()->dc_ipl = _newpl;
232: }
233:
234: return _prev_pl;
235: }
236:
237: #endif
238:
239:
240: #define __splbase() splx (plbase)
241: #define __spltimeout() splx (pltimeout)
242: #define __spldisk() splx (pldisk)
243: #define __splstr() splx (plbase)
244: #define __splhi() splx (plhi)
245:
246: #define __FORWARD_splbase__
247: #define __FORWARD_spltimeout__
248: #define __FORWARD_spldisk__
249: #define __FORWARD_splstr__
250: #define __FORWARD_splhi__
251:
252: #endif
253:
254:
255: /*
256: * Function versions of these are available by including <sys/ddi.h> or by
257: * using a compiler setup that does not permit inlining. The actual function
258: * prototypes always live here, <sys/ddi.h> merely knows how to #undef some
259: * names.
260: */
261:
262: __EXTERN_C_BEGIN__
263:
264: __pl_t splbase __PROTO ((void)); /* enabled */
265: __pl_t spltimeout __PROTO ((void)); /* timeouts */
266: __pl_t spldisk __PROTO ((void)); /* disk I/O */
267: __pl_t splstr __PROTO ((void)); /* STREAMS */
268: __pl_t splhi __PROTO ((void)); /* disabled */
269: __pl_t splx __PROTO ((__pl_t _pl)); /* restore */
270:
271: /* Internal functions - not part of DDI/DKI interface */
272:
273: int splcmp __PROTO ((__pl_t _l, __pl_t _r));
274: /* compare */
275: __pl_t splraise __PROTO ((__pl_t _pl)); /* raise priority */
276:
277: __EXTERN_C_END__
278:
279:
280: /*
281: * Define forwarding macros for those functions that need them.
282: *
283: * Note that the form of these definitions is such that they can be
284: * suppressed by enclosing the name in parentheses. Simply defining a
285: * token mapping is not a good idea for functions.
286: */
287:
288: #ifdef __FORWARD_splbase__
289: # define splbase() __splbase ()
290: #endif
291:
292: #ifdef __FORWARD_spltimeout__
293: # define spltimeout() __spltimeout ()
294: #endif
295:
296: #ifdef __FORWARD_spldisk__
297: # define spldisk() __spldisk ()
298: #endif
299:
300: #ifdef __FORWARD_splstr__
301: # define splstr() __splstr ()
302: #endif
303:
304: #ifdef __FORWARD_splhi__
305: # define splhi() __splhi ()
306: #endif
307:
308: #ifdef __FORWARD_splx__
309: # define splx(x) __splx (x)
310: #endif
311:
312: #ifdef __FORWARD_splcmp__
313: # define splcmp(l,r) __splcmp (l,r)
314: #endif
315:
316: #ifdef __FORWARD_splraise__
317: # define splraise(x) __splraise(x)
318: #endif
319:
320:
321: /*
322: * Clean up the macros we #define
323: */
324:
325: #undef __IBM_PC__
326: #undef __FORWARD_splbase__
327: #undef __FORWARD_spltimeout__
328: #undef __FORWARD_spldisk__
329: #undef __FORWARD_splstr__
330: #undef __FORWARD_splhi__
331: #undef __FORWARD_splx__
332: #undef __FORWARD_splcmp__
333: #undef __FORWARD_splraise__
334:
335:
336: #endif /* ! defined (__SYS_INLINE_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.