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

📄 mpc5xx_hi.c

📁 Coldfire MCF5282 DBug bootloader
💻 C
📖 第 1 页 / 共 4 页
字号:

/*********************************************************************/
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 |= MPC_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 |= MPC_MSR_SE;
		}
	}
	asm_switch_context(&context);
}

/*********************************************************************/
void
cpu_write_data (ADDRESS address, int size, uint32 data)
{
	switch (size)
	{
		case SIZE_8:
			*((uint8 *)address) =  (uint8)data;
			break;
		case SIZE_16:
			*((uint16 *)address) = (uint16)data;
			break;
		case SIZE_32:
			*((uint32 *)address) = (uint32)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
usiu_handler (void)
{
	uint32 sipend;

	sipend = (uint32)(USIU.SIPEND.R & USIU.SIMASK.R);

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

	if (sipend & 0x80000000)
	{
		printf("IRQ0 ");
	}
	if (sipend & 0x40000000)
	{
		printf("LVL0 ");
	}
	if (sipend & 0x20000000)
	{
		printf("IRQ1 ");
	}
	if (sipend & 0x10000000)
	{
		printf("LVL1 ");
	}
	if (sipend & 0x08000000)
	{
		printf("IRQ2 ");
	}
	if (sipend & 0x04000000)
	{
		printf("LVL2 ");
	}
	if (sipend & 0x02000000)
	{
		printf("IRQ3 ");
	}
	if (sipend & 0x01000000)
	{
		printf("LVL3 ");
	}
	if (sipend & 0x00800000)
	{
		printf("IRQ4 ");
	}
	if (sipend & 0x00400000)
	{
		printf("LVL4 ");
	}
	if (sipend & 0x00200000)
	{
		printf("IRQ5 ");
	}
	if (sipend & 0x00100000)
	{
		printf("LVL5 ");
	}
	if (sipend & 0x00080000)
	{
		printf("IRQ6 ");
	}
	if (sipend & 0x00040000)
	{
		printf("LVL6 ");
	}
	if (sipend & 0x00030000)
	{
		printf("IRQ7 ");
	}
	if (sipend & 0x00010000)
	{
		printf("LVL7 ");
	}

	printf("\n");
}

/*********************************************************************/
int
cpu_handler (int exception)
{
	/*
	 * This is the exception handler for all defined exceptions.  Most
	 * exceptions do nothing, but some of the more important ones are
	 * handled to some extent.
	 */
	int user_brkpnt, user_triggered;
	int cpu_handler_flag;

	/*
	 * Most exceptions result in dumping out to the dBUG prompt.
	 */
	cpu_handler_flag = EXEC_DBUG;

	/*
	 * The value passed in for 'exception' is actually the LR.  So,
	 * pick-off the actual exception number now.
	 */
	exception = (exception & 0x0000FF00);

	/*
	 * Handle breakpoints properly.
	 */
	user_brkpnt = breakpoint_deinstall((ADDRESS)context.srr0, &user_triggered);

	switch (exception)
	{
		case 0x0000:
			printf(EXCEPT, exception, "Reserved");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0100:
			printf(EXCEPT, exception, "Reset");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0200:
			printf(EXCEPT, exception, "Machine Check");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0300:
			printf(EXCEPT, exception, "Data Storage");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0400:
			printf(EXCEPT, exception, "Instruction Storage");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0500:
			printf(EXCEPT, exception, "External Interrupt");
			usiu_handler();
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0600:
			printf(EXCEPT, exception, "Alignment");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0700:
			printf(EXCEPT, exception, "Program");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0800:
			printf(EXCEPT, exception, "Floating-point Unavailable");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0900:
			printf(EXCEPT, exception, "Decrementer");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0A00:
		case 0x0B00:
			printf(EXCEPT, exception, "Reserved");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0C00:
			printf(EXCEPT, exception, "System Call");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0D00:
			/* 'step' or 'go' while sitting on a user breakpoint */
			if ((int)trace_thru)
			{
				/* got here from 'step' command */
				if ((ADDRESS)cpu_step_over == (ADDRESS)CPU_REG_SRR0)
				{
					/* clean up at end of handler */
					trace_thru = NULL;
					cpu_reg_display(NULL);
					cpu_disasm(CPU_REG_SRR0, TRUE);
				}
				/* got here from 'go' command */
				else
				{
					/* reinstall all breakpoints except for one a current address */
					breakpoint_install((ADDRESS)context.srr0);
					/* place breakpoint at current address */
					cpu_write_data(trace_thru,32,(int)ILLEGAL);
					/* turn off tracing */
					CPU_REG_MSR &= (~MPC_MSR_SE);
					/* nullify trace_thru and continue execution */
					trace_thru = NULL;
					cpu_handler_flag = EXEC_RFI;
				}
				break;
			}
			/* each time through, decrement cpu_trace_count */
			if (--cpu_trace_count > 0)
			{
				/* turn tracing on */
				CPU_REG_MSR |= MPC_MSR_SE;
				cpu_handler_flag = EXEC_RFI;
			}
			else
			{
				/* turn off trace bit in MSR */
				CPU_REG_MSR &= (~MPC_MSR_SE);
				cpu_handler_flag = EXEC_DBUG;
				cpu_trace_count = 0;
			}
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0E00:
			printf(EXCEPT, exception, "Floating-Point Assist");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0F00:
			printf(EXCEPT, exception, "Reserved");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1000:
			if (!user_brkpnt)
			{
				printf(EXCEPT, exception, "Software Emulation");
				cpu_reg_display(NULL);
				cpu_disasm(CPU_REG_SRR0, TRUE);
			}
			else
			{
				if ((ADDRESS)cpu_step_over == (ADDRESS)CPU_REG_SRR0)
				{
					/* clean up at end of handler */
					cpu_reg_display(NULL);
					cpu_disasm(CPU_REG_SRR0, TRUE);
					break;
				}
				if (user_triggered)
				{
					printf("Breakpoint encountered at %#08X\n",
						CPU_REG_SRR0);
					cpu_reg_display(NULL);
					cpu_disasm(CPU_REG_SRR0, TRUE);
				}
				/* else reinstall breakpoints and continue */
				/* execution of the task...we will return  */
				/* task from here, not write out regs and RFI */
				else
				{
					if (breakpoint_install((ADDRESS)context.srr0))
					{
						/* about to execute at breakpoint */
						/* trace thru rather than breaking */
						trace_thru = CPU_REG_SRR0;
						/* turn tracing on */
						CPU_REG_MSR |= MPC_MSR_SE;
						cpu_handler_flag = EXEC_RFI;
					}
				}
			}
			break;
		case 0x1100:
			printf(EXCEPT, exception, "Instruction TLB Miss");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1200:
			printf(EXCEPT, exception, "Data TLB Miss");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1300:
			printf(EXCEPT, exception, "Instruction TLB Error");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1400:
			printf(EXCEPT, exception, "Data TLB Error");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1500:
		case 0x1600:
		case 0x1700:
		case 0x1800:
		case 0x1900:
		case 0x1A00:
		case 0x1B00:
			printf(EXCEPT, exception, "Reserved");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1C00:
			printf(EXCEPT, exception, "Data Breakpoint");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1D00:
			printf(EXCEPT, exception, "Instruction Breakpoint");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x00000008);/*ignore next occurance of this breakpoint that got me here*/
			break;
		case 0x1E00:
			printf(EXCEPT, exception, "Peripheral Breakpoint");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x1F00:
			printf(EXCEPT, exception, "Development Port");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
		case 0x0FF00:	/* cheat for exit to dbug prompt */
			cpu_handler_flag = EXEC_DBUG;
			printf("\n");
			break;
		default:
			printf(EXCEPT, exception, "Unknown");
			cpu_reg_display(NULL);
			cpu_disasm(CPU_REG_SRR0, TRUE);
			break;
	}

	if ((cpu_handler_flag == EXEC_DBUG) && cpu_step_over)
	{
		cpu_step_over = 0;
	}

	return cpu_handler_flag;
}

/*********************************************************************/
void
cpu_cache_flush (void)
{
	/*
	 * No cache in 5xx
	 */
}

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

#define REGREAD  (1)
#define REGWRITE (0)

static const char FORMAT8[]  = " %8s: %02X\n";
static const char FORMAT16[] = " %8s: %04X\n";
static const char FORMAT32[] = " %8s: %08X\n";

#define IRMD(MOD,REG,SIZE)	\
	if ((strcasecmp(#REG,reg) == 0) || display_all)			\
	{														\
		if (regread)										\
		{													\
			printf(FORMAT ## SIZE, #REG,					\
				MOD . REG .R );								\
			pause(&displayed);								\
		}													\
		else												\
			MOD . REG .R= (uint ## SIZE)value;				\
 															\
		if (!display_all)									\
			return;											\
	}

static int display_all;
static int displayed;

/*********************************************************************/
/*
 * Common to all MPC5xx parts
 */
static void
irmd_usiu (char *reg, int regread, uint32 value)
{
	IRMD(USIU, SIUMCR, 	32)
	IRMD(USIU, SYPCR,  	32)
	IRMD(USIU, SWSR,   	16)
	IRMD(USIU, SIPEND, 	32)
	IRMD(USIU, SIMASK, 	32)
	IRMD(USIU, SIEL,   	32)
	IRMD(USIU, SIVEC,  	32)
	IRMD(USIU, TESR,   	32)
	IRMD(USIU, SGPIODT1,32)
	IRMD(USIU, SGPIODT2,32)
	IRMD(USIU, SGPIOCR,	32)
	IRMD(USIU, EMCR,	32)
	IRMD(USIU, PDMCR,  	32)
	
	/* 
	 * Only the MPC555 doesn't have these
	 */
	#ifndef CPU_MPC555
		IRMD(USIU, PDMCR2, 	32)
		IRMD(USIU, SIPEND2,	32)
		IRMD(USIU, SIPEND3,	32)
		IRMD(USIU, SIMASK2,	32)
		IRMD(USIU, SIMASK3,	32)
		IRMD(USIU, SISR2,	32)
		IRMD(USIU, SISR3,	32)
	#endif

	/*
	 * Memory Controller Registers
	 */
	IRMD(USIU, BR0,		32)
	IRMD(USIU, OR0,		32)
	IRMD(USIU, BR1,		32)
	IRMD(USIU, OR1,		32)
	IRMD(USIU, BR2,		32)
	IRMD(USIU, OR2,		32)
	IRMD(USIU, BR3,		32)
	IRMD(USIU, OR3,		32)
	IRMD(USIU, DMBR,	32)
	IRMD(USIU, DMOR,	32)
	IRMD(USIU, MSTAT,	16)

	/*
	 * System integration Timers
	 */
	IRMD(USIU, TBSCR,	16)
	IRMD(USIU, TBREF0,	32)
	IRMD(USIU, TBREF1,	32)
	IRMD(USIU, RTCSC,	16)
	IRMD(USIU, RTC,		32)
	IRMD(USIU, RTSEC,	32)
	IRMD(USIU, RTCAL,	32)
	IRMD(USIU, PISCR,	16)
	IRMD(USIU, PITC,	32)
	IRMD(USIU, PITR,	32)

	/*
	 * Clocks and Reset
	 */
	IRMD(USIU, SCCR,	32) 
	IRMD(USIU, PLPRCR,	32)
	IRMD(USIU, RSR,		16)
	IRMD(USIU, COLIR,	16)
	IRMD(USIU, VSRMCR,	16)

	/*
	 * System Integration Timer Keys
	 */
/*	IRMD(USIU, TBSCRK,	32)
	IRMD(USIU, TBREF0K,	32)
	IRMD(USIU, TBREF1K,	32)
	IRMD(USIU, TBK,		32)
	IRMD(USIU, RTCSCK,	32)
	IRMD(USIU, RTCK,	32)
	IRMD(USIU, RTSECK,	32)

⌨️ 快捷键说明

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