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

📄 excarchlib.c

📁 vxworks的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** excBErrVecInit - initialize the bus error interrupt vector** This routine sets the specified bus error interrupt vector to point to* a special bridge-routine to emulate a bus error exception.  The SH* architecture does not have a bus error exception, but some boards could* detect a VME bus timeout error and report it to CPU using interrupt* mechanism.  To treat this type of interrupt as an exception, BSP should call* this routine to specify the bus error interrupt vector.  Also the interrupt* acknowledge function pointer _func_excBErrIntAck must be initialized by BSP.* Then the interrupt is treated as an exception, and the handler run in the* context of offending task.** WHEN TO CALL* This routine may be called from sysHwInit2() in BSP, if necessary.** RETURNS: OK if specified vector is valid, ERROR otherwise.*/STATUS excBErrVecInit    (    int inum    )    {    STATUS status = ERROR;    /* set global variable to specify bus error interrupt vector number */    excBErrVecNum = inum;    /* set bus error emulation vector */#if (CPU==SH7750 || CPU==SH7700)    if ((inum >= INUM_INTR_LOW && inum <= INUM_INTR_HIGH) || inum == INUM_NMI)	{	UINT vecAddr = (UINT)intVecBaseGet () + SH7700_EXC_BERR_STUB_OFFSET;	intVecSet ((FUNCPTR *)INUM_TO_IVEC (inum), (FUNCPTR)vecAddr);	status = OK;	}#elif (CPU==SH7600 || CPU==SH7000)    if ((inum > INUM_USER_BREAK && inum <= HIGH_VEC) || inum == INUM_NMI)	{	intVecSet ((FUNCPTR *)INUM_TO_IVEC (inum), (FUNCPTR)excBsrTblBErr);	status = OK;	}#endif /* CPU==SH7600 || CPU==SH7000 */    return status;    }/******************************************************************************** excExcHandle - interrupt level handling of exceptions** This routine handles exception traps.  It is never to be called except* from the special assembly language interrupt stub routine.** It prints out a bunch of pertinent information about the trap that* occurred via excTask.** Note that this routine runs in the context of the task that got the exception.** NOMANUAL*/void excExcHandle    (    int		vecNum,	/* exception vector number */    ESFSH *	pEsf,	/* pointer to exception stack frame */    REG_SET *	pRegs	/* pointer to register info on stack */    )    {    EXC_INFO excInfo;#if (CPU==SH7750)    /* see if denormalized number exception */    if ((vecNum == INUM_FPU_EXCEPTION) && (fppExcHandle (pEsf, pRegs) == OK))	return;#endif    excGetInfoFromESF (vecNum, pEsf, pRegs, &excInfo);  /* fill excInfo/pRegs */    if ((_func_excBaseHook != NULL) &&			/* user hook around? */	((* _func_excBaseHook) (vecNum, pEsf, pRegs, &excInfo)))	return;						/* user hook fixed it */    if ((excBErrVecNum != NONE) && (vecNum == excBErrVecNum) &&	excTasRetry (vecNum, pEsf, pRegs))	return;						/* retry the TAS */#ifdef WV_INSTRUMENTATION    /* windview - level 3 event logging */#if (CPU==SH7750 || CPU==SH7700)    EVT_CTX_1(EVENT_EXCEPTION, INUM_TO_IEVT (vecNum));#elif (CPU==SH7600 || CPU==SH7000)    EVT_CTX_1(EVENT_EXCEPTION, vecNum);#endif#endif    /* if exception occured in an isr or before multi tasking then reboot */    if ((INT_CONTEXT ()) || (Q_FIRST (&activeQHead) == NULL))	{	if (_func_excPanicHook != NULL)			/* panic hook? */	    (*_func_excPanicHook) (vecNum, pEsf, pRegs, &excInfo);	reboot (BOOT_WARM_AUTOBOOT);	return;						/* reboot returns?! */	}    /* task caused exception */    taskIdCurrent->pExcRegSet = pRegs;			/* for taskRegs[GS]et */    taskIdDefault ((int)taskIdCurrent);			/* update default tid */    bcopy ((char *) &excInfo, (char *) &(taskIdCurrent->excInfo),	   sizeof (EXC_INFO));				/* copy in exc info */    /* CAUTION: pRegs is invalid after calling _func_sigExcKill. */    if (_func_sigExcKill != NULL)			/* signals installed? */	(*_func_sigExcKill) (vecNum, INUM_TO_IVEC(vecNum), pRegs);    if (_func_excInfoShow != NULL)			/* default show rtn? */	(*_func_excInfoShow) (&excInfo, TRUE);    if (excExcepHook != NULL)				/* 5.0.2 hook? */	(* excExcepHook) (taskIdCurrent, vecNum, pEsf);    taskSuspend (0);					/* whoa partner... */    taskIdCurrent->pExcRegSet = (REG_SET *) NULL;	/* invalid after rts */    }/******************************************************************************** excIntHandle - interrupt level handling of interrupts** This routine handles interrupts.  It is never to be called except* from the special assembly language interrupt stub routine.** It prints out a bunch of pertinent information about the trap that* occurred via excTask().** NOMANUAL*/void excIntHandle    (    int		vecNum,	/* exception vector number */    ESFSH *	pEsf,	/* pointer to exception stack frame */    REG_SET *	pRegs	/* pointer to register info on stack */    )    {    EXC_INFO excInfo;    excGetInfoFromESF (vecNum, pEsf, pRegs, &excInfo);	/* fill excInfo/pRegs */#ifdef WV_INSTRUMENTATION    /* windview - level 3 event logging */#if (CPU==SH7750 || CPU==SH7700)    EVT_CTX_1(EVENT_EXCEPTION, INUM_TO_IEVT (vecNum));#elif (CPU==SH7600 || CPU==SH7000)    EVT_CTX_1(EVENT_EXCEPTION, vecNum);#endif#endif        if (_func_excIntHook != NULL)	(*_func_excIntHook) (vecNum, pEsf, pRegs, &excInfo);    if (Q_FIRST (&activeQHead) == NULL)			/* pre kernel */	reboot (BOOT_WARM_AUTOBOOT);			/* better reboot */    }/******************************************************************************** excGetInfoFromESF - get relevent info from exception stack frame** NOMANUAL** <SH7700 exception case, it differs if interrupt>**           |_____________|        _______*           |TRA/TEA/FPSCR| 96  +12        ESFSH.info (JUNK if interrupt)*           |   EXPEVT    | 92  +8 _____   ESFSH.event (not saved, use vecNum)*           |     ssr     | 88  +4   ^     ESFSH.sr*  pEsf --> |     spc     | 84  +0   | ___ ESFSH.pc*           |     r15     | 80       |*           |     r14     | 76       |*           |     r13     | 72       |*           |     r12     | 68       |*           |     r11     | 64       |*           |     r10     | 60       |*           |     r9      | 56       |*           |     r8      | 52       |*           |    macl     | 48       |*           |    mach     | 44    REG_SET*           |     r7      | 40       |*           |     r6      | 36       |*           |     r5      | 32       |*           |     r4      | 28       |*           |     r3      | 24       |*           |     r2      | 20       |			_________________*           |     r1      | 16       |			|_____pad_______|*           |     r0      | 12       |			|_____info______|*           |     pr      |  8       |			|______sr_______|*           |     gbr     |  4       |			|______pc_______| *  pRegs -> |____ vbr ____|  0  _____v__  pExcInfo ---> |_valid_|_vecNum|*           |             |*/LOCAL void excGetInfoFromESF    (    FAST int	vecNum,		/* vector number */    FAST ESFSH *pEsf,		/* pointer to exception stack frame */    REG_SET *	pRegs,		/* pointer to register info on stack */    EXC_INFO *	pExcInfo	/* where to fill in exception info */    )    {#if (CPU==SH7750 || CPU==SH7700)    pExcInfo->valid	= EXC_VEC_NUM | EXC_PC | EXC_STATUS_REG;    pExcInfo->vecNum	= vecNum;    pExcInfo->pc	= ((ESFSH *)pEsf)->pc;    pExcInfo->sr	= ((ESFSH *)pEsf)->sr;    pExcInfo->info	= ((ESFSH *)pEsf)->info;    if (((ESFSH *)pEsf)->event == (INUM_TO_IEVT (INUM_TRAPA_INSTRUCTION)))	{	pExcInfo->valid |= EXC_TRAP;	}    else if ((vecNum>=INUM_TLB_READ_MISS) && (vecNum<=INUM_WRITE_ADDRESS_ERROR))	{	pExcInfo->valid |= EXC_ACCESS_ADDR;	}#ifdef _WRS_HW_FP_SUPPORT    else if (vecNum == INUM_FPU_EXCEPTION)	{	pExcInfo->valid |= EXC_FPSCR;	if (pTaskLastFpTcb != NULL) fppSave (pTaskLastFpTcb->pFpContext);	}#endif#if (CPU==SH7750)    else if (vecNum==INUM_TLB_MULTIPLE_HIT)	{	pExcInfo->valid |= EXC_ACCESS_ADDR;	}#endif /* CPU==SH7750 */#elif (CPU==SH7600 || CPU==SH7000)    int size = sizeof (ESFSH);    pExcInfo->valid	= EXC_VEC_NUM | EXC_PC | EXC_STATUS_REG;    pExcInfo->vecNum	= vecNum;    pExcInfo->pc	= ((ESFSH *)pEsf)->pc;    pExcInfo->sr	= ((ESFSH *)pEsf)->sr;    pRegs->spReg = (ULONG)((char *) pEsf + size);       /* bump up stack ptr */#endif /* CPU==SH7600 || CPU==SH7000 */    }/******************************************************************************** excTasRetry - retry a TAS instruction** If this was a bus error involving a RMW cycle (TAS instruction) we* return to the handler to retry it.  Such is the case in a vme* bus deadlock cycle, where the local CPU initiates a TAS instuction* (or RMW cycle) at the same time it's dual port arbiter grants the local bus* to an external access.  The cpu backs off by signaling a bus error and* setting the RM bit in the special status word of the bus error exception* frame.  The solution is simply to retry the instruction hoping that the* external access has been resolved.  Even if a card such as a disk controller* has grabed the bus for DMA accesses for a long time, the worst that will* happen is we'll end up back here again, and we can keep trying until we get* through.** RETURNS: TRUE if retry desired, FALSE if not TAS cycle.* NOMANUAL*/LOCAL BOOL excTasRetry    (    int		vecNum,		/* exception vector number */    ESFSH *	pEsf,		/* pointer to exception stack frame */    REG_SET *	pRegs		/* pointer to register info on stack */    )    {    if (_func_excBErrIntAck != NULL)	(* _func_excBErrIntAck) ();    if (0)	/* XXX how to identify the TAS cycle with SH??? */	{	++excTasErrors;				/* keep count of TAS errors */	return (TRUE);				/* retry the instruction */	}        return (FALSE);    }

⌨️ 快捷键说明

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