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

📄 mpc8xx_hi.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * File:		mpc8xx_hi.c
 * Purpose:		High level MPC8XX specific support routines.
 *
 * Notes:
 *
 */

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

#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_MPC821))
const char CPU_STR[] = "MPC821";

#elif	(defined(CPU_MPC823))
const char CPU_STR[] = "MPC823";

#elif	(defined(CPU_MPC850))
const char CPU_STR[] = "MPC850";

#elif	(defined(CPU_MPC860))
const char CPU_STR[] = "MPC860";

#elif	(defined(CPU_MPC860SAR))
const char CPU_STR[] = "MPC860SAR";

#else
#error "Error: Unsupported MPC8XX CPU!"
#endif

const int  CPU_VER_MAJOR = 1;
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(MPC8XX_R0)		},
	{ "r1", 		0,		regp(MPC8XX_R1)		},
	{ "r2", 		0,		regp(MPC8XX_R2)		},
	{ "r3", 		0,		regp(MPC8XX_R3)		},
	{ "r4", 		0,		regp(MPC8XX_R4)		},
	{ "r5", 		0,		regp(MPC8XX_R5)		},
	{ "r6", 		0,		regp(MPC8XX_R6)		},
	{ "r7", 		0,		regp(MPC8XX_R7)		},
	{ "r8", 		0,		regp(MPC8XX_R8)		},
	{ "r9", 		0,		regp(MPC8XX_R9)		},
	{ "r10", 		0,		regp(MPC8XX_R10)	},
	{ "r11", 		0,		regp(MPC8XX_R11)	},
	{ "r12", 		0,		regp(MPC8XX_R12)	},
	{ "r13", 		0,		regp(MPC8XX_R13)	},
	{ "r14", 		0,		regp(MPC8XX_R14)	},
	{ "r15", 		0,		regp(MPC8XX_R15)	},
	{ "r16", 		0,		regp(MPC8XX_R16)	},
	{ "r17", 		0,		regp(MPC8XX_R17)	},
	{ "r18", 		0,		regp(MPC8XX_R18)	},
	{ "r19", 		0,		regp(MPC8XX_R19)	},
	{ "r20", 		0,		regp(MPC8XX_R20)	},
	{ "r21", 		0,		regp(MPC8XX_R21)	},
	{ "r22", 		0,		regp(MPC8XX_R22)	},
	{ "r23", 		0,		regp(MPC8XX_R23)	},
	{ "r24", 		0,		regp(MPC8XX_R24)	},
	{ "r25", 		0,		regp(MPC8XX_R25)	},
	{ "r26", 		0,		regp(MPC8XX_R26)	},
	{ "r27", 		0,		regp(MPC8XX_R27)	},
	{ "r28", 		0,		regp(MPC8XX_R28)	},
	{ "r29", 		0,		regp(MPC8XX_R29)	},
	{ "r30", 		0,		regp(MPC8XX_R30)	},
	{ "r31", 		0,		regp(MPC8XX_R31)	},

	{ "msr", 		0,		regp(MPC8XX_MSR)	},
	{ "cr", 		0,		regp(MPC8XX_CR)		},

	{ "XER",		1,		regp(MPC8XX_XER)		},
	{ "LR",			8,		regp(MPC8XX_LR)			},
	{ "CTR",		9,		regp(MPC8XX_CTR)		},
	{ "DSISR",		18,		regp(MPC8XX_DSISR)		},
	{ "DAR",		19,		regp(MPC8XX_DAR)		},
	{ "DEC",		22,		regp(MPC8XX_DEC)		},
	{ "SRR0",		26,		regp(MPC8XX_SRR0)		},
	{ "SRR1",		27,		regp(MPC8XX_SRR1)		},
	{ "PVR",		287,	regp(MPC8XX_PVR)		},
	{ "TBL",		268,	regp(MPC8XX_TBL)		},
	{ "TBU",		269,	regp(MPC8XX_TBU)		},
	{ "SPRG0",		272,	regp(MPC8XX_SPRG0)		},
	{ "SPRG1",		273,	regp(MPC8XX_SPRG1)		},
	{ "SPRG2",		274,	regp(MPC8XX_SPRG2)		},
	{ "SPRG3",		275,	regp(MPC8XX_SPRG3)		},
	{ "EIE",		80,		regp(MPC8XX_EIE)		},
	{ "EID",		81,		regp(MPC8XX_EID)		},
	{ "NRI",		82,		regp(MPC8XX_NRI)		},
	{ "CMPA",		144,	regp(MPC8XX_CMPA)		},
	{ "CMPB",		145,	regp(MPC8XX_CMPB)		},
	{ "CMPC",		146,	regp(MPC8XX_CMPC)		},
	{ "CMPD",		147,	regp(MPC8XX_CMPD)		},
	{ "ICR",		148,	regp(MPC8XX_ICR)		},
	{ "DER",		149,	regp(MPC8XX_DER)		},
	{ "COUNTA",		150,	regp(MPC8XX_COUNTA)		},
	{ "COUNTB",		151,	regp(MPC8XX_COUNTB)		},
	{ "CMPE",		152,	regp(MPC8XX_CMPE)		},
	{ "CMPF",		153,	regp(MPC8XX_CMPF)		},
	{ "CMPG",		154,	regp(MPC8XX_CMPG)		},
	{ "CMPH",		155,	regp(MPC8XX_CMPH)		},
	{ "LCTRL1",		156,	regp(MPC8XX_LCTRL1)		},
	{ "LCTRL2",		157,	regp(MPC8XX_LCTRL2)		},
	{ "ICTRL",		158,	regp(MPC8XX_ICTRL)		},
	{ "BAR",		159,	regp(MPC8XX_BAR)		},
	{ "DPDR",		630,	regp(MPC8XX_DPDR)		},
	{ "DPIR",		631,	regp(MPC8XX_DPIR)		},
	{ "IMMR",		638,	regp(MPC8XX_IMMR)		},
	{ "IC_CST",		560,	regp(MPC8XX_IC_CST)		},
	{ "IC_ADR",		561,	regp(MPC8XX_IC_ADR)		},
	{ "IC_DAT",		562,	regp(MPC8XX_IC_DAT)		},
	{ "DC_CST",		568,	regp(MPC8XX_DC_CST)		},
	{ "DC_ADR",		569,	regp(MPC8XX_DC_ADR)		},
	{ "DC_DAT",		570,	regp(MPC8XX_DC_DAT)		},
	{ "MI_CTR",		784,	regp(MPC8XX_MI_CTR)		},
	{ "MI_AP",		786,	regp(MPC8XX_MI_AP)		},
	{ "MI_EPN",		787,	regp(MPC8XX_MI_EPN)		},
	{ "MI_TWC",		789,	regp(MPC8XX_MI_TWC)		},
	{ "MI_RPN",		790,	regp(MPC8XX_MI_RPN)		},
	{ "MI_DBCAM",	816,	regp(MPC8XX_MI_DBCAM)	},
	{ "MI_DBRAM0",	817,	regp(MPC8XX_MI_DBRAM0)	},
	{ "MI_DBRAM1",	818,	regp(MPC8XX_MI_DBRAM1)	},
	{ "MD_CTR",		792,	regp(MPC8XX_MD_CTR)		},
	{ "M_CASID",	793,	regp(MPC8XX_M_CASID)	},
	{ "MD_AP",		794,	regp(MPC8XX_MD_AP)		},
	{ "MD_EPN",		795,	regp(MPC8XX_MD_EPN)		},
	{ "M_TWB",		796,	regp(MPC8XX_M_TWB)		},
	{ "MD_TWC",		797,	regp(MPC8XX_MD_TWC)		},
	{ "MD_RPN",		798,	regp(MPC8XX_MD_RPN)		},
	{ "M_TW",		799,	regp(MPC8XX_M_TW)		},
	{ "MD_DBCAM",	824,	regp(MPC8XX_MD_DBCAM)	},
	{ "MD_DBRAM0",	825,	regp(MPC8XX_MD_DBRAM0)	},
	{ "MD_DBRAM1",	826,	regp(MPC8XX_MD_DBRAM1)	},

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

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

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

/*
 * Constant strings
 */
static const char INVREG[] = "Error: Invalid Register: %s\n";
static const char INVMOD[] = "Error: Invalid Module: %s\n";
static const char FMT8REG[] = "%08X %08X %08X %08X %08X %08X %08X %08X\n";
static 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.
 */
#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
		| MPC8XX_MSR_EE
		| MPC8XX_MSR_ME
		| MPC8XX_MSR_RI
		) ;

	CPU_REG_DEC = ~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_msr (void)
{
	int first = TRUE;
	uint32 mask = MPC8XX_MSR_POW;	/* MSR[13,POW] */

	printf("[");
	while (mask)
	{
		if (CPU_REG_MSR & mask)
		{
			if (!first)
				printf(",");
			else
				first = FALSE;

			switch (CPU_REG_MSR & mask)
			{
				case MPC8XX_MSR_POW:
					printf("POW"); break;
				case MPC8XX_MSR_ILE:
					printf("ILE"); break;
				case MPC8XX_MSR_EE:
					printf("EE"); break;
				case MPC8XX_MSR_PR:
					printf("PR"); break;
				case MPC8XX_MSR_FP:
					printf("FP"); break;
				case MPC8XX_MSR_ME:
					printf("ME"); break;
				case MPC8XX_MSR_FE0:
					printf("FE0"); break;
				case MPC8XX_MSR_SE:
					printf("SE"); break;
				case MPC8XX_MSR_BE:
					printf("BE"); break;
				case MPC8XX_MSR_FE1:
					printf("FE1"); break;
				case MPC8XX_MSR_IP:
					printf("IP"); break;
				case MPC8XX_MSR_IR:
					printf("IR"); break;
				case MPC8XX_MSR_DR:
					printf("DR"); break;
				case MPC8XX_MSR_RI:
					printf("RI"); break;
				case MPC8XX_MSR_LE:
					printf("LE"); break;
				default:
					break;
			}
		}
		mask >>= 1;
	}	
	printf("]");
}

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

	if (reg == NULL)
	{
		printf("    ip: %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;
			}
		}
		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;
}

/*********************************************************************/
int
cpu_valid_insn_addr (ADDRESS address)
{
	/* MPC needs instruction aligned on 32-bit boundaries */
	return !(address & 0x00000003);
}

/*********************************************************************/
void
cpu_switch_context (int trace)
{
	/*
	 * if 'trace' is true, then do not put in breakpoints, we are
	 * tracing through the code.  otherwise, install breakpoints,
	 * we are executing a 'go' command.
	 */

	if (trace)
	{
		/* turn tracing on */
		CPU_REG_MSR |= MPC8XX_MSR_SE;
	}
	else
	{
		if (breakpoint_install((ADDRESS)context.srr0))
		{
			/* about to execute at a breakpoint */
			/* trace thru this rather than breaking */
			trace_thru = (ADDRESS)context.srr0;
			/* turn tracing on */
			CPU_REG_MSR |= MPC8XX_MSR_SE;
		}
	}
	asm_switch_context(&context);
}

/*********************************************************************/
void
cpu_write_data (ADDRESS address, int size, uint32 data)
{
	switch (size)
	{
		case SIZE_8:
			*((uint8 *)address) = data;
			break;
		case SIZE_16:
			*((uint16 *)address) = data;
			break;
		case SIZE_32:
			*((uint32 *)address) = data;
			break;
		default:
			break;
	}
}

/*********************************************************************/
uint32
cpu_read_data (ADDRESS address, int size)
{
	switch (size)
	{
		case SIZE_8:
			return *((uint8 *)address);
			break;
		case SIZE_16:
			return *((uint16 *)address);
			break;
		case SIZE_32:
			return *((uint32 *)address);
			break;
		default:
			return 0;
			break;
	}
}

/*********************************************************************/
ADDRESS
cpu_align_address (ADDRESS address, int size)
{
	switch (size)
	{
		case SIZE_16:
			return (ADDRESS)(address & ~0x00000001);
			break;
		case SIZE_32:
			return (ADDRESS)(address & ~0x00000003);
			break;
		case SIZE_8:
		default:
			return (address);
			break;
	}
}

/*********************************************************************/
ADDRESS
cpu_stack_frame (ADDRESS fp, ADDRESS *retpc)
{
	/*
	 * PowerPC SVR4/EABI
	 */
	ADDRESS backchain;
 
	if (retpc == NULL)
	{
		return context.r1;
	}
	else
	{
		backchain = *(ADDRESS *)fp;
		*retpc = *(ADDRESS *)(backchain + 4);
		return backchain;
	}
}

/*********************************************************************/
static void
cpic_handler (void)
{
	uint32 cipr;
	MPC8XX_IMM *imm = mpc8xx_get_immp();

	/*
	 * The CIPR does not present just one interrupt source.  It will
	 * present all sources that require servicing.  This is different
	 * than the SIU int controller.
	 */
	cipr = imm->cpic.CIPR;	/* mask with CIMR ? */

	printf("CPIC IRQ(s): ");

	if (cipr & MPC8XX_CPIC_CIPR_PC15)
	{
		printf("PC15 ");
	}
	if (cipr & MPC8XX_CPIC_CIPR_SCC1)
	{
		printf("SCC1 ");
	}
	if (cipr & MPC8XX_CPIC_CIPR_SCC2)
	{
		printf("SCC2 ");
	}
	if (cipr & MPC8XX_CPIC_CIPR_SCC3)
	{
		printf("SCC3 ");
	}
	if (cipr & MPC8XX_CPIC_CIPR_SCC4)
	{
		printf("SCC4 ");
	}
	if (cipr & MPC8XX_CPIC_CIPR_PC14)
	{
		printf("PC14 ");
	}
	if (cipr & MPC8XX_CPIC_CIPR_TIMER1)
	{
		printf("TIMER1 ");
	}
	if (cipr & MPC8XX_CPIC_CIPR_PC13)
	{
		printf("PC13 ");
	}

⌨️ 快捷键说明

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