?? wdbdbgarchlib.c
字號:
/* wdbDbgArchLib.c - MIPS architecture-dependent debugger library *//* Copyright 1988-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * This file has been developed or significantly modified by the * MIPS Center of Excellence Dedicated Engineering Staff. * This notice is as per the MIPS Center of Excellence Master Partner * Agreement, do not remove this notice without checking first with * WR/Platforms MIPS Center of Excellence engineering management. *//*modification history--------------------01p,18jul01,sru add wdbTool variable01o,16jul01,ros add CofE comment01n,02may01,dxc SPR 64101: Add check for jump delay slot in wdbNpc16Get01m,16apr01,dxc SPR 64275: Fix break exception handling01m,21dec00,pes Adapt to MIPS32/MIPS64 CPU architectures01l,30mar00,dra Fix MIPS16 merge errors.01k,23sep99,myz reworked last mod.01j,08sep99,myz added mips16 support. 01h,19jan99,dra added CW4000, CW4011, VR4100, VR5000 and VR5400 support. protected fpscr checks with #ifndef SOFT_FLOAT.01h,14jan99,elg made breakpoints on delay slot work (SPR 24356).01g,12mar98,dbt return corresponding error if the hardware breakoint registers are full or if the hardware breakpoint is invalid.01f,08jan98,dbt modified for new breakpoint scheme. Added hardware breakpoints support01e,12dec96,tam set fpcsr field in wdbArchBreakpoint if necessary (spr #7631).01d,14nov96,mem corrected mask of pc used in J and JAL calculations.01c,20nov96,kkk added R4650 support.01b,14jun96,kkk changed dbg_trap_hander to wdbTrap, fixed wdbGetNpc.01a,04dec95,mem written.*//*DESCRIPTIONThis module contains the architecture specific calls needed by the WDBdebug agent.*//* includes */#include "vxWorks.h"#include "regs.h"#include "iv.h"#include "intLib.h"#include "ioLib.h"#include "esf.h"#include "fppLib.h"#include "wdb/wdbDbgLib.h"/* external functions */extern void wdbDbgTrap();extern void excExcHandle(int vecNum, ESFMIPS * pEsf, REG_SET * pRegs);extern uint16_t excBreakTypeGet(ESFMIPS *pEsf);#if (DBG_HARDWARE_BP)extern void wdbDbgRegsGet (DBG_REGS * pDbgReg);#endif /* (DBG_HARDWARE_BP) *//* forward declarations */LOCAL void wdbDbgArchBreakpoint (int vecNum, ESFMIPS * pInfo, REG_SET * pRegs);LOCAL void wdbDbgBpStub (int vecNum, ESFMIPS * pInfo, REG_SET * pRegs);#if (DBG_HARDWARE_BP)LOCAL void wdbDbgArchHwBreakpoint (int vecNum, ESFMIPS * pInfo, REG_SET * pRegs);#endif /* (DBG_HARDWARE_BP) *//** This function allows the user to dynamically bind a breakpoint* handler to breakpoints of type 0 - 7. By default only breakpoints* of type zero are handled with the function dbgBreakpoint (see dbgLib).* Other types may be used for Ada stack overflow or other such functions.* Use the function dbgBpTypeBind to bind a handler for the corresponding* breakpoint type. The installed handler must take the same parameters as* excExcHandle (see excLib).*/FUNCPTR wdbDbgArchHandler [] = { (FUNCPTR) wdbDbgArchBreakpoint, (FUNCPTR) excExcHandle, (FUNCPTR) excExcHandle, (FUNCPTR) excExcHandle, (FUNCPTR) excExcHandle, (FUNCPTR) excExcHandle, (FUNCPTR) excExcHandle, (FUNCPTR) excExcHandle, };#define NUM_WDB_DBG_ARCH_HANDLERS (sizeof(wdbDbgArchHandler)/sizeof(FUNCPTR))#ifdef _WRS_MIPS16/* mips16 register index to 32 bit mode register index conversion array */LOCAL int reg32Inx[8] = {16,17,2,3,4,5,6,7};LOCAL INSTR * wdbNpc32Get (REG_SET *);LOCAL void * wdbNpc16Get (REG_SET *);#endif/******************************************************************************* wdbDbgArchInit - set exception handlers for the break and the trace.** RETURNS: N/A** NOMANUAL*/void wdbDbgArchInit(void) { intVecSet ((FUNCPTR *) INUM_TO_IVEC(IV_BP_VEC), (FUNCPTR) wdbDbgBpStub);#if (DBG_HARDWARE_BP) intVecSet ((FUNCPTR *) INUM_TO_IVEC (IV_WATCH_VEC), (FUNCPTR) wdbDbgArchHwBreakpoint);#endif /* (DBG_HARDWARE_BP) */ }/********************************************************************************* wdbDbgBpStub - breakpoint handling** Called from "excStub" exception vector handler upon decoding a BREAK* exception in the CAUSE register. Upon entry, `a0' contains the exception* code number, `a1' the exception stack frame pointer, and `a2' points to * the saved task registers.** The code value in the actual BREAK instruction hit determines whether* this exception should be processed by the native debugger or the* remote (i.e., VME backplane) debugger. A code of zero (0) means native.** NOMANUAL*/LOCAL void wdbDbgBpStub ( int vecNum, /* exception vector number */ ESFMIPS * pEsf, /* pointer to exception stack frame */ REG_SET * pRegs /* pointer to buf containing saved regs */ ) { uint16_t breakType; /* type of break point */ breakType = excBreakTypeGet(pEsf); if (breakType < NUM_WDB_DBG_ARCH_HANDLERS) (wdbDbgArchHandler[breakType]) (vecNum, pEsf, pRegs); #ifdef _WRS_MIPS16#endif /* _WRS_MIPS16 */ }/******************************************************************************** wdbDbgArchBreakpoint - setup to call breakpoint handler.** RETURNS: N/A** NOMANUAL*/LOCAL void wdbDbgArchBreakpoint ( int vecNum, /* exception vector number */ ESFMIPS * pInfo, /* pointer to esf info saved on stack */ REG_SET * pRegs /* pointer to buf containing saved regs */ ) {#if (DBG_HARDWARE_BP) /* clear debug registers */ wdbDbgRegsClear ();#endif /* (DBG_HARDWARE_BP) */ /* Provide the cause register value for wdbDbgGetNpc() */ pRegs->cause = pInfo->cause; /* * If the breaked instruction is a branch delay slot then the PC is the * address of the branch instruction immadiately preceding the delay slot. * It must be changed to match with the breakpoint address. */ /* mips16 code does not have branch delay slots. * It only has delay slots for jump instructions. * * BUG: There are both 32-bit and 16 bit jump instructions on mips16. * This code is oversimplified. * Should place code here to implement table 6.6 P. 6-31 in TR4101 Technical * Manual. This logic is also needed in excArchLib.c (excBreakTypeGet) * to retrieve the break instruction correctly. */ if (pRegs->cause & CAUSE_BD) /* Branch Delay Slot */ pRegs->pc++; #ifdef SOFT_FLOAT pRegs->fpcsr = 0;#else /* SOFT_FLOAT */ /* Provide the FPCSR register value for wdbDbgGetNpc() */ if (fppProbe() == OK) pRegs->fpcsr = pInfo->fpcsr; else pRegs->fpcsr = 0;#endif /* SOFT_FLOAT */ #ifdef _WRS_R3K_EXC_SUPPORT /* restore old sr so it looks like an rfe occured * thus allowing interrupts. */ pRegs->sr = (pRegs->sr & ~(SR_KUP|SR_IEP|SR_KUC|SR_IEC)) | ((pRegs->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 */ pRegs->sr &= ~SR_EXL;#endif wdbDbgTrap (pRegs->pc, pRegs, (void *) NULL, (void *) NULL, FALSE); }#if (DBG_HARDWARE_BP)/******************************************************************************** wdbDbgArchHwBreakpoint - setup to call breakpoint handler.** RETURNS: N/A** NOMANUAL*/LOCAL void wdbDbgArchHwBreakpoint ( int vecNum, /* exception vector number */ ESFMIPS *pInfo, /* pointer to esf info saved on stack */ REG_SET *pRegs /* pointer to buf containing saved regs */ ) { DBG_REGS dbgRegs; void * pDbgRegs = &dbgRegs;#ifdef _WRS_R4650 UINT32 causeReg;#endif /* _WRS_R4650 */ /* read the debug registers */ wdbDbgRegsGet (pDbgRegs); /* Clear debug registers */ wdbDbgRegsClear (); /* Provide the cause register value for hardware breakpoints handling */ dbgRegs.cause = pInfo->cause;#ifdef _WRS_R4650 /* Clean watch bits in the cause register */ causeReg = intCRGet (); causeReg &= ~0x03000000; intCRSet (causeReg);#endif /* _WRS_R4650 */ /* Provide the cause register value for wdbDbgGetNpc() */ pRegs->cause = pInfo->cause; /* * If the breaked instruction is a branch delay slot then the PC is the * address of the branch instruction immadiately preceding the delay slot. * It must be changed to match with the breakpoint address. */ if (pRegs->cause & CAUSE_BD) /* Branch Delay Slot */ pRegs->pc++; /* Provide the FPCSR register value for wdbDbgGetNpc() */ if (fppProbe() == OK) pRegs->fpcsr = pInfo->fpcsr; else pRegs->fpcsr = 0;#ifndef _WRS_R3K_EXC_SUPPORT /* Restore old sr so it looks like an eret occured */ pRegs->sr &= ~SR_EXL;#endif wdbDbgTrap(pRegs->pc, pRegs, (void *) NULL, (void *) pDbgRegs, TRUE); }#endif /* DBG_HARDWARE_BP *//******************************************************************************** wdbDbgTraceModeSet - lock interrupts and set the trace bit.** Because MIPS has no trace mode, all this routine needs to do is* lock interrupts for the reg set.** RETURNS: the old int level** NOMANUAL*/ int wdbDbgTraceModeSet ( REG_SET *pRegs ) { return intRegsLock (pRegs); }/******************************************************************************** wdbDbgTraceModeClear - restore old int lock level and clear the trace bit.** Because MIPS has no trace mode, all this routine needs to do is* restore the int mask from the last wdbDbgTraceModeSet().** RETURNS: N/A** NOMANUAL*/ void wdbDbgTraceModeClear ( REG_SET *pRegs, int oldSr ) { intRegsUnlock (pRegs, oldSr); }#ifdef _WRS_MIPS16/***************************************************************************** wdbNpcSizeGet - Get the next breakpoint instruction size** Usually the size is 2 in 16 bit mode, and 4 in 32 bit mode. But when program* jumps from 16 bit mode to 32 bit mode,or other way around, the size should* be either 4 or 2.**/int wdbNpcSizeGet ( REG_SET *pRegs /* pointer to task registers */ ) { ULONG pc; int npcSize; pc = (ULONG)(pRegs->pc); if (pc & 0x1) { /* in mips16 mode */ UINT16 instr16; /* defalut size is 2 */ npcSize = 2; pc &= ~0x1; instr16 = *(UINT16 *)pc; if ( (instr16 & 0xfc00) == 0x1c00) /* jalx */ /* jumping to a 32 bit function */ npcSize = 4; else if ( (instr16 & 0xf81f) == 0xe800) { /* J(AL)R */ if ((instr16 & 0x7e0) == 0x20) { /* JR ra instr */ if ( !((ULONG)(pRegs->gpreg[31]) & 0x1) ) /* jumping to a 32 bit function */ npcSize = 4; } else { /* JR rx or JALR ra,rx */ if (!((pRegs->gpreg[reg32Inx[M16_RX(instr16)]]) & 0x1)) /* jumping to a 32 bit function */ npcSize = 4; } } } /* if (pc & 0x1)*/ else { /* 32 bit mode */ ULONG machInstr; machInstr = *(ULONG *)pc; npcSize = 4; if (((machInstr & 0xfc1f07ff) == 0x00000009) || ((machInstr & 0xfc1fffff) == 0x00000008)) { if ( (pRegs->gpreg[(machInstr >> 21) & 0x1f]) & 0x1) /* jumping to a 16 bit function */ npcSize = 2; } } return (npcSize); }/******************************************************************************** wdbGetNpc - get the next pc** If not in the delay slot of a jump or branch instruction,* the next instruction is always pc+4 (all branch and jump instructions* have 1 delay slot). Otherwise the npc is the target of the jump or branch.** For branch and jump instructions, the instruction in the delay slot is* never reported. The expectation is that a breakpoint will be set on* the instruction that is returned. When a resuming from a breakpoint* hit in a delay slot, execution restarts at the branch or jump.** RETURNS: The next instruction** NOMANUAL*/INSTR * wdbDbgGetNpc ( REG_SET *pRegs /* pointer to task registers */ ) { INSTR * ret; if ((ULONG)(pRegs->pc) & 0x1) ret = (INSTR *)wdbNpc16Get(pRegs); else ret = wdbNpc32Get(pRegs); return (ret); }/**************************************************************************** wdbNpc16Get - Get next instruction address running in mips16 mode.**/LOCAL void * wdbNpc16Get ( REG_SET *pRegs ) { UINT16 instr16; ULONG npc; ULONG disp; ULONG extImm; ULONG pc; /* mips16 code does not have branch delay slots. If a branch is taken, * the instruction that immediately follows the branch(the delay slot * instruction) is cancelled. * However there is a delay slot for jump instructions. Branch,jump * or extended instructions must not be placed in the jump delay slot */ pc = (ULONG)(pRegs->pc) & EPC_PC; instr16 = *(UINT16 *)pc; extImm = 0; /* if it is a extend instruction, extract the immediate field * and advance to the next instruction. The M16_EXTEND_IMM macro * works for all extended instructions ***EXCEPT*** EXT-RRI-A * format (ADDIU) and EXT-SHIFT format (SHIFT). Since neither * of these instructions branch or jump, they are a "don't-care". */ if (M16_INSTR_OPCODE(instr16) == M16_EXTEND_INSTR) { extImm = M16_EXTEND_IMM(instr16); pc += 2; instr16 = *(UINT16 *)pc; } /* default next pc */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -