📄 wdbdbgarchlib.c
字号:
/* wdbDbgArchLib.c - PowerPc specific callouts for the debugger *//* Copyright 1988-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01w,02dec02,mil Updated support for PPC85XX.01v,03aug02,pcs Add support for PPC85XX and make it the same as PPC603 for the present.01u,16may02,pch add cross-ref for maintainability01t,14mar02,pch SPR 74270: make 440 bh types consistent with 5xx/604/86001s,22aug01,pch Add PPC440 support; cleanup01r,03may01,pch fix 403 breakage introduced in 405 project01q,30oct00,s_m merged changes for 403 HW BP support01p,27oct00,s_m changes for PPC405 support01o,25oct00,s_m renamed PPC405 cpu types01n,11oct00,sm fixed problems with 40501m,10oct00,sm set _func_excTrapRtn to wdbDbgBreakpoint for 40501l,06oct00,sm PPC405 support01k,19apr99,zl added PowerPC 509 and 555 support.01k,09nov98,elg added hardware breakpoints for PPC40301j,13oct98,elg added hardware breakpoints for PPC603 and PPC60401i,20sep98,tpr added PowerPC EC603 support.01h,28jul98,elg added hardware breakpoints01g,09jan98,dbt modified for new breakpoint scheme01f,12feb97,tam modified wdbArchInit to get rid off wdbBpStub() 01e,09jul96,ms modified 403 support for new WDB breakpoint library01d,09may96,tpr added PowerPC 860 support.01c,26feb96,tam added support for PPC403. Added single step support for the PPC403.01b,26feb96,kkk use _EXC_OFF_RUN_TRACE for trace on 60101a,09sep95,xxx written.*//*DESCRIPTIONThis module contains the architecture specific calls needed by the debuggerHardware breakpoint support should be coordinated withhwBpTypeList in host/resource/tcl/dbgPpcLib.tcl, anddocumented in host/src/tgtsvr/server/wtx.pcl*/#include "vxWorks.h"#include "regs.h"#include "iv.h"#include "intLib.h"#include "ioLib.h"#include "wdb/wdbDbgLib.h"#include "arch/ppc/excPpcLib.h"#include "arch/ppc/vxPpcLib.h"#if (CPU == PPC604)#include "arch/ppc/mmuArchVars.h"#endif /* (CPU == PPC604) *//* externals */IMPORT void wdbDbgTraceStub();IMPORT FUNCPTR _func_excTrapRtn;#if DBG_HARDWARE_BPIMPORT void wdbDbgHwBpStub ();# if (CPU == PPC604)IMPORT void wdbDbgDataAccessStub ();# endif /* (CPU == PPC604) */#endif /* DBG_HARDWARE_BP */#if ((CPU == PPC405) || (CPU == PPC405F))/* * Table containing mappings of hardware data breakpoint types and * the corresponding DBCR1 bit settings. Each row represents one * breakpoint type. Column 1 in the table is for the first data * breakpoint and column 2 is for the second. */static UINT32 wdbDbgDbcr1ValTable [][2] = { { 0, 0 }, /* dummy entry for BRK_INST */ { _DBCR1_D1W | _DBCR1_D1S_BYTE, _DBCR1_D2W | _DBCR1_D2S_BYTE }, /* BRK_DATAW1 */ { _DBCR1_D1R | _DBCR1_D1S_BYTE, _DBCR1_D2R | _DBCR1_D2S_BYTE }, /* BRK_DATAR1 */ { _DBCR1_D1R | _DBCR1_D1W | _DBCR1_D1S_BYTE, _DBCR1_D2R | _DBCR1_D2W | _DBCR1_D2S_BYTE }, /* BRK_DATARW1 */ { _DBCR1_D1W | _DBCR1_D1S_HWORD, _DBCR1_D2W | _DBCR1_D2S_HWORD }, /* BRK_DATAW2 */ { _DBCR1_D1R | _DBCR1_D1S_HWORD, _DBCR1_D2R | _DBCR1_D2S_HWORD }, /* BRK_DATAR2 */ { _DBCR1_D1R | _DBCR1_D1W | _DBCR1_D1S_HWORD, _DBCR1_D2R | _DBCR1_D2W | _DBCR1_D2S_HWORD}, /* BRK_DATARW2 */ { _DBCR1_D1W | _DBCR1_D1S_WORD, _DBCR1_D2W | _DBCR1_D2S_WORD }, /* BRK_DATAW4 */ { _DBCR1_D1R | _DBCR1_D1S_WORD, _DBCR1_D2R | _DBCR1_D2S_WORD }, /* BRK_DATAR4 */ { _DBCR1_D1R | _DBCR1_D1W | _DBCR1_D1S_WORD, _DBCR1_D2R | _DBCR1_D2W | _DBCR1_D2S_WORD }, /* BRK_DATARW4 */ { _DBCR1_D1W | _DBCR1_D1S_CACHE_LINE, _DBCR1_D2W | _DBCR1_D2S_CACHE_LINE }, /* BRK_DATAW32 */ { _DBCR1_D1R | _DBCR1_D1S_CACHE_LINE, _DBCR1_D2R | _DBCR1_D2S_CACHE_LINE }, /* BRK_DATAR32 */ { _DBCR1_D1R | _DBCR1_D1W | _DBCR1_D1S_CACHE_LINE, _DBCR1_D2R | _DBCR1_D2W | _DBCR1_D2S_CACHE_LINE }, /* BRK_DATARW32 */ };#elif ((CPU == PPC440) || (CPU == PPC85XX))/* * Table containing mappings of hardware data breakpoint types and * the corresponding DBCR0 bit settings. Each row represents one * breakpoint type. Column 1 in the table is for the first data * breakpoint and column 2 is for the second. */static UINT32 wdbDbgDbcr0ValTable [][2] = { { 0, 0 }, /* dummy entry for BRK_INST */ { _DBCR0_DAC1R | _DBCR0_DAC1W, _DBCR0_DAC2R | _DBCR0_DAC2W }, /* BRK_DATARW */ { _DBCR0_DAC1R, _DBCR0_DAC2R }, /* BRK_DATAR */ { _DBCR0_DAC1W, _DBCR0_DAC2W }, /* BRK_DATAW */ };#endif /* CPU == PPC405 || CPU == PPC405F : CPU == PPC440 || CPU == PPC85XX *//* forward declaration */#if DBG_HARDWARE_BPLOCAL void wdbDbgRegsGet (DBG_REGS * pDbgReg);#endif /* DBG_HARDWARE_BP *//********************************************************************************* wdbDbgArchInit - set exception handlers for the break and the trace.** This routine set exception handlers for the break and the trace.* And also make a break instruction.*/void wdbDbgArchInit(void) {#if DBG_NO_SINGLE_STEP _func_excTrapRtn = (FUNCPTR) wdbDbgTrap;#else /* DBG_NO_SINGLE_STEP */ _func_excTrapRtn = (FUNCPTR) wdbDbgBreakpoint;#endif /* DBG_NO_SINGLE_STEP */#if (CPU == PPC601) excVecSet ((FUNCPTR *) _EXC_OFF_RUN_TRACE, (FUNCPTR) wdbDbgTraceStub);#elif ((CPU == PPC509) || (CPU == PPC555) || (CPU == PPC603) || \ (CPU == PPCEC603) || (CPU == PPC604) || (CPU == PPC860)) excVecSet ((FUNCPTR *) _EXC_OFF_TRACE, (FUNCPTR) wdbDbgTraceStub);#endif /* 601 : 509 | 555 | 603 | EC603 | 604 | 860 */#if DBG_HARDWARE_BP# if ((CPU == PPC509) || (CPU == PPC555) || (CPU == PPC860)) excVecSet ((FUNCPTR *) _EXC_OFF_DATA_BKPT, (FUNCPTR) wdbDbgHwBpStub);# elif (CPU == PPC604) excVecSet ((FUNCPTR *) _EXC_OFF_DATA, (FUNCPTR) wdbDbgDataAccessStub);# endif /* PPC509 | PPC555 | PPC860 : PPC604 */# if ((CPU == PPC509) || (CPU == PPC555) || (CPU == PPC603) || \ (CPU == PPCEC603) || (CPU == PPC604) || (CPU == PPC860)) excVecSet ((FUNCPTR *) _EXC_OFF_INST_BKPT, (FUNCPTR) wdbDbgHwBpStub);# elif (defined(_PPC_MSR_CE)) excCrtConnect ((VOIDFUNCPTR *) _EXC_OFF_DBG, (VOIDFUNCPTR) wdbDbgHwBpStub);# endif /* 509 | 555 | 603 | EC603 | 604 | 860 : _PPC_MSR_CE */#endif /* DBG_HARDWARE_BP */ }/******************************************************************************** wdbDbgTraceModeSet - lock interrupts and set the trace bit.*/ int wdbDbgTraceModeSet ( REG_SET * pRegs /* pointer to the register set */ ) { int oldMsr; oldMsr = intRegsLock (pRegs);#ifdef _PPC_MSR_SE pRegs->msr |= _PPC_MSR_SE;#endif /* _PPC_MSR_SE */ return (oldMsr); }/******************************************************************************** wdbDbgTraceModeClear - restore old int lock level and clear the trace bit.*/ void wdbDbgTraceModeClear ( REG_SET * pRegs, /* pointer to the register set */ int oldMsr /* old value of Machine status register */ ) { intRegsUnlock (pRegs, oldMsr);#ifdef _PPC_MSR_SE pRegs->msr &= ~_PPC_MSR_SE;#endif /* _PPC_MSR_SE */ }#if DBG_NO_SINGLE_STEP /* no h/w single stepping *//********************************************************************************* wdbDbgGetNpc - returns the adress of the next instruction to be executed.** RETURNS: Adress of the next instruction to be executed.*/INSTR * wdbDbgGetNpc ( REG_SET * pRegs /* pointer to task registers */ ) { INSTR machInstr; /* Machine instruction */ INSTR * npc; /* next program counter */ UINT32 branchType; UINT32 li; /* LI field */ UINT32 lr; /* LR field */ UINT32 bd; /* BD field */ UINT32 bo; /* BO field */ UINT32 bi; /* BI field */ _RType ctr; /* CTR register */ INSTR * cr; /* CR register */ BOOL cond; UINT32 bo2,bo3,bo0,bo1,crbi; /* bits values */ npc = (INSTR *) (pRegs->pc + 4); /* Default nPC */ machInstr = *(INSTR *)(pRegs->reg_pc); /* * tests for branch instructions: * bits 0-3 are common for all branch */ if ((machInstr & BRANCH_MASK) == OP_BRANCH) { /* opcode bits 0 to 5 equal 16,17,18 or 19 */ branchType = (machInstr & 0xFC000000) >> 26; ctr = pRegs->ctr; cr = (INSTR *) pRegs->cr; lr = pRegs->lr; li = _IFIELD_LI (machInstr); bo = _IFIELD_BO (machInstr); bi = _IFIELD_BI (machInstr); bd = _IFIELD_BD (machInstr); bo0 = _REG32_BIT (bo, (BO_NB_BIT-1)); /* bit 0 of BO */ bo1 = _REG32_BIT (bo, (BO_NB_BIT-2)); /* bit 1 of BO */ bo2 = _REG32_BIT (bo, (BO_NB_BIT-3)); /* bit 2 of BO */ bo3 = _REG32_BIT (bo, (BO_NB_BIT-4)); /* bit 3 of BO */ crbi = _REG32_BIT ((UINT32) cr, (CR_NB_BIT-1-((UINT32) bi))); /* bit bi of CR */ /* Switch on the type of branch (Bx, BCx, BCCTRx, BCLRx) */ switch (branchType) { case (16): /* BC - Branch Conditional */ { if (bo2 == 0) /* bit 2 of BO == 0 */ ctr--; /* decrement CTR register */ /* test branch condition */ cond = FALSE; if ((bo2 == 1) || ((ctr == 0) && (bo3 == 0)) ) if ((bo0 == 1) || (bo1 == crbi)) cond = TRUE; if (cond) if ((machInstr & AA_MASK) == 1) npc = (INSTR *) bd; /* AA = 1 : absolute branch */ else /* AA = 0 : relative branch */ npc = (INSTR *) (pRegs->pc + bd); } break; case (18): /* B - Unconditional Branch */ { if ((machInstr & AA_MASK) == 1) npc = (INSTR *) li; /* AA = 1 : absolute branch */ else /* AA = 0 : relative branch */ npc = (INSTR *)(pRegs->pc + li); } break; case (19): /* Bcctr or Bclr - Branch Conditional to Register */ { if ((machInstr & BCCTR_MASK) == INST_BCCTR) { /* Bcctr - Branch Conditional to Count Register */ if (bo2 == 0) /* bit 2 of BO == 0 */ ctr--; /* decrement CTR register */ /* test branch condition */ cond = FALSE; if ((bo2 == 1) || ((ctr == 0) && (bo3 == 0))) if ((bo0 == 1) || (bo1 == crbi)) cond = TRUE; if (cond) /* branch relative to CTR */ npc = (INSTR *) (ctr & 0xFFFFFFFC); } if ((machInstr & BCLR_MASK) == INST_BCLR) { /* Bclr - Branch Conditional to Link Register */ if (bo2 == 0) /* bit 2 of BO == 0 */ ctr--; /* decrement CTR register */ /* test branch condition */ cond = FALSE; if ((bo2 == 1) || ((ctr == 0) && (bo3 == 0))) if ((bo0 == 1) || (bo1 == crbi)) cond = TRUE; if (cond) /* branch relative to LR */ npc = (INSTR *) (lr & 0xFFFFFFFC); } } break; } } return (npc); }#endif /* DBG_NO_SINGLE_STEP */#if DBG_HARDWARE_BP/********************************************************************************* wdbDbgHwAddrCheck - check the address for the hardware breakpoint.** This routine checks the address for the hardware breakpoint.** RETUTNS: OK or ERROR if address not 32-bit boundary or unaccessible.** NOMANUAL*/STATUS wdbDbgHwAddrCheck ( UINT32 addr, /* address to check */ UINT32 type, /* access type */ FUNCPTR memProbeRtn /* memProbe routine */ ) { UINT32 val; /* dummy for memProbeRtn */ type = (type & BRK_HARDMASK); /* * Breakpoint address must be 32bit-aligned except for a data breakpoint * on a PPC4xx/5xx/860 where it is possible to break on a byte access. */#if ((CPU == PPC509) || (CPU == PPC555) || (CPU == PPC860) || \ (CPU == PPC405F) || (CPU == PPC405) || (CPU == PPC440) || \ (CPU == PPC85XX)) if (type == BRK_INST)#endif /* CPU == PPC5xx, PPC860, PPC4xx, PPC85XX */ if (addr & 0x03) return (ERROR); switch (type) {#if (CPU == PPC509) || (CPU == PPC555) || (CPU == PPC603) || \ (CPU == PPCEC603) || (CPU == PPC604) || (CPU == PPC860) case BRK_INST: case BRK_READ: case BRK_WRITE: case BRK_RW: if (memProbeRtn ((char *) (addr & ~0x03), O_RDONLY, 4, (char *) &val) != OK) return (ERROR); break;#elif ( (CPU == PPC403) || (CPU == PPC405) || (CPU == PPC405F) ) case BRK_DATAR1: case BRK_DATAW1: case BRK_DATARW1: if (memProbeRtn ((char *) addr, O_RDONLY, 1, (char *) &val) != OK) return (ERROR); break; case BRK_DATAR2: case BRK_DATAW2: case BRK_DATARW2: if ((addr & 0x01) || (memProbeRtn ((char *) addr, O_RDONLY, 2, (char *) &val) != OK)) return (ERROR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -