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