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

📄 mpc5xx_hi.c

📁 Coldfire MCF5282 DBug bootloader
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * File:		mpc5xx_hi.c
 * Purpose:		High level MPC5XX specific support routines.
 *
 * Notes:
 * Date:
 *
 * Modifications:
 *
 */

/*********************************************************************/

#include "src/include/dbug.h"
#include "src/uif/cpu.h"
#include "src/uif/bkpt.h"

/*********************************************************************/

/*
 * This defines the data structure which will hold the values
 * of the registers of the user task.
 */
REGISTERS context;

/*********************************************************************/

/*
 * Strings displayed upon bootup.
 */

#if	(defined(CPU_MPC555))
const char CPU_STR[] = "MPC555";

#elif (defined(CPU_MPC561))
const char CPU_STR[] = "MPC561";

#elif (defined(CPU_MPC562))
const char CPU_STR[] = "MPC562";

#elif (defined(CPU_MPC563))
const char CPU_STR[] = "MPC563";

#elif (defined(CPU_MPC564))
const char CPU_STR[] = "MPC564";

#elif (defined(CPU_MPC565))
const char CPU_STR[] = "MPC565";

#elif (defined(CPU_MPC566))
const char CPU_STR[] = "MPC566";

#else
#error "Error: Unsupported MPC5XX CPU"
#endif

const int  CPU_VER_MAJOR = 2;
const char CPU_VER_MINOR = 'a';

/*********************************************************************/

/*
 * Data structure for managing PowerPC registers.  All regs 32-bits.
 */
typedef struct
{
	char	*reg_name;
	uint32	reg_spr;
	uint32	*reg_offset;
} ppc_reg;

/*
 * This structure contains info about the registers.  The name
 * is given so that users can type it.
 */
#define regp(REG) (uint32 *)&((uint8 *)&context)[REG]

static const ppc_reg registers[] =
{
	{ "r0", 		0,		regp(MPC5XX_R0)		},
	{ "r1", 		0,		regp(MPC5XX_R1)		},
	{ "r2", 		0,		regp(MPC5XX_R2)		},
	{ "r3", 		0,		regp(MPC5XX_R3)		},
	{ "r4", 		0,		regp(MPC5XX_R4)		},
	{ "r5", 		0,		regp(MPC5XX_R5)		},
	{ "r6", 		0,		regp(MPC5XX_R6)		},
	{ "r7", 		0,		regp(MPC5XX_R7)		},
	{ "r8", 		0,		regp(MPC5XX_R8)		},
	{ "r9", 		0,		regp(MPC5XX_R9)		},
	{ "r10", 		0,		regp(MPC5XX_R10)	},
	{ "r11", 		0,		regp(MPC5XX_R11)	},
	{ "r12", 		0,		regp(MPC5XX_R12)	},
	{ "r13", 		0,		regp(MPC5XX_R13)	},
	{ "r14", 		0,		regp(MPC5XX_R14)	},
	{ "r15", 		0,		regp(MPC5XX_R15)	},
	{ "r16", 		0,		regp(MPC5XX_R16)	},
	{ "r17", 		0,		regp(MPC5XX_R17)	},
	{ "r18", 		0,		regp(MPC5XX_R18)	},
	{ "r19", 		0,		regp(MPC5XX_R19)	},
	{ "r20", 		0,		regp(MPC5XX_R20)	},
	{ "r21", 		0,		regp(MPC5XX_R21)	},
	{ "r22", 		0,		regp(MPC5XX_R22)	},
	{ "r23", 		0,		regp(MPC5XX_R23)	},
	{ "r24", 		0,		regp(MPC5XX_R24)	},
	{ "r25", 		0,		regp(MPC5XX_R25)	},
	{ "r26", 		0,		regp(MPC5XX_R26)	},
	{ "r27", 		0,		regp(MPC5XX_R27)	},
	{ "r28", 		0,		regp(MPC5XX_R28)	},
	{ "r29", 		0,		regp(MPC5XX_R29)	},
	{ "r30", 		0,		regp(MPC5XX_R30)	},
	{ "r31", 		0,		regp(MPC5XX_R31)	},

	{ "msr", 		0,		regp(MPC5XX_MSR)	},
	{ "cr", 		0,		regp(MPC5XX_CR)		},
	
	{ "fpscr",		0,		regp(MPC5XX_FPSCR)		},

	{ "XER",		1,		regp(MPC5XX_XER)		},
	{ "LR",			8,		regp(MPC5XX_LR)			},
	{ "CTR",		9,		regp(MPC5XX_CTR)		},
	{ "DSISR",		18,		regp(MPC5XX_DSISR)		},
	{ "DAR",		19,		regp(MPC5XX_DAR)		},
	{ "DEC",		22,		regp(MPC5XX_DEC)		},
	{ "SRR0",		26,		regp(MPC5XX_SRR0)		},
	{ "SRR1",		27,		regp(MPC5XX_SRR1)		},
	{ "PVR",		287,	regp(MPC5XX_PVR)		},
	{ "TBL",		268,	regp(MPC5XX_TBL)		},
	{ "TBU",		269,	regp(MPC5XX_TBU)		},
	{ "SPRG0",		272,	regp(MPC5XX_SPRG0)		},
	{ "SPRG1",		273,	regp(MPC5XX_SPRG1)		},
	{ "SPRG2",		274,	regp(MPC5XX_SPRG2)		},
	{ "SPRG3",		275,	regp(MPC5XX_SPRG3)		},
	{ "EIE",		80,		regp(MPC5XX_EIE)		},
	{ "EID",		81,		regp(MPC5XX_EID)		},
	{ "NRI",		82,		regp(MPC5XX_NRI)		},
	{ "CMPA",		144,	regp(MPC5XX_CMPA)		},
	{ "CMPB",		145,	regp(MPC5XX_CMPB)		},
	{ "CMPC",		146,	regp(MPC5XX_CMPC)		},
	{ "CMPD",		147,	regp(MPC5XX_CMPD)		},
	{ "ECR",		148,	regp(MPC5XX_ECR)		},
	{ "DER",		149,	regp(MPC5XX_DER)		},
	{ "COUNTA",		150,	regp(MPC5XX_COUNTA)		},
	{ "COUNTB",		151,	regp(MPC5XX_COUNTB)		},
	{ "CMPE",		152,	regp(MPC5XX_CMPE)		},
	{ "CMPF",		153,	regp(MPC5XX_CMPF)		},
	{ "CMPG",		154,	regp(MPC5XX_CMPG)		},
	{ "CMPH",		155,	regp(MPC5XX_CMPH)		},
	{ "LCTRL1",		156,	regp(MPC5XX_LCTRL1)		},
	{ "LCTRL2",		157,	regp(MPC5XX_LCTRL2)		},
	{ "ICTRL",		158,	regp(MPC5XX_ICTRL)		},
	{ "BAR",		159,	regp(MPC5XX_BAR)		},
	{ "MI_GRA",		528,	regp(MPC5XX_MI_GRA)		},
	{ "L2U_GRA",	536,	regp(MPC5XX_L2U_GRA)	},
	{ "DPDR",		630,	regp(MPC5XX_DPDR)		},
	{ "IMMR",		638,	regp(MPC5XX_IMMR)		},
	{ "BBCMCR",		560,	regp(MPC5XX_BBCMCR)		},
	{ "L2U_MCR",	568,	regp(MPC5XX_L2U_MCR)	},
	{ "MI_RBA0",	784,	regp(MPC5XX_MI_RBA0)	},
	{ "MI_RBA1",	785,	regp(MPC5XX_MI_RBA1)	},
	{ "MI_RBA2",	786,	regp(MPC5XX_MI_RBA2)	},
	{ "MI_RBA3",	787,	regp(MPC5XX_MI_RBA3)	},
	{ "MI_RA0",		816,	regp(MPC5XX_MI_RA0)		},
	{ "MI_RA1",		817,	regp(MPC5XX_MI_RA1)		},
	{ "MI_RA2",		818,	regp(MPC5XX_MI_RA2)		},
	{ "MI_RA3",		819,	regp(MPC5XX_MI_RA3)		},
	{ "L2U_RBA0",	792,	regp(MPC5XX_L2U_RBA0)	},
	{ "L2U_RBA1",	793,	regp(MPC5XX_L2U_RBA1)	},
	{ "L2U_RBA2",	794,	regp(MPC5XX_L2U_RBA2)	},
	{ "L2U_RBA3",	795,	regp(MPC5XX_L2U_RBA3)	},
	{ "L2U_RA0",	824,	regp(MPC5XX_L2U_RA0)	},
	{ "L2U_RA1",	825,	regp(MPC5XX_L2U_RA1)	},
	{ "L2U_RA2",	826,	regp(MPC5XX_L2U_RA2)	},
	{ "L2U_RA2",	827,	regp(MPC5XX_L2U_RA3)	},
	{ "FPECR",		1022,	regp(MPC5XX_FPECR)		},

	{ "ip",			0,		regp(MPC5XX_SRR0)		},
	{ "pc",			0,		regp(MPC5XX_SRR0)		},
} ;

#define	REGTAB_SIZE (int)(sizeof(registers) / sizeof(ppc_reg))

/*********************************************************************/

/*
 * Constant strings
 */
const char INVMOD[] = "Error: Invalid Module: %s\n";
const char FMT8REG[] = "%08X %08X %08X %08X %08X %08X %08X %08X\n";
const char EXCEPT[]  = "Exception %04X: %s\n";

/*********************************************************************/

/*
 * When cpu_handler() returns,  a value of 0 means restore the context
 * and perform an RFI to continue executing code.  A non-zero return
 * value drops back to the command prompt. A value of EXEC_RFI means resume execution of code.  A value of
 * EXEC_DBUG means return to the dBUG prompt, no more execution of
 * user code.
 */
#define EXEC_RFI 0
#define EXEC_DBUG 1

/*********************************************************************/

int
cpu_trace_count;

static ADDRESS
trace_thru;

ADDRESS
cpu_step_over;

/*********************************************************************/
void
cpu_init (void)
{
	/* init user regs */
	CPU_REG_SRR0  = (ADDRESS)__USER_SPACE;
	CPU_REG_CR  = 0;
	CPU_REG_MSR = ( 0
		| MPC_MSR_EE
		| MPC_MSR_ME
		| MPC_MSR_RI
		) ; /*these bits are defined in mpc5xx.h*/

	CPU_REG_DEC = (uint32)~0;
	trace_thru = 0;
	cpu_step_over = 0;
	cpu_trace_count = 0;
}

/*********************************************************************/
static int
find_register (char *reg)
{
	/*
	 * This routine searches the register table for the
	 * register named `reg'.  If it is found, then the
	 * index needed to access that register in the table
	 * is returned, otherwise -1 is returned.
	 */
	int index, spr, success;

	for (index = 0; index < REGTAB_SIZE; index++)
	{
		if (strcasecmp(registers[index].reg_name,reg) == 0)
			return index;
	}

	/*
	 * See if an sprXXXX was requested
	 */
	if (strncasecmp("spr",reg,3) == 0)
	{
		spr = get_value(&reg[3], &success, 10);
		if (success)
		{
			for (index = 0; index < REGTAB_SIZE; index++)
			{
				if (registers[index].reg_spr == spr)
					return index;
			}
		}
	}
	return -1;
}

/*********************************************************************/
static int
find_spr (int spr)
{
	/*
	 * This routine searches the register table for the register 'spr'.
	 */
	int index;

	for (index = 0; index < REGTAB_SIZE; ++index)
	{
		if (registers[index].reg_spr == spr)
			return index;
	}
	return -1;
}

/*********************************************************************/
void
cpu_reg_modify (char *reg, uint32 value)
{
	int index;
	if ((index = find_register(reg)) != -1)
	{
		*(uint32 *)registers[index].reg_offset = value;
	}
	else
	{
		printf(INVREG,reg);
	}
}

/*********************************************************************/
static void
dump_gprs (void)
{
	printf("r00-07: ");
	printf(FMT8REG,
		CPU_REG_R0,
		CPU_REG_R1,
		CPU_REG_R2,
		CPU_REG_R3,
		CPU_REG_R4,
		CPU_REG_R5,
		CPU_REG_R6,
		CPU_REG_R7 );
	printf("r08-15: ");
	printf(FMT8REG,
		CPU_REG_R8,
		CPU_REG_R9,
		CPU_REG_R10,
		CPU_REG_R11,
		CPU_REG_R12,
		CPU_REG_R13,
		CPU_REG_R14,
		CPU_REG_R15 );
	printf("r16-23: ");
	printf(FMT8REG,
		CPU_REG_R16,
		CPU_REG_R17,
		CPU_REG_R18,
		CPU_REG_R19,
		CPU_REG_R20,
		CPU_REG_R21,
		CPU_REG_R22,
		CPU_REG_R23 );
	printf("r24-31: ");
	printf(FMT8REG,
		CPU_REG_R24,
		CPU_REG_R25,
		CPU_REG_R26,
		CPU_REG_R27,
		CPU_REG_R28,
		CPU_REG_R29,
		CPU_REG_R30,
		CPU_REG_R31 );
}

/*********************************************************************/
static void
dump_sprs (void)
{
	int index;
	int displayed = 0;

	for (index = 0; index < REGTAB_SIZE; ++index)
	{
		if (registers[index].reg_spr != 0)
		{
			printf(" %-9s (spr%4d): %08X\n",
				registers[index].reg_name,
				registers[index].reg_spr,
				*registers[index].reg_offset);

			pause(&displayed);
		}
	}
}

/*********************************************************************/
static void
dump_fprs (void)
{
	printf("fpr00-07: ");
	printf(FMT8REG,
		CPU_REG_FPR0,
		CPU_REG_FPR1,
		CPU_REG_FPR2,
		CPU_REG_FPR3,
		CPU_REG_FPR4,
		CPU_REG_FPR5,
		CPU_REG_FPR6,
		CPU_REG_FPR7 );
	printf("fpr08-15: ");
	printf(FMT8REG,
		CPU_REG_FPR8,
		CPU_REG_FPR9,
		CPU_REG_FPR10,
		CPU_REG_FPR11,
		CPU_REG_FPR12,
		CPU_REG_FPR13,
		CPU_REG_FPR14,
		CPU_REG_FPR15 );
	printf("fpr16-23: ");
	printf(FMT8REG,
		CPU_REG_FPR16,
		CPU_REG_FPR17,
		CPU_REG_FPR18,
		CPU_REG_FPR19,
		CPU_REG_FPR20,
		CPU_REG_FPR21,
		CPU_REG_FPR22,
		CPU_REG_FPR23 );
	printf("fpr24-31: ");
	printf(FMT8REG,
		CPU_REG_FPR24,
		CPU_REG_FPR25,
		CPU_REG_FPR26,
		CPU_REG_FPR27,
		CPU_REG_FPR28,
		CPU_REG_FPR29,
		CPU_REG_FPR30,
		CPU_REG_FPR31 );
}

/*********************************************************************/
static void
dump_msr (void)
{
	int first = TRUE;
	uint32 mask = MPC_MSR_POW;	/* MSR[13,POW] */

	printf("[");
	while (mask)
	{
		if (CPU_REG_MSR & mask)
		{
			if (!first)
				printf(",");
			else
				first = FALSE;
//see table 3-12 in 555/556 manual
			switch (CPU_REG_MSR & mask)
			{
				case MPC_MSR_POW:
					printf("POW"); break;
				case MPC_MSR_ILE:
					printf("ILE"); break;
				case MPC_MSR_EE:
					printf("EE"); break;
				case MPC_MSR_PR:
					printf("PR"); break;
				case MPC_MSR_FP:
					printf("FP"); break;
				case MPC_MSR_ME:
					printf("ME"); break;
				case MPC_MSR_FE0:
					printf("FE0"); break;
				case MPC_MSR_SE:
					printf("SE"); break;
				case MPC_MSR_BE:
					printf("BE"); break;
				case MPC_MSR_FE1:
					printf("FE1"); break;
				case MPC_MSR_IP:
					printf("IP"); break;
				case MPC_MSR_IR:
					printf("IR"); break;
				case MPC_MSR_DR:
					printf("DR"); break;
				case MPC_MSR_RI:
					printf("RI"); break;
				case MPC_MSR_LE:
					printf("LE"); break;
				default:
					break;
			}
		}
		mask >>= 1;
	}
	printf("]");
}

/*********************************************************************/
void
cpu_reg_display (char *reg)
{
	int index;

	if (reg == NULL)
	{
		printf("    pc: %08X     msr: %08X ",
			CPU_REG_SRR0,
			CPU_REG_MSR
			);
		dump_msr();
		printf("\n");

		printf("    cr: %08X     xer: %08X      lr: %08X     ctr: %08X\n",
			CPU_REG_CR,
			CPU_REG_XER,
			CPU_REG_LR,
			CPU_REG_CTR
			);
		dump_gprs();
	}
	else
	{
		/* display specific reg */
		if ((index = find_register(reg)) != -1)
		{
			printf("%-9s: %08X\n",
				registers[index].reg_name,
				*(uint32 *)registers[index].reg_offset );
				return;
		}
		else
		{
			if (strcasecmp("gprs",reg) == 0)
			{
				dump_gprs();
				return;
			}
			if (strcasecmp("sprs",reg) == 0)
			{
				dump_sprs();
				return;
			}
			if (strcasecmp("fprs",reg) == 0)
			{
				dump_fprs();
				return;
			}
		}
		printf(INVREG,reg);
	}
}

/*********************************************************************/
void
cpu_pc_modify (ADDRESS address)
{
	CPU_REG_SRR0 = address;
}

/*********************************************************************/
ADDRESS
cpu_pc_get (void)
{
	return CPU_REG_SRR0;
}

/*********************************************************************/
int
cpu_parse_size (char *arg)
{
	int i, size = SIZE_32;

	for (i = 0; arg[i] != '\0'; i++)
	{
		if (arg[i] == '.')
		{
			switch (arg[i+1])
			{
				case 'b':
				case 'B':
					size = SIZE_8;
					break;
				case 'h':
				case 'H':
					size = SIZE_16;
					break;
				case 'w':
				case 'W':
					size = SIZE_32;
					break;
				default:
					size = SIZE_32;
					break;
			}
			break;
		}
	}
	return size;
}

⌨️ 快捷键说明

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