📄 m8260intrctl.c
字号:
{
/* test the vector */
if (((int)(vector) < 0) || ((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 only condition upon which this function exits is that
* SIVEC's vector value is INUM_ERROR(no other interrupt occurs).
*
* NOTE: when this function is called the interrupts are still locked. It's
* this function's 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(INUM_ERROR == 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 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 the indicated interrupt
*
* This routine will mask the bit in the SIMASK register corresponding to
* the requested interrupt number.
*
* RETURNS: 0, always.
*/
int m8260IntDisable
(
int intNum /* interrupt 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;
}
/*******************************************************************************
*
* m8260InumToIvec - get the relevant interrupt vector
*
* This routine finds out the interrupt vector associated with the interrupt
* number in <intNum>.
*
* <intNumb> are defined in m8260IntrCtl.h.
*
* RETURNS: the interrupt vector for the number
*
* SEE ALSO: m8260IntrCtl.h
*/
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 m8260IntrCtl.h.
*
* RETURNS: the interrupt number for the vector
*
* SEE ALSO: m8260IntrCtl.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);
}
/*******************************************************************************
*
* m8260IntTypeSet - set interrupt trigger type
*
* This routine provide interface for setting up triggering type of PORT c and
* IRQ[0..7]. Only Port C and IRQ[0..7] have this option. When mode set is not
* applicable, nothing will be done.
*
* NOTE:
* - Valid type for Port C: INT_TYPE_BOTH_EDGE, INT_TYPE_FALL
* - Valid type for IRQ[0..7]: INT_TYPE_LOW, INT_TYPE_FALL
* - disable the corresponding interrupt before invoe this function
*
* RETURNS: OK, or ERROR on invalid type for the interrupt.
*
* SEE ALSO: m8260IntrCtl.h
*/
STATUS m8260IntTypeSet
(
int intNum, /* interrupt to be set */
int intType /* trigger type to be set */
)
{
UINT32 immrVal = (vxImmrGet() & IMMR_ISB_MASK);
/* set port C interrupt type */
if(intNum >= INUM_PC15 || intNum <= INUM_PC0)
{
switch(intType)
{
case INT_TYPE_BOTH_EDGE:
*M8260_SIEXR(immrVal) &= ~(1 << (intNum - 24)); /* clear bit */
break;
case INT_TYPE_FALL:
*M8260_SIEXR(immrVal) |= (1 << (intNum - 24)); /* set bit */
break;
default:
return (ERROR); /* invalid interrupt type */
}
}
/* set IRQ0~7 interrupt type */
if(intNum >= INUM_IRQ0 && intNum <= INUM_IRQ7)
{
switch(intType)
{
case INT_TYPE_LOW:
*M8260_SIEXR(immrVal) &= ~(1 << (33 - intNum)); /* clear bit */
break;
case INT_TYPE_FALL:
*M8260_SIEXR(immrVal) |= (1 << (33 - intNum)); /* set bit */
break;
default:
return (ERROR); /* invalid interrupt type */
}
}
return (OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -