📄 excarchlib.c
字号:
++(pRegs->r[0]); /* increment r0 */ }#endif /* TEST_SWI_HANDLER *//********************************************************************************* 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 ( ESF * pEsf, /* pointer to exception stack frame */ REG_SET * pRegs /* pointer to register info on stack */ ) { EXC_INFO excInfo; int vec = pEsf->vecAddr; /* exception vector */ excGetInfoFromESF (vec, pEsf, pRegs, &excInfo); /* fill excInfo/pRegs */ if ((_func_excBaseHook != NULL) && /* user hook around? */ ((* _func_excBaseHook) (vec, pEsf, pRegs, &excInfo))) return; /* user hook fixed it */#ifdef WV_INSTRUMENTATION /* windview - level 3 event logging */ EVT_CTX_1(EVENT_EXCEPTION, vec);#endif /* WV_INSTRUMENTATION */ /* 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) (vec, 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) /* signals installed? */ (*_func_sigExcKill) (vec, 0, pRegs); if (_func_excInfoShow != NULL) /* default show rtn? */ (*_func_excInfoShow) (&excInfo, TRUE); if (excExcepHook != NULL) /* 5.0.2 hook? */ (* excExcepHook) (taskIdCurrent, vec, 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 () {#ifdef WV_INSTRUMENTATION /* windview - level 3 event logging */ EVT_CTX_1(EVENT_EXCEPTION, EXC_OFF_IRQ);#endif /* WV_INSTRUMENTATION */ if (_func_excIntHook != NULL) (*_func_excIntHook) (); if (Q_FIRST (&activeQHead) == NULL) /* pre kernel */ reboot (BOOT_WARM_AUTOBOOT); /* better reboot */ }/******************************************************************************* excGetInfoFromESF - get relevent info from exception stack frame**/LOCAL void excGetInfoFromESF ( int vec, /* vector */ FAST ESF * pEsf, /* pointer to exception stack frame */ REG_SET * pRegs, /* pointer to register info on stack */ EXC_INFO * pExcInfo /* where to fill in exception info */ ) { pExcInfo->valid = EXC_INFO_VECADDR | EXC_INFO_PC | EXC_INFO_CPSR; pExcInfo->vecAddr = pEsf->vecAddr; pExcInfo->pc = pRegs->pc; pExcInfo->cpsr = pRegs->cpsr; switch (pEsf->vecAddr) { case EXC_OFF_RESET: /* branch through zero */ pExcInfo->valid ^= EXC_INFO_PC; /* PC not valid */ break; case EXC_OFF_UNDEF: /* undefined instruction */ case EXC_OFF_SWI: /* software interrupt */ case EXC_OFF_PREFETCH: /* prefetch abort */ break; case EXC_OFF_DATA: /* data abort */ /* * note that registers may need unwinding if reexecution of * the instruction is to be attempted after the cause of * the abort has been fixed */ break; default: /* what else can there be? */ break; } }/********************************************************************************* excExcContinue - continue low level handling of exception** This routine is called from the excEnter stubs to pass control to* the required exception handler.** Note that this routine runs in the context of the task that got the exception.** NOMANUAL*/void excExcContinue ( ESF * pEsf, /* pointer to exception stack frame */ REG_SET * pRegs /* pointer to register info on stack */ ) { EXC_INFO excInfo; FAST UINT32 vec = pEsf->vecAddr; /* exception vector */ /* * call exception handler for this exception * if exception occurred at address 0, we don't care what sort of * exception it was - it MUST be a branch-through-zero (EXC_OFF_RESET). */ if (pRegs->pc == 0) vec = pEsf->vecAddr = EXC_OFF_RESET; switch (vec) { case EXC_OFF_RESET: /* reset = branch through zero */ case EXC_OFF_SWI: /* software interrupt */ case EXC_OFF_PREFETCH: /* prefetch abort */ case EXC_OFF_DATA: /* data abort */ (excHandlerTbl[vec >> 2].fn) (pEsf, pRegs); break; case EXC_OFF_UNDEF: /* undefined instruction */ /* * check explicitly for an undefined instruction exception * caused by the undefined instruction we use as a breakpoint * and invoke its handler directly. WDB and DBG both use this * so only one can be installed at a time. */ if (*(pRegs->pc) == DBG_BREAK_INST && _func_excBreakpoint != NULL) _func_excBreakpoint(pEsf, pRegs); else (excHandlerTbl[vec >> 2].fn) (pEsf, pRegs); break; default: /* should not happen - reboot */ excGetInfoFromESF (vec, pEsf, pRegs, &excInfo); if (_func_excPanicHook != NULL) /* panic hook? */ (*_func_excPanicHook) (vec, pEsf, pRegs, &excInfo); reboot (BOOT_WARM_AUTOBOOT); break; } }/********************************************************************************* excVecSet - set an exception vector** This routine specifies the C routine that will be called when the exception* corresponding to <vector> occurs. This routine does not create the* exception stub; it simply replaces the C routine to be called in the* exception stub.** NOTE* On the ARM, there is no excConnect() routine, unlike the PowerPC. The C* routine is attached to a default stub using excVecSet().*** SEE ALSO: excVecGet()*/void excVecSet ( FUNCPTR * vector, /* exception vector */ FUNCPTR function /* routine to be called */ ) { FAST int i; /* * find entry in table for this exception * NOTE: -1 because we don't put IRQ through here and FIQ isn't * in the table */ for (i = 0; i < NUM_CHANGEABLE_EXC_VECS; ++i) if (excHandlerTbl[i].vecAddr == (UINT32)vector) break; if (i < NUM_CHANGEABLE_EXC_VECS) excHandlerTbl[i].fn = (VOIDFUNCPTR)function; /* install handler */ }/********************************************************************************* excVecGet - get an exception vector** This routine returns the address of the C routine currently connected to* <vector>.** SEE ALSO: excVecSet()*/FUNCPTR excVecGet ( FUNCPTR * vector /* exception vector */ ) { FAST int i; /* * find entry in table for this exception * NOTE: -1 because we don't put IRQ through here and FIQ isn't * in the table */ for (i = 0; i < NUM_CHANGEABLE_EXC_VECS; ++i) if (excHandlerTbl[i].vecAddr == (UINT32)vector) return (FUNCPTR)excHandlerTbl[i].fn; return NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -