📄 excarchlib.c
字号:
/* excArchLib.c - PowerPC exception handling facilities *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02o,25aug03,mil Fixed reg corruption of machine check stub code.02o,25aug03,dtr Wrap new ESF info mcesr with CPU==PPC85XX.02n,13aug03,mil Consolidated esr and mcsr as well as dear and mcar for e500.02m,19nov02,mil Updated support for PPC85XX.02l,03aug02,pcs Add support for PPC85XX and make it the same as PPC603 for the present.02k,22may02,mil Added back excIntConnectTimer() for compatibility.02j,08may02,mil Relocated _EXC_OFF_PERF to avoid corruption by the extended _EXC_ALTIVEC_UNAVAILABLE vector (SPR #76916). Patched calculation of wrong relocated vector offset (SPR #77145). Added _EXC_OFF_THERMAL for PPC604 (SPR #77552).02i,04apr02,pch SPR 74348: Enable PPC Machine Check exception ASAP02h,13nov01,yvp Fix SPR 27916, 8179: Added extended (32-bit) vectors for exception handling.02g,05oct01,pch SPR's 68093 & 68585: handle critical vectors in excVecGet() and excVecSet(). Comment changes (only) supporting rework of SPR 69328 fix02f,15aug01,pch Add PPC440 support02e,14jun01,kab Fixed Altivec Unavailable Exchandler, SPR 6820602d,30nov00,s_m fixed bus error handling for 40502c,25oct00,s_m renamed PPC405 cpu types02b,13oct00,sm modified machine check handling for PPC40502a,06oct00,sm PPC405 GF & PPC405 support01z,12mar99,zl added PowerPC 509 and PowerPC 555 support.01y,24aug98,cjtc intEnt logging for PPC is now performed in a single step instead of the two-stage approach which gave problems with out-of-order timestamps in the event log. Global evtTimeStamp no longer required (SPR 21868)01x,18aug98,tpr added PowerPC EC 603 support.01w,09jan98,dbt modified for new breakpoint scheme01v,06aug97,tam fixed problem with CE interrupt (SPR #8964)01u,26mar97,tam added test for DBG_BREAK_INST in excExcHandle() (SPR #8217).01t,26mar97,jdi,tam doc cleanup.01s,20mar97,tam added function excIntCrtConnect for PPC403 Critical Intr.01r,24feb97,tam added support for 403GC/GCX exceptions.01q,10feb97,tam added support to handle floating point exceptions (SPR #7840).01p,05feb97,tpr reawork PPC860 support in excExcHandle() (SPR 7881).01o,16jan97,tpr Changed CACHE_TEXT_UPDATE() address in excVecSet(). (SPR #7754)01n,03oct96,tpr Reworked excGetInfoFromESF () to include DSISR and DAR registers for PPC860 (SPR# 7254)01o,11jul96,pr cleanup windview instrumentation 01n,08jul96,pr added windview instrumentation - conditionally compiled01m,31may96,tpr added PowerPC 860 support.01l,12mar96,tam re-worked exception handling for the PPC403 FIT and PIT interrupts. Added excIntConnectTimer().01k,28feb96,tam added excCrtConnect() for critical exceptions on the PPC403 cpu. 01j,27feb96,ms made excConnectCode use "stwu" instead of "addi". fixed compiler warnings. Change logMsg to func_logMsg.01i,23feb96,tpr added excConnect() & excIntConnect(), renamed excCode[] by excConnectCode.01h,05oct95,tpr changed excCode[] code.01g,23may95,caf fixed unterminated comment in version 01f.01f,22may95,caf enable PowerPC 603 MMU.01e,09feb95,yao changed machine check exception handler to excCrtStub for PPC403.01d,07feb95,yao fixed excExcHandler () for PPC403. removed _AIX_TOOL support.01c,02feb95,yao changed to set timer exceptions to excClkStub for PPC403. changed to call vxEvpr{S,G}et for PPC403.01b,07nov94,yao cleanup.01a,09sep94,yao written.*//*This module provides architecture-dependent facilities for handling PowerPC exceptions. See excLib for the portions that are architecture independent.INITIALIZATIONInitialization of exception handling facilities is in two parts. First,excVecInit() is called to set all the PowerPC exception, trap, and interruptvectors to the default handlers provided by this module. The rest of thispackage is initialized by calling excInit() (in excLib), which spawns theexception support task, excTask(), and creates the pipe used to communicatewith it. See the manual entry for excLib for more information.SEE ALSO: excLib,.pG "Debugging"*//* LINTLIBRARY */#include "vxWorks.h"#include "esf.h"#include "iv.h"#include "sysLib.h"#include "intLib.h"#include "msgQLib.h"#include "signal.h"#include "cacheLib.h"#include "errnoLib.h"#include "string.h"#include "rebootLib.h"#include "excLib.h"#include "vxLib.h"#include "private/funcBindP.h"#include "private/sigLibP.h"#include "private/taskLibP.h"#include "wdb/wdbDbgLib.h"#ifdef _WRS_ALTIVEC_SUPPORT#include "altivecLib.h"#endif /* _WRS_ALTIVEC_SUPPORT */typedef struct excTbl { UINT32 vecOff; /* vector offset */ STATUS (*excCnctRtn) (); /* routine to connect the exception handler*/ void (*excHandler) (); /* exception handler routine */ UINT32 vecOffReloc; /* vector offset relocation address */ } EXC_TBL;/* externals */IMPORT FUNCPTR excExcepHook; /* add'l rtn to call when exceptions occur */IMPORT void excEnt (void); /* exception entry routine */IMPORT void excExit (void); /* exception exit routine */#ifdef _PPC_MSR_CEIMPORT void excCrtExit (void); /* critical exception stub */IMPORT void excCrtEnt (void); /* critical exception stub */IMPORT void intCrtExit (void); /* external critical exception stub */IMPORT void intCrtEnt (void); /* external critical exception stub */IMPORT FUNCPTR _dbgDsmInstRtn;#endif /* _PPC_MSR_CE */#ifdef _PPC_MSR_MCEIMPORT void excMchkExit (void); /* machine check exception stub */IMPORT void excMchkEnt (void); /* machine check exception stub */#endif /* _PPC_MSR_MCE */IMPORT void intEnt (void); /* interrupt entry routine */IMPORT void intExit (void); /* interrupt exit routine */IMPORT void excEPSet (FUNCPTR *);/* globals */FUNCPTR _func_excTrapRtn = NULL; /* trap handling routine *//* * Option to use extended (full 32-bit) vectors to jump from the vector table * to handler functions. Normally we use a 26-bit address, which suffices for * a vast majority of functions. However a 26-bit address restricts branches * to within 32MB which may be a problem for some systems. * * Setting excExtendedVectors to TRUE enables branching to an absolute 32-bit * address. This option increases interrupt latency by about 20%, but there is * no other choice left when the handler routine is more than 32MB away. */BOOL excExtendedVectors = FALSE; /* extended exception stubs flag *//* Macro to sign-extend a 26-bit integer value */#define SEXT_26BIT(x) (((0x03ffffff & (INSTR) (x)) ^ 0x02000000) - 0x02000000)#define SPR_SET(x) (((((x) & 0x1f) << 5) | (((x) & 0x3e0) >> 5)) << 11)/* locals */LOCAL FUNCPTR * excVecBase = NULL; /* exception vector base address */LOCAL int entOffset, exitOffset, isrOffset;#ifdef _EXC_OFF_CRTLLOCAL int entCrtOffset, exitCrtOffset, isrCrtOffset;#endif /* _EXC_OFF_CRTL */LOCAL int excGetInfoFromESF (FAST int vecNum, FAST ESFPPC *pEsf, EXC_INFO *pExcInfo);/* * Vector type definitions for local function excConnectVector() */#define VEC_TYPE_UNDEF 0 /* to catch default values */#define VEC_TYPE_NORM 1 /* normal vector type */#define VEC_TYPE_CRT 2 /* critical vector type */#define VEC_TYPE_MCHK 3 /* machine check vector type */LOCAL STATUS excConnectVector ( INSTR * newVector, /* calculated exc vector */ int vecType, /* norm/crit/mchk? */ VOIDFUNCPTR entry, /* handler entry */ VOIDFUNCPTR routine, /* routine to be called */ VOIDFUNCPTR exit /* handler exit */ );/* forward declarations */STATUS excRelocConnect (VOIDFUNCPTR *, VOIDFUNCPTR, VOIDFUNCPTR *);STATUS excRelocIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR, VOIDFUNCPTR *);STATUS excRelocCrtConnect (VOIDFUNCPTR *, VOIDFUNCPTR, VOIDFUNCPTR *);STATUS excRelocIntCrtConnect (VOIDFUNCPTR *, VOIDFUNCPTR, VOIDFUNCPTR *);STATUS excRelocMchkConnect (VOIDFUNCPTR *, VOIDFUNCPTR, VOIDFUNCPTR *);UINT32 vecOffRelocMatch (UINT32 vector);UINT32 vecOffRelocMatchRev (UINT32 vector);void excExcHandle (ESFPPC * pEsf);void excIntHandle ();void excVecSet (FUNCPTR * vector, FUNCPTR function);FUNCPTR * excVecBaseGet (void);#ifdef IVOR0void excIvorInit (void);#endif/* * Exception vector table * * Each entry in the exception vector table is consists of: * - the vector offset (from the vector base address) of the exception type * - the connect routine to be used, and must be one of: * excConnect() or excRelocConnect() * excIntConnect() or excRelocIntConnect() * excCrtConnect() or excRelocCrtConnect() * excIntCrtConnect() or excRelocIntCrtConnect() * excMchkConnect() or excRelocMchkConnect() * excIntConnectTimer() (phasing out) * - the handler routine, which is one of: * excExcHandle() * excIntHandle() * - the relocated vector offset (from the vector base address) * * The original implementation of the exception handling routines do not * have facility to relocate vectors. To find out the vector offset of * the exception that causes the instance of excEnt()/intEnt() to run, a * pre-computed value is subtracted from the beginning of the stub whose * address is put into LR by the bl excEnt or bl intEnt in the stub. * However, a stub which is relocated to another address will cause * the calculation in excEnt() and intEnt() to yield a wrong vector. * With SPRG0-SPRG3 all used up, the same excEnt()/intEnt() routines used * for both the un-relocated and relocated cases cannot find an efficient * way to calculate the right vector offset. * * As a temporary workaround, excEnt() and intEnt() are hard coded to * detect the relocated vectors and patch them up with the right * values before saving them to the ESF. This causes limitations if * a user wants to install their own exception handling routines that * span through a relocated vector address. This also means that they * need to treat the relocated vectors as special cases. They need to * use excVecSet() with the relocated vector offset instead of the * original vector offset. Ditto to excVecGet(). Note also that adding * any relocated vectors require to add the patch up code in excEnt() * and/or intEnt() in excALib.s and/or intALib.s respectively. */LOCAL EXC_TBL excBlTbl[] = {#if ( (CPU == PPC403) || (CPU==PPC405) || (CPU==PPC405F) ) {_EXC_OFF_CRTL, excIntCrtConnect, excIntHandle, 0}, /* crit int */ {_EXC_OFF_MACH, excCrtConnect, excExcHandle, 0}, /* machine chk */ {_EXC_OFF_PROT, excConnect, excExcHandle, 0}, /* protect viol */ {_EXC_OFF_INST, excConnect, excExcHandle, 0}, /* instr access */ {_EXC_OFF_INTR, excIntConnect, excIntHandle, 0}, /* ext int */ {_EXC_OFF_ALIGN, excConnect, excExcHandle, 0}, /* alignment */ {_EXC_OFF_PROG, excConnect, excExcHandle, 0}, /* program */# if (CPU == PPC405F) /* 405GF supports a FPU */ {_EXC_OFF_FPU, excConnect, excExcHandle, 0}, /* fp unavail */# endif {_EXC_OFF_SYSCALL, excConnect, excExcHandle, 0}, /* system call */#ifdef _EXC_NEW_OFF_PIT /* prog timer */ {_EXC_OFF_PIT, excRelocIntConnect, excIntHandle, _EXC_NEW_OFF_PIT},#else {_EXC_OFF_PIT, excIntConnect, excIntHandle, 0}, /* prog timer */#endif /* _EXC_NEW_OFF_PIT */#ifdef _EXC_NEW_OFF_FIT /* fixed timer */ {_EXC_OFF_FIT, excRelocIntConnect, excIntHandle, _EXC_NEW_OFF_FIT},#else {_EXC_OFF_FIT, excIntConnect, excIntHandle, 0}, /* fixed timer */#endif /* _EXC_NEW_OFF_FIT */ {_EXC_OFF_WD, excIntCrtConnect, excIntHandle, 0}, /* watchdog */ {_EXC_OFF_DATA_MISS,excConnect, excExcHandle, 0}, /* data TLB miss */ {_EXC_OFF_INST_MISS,excConnect, excExcHandle, 0}, /* inst TLB miss */ {_EXC_OFF_DBG, excCrtConnect, excExcHandle, 0}, /* debug events */#elif (CPU == PPC440) {_EXC_OFF_CRTL, excIntCrtConnect, excIntHandle, 0}, /* critical int */ {_EXC_OFF_MACH, excCrtConnect, excExcHandle, 0}, /* machine chk */ {_EXC_OFF_DATA, excConnect, excExcHandle, 0}, /* data storage */ {_EXC_OFF_INST, excConnect, excExcHandle, 0}, /* instr access */ {_EXC_OFF_INTR, excIntConnect, excIntHandle, 0}, /* ext int */ {_EXC_OFF_ALIGN, excConnect, excExcHandle, 0}, /* alignment */ {_EXC_OFF_PROG, excConnect, excExcHandle, 0}, /* program */ {_EXC_OFF_FPU, excConnect, excExcHandle, 0}, /* fp unavail */ {_EXC_OFF_SYSCALL, excConnect, excExcHandle, 0}, /* system call */ {_EXC_OFF_APU, excConnect, excExcHandle, 0}, /* auxp unavail*/ {_EXC_OFF_DECR, excIntConnect, excIntHandle, 0}, /* decrementer */ {_EXC_OFF_FIT, excIntConnect, excIntHandle, 0}, /* fixed timer */ {_EXC_OFF_WD, excIntCrtConnect, excIntHandle, 0}, /* watchdog */ {_EXC_OFF_DATA_MISS,excConnect, excExcHandle, 0}, /* data TLB miss */ {_EXC_OFF_INST_MISS,excConnect, excExcHandle, 0}, /* inst TLB miss */ {_EXC_OFF_DBG, excCrtConnect, excExcHandle, 0}, /* debug events */#elif (CPU == PPC85XX) /* placed here to reflect on 440 */ {_EXC_OFF_CRTL, excIntCrtConnect, excIntHandle, 0}, /* critical int */ {_EXC_OFF_MACH, excMchkConnect, excExcHandle, 0}, /* machine chk */ {_EXC_OFF_DATA, excConnect, excExcHandle, 0}, /* data storage */ {_EXC_OFF_INST, excConnect, excExcHandle, 0}, /* instr access */ {_EXC_OFF_INTR, excIntConnect, excIntHandle, 0}, /* ext int */ {_EXC_OFF_ALIGN, excConnect, excExcHandle, 0}, /* alignment */ {_EXC_OFF_PROG, excConnect, excExcHandle, 0}, /* program */ {_EXC_OFF_FPU, excConnect, excExcHandle, 0}, /* fp unavail */ {_EXC_OFF_SYSCALL, excConnect, excExcHandle, 0}, /* system call */ {_EXC_OFF_APU, excConnect, excExcHandle, 0}, /* auxp unavail*/ {_EXC_OFF_DECR, excIntConnect, excIntHandle, 0}, /* decrementer */ {_EXC_OFF_FIT, excIntConnect, excIntHandle, 0}, /* fixed timer */ {_EXC_OFF_WD, excIntCrtConnect, excIntHandle, 0}, /* watchdog */ {_EXC_OFF_DATA_MISS,excConnect, excExcHandle, 0}, /* data TLB miss */ {_EXC_OFF_INST_MISS,excConnect, excExcHandle, 0}, /* inst TLB miss */ {_EXC_OFF_DBG, excCrtConnect, excExcHandle, 0}, /* debug events */ {_EXC_OFF_SPE, excConnect, excExcHandle, 0}, /* SPE */ {_EXC_OFF_VEC_DATA, excConnect, excExcHandle, 0}, /* vector data */ {_EXC_OFF_VEC_RND, excConnect, excExcHandle, 0}, /* vector round */ {_EXC_OFF_PERF_MON, excConnect, excExcHandle, 0}, /* perf monitor */#elif ((CPU == PPC509) || (CPU == PPC555)) {_EXC_OFF_RESET, excConnect, excExcHandle, 0}, /* system reset */ {_EXC_OFF_MACH, excConnect, excExcHandle, 0}, /* machine chk */ {_EXC_OFF_INTR, excIntConnect, excIntHandle, 0}, /* ext int */ {_EXC_OFF_ALIGN, excConnect, excExcHandle, 0}, /* alignment */ {_EXC_OFF_PROG, excConnect, excExcHandle, 0}, /* program */ {_EXC_OFF_FPU, excConnect, excExcHandle, 0}, /* fp unavail */ {_EXC_OFF_DECR, excIntConnect, excIntHandle, 0}, /* decrementer */ {_EXC_OFF_SYSCALL, excConnect, excExcHandle, 0}, /* system call */ {_EXC_OFF_TRACE, excConnect, excExcHandle, 0}, /* trace except */ {_EXC_OFF_FPA, excConnect, excExcHandle, 0}, /* fp assist */ {_EXC_OFF_SW_EMUL, excConnect, excExcHandle, 0}, /* sw emul */# if (CPU == PPC555)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -