⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m5200intr.c

📁 mpc5200 for bsp,it is have passed built.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* m5200Intr.c - Motorola MPC5200 interrupt driver *//* Copyright 1989-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01d,11nov03,pdr  added support for main interrupt.01c,24sep03,pdr  added support for Slice Timer 1.            pkr01b,17sep03,pdr  changed registers method access.01a,03jul03,pkr  derived from ppc860Intr.c*//*DESCRIPTIONThis module provides the interrupt handler libary for the MPC5200. *//* includes */#include "intLib.h"#include "dbgLib.h"#include "iv.h"#include "drv/intrCtl/m5200Intr.h"#include "rebootLib.h"#include "fioLib.h"#ifdef  INCLUDE_WINDVIEW#include "private/funcBindP.h"#include "private/eventP.h"#include "wdb/wdbDbgLib.h"#endif /* INCLUDE_WINDVIEW */FUNCPTR _func_sdmaIntEnableRtn = NULL;FUNCPTR _func_sdmaIntDisableRtn = NULL;FUNCPTR _func_sdmaIntSetLevelRtn = NULL;void m5200SdmaIntTrigger(int intNum);/* local */LOCAL INTR_HANDLER	intrVecTable[NUM_VEC_MAX];	/*  Intr vector table *//* all peripheral sources at level i have their corresponding PIMR bit set in   lvlPIMR[i].   mskPIMR[i] is the union of all lvlPIMR[j] with j > i */   LOCAL UINT32		lvlPIMR[16];LOCAL UINT32		mskPIMR[16];/* forward declarations */LOCAL void	m5200ExtIntrDeMux (void);LOCAL void	m5200SysMngIntrDeMux (void);LOCAL STATUS	m5200IntConnect (VOIDFUNCPTR *, VOIDFUNCPTR, int);LOCAL int	m5200IntEnable (int);LOCAL int	m5200IntDisable (int);LOCAL void	m5200MachCheckHandler(ESFPPC *pEsf);LOCAL void	m5200ExcInfoShow (EXC_INFO *pExcInfo, BOOL doBell);LOCAL VOIDFUNCPTR org_func_excInfoShow = NULL;#if USE_CRITICAL_INTERRUPT#define _EXC_OFF_CRIT _EXC_OFF_RES1LOCAL void	m5200CriticalIntrDeMux (int);#endif/********************************************************************************* m5200IntrInit - initialize the interrupt manager for the PowerPC 800 series** This routine connects the default demultiplexers, m5200IntrDeMux() and * m5200CpmIntrDeMux, to the external interrupt vector and associates all * interrupt sources with the default interrupt handler.  This routine is* called by sysHwInit() in sysLib.c.** NOTE: All interrupt from the SIU and CPM unit are enabled, CICR is setup so* that SCC1 has the highest relative interrupt priority, through SCC4 with the* lowest.** RETURN : OK or ERROR if the SUI interrupt level to connect the CPM * interrupt contoller is wrong.*/STATUS m5200IntrInit     (    void    )    {    VOIDFUNCPTR defaultVec;     	/* INTR3 default vector */    int		vector;    int 	level;    /* Get the default vector connected to the Machine Check exception */    defaultVec = (VOIDFUNCPTR) excVecGet ((FUNCPTR *) _EXC_OFF_MACH);    /* Connect new machine check handler */    excConnect ((VOIDFUNCPTR *) _EXC_OFF_MACH, m5200MachCheckHandler);    /* 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, m5200ExtIntrDeMux);    /* Get the default vector connected to the System Mng Interrupt (0x1400) */    defaultVec = (VOIDFUNCPTR) excVecGet ((FUNCPTR *) _EXC_OFF_SYS_MNG);    /* Connect the interrupt demultiplexer to System Mng Interrupt (0x1400) */    excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_SYS_MNG, m5200SysMngIntrDeMux);#if USE_CRITICAL_INTERRUPT    /* Get the default vector connected to the Critical Interrupt (0xA00) */    defaultVec = (VOIDFUNCPTR) excVecGet ((FUNCPTR *) _EXC_OFF_CRIT);    /* Connect the interrupt demultiplexer to Critical Interrupt (0xA00) */    excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_CRIT, m5200CriticalIntrDeMux);#endif    /* Install `system' intConnect routine */    if (_func_intConnectRtn == NULL)        _func_intConnectRtn = m5200IntConnect;    if (_func_intEnableRtn == NULL)        _func_intEnableRtn = m5200IntEnable;    if (_func_intDisableRtn == NULL)        _func_intDisableRtn = m5200IntDisable;    /* Set all vectors to default handler */    for (vector = 0; vector < NUM_VEC_MAX; vector++)	intConnect (INUM_TO_IVEC(vector), defaultVec, 0);    /* initially we have all masked and level is all 0 */    lvlPIMR[0] = 0xFFFFFFFF;    for(level=1; level < 15; level++)	lvlPIMR[level] = 0;    mskPIMR[0] = 0x0;    for(level=1; level < 15; level++)	mskPIMR[level] = 0xFFFFFFFF;    /* Init SIU  */    *ICTL_PIMR   = 0xFFFFFFFF; /* mask all peripheral interrupts */    ICTL_PPR[0]  = 0x0;        /* peripherals prio 0 */    ICTL_PPR[1]  = 0x0;        /* peripherals prio 0 */    ICTL_PPR[2]  = 0x0;        /* peripherals prio 0 */    /* clear and disable all IRQ's */    *ICTL_EEETR  = ICTL_EEETR_ECLR0_MASK | ICTL_EEETR_ECLR1_MASK | ICTL_EEETR_ECLR2_MASK		     | ICTL_EEETR_ECLR3_MASK;    *ICTL_EEETR  |= ICTL_EEETR_MEE;#if !USE_CRITICAL_INTERRUPT    *ICTL_EEETR  |= ICTL_EEETR_CEb; /* set CEb */#endif    *ICTL_CPMIMR = 0x0001EFFF;  /* mask all main interrupts but LO */    ICTL_MIPR[0] = 0x00070000;  /* main ints prio 0, LO to prio 7 */    ICTL_MIPR[1] = 0x0;         /* main ints prio 0 */    /* make sure no critical interrupt is pending */    /* Reset Slice Timer 0 */    *SLT0_CTRL = 0;    /* Reset Slice Timer 0 Status Bit */    *SLT0_STATUS = SLT_STATUS_RESET;    /* Setup XLB  */    /* addresss and data timeout */    *XLB_CR	|= XLB_CR_DT_ENABLED | XLB_CR_AT_ENABLED;    *XLB_SR	= XLB_SR_CLEAR_ALL;    *XLB_IER	= 0;    *XLB_ATTOR	= XLB_ADDR_TO;    *XLB_DTTOR	= XLB_DATA_TO;    return (OK);     }/********************************************************************************* m5200IntConnect - 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.** <vector> types are defined in h/drv/intrClt/m5200Intr.h.** RETURNS: OK, or ERROR if <vector> is unknown.** SEE ALSO: m5200Intr.h*/LOCAL STATUS m5200IntConnect    (    VOIDFUNCPTR *	vector,		/* interrupt vector to attach to */    VOIDFUNCPTR		routine,	/* routine to be called */    int 		parameter	/* parameter to be passed to routine */    )    {    int inum = IVEC_TO_INUM(vector);    /* test the vector */    if (inum >= NUM_VEC_MAX)	return (ERROR);    intrVecTable[IVEC_TO_INUM(vector)].vec = routine;    intrVecTable[IVEC_TO_INUM(vector)].arg = parameter;    m5200IntrSetLevel (inum, INTR_LEVEL_DEFAULT);    return (OK);    }void m5200SdmaIntTrigger(int intNum){    if (intNum < INUM_SDMA_FIRST || intNum > INUM_SDMA_LAST)	return;    /* make sure other sdma interrupts can be handled while this on is served */    /* TBD */    /* EE is already unlocked but SDMA int level is masked */        intrVecTable[intNum].vec (intrVecTable[intNum].arg);}/********************************************************************************* m5200ExtIntrDeMux - 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 interrupts are prioritized in the following order:** NOTE: when this function is called the interrupts are still locked. It's* this function responsability to unlock the interrupt.** RETURNS: N/A*/LOCAL void m5200ExtIntrDeMux (void)    {    UINT32 isr;    UINT32 isr_PSe;    UINT32 isr_MSe;#if !USE_CRITICAL_INTERRUPT    UINT32 isr_CSe;    UINT32 isr_CSe_Nr;#endif    VOIDFUNCPTR *vector;    UINT32 intMask;    isr = *ICTL_ISR;			/* get interrupt status */#if !USE_CRITICAL_INTERRUPT    /* check for critical interrupt */    if ((isr_CSe = (isr & ICTL_ISR_CSe_MASK)) != 0)        {	isr_CSe_Nr = isr_CSe &  ICTL_ISR_CSe_MASK_NR;        isr_CSe_Nr >>= ICTL_ISR_CSe_SHIFT;        vector = INUM_TO_IVEC(INUM_CRITICAL_FIRST + isr_CSe_Nr);        }    else#endif    /* check for peripheral interrupt BEFORE main interrupt */    if ((isr_PSe = (isr & ICTL_ISR_PSe_MASK)) != 0)        { 	isr_PSe &= ICTL_ISR_PSe_MASK_NR;        isr_PSe >>= ICTL_ISR_PSe_SHIFT;        vector = INUM_TO_IVEC(INUM_PERIPHERAL_FIRST + isr_PSe);        }    else    /* check for main interrupt routed this way */    if ((isr_MSe = (isr & ICTL_ISR_MSe_MASK)) != 0)	{	isr_MSe  &= ICTL_ISR_MSe_MASK_NR;	isr_MSe >>= ICTL_ISR_MSe_SHIFT;	vector    = INUM_TO_IVEC(INUM_MAIN_FIRST + isr_MSe);	}    else    /* spurious interrupt */	{	return;	}#ifdef  INCLUDE_WINDVIEW    WV_EVT_INT_ENT(vector)#endif#if !USE_CRITICAL_INTERRUPT/* TBD correct prio handling */    if (isr_CSe > 0)        {	/* as there is no masking of the critical interrupts, the MSR_EE needs	   to remain set until the ISR deasserts the interrupt cause	   It shall call m5200IntAck() for that purpose */        }     else#endif    if (isr_MSe > 0)	{	/* save the current interrupt mask */ 	intMask = *ICTL_CPMIMR;		*ICTL_CPMIMR |= ICTL_CPMIMR_MASK_ALL; /* mask all for now -> no nesting */		/* unlock the interrupt */	#if 0        /* TBD: remove to enable nesting */	intUnlock (_PPC_MSR_EE);#endif	}    else        {        intMask = *ICTL_PIMR;        /* lock all levels inferior to the interrupt detected */        /* those with lower priority level are all in mskPIMR[isr_PSe] */        *ICTL_PIMR |= mskPIMR[isr_PSe];        /* those with same priority level are all in lvlPIMR[isr_PSe]           mask only those bits on the right hand side and including isr_PSe */        *ICTL_PIMR |= (lvlPIMR[isr_PSe] & ( ( 1 << (32-isr_PSe) ) - 1));        /* unlock the interrupt */#if 0        /* TBD: remove to enable nesting */        intUnlock (_PPC_MSR_EE);#endif        }    /* call the Interrupt Handler */    intrVecTable[IVEC_TO_INUM(vector)].vec (intrVecTable[IVEC_TO_INUM(vector)].arg);    /* restore the interrupt mask */#if !USE_CRITICAL_INTERRUPT    if (isr_CSe > 0)        {        /* unlock the interrupt in case the ISR did not call m5200IntAck */            intUnlock (_PPC_MSR_EE);        }     else#endif        if (isr_MSe >0)        {        *ICTL_CPMIMR = intMask;        }    else	{        *ICTL_PIMR = intMask;	}    return;    }/********************************************************************************* m5200SysMngIntrDeMux - SIU interrupt demultiplexer ** This routine must be bound to system management interrupt exception (vector 0x1400). * It is used to call the appropriate handler with its argument when an* interrupt occurs. ** The interrupts are prioritized in the following order:** NOTE: when this function is called the interrupts are still locked. It's* this function responsability to unlock the interrupt.** RETURNS: N/A*/LOCAL void m5200SysMngIntrDeMux (void)    {    UINT32 isr;    UINT32 isr_MSe;    VOIDFUNCPTR *vector;    UINT32 intMask;    isr = *ICTL_ISR;			/* get interrupt status */    /* check for main interrupt */    if ((isr_MSe = (isr & ICTL_ISR_MSe_MASK)) != 0)        { 	isr_MSe &= ICTL_ISR_MSe_MASK_NR;        isr_MSe >>= ICTL_ISR_MSe_SHIFT;        vector = INUM_TO_IVEC(INUM_MAIN_FIRST + isr_MSe);        }     else        {	return;	}#ifdef  INCLUDE_WINDVIEW    WV_EVT_INT_ENT(vector)#endif	    /* save the current interrupt mask */ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -