⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbgarmlib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* dbgArmLib.c - ARM-specific debug routines for dbg and wdb *//* Copyright 1996-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01h,24may01,h_k  fixed reloc to INT32 from UINT32 for BL in Thumb01g,23may01,h_k  fixed sign extention for BL in Thumb01f,04sep98,cdp  make Thumb support dependent on ARM_THUMB.01e,27oct97,kkk  took out "***EOF***" line from end of file.01d,23oct97,cdp  make thumbGetNpc() return bit zero clear for all opcodes.01c,08oct97,cdp  thumbInstrChangesPc(): clear bit zero of PC before fetching		 instruction; return false for second half of BL;		 make thumbGetNpc() return rn when PC is at BL _call_via_rn.01b,15apr97,cdp  added Thumb (ARM7TDMI_T) support.01a,08aug96,cdp  created by splitting wdbArchLib.c*//*DESCRIPTIONThis module contains some ARM-specific functions used by dbgArchLib.c,trcLib.c and wdbArchLib.c. They are in a separate file so that they can beexcluded from the image if neither dbg nor wdb is enabled. Putting them herealso saves having to maintain separate versions in parallel.*/#include "vxWorks.h"#include "regs.h"/* * check that this compiler does sign extension when an int is shifted right * because a lot of the code below relies on its doing so. */#if (((INT32)-1L) >> 1) > 0#	error right shifting an int does not perform sign extension#endif#define BIT(n) ((UINT32)1U << (n))#define BITSET(x,n) (((UINT32)(x) & (1U<<(n))) >> (n))#define BITS(x,m,n) (((UINT32)((x) & (BIT(n) - BIT(m) + BIT(n)))) >> (m))/* externals */#if (ARM_THUMB)extern int _call_via_r0 (void);extern int _call_via_r1 (void);extern int _call_via_r2 (void);extern int _call_via_r3 (void);extern int _call_via_r4 (void);extern int _call_via_r5 (void);extern int _call_via_r6 (void);extern int _call_via_r7 (void);extern int _call_via_r8 (void);extern int _call_via_r9 (void);extern int _call_via_sl (void);extern int _call_via_fp (void);extern int _call_via_ip (void);extern int _call_via_lr (void);#endif/* locals */#if (ARM_THUMB)/* * call_via_tbl is used to determine whether a BL is to one of the call_via_rn * functions (we can't guarantee we have a symbol table in which we can * look up an address. */LOCAL FUNCPTR call_via_tbl[] =    {    _call_via_r0,    _call_via_r1,    _call_via_r2,    _call_via_r3,    _call_via_r4,    _call_via_r5,    _call_via_r6,    _call_via_r7,    _call_via_r8,    _call_via_r9,    _call_via_sl,    _call_via_fp,    _call_via_ip,    _call_via_lr    };#endif/* * ccTable is used to determine whether an instruction will be executed, * according to the flags in the PSR and the condition field of the * instruction. The table has an entry for each possible value of the * condition field of the instruction. Each bit indicates whether a particular * combination of flags will cause the instruction to be executed. Since * ther are four flags, this makes 16 possible TRUE/FALSE values. */LOCAL UINT32 ccTable[] =    {    0xF0F0, 0x0F0F, 0xCCCC, 0x3333, 0xFF00, 0x00FF, 0xAAAA, 0x5555,    0x0C0C, 0xF3F3, 0xAA55, 0x55AA, 0x0A05, 0xF5FA, 0xFFFF, 0x0000    };#if (!ARM_THUMB)/********************************************************************************* armShiftedRegVal - calculate value of shifted register specified in opcode**/LOCAL UINT32 armShiftedRegVal    (    REG_SET *	pRegs,		/* pointer to task registers */    UINT32	instr,		/* machine instruction */    int		cFlag		/* value of carry flag */    )    {    UINT32 res, shift, rm, rs, shiftType;    rm = BITS(instr, 0, 3);    shiftType = BITS(instr, 5, 6);    if (BITSET(instr, 4))	{	rs = BITS(instr, 8, 11);	shift = (rs == 15 ? (UINT32)pRegs->pc + 8 : pRegs->r[rs]) & 0xFF;	}    else	shift = BITS(instr, 7, 11);    res = rm == 15		? (UINT32)pRegs->pc + (BITSET(instr, 4) ? 12 : 8)		: pRegs->r[rm];    switch (shiftType)	{	case 0:		/* LSL */	    res = shift >= 32 ? 0 : res << shift;	    break;	case 1:		/* LSR */	    res = shift >= 32 ? 0 : res >> shift;	    break;	case 2:		/* ASR */	    if (shift >= 32)		shift = 31;	    res = (res & 0x80000000L) ? ~((~res) >> shift) : res >> shift;	    break;	case 3:		/* ROR */	    shift &= 31;	    if (shift == 0)		res = (res >> 1) | (cFlag ? 0x80000000L : 0);	    else		res = (res >> shift) | (res << (32 - shift));	    break;	}    return res;    } /* armShiftedRegVal() */#endif#if (ARM_THUMB)/********************************************************************************* thumbGetNpc - get the address of the next instruction to be executed** RETURNS: address of the next instruction to be executed.** INTERNAL* This function must be passed the instruction rather than using the one* pointed to by pRegs->pc as the latter may have been replaced by a breakpoint* instruction.*/INSTR * thumbGetNpc    (    INSTR	instr,			/* the current instruction */    REG_SET *	pRegs			/* pointer to task registers */    )    {    UINT32		pc;		/* current program counter */    UINT32 		nPc;		/* next program counter */    pc = (UINT32)pRegs->pc & ~1;	/* current PC as a UINT32 */    nPc = pc + 2;			/* Thumb default */    /*     * Now examine the instruction     * Following code is derived from the ARM symbolic debugger.     */    switch (BITS(instr, 12, 15))	{	case 0x0:	case 0x1:	case 0x2:	case 0x3:	case 0x5:	case 0x6:	case 0x7:	case 0x8:	case 0x9:	case 0xA:	case 0xC:	    /* no effect on PC - next instruction executes */	    break;	case 4:	    if (BITS(instr, 7, 11) == 0x0E)		{		/* BX */		int rn;		rn = BITS(instr, 3, 6);		nPc = rn == 15 ? pc + 4 : pRegs->r[rn];		break;		}	    if (BITSET(instr, 7) && (BITS(instr, 0, 11) & 0xC07) == 0x407)		{		/* do something to pc */		int rn;		UINT32 operand;		rn = BITS(instr, 3, 6);		operand = rn == 15 ? pc + 4 : pRegs->r[rn];		switch (BITS(instr, 8, 9))		    {		    case 0:		/* ADD */			nPc = pc + 4 + operand;			break;		    case 1:		/* CMP */			break;		    case 2:		/* MOV */			nPc = operand;			break;		    case 3:		/* BX - already handled */			break;		    }		}	    break;	case 0xB:	    if (BITS(instr, 8, 11) == 0xD)		{		/* POP {rlist, pc} */		INT32 offset = 0;		UINT32 regList, regBit;		for (regList = BITS(instr, 0, 7); regList != 0;						regList &= ~regBit)		    {		    regBit = regList & (-regList);		    offset += 4;		    }		nPc = *(UINT32 *)(pRegs->r[13] + offset);		/* don't check for new pc == pc like ARM debugger does */		}	    break;	case 0xD:	    {	    /* SWI or conditional branch */	    UINT32 cond;	    	    cond = (instr >> 8) & 0xF;	    if (cond == 0xF)		break;	/* SWI */	    /* Conditional branch	     * Use the same mechanism as armGetNpc() to determine whether	     * the branch will be taken	     */	    if (((ccTable[cond] >> (pRegs->cpsr >> 28)) & 1) == 0)		break;	/* instruction will not be executed */	    /* branch will be taken */	    nPc = pc + 4 + (((instr & 0x00FF) << 1) |		    (BITSET(instr, 7)  ? 0xFFFFFE00 : 0));	    }	    break;	case 0xE:	    if (BITSET(instr, 11) == 0)		/* Unconditional branch */		nPc = pc + 4 + (((instr & 0x07FF) << 1) |			(BITSET(instr, 10) ? 0xFFFFF000 : 0));	    break;	case 0xF:	    /* BL */	    if (BITSET(instr, 11))		{		/* second half of BL - PC should never be here */		nPc = pRegs->r[14] + ((instr & 0x07FF) << 1);		}	    else		{		/* first half of BL */		UINT32 nextBit;		UINT i;		INT32 reloc;		nextBit = *(UINT16 *)(pc + 2);		if ((nextBit & 0xF800) != 0xF800)		    /* Something strange going on */		    break;		reloc = (INT32)(((instr & 0x7FF) << 12) |			((nextBit & 0x7FF) << 1));		reloc = (reloc ^ 0x00400000) - 0x00400000; /* sign extend */		nPc = pc + 4 + reloc;		/*		 * if it's a call to a call_via_rn function, make the		 * next PC the contents of the register being used		 * (otherwise the kernel will halt)		 */ 		for (i = 0; i < (sizeof(call_via_tbl) / sizeof(FUNCPTR)); ++i)		    if (nPc == ((UINT32)(call_via_tbl[i]) & ~1))			break;		if (i < (sizeof(call_via_tbl) / sizeof(FUNCPTR)))		    /* address matches one of the call_via_rn functions */		    nPc = pRegs->r[i];		}	    break;	} /* switch */    return (INSTR *)((UINT32)nPc & ~1);    } /* thumbGetNpc() */#else	/* (ARM_THUMB) *//********************************************************************************* armGetNpc - get the address of the next instruction to be executed** RETURNS: address of the next instruction to be executed.** INTERNAL* This function must be passed the instruction rather than using the one* pointed to by pRegs->pc as the latter may have been replaced by a breakpoint* instruction.*/INSTR * armGetNpc    (    INSTR	instr,			/* the current instruction */    REG_SET *	pRegs			/* pointer to task registers */    )    {    UINT32		pc;		/* current program counter */    UINT32 		nPc;		/* next program counter */    /*     * Early versions of this file looked at the PSR to determine whether the     * CPU was in ARM state or Thumb state and decode the next instruction     * accordingly. This has been removed since there is to be no support for     * ARM/Thumb interworking.     */    pc = (UINT32)pRegs->pc;	/* current PC as a UINT32 */    nPc = pc + 4;		/* default */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -