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

📄 mcf5xxx_hi.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
字号:
/*
 * File:		src/cpu/coldfire/mcf5xxx/mcf5xxx_hi.c
 * Purpose:		Higher level processing for MCF52xx processors.
 *
 * 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;

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

/*
 * This structure contains info about the registers.  The name
 * is given so that users can type it.
 */
typedef struct
{
	const char *	name;
	const void *	ptr;
	const int		size;
} reg_entry;

/*
 * The method for specifying the pointer to the register in the
 * 'context' data structure is to ensure that no matter which 
 * compiler is used, the offsets are the same.  (ANSI C doesn't
 * specify how the context of a structure/array are stored.)
 */
static const reg_entry registers[] =
{
	{ "D0", &context.d0, 32 },
	{ "D1", &context.d1, 32 },
	{ "D2", &context.d2, 32 },
	{ "D3", &context.d3, 32 },
	{ "D4", &context.d4, 32 },
	{ "D5", &context.d5, 32 },
	{ "D6", &context.d6, 32 },
	{ "D7", &context.d7, 32 },

	{ "A0", &context.a0, 32 },
	{ "A1", &context.a1, 32 },
	{ "A2", &context.a2, 32 },
	{ "A3", &context.a3, 32 },
	{ "A4", &context.a4, 32 },
	{ "A5", &context.a5, 32 },
	{ "A6", &context.a6, 32 },
	{ "A7", &context.a7, 32 },

	{ "PC", &context.pc, 32 },
	{ "SR", &context.sr, 16 },

	{ "SP", &context.a7, 32 },
} ;

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

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

/*
 * When cpu_handler() returns, a value of 0 means restore the context
 * and perform an RTE to continue executing code.  A non-zero return
 * value drops back to the command prompt.
 */
#define EXEC_RTE	0
#define EXEC_DBUG	1

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

static const char INVREG[] = "Error: Invalid Register: %s\n";

ADDRESS
cpu_step_over;

int
cpu_trace_count;

static ADDRESS
trace_thru;

#if (defined(CPU_MCF5272))
extern void ext_irq6_handler(void);
#endif

/********************************************************************/
static int
find_register (char *reg)
{
	int index;

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

/********************************************************************/
static void
dump_sr (uint16 sr)
{
	char sr_buffer[17];
	register int i;
	int32 mask = MCF5XXX_SR_T;
	int32 result;

	for (i = 0; i < 16; i++)
	{
		result = mask & sr;
		mask = mask >> 1;

		switch (i)		/* going from left to right, don't be fooled */
		{
			case 0:
				if (result)
					sr_buffer[i] = 'T';
				else
					sr_buffer[i] = 't';
				break;
			case 1:
			case 4:
			case 8:
			case 9:
			case 10:
					sr_buffer[i] = '.';
					break;
			case 2:
				if (result)
					sr_buffer[i] = 'S';
				else
					sr_buffer[i] = 's';
				break;
			case 3:
				if (result)
					sr_buffer[i] = 'M';
				else
					sr_buffer[i] = 'm';
				break;
			case 5:
			case 6:
			case 7:
				if (result)
					sr_buffer[i] = '1';
				else
					sr_buffer[i] = '0';
				break;
			case 11:
				if (result)
					sr_buffer[i] = 'X';
				else
					sr_buffer[i] = 'x';
				break;
			case 12:
				if (result)
					sr_buffer[i] = 'N';
				else
					sr_buffer[i] = 'n';
				break;
			case 13:
				if (result)
					sr_buffer[i] = 'Z';
				else
					sr_buffer[i] = 'z';
				break;
			case 14:
				if (result)
					sr_buffer[i] = 'V';
				else
					sr_buffer[i] = 'v';
				break;
			case 15:
				if (result)
					sr_buffer[i] = 'C';
				else
					sr_buffer[i] = 'c';
				break;
			default:
				break;
		}
	}
	sr_buffer[i] = 0;
	printf("%s",sr_buffer);
}

/********************************************************************/
static void
dump_fs (void *framep)
{
	int fault = MCF5XXX_RD_SF_FS(framep);

	printf(" FS=%X, ",fault);

	switch (fault)
	{
		case 0x04:
			printf("Physical bus error on instruction fetch");
			break;
		case 0x08:
			printf("Physical bus error on operand write");
			break;
		case 0x09:
			printf("Attempted write to write-protected space");
			break;
		case 0x0C:
			printf("Physical bus error on operand read");
			break;
		default:
			printf("Reserved");
			break;
	}
	printf("\n");
}

/********************************************************************/
void
cpu_init (void)
{
	trace_thru = NULL;
	cpu_step_over = NULL;
	cpu_trace_count = 0;

	context.sr = MCF5XXX_SR_S;
}

/********************************************************************/
void
cpu_reg_modify (char *reg, uint32 value)
{
	int index;
	if ((index = find_register(reg)) != -1)
	{
		switch (registers[index].size)
		{
			case SIZE_16:
				*(uint16 *)registers[index].ptr = (uint16)value;
				break;
			case SIZE_32:
			default:
				*(uint32 *)registers[index].ptr = (uint32)value;
				break;
		}
	}
	else
	{
		printf(INVREG,reg);
	}
}

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

	if (reg == NULL)
	{
		printf("PC: %08X ", context.pc);
		printf("SR: %04X [", context.sr);
		dump_sr(context.sr);
		printf("]\n");

		printf("An: %08X %08X %08X %08X %08X %08X %08X %08X\n",
			context.a0,
			context.a1,
			context.a2,
			context.a3,
			context.a4,
			context.a5,
			context.a6,
			context.a7 );
			
		printf("Dn: %08X %08X %08X %08X %08X %08X %08X %08X\n",
			context.d0,
			context.d1,
			context.d2,
			context.d3,
			context.d4,
			context.d5,
			context.d6,
			context.d7 );
	}
	else
	{
		if ((index = find_register(reg)) != -1)
		{
			switch (registers[index].size)
			{
				case SIZE_16:
					printf("%s:  %04X\n",
						registers[index].name,
						*(uint16 *)(registers[index].ptr));
					break;
				case SIZE_32:
				default:
					printf("%s:  %08X\n",
						registers[index].name,
						*(uint32 *)(registers[index].ptr));
			}
		}
		else
		{
			printf(INVREG,reg);
		}
	}
}

/********************************************************************/
void
cpu_pc_modify (ADDRESS address)
{
	context.pc = address;
}

/********************************************************************/
ADDRESS
cpu_pc_get (void)
{
	return context.pc;
}

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

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

/********************************************************************/
int
cpu_valid_insn_addr (ADDRESS address)
{
	/* ColdFire requires instructions be on 16-bit boundary */
	return !(address & 0x00000001);
}

/********************************************************************/
void
cpu_switch_context (int trace)
{
	/*
	 * If 'trace' is TRUE, then we are performing a single
	 * instruction trace, thus, do not insert breakponts.
	 * Otherwise, install breakpoints and run normally.
	 */

	if (trace)
	{
		context.sr |= MCF5XXX_SR_T;
	}
	else
	{
	    if (breakpoint_install(context.pc))
		{
			/*
			 * The PC is at a breakpoint already.  Trace thru
			 * this breakpoint rather than actually breaking.
			 */
			trace_thru = context.pc;
			context.sr |= MCF5XXX_SR_T;
		}
	}
	
	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 & ~0x00000001);
			break;
		case SIZE_32:
			return (address & ~0x00000003);
			break;
		case SIZE_8:
		default:
			return (address);
			break;
	}
}

/********************************************************************/
ADDRESS
cpu_stack_frame (ADDRESS fp, ADDRESS *retpc)
{
	/*
	 * ColdFire/M68K JSR w/LINK and UNLK w/RTS
	 */
	if (retpc == NULL)
	{
		return context.a6;
	}
	else
	{
		*retpc = *(ADDRESS *)(fp + 4);
		return *(ADDRESS *)fp;
	}
}

/********************************************************************/
int
cpu_handler (void *framep)
{
	/*
	 * 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 ispdelta;
	int cpu_handler_flag;
	int user_brkpnt, user_triggered;

	/*
	 * Default action for most exceptions is to break to monitor.
	 */
	cpu_handler_flag = EXEC_DBUG;

	/*
	 * Update context.sp to point to prior to stack frame.
	 */
	switch (MCF5XXX_RD_SF_FORMAT(framep))
	{
		case 4:
			ispdelta = 8;
			break;
		case 5:
			ispdelta = 9;
			break;
		case 6:
			ispdelta = 10;
			break;
		case 7:
			ispdelta = 11;
			break;
		default:
			printf("\nIllegal stack type!\n");
			ispdelta = 0;
			break;
	}
	context.a7 += ispdelta;

	user_brkpnt = breakpoint_deinstall(context.pc, &user_triggered);

	switch (MCF5XXX_RD_SF_VECTOR(framep))
	{
		case 2:
			printf("Access Error: ");
			dump_fs(framep);
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 3:
			printf("Address Error: ");
			dump_fs(framep);
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 4:
			if (!user_brkpnt)
			{
				printf("Illegal instruction at %#08X\n",context.pc);
				cpu_reg_display(NULL);
				cpu_disasm(context.pc,TRUE);
				break;
			}

			if (cpu_step_over == context.pc)
			{
				/* clean up is at end of handler */
				cpu_reg_display(NULL);
				cpu_disasm(context.pc,TRUE);
				break;
			}

			if (user_triggered)
			{
				printf("Breakpoint encountered at %#08X\n",context.pc);
				cpu_reg_display(NULL);
				cpu_disasm(context.pc,TRUE);
				break;
			}

			/* else reinstall breakpoints and continue */
			/* execution of the task...we will return  */
			/* to task from here, not write out regs and RTE */
	    	if (breakpoint_install(context.pc))
			{
				/* about to execute at a breakpoint */
				/* trace thru this breakpoint rather breaking */
				trace_thru = context.pc;
				/* turn tracing on */
				MCF5XXX_SF_SR(framep) |= MCF5XXX_SR_T;
				/* readjust stack pointer for RTE */
				context.a7 -= ispdelta;
				cpu_handler_flag = EXEC_RTE;
			}
			break;
		case 8:
			printf("Privilege violation\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 9:
			if (trace_thru)
			{
				/* place breakpoint at trace_thru */
				cpu_write_data(trace_thru, SIZE_16, ILLEGAL);
				/* turn off tracing */
				context.sr &= ~MCF5XXX_SR_T;
				/* nullify trace_thru and continue execution */
				trace_thru = 0;
				cpu_handler_flag = EXEC_RTE;
				/* adjust user stack back so RTE frame correct */
				context.a7 -= ispdelta;
				/* since not recreating a new stack frame, must */
				/* turn off trace bit in SR already on stack.   */
				MCF5XXX_SF_SR(framep) &= ~MCF5XXX_SR_T;
				break;
			}

			/* each time through, decrement cpu_trace_count */
			if (--cpu_trace_count > 0)
			{
				context.a7 -= ispdelta;
				cpu_handler_flag = EXEC_RTE;
			}
			else
			{
				/* since not recreating a new stack frame, must */
				/* turn off trace bit in SR already on stack.   */
				MCF5XXX_SF_SR(framep) &= ~MCF5XXX_SR_T;
				/* turn off tracing */
				context.sr &= ~MCF5XXX_SR_T;
				cpu_handler_flag = EXEC_DBUG;
				cpu_trace_count = 0;
			}
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 10:
			printf("Unimplemented A-Line Instruction\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 11:
			printf("Unimplemented F-Line Instruction\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 12:
			printf("Debug Interrupt\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 14:
			printf("Format Error\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 15:
			printf("Unitialized Interrupt\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 24:
			printf("Spurious Interrupt\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 25:
		case 26:
		case 27:
		case 28:
		case 29:
		case 30:
		case 31:
			printf("Autovector interrupt level %d\n",
				MCF5XXX_RD_SF_VECTOR(framep) - 24);
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		case 32:
		case 33:
		case 34:
		case 35:
		case 36:
		case 37:
		case 38:
		case 39:
		case 40:
		case 41:
		case 42:
		case 43:
		case 44:
		case 45:
		case 46:
		case 47:
			printf("TRAP #%d\n", MCF5XXX_RD_SF_VECTOR(framep) - 32);
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
#if (defined(CPU_MCF5272))
		case 91:
			printf("External Interrupt 6\n");
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			ext_irq6_handler();
			break;
#endif
		case 5:
		case 6:
		case 7:
		case 13:
		case 16:
		case 17:
		case 18:
		case 19:
		case 20:
		case 21:
		case 22:
		case 23:
		case 48:
		case 49:
		case 50:
		case 51:
		case 52:
		case 53:
		case 54:
		case 55:
		case 56:
		case 57:
		case 58:
		case 59:
		case 60:
		case 61:
		case 62:
		case 63:
			printf("Reserved: #%d\n",
				MCF5XXX_RD_SF_VECTOR(framep));
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
		default:
			printf("User Defined Vector #%d\n",
				MCF5XXX_RD_SF_VECTOR(framep));
			cpu_reg_display(NULL);
			cpu_disasm(context.pc,TRUE);
			break;
	}

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

	return cpu_handler_flag;
}

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

⌨️ 快捷键说明

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