procintrctl.c
来自「ge公司的dv4av4信号处理板的bsp源代码」· C语言 代码 · 共 357 行
C
357 行
/* procIntrCtl.c - 7410 Processor Interrupt driver */
/* Copyright 1984-1998 Wind River Systems, Inc. */
#include "copyright_wrs.h"
/*
$RCSfile: procIntrCtl.c $
Copyright 2001 DY4 Systems, Inc. All Rights Reserved.
$Revision: 1.7 $
$Name: AV4-ISP-R1.2-1 AV4-ISP-R1.2-0 HMTST2 HMTST1 DVT_AV4_4.101 AV4-VSP-R1.0-2 AV4-VSP-R1.0 CT-ISP-1.1 AV4 ISP 1.1 CT_R0.1_AV4/CAV4 CAV4_CP1 CHAMPtools FW 3.0 $ $State: Developmental $ $Locker: $
$Source: L:/SWRND/champAV2/src/vx/src/drv/intrCtl/rcs/procIntrCtl.c $
RCS Project Name: ChampAv2
Target: ChampAv2
Description: Interrupt handler for the ppc7410 on the ChampAv2 board.
Usage:
$Log: procIntrCtl.c $
Revision 1.7 2004/10/07 14:45:26Z dwinant
Updated to better handle edge-triggered interrupts.
Revision 1.6 2004/08/25 19:39:27 esaunder
Changed procIntrDeMux to clear interrupt in DISCO's
cause register, even when interrupt is spurious
(no interrupt handler installed).
Revision 1.5 2002/05/29 10:40:22 coopertr
Revision 1.4 2002/05/17 00:13:34 coopertr
Revision 1.3 2002/05/10 13:33:28 coopertr
Revision 1.2 2002/03/05 21:02:07 dsessler
Revision 1.1 2002/03/05 17:07:30 ilidwa
Initial revision
*/
/*
OVERVIEW
This interrupt controller provides interrupt management for the interrupts
into the 4 PowerPC processors. All interrupts are coming from the MUX.
The software defines "interrupt IDs" in the range 0 to 255. The software
sets or clears bits within the MUX or DISCO based on the interrupt ID.
When an interrupt occurs, the MUX will cause the PowerPC to service an
external interrupt. The PowerPC will do some minimal context save, and then
start execution at location 0x0500. vxWorks provides an interrupt service
"shell" which calls a C function of our choice: in our case it will be
the interrupt demultiplexer.
*/
/* includes */
#include "intLib.h"
#include "iv.h"
#include "bslInt.h"
#include "bsl.h"
#include "_bsl.h"
/*
* externs defined in bslInt.c
*/
extern int intStatsEnabled;
extern intVector intVectorTable[];
extern void (*pDefaultIsr)();
/* forward declarations */
LOCAL void procIntrDeMux (void);
LOCAL STATUS procIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR, int);
LOCAL int procIntEnable (int);
LOCAL int procIntDisable (int);
/*******************************************************************************
*
* procIntrInit - initialize MUX.
*
* This routine connects the default demultiplexers, procIntrDeMux(), to
* the external interrupt vector and associates all interrupt sources
* with the default interrupt handler. This routine is called by
* sysHwInit() in sysLib.c.
*
*
* RETURNS: OK
* NOMANUAL
*/
STATUS procIntrInit
(
void
)
{
VOIDFUNCPTR defaultVec;
/* Get the default vector connected to the External Interrupt (0x500) */
defaultVec = (VOIDFUNCPTR) excVecGet ((FUNCPTR *) _EXC_OFF_INTR);
/* Connect the interrupt demultiplexer to External Interrupt (0x500) */
excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, procIntrDeMux);
_func_intConnectRtn = procIntConnect;
_func_intEnableRtn = procIntEnable;
_func_intDisableRtn = procIntDisable;
/* Set up the interrupt mux */
_bslIntInit2();
/* Set all vectors to default handler */
bslIntSetVect (INT_ID_DEFAULT, defaultVec, 0);
return (OK);
}
/*******************************************************************************
*
* procIntConnect - 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.
*
* Interrupt ids (vect) are defined in bslInt.h. IDs 1 through 7
* are translated to interrupt IDs INT_ID_VME1 through INT_ID_VME7.
*
* RETURNS: OK, or ERROR if <vector> is unknown.
*
* SEE ALSO: procIntrCtl.h
*/
LOCAL STATUS procIntConnect
(
VOIDFUNCPTR * vect, /* interrupt vector to attach to */
VOIDFUNCPTR routine, /* routine to be called */
int parameter /* parameter to be passed to routine */
)
{
if ((int) vect >= 1 && (int) vect <= 7)
vect = (VOIDFUNCPTR *)((int)vect + INT_ID_VME1 - 1);
if (bslIntSetVect ((int) vect, routine, parameter) == 0)
{
return (OK);
}
return (ERROR);
}
/*******************************************************************************
*
* procIntEnable - Enable one of the interrupts.
*
* This routine will enable an interrupt by clearing the appropriate bit
* or, for muxed interrupts, by setting the appropriate bit in the
* mux's interrupt mask register.
*
* This function translates interrupt numbers 1-7 to interrupt IDs
* INT_ID_VME1 through INT_ID_VME7.
*
* RETURNS: 0, always.
*/
LOCAL int procIntEnable
(
int intNum /* interrupt ID to enable */
)
{
if (intNum >= 1 && intNum <= 7)
intNum += INT_ID_VME1 - 1;
if (bslIntEnable (intNum) == 0)
{
return (OK);
}
return (ERROR);
}
/*******************************************************************************
*
* procIntDisable - Disable an interrupt.
*
* This function translates interrupt numbers 1-7 to interrupt IDs
* INT_ID_VME1 through INT_ID_VME7.
*
* RETURNS: 0, always.
*/
LOCAL int procIntDisable
(
int intNum /* interrupt id to disable */
)
{
if (intNum >= 1 && intNum <= 7)
intNum += INT_ID_VME1 - 1;
if (bslIntDisable (intNum) == 0)
{
return (OK);
}
return (ERROR);
}
/*******************************************************************************
*
* procIntrDeMux - processor 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.
*
* This function determines the origin of interrupt,logs the interrupt
* using WindView logging function, and calls the appropriate ISR.
* It also collects information about the interrupts which is stored in the
* table of INT_VECTOR data structures.
*
* Inputs: none
* Return: void
*
* Notes:
* This function is for VxWorks only.
* When VxWorks not present use bslIntHandler.
* This function calls bslIntDemux to find out the interrupt id
* and it's vector. The assumption is that the value of interrupt id
* returned by bslIntDemux IS ALWAYS in range of 0 to 255.
*
* If ISR_LED_FLASH is enabled, this function turns off the
* front panel LED at the start of processing, and turns it
* back on at the end of processing. This visible indication
* can be helpful during debug, indicating if an application
* gets stuck in an ISR.
*
*/
LOCAL void procIntrDeMux
(
void
)
{
unsigned long startTime, stopTime, deltaTime;
unsigned long vect, reg;
int intId;
startTime = bslPpcLongGetTime (0);
#ifdef ISR_LED_FLASH_ENTRY
ISR_LED_FLASH_ENTRY;
#endif
/* get interrupt's ID and it's vector */
intId = bslIntDemux( &vect );
do
{
#ifdef INCLUDE_WINDVIEW
WV_EVT_INT_ENT( intId );
#endif
/*
* Clear interrupt in Disco's local cause register.
* Because some interrupts are triggered by more then
* one bit in a local cause register the ISR for that
* interrupt MUST process all bits that are currently set.
* Failure to do so may cause some interrupts to be lost.
* Interrupts that are trigered by multiple bits are:
* INT_ID_CPU_ERROR
* INT_ID_PCI0_PARITY_ERROR
* INT_ID_PCI1_PARITY_ERROR
* INT_ID_PCI0_SLAVE_FAILURE
* INT_ID_PCI1_SLAVE_FAILURE
* INT_ID_SDMA0
* INT_ID_SDMA1
* INT_ID_MPSC0
* INT_ID_MPSC1
* INT_ID_COMM_ETHER0
* INT_ID_COMM_MPSC0
* INT_ID_COMM_MPSC1
* INT_ID_ETHERNET0
*/
if( intVectorTable[intId].pCauseRegister )
{
reg = bslPpcSwapRead32((void*)intVectorTable[intId].pCauseRegister);
reg &= ~intVectorTable[intId].intEnable;
bslPpcSwapWrite32((void*)intVectorTable[intId].pCauseRegister, reg );
}
/* call ISR for this interrupt or default ISR if entry
* for ISR in intVectorTable is zero
*/
if( intVectorTable[intId].pIsr )
{
intVectorTable[intId].pIsr( intVectorTable[intId].param, vect );
}
else
{
pDefaultIsr(intId);
}
if( intStatsEnabled )
{
stopTime = bslPpcLongGetTime( 0 );
deltaTime = stopTime - startTime;
/* was this the longest time for this ISR? */
if( deltaTime > intVectorTable[intId].maxTime )
{
intVectorTable[intId].maxTime = deltaTime;
}
/* add deltaTime to the cumulative value of totalTime and increment count */
bslPpcLongAdd32( &intVectorTable[intId].totalTime,
&intVectorTable[intId].totalTime, deltaTime );
intVectorTable[intId].count++;
/* make stopTime a startTime of next interrupt */
startTime = stopTime;
}
intId = bslIntDemux( &vect ); /* get next interrupt */
} while( intId != INT_ID_SPURIOUS );
#ifdef ISR_LED_FLASH_EXIT
ISR_LED_FLASH_EXIT;
#endif
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?