📄 intarchlib.c
字号:
/* intArchLib.c - architecture-dependent interrupt library *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------02v,05jun02,wsl remove reference to SPARC and i96002u,09may02,wsl fix minor formatting error02t,20nov01,hdn updated x86 specific sections02s,13nov01,hbh Updated for simulators.02r,30oct01,zl corrected table in SH section of intConnect().02q,02oct01,hdn added intStackEnable() for PENTIUM (spr 69832: int stack)02p,14sep01,hdn added intHandlerCreateI86()/intVec[SG]et2() doc (spr 30292)02o,19feb01,hk update intConnect()/intVecBaseSet()/intVecSet() docs for T2/SH.02n,03mar00,zl merged SH support into T202m,16mar99,elg add information about conversion macros (SPR 7473).02l,12mar99,elg delete the SEE ALSO comment in intLevelSet() (SPR 22809).02k,11feb99,wsl add comment documenting ERRNO value02j,05oct98,jmp doc: added {...} when necessary.02i,21apr98,jpd updated ARM-specific documentation.02h,08jul97,dgp doc: add info about PowerPC to intLock() (SPR 7768)02h,03mar97,jpd added ARM-specific documentation.02g,09dec96,dgp doc: fix SPR #7580 (add INCLUDE FILE: intLib.h) and change MIPS R3000/R4000 to MIPS02f,14nov96,dgp doc: specify MIPS and PPC support for specific routines02e,30oct96,dgp doc: intHandlerCreate() does not exist in PowerPC per SPR 585102d,25nov95,jdi removed 29k stuff.02c,06feb95,rhp add AM29K note to intHandlerCreate() man page. jdi changed 80960 to i960.02b,26jan95,rhp doc: included i386/i486 info, R4000 info, and misc doc tweaks02a,12jan95,rhp propagated no-syscall caveat to intLevelSet doc (SPR#1094); added refs to intLock() and taskLock() to SEE ALSO line for intLockLevelSet(), and second example to intLock() man page (SPR#1304).01d,18apr94,pme added Am29K specific information to intLevelSet() fixed intVecGet() manual for Am29200 and Am29030.01c,07dec93,pme doc tweaks. added Am29K family support.01h,22sep94,rhp Restore paragraph break accidentally deleted with previous fix.01g,22sep94,rhp fix SPARC-specific intVecSet() description (SPR#2513).01f,20sep94,rhp propagate new SPARC info for intVecBaseSet()01e,20sep94,rhp propagate new SPARC info for intVecSet(); '94 copyright01d,19sep94,rhp do not mention exceptions in intArchLib man page (SPR#1494).01c,16sep94,rhp add caveats re avoiding system calls under intLock (SPR#3582).01b,20jan93,jdi documentation cleanup.01a,23sep92,jdi written, based on intALib.s and intArchLib.c for mc68k, sparc, i960, mips.*//*DESCRIPTIONThis library provides architecture-dependent routines to manipulateand connect to hardware interrupts. Any C language routine can beconnected to any interrupt by calling intConnect(). Vectors can beaccessed directly by intVecSet() and intVecGet(). The vector (trap)base register (if present) can be accessed by the routinesintVecBaseSet() and intVecBaseGet().Tasks can lock and unlock interrupts by calling intLock() and intUnlock().The lock-out level can be set and reported by intLockLevelSet() andintLockLevelGet() (MC680x0, x86, ARM and SH only).The routine intLevelSet() changes the current interrupt level of theprocessor (MC680x0, ARM, SimSolaris and SH).WARNINGDo not call VxWorks system routines with interrupts locked.Violating this rule may re-enable interrupts unpredictably.INTERRUPT VECTORS AND NUMBERSMost of the routines in this library take an interrupt vector as aparameter, which is generally the byte offset into the vector table.Macros are provided to convert between interrupt vectors and interruptnumbers:.iP IVEC_TO_INUM(intVector) 10converts a vector to a number..iP INUM_TO_IVEC(intNumber)converts a number to a vector..iP TRAPNUM_TO_IVEC(trapNumber)converts a trap number to a vector.EXAMPLETo switch between one of several routines for a particular interrupt,the following code fragment is one alternative:.CS vector = INUM_TO_IVEC(some_int_vec_num); oldfunc = intVecGet (vector); newfunc = intHandlerCreate (routine, parameter); intVecSet (vector, newfunc); ... intVecSet (vector, oldfunc); /@ use original routine @/ ... intVecSet (vector, newfunc); /@ reconnect new routine @/.CEINCLUDE FILES: iv.h, intLib.hSEE ALSO: intLib*//********************************************************************************* intLevelSet - set the interrupt level (MC680x0, x86, ARM, SimSolaris, SimNT and SH)** This routine changes the interrupt mask in the status register to take on* the value specified by <level>. Interrupts are locked out at or below* that level. The value of <level> must be in the following range:** .TS* tab(|);* l l.* MC680x0: | 0 - 7* SH: | 0 - 15* ARM: | BSP-specific* SimSolaris: | 0 - 1* x86: | interrupt controller specific* .TE** \"On SPARC systems, traps must be enabled before the call.* On x86 systems, there are no interrupt level in the processor* and the external interrupt controller manages the interrupt level.* Therefore this routine does nothing and returns OK always.** NOTE SIMNT: * This routine does nothing.** WARNING* Do not call VxWorks system routines with interrupts locked.* Violating this rule may re-enable interrupts unpredictably.** RETURNS: The previous interrupt level.*/int intLevelSet ( int level /* new interrupt level mask */ ) { ... }/********************************************************************************* intLock - lock out interrupts* * This routine disables interrupts. The intLock() routine returns an* architecture-dependent lock-out key representing the interrupt level* prior to the call; this key can be passed to intUnlock() to* re-enable interrupts.* * For MC680x0, x86, and SH architectures, interrupts* are disabled at the level set by intLockLevelSet(). The default* lock-out level is the highest interrupt level (MC680x0 = 7,* x86 = 1, SH = 15). * * For SimSolaris architecture, interrupts are masked. Lock-out level returned* is 1 if interrupts were already locked, 0 otherwise.** For SimNT, a windows semaphore is used to lock the interrupts.* Lock-out level returned is 1 if interrupts were already locked, 0 otherwise.** For MIPS processors, interrupts are disabled at the* master lock-out level; this means no interrupt can occur even if* unmasked in the IntMask bits (15-8) of the status register.** For ARM processors, interrupts (IRQs) are disabled by setting the I bit* in the CPSR. This means no IRQs can occur.** For PowerPC processors, there is only one interrupt vector. The external* interrupt (vector offset 0x500) is disabled when intLock() is called; this* means that the processor cannot be interrupted by any external event.** IMPLEMENTATION* The lock-out key is implemented differently for different architectures:** .TS* tab(|);* l l.* MC680x0: | interrupt field mask* MIPS: | status register* x86: | interrupt enable flag (IF) bit from EFLAGS register* PowerPC: | MSR register value* ARM | I bit from the CPSR* SH: | status register* SimSolaris: | 1 or 0 * SimNT: | 1 or 0 * .TE* * WARNINGS* Do not call VxWorks system routines with interrupts locked.* Violating this rule may re-enable interrupts unpredictably.** The routine intLock() can be called from either interrupt or task level.* When called from a task context, the interrupt lock level is part of the* task context. Locking out interrupts does not prevent rescheduling.* Thus, if a task locks out interrupts and invokes kernel services that* cause the task to block (e.g., taskSuspend() or taskDelay()) or that cause a* higher priority task to be ready (e.g., semGive() or taskResume()), then* rescheduling occurs and interrupts are unlocked while other tasks* run. Rescheduling may be explicitly disabled with taskLock().* Traps must be enabled when calling this routine.* ** EXAMPLES* .CS* lockKey = intLock ();** ... (work with interrupts locked out)** intUnlock (lockKey);* .CE** To lock out interrupts and task scheduling as well (see WARNING above):* .CS* if (taskLock() == OK)* {* lockKey = intLock ();** ... (critical section)** intUnlock (lockKey);* taskUnlock();* }* else* {* ... (error message or recovery attempt)* }* .CE** RETURNS* An architecture-dependent lock-out key for the interrupt level* prior to the call.** SEE ALSO: intUnlock(), taskLock(), intLockLevelSet()*/int intLock (void) { ... }/********************************************************************************* intUnlock - cancel interrupt locks** This routine re-enables interrupts that have been disabled by intLock().* The parameter <lockKey> is an architecture-dependent lock-out key* returned by a preceding intLock() call.** RETURNS: N/A** SEE ALSO: intLock()*/void intUnlock ( int lockKey /* lock-out key returned by preceding intLock() */ ) { ... }/********************************************************************************* intEnable - enable corresponding interrupt bits (MIPS, PowerPC, ARM)* * This routine enables the input interrupt bits on the present status* register of the MIPS and PowerPC processors.** NOTE ARM:* ARM processors generally do not have on-chip interrupt controllers.* Control of interrupts is a BSP-specific matter. This routine calls a* BSP-specific routine to enable the interrupt. For each interrupt* level to be used, there must be a call to this routine before it will* be allowed to interrupt.** NOTE MIPS:* For MIPS, it is strongly advised that the level be a combination of* `SR_IBIT1' - `SR_IBIT8'.** RETURNS: OK or ERROR. (MIPS: The previous contents of the status register).* */int intEnable ( int level /* new interrupt bits (0x00 - 0xff00) */ ) { ... }/********************************************************************************* intDisable - disable corresponding interrupt bits (MIPS, PowerPC, ARM)* * On MIPS and PowerPC architectures, this routine disables the corresponding* interrupt bits from the present status register. ** NOTE ARM:* ARM processors generally do not have on-chip interrupt controllers.* Control of interrupts is a BSP-specific matter. This routine calls a* BSP-specific routine to disable a particular interrupt level,* regardless of the current interrupt mask level.** NOTE MIPS:* For MIPS, the macros `SR_IBIT1' - `SR_IBIT8' define bits that may be set.** RETURNS: OK or ERROR. (MIPS: The previous contents of the status register).*/int intDisable ( int level /* new interrupt bits (0x0 - 0xff00) */ ) { ... }/********************************************************************************* intCRGet - read the contents of the cause register (MIPS)** This routine reads and returns the contents of the MIPS cause* register.** RETURNS: The contents of the cause register.*/int intCRGet (void) { ... }/********************************************************************************* intCRSet - write the contents of the cause register (MIPS)** This routine writes the contents of the MIPS cause register.** RETURNS: N/A*/void intCRSet ( int value /* value to write to cause register */ ) { ... }/********************************************************************************* intSRGet - read the contents of the status register (MIPS)** This routine reads and returns the contents of the MIPS status* register.** RETURNS: The previous contents of the status register.*/int intSRGet (void) { ... }/********************************************************************************* intSRSet - update the contents of the status register (MIPS)** This routine updates and returns the previous contents of the MIPS* status register.** RETURNS: The previous contents of the status register.*/int intSRSet ( int value /* value to write to status register */ ) { ... }/********************************************************************************* intConnect - connect a C routine to a hardware interrupt** This routine connects a specified C routine to a specified interrupt* vector. The address of <routine> is generally stored at <vector> so* that <routine> is called with <parameter> when the interrupt occurs.* The routine is invoked in supervisor mode at interrupt level. A proper* C environment is established, the necessary registers saved, and the* stack set up.** The routine can be any normal C code, except that it must not invoke
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -