/******************************************************************************
*
* tempeBusErrShow - Display any pending VME exceptions
*
* This routine is called by excTask, not directly by the ISR. It is
* responsible for displaying the contents of the VEAT and VEAL registers
* that are passed to it as arguments
*
* RETURNS: NA
*/
LOCAL void tempeBusErrShow
(
int tid,
UINT32 veat,
UINT32 veal
)
{
int am = (veat & TEMPE_VEAT_AM_MASK) >> TEMPE_VEAT_AM_BIT;
printf("\nVME Bus Error %sing ",
(veat & TEMPE_VEAT_WRITE_MASK) ? "writ" : "read");
switch (am)
{
case VME_AM_EXT_SUP_PGM:
case VME_AM_EXT_USR_PGM:
case VME_AM_EXT_SUP_DATA:
case VME_AM_EXT_USR_DATA:
printf("A32: 0x%8.8x", veal);
break;
case VME_AM_STD_SUP_PGM:
case VME_AM_STD_USR_PGM:
case VME_AM_STD_SUP_DATA:
case VME_AM_STD_USR_DATA:
printf("A24: 0x%6.6x", veal & 0x00ffffff);
break;
case VME_AM_SUP_SHORT_IO:
case VME_AM_USR_SHORT_IO:
printf("A16: 0x%4.4x", veal & 0x0000ffff);
break;
default:
printf("AM=0x%2.2x: %#x", am, veal);
break;
}
printf("\nTask 0x%x \"%s\" was suspended\n", tid, taskName(tid));
if (veat & TEMPE_VEAT_VEOF_MASK)
{
printf("VME exception overflow, later details lost.\n");
}
}
/******************************************************************************
*
* sysTempeBusErrIntr - Handle VME Bus Error interrupt
*
* This routine is invoked when the Tempe chip notices a VMEbus Exception
* and sets the VES bit in the VEAT register.
*
* RETURNS: NA
*/
void sysTempeBusErrIntr(int dummy) {
int tid = taskIdSelf();
UINT32 base = TEMPE_REG_BASE;
UINT32 veat = TEMPE_READ32 (base, TEMPE_VEAT);
UINT32 veal = TEMPE_READ32 (base, TEMPE_VEAL);
TEMPE_WRITE32_PUSH (base, TEMPE_VEAT, TEMPE_VEAT_VESCL_MASK);
excJobAdd(tempeBusErrShow, tid, veat, veal, 4, 5, 6);
/*
* When called from this ISR, the task ID returned by taskIdSelf()
* should be that of the task that the interrupt preempted and hence
* that of whatever caused the Bus Error to occur. Unfortunately
* however, that will not be the case if the Bus Error occurs in
* another ISR, or if a higher priority ISR was entered first that
* caused a task switch to occur. The chances of that are much
* higher if the bus error occurs while interrupts are disabled.
* Thus this approach is unreliable, but the best we can do...
*/
taskSuspend(tid); /* suspend *after* queueing the msg, just in case */
}