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

📄 brktab.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
字号:
/*
 * File:		brktab.c
 * Purpose:		Breakpoint table management routines.
 *
 * Notes:
 *
 * Author:		Eric DeVolder
 * Date:		
 *
 * Modifications:
 *
 */

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

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

/*
 * Data structure used to maintain break points and trace
 * information.
 */
typedef struct
{
	ADDRESS		address;
	INSTRUCTION	instruction;
	int			count;
	int			trigger;
	int			valid;	/* and type info */
} BRKENT;

BRKENT
brktab[UIF_MAX_BRKPTS];

/********************************************************************/
static void
breakpoint_clear (int index)
{
	if ((index >= 0) && (index < UIF_MAX_BRKPTS))
	{
		brktab[index].address = NULL;
		brktab[index].instruction = NULL;
		brktab[index].count = 0;
		brktab[index].trigger = 0;
		brktab[index].valid = BKPT_NONE;
	}
}

/********************************************************************/
void
breakpoint_init (void)
{
	int index;

	for (index = 0; index < UIF_MAX_BRKPTS; index++)
		breakpoint_clear(index);
}

/********************************************************************/
static int
breakpoint_find (ADDRESS address)
{
	/*
	 * This function searches the breakpoint table for `address'.
	 * If it is found, then an index into the table is returned,
	 * otherwise -1 is returned.
	 */
	int index;
	for (index = 0; index < UIF_MAX_BRKPTS; index++)
	{
		if (brktab[index].address == address)
			return index;
	}
	return -1;
}

/********************************************************************/
static void
breakpoint_display_info (int index)
{
	if ((index >= 0) && (index < UIF_MAX_BRKPTS))
	{
		printf("%08X:  %08X %08X\n",
			(int)brktab[index].address,
			brktab[index].count,
			brktab[index].trigger );
	}
}

/********************************************************************/
static void
breakpoint_display (int argc, char **argv)
{
	ADDRESS address;
	int i,j;

	(void)argc;

	printf(" Address      Count  Trigger\n");
	/* break points are listed one by one starting at argv[1]  */
	/* if no break points listed, argv[1] == NULL, display all */
	if (argv[1] == NULL)
	{
		/* display all */
		for (i = 0; i < UIF_MAX_BRKPTS; i++)
		{
			if (brktab[i].valid)
				breakpoint_display_info(i);
		}
	}
	else
	{
		i = 1;
		while (argv[i] != NULL)
		{
			address = (ADDRESS)strtoul(argv[i],NULL,16);
			for (j = 0; j < UIF_MAX_BRKPTS; j++)
			{
				if (brktab[j].address == address)
					breakpoint_display_info(j);
			}
			i++;
		}
	}
}

/********************************************************************/
static void
breakpoint_set_count (ADDRESS brkpnt, int count)
{
	int index;
	index = breakpoint_find(brkpnt);

	if ((index >= 0) && (index < UIF_MAX_BRKPTS))
	{
		brktab[index].count = count;
	}
}

/********************************************************************/
static void
breakpoint_set_all_count (int value)
{
	int index;
	for (index = 0; index < UIF_MAX_BRKPTS; index++)
		brktab[index].count = value;
}

/********************************************************************/
static void
breakpoint_set_trigger (ADDRESS brkpnt, int count)
{
	int index;
	index = breakpoint_find(brkpnt);

	if ((index >= 0) && (index < UIF_MAX_BRKPTS))
	{
		brktab[index].trigger = count;
	}
}

/********************************************************************/
static void
breakpoint_set_all_trigger (int value)
{
	int index;
	for (index = 0; index < UIF_MAX_BRKPTS; index++)
		brktab[index].trigger = value;
}

/********************************************************************/
void
breakpoint_remove (ADDRESS address)
{
	int index;
	if ((index = breakpoint_find(address)) != -1)
	{
		breakpoint_clear(index);
	}
}

/********************************************************************/
void
breakpoint_add (ADDRESS address, int type)
{
	int i;
	/* first check to make sure not already in table */
	if (breakpoint_find(address) != -1)
		return;
	
	/* find an open slot and put it in */
	for (i = 0; i < UIF_MAX_BRKPTS; i++)
	{
		if (!brktab[i].valid)
		break;
	}
	if (i == UIF_MAX_BRKPTS)
	{
		printf("Break table full.\n");
		return;
	}

	/*
	 * Test for valid breakpoint address
	 */
	if (!cpu_valid_insn_addr(address))
	{
		printf("Error:  Invalid breakpoint address!\n");
		return;
	}

	/*
	 * Test for read-only memory
	 */
	brktab[i].instruction = *(INSTRUCTION *)address;
	*(INSTRUCTION *)address = (INSTRUCTION)ILLEGAL;
	if (*(INSTRUCTION *)address != (INSTRUCTION)ILLEGAL)
	{
		printf("Error:  Address is read-only!\n");
	}
	else
	{
		*(INSTRUCTION *)address = brktab[i].instruction;
		brktab[i].address = address;
		brktab[i].count = 0;
		brktab[i].trigger = 1;
		brktab[i].valid = type;
	}
}

/********************************************************************/
int
breakpoint_install (ADDRESS address)
{
	/*
	 * This function inserts the breakpoints in user code.  Extensive
	 * checking of breakpoints is done before entry into the table, so
	 * all breakpoints in table should be OK to just implant.  If
	 * a breakpoint with the same `address' is found, it is not
	 * inserted, and TRUE is returned, otherwise FALSE.
	 * This routine is generally called right before executing user
	 * code.
	 */
	int index, found = FALSE;
	for (index = 0; index < UIF_MAX_BRKPTS; index++)
	{
		if (brktab[index].valid)
		{
			if (brktab[index].address == address)
			{
				found = TRUE;
			}
			else
			{
				brktab[index].instruction = 
					*(INSTRUCTION *)brktab[index].address;
				*(INSTRUCTION *)brktab[index].address =
					(INSTRUCTION)ILLEGAL;
			}
		}
	}
	cpu_cache_flush();
	return found;
}

/********************************************************************/
int
breakpoint_deinstall (ADDRESS address, int *triggered)
{
	/*
	 * This function removes breakpoints from user code.  If
	 * `address' is/was installed, TRUE is returned, else FALSE
	 * if `address' was encountered, its count is incremented.
	 */
	int index, found = FALSE;
	*triggered = FALSE;
	for (index = 0; index < UIF_MAX_BRKPTS; index++)
	{
		if (brktab[index].valid)
		{
			*(INSTRUCTION *)brktab[index].address =
				(INSTRUCTION)brktab[index].instruction;
			if (brktab[index].address == address)
			{
				found = TRUE;
				if ( ++brktab[index].count >=
						brktab[index].trigger)
					*triggered = TRUE;
			}
			if (brktab[index].valid == BKPT_TEMP)
			{
				/* knock out Temporary breakpoints */
				breakpoint_clear(index);
			}
		}
	}
	cpu_cache_flush();
	return found;
}

/********************************************************************/
void
uif_cmd_br (int argc, char **argv)
{
	int i, value, success;
	ADDRESS brkpnt;
	char *p;

	brkpnt = (ADDRESS)-1;	/* improbable breakpoint address */
	if (argc == 1)
	{
		/* display all break points */
		breakpoint_display(argc,argv);
		return ;
	}

	/* parse through arguments */
	i = 1;
	while (i < argc)
	{
		if (argv[i][0] != '-')
		{
			/* must be a breakpoint address */
			brkpnt = get_value(argv[i],&success,16);
			if (success == 0)
			{
				printf("Error:  Bad Value:  %s\n",argv[i]);
				return;
			}
			/* add breakpont, if not already there */
			breakpoint_add(brkpnt, BKPT_PERM);
			i++;
		}
		else
		{
			/* must be an option of some sort */
			switch (argv[i][1])
			{
				case 'c':
				case 'C':
					/* set break point count */
					if (argv[i+1] == NULL)
						value = 0;
					else
					{
						value = strtoul(argv[++i],&p,BASE);
						if ((value == 0) && (p == argv[i]))
							value = 0;
					}
					if (brkpnt == (ADDRESS)-1)
					{
						/* set all counts */
						breakpoint_set_all_count(value);
						return;
					}
					else
					{
						breakpoint_set_count(brkpnt,value);
					}
					break;
				case 't':
				case 'T':
					/* set break point trigger */
					if (argv[i+1] == NULL)
						value = 1;
					else
					{
						value = strtoul(argv[++i],&p,BASE);
						if ((value == 0) && (p == argv[i]))
							value = 1;
					}
					if (brkpnt == (ADDRESS)-1)
					{
						/* set all triggers */
						breakpoint_set_all_trigger(value);
						return;
					}
					else
					{
						breakpoint_set_trigger(brkpnt,value);
					}
					break;
				case 'r':
				case 'R':
					/* remove break points */
					if (brkpnt == (ADDRESS)-1)
					{
						/* check for address given after '-r' */
						if (argv[i+1] == NULL)
							breakpoint_init();
						else
						{
							while (++i < argc)
							{
								brkpnt = get_value(argv[i],&success,16);
								if (success == 0)
									breakpoint_init();
								else
									breakpoint_remove(brkpnt);
							}
						}
					}
					else
					{
						breakpoint_remove(brkpnt);
					}
					break;
				case 'i':
				case 'I':
						breakpoint_set_all_trigger(1);
						breakpoint_set_all_count(0);
						break;
				default:
					printf("Error:  Invalid option:  %s\n",argv[1]);
					break;
			}
			i++;
		}
	}
}

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

⌨️ 快捷键说明

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