intArchLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:41k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* intArchLib.c - architecture-dependent interrupt library */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 02v,05jun02,wsl  remove reference to SPARC and i960
  7. 02u,09may02,wsl  fix minor formatting error
  8. 02t,20nov01,hdn  updated x86 specific sections
  9. 02s,13nov01,hbh  Updated for simulators.
  10. 02r,30oct01,zl   corrected table in SH section of intConnect().
  11. 02q,02oct01,hdn  added intStackEnable() for PENTIUM (spr 69832: int stack)
  12. 02p,14sep01,hdn  added intHandlerCreateI86()/intVec[SG]et2() doc (spr 30292)
  13. 02o,19feb01,hk   update intConnect()/intVecBaseSet()/intVecSet() docs for T2/SH.
  14. 02n,03mar00,zl   merged SH support into T2
  15. 02m,16mar99,elg  add information about conversion macros (SPR 7473).
  16. 02l,12mar99,elg  delete the SEE ALSO comment in intLevelSet() (SPR 22809).
  17. 02k,11feb99,wsl  add comment documenting ERRNO value
  18. 02j,05oct98,jmp  doc: added {...} when necessary.
  19. 02i,21apr98,jpd  updated ARM-specific documentation.
  20. 02h,08jul97,dgp  doc: add info about PowerPC to intLock() (SPR 7768)
  21. 02h,03mar97,jpd  added ARM-specific documentation.
  22. 02g,09dec96,dgp  doc: fix SPR #7580 (add INCLUDE FILE: intLib.h) and change
  23.       MIPS R3000/R4000 to MIPS
  24. 02f,14nov96,dgp  doc: specify MIPS and PPC support for specific routines
  25. 02e,30oct96,dgp  doc: intHandlerCreate() does not exist in PowerPC per 
  26.  SPR 5851
  27. 02d,25nov95,jdi  removed 29k stuff.
  28. 02c,06feb95,rhp  add AM29K note to intHandlerCreate() man page.
  29.             jdi  changed 80960 to i960.
  30. 02b,26jan95,rhp  doc: included i386/i486 info, R4000 info, and misc doc tweaks
  31. 02a,12jan95,rhp  propagated no-syscall caveat to intLevelSet doc (SPR#1094);
  32.                  added refs to intLock() and taskLock() to SEE ALSO line 
  33.                  for intLockLevelSet(), and second example to intLock() man page
  34.                  (SPR#1304).
  35. 01d,18apr94,pme  added Am29K specific information to intLevelSet()
  36.                  fixed intVecGet() manual for Am29200 and Am29030.
  37. 01c,07dec93,pme  doc tweaks.
  38.  added Am29K family support.
  39. 01h,22sep94,rhp  Restore paragraph break accidentally deleted with previous fix.
  40. 01g,22sep94,rhp  fix SPARC-specific intVecSet() description (SPR#2513).
  41. 01f,20sep94,rhp  propagate new SPARC info for intVecBaseSet()
  42. 01e,20sep94,rhp  propagate new SPARC info for intVecSet(); '94 copyright
  43. 01d,19sep94,rhp  do not mention exceptions in intArchLib man page (SPR#1494).
  44. 01c,16sep94,rhp  add caveats re avoiding system calls under intLock (SPR#3582).
  45. 01b,20jan93,jdi  documentation cleanup.
  46. 01a,23sep92,jdi  written, based on intALib.s and intArchLib.c for
  47.  mc68k, sparc, i960, mips.
  48. */
  49. /*
  50. DESCRIPTION
  51. This library provides architecture-dependent routines to manipulate
  52. and connect to hardware interrupts.  Any C language routine can be
  53. connected to any interrupt by calling intConnect().  Vectors can be
  54. accessed directly by intVecSet() and intVecGet().  The vector (trap)
  55. base register (if present) can be accessed by the routines
  56. intVecBaseSet() and intVecBaseGet().
  57. Tasks can lock and unlock interrupts by calling intLock() and intUnlock().
  58. The lock-out level can be set and reported by intLockLevelSet() and
  59. intLockLevelGet() (MC680x0, x86, ARM and SH only).
  60. The routine intLevelSet() changes the current interrupt level of the
  61. processor (MC680x0, ARM, SimSolaris and SH).
  62. WARNING
  63. Do not call VxWorks system routines with interrupts locked.
  64. Violating this rule may re-enable interrupts unpredictably.
  65. INTERRUPT VECTORS AND NUMBERS
  66. Most of the routines in this library take an interrupt vector as a
  67. parameter, which is generally the byte offset into the vector table.
  68. Macros are provided to convert between interrupt vectors and interrupt
  69. numbers:
  70. .iP IVEC_TO_INUM(intVector) 10
  71. converts a vector to a number.
  72. .iP INUM_TO_IVEC(intNumber)
  73. converts a number to a vector.
  74. .iP TRAPNUM_TO_IVEC(trapNumber)
  75. converts a trap number to a vector.
  76. EXAMPLE
  77. To switch between one of several routines for a particular interrupt,
  78. the following code fragment is one alternative:
  79. .CS
  80.     vector  = INUM_TO_IVEC(some_int_vec_num);
  81.     oldfunc = intVecGet (vector);
  82.     newfunc = intHandlerCreate (routine, parameter);
  83.     intVecSet (vector, newfunc);
  84.     ...
  85.     intVecSet (vector, oldfunc);    /@ use original routine @/
  86.     ...
  87.     intVecSet (vector, newfunc);    /@ reconnect new routine @/
  88. .CE
  89. INCLUDE FILES: iv.h, intLib.h
  90. SEE ALSO: intLib
  91. */
  92. /*******************************************************************************
  93. *
  94. * intLevelSet - set the interrupt level (MC680x0, x86, ARM, SimSolaris, SimNT and SH)
  95. *
  96. * This routine changes the interrupt mask in the status register to take on
  97. * the value specified by <level>.  Interrupts are locked out at or below
  98. * that level.  The value of <level> must be in the following range:
  99. *
  100. * .TS
  101. * tab(|);
  102. * l l.
  103. *     MC680x0:         | 0 - 7
  104. *     SH:         | 0 - 15
  105. *     ARM:         | BSP-specific
  106. *     SimSolaris: | 0 - 1
  107. *     x86:         | interrupt controller specific
  108. * .TE
  109. *
  110. * "On SPARC systems, traps must be enabled before the call.
  111. * On x86 systems, there are no interrupt level in the processor
  112. * and the external interrupt controller manages the interrupt level.
  113. * Therefore this routine does nothing and returns OK always.
  114. *
  115. * NOTE SIMNT: 
  116. * This routine does nothing.
  117. *
  118. * WARNING
  119. * Do not call VxWorks system routines with interrupts locked.
  120. * Violating this rule may re-enable interrupts unpredictably.
  121. *
  122. * RETURNS: The previous interrupt level.
  123. */
  124. int intLevelSet
  125.     (
  126.     int level /* new interrupt level mask */
  127.     )
  128.     {
  129.     ...
  130.     }
  131. /*******************************************************************************
  132. *
  133. * intLock - lock out interrupts
  134. * This routine disables interrupts.  The intLock() routine returns an
  135. * architecture-dependent lock-out key representing the interrupt level
  136. * prior to the call; this key can be passed to intUnlock() to
  137. * re-enable interrupts.
  138. * For MC680x0, x86, and SH architectures, interrupts
  139. * are disabled at the level set by intLockLevelSet().  The default
  140. * lock-out level is the highest interrupt level (MC680x0 = 7,
  141. * x86 = 1, SH = 15).  
  142. * For SimSolaris architecture, interrupts are masked. Lock-out level returned
  143. * is 1 if interrupts were already locked, 0 otherwise.
  144. *
  145. * For SimNT, a windows semaphore is used to lock the interrupts.
  146. * Lock-out level returned is 1 if interrupts were already locked, 0 otherwise.
  147. *
  148. * For MIPS processors, interrupts are disabled at the
  149. * master lock-out level; this means no interrupt can occur even if
  150. * unmasked in the IntMask bits (15-8) of the status register.
  151. *
  152. * For ARM processors, interrupts (IRQs) are disabled by setting the I bit
  153. * in the CPSR. This means no IRQs can occur.
  154. *
  155. * For PowerPC processors, there is only one interrupt vector.  The external
  156. * interrupt (vector offset 0x500) is disabled when intLock() is called; this
  157. * means that the processor cannot be interrupted by any external event.
  158. *
  159. * IMPLEMENTATION
  160. * The lock-out key is implemented differently for different architectures:
  161. *
  162. * .TS
  163. * tab(|);
  164. * l l.
  165. *     MC680x0:     | interrupt field mask
  166. *     MIPS:        | status register
  167. *     x86:         | interrupt enable flag (IF) bit from EFLAGS register
  168. *     PowerPC:     | MSR register value
  169. *     ARM          | I bit from the CPSR
  170. *     SH:          | status register
  171. *     SimSolaris:  | 1 or 0 
  172. *     SimNT:       | 1 or 0 
  173. * .TE
  174. * WARNINGS
  175. * Do not call VxWorks system routines with interrupts locked.
  176. * Violating this rule may re-enable interrupts unpredictably.
  177. *
  178. * The routine intLock() can be called from either interrupt or task level.
  179. * When called from a task context, the interrupt lock level is part of the
  180. * task context.  Locking out interrupts does not prevent rescheduling.
  181. * Thus, if a task locks out interrupts and invokes kernel services that
  182. * cause the task to block (e.g., taskSuspend() or taskDelay()) or that cause a
  183. * higher priority task to be ready (e.g., semGive() or taskResume()), then
  184. * rescheduling occurs and interrupts are unlocked while other tasks
  185. * run.  Rescheduling may be explicitly disabled with taskLock().
  186. * Traps must be enabled when calling this routine.
  187. *
  188. * EXAMPLES
  189. * .CS
  190. *     lockKey = intLock ();
  191. *
  192. *      ... (work with interrupts locked out)
  193. *
  194. *     intUnlock (lockKey);
  195. * .CE
  196. *
  197. * To lock out interrupts and task scheduling as well (see WARNING above):
  198. * .CS
  199. *     if (taskLock() == OK)
  200. *         {
  201. *         lockKey = intLock ();
  202. *
  203. *         ... (critical section)
  204. *
  205. *         intUnlock (lockKey);
  206. *         taskUnlock();
  207. *         }
  208. *      else
  209. *         {
  210. *         ... (error message or recovery attempt)
  211. *         }
  212. * .CE
  213. *
  214. * RETURNS
  215. * An architecture-dependent lock-out key for the interrupt level
  216. * prior to the call.
  217. *
  218. * SEE ALSO: intUnlock(), taskLock(), intLockLevelSet()
  219. */
  220. int intLock (void)
  221.     {
  222.     ...
  223.     }
  224. /*******************************************************************************
  225. *
  226. * intUnlock - cancel interrupt locks
  227. *
  228. * This routine re-enables interrupts that have been disabled by intLock().
  229. * The parameter <lockKey> is an architecture-dependent lock-out key
  230. * returned by a preceding intLock() call.
  231. *
  232. * RETURNS: N/A
  233. *
  234. * SEE ALSO: intLock()
  235. */
  236. void intUnlock
  237.     (
  238.     int lockKey /* lock-out key returned by preceding intLock() */
  239.     )
  240.     {
  241.     ...
  242.     }
  243. /*******************************************************************************
  244. *
  245. * intEnable - enable corresponding interrupt bits (MIPS, PowerPC, ARM)
  246. * This routine enables the input interrupt bits on the present status
  247. * register of the MIPS and PowerPC processors.
  248. *
  249. * NOTE ARM:
  250. * ARM processors generally do not have on-chip interrupt controllers.
  251. * Control of interrupts is a BSP-specific matter.  This routine calls a
  252. * BSP-specific routine to enable the interrupt.  For each interrupt
  253. * level to be used, there must be a call to this routine before it will
  254. * be allowed to interrupt.
  255. *
  256. * NOTE MIPS:
  257. * For MIPS, it is strongly advised that the level be a combination of
  258. * `SR_IBIT1' - `SR_IBIT8'.
  259. *
  260. * RETURNS: OK or ERROR. (MIPS: The previous contents of the status register).
  261. */
  262. int intEnable
  263.     (
  264.     int level   /* new interrupt bits (0x00 - 0xff00) */
  265.     )
  266.     {
  267.     ...
  268.     }
  269. /*******************************************************************************
  270. *
  271. * intDisable - disable corresponding interrupt bits (MIPS, PowerPC, ARM)
  272. * On MIPS and PowerPC architectures, this routine disables the corresponding
  273. * interrupt bits from the present status register.  
  274. *
  275. * NOTE ARM:
  276. * ARM processors generally do not have on-chip interrupt controllers.
  277. * Control of interrupts is a BSP-specific matter. This routine calls a
  278. * BSP-specific routine to disable a particular interrupt level,
  279. * regardless of the current interrupt mask level.
  280. *
  281. * NOTE MIPS:
  282. * For MIPS, the macros `SR_IBIT1' - `SR_IBIT8' define bits that may be set.
  283. *
  284. * RETURNS: OK or ERROR. (MIPS: The previous contents of the status register).
  285. */
  286. int intDisable
  287.     (
  288.     int level   /* new interrupt bits (0x0 - 0xff00) */
  289.     )
  290.     {
  291.     ...
  292.     }
  293. /*******************************************************************************
  294. *
  295. * intCRGet - read the contents of the cause register (MIPS)
  296. *
  297. * This routine reads and returns the contents of the MIPS cause
  298. * register.
  299. *
  300. * RETURNS: The contents of the cause register.
  301. */
  302. int intCRGet (void)
  303.     {
  304.     ...
  305.     }
  306. /*******************************************************************************
  307. *
  308. * intCRSet - write the contents of the cause register (MIPS)
  309. *
  310. * This routine writes the contents of the MIPS cause register.
  311. *
  312. * RETURNS: N/A
  313. */
  314. void intCRSet
  315.     (
  316.     int value      /* value to write to cause register */
  317.     )
  318.     {
  319.     ...
  320.     }
  321. /*******************************************************************************
  322. *
  323. * intSRGet - read the contents of the status register (MIPS)
  324. *
  325. * This routine reads and returns the contents of the MIPS status
  326. * register.
  327. *
  328. * RETURNS: The previous contents of the status register.
  329. */
  330. int intSRGet (void)
  331.     {
  332.     ...
  333.     }
  334. /*******************************************************************************
  335. *
  336. * intSRSet - update the contents of the status register (MIPS)
  337. *
  338. * This routine updates and returns the previous contents of the MIPS
  339. * status register.
  340. *
  341. * RETURNS: The previous contents of the status register.
  342. */
  343. int intSRSet
  344.     (
  345.     int value   /* value to write to status register */
  346.     )
  347.     {
  348.     ...
  349.     }
  350. /*******************************************************************************
  351. *
  352. * intConnect - connect a C routine to a hardware interrupt
  353. *
  354. * This routine connects a specified C routine to a specified interrupt
  355. * vector.  The address of <routine> is generally stored at <vector> so
  356. * that <routine> is called with <parameter> when the interrupt occurs.
  357. * The routine is invoked in supervisor mode at interrupt level.  A proper
  358. * C environment is established, the necessary registers saved, and the
  359. * stack set up.
  360. *
  361. * The routine can be any normal C code, except that it must not invoke
  362. * certain operating system functions that may block or perform I/O
  363. * operations.
  364. *
  365. * This routine generally simply calls intHandlerCreate() and
  366. * intVecSet().  The address of the handler returned by intHandlerCreate()
  367. * is what actually goes in the interrupt vector.
  368. *
  369. * This routine takes an interrupt vector as a parameter, which is the byte
  370. * offset into the vector table. Macros are provided to convert between interrupt
  371. * vectors and interrupt numbers, see `intArchLib'.
  372. *
  373. * NOTE ARM:
  374. * ARM processors generally do not have on-chip interrupt controllers.
  375. * Control of interrupts is a BSP-specific matter. This routine calls a
  376. * BSP-specific routine to install the handler such that, when the
  377. * interrupt occurs, <routine> is called with <parameter>.
  378. *
  379. * NOTE X86:
  380. * Refer to the special x86 routine intHandlerCreateI86().
  381. * NOTE SH:
  382. * The on-chip interrupt controller (INTC) design of SH architecture depends
  383. * on the processor type, but there are some similarities.  The number of
  384. * external interrupt inputs are limited, so it may necessary to multiplex
  385. * some interrupt requests.  However most of them are auto-vectored, thus have
  386. * only one vector to an external interrupt input.  As a framework to handle
  387. * this type of multiplexed interrupt, you can use your original intConnect
  388. * code by hooking it to _func_intConnectHook pointer.  If _func_intConnectHook
  389. * is set, the SH version of intConnect() simply calls the hooked routine with
  390. * same arguments, then returns the status of hooked routine.  A sysLib sample
  391. * is shown below:
  392. *
  393. * .CS
  394. * #include "intLib.h"
  395. * #include "iv.h" /@ INUM_INTR_HIGH for SH7750/SH7700 @/
  396. *
  397. * #define SYS_INT_TBL_SIZE (255 - INUM_INTR_HIGH)
  398. *
  399. * typedef struct
  400. *     {
  401. *     VOIDFUNCPTR routine; /@ routine to be called @/
  402. *     int         parameter; /@ parameter to be passed @/
  403. *     } SYS_INT_TBL;
  404. *
  405. * LOCAL SYS_INT_TBL sysIntTbl [SYS_INT_TBL_SIZE]; /@ local vector table @/
  406. *
  407. * LOCAL int sysInumVirtBase = INUM_INTR_HIGH + 1;
  408. *
  409. * STATUS sysIntConnect
  410. *     (
  411. *     VOIDFUNCPTR *vec, /@ interrupt vector to attach to     @/
  412. *     VOIDFUNCPTR routine, /@ routine to be called              @/
  413. *     int         param /@ parameter to be passed to routine @/
  414. *     )
  415. *     {
  416. *     FUNCPTR intDrvRtn;
  417. *  
  418. *     if (vec >= INUM_TO_IVEC (0) && vec < INUM_TO_IVEC (sysInumVirtBase))
  419. *         {
  420. *         /@ do regular intConnect() process @/
  421. *
  422. *         intDrvRtn = intHandlerCreate ((FUNCPTR)routine, param);
  423. *  
  424. *         if (intDrvRtn == NULL)
  425. *             return ERROR;
  426. *  
  427. *         /@ make vector point to synthesized code @/
  428. *  
  429. *         intVecSet ((FUNCPTR *)vec, (FUNCPTR)intDrvRtn);
  430. *         }
  431. *     else
  432. *         {
  433. *         int index = IVEC_TO_INUM (vec) - sysInumVirtBase;
  434. *  
  435. *         if (index < 0 || index >= SYS_INT_TBL_SIZE)
  436. *             return ERROR;
  437. *  
  438. *         sysIntTbl [index].routine   = routine;
  439. *         sysIntTbl [index].parameter = param;
  440. *         }
  441. *  
  442. *     return OK;
  443. *     }
  444. *
  445. * void sysHwInit (void)
  446. *     {
  447. *     ...
  448. *     _func_intConnectHook = (FUNCPTR)sysIntConnect;
  449. *     }
  450. *
  451. * LOCAL void sysVmeIntr (void)
  452. *     {
  453. *     volatile UINT32 vec = *VME_VEC_REGISTER; /@ get VME interrupt vector @/
  454. *     int i = vec - sysInumVirtBase;
  455. *  
  456. *     if (i >= 0 && i < SYS_INT_TBL_SIZE && sysIntTbl[i].routine != NULL)
  457. *         (*sysIntTbl[i].routine)(sysIntTbl[i].parameter);
  458. *     else
  459. *         logMsg ("uninitialized VME interrupt: vec = %dn", vec,0,0,0,0,0);
  460. *     }
  461. *
  462. * void sysHwInit2 (void)
  463. *     {
  464. *     int i;
  465. *     ...
  466. *     /@ initialize VME interrupts dispatch table @/
  467. *
  468. *     for (i = 0; i < SYS_INT_TBL_SIZE; i++)
  469. *         {
  470. *         sysIntTbl[i].routine   = (VOIDFUNCPTR)NULL;
  471. *         sysIntTbl[i].parameter = NULL;
  472. *         }
  473. *
  474. *     /@ connect generic VME interrupts handler @/
  475. *
  476. *     intConnect (INT_VEC_VME, sysVmeIntr, NULL);
  477. *     ...
  478. *     }
  479. * .CE
  480. *
  481. * The used vector numbers of SH processors are limited to certain ranges,
  482. * depending on the processor type. The `sysInumVirtBase' should be initialized
  483. * to a value higher than the last used vector number, defined as INUM_INTR_HIGH.
  484. * It is typically safe to set `sysInumVirtBase' to (INUM_INTR_HIGH + 1).
  485. *
  486. * The sysIntConnect() routine simply acts as the regular intConnect() if 
  487. * <vector> is smaller than INUM_TO_IVEC (sysInumVirtBase), so sysHwInit2() 
  488. * connects a common VME interrupt dispatcher `sysVmeIntr' to the multiplexed
  489. * interrupt vector. If <vector> is equal to or greater than INUM_TO_IVEC 
  490. * (sysInumVirtBase), the sysIntConnect() fills a local vector entry in 
  491. * sysIntTbl[] with an individual VME interrupt handler, in a coordinated 
  492. * manner with `sysVmeIntr'.
  493. *
  494. * RETURNS: OK, or ERROR if the interrupt handler cannot be built.
  495. *
  496. * SEE ALSO: intHandlerCreate(), intVecSet()
  497. */
  498. STATUS intConnect
  499.     (
  500.     VOIDFUNCPTR *  vector,      /* interrupt vector to attach to     */
  501.     VOIDFUNCPTR    routine,     /* routine to be called              */
  502.     int            parameter    /* parameter to be passed to routine */
  503.     )
  504.     {
  505.     ...
  506.     }
  507. /*******************************************************************************
  508. *
  509. * intHandlerCreate - construct an interrupt handler for a C routine (MC680x0, x86, MIPS, SimSolaris)
  510. *
  511. * This routine builds an interrupt handler around the specified C routine.
  512. * This interrupt handler is then suitable for connecting to a specific
  513. * vector address with intVecSet().  The interrupt handler is invoked in
  514. * supervisor mode at interrupt level.  A proper C environment is
  515. * established, the necessary registers saved, and the stack set up.
  516. *
  517. * The routine can be any normal C code, except that it must not invoke
  518. * certain operating system functions that may block or perform I/O
  519. * operations.
  520. *
  521. * RETURNS: A pointer to the new interrupt handler, or NULL if memory 
  522. * is insufficient.
  523. */
  524. FUNCPTR intHandlerCreate
  525.     (
  526.     FUNCPTR  routine,     /* routine to be called              */
  527.     int      parameter    /* parameter to be passed to routine */
  528.     )
  529.     {
  530.     ...
  531.     }
  532. /*******************************************************************************
  533. *
  534. * intLockLevelSet - set the current interrupt lock-out level (MC680x0, x86, ARM, SH, SimSolaris, SimNT)
  535. * This routine sets the current interrupt lock-out level and stores it
  536. * in the globally accessible variable `intLockMask'.  The specified
  537. * interrupt level is masked when interrupts are locked by
  538. * intLock().  The default lock-out level (MC680x0 = 7,
  539. * x86 = 1, SH = 15) is initially set by kernelInit() when
  540. * VxWorks is initialized.
  541. *
  542. * NOTE SIMSOLARIS, SIMNT:
  543. * This routine does nothing.
  544. *
  545. * NOTE ARM:
  546. * On the ARM, this call establishes the interrupt level to be set when
  547. * intLock() is called.
  548. *
  549. * RETURNS: N/A
  550. * SEE ALSO: intLockLevelGet(), intLock(), taskLock()
  551. */
  552. void intLockLevelSet
  553.     (
  554.     int  newLevel        /* new interrupt level */
  555.     )
  556.     {
  557.     ...
  558.     }
  559. /*******************************************************************************
  560. *
  561. * intLockLevelGet - get the current interrupt lock-out level (MC680x0, x86, ARM, SH, SimSolaris, SimNT)
  562. * This routine returns the current interrupt lock-out level, which is
  563. * set by intLockLevelSet() and stored in the globally accessible
  564. * variable `intLockMask'.  This is the interrupt level currently
  565. * masked when interrupts are locked out by intLock().  The default
  566. * lock-out level (MC680x0 = 7, x86 = 1, SH = 15)
  567. * is initially set by kernelInit() when VxWorks is initialized.
  568. *
  569. * NOTE SIMNT:
  570. * This routine does nothing.
  571. *
  572. * RETURNS: The interrupt level currently stored in the interrupt
  573. * lock-out mask. (ARM = ERROR always)
  574. *
  575. * SEE ALSO: intLockLevelSet()
  576. */
  577. int intLockLevelGet (void)
  578.     {
  579.     ...
  580.     }
  581. /*******************************************************************************
  582. *
  583. * intVecBaseSet - set the vector (trap) base address (MC680x0, x86, MIPS, ARM, SimSolaris, SimNT)
  584. *
  585. * This routine sets the vector (trap) base address.  The CPU's vector base
  586. * register is set to the specified value, and subsequent calls to intVecGet()
  587. * or intVecSet() will use this base address.  The vector base address is
  588. * initially 0, until modified by calls to this routine.
  589. *
  590. * "NOTE SPARC:
  591. * "On SPARC processors, the vector base address must be on a 4 Kbyte boundary
  592. * "(that is, its bottom 12 bits must be zero).
  593. * "
  594. * NOTE 68000:
  595. * The 68000 has no vector base register; thus, this routine is a no-op for
  596. * 68000 systems.
  597. *
  598. * "NOTE I960:
  599. * "This routine is a no-op for i960 systems.  The interrupt vector table is
  600. * "located in sysLib, and moving it by intVecBaseSet() would require
  601. * "resetting the processor.  Also, the vector base is cached on-chip in the
  602. * "PRCB and thus cannot be set from this routine.
  603. * "
  604. * NOTE MIPS:
  605. * The MIPS processors have no vector base register;
  606. * thus this routine is a no-op for this architecture.
  607. *
  608. * NOTE SH77XX:
  609. * This routine sets <baseAddr> to vbr, then loads an interrupt dispatch
  610. * code to (vbr + 0x600).  When SH77XX processor accepts an interrupt request,
  611. * it sets an exception code to INTEVT register and jumps to (vbr + 0x600).
  612. * Thus this dispatch code is commonly used for all interrupts' handling.
  613. *
  614. * The exception codes are 12bits width, and interleaved by 0x20.  VxWorks
  615. * for SH77XX locates a vector table at (vbr + 0x800), and defines the vector
  616. * offsets as (exception codes / 8).  This vector table is commonly used by
  617. * all interrupts, exceptions, and software traps.
  618. *
  619. * All SH77XX processors have INTEVT register at address 0xffffffd8.  The SH7707
  620. * processor has yet another INTEVT2 register at address 0x04000000, to identify
  621. * its enhanced interrupt sources.  The dispatch code obtains the address
  622. * of INTEVT register from a global constant `intEvtAdrs'.  The constant is
  623. * defined in `sysLib', thus the selection of INTEVT/INTEVT2 is configurable
  624. * at BSP level.  The `intEvtAdrs' is loaded to (vbr + 4) by intVecBaseSet().
  625. *
  626. * After fetching the exception code, the interrupt dispatch code applies
  627. * a new interrupt mask to the status register, and jumps to an individual
  628. * interrupt handler.  The new interrupt mask is taken from `intPrioTable[]',
  629. * which is defined in `sysALib'.  The `intPrioTable[]' is loaded to
  630. * (vbr + 0xc00) by intVecBaseSet().
  631. *
  632. * NOTE ARM:
  633. * The ARM processors have no vector base register;
  634. * thus this routine is a no-op for this architecture.
  635. *
  636. * NOTE SIMSOLARIS, SIMNT:
  637. * This routine does nothing.
  638. *
  639. * RETURNS: N/A
  640. *
  641. * SEE ALSO: intVecBaseGet(), intVecGet(), intVecSet()
  642. */
  643. void intVecBaseSet
  644.     (
  645.     FUNCPTR *  baseAddr     /* new vector (trap) base address */
  646.     )
  647.     {
  648.     ...
  649.     }
  650. /*******************************************************************************
  651. *
  652. * intVecBaseGet - get the vector (trap) base address (MC680x0, x86, MIPS, ARM, SimSolaris, SimNT)
  653. *
  654. * This routine returns the current vector base address, which is set
  655. * with intVecBaseSet().
  656. *
  657. * RETURNS: The current vector base address
  658. * (MIPS = 0 always, ARM = 0 always, SimSolaris = 0 always and 
  659. * SimNT = 0 always).
  660. *
  661. * SEE ALSO: intVecBaseSet()
  662. */
  663. FUNCPTR *intVecBaseGet (void)
  664.     {
  665.     ...
  666.     }
  667. /******************************************************************************
  668. *
  669. * intVecSet - set a CPU vector (trap) (MC680x0, x86, MIPS, SH, SimSolaris, SimNT)
  670. *
  671. * This routine attaches an exception/interrupt/trap handler to a specified 
  672. * vector.  The vector is specified as an offset into the CPU's vector table. 
  673. * This vector table starts, by default, at:
  674. * .TS
  675. * tab(|);
  676. * l l.
  677. *     MC680x0:     | 0
  678. *     MIPS:        | `excBsrTbl' in excArchLib
  679. *     x86:         | 0
  680. *     SH702x/SH703x/SH704x/SH76xx: | `excBsrTbl' in excArchLib
  681. *     SH77xx:      | vbr + 0x800
  682. *     SimSolaris:  | 0
  683. * .TE
  684. *
  685. * However, the vector table may be set to start at any address with
  686. * intVecBaseSet() (on CPUs for which it is available).  The vector table is
  687. * set up in usrInit().
  688. *
  689. * This routine takes an interrupt vector as a parameter, which is the byte
  690. * offset into the vector table. Macros are provided to convert between interrupt
  691. * vectors and interrupt numbers, see `intArchLib'.
  692. *
  693. * "NOTE SPARC:
  694. * "This routine generates code to:
  695. * ".IP (1) 4
  696. * "save volatile registers;
  697. * ".IP (2)
  698. * "fix possible window overflow;
  699. * ".IP (3)
  700. * "read the processor state register into register %L0; and 
  701. * ".IP (4)
  702. * "jump to the specified address.
  703. * ".LP
  704. * "
  705. * The intVecSet() routine puts this generated code into the trap table
  706. * entry corresponding to <vector>.
  707. * Window overflow and window underflow are sacred to
  708. * the kernel and may not be pre-empted.  They are written here
  709. * only to track changing trap base registers (TBRs).
  710. * With the "branch anywhere" scheme (as opposed to the branch PC-relative
  711. * +/-8 megabytes) the first instruction in the vector table must not be a 
  712. * change of flow control nor affect any critical registers.  The JMPL that 
  713. * replaces the BA will always execute the next vector's first instruction.
  714. *
  715. * "NOTE I960:
  716. * "Vectors 0-7 are illegal vectors; using them puts the vector into the
  717. * "priorities/pending portion of the table, which yields undesirable
  718. * "actions.  The i960CA caches the NMI vector in internal RAM at system
  719. * "power-up.  This is where the vector is taken when the NMI occurs.  Thus, it
  720. * "is important to check to see if the vector being changed is the NMI
  721. * "vector, and, if so, to write it to internal RAM.
  722. * "
  723. * NOTE MIPS:
  724. * On MIPS CPUs the vector table is set up statically in software.
  725. *
  726. * NOTE SH77XX:
  727. * The specified interrupt handler <function> has to coordinate with an interrupt
  728. * stack frame which is specially designed for SH77XX version of VxWorks:
  729. *
  730. *.CS
  731. *    [ task's stack ]       [ interrupt stack ]
  732. *
  733. * |  xxx  | high address
  734. * |  yyy  | +-------+
  735. * |__zzz__|<--------------|task'sp|  0
  736. * | | |INTEVT | -4
  737. * | | low address |  ssr  | -8
  738. * |_ spc _| -12 <- sp (non-nested interrupt)
  739. * : :
  740. * : :
  741. * :_______:
  742. *                               |INTEVT |  0
  743. *                               |  ssr  | -4
  744. *                               |_ spc _| -8  <- sp (nested interrupt)
  745. *                               |       |
  746. *.CE
  747. *
  748. * This interrupt stack frame is formed by a common interrupt dispatch code
  749. * which is loaded at (vbr + 0x600).  You usually do not have to pay any
  750. * attention to this stack frame, since intConnect() automatically appends
  751. * an appropriate stack manipulation code to your interrupt service routine.
  752. * The intConnect() assumes that your interrupt service routine (ISR) is
  753. * written in C, thus it also wraps your ISR in minimal register save/restore
  754. * codes.  However if you need a very fast response time to a particular
  755. * interrupt request, you might want to skip this register save/restore
  756. * sequence by directly attaching your ISR to the corresponding vector table
  757. * entry using intVecSet().  Note that this technique is only applicable to
  758. * an interrupt service with NO VxWorks system call.  For example it is not
  759. * allowed to use semGive() or logMsg() in the interrupt service routine which
  760. * is directly attached to vector table by intVecSet().  To facilitate the
  761. * direct usage of intVecSet() by user, a special entry point to exit an
  762. * interrupt context is provided within the SH77XX version of VxWorks kernel.
  763. * This entry point is located at address (vbr + intRte1W), here the intRte1W
  764. * is a global symbol for the vbr offset of the entry point in 16 bit length.
  765. * This entry point `intRte1' assumes that the current register bank is 0
  766. * (SR.RB == 0), and r1 and r0 are still saved on the interrupt stack, and
  767. * it also requires 0x70000000 in r0. Then `intRte1' properly cleans up the
  768. * interrupt stack and executes <rte> instruction to return to the previous
  769. * interrupt or task context.  The following code is an example of `intRte1'
  770. * usage.  Here the corresponding intPrioTable[] entry is assumed to be
  771. * 0x400000X0, namely MD=1, RB=0, BL=0 at the beginning of `usrIsr1'.
  772. *
  773. *.CS
  774. * .text
  775. * .align 2
  776. * .global _usrIsr1
  777. * .type _usrIsr1,@function
  778. * .extern _usrRtn
  779. * .extern intRte1W
  780. * /@ intPrioTable[] sets SR to 0x400000X0 @/
  781. * _usrIsr1:
  782. * mov.l r0,@-sp /@ must save r0 first (BANK0) @/
  783. * mov.l r1,@-sp /@ must save r1 second (BANK0) @/
  784. *
  785. * mov.l r2,@-sp /@ save rest of volatile registers (BANK0) @/
  786. * mov.l r3,@-sp
  787. * mov.l r4,@-sp
  788. * mov.l r5,@-sp
  789. * mov.l r6,@-sp
  790. * mov.l r7,@-sp
  791. * sts.l pr,@-sp
  792. * sts.l mach,@-sp
  793. * sts.l macl,@-sp
  794. *
  795. * mov.l UsrRtn,r0
  796. * jsr @r0 /@ call user's C routine @/
  797. * nop /@ (delay slot) @/
  798. *
  799. * lds.l @sp+,macl /@ restore volatile registers (BANK0) @/
  800. * lds.l @sp+,mach
  801. * lds.l @sp+,pr
  802. * mov.l @sp+,r7
  803. * mov.l @sp+,r6
  804. * mov.l @sp+,r5
  805. * mov.l @sp+,r4
  806. * mov.l @sp+,r3
  807. * mov.l @sp+,r2
  808. * /@ intRte1 restores r1 and r0 @/
  809. * mov.l IntRte1W,r1
  810. * mov.w @r1,r0
  811. * stc vbr,r1
  812. * add r0,r1
  813. * mov.l IntRteSR,r0 /@ r0: 0x70000000 @/
  814. * jmp @r1 /@ let intRte1 clean up stack, then rte @/
  815. * nop /@ (delay slot) @/
  816. *
  817. * .align 2
  818. * UsrRtn: .long _usrRtn /@ user's C routine @/
  819. * IntRteSR: .long 0x70000000 /@ MD=1, RB=1, BL=1 @/
  820. * IntRte1W: .long intRte1W
  821. * .CE
  822. *
  823. * The `intRte1' sets r0 to status register (SR: 0x70000000), to safely restore
  824. * SPC/SSR and to clean up the interrupt stack.  Note that TLB mishit exception
  825. * immediately reboots CPU while SR.BL=1.  To avoid this fatal condition, VxWorks
  826. * loads the `intRte1' code and the interrupt stack to a physical address space
  827. * (P1) where no TLB mishit happens.
  828. *
  829. * Furthermore, there is another special entry point called `intRte2' at an
  830. * address (vbr + intRte2W).  The `intRte2' assumes that SR is already set to
  831. * 0x70000000 (MD: 1, RB: 1, BL: 1), then it does not restore r1 and r0.
  832. * While SR value is 0x70000000, you may use r0,r1,r2,r3 in BANK1 as volatile
  833. * registers.  The rest of BANK1 registers (r4,r5,r6,r7) are non-volatile, so
  834. * if you need to use them then you have to preserve their original values by
  835. * saving/restoring them on the interrupt stack.  So, if you need the ultimate
  836. * interrupt response time, you may set the corresponding intPrioTable[] entry
  837. * to NULL and manage your interrupt service only with r0,r1,r2,r3 in BANK1
  838. * as shown in the next sample code:
  839. *
  840. * .CS
  841. * .text
  842. * .global  _usrIsr2
  843. * .type    _usrIsr2,@function
  844. * .extern  _usrIntCnt /@ interrupt counter @/
  845. * .extern  intRte2W
  846. * .align   2
  847. * /@ MD=1, RB=1, BL=1, since SR is not @/
  848. * /@ substituted from intPrioTable[].  @/
  849. * _usrIsr2:
  850. * mov.l UsrIntAck,r1
  851. * mov #0x1,r0
  852. * mov.b r0,@r1 /@ acknowledge interrupt @/
  853. *
  854. * mov.l UsrIntCnt,r1
  855. * mov.l X1FFFFFFF,r2
  856. * mov.l X80000000,r3
  857. * and r2,r1
  858. * or r3,r1 /@ r1: _usrIntCnt address in P1 @/
  859. * mov.l @r1,r0
  860. * add #1,r0
  861. * mov.l r0,@r1 /@ increment counter @/
  862. *
  863. * mov.l IntRte2W,r1
  864. * and r2,r1
  865. * or r3,r1 /@ r1: intRte2W address in P1 @/
  866. * mov.w @r1,r0
  867. * stc vbr,r1
  868. * add r1,r0
  869. * jmp @r0 /@ let intRte2 clean up stack, then rte @/
  870. * nop /@ (delay slot) @/
  871. *
  872. * .align 2
  873. * UsrIntAck: .long 0xa0001234 /@ interrupt acknowledge register @/
  874. * UsrIntCnt: .long _usrIntCnt
  875. * IntRte2W: .long intRte2W
  876. * X1FFFFFFF: .long 0x1fffffff
  877. * X80000000: .long 0x80000000
  878. * .CE
  879. *
  880. * Note that the entire interrupt service is executed under SR.BL=1 in this
  881. * sample code.  It means that any access to virtual address space may reboot
  882. * CPU, since TLB mishit exception is blocked.  Therefore `usrIsr2' has to
  883. * access `usrIntCnt' and `intRte2W' from P1 region.  Also `usrIsr2' itself
  884. * has to be executed on P1 region, and it can be done by relocating the address
  885. * of `usrIsr2' to P1 as shown below:
  886. *
  887. * .CS
  888. * IMPORT void usrIsr2 (void);
  889. *
  890. * intVecSet (vector, (FUNCPTR)(((UINT32)usrIsr2 & 0x1fffffff) | 0x80000000));
  891. * .CE
  892. *
  893. * In conclusion, you have to guarantee that the entire ISR does not access to
  894. * any virtual address space if you set the corresponding intPrioTable[] entry
  895. * to NULL.
  896. * NOTE SIMNT:
  897. * This routine does nothing.
  898. *
  899. * RETURNS: N/A
  900. *
  901. * SEE ALSO: intVecBaseSet(), intVecGet()
  902. */
  903. void intVecSet
  904.     (
  905.     FUNCPTR * vector, /* vector offset              */
  906.     FUNCPTR function /* address to place in vector */
  907.     )
  908.     {
  909.     ...
  910.     }
  911. /*******************************************************************************
  912. *
  913. * intVecGet - get an interrupt vector (MC680x0, x86, MIPS, SH, SimSolaris, SimNT)
  914. *
  915. * This routine returns a pointer to the exception/interrupt handler attached
  916. * to a specified vector.  The vector is specified as an offset into the CPU's
  917. * vector table.  This vector table starts, by default, at:
  918. * .TS
  919. * tab(|);
  920. * l l.
  921. *     MC680x0:     | 0
  922. *     MIPS:        | `excBsrTbl' in excArchLib
  923. *     x86:         | 0
  924. *     SH702x/SH703x/SH704x/SH76xx: | `excBsrTbl' in excArchLib
  925. *     SH77xx:      | vbr + 0x800
  926. *     SimSolaris:  | 0
  927. * .TE
  928. *
  929. * However, the vector table may be set to start at any address with
  930. * intVecBaseSet() (on CPUs for which it is available).
  931. *
  932. * This routine takes an interrupt vector as a parameter, which is the byte
  933. * offset into the vector table. Macros are provided to convert between interrupt
  934. * vectors and interrupt numbers, see `intArchLib'.
  935. *
  936. * "NOTE I960:
  937. * "The interrupt table location is reinitialized to <sysIntTable> after
  938. * "booting.  This location is returned by intVecBaseGet().
  939. * "
  940. * NOTE SIMNT:
  941. * This routine does nothing and always returns 0.
  942. *
  943. * RETURNS:
  944. * A pointer to the exception/interrupt handler attached to the specified vector.
  945. *
  946. * SEE ALSO: intVecSet(), intVecBaseSet()
  947. */
  948. FUNCPTR intVecGet
  949.     (
  950.     FUNCPTR *  vector     /* vector offset */
  951.     )
  952.     {
  953.     ...
  954.     }
  955. /*******************************************************************************
  956. *
  957. * intVecTableWriteProtect - write-protect exception vector table (MC680x0, x86, ARM, SimSolaris, SimNT)
  958. *
  959. * If the unbundled Memory Management Unit (MMU) support package (VxVMI) is
  960. * present, this routine write-protects the exception vector table to
  961. * protect it from being accidentally corrupted.
  962. *
  963. * Note that other data structures contained in the page will also be 
  964. * write-protected.  In the default VxWorks configuration, the exception vector
  965. * table is located at location 0 in memory.  Write-protecting this affects
  966. * the backplane anchor, boot configuration information, and potentially the
  967. * text segment (assuming the default text location of 0x1000.)  All code
  968. * that manipulates these structures has been modified to write-enable 
  969. * memory for the duration of the operation.  If you select a different
  970. * address for the exception vector table, be sure it resides in a page
  971. * separate from other writable data structures.
  972. *
  973. * NOTE SIMSOLARIS, SIMNT:
  974. * This routine always returns ERROR on simulators.
  975. *
  976. * RETURNS: OK, or ERROR if memory cannot be write-protected.
  977. *
  978. * ERRNO: S_intLib_VEC_TABLE_WP_UNAVAILABLE
  979. */
  980. STATUS intVecTableWriteProtect (void)
  981.     {
  982.     ...
  983.     }
  984. /********************************************************************************
  985. * intUninitVecSet - set the uninitialized vector handler (ARM)
  986. *
  987. * This routine installs a handler for the uninitialized vectors to be
  988. * called when any uninitialised vector is entered.
  989. *
  990. * RETURNS: N/A.
  991. */
  992. void intUninitVecSet
  993.     (
  994.     VOIDFUNCPTR routine /* ptr to user routine */
  995.     )
  996.     {
  997.     ...
  998.     }
  999. /*******************************************************************************
  1000. *
  1001. * intHandlerCreateI86 - construct an interrupt handler for a C routine (x86)
  1002. *
  1003. * This routine builds an interrupt handler around a specified C routine.
  1004. * This interrupt handler is then suitable for connecting to a specific
  1005. * vector address with intVecSet().  The interrupt handler is invoked in
  1006. * supervisor mode at interrupt level.  A proper C environment is
  1007. * established, the necessary registers saved, and the stack set up.
  1008. * The routine can be any normal C code, except that it must not invoke
  1009. * certain operating system functions that may block or perform I/O
  1010. * operations.
  1011. *
  1012. * IMPLEMENTATION:
  1013. * This routine builds an interrupt handler of the following form in
  1014. * allocated memory:
  1015. *
  1016. * .CS
  1017. * 00  e8 kk kk kk kk call _intEnt * tell kernel
  1018. * 05  50 pushl %eax * save regs
  1019. * 06  52 pushl %edx
  1020. * 07  51 pushl %ecx
  1021. * 08  68 pp pp pp pp pushl $_parameterBoi * push BOI param
  1022. * 13  e8 rr rr rr rr call _routineBoi * call BOI routine
  1023. * 18  68 pp pp pp pp pushl $_parameter * push param
  1024. * 23  e8 rr rr rr rr call _routine * call C routine
  1025. * 28  68 pp pp pp pp pushl $_parameterEoi * push EOI param
  1026. * 33  e8 rr rr rr rr call _routineEoi * call EOI routine
  1027. * 38  83 c4 0c addl $12, %esp * pop param
  1028. * 41  59 popl %ecx * restore regs
  1029. * 42  5a popl %edx
  1030. * 43  58 popl %eax
  1031. * 44  e9 kk kk kk kk jmp _intExit * exit via kernel
  1032. * .CE
  1033. * Third and fourth parameter of intHandlerCreateI86() are the BOI routine 
  1034. * address and its parameter that are inserted into the code as "routineBoi" 
  1035. * and "parameterBoi". 
  1036. * Fifth and sixth parameter of intHandlerCreateI86() are the EOI routine 
  1037. * address and its parameter that are inserted into the code as "routineEoi" 
  1038. * and "parameterEoi". 
  1039. * The BOI routine detects if this interrupt is stray/spurious/phantom by
  1040. * interrogating the interrupt controller, and returns from the interrupt
  1041. * if it is.  The EOI routine issues End Of Interrupt signal to the 
  1042. * interrupt controller, if it is required by the controller.  
  1043. * Each interrupt controller has its own BOI and EOI routine.  They are
  1044. * located in the BSP, and their address and parameter are taken by the
  1045. * intEoiGet function (set to sysIntEoiGet() in the BSP).
  1046. * The Tornado 2, and later, BSPs should use the BOI and EOI mechanism with
  1047. * intEoiGet function pointer.
  1048. *
  1049. * To keep the Tornado 101 BSP backward compatible, the function pointer 
  1050. * intEOI is not removed.  If intEoiGet is NULL, it should be set to the
  1051. * sysIntEoiGet() routine in the BSP, intHandlerCreate() and the intEOI 
  1052. * function pointer (set to sysIntEOI() in the Tornado 101 BSP) is used.
  1053. * RETURNS: A pointer to the new interrupt handler, or NULL if memory
  1054. * is insufficient.
  1055. */
  1056. FUNCPTR intHandlerCreateI86
  1057.     (
  1058.     FUNCPTR routine, /* routine to be called              */
  1059.     int parameter, /* parameter to be passed to routine */
  1060.     FUNCPTR routineBoi, /* BOI routine to be called          */
  1061.     int parameterBoi, /* parameter to be passed to routineBoi */
  1062.     FUNCPTR routineEoi, /* EOI routine to be called          */
  1063.     int parameterEoi /* parameter to be passed to routineEoi */
  1064.     )
  1065.     {
  1066.     ...
  1067.     }
  1068. /******************************************************************************
  1069. *
  1070. * intVecSet2 - set a CPU vector, gate type(int/trap), and selector (x86)
  1071. *
  1072. * This routine attaches an exception handler to a specified vector,
  1073. * with the type of the gate and the selector of the gate.  
  1074. * The vector is specified as an offset into the CPU's vector table.  This
  1075. * vector table starts, by default, at address 0.  
  1076. * However, the vector table may be set to start at any address with
  1077. * intVecBaseSet().  The vector table is set up in usrInit().
  1078. *
  1079. * RETURNS: N/A
  1080. *
  1081. * SEE ALSO: intVecBaseSet(), intVecGet(), intVecSet(), intVecGet2()
  1082. */
  1083. void intVecSet2
  1084.     (
  1085.     FUNCPTR * vector, /* vector offset              */
  1086.     FUNCPTR function, /* address to place in vector */
  1087.     int idtGate, /* IDT_TRAP_GATE or IDT_INT_GATE */
  1088.     int idtSelector /* sysCsExc or sysCsInt */
  1089.     )
  1090.     {
  1091.     ...
  1092.     }
  1093. /******************************************************************************
  1094. *
  1095. * intVecGet2 - get a CPU vector, gate type(int/trap), and gate selector (x86)
  1096. *
  1097. * This routine gets a pointer to the exception/interrupt handler attached
  1098. * to a specified vector, the type of the gate, the selector of the gate.  
  1099. * The vector is specified as an offset into the CPU's vector table.  
  1100. * This vector table starts, by default, at address 0.
  1101. * However, the vector table may be set to start at any address with
  1102. * intVecBaseSet().
  1103. *
  1104. * RETURNS: N/A
  1105. *
  1106. * SEE ALSO: intVecBaseSet(), intVecGet(), intVecSet(), intVecSet2()
  1107. */
  1108. void intVecGet2
  1109.     (
  1110.     FUNCPTR * vector, /* vector offset              */
  1111.     FUNCPTR * pFunction, /* address to place in vector */
  1112.     int *     pIdtGate, /* IDT_TRAP_GATE or IDT_INT_GATE */
  1113.     int *     pIdtSelector /* sysCsExc or sysCsInt */
  1114.     )
  1115.     {
  1116.     ...
  1117.     }
  1118. /*******************************************************************************
  1119. *
  1120. * intStackEnable - enable or disable the interrupt stack usage (x86)
  1121. *
  1122. * This routine enables or disables the interrupt stack usage and is only 
  1123. * callable from the task level. An Error is returned for any other calling 
  1124. * context. The interrupt stack usage is disabled in the default configuration
  1125. * for the backward compatibility.  Routines that manipulate the interrupt
  1126. * stack, are located in the file i86/windALib.s. These routines include
  1127. * intStackEnable(), intEnt() and intExit().
  1128. *
  1129. * RETURNS: OK, or ERROR if it is not in the task level.
  1130. */
  1131. STATUS intStackEnable 
  1132.     (
  1133.     BOOL enable /* TRUE to enable, FALSE to disable */
  1134.     )
  1135.     {
  1136.     ...
  1137.     }