📄 sysepic.c
字号:
/* initialize the interrupt table */
for (vector = 0; vector < INTERRUPT_TABLESIZE; vector++)
{
sysIntTbl [vector] = NULL;
}
/*
* connect the interrupt demultiplexer to the PowerPC external
* interrupt exception vector.
* i. e. put the address of this interrupt handler in
* the PowerPC's only external interrupt exception vector
* which is _EXC_OFF_INTR = 0x500
*/
excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, sysEpicIntHandler);
/*
* set up the BSP specific interrupt routines
* Attach the local routines to the VxWorks system calls
*
*/
_func_intConnectRtn = sysEpicIntConnect;
_func_intEnableRtn = sysEpicIntEnable;
_func_intDisableRtn = sysEpicIntDisable;
epicCurTaskPrioSet (EPIC_PRIORITY_MIN); /* set it to lowest priority */
return (OK);
}
/*******************************************************************************
*
* sysEpicIntEnable - enable a EPIC interrupt level
*
* This routine enables a specified EPIC interrupt level.
*
* NOMANUAL
*
* RETURNS: OK.
*/
LOCAL int sysEpicIntEnable
(
int intNum
)
{
/* enable interrupt on vt82c686 */
if ((intNum >= INT_NUM_IRQ0) && /* check of vt82c686 IRQs */
(intNum != EPIC_DUART1_INT_VECT) &&
(intNum != EPIC_DUART2_INT_VECT))
{
intNum = intNum - INT_NUM_IRQ0;
if ((sysPciIbcIntEnable (intNum)) != OK)
{
return (ERROR);
}
return (OK);
}
/* enable interrupt on EPIC */
if (((0 <= intNum) && (intNum < EPIC_MAX_EXT_IRQS)) ||
(intNum == EPIC_DUART1_INT_VECT) ||
(intNum == EPIC_DUART2_INT_VECT))
{
epicIntEnable (EPIC_VEC_REG (intNum));
return OK;
}
else
{
return (ERROR);
}
}
/*******************************************************************************
*
* sysEpicIntDisable - disable a EPIC interrupt level
*
* This routine disables a specified EPIC interrupt level.
*
* NOMANUAL
*
* RETURNS: OK.
*/
LOCAL int sysEpicIntDisable
(
int intNum
)
{
int mask;
/* disable interrupt on vt82c686 */
if ((intNum >= INT_NUM_IRQ0) && /* check of vt82c686 IRQs */
(intNum != EPIC_DUART1_INT_VECT) &&
(intNum != EPIC_DUART2_INT_VECT))
{
intNum = intNum - INT_NUM_IRQ0;
mask = sysPciIbcIntDisable (intNum);
if (mask == ERROR)
{
return (ERROR);
}
return (OK);
}
/* disable interrupt on EPIC */
if (((0 <= intNum) && (intNum < EPIC_MAX_EXT_IRQS)) ||
(intNum == EPIC_DUART1_INT_VECT) ||
(intNum == EPIC_DUART2_INT_VECT))
{
epicIntDisable (EPIC_VEC_REG(intNum));
return OK;
}
else
{
return (ERROR);
}
}
/*******************************************************************************
*
* sysEpicIntConnect - connect an interrupt handler to the system vector table
*
* This function connects an interrupt handler to the system vector table.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS sysEpicIntConnect
(
VOIDFUNCPTR * vector, /* interrupt vector to attach */
VOIDFUNCPTR routine, /* routine to be called */
int parameter /* parameter to be passed to routine */
)
{
INT_HANDLER_DESC * pNewHandler;
INT_HANDLER_DESC * pCurrHandler;
int intVal;
BOOL sharing = FALSE;
if (((int)vector < 0) || ((int) vector > INTERRUPT_TABLESIZE))
{
return (ERROR); /* out of range */
}
/* create a new interrupt handler */
pNewHandler = malloc (sizeof (INT_HANDLER_DESC));
/* check if the memory allocation succeed */
if (pNewHandler == NULL)
return (ERROR);
/* initialize the new handler */
pNewHandler->vec = routine;
pNewHandler->arg = parameter;
pNewHandler->next = NULL;
/* install the handler in the system interrupt table */
intVal = intLock (); /* lock interrupts to prevent races */
if (sysIntTbl [(int) vector] == NULL)
{
sysIntTbl [(int) vector] = pNewHandler; /* single int. handler case */
}
else
{
pCurrHandler = sysIntTbl[(int) vector];/* multiple int. handler case */
while (pCurrHandler->next != NULL)
{
pCurrHandler = pCurrHandler->next;
}
pCurrHandler->next = pNewHandler;
sharing = TRUE;
}
if ((int)vector >= 0 && (int)vector < INT_VEC_IRQ0)
{
/* EPIC IRQ set EPIC registers, priority = WB_PRIO + vector */
if (!sharing)
{
epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY,
EPIC_SENSE_LVL, (int) (vector+6), (int) vector);
}
}
else
{
if ((int)vector == EPIC_DUART1_INT_VECT) /* setup duart 1 */
{
if (!sharing)
epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY, \
EPIC_SENSE_LVL, 0x03, (int)vector);
}
else
if ((int)vector == EPIC_DUART2_INT_VECT) /* setup duart 2 */
{
if (!sharing)
epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY, \
EPIC_SENSE_LVL, 0x05, (int)vector);
}
}
intUnlock (intVal);
return (OK);
}
/*******************************************************************************
*
* sysEpicIntHandlerExec - execute the handlers for a given vector
*
* This routine executes all the handlers chained to a given vector.
* If a vector has no handlers attached to it, a logMsg is generated.
*
* NOMANUAL
*
* RETURNS: N/A
*
*/
void sysEpicIntHandlerExec
(
UCHAR intVec
)
{
INT_HANDLER_DESC * pCurrHandler;
/* call each respective interrupt handler */
if ((pCurrHandler = sysIntTbl [intVec]) == NULL)
{
logMsg ("uninitalized PIC interrupt vector %x\r\n",
intVec, 0,0,0,0,0);
}
else
{
if (epicIntTrace)
{
/* execute duart interrupts */
if ((intVec == EPIC_DUART1_INT_VECT) || (intVec == EPIC_DUART2_INT_VECT))
logMsg ("sysEpicIntHandlerExec, duart interrupt vector %x\r\n",intVec, 0,0,0,0,0);
}
/* call Each respective chained interrupt handler */
while (pCurrHandler != NULL)
{
(*pCurrHandler->vec) (pCurrHandler->arg);
pCurrHandler = pCurrHandler->next;
}
} /* else */
}
/*******************************************************************************
*
* sysEpicIntHandler - handles the EPIC interrupts to the CPU
*
* This routine handles interrupts originating from the embedded interrupt
* controller on the MPC8240 Power PC processor.
* This handler is entered from the 0x500 exception.
*
* This routine is entered with CPU external interrupts enables.
*
* Since the EPIC is the primary interrupt controller this driver
* first initiates an Epic acknowledge call and reads the vector
* put out by the EPIC. Subsequent vectors have to be obtained if
* an external interrupt controller is connected to one of the
* epic handlers.
*
* This routine then processes the interrupt by calling all the interrupt
* service routines chained to the vector.
*
* Finally, this routine re-arms the interrupt at the PIC by performing an
* PIC EOI for both the EPIC and the 8259s.
*
* RETURNS: N/A
*
*/
void sysEpicIntHandler (void)
{
int dontCare;
UCHAR epicIntVec;
INT32 oldLock;
#if FALSE
int oldLevel;
#endif
oldLock = intLock (); /* LOCK INTERRUPT */
epicIntVec = epicIntAck (); /* clear int, return the vec for highest IRQ */
/* loop till all interrupts are cleared */
while (epicIntVec != 0xff)
{
if (epicIntTrace)
{
/* execute duart interrupt handler */
if ((epicIntVec == EPIC_DUART1_INT_VECT) || (epicIntVec == EPIC_DUART2_INT_VECT))
logMsg ("sysEpicIntHandler: duart interrupt vector %x\r\n",epicIntVec, 0,0,0,0,0);
}
#ifdef INCLUDE_WINDVIEW
WV_EVT_INT_ENT (epicIntVec);
#endif
#if FALSE
/* block all lower priority interrupts */
if ((oldLevel = epicCurTaskPrioSet (epicIntVec)) == EPIC_INV_PRIO_ERROR)
{
return;
}
#endif
/* Allow external interrupts to the CPU. */
/*CPU_INT_UNLOCK (_PPC_MSR_EE);*/
/*if(epicIntVec == 4)
logMsg("epicIntVec = 0x%x\n",epicIntVec,0,0,0,0,0);*/
sysEpicIntHandlerExec (epicIntVec);
/*
* Disable External Interrupts
* External Interrupts will be re-enabled in the kernel's wrapper
* of this Interrupt.
*/
/*CPU_INT_LOCK (&dontCare);*/
WRS_ASM ("sync");
epicEOI (); /* signal end of interrupt on EPIC */
WRS_ASM ("sync");
epicIntVec = epicIntAck ();
#if FALSE
epicCurTaskPrioSet (oldLevel); /* Allow the next interrupt to occur */
#endif
} /* while */
intUnlock (oldLock); /* UNLOCK INTERRUPT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -