|
|
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.