📄 excarchlib.c
字号:
( void *vecAdrs ) { extern int excTlbVec[]; /* instructions for branch to TLB handler */ extern int excTlbVecSize; /* Load tlb vector and invalidate instruction cache */ bcopy ((const char *) excTlbVec, (char *) vecAdrs, excTlbVecSize); cacheTextUpdate (vecAdrs, excTlbVecSize); }#ifndef _WRS_R3K_EXC_SUPPORT/********************************************************************************* excXtlbVecInit - initialize the XTLB exception vector.** This routine loads the exception handler code for the XTLB exception * vector into the address requested by the BSP.** RETURNS: N/A*/void excXtlbVecInit ( void *vecAdrs ) { extern int excXtlbVec[]; /* instructions for branch to xtlb handler */ extern int excXtlbVecSize; /* Load xtlb vector and invalidate instruction cache */ bcopy ((const char *) excXtlbVec, (char *) vecAdrs, excXtlbVecSize); cacheTextUpdate (vecAdrs, excXtlbVecSize); }/********************************************************************************* excCacheVecInit - initialize the cache exception vector.** This routine loads the exception handler code for the cache exception * vector into the address requested by the BSP.** RETURNS: N/A*/void excCacheVecInit ( void *vecAdrs ) { extern int excCacheVec[]; /* instructions for branch to cache handler */ extern int excCacheVecSize; /* Load cache exception vector and invalidate instruction cache */ bcopy ((const char *) excCacheVec, (char *) vecAdrs, excCacheVecSize); cacheTextUpdate (vecAdrs, excCacheVecSize); }#endif /* _WRS_R3K_EXC_SUPPORT *//********************************************************************************* excVecInit - initialize the exception/interrupt vectors** This routine sets up the MIPS exception vectors to point to the * appropriate default exception handlers.** INTERNAL* The common exception handler excStub() is found in excALib.s.* * WHEN TO CALL* This routine is usually called from the system start-up routine* usrInit() in usrConfig.c, before interrupts are enabled.** RETURNS: OK (always).** SEE ALSO: excLib*/STATUS excVecInit (void) { extern int excNormVec[]; /* instructions for branch to normal handler */ extern int excNormVecSize; extern int excTlbVec[]; /* instructions for branch to tlb handler */ extern int excTlbVecSize; /* instructions for branch to tlb handler */#ifndef _WRS_R3K_EXC_SUPPORT extern int excXtlbVec[]; /* instructions for branch to xtlb handler */ extern int excXtlbVecSize; /* instructions for branch to xtlb handler */ extern int excCacheVec[]; /* instructions for branch to cache handler */ extern int excCacheVecSize; /* instructions for branch to cache handler */#endif /* _WRS_R3K_EXC_SUPPORT */ ULONG srValue; /* status register placeholder */ /* If available, use BSP-provided initialization function */ if (sysExcVecInitHook != NULL) { (*sysExcVecInitHook)(); } else { /* Load normal vector and invalidate instruction cache */ bcopy ((const char *)excNormVec, (char *) E_VEC, excNormVecSize); cacheTextUpdate ((void *) E_VEC, excNormVecSize); /* Load tlb vector and invalidate instruction cache */#ifdef _WRS_R3K_EXC_SUPPORT bcopy ((const char *)excTlbVec, (char *) UT_VEC, excTlbVecSize); cacheTextUpdate ((void *) UT_VEC, excTlbVecSize);#else /* !_WRS_R3K_EXC_SUPPORT */ bcopy ((const char *)excTlbVec, (char *) T_VEC, excTlbVecSize); cacheTextUpdate ((void *) T_VEC, excTlbVecSize);#endif /* !_WRS_R3K_EXC_SUPPORT */#ifndef _WRS_R3K_EXC_SUPPORT /* Load xtlb vector and invalidate instruction cache */ bcopy ((const char *)excXtlbVec, (char *) X_VEC, excXtlbVecSize); cacheTextUpdate ((void *) X_VEC, excXtlbVecSize); /* Load cache exception vector and invalidate instruction cache */ bcopy ((const char *)excCacheVec, (char *) C_VEC, excCacheVecSize); cacheTextUpdate ((void *) C_VEC, excCacheVecSize);#endif /* _WRS_R3K_EXC_SUPPORT */ } /* Make the vectors usable by turning off rom based vectors */ srValue = intSRGet(); srValue &= ~SR_BEV; intSRSet(srValue); return (OK); }/********************************************************************************* excExcHandle - interrupt level handling of exceptions** This routine handles exception traps. It is never 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 */ ESFMIPS * pEsf, /* pointer to exception stack frame */ REG_SET * pRegs /* pointer to general regs on esf */ ) { EXC_INFO excInfo; int esfSize;#ifdef _WRS_R3K_EXC_SUPPORT /* restore old sr so it looks like an rfe occured thus allowing interrupts*/ pEsf->esfRegs.sr = (pEsf->esfRegs.sr & ~(SR_KUP|SR_IEP|SR_KUC|SR_IEC)) | ((pEsf->esfRegs.sr & (SR_KUO|SR_IEO|SR_KUP|SR_IEP|SR_KUC|SR_IEC)) >> 2);#else /* restore old sr so it looks like an eret occured */ pEsf->esfRegs.sr &= ~SR_EXL;#endif esfSize = excGetInfoFromESF (vecNum, pEsf, &excInfo); /* fix task stack pointer and registers */ pRegs->sr = pEsf->esfRegs.sr; if ((_func_excBaseHook != NULL) && /* user hook around? */ ((* _func_excBaseHook) (vecNum, pEsf, pRegs, &excInfo))) return; /* user hook fixed it */#ifdef WV_INSTRUMENTATION /* windview - level 3 event logging */ EVT_CTX_1(EVENT_EXCEPTION, vecNum);#endif /* WV_INSTRUMENTATION */ if (INT_CONTEXT ()) { 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 */ if (_func_sigExcKill != NULL) _func_sigExcKill((int) vecNum, vecNum, pRegs); if (_func_excInfoShow != NULL) /* default show rtn? */ (*_func_excInfoShow) (&excInfo, TRUE); if (excExcepHook != NULL) (* excExcepHook) (taskIdCurrent, vecNum, pEsf); taskSuspend (0); /* whoa partner... */ taskIdCurrent->pExcRegSet = (REG_SET *) NULL; /* invalid after rts */ }/******************************************************************************* excBreakTypeGet - Get break type number from break instruction.** RETURNS: break instruction type*/uint16_t excBreakTypeGet ( ESFMIPS *pEsf /* pointer to Exception Stack Frame */ ) { uint32_t epc; /* Exception Program Counter Register */ uint32_t *pInst32; /* epc typed as a pointer to a 32-bit instruction */#ifdef _WRS_MIPS16 uint16_t *pInst16; /* epc typed as a pointer to a 16-bit instruction */#endif uint16_t breakType; /* returned break type */ epc = (uint32_t) pEsf->esfRegs.pc; /* * Determine type of BREAK exception by examining the BREAK instruction. * If the breaked instruction is a branch delay slot, then the pc is the * address of the preceding jump or branch instruction. In this case, the * instruction at pc + 1 must be examined. * * For MIPS16 CPU, check the EPC for 16-bit ISA Mode, and retrieve the * break exception type from the 16-bit break instruction. In this case, * there is no branch delay slot. */#ifdef _WRS_MIPS16 /* If executing in 16-bit instruction mode then decode 16-bit break * instruction. Else decode 32-bit break instruction. */ if (epc & EPC_EIM) { /* Executing in 16-bit instruction mode on a MIPS16. * There is no branch delay slot in 16-bit ISA mode. */ pInst16 = (uint16_t *) (epc & EPC_PC); breakType = (*pInst16 & BREAK16_CODE_MASK) >> BREAK16_CODE_POS; } else { /* Executing in 32-bit instruction mode on a MIPS16*/ pInst32 = (uint32_t *) epc; if (pEsf->cause & CAUSE_BD) /* Branch Delay Slot */ pInst32++; breakType = (uint16_t) ((*pInst32 & BREAK_CODE_MASK) >> BREAK_CODE_POS); } #else /* !_WRS_MIPS16 */ pInst32 = (uint32_t *) epc; if (pEsf->cause & CAUSE_BD) /* Branch Delay Slot */ pInst32++; breakType = (uint16_t) ((*pInst32 & BREAK_CODE_MASK) >> BREAK_CODE_POS); #endif /* _WRS_MIPS16 */ return (breakType); }/********************************************************************************* excIntHandle - interrupt level handling of interrupts** This routine handles interrupts. It is never 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.*/LOCAL void excIntHandle ( int vecNum, /* exception vector number */ ESFMIPS * pEsf /* pointer to exception stack frame */ ) { USHORT eid = 0; /* clear data bus interrupt */ int result; /* unacked ints return value */#ifdef WV_INSTRUMENTATION /* windview - level 3 event logging */ EVT_CTX_1(EVENT_EXCEPTION, vecNum);#endif /* WV_INSTRUMENTATION */ if ((vecNum <= HIGH_VEC) && (vecNum >= LOW_VEC)) { result = sysAutoAck(vecNum); /* clear interrupt condition */ if (vecNum == IV_BUS_ERROR_VEC) eid = (USHORT) result; /* result of data bus interrupt */ if ((vecNum <= IV_FPA_PREC_VEC) && (vecNum >= IV_FPA_UNIMP_VEC)) pEsf->fpcsr = result; /* result of fpa interrupt */ } if (_func_excIntHook != NULL) (*_func_excIntHook) (vecNum, pEsf, eid); }/******************************************************************************* excGetInfoFromESF - get relevent info from exception stack frame** RETURNS: size of specified ESF*/LOCAL int excGetInfoFromESF ( FAST int vecNum, FAST ESFMIPS *pEsf, EXC_INFO *pExcInfo ) { pExcInfo->vecNum = vecNum; pExcInfo->valid = EXC_VEC_NUM; if (( vecNum == IV_TLBMOD_VEC ) || (vecNum == IV_TLBL_VEC ) || (vecNum == IV_TLBS_VEC ) || (vecNum == IV_ADEL_VEC ) || (vecNum == IV_ADES_VEC )) { /* Its an address error , or tlb miss */ pExcInfo->valid |= EXC_EPC | EXC_STATUS_REG | EXC_ACCESS_ADDR | EXC_CAUSE_REG ; pExcInfo->epc = ((ESFMIPS *)pEsf)->esfRegs.pc; pExcInfo->statusReg = ((ESFMIPS *)pEsf)->esfRegs.sr; pExcInfo->causeReg = ((ESFMIPS *)pEsf)->cause; pExcInfo->badVa = ((ESFMIPS *)pEsf)->badva; return (sizeof (ESFMIPS)); } else if ( (vecNum == IV_IBUS_VEC ) || (vecNum == IV_DBUS_VEC )) { /* Its a bus error */ pExcInfo->valid |= EXC_EPC | EXC_STATUS_REG | EXC_CAUSE_REG | EXC_ERROR_ADDR ; pExcInfo->epc = ((ESFMIPS *)pEsf)->esfRegs.pc; pExcInfo->statusReg = ((ESFMIPS *)pEsf)->esfRegs.sr; pExcInfo->causeReg = ((ESFMIPS *)pEsf)->cause; pExcInfo->ear = sysBusEar(); pExcInfo->eid = sysBusEid(); return (sizeof (ESFMIPS)); } else if ((vecNum <= IV_FPA_PREC_VEC) && (vecNum >= IV_FPA_UNIMP_VEC)) { /* Its a floating point error */ pExcInfo->valid |= EXC_EPC | EXC_STATUS_REG | EXC_CAUSE_REG | EXC_FP_STATUS_REG ; pExcInfo->epc = ((ESFMIPS *)pEsf)->esfRegs.pc; pExcInfo->statusReg = ((ESFMIPS *)pEsf)->esfRegs.sr; pExcInfo->causeReg = ((ESFMIPS *)pEsf)->cause; pExcInfo->fpcsr = ((ESFMIPS *)pEsf)->fpcsr; return (sizeof (ESFMIPS)); }#ifdef EXC_BREAK_TYPE else if (vecNum == IV_BP_VEC) { pExcInfo->valid |= EXC_EPC | EXC_STATUS_REG | EXC_CAUSE_REG | EXC_BREAK_TYPE; pExcInfo->epc = ((ESFMIPS *)pEsf)->esfRegs.pc; pExcInfo->statusReg = ((ESFMIPS *)pEsf)->esfRegs.sr; pExcInfo->causeReg = ((ESFMIPS *)pEsf)->cause; pExcInfo->breakType = excBreakTypeGet(pEsf); return (sizeof (ESFMIPS)); }#endif else { pExcInfo->valid |= EXC_EPC | EXC_STATUS_REG | EXC_CAUSE_REG; pExcInfo->epc = ((ESFMIPS *)pEsf)->esfRegs.pc; pExcInfo->statusReg = ((ESFMIPS *)pEsf)->esfRegs.sr; pExcInfo->causeReg = ((ESFMIPS *)pEsf)->cause; return (sizeof (ESFMIPS)); } }#if 0/********************************************************************************* programError - determine if exception is program error** RETURNS:* TRUE if exception indicates program error,* FALSE if hardware interrupt or failure.*/LOCAL BOOL programError ( int vecNum /* exception vector number */ ) { return (((vecNum < USER_VEC_START) && ((vecNum != IV_SYSCALL_VEC) && (vecNum != IV_BP_VEC))) || (vecNum == IV_BUS_ERROR_VEC) ); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -