📄 wdbdbgarchlib.c
字号:
npc = pc + 2; switch (M16_INSTR_OPCODE(instr16)) { case M16_B_INSTR: /* B instr */ /* It is expected that the bit 5 to bit 10 of the B instruction is * zero when the preceding instruction is EXTEND. */ disp = (instr16 & (~M16_OPCODE_MASK)) | extImm; /* sign(msb of the offset) extended to 32 bit */ if (!extImm) disp = ((int)(disp << 21)) >> 20; else disp = ((int)(disp << 16)) >> 15; npc = disp + pc + 2; break; case M16_BEQZ_INSTR: /* BEQZ */ case M16_BNEZ_INSTR: /* BNEZ */ { int regNo; /* offset and signed extended */ disp = (instr16 & 0xff) | extImm; if (!extImm) disp = ((int)(disp << 24)) >> 23; else disp = ((int)(disp << 16)) >> 15; /* convert register index for 16 bit instruction to 32 bit's */ regNo = reg32Inx[M16_RX(instr16)]; if ( (pRegs->gpreg[regNo] == 0 && M16_INSTR_OPCODE(instr16) == M16_BEQZ_INSTR) || (pRegs->gpreg[regNo] != 0 && M16_INSTR_OPCODE(instr16) == M16_BNEZ_INSTR) ) npc = pc + disp + 2; } break; case M16_I8_INSTR: if ( (instr16 & 0x0700) == 0x0000 || (instr16 & 0x0700) == 0x0100 ) { /* BTEQZ or BTNEZ */ disp = (instr16 & 0xff) | extImm; if (!extImm) disp = ((int)(disp << 24)) >> 23; else disp = ((int)(disp << 16)) >> 15; if ( (pRegs->gpreg[24] == 0 && (instr16 & 0x0700) == 0x0000) || (pRegs->gpreg[24] != 0 && (instr16 & 0x0700) == 0x0100) ) npc = disp + pc + 2; } break; case M16_JALNX_INSTR: /* JAL or JALX*/ disp = ((*(UINT16 *)pc) << 16) + (*((UINT16 *)pc + 1)); disp = M16_JALX_IMM(disp); npc = ((pc + 4) & 0xf0000000) | disp; break; case M16_RR_INSTR: if (!(instr16 & 0x1f)) { /* J(AL)R */ if ( (instr16 & 0x7e0) == 0x20) /* JR ra instr */ npc = (pRegs->gpreg[31]) & 0xfffffffe; else /* JR rx or JALR ra,rx */ npc = (pRegs->gpreg[reg32Inx[M16_RX(instr16)]]) & 0xfffffffe; } break; default: break; } /* end switch */ return ((void *)npc); }#endif /* _WRS_MIPS16 */#ifndef _WRS_MIPS16/******************************************************************************** wdbDbgGetNpc - 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 #else LOCAL INSTR * wdbNpc32Get#endif /* _WRS_MIPS16 */ ( REG_SET *pRegs /* pointer to task registers */ ) { int rsVal; int rtVal; int disp; INSTR machInstr; ULONG npc; ULONG pc;#if FALSE /* * If we are in a branch delay slot, the pc has been changed in the * breakpoint handler to match with the breakpoint address. * It is modified to have its normal value. */ if (pRegs->cause & CAUSE_BD) pRegs->pc--;#endif /* FALSE */ pc = (ULONG) pRegs->pc; machInstr = *(INSTR *) pRegs->pc; /* Get the Instruction */ /* Default instruction is the next one. */ npc = pc + 4; /* * Do not report the instruction in a branch delay slot as the * next pc. Doing so will mess up the WDB_STEP_OVER case as * the branch instruction is re-executed. */ /* * Check if we are on a branch likely instruction, which will nullify * the instruction in the slot if the branch is taken. * Also, pre-extract some of the instruction fields just to make coding * easier. */ rsVal = pRegs->gpreg[(machInstr >> 21) & 0x1f]; rtVal = pRegs->gpreg[(machInstr >> 16) & 0x1f]; disp = ((int) ((machInstr & 0x0000ffff) << 16)) >> 14; if ((machInstr & 0xf3ff0000) == 0x41020000) /* BCzFL */ { int copId = (machInstr >> 26) & 0x03; npc = pc + 8; switch (copId) { case 1:#ifndef SOFT_FLOAT if ((pRegs->fpcsr & FP_COND) != FP_COND) npc = disp + pc + 4;#endif /* !SOFT_FLOAT */ break; } } else if ((machInstr & 0xf3ff0000) == 0x41030000) /* BCzTL */ { int copId = (machInstr >> 26) & 0x03; npc = pc + 8; switch (copId) { case 1:#ifndef SOFT_FLOAT if ((pRegs->fpcsr & FP_COND) == FP_COND) npc = disp + pc + 4;#endif /* !SOFT_FLOAT */ break; } } else if (((machInstr & 0xfc1f0000) == 0x04130000) /* BGEZALL*/ || ((machInstr & 0xfc1f0000) == 0x04030000)) /* BGEZL */ { if (rsVal >= 0) npc = disp + pc + 4; else npc = pc + 8; } else if ((machInstr & 0xfc1f0000) == 0x5c000000) /* BGTZL */ { if (rsVal > 0) npc = disp + pc + 4; else npc = pc + 8; } else if ((machInstr & 0xfc1f0000) == 0x58000000) /* BLEZL */ { if (rsVal <= 0) npc = disp + pc + 4; else npc = pc + 8; } else if (((machInstr & 0xfc1f0000) == 0x04120000) /* BLTZALL*/ || ((machInstr & 0xfc1f0000) == 0x04020000)) /* BLTZL */ { if (rsVal < 0) npc = disp + pc + 4; else npc = pc + 8; } else if ((machInstr & 0xfc000000) == 0x50000000) /* BEQL */ { if (rsVal == rtVal) npc = disp + pc + 4; else npc = pc + 8; } else if ((machInstr & 0xfc000000) == 0x54000000) /* BNEL */ { if (rsVal != rtVal) npc = disp + pc + 4; else npc = pc + 8; } else if (((machInstr & 0xfc000000) == 0x08000000) /* J */ || ((machInstr & 0xfc000000) == 0x0c000000)) /* JAL */ npc = ((machInstr & 0x03ffffff) << 2) | (pc & 0xf0000000); else if (((machInstr & 0xfc1f07ff) == 0x00000009) /* JALR */ || ((machInstr & 0xfc1fffff) == 0x00000008)) /* JR */ npc = pRegs->gpreg[(machInstr >> 21) & 0x1f]; else if ((machInstr & 0xf3ff0000) == 0x41000000) /* BCzF */ { int copId = (machInstr >> 26) & 0x03; npc = pc + 8; switch (copId) { case 1:#ifndef SOFT_FLOAT if ((pRegs->fpcsr & FP_COND) != FP_COND) npc = disp + pc + 4;#endif /* !SOFT_FLOAT */ break; } } else if ((machInstr & 0xf3ff0000) == 0x41010000) /* BCzT */ { int copId = (machInstr >> 26) & 0x03; npc = pc + 8; switch (copId) { case 1:#ifndef SOFT_FLOAT if ((pRegs->fpcsr & FP_COND) == FP_COND) npc = disp + pc + 4;#endif /* !SOFT_FLOAT */ break; } } else if ((machInstr & 0xfc000000) == 0x10000000) /* BEQ */ { if (rsVal == rtVal) npc = disp + pc + 4; else npc = pc + 8; } else if (((machInstr & 0xfc1f0000) == 0x04010000) /* BGEZ */ || ((machInstr & 0xfc1f0000) == 0x04110000)) /* BGEZAL */ { if (rsVal >= 0) npc = disp + pc + 4; else npc = pc + 8; } else if ((machInstr & 0xfc1f0000) == 0x1c000000) /* BGTZ */ { if (rsVal > 0) npc = disp + pc + 4; else npc = pc + 8; } else if ((machInstr & 0xfc1f0000) == 0x18000000) /* BLEZ */ { if (rsVal <= 0) npc = disp + pc + 4; else npc = pc + 8; } else if (((machInstr & 0xfc1f0000) == 0x04000000) /* BLTZ */ || ((machInstr & 0xfc1f0000) == 0x04100000)) /* BLTZAL */ { if (rsVal < 0) npc = disp + pc + 4; else npc = pc + 8; } else if ((machInstr & 0xfc000000) == 0x14000000) /* BNE */ { if (rsVal != rtVal) npc = disp + pc + 4; else npc = pc + 8; } else { /* normal instruction */ } return (INSTR *) npc; }#if (DBG_HARDWARE_BP)/******************************************************************************** wdbDbgHwBpSet - set a data breakpoint register** type is the type of access that will generate a breakpoint.** NOMANUAL*/STATUS wdbDbgHwBpSet ( DBG_REGS * pDbgReg, /* debug registers */ UINT32 access, /* access type */ UINT32 addr /* breakpoint addr */ ) { int status = OK; switch (access) { case BRK_WRITE: case BRK_READ: case BRK_RW:#ifndef _WRS_R4650 if (pDbgReg->watchLo == 0) { pDbgReg->watchLo = (K0_TO_PHYS(addr) & ~7) | access; pDbgReg->watchHi = 0; } else status = WDB_ERR_HW_REGS_EXHAUSTED; break;#else if (pDbgReg->dWatch == 0) pDbgReg->dWatch = (((UINT32) addr & ~7) | ((access << 1) & 0x6)); else status = WDB_ERR_HW_REGS_EXHAUSTED; break; case BRK_INST: if (pDbgReg->iWatch == 0) pDbgReg->iWatch = ((UINT32) addr & ~3) | 0x1; else status = WDB_ERR_HW_REGS_EXHAUSTED; break;#endif /* _WRS_R4650 */ default: status = WDB_ERR_INVALID_HW_BP; } return (status); }/******************************************************************************** wdbDbgHwBpFind - Find the hardware breakpoint** This routines find the type and the address of the address of the* hardware breakpoint that is set in the DBG_REGS structure.* Those informations are stored in the breakpoint structure that is passed* in parameter.** RETURNS : OK or ERROR if unable to find the hardware breakpoint** NOMANUAL*/STATUS wdbDbgHwBpFind ( DBG_REGS * pDbgRegs, UINT32 * pType, /* return type info via this pointer */ UINT32 * pAddr /* return address info via this pointer */ ) { int eventFlags; int addr = 0; int type = 0;#ifndef _WRS_R4650 eventFlags = pDbgRegs->cause & 0x00800000; if (eventFlags) { type = (pDbgRegs->watchLo & 0x3) | BRK_HARDWARE; addr = PHYS_TO_K0 (pDbgRegs->watchLo & ~0x7); }#else eventFlags = pDbgRegs->cause & 0x03000000; if (eventFlags & 0x02000000) { type = ((pDbgRegs->dWatch >> 1) & 0x3) | BRK_HARDWARE; addr = pDbgRegs->dWatch & ~0x7; } else if (eventFlags & 0x01000000) { type = BRK_INST | BRK_HARDWARE; addr = pDbgRegs->iWatch & ~0x3; }#endif /* _WRS_R4650 */ if ((addr == 0) && (type == 0)) return (ERROR); *pType = type; *pAddr = addr; return (OK); }/********************************************************************************* wdbDbgHwAddrCheck - check the address for the hardware breakpoint.** This routine check the address for the hardware breakpoint.** RETURNS: OK or ERROR if the address is not appropriate.** NOMANUAL*/STATUS wdbDbgHwAddrCheck ( UINT32 addr, /* instuction pointer */ UINT32 type, /* access type */ FUNCPTR memProbeRtn /* memProbe routine */ ) { UINT32 val; /* dummy for memProbeRtn */ if (addr & 0x03) return (ERROR); switch (type) { case BRK_WRITE: case BRK_READ: case BRK_RW:#ifdef _WRS_R4650 case BRK_INST:#endif /* _WRS_R4650) */ if (memProbeRtn ((char *)addr, O_RDONLY, 4, (char *) &val) != OK) { return (ERROR); } break; default: break; } return (OK); }/********************************************************************************* wdbDbgRegsClear - clear hardware break point registers** This routine clears hardware breakpoint registers.** RETURNS : N/A.** NOMANUAL*/void wdbDbgRegsClear ( void ) { DBG_REGS dbgRegs;#ifndef _WRS_R4650 dbgRegs.watchLo = 0; dbgRegs.watchHi = 0;#else dbgRegs.iWatch = 0; dbgRegs.dWatch = 0;#endif /* _WRS_R4650 */ wdbDbgRegsSet (&dbgRegs); }#endif /* (DBG_HARDWARE_BP) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -