📄 hbrktab.c
字号:
/*
* File: hbrktab.c
* Purpose: Hardware Breakpoint table management routines.
*
* Notes:
*
*/
#include "src/include/dbug.h"
#include "src/uif/uif.h"
/********************************************************************/
/*
* Data structure used to maintain break points and trace
* information.
*/
typedef struct
{
ADDRESS address;
int valid; /* and type info */
} HBRKENT;
HBRKENT hbrktab[UIF_MAX_HBRKPTS];
/********************************************************************/
static void
hbreakpoint_clear (int index)
{
if ((index >= 0) && (index < UIF_MAX_HBRKPTS))
{
hbrktab[index].address = NULL;
hbrktab[index].valid = BKPT_NONE;
switch(index){
case 0:
mpc5xx_wr_cmpa(0x00000000); /*clear address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() & 0x1FF3F7FF); /*turn off compare type of CMPA*/
printf("Cleared Hardware Breakpoint A\n");
break;
case 1:
mpc5xx_wr_cmpb(0x00000000); /*clear address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() & 0xEFFDFBFF); /*turn off compare type of CMPB*/
printf("Cleared Hardware Breakpoint Bn");
break;
case 2:
mpc5xx_wr_cmpc(0x00000000); /*clear address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() & 0xFDFF7DFF); /*turn off compare type of CMPC*/
printf("Cleared Hardware Breakpoint C\n");
break;
case 3:
mpc5xx_wr_cmpd(0x00000000); /*clear address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() & 0xFFBFDEFF); /*turn off compare type of CMPD*/
printf("Cleared Hardware Breakpoint D\n");
break;
}
}
}
/********************************************************************/
void
hbreakpoint_init (void)
{
int index;
for (index = 0; index < UIF_MAX_HBRKPTS; index++)
hbreakpoint_clear(index);
}
/********************************************************************/
static int
hbreakpoint_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_HBRKPTS; index++)
{
if (hbrktab[index].address == address)
return index;
}
return -1;
}
/********************************************************************/
static void
hbreakpoint_display_info (int index)
{
if ((index >= 0) && (index < UIF_MAX_HBRKPTS))
{
printf("%08X\n",hbrktab[index].address);
}
}
/********************************************************************/
static void
hbreakpoint_display (int argc, char **argv)
{
ADDRESS address;
int i,j;
(void)argc;
printf(" Address \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_HBRKPTS; i++)
{
if (hbrktab[i].valid)
hbreakpoint_display_info(i);
}
}
else
{
i = 1;
while (argv[i] != NULL)
{
address = (ADDRESS)strtoul(argv[i],NULL,16);
for (j = 0; j < UIF_MAX_HBRKPTS; j++)
{
if (hbrktab[j].address == address)
hbreakpoint_display_info(j);
}
i++;
}
}
}
/********************************************************************/
void
hbreakpoint_remove (ADDRESS address)
{
int index;
if ((index = hbreakpoint_find(address)) != -1)
{
hbreakpoint_clear(index);
}
}
/********************************************************************/
void
hbreakpoint_add (ADDRESS address, int type)
{
int i;
/* first check to make sure not already in table */
if (hbreakpoint_find(address) != -1)
return;
/*
* Test for valid breakpoint address
*/
if (!cpu_valid_insn_addr(address))
{
printf("Error: Invalid breakpoint address!\n");
return;
}
/* FIX THIS to check for overlap of dBUG code
* Test for read-only memory
*/
/* find an open slot and put it in table*/
for (i = 0; i < UIF_MAX_HBRKPTS; i++)
{
if (!hbrktab[i].valid)
break;
}
if (i == UIF_MAX_HBRKPTS)
{
printf("Hardware Break table full.\n");
return;
}
else
{
/*program the CMP and ICTRL registers with the hardware breakpoint*/
hbrktab[i].address = address;
hbrktab[i].valid = type;
//hbreakpoint_install (address);
switch(i){
case 0:
mpc5xx_wr_cmpa(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x80080800); /*set compare type of CMPA to "equal"*/
printf("Added Hardware Breakpoint at %08X\n",address);
break;
case 1:
mpc5xx_wr_cmpb(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x10020400); /*set compare type of CMPB to "equal"*/
printf("Added Hardware Breakpoint at %08X\n",address);
break;
case 2:
mpc5xx_wr_cmpc(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x02008200); /*set compare type of CMPC to "equal"*/
printf("Added Hardware Breakpoint at %08X\n",address);
break;
case 3:
mpc5xx_wr_cmpd(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x00402100); /*set compare type of CMPD to "equal"*/
printf("Added Hardware Breakpoint at %08X\n",address);
break;
default:
printf("I'm lost");
break;
}
}
}
/********************************************************************/
int
hbreakpoint_install (ADDRESS address)
{
/*
* This function inserts the hardare 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_HBRKPTS; index++)
{
if (hbrktab[index].valid)
{
switch(index){
case 0:
mpc5xx_wr_cmpa(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x80080800); /*set compare type of CMPA to "equal"*/
break;
case 1:
mpc5xx_wr_cmpb(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x10020800); /*set compare type of CMPB to "equal"*/
break;
case 2:
mpc5xx_wr_cmpc(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x02008200); /*set compare type of CMPC to "equal"*/
break;
case 3:
mpc5xx_wr_cmpd(address); /*set address of hardware breakpoint*/
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x00402100); /*set compare type of CMPD to "equal"*/
break;
default:
printf("I'm lost");
break;
}
}
}
return found;
}
/********************************************************************/
void
mpc5xx_hbr (int argc, char **argv)
{
int i, success;
ADDRESS hbrkpnt;
hbrkpnt = (ADDRESS)-1; /* improbable breakpoint address */
if (argc == 1)
{
/* display all break points */
hbreakpoint_display(argc,argv);
return ;
}
/* parse through arguments */
i = 1;
while (i < argc)
{
if (argv[i][0] != '-')
{
/* must be a breakpoint address */
hbrkpnt = get_value(argv[i],&success,16);
if (success == 0)
{
printf("Error: Bad Value: %s\n",argv[i]);
return;
}
/* add breakpont, if not already there */
hbreakpoint_add(hbrkpnt, BKPT_PERM);
i++;
}
else
{
/* must be an option of some sort */
switch (argv[i][1])
{
case 'r':
case 'R':
/* remove break points */
if (hbrkpnt == (ADDRESS)-1)
{
/* check for address given after '-r' */
if (argv[i+1] == NULL)
hbreakpoint_init();
else
{
while (++i < argc)
{
hbrkpnt = get_value(argv[i],&success,16);
if (success == 0)
hbreakpoint_init();
else
hbreakpoint_remove(hbrkpnt);
}
}
}
else
{
hbreakpoint_remove(hbrkpnt);
}
break;
default:
printf("Error: Invalid option: %s\n",argv[1]);
break;
}
i++;
}
}
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -