📄 m8260intrctl.c
字号:
/* Set all vectors to default handler */ for (vector = 0; vector <= IVEC_MAX; vector++) intConnect (INUM_TO_IVEC(vector), (VOIDFUNCPTR) defaultVec, 0); /* disable all interrupts */ *M8260_SIMR_L(immrVal) = 0x00000000; *M8260_SIMR_H(immrVal) = 0x00000000; return (OK); }/********************************************************************************* m8260IntConnect - connect a routine to an interrupt ** This routine connects any C or assembly routine to one of the multiple * sources of interrupts.** The connected routine can be any normal C code, except that it must not * invoke certain operating system functions that may block or perform I/O* operations.** <vector> types are defined in h/drv/intrClt/m8260Intr.h.** RETURNS: OK, or ERROR if <vector> is unknown.** SEE ALSO: m8260Intr.h*/LOCAL STATUS m8260IntConnect ( VOIDFUNCPTR * vector, /* interrupt vector to attach to */ VOIDFUNCPTR routine, /* routine to be called */ int parameter /* parameter to be passed to routine */ ) { /* test the vector */ if ((int)(vector) > IVEC_MAX) return (ERROR); intrVecTable[(int)(vector)].vec = routine; intrVecTable[(int)(vector)].arg = parameter; return (OK); }/********************************************************************************* m8260IntrDeMux - SIU interrupt demultiplexer ** This routine must be bound to external interrupt exception (vector 0x500). * It is used to call the appropriate handler with its argument when an* interrupt occurs. ** The interrupts are prioritized in the following order:** NOTE: when this function is called the interrupts are still locked. It's* this function responsability to unlock the interrupt.** RETURNS: N/A*/void m8260IntrDeMux (void) { VINT32 intVec; /* interrupt vector */ UINT32 oldIntMask_L; /* current interrupt mask */ UINT32 oldIntMask_H; /* current interrupt mask */ UINT32 immrVal = (vxImmrGet() & IMMR_ISB_MASK); while(WAIT_FOREVER) { /* read the interrupt vector register */ intVec = (0x0000003f & ((* M8260_SIVEC(immrVal)) >> 26)); if(!intVec) { break; }#ifdef INCLUDE_WINDVIEW WV_EVT_INT_ENT(intVec)#endif /* INCLUDE_WINDVIEW */ /* save the current interrupt mask */ oldIntMask_L = * M8260_SIMR_L(immrVal); oldIntMask_H = * M8260_SIMR_H(immrVal); /* enable only the higher priority interrupts */ * M8260_SIMR_L(immrVal)&= enableHighPriInts[IVEC_TO_INUM((VOIDFUNCPTR *)intVec)].simr_l; * M8260_SIMR_H(immrVal)&= enableHighPriInts[IVEC_TO_INUM((VOIDFUNCPTR *)intVec)].simr_h; /* unlock the interrupt */ intUnlock (_PPC_MSR_EE); /* call the Interrupt Handler */ /* table is indexed by vector */ intrVecTable[intVec].vec (intrVecTable[intVec].arg); /* restore the interrupt mask */ * M8260_SIMR_L(immrVal) = oldIntMask_L; * M8260_SIMR_H(immrVal) = oldIntMask_H; } return; }/********************************************************************************* m8260IntEnable - enable the indicated interrupt** This routine will enable the indicated interrupt by setting the appropriate* bit in the SIU Interrupt Mask Registers.** The design of the 8260 presents the following design requirements:** 1. the mapping from interrupt number to mask bit can not be represented by * a function. An array, indexed by interrupt number (INUM), is used to map* the interrupt number to the appropriate mask. ** 2. There are two 32 bit mask registers (SIMR_L and SIMR_H). The interrupt* number must be compared to 4 ranges to determine which register contains* its mask bit:* * .CS* interrupt number* in m8260IntrCtl.h register* ---------------- -------* 0-15 SIMR_L* 16-31 SIMR_H* 32-47 SIMR_L* 48-63 SIMR_H* .CE** RETURNS: 0, always.*/int m8260IntEnable ( int intNum /* interrupt level to enable */ ) { UINT32 immrVal = (vxImmrGet() & IMMR_ISB_MASK); if ((intNum > 0) && (intNum <= IVEC_MAX)) { if (((intNum >= 0) && (intNum <= 15)) || ((intNum >= 27) && (intNum <= 38))) *M8260_SIMR_L(immrVal) |= iNumToMaskPattern[intNum]; else *M8260_SIMR_H(immrVal) |= iNumToMaskPattern[intNum]; } return 0; }/********************************************************************************* m8260IntDisable - Disable one of the Level or IRQ interrupts into the SIU** This routine will mask the bit in the SIMASK register corresponding to* the requested interrupt level. * * RETURNS: 0, always.*/int m8260IntDisable ( int intNum /* interrupt level to disable */ ) { UINT32 immrVal = (vxImmrGet() & IMMR_ISB_MASK); if ((intNum >= 0) && (intNum <= IVEC_MAX)) { if (((intNum >= 0) && (intNum <= 15)) || ((intNum >= 27) && (intNum <= 38))) *M8260_SIMR_L(immrVal) &= ~iNumToMaskPattern[intNum]; else *M8260_SIMR_H(immrVal) &= ~iNumToMaskPattern[intNum]; } return 0; }VOIDFUNCPTR * m8260InumToIvec ( int intNum ) { if (intNum <0) /* error */ return ((VOIDFUNCPTR *) 0); else if (intNum <= 25) return ((VOIDFUNCPTR *) intNum); else if (intNum == 26) /* error */ return ((VOIDFUNCPTR *) 0); else if (intNum <= 38) return ((VOIDFUNCPTR *) (intNum + 5)); else if (intNum == 39) /* error */ return ((VOIDFUNCPTR *) 0); else if (intNum <= 55) return ((VOIDFUNCPTR *) (intNum + 8)); else /* error */ return ((VOIDFUNCPTR *) 0); }/********************************************************************************* m8260IvecToInum - get the relevant interrupt number** This routine finds out the interrupt number associated with the vector* in <vector>.** <vector> types are defined in h/drv/intrClt/m8260Intr.h.** RETURNS: the interrupt number for the vector** SEE ALSO: m8260Intr.h*/ int m8260IvecToInum ( VOIDFUNCPTR * vector /* interrupt vector to attach to */ ) { /* test the vector */ if ((int) (vector) <= 0) return ((int ) 0); else if ((int) vector < INUM_RESERVED26) return ((int) vector); else if ((int) vector < 32) return (INUM_RESERVED26); else if ((int) vector < 44) return ((int) vector - 5); else if ((int) vector < 48) return ((int) INUM_RESERVED39); else if ((int) vector <= IVEC_MAX) return ((int) vector - 8); else return (0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -