|
|
1.1 root 1: /*
2: * This file contains the entry points into the STREAMS system called by the
3: * Coherent kernel.
4: */
5:
6: #define _DDI_DKI 1
7: #define _SYSV3 1
8:
9: #include <kernel/ddi_cpu.h>
10: #include <kernel/ddi_glob.h>
11: #include <kernel/confinfo.h>
12: #include <sys/types.h>
13: #include <sys/cmn_err.h>
14: #include <stdlib.h>
15:
16: #ifdef __MSDOS__
17: #include <sys/_con.h>
18: #else
19: #include <sys/con.h>
20: #endif
21:
22:
23: /*
24: * Refer to memory allocated by "space.c" file from tunable parameters.
25: */
26:
27: extern size_t _streams_size;
28: extern uchar_t _streams_heap [];
29:
30:
31: __EXTERN_C_BEGIN__
32:
33: int INTR_INIT __PROTO ((void));
34: int DDI_INIT __PROTO ((void));
35: int STRMEM_INIT __PROTO ((_VOID * _addr, size_t _size));
36: int LOCK_TESTS __PROTO ((int _negative));
37:
38: __EXTERN_C_END__
39:
40:
41: #if __BORLANDC__
42:
43: void SETIVEC __PROTO ((int _num));
44: void CLRIVEC __PROTO ((int _num));
45:
46: #else __COHERENT__
47:
48: #define SETIVEC(num) setivec (inttab [num].int_vector, \
49: inttab [num].int_thunk)
50:
51: #define CLRIVEC(num) clrivec (inttab [num].int_vector)
52:
53: #endif /* __COHERENT__ */
54:
55:
56: /*
57: * Global start/exit state. We use this so that if an exit or halt routine
58: * panics (which may cause a retry of the shutdown process) we can try again.
59: */
60:
61: static int _exitlevel;
62: static int _intlevel;
63: static int _haltlevel;
64:
65:
66: /*
67: * Since we don't have a real trap-handler, I have factored out the deferred-
68: * function check to here.
69: *
70: * Entered with interrupts disabled. This routine must be able to enable
71: * interrupts without causing excess stack growth. Note that if we have
72: * interrupt prologue and epilogue code in assembly language, a rather
73: * different loop structure might work out simpler.
74: */
75:
76: #if __USE_PROTO__
77: __LOCAL__ int (RUN_INT_DEFER) (defer_t * deferp)
78: #else
79: __LOCAL__ int
80: RUN_INT_DEFER __ARGS ((deferp))
81: defer_t * deferp;
82: #endif
83: {
84: int recheck = 0;
85: int idx;
86:
87: /*
88: * If we detected a non-empty global defer table, try and lock the
89: * table before processing the deferred routines. Only try once; if
90: * the table is busy, then someone else must be dealing with it.
91: */
92:
93: if (ATOMIC_FETCH_AND_STORE_UCHAR (deferp->df_rlock, 1) != 0)
94: return 1;
95:
96: while ((idx = ATOMIC_FETCH_UCHAR (deferp->df_read)) !=
97: ATOMIC_FETCH_UCHAR (deferp->df_write)) {
98: __CHEAP_ENABLE_INTS ();
99:
100: (* deferp->df_tab [idx ++]) ();
101:
102: if (idx == ATOMIC_FETCH_UCHAR (deferp->df_max))
103: idx = 0;
104:
105: ATOMIC_STORE_UCHAR (deferp->df_read, idx);
106:
107: recheck = 1;
108:
109: __CHEAP_DISABLE_INTS ();
110: }
111:
112: /*
113: * Release the lock on the global defer table.
114: */
115:
116: ATOMIC_STORE_UCHAR (deferp->df_rlock, 0);
117:
118: return recheck;
119: }
120:
121: #ifdef __MSDOS__
122:
123: #include <dos.h>
124:
125: void CHECK_DEFER (void) {
126: while (RUN_INT_DEFER (& ddi_global_data ()->dg_defint) ||
127: RUN_INT_DEFER (& ddi_cpu_data ()->dc_defint))
128: (* (char __far *) MK_FP (0xB800, 6)) ++;
129:
130: /*
131: * For breaking out of bad situations... hold right shift.
132: */
133:
134: if ((* (char __far *) MK_FP (0x40, 0x17) & 1) != 0)
135: cmn_err (CE_PANIC, "Emergency abort!");
136:
137: }
138: #endif
139:
140: #ifdef __COHERENT__
141:
142: #if __USE_PROTO__
143: void (STREAMS_SCHEDULER) (void)
144: #else
145: void
146: STREAMS_SCHEDULER __ARGS (())
147: #endif
148: {
149: __CHEAP_DISABLE_INTS ();
150:
151: while (RUN_INT_DEFER (& ddi_global_data ()->dg_defint) ||
152: RUN_INT_DEFER (& ddi_cpu_data ()->dc_defint))
153: ; /* DO NOTHING */
154:
155: __CHEAP_ENABLE_INTS ();
156: }
157: #endif /* ! defined (__COHERENT__) */
158:
159:
160: /*
161: * Shut things down, in the right order.
162: */
163:
164: #if __USE_PROTO__
165: void (STREAMS_EXIT) (void)
166: #else
167: void
168: STREAMS_EXIT __ARGS (())
169: #endif
170: {
171: spltimeout ();
172: ddi_cpu_data ()->dc_int_level = 0;
173:
174: while (_exitlevel > 0)
175: (* exittab [-- _exitlevel]) ();
176:
177: /*
178: * Turn off interrupts.
179: */
180:
181: while (_intlevel > 0)
182: CLRIVEC (-- _intlevel);
183:
184: while (_haltlevel > 0)
185: (* halttab [-- _haltlevel]) ();
186: }
187:
188:
189: /*
190: * Get an old Coherent "CON" entry.
191: */
192:
193: #if __USE_PROTO__
194: CON * (STREAMS_GETCON) (o_dev_t dev)
195: #else
196: CON *
197: STREAMS_GETCON __ARGS ((dev))
198: o_dev_t dev;
199: #endif
200: {
201: int omajor = (dev >> 8) & 0xFF;
202:
203: return (omajor > _maxmajor || _major [omajor] == NODEV) ? NULL :
204: & cdevsw [_major [omajor]].cdev_con;
205: }
206:
207:
208: /*
209: * Start things up, in the right order. If we can't proceed, panic.
210: */
211:
212: #if __USE_PROTO__
213: void (STREAMS_INIT) (void)
214: #else
215: void
216: STREAMS_INIT __ARGS (())
217: #endif
218: {
219: int i;
220:
221: /*
222: * We call upon INTR_INIT () to ensure that we can call spl... ()
223: * functions safely. For some environments, this needs to take note of
224: * the existing interrupt masks.
225: */
226:
227: while (INTR_INIT ())
228: cmn_err (CE_PANIC, "Initial DDI/DKI setup failed");
229:
230: #ifdef __MSDOS__
231: /*
232: * Arrange for the exit routines to be called eventually.
233: */
234:
235: atexit (STREAMS_EXIT);
236: #endif
237:
238: /*
239: * Bootstrap the heap allocator. The allocation routines may need
240: * locking (which needs an allocator), but we depend on STRMEM_INIT ()
241: * to deal with that.
242: */
243:
244: while (STRMEM_INIT (_streams_heap, _streams_size) != 0)
245: cmn_err (CE_PANIC, "Unable to initalise STREAMS heap");
246:
247: /*
248: * Other global initialization which can proceed now we have an
249: * allocation system active.
250: */
251:
252: while (DDI_INIT ())
253: cmn_err (CE_PANIC, "Unable to set up DDI/DKI global data");
254:
255: /*
256: * After the defer tables have been set up, we can call LOCK_TESTS (),
257: * which we couldn't before because the ..._DEALLOC () calls that the
258: * tests perform at the end require defer-table support.
259: */
260:
261: if (LOCK_TESTS (0))
262: cmn_err (CE_PANIC, "Lock primitives not functional");
263:
264: /*
265: * Call the configured init routines for the system. According to the
266: * specification of init (D2DK), this happens before interrupts are
267: * enabled and before there is any real process context for us to
268: * be able to sleep.
269: */
270:
271: for (i = 0 ; i < ninit ; i ++)
272: (* inittab [i]) ();
273:
274: _exitlevel = nexit;
275:
276:
277: /*
278: * Now we can configure the interrupts for the system.
279: */
280:
281: for (_intlevel = 0 ; _intlevel < nintr ; _intlevel ++)
282: SETIVEC (_intlevel);
283:
284: splbase ();
285:
286:
287: /*
288: * And finally, we can call the start routines.
289: */
290:
291: for (i = 0 ; i < nstart ; i ++)
292: (* starttab [i]) ();
293:
294: }
295:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.