📄 m8260intrctl.c
字号:
}
/*******************************************************************************
*
* 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) > INUM_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();
/* read the interrupt vector register */
while(1)
{
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 */
intLock();
* 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();
if ((intNum > 0) && (intNum <= 55))
{
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();
if ((intNum >= 0) && (intNum <= INUM_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 + -