EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: VME Bus Error handling for the mv6100 BSP
From: Andrew Johnson <[email protected]>
To: undisclosed-recipients:;
Date: Fri, 02 Feb 2007 11:43:33 -0600
On the MVME6100 board, the only way to trap VME bus errors is with an interrupt vector since there is no Machine Check Exception generated by the Tempe chip. The following code is probably the best we can do to get a bus error to suspend the relevent task (it isn't guaranteed that we'll actually catch the right task and woe betide you if an ISR causes a bus error, although this does seem to work for the common cases in my tests).

I'm sending this message directly to the tech-talk archive without copying it to tech-talk, in order to avoid a message storm about the subject.

The Bus Error handling changes are all in the sysTempeInt.c file. First you need to add a line to the includes section near the top:

#include "excLib.h"

Then in sysTempeIntInit() add this code:


intConnect (INUM_TO_IVEC (TEMPE_INT_NUM_VERR), sysTempeBusErrIntr, 0);

    /* Clear any pending VEAT errors, enable the interrupt */
    TEMPE_WRITE32_PUSH (TEMPE_REG_BASE, TEMPE_VEAT, TEMPE_VEAT_VESCL_MASK);
    intEnable (TEMPE_INT_NUM_VERR);

Finally add these two routines, preferably just above sysTempeIntInit() so you don't have to declare them higher up:


/******************************************************************************
* * 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 */
}

- Andrew -- The right to be heard does not automatically include the right to be taken seriously. -- Hubert H. Humphrey

Navigate by Date:
Prev: IOC-OCTAVE server Miroslaw Dach
Next: Imminent ASYN release Eric Norum
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: IOC-OCTAVE server Miroslaw Dach
Next: Imminent ASYN release Eric Norum
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 10 Nov 2011 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·