📄 intarchlib.c
字号:
* 0x0a 2F3C pppp pppp move.l #parameter,-(a7) * push param* 0x10 4EB9 rrrr rrrr jsr routine * call C routine* 0x16 588F addq.l #4,a7 * pop param* 0x18 4CDF 0307 movem.l (a7)+,d0-d2/a0-a1 * restore regs* 0x1c 4EF9 kkkk kkkk jmp _intExit * exit via kernel* .CE** RETURNS: A pointer to the new interrupt handler,* or NULL if the routine runs out of memory.*/FUNCPTR intHandlerCreate ( FUNCPTR routine, /* routine to be called */ int parameter /* parameter to be passed to routine */ ) { FAST USHORT *pCode; /* pointer to newly synthesized code */ pCode = (USHORT *)malloc (sizeof (intConnectCode)); if (pCode != NULL) { /* copy intConnectCode into new code area */ bcopy ((char *)intConnectCode, (char *)pCode, sizeof (intConnectCode)); /* set the addresses & instructions */ pCode [1] = HI_WORD (intEnt); pCode [2] = LO_WORD (intEnt); pCode [6] = HI_WORD (parameter); pCode [7] = LO_WORD (parameter); pCode [9] = HI_WORD (routine); pCode [10] = LO_WORD (routine); pCode [15] = HI_WORD (intExit); pCode [16] = LO_WORD (intExit); } CACHE_TEXT_UPDATE ((void *) pCode, sizeof (intConnectCode)); return ((FUNCPTR) (int) pCode); }/********************************************************************************* intLockLevelSet - set the current interrupt lock-out level** This routine sets the current interrupt lock-out level and stores it in* the globally accessible variable `intLockMask'. The specified* interrupt level will be masked when interrupts are locked by intLock().* The default lock-out level is 7 for MC680x0 processors, and is initially* set by kernelInit() when VxWorks is initialized.** RETURNS: N/A** SEE ALSO: intLockLevelGet()*/void intLockLevelSet ( int newLevel /* new interrupt level */ ) { int oldSR = intLock (); /* LOCK INTERRUPTS */ intLockMask = (USHORT) (newLevel << 8); intLockIntSR &= 0xf8ff; intLockTaskSR &= 0xf8ff; intLockIntSR |= intLockMask; intLockTaskSR |= intLockMask; intUnlock (oldSR); /* UNLOCK INTERRUPTS */ }/********************************************************************************* intLockLevelGet - get the current interrupt lock-out level** This routine returns the current interrupt lock-out level, which is* set by intLockLevelSet() and stored in the globally accessible* variable `intLockMask'. This is the interrupt level currently* masked when interrupts are locked out by intLock(). The default* lock-out level is 7 for 68K processors, and is initially set by* kernelInit() when VxWorks is initialized.** RETURNS:* The interrupt level currently stored in the interrupt lock-out mask.** SEE ALSO: intLockLevelSet() */int intLockLevelGet (void) { return ((int)(intLockMask >> 8)); }/********************************************************************************* intVecBaseSet - set the vector base address** This routine sets the vector base address. The CPU's vector base register* is set to the specified value, and subsequent calls to intVecGet() or* intVecSet() will use this base address. The vector base address is* initially 0, until modified by calls to this routine.** NOTE:* The 68000 has no vector base register;* thus, this routine is thus a no-op for 68000 systems.** RETURNS: N/A** SEE ALSO: intVecBaseGet(), intVecGet(), intVecSet()*/void intVecBaseSet ( FUNCPTR *baseAddr /* new vector base address */ ) { if (sysCpu == MC68000) return; intVecBase = baseAddr; /* keep the base address in a static variable */ intVBRSet (baseAddr); /* set the actual vector base register */ CACHE_TEXT_UPDATE ((void *) baseAddr, 256 * sizeof (FUNCPTR)); }/********************************************************************************* intVecBaseGet - get the vector base address** This routine returns the current vector base address, which is set* with intVecBaseSet().** RETURNS: The current vector base address.** SEE ALSO: intVecBaseSet()*/FUNCPTR *intVecBaseGet (void) { return (intVecBase); }/******************************************************************************** intVecSet - set a CPU vector** This routine attaches an exception/interrupt handler to a specified vector.* The vector is specified as an offset into the CPU's vector table. This* vector table starts, by default, at address 0. However on 68010 and 68020* CPUs, the vector table may be set to start at any address with the* intVecBaseSet() routine. The vector table is set up in usrInit() and* starts at the lowest available memory address.** RETURNS: N/A** SEE ALSO: intVecBaseSet(), intVecGet()*/void intVecSet ( FUNCPTR * vector, /* vector offset */ FUNCPTR function /* address to place in vector */ ) { FUNCPTR * newVector; UINT state; BOOL writeProtected = FALSE; int pageSize = 0; char * pageAddr = 0; if (VXM_IF_VEC_SET (vector, function) == OK) /* can monitor do it? */ return; /* vector is offset by the vector base address */ newVector = (FUNCPTR *) ((int) vector + (int) intVecBaseGet ()); /* see if we need to write enable the memory */ if (vmLibInfo.vmLibInstalled) { pageSize = VM_PAGE_SIZE_GET(); pageAddr = (char *) ((UINT) newVector / pageSize * pageSize); if (VM_STATE_GET (NULL, (void *) pageAddr, &state) != ERROR) if ((state & VM_STATE_MASK_WRITABLE) == VM_STATE_WRITABLE_NOT) { writeProtected = TRUE; VM_STATE_SET (NULL, pageAddr, pageSize, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE); } } *newVector = function; if (writeProtected) { VM_STATE_SET (NULL, pageAddr, pageSize, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE_NOT); } CACHE_TEXT_UPDATE ((void *) newVector, sizeof (FUNCPTR)); }/********************************************************************************* intVecGet - get a vector* * This routine returns a pointer to the exception/interrupt handler* attached to a specified vector. The vector is specified as an* offset into the CPU's vector table. This vector table starts, by* default, at address 0. However, on 68010 and 68020 CPUs, the vector* table may be set to start at any address with intVecBaseSet().** RETURNS* A pointer to the exception/interrupt handler attached to the specified vector.** SEE ALSO: intVecSet(), intVecBaseSet()*/FUNCPTR intVecGet ( FUNCPTR *vector /* vector offset */ ) { FUNCPTR vec; if ((vec = VXM_IF_VEC_GET (vector)) != NULL) /* can monitor do it? */ return (vec); /* vector is offset by vector base address */ return (* (FUNCPTR *) ((int) vector + (int) intVecBaseGet ())); }/********************************************************************************* intVecTableWriteProtect - write protect exception vector table** If the unbundled Memory Management Unit (MMU) support package (VxVMI) is* present, this routine write-protects the exception vector table to* protect it from being accidentally corrupted.** Note that other data structures contained in the page will also be* write-protected. In the default VxWorks configuration, the exception* vector table is located at location 0 in memory. Write-protecting this* affects the backplane anchor, boot configuration information, and potentially* the text segment (assuming the default text location of 0x1000.) All code* that manipulates these structures has been modified to write-enable the * memory for the duration of the operation. If you select a different * address for the exception vector table, be sure it resides * in a page separate from other writable data structures.* * RETURNS: OK, or ERROR if unable to write protect memory.** ERRNO: S_intLib_VEC_TABLE_WP_UNAVAILABLE*/STATUS intVecTableWriteProtect ( void ) { int pageSize; UINT vectorPage; if (!vmLibInfo.vmLibInstalled) { errno = S_intLib_VEC_TABLE_WP_UNAVAILABLE; return (ERROR); } pageSize = VM_PAGE_SIZE_GET(); vectorPage = (UINT) intVecBaseGet () / pageSize * pageSize; return (VM_STATE_SET (0, (void *) vectorPage, pageSize, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE_NOT)); }/******************************************************************************** intRegsLock - modify a REG_SET to have interrupts locked.*/ int intRegsLock ( REG_SET *pRegs /* register set to modify */ ) { int oldSr = pRegs->sr; pRegs->sr |= intLockMask; return (oldSr); }/******************************************************************************** intRegsUnlock - restore an REG_SET's interrupt lockout level.*/ void intRegsUnlock ( REG_SET * pRegs, /* register set to modify */ int oldSr /* sr with int lock level to restore */ ) { pRegs->sr &= (~0x0700); pRegs->sr |= (oldSr & 0x0700); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -