diff options
author | wdenk <wdenk> | 2002-08-27 10:52:29 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2002-08-27 10:52:29 +0000 |
commit | 1dda0b1f7c442a7e61a7faead9adcebff3e88053 (patch) | |
tree | 1b2f8b1902ba217a3bd58edf3209e500d47634ea /cpu | |
parent | 0f9cfa09df48b86ce5f8baefb3300417cc5b845b (diff) |
Initial revision
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/mpc8260/bedbug_603e.c | 239 | ||||
-rw-r--r-- | cpu/mpc8xx/bedbug_860.c | 318 | ||||
-rw-r--r-- | cpu/ppc4xx/bedbug_405.c | 309 |
3 files changed, 866 insertions, 0 deletions
diff --git a/cpu/mpc8260/bedbug_603e.c b/cpu/mpc8260/bedbug_603e.c new file mode 100644 index 00000000000..1ca057f7328 --- /dev/null +++ b/cpu/mpc8260/bedbug_603e.c @@ -0,0 +1,239 @@ +/* + * Bedbug Functions specific to the MPC603e core + */ + +#include <common.h> +#include <command.h> +#include <linux/ctype.h> + +#include <cmd_bedbug.h> +#include <bedbug/bedbug.h> +#include <bedbug/regs.h> +#include <bedbug/ppc.h> + +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) && (defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)) + +#define MAX_BREAK_POINTS 1 + +extern CPU_DEBUG_CTX bug_ctx; + +void bedbug603e_init __P((void)); +void bedbug603e_do_break __P((cmd_tbl_t*,int,int,char*[])); +void bedbug603e_break_isr __P((struct pt_regs*)); +int bedbug603e_find_empty __P((void)); +int bedbug603e_set __P((int,unsigned long)); +int bedbug603e_clear __P((int)); + + +/* ====================================================================== + * Initialize the global bug_ctx structure for the processor. Clear all + * of the breakpoints. + * ====================================================================== */ + +void bedbug603e_init( void ) +{ + int i; + /* -------------------------------------------------- */ + + bug_ctx.hw_debug_enabled = 0; + bug_ctx.stopped = 0; + bug_ctx.current_bp = 0; + bug_ctx.regs = NULL; + + bug_ctx.do_break = bedbug603e_do_break; + bug_ctx.break_isr = bedbug603e_break_isr; + bug_ctx.find_empty = bedbug603e_find_empty; + bug_ctx.set = bedbug603e_set; + bug_ctx.clear = bedbug603e_clear; + + for( i = 1; i <= MAX_BREAK_POINTS; ++i ) + (*bug_ctx.clear)( i ); + + puts ("BEDBUG:ready\n"); + return; +} /* bedbug_init_breakpoints */ + + + +/* ====================================================================== + * Set/clear/show the hardware breakpoint for the 603e. The "off" + * string will disable a specific breakpoint. The "show" string will + * display the current breakpoints. Otherwise an address will set a + * breakpoint at that address. Setting a breakpoint uses the CPU-specific + * set routine which will assign a breakpoint number. + * ====================================================================== */ + +void bedbug603e_do_break (cmd_tbl_t *cmdtp, int flag, int argc, + char *argv[]) +{ + long addr; /* Address to break at */ + int which_bp; /* Breakpoint number */ + /* -------------------------------------------------- */ + + if (argc < 2) + { + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + + /* Turn off a breakpoint */ + + if( strcmp( argv[ 1 ], "off" ) == 0 ) + { + if( bug_ctx.hw_debug_enabled == 0 ) + { + printf( "No breakpoints enabled\n" ); + return; + } + + which_bp = simple_strtoul( argv[ 2 ], NULL, 10 ); + + if( bug_ctx.clear ) + (*bug_ctx.clear)( which_bp ); + + printf( "Breakpoint %d removed\n", which_bp ); + return; + } + + /* Show a list of breakpoints */ + + if( strcmp( argv[ 1 ], "show" ) == 0 ) + { + for( which_bp = 1; which_bp <= MAX_BREAK_POINTS; ++which_bp ) + { + + addr = GET_IABR(); + + printf( "Breakpoint [%d]: ", which_bp ); + if( (addr & 0x00000002) == 0 ) + printf( "NOT SET\n" ); + else + disppc( (unsigned char *)(addr & 0xFFFFFFFC), 0, 1, bedbug_puts, F_RADHEX ); + } + return; + } + + /* Set a breakpoint at the address */ + + if(!(( isdigit( argv[ 1 ][ 0 ] )) || + (( argv[ 1 ][ 0 ] >= 'a' ) && ( argv[ 1 ][ 0 ] <= 'f' )) || + (( argv[ 1 ][ 0 ] >= 'A' ) && ( argv[ 1 ][ 0 ] <= 'F' )))) + { + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + + addr = simple_strtoul( argv[ 1 ], NULL, 16 ); + + if(( bug_ctx.set ) && ( which_bp = (*bug_ctx.set)( 0, addr )) > 0 ) + { + printf( "Breakpoint [%d]: ", which_bp ); + disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX ); + } + + return; +} /* bedbug603e_do_break */ + + + +/* ====================================================================== + * Handle a breakpoint. Enter a mini main loop. Stay in the loop until + * the stopped flag in the debug context is cleared. + * ====================================================================== */ + +void bedbug603e_break_isr( struct pt_regs *regs ) +{ + unsigned long addr; /* Address stopped at */ + /* -------------------------------------------------- */ + + bug_ctx.current_bp = 1; + addr = GET_IABR() & 0xFFFFFFFC; + + bedbug_main_loop( addr, regs ); + return; +} /* bedbug603e_break_isr */ + + + +/* ====================================================================== + * See if the hardware breakpoint is available. + * ====================================================================== */ + +int bedbug603e_find_empty( void ) +{ + /* -------------------------------------------------- */ + + if( (GET_IABR() && 0x00000002) == 0 ) + return 1; + + return 0; +} /* bedbug603e_find_empty */ + + + +/* ====================================================================== + * Set a breakpoint. If 'which_bp' is zero then find an unused breakpoint + * number, otherwise reassign the given breakpoint. If hardware debugging + * is not enabled, then turn it on via the MSR and DBCR0. Set the break + * address in the IABR register. + * ====================================================================== */ + +int bedbug603e_set( int which_bp, unsigned long addr ) +{ + /* -------------------------------------------------- */ + + if(( addr & 0x00000003 ) != 0 ) + { + printf( "Breakpoints must be on a 32 bit boundary\n" ); + return 0; + } + + /* Only look if which_bp == 0, else use which_bp */ + if(( bug_ctx.find_empty ) && ( !which_bp ) && + ( which_bp = (*bug_ctx.find_empty)()) == 0 ) + { + printf( "All breakpoints in use\n" ); + return 0; + } + + if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) + { + printf( "Invalid break point # %d\n", which_bp ); + return 0; + } + + if( ! bug_ctx.hw_debug_enabled ) + { + bug_ctx.hw_debug_enabled = 1; + } + + SET_IABR( addr | 0x00000002 ); + + return which_bp; +} /* bedbug603e_set */ + + + +/* ====================================================================== + * Disable a specific breakoint by setting the IABR register to zero. + * ====================================================================== */ + +int bedbug603e_clear( int which_bp ) +{ + /* -------------------------------------------------- */ + + if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) + { + printf( "Invalid break point # (%d)\n", which_bp ); + return -1; + } + + SET_IABR( 0 ); + + return 0; +} /* bedbug603e_clear */ + + +/* ====================================================================== */ +#endif + diff --git a/cpu/mpc8xx/bedbug_860.c b/cpu/mpc8xx/bedbug_860.c new file mode 100644 index 00000000000..05590df30af --- /dev/null +++ b/cpu/mpc8xx/bedbug_860.c @@ -0,0 +1,318 @@ +/* + * Bedbug Functions specific to the MPC860 chip + */ + +#include <common.h> +#include <command.h> +#include <linux/ctype.h> + +#include <cmd_bedbug.h> +#include <bedbug/bedbug.h> +#include <bedbug/regs.h> +#include <bedbug/ppc.h> + +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) && defined(CONFIG_MPC860) + +#define MAX_BREAK_POINTS 2 + +extern CPU_DEBUG_CTX bug_ctx; + +void bedbug860_init __P((void)); +void bedbug860_do_break __P((cmd_tbl_t*,int,int,char*[])); +void bedbug860_break_isr __P((struct pt_regs*)); +int bedbug860_find_empty __P((void)); +int bedbug860_set __P((int,unsigned long)); +int bedbug860_clear __P((int)); + + +/* ====================================================================== + * Initialize the global bug_ctx structure for the MPC860. Clear all + * of the breakpoints. + * ====================================================================== */ + +void bedbug860_init( void ) +{ + int i; + /* -------------------------------------------------- */ + + bug_ctx.hw_debug_enabled = 0; + bug_ctx.stopped = 0; + bug_ctx.current_bp = 0; + bug_ctx.regs = NULL; + + bug_ctx.do_break = bedbug860_do_break; + bug_ctx.break_isr = bedbug860_break_isr; + bug_ctx.find_empty = bedbug860_find_empty; + bug_ctx.set = bedbug860_set; + bug_ctx.clear = bedbug860_clear; + + for( i = 1; i <= MAX_BREAK_POINTS; ++i ) + (*bug_ctx.clear)( i ); + + puts ("BEDBUG:ready\n"); + return; +} /* bedbug_init_breakpoints */ + + + +/* ====================================================================== + * Set/clear/show one of the hardware breakpoints for the 860. The "off" + * string will disable a specific breakpoint. The "show" string will + * display the current breakpoints. Otherwise an address will set a + * breakpoint at that address. Setting a breakpoint uses the CPU-specific + * set routine which will assign a breakpoint number. + * ====================================================================== */ + +void bedbug860_do_break (cmd_tbl_t *cmdtp, int flag, int argc, + char *argv[]) +{ + long addr = 0; /* Address to break at */ + int which_bp; /* Breakpoint number */ + /* -------------------------------------------------- */ + + if (argc < 2) + { + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + + /* Turn off a breakpoint */ + + if( strcmp( argv[ 1 ], "off" ) == 0 ) + { + if( bug_ctx.hw_debug_enabled == 0 ) + { + printf( "No breakpoints enabled\n" ); + return; + } + + which_bp = simple_strtoul( argv[ 2 ], NULL, 10 ); + + if( bug_ctx.clear ) + (*bug_ctx.clear)( which_bp ); + + printf( "Breakpoint %d removed\n", which_bp ); + return; + } + + /* Show a list of breakpoints */ + + if( strcmp( argv[ 1 ], "show" ) == 0 ) + { + for( which_bp = 1; which_bp <= MAX_BREAK_POINTS; ++which_bp ) + { + + switch( which_bp ) + { + case 1: addr = GET_CMPA(); break; + case 2: addr = GET_CMPB(); break; + case 3: addr = GET_CMPC(); break; + case 4: addr = GET_CMPD(); break; + } + + printf( "Breakpoint [%d]: ", which_bp ); + if( addr == 0 ) + printf( "NOT SET\n" ); + else + disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX ); + } + return; + } + + /* Set a breakpoint at the address */ + + if( !isdigit( argv[ 1 ][ 0 ])) + { + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + + addr = simple_strtoul( argv[ 1 ], NULL, 16 ) & 0xfffffffc; + + if(( bug_ctx.set ) && ( which_bp = (*bug_ctx.set)( 0, addr )) > 0 ) + { + printf( "Breakpoint [%d]: ", which_bp ); + disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX ); + } + + return; +} /* bedbug860_do_break */ + + + +/* ====================================================================== + * Handle a breakpoint. First determine which breakpoint was hit by + * looking at the DeBug Status Register (DBSR), clear the breakpoint + * and enter a mini main loop. Stay in the loop until the stopped flag + * in the debug context is cleared. + * ====================================================================== */ + +void bedbug860_break_isr( struct pt_regs *regs ) +{ + unsigned long addr; /* Address stopped at */ + unsigned long cause; /* Address stopped at */ + /* -------------------------------------------------- */ + + cause = GET_ICR(); + + if( !(cause & 0x00000004)) { + printf( "Not an instruction breakpoint (ICR 0x%08lx)\n", cause ); + return; + } + + addr = regs->nip; + + if( addr == GET_CMPA() ) + { + bug_ctx.current_bp = 1; + } + else if( addr == GET_CMPB() ) + { + bug_ctx.current_bp = 2; + } + else if( addr == GET_CMPC() ) + { + bug_ctx.current_bp = 3; + } + else if( addr == GET_CMPD() ) + { + bug_ctx.current_bp = 4; + } + + bedbug_main_loop( addr, regs ); + return; +} /* bedbug860_break_isr */ + + + +/* ====================================================================== + * Look through all of the hardware breakpoints available to see if one + * is unused. + * ====================================================================== */ + +int bedbug860_find_empty( void ) +{ + /* -------------------------------------------------- */ + + if( GET_CMPA() == 0 ) + return 1; + + if( GET_CMPB() == 0 ) + return 2; + + if( GET_CMPC() == 0 ) + return 3; + + if( GET_CMPD() == 0 ) + return 4; + + return 0; +} /* bedbug860_find_empty */ + + + +/* ====================================================================== + * Set a breakpoint. If 'which_bp' is zero then find an unused breakpoint + * number, otherwise reassign the given breakpoint. If hardware debugging + * is not enabled, then turn it on via the MSR and DBCR0. Set the break + * address in the appropriate IACx register and enable proper address + * beakpoint in DBCR0. + * ====================================================================== */ + +int bedbug860_set( int which_bp, unsigned long addr ) +{ + /* -------------------------------------------------- */ + + /* Only look if which_bp == 0, else use which_bp */ + if(( bug_ctx.find_empty ) && ( !which_bp ) && + ( which_bp = (*bug_ctx.find_empty)()) == 0 ) + { + printf( "All breakpoints in use\n" ); + return 0; + } + + if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) + { + printf( "Invalid break point # %d\n", which_bp ); + return 0; + } + + if( ! bug_ctx.hw_debug_enabled ) + { + bug_ctx.hw_debug_enabled = 1; + SET_DER( GET_DER() | 0x00000004 ); + } + + switch( which_bp ) + { + case 1: + SET_CMPA( addr ); + SET_ICTRL( GET_ICTRL() | 0x80080800 ); /* CTA=Equal,IW0=Match A,SIW0EN */ + break; + + case 2: + SET_CMPB( addr ); + SET_ICTRL( GET_ICTRL() | 0x10020400 ); /* CTB=Equal,IW1=Match B,SIW1EN */ + break; + + case 3: + SET_CMPC( addr ); + SET_ICTRL( GET_ICTRL() | 0x02008200 ); /* CTC=Equal,IW2=Match C,SIW2EN */ + break; + + case 4: + SET_CMPD( addr ); + SET_ICTRL( GET_ICTRL() | 0x00404100 ); /* CTD=Equal,IW3=Match D,SIW3EN */ + break; + } + + return which_bp; +} /* bedbug860_set */ + + + +/* ====================================================================== + * Disable a specific breakoint by setting the appropriate IACx register + * to zero and claring the instruction address breakpoint in DBCR0. + * ====================================================================== */ + +int bedbug860_clear( int which_bp ) +{ + /* -------------------------------------------------- */ + + if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) + { + printf( "Invalid break point # (%d)\n", which_bp ); + return -1; + } + + switch( which_bp ) + { + case 1: + SET_CMPA( 0 ); + SET_ICTRL( GET_ICTRL() & ~0x80080800 ); /* CTA=Equal,IW0=Match A,SIW0EN */ + break; + + case 2: + SET_CMPB( 0 ); + SET_ICTRL( GET_ICTRL() & ~0x10020400 ); /* CTB=Equal,IW1=Match B,SIW1EN */ + break; + + case 3: + SET_CMPC( 0 ); + SET_ICTRL( GET_ICTRL() & ~0x02008200 ); /* CTC=Equal,IW2=Match C,SIW2EN */ + break; + + case 4: + SET_CMPD( 0 ); + SET_ICTRL( GET_ICTRL() & ~0x00404100 ); /* CTD=Equal,IW3=Match D,SIW3EN */ + break; + } + + return 0; +} /* bedbug860_clear */ + + +/* ====================================================================== */ +#endif + diff --git a/cpu/ppc4xx/bedbug_405.c b/cpu/ppc4xx/bedbug_405.c new file mode 100644 index 00000000000..eabc583d216 --- /dev/null +++ b/cpu/ppc4xx/bedbug_405.c @@ -0,0 +1,309 @@ +/* + * Bedbug Functions specific to the PPC405 chip + */ + +#include <common.h> +#include <command.h> +#include <linux/ctype.h> + +#include <cmd_bedbug.h> +#include <bedbug/bedbug.h> +#include <bedbug/regs.h> +#include <bedbug/ppc.h> + +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) && defined(CONFIG_4xx) + +#define MAX_BREAK_POINTS 4 + +extern CPU_DEBUG_CTX bug_ctx; + +void bedbug405_init __P ((void)); +void bedbug405_do_break __P ((cmd_tbl_t *, int, int, char *[])); +void bedbug405_break_isr __P ((struct pt_regs *)); +int bedbug405_find_empty __P ((void)); +int bedbug405_set __P ((int, unsigned long)); +int bedbug405_clear __P ((int)); + + +/* ====================================================================== + * Initialize the global bug_ctx structure for the IBM PPC405. Clear all + * of the breakpoints. + * ====================================================================== */ + +void bedbug405_init (void) +{ + int i; + + /* -------------------------------------------------- */ + + bug_ctx.hw_debug_enabled = 0; + bug_ctx.stopped = 0; + bug_ctx.current_bp = 0; + bug_ctx.regs = NULL; + + bug_ctx.do_break = bedbug405_do_break; + bug_ctx.break_isr = bedbug405_break_isr; + bug_ctx.find_empty = bedbug405_find_empty; + bug_ctx.set = bedbug405_set; + bug_ctx.clear = bedbug405_clear; + + for (i = 1; i <= MAX_BREAK_POINTS; ++i) + (*bug_ctx.clear) (i); + + puts ("BEDBUG:ready\n"); + return; +} /* bedbug_init_breakpoints */ + + + +/* ====================================================================== + * Set/clear/show one of the hardware breakpoints for the 405. The "off" + * string will disable a specific breakpoint. The "show" string will + * display the current breakpoints. Otherwise an address will set a + * breakpoint at that address. Setting a breakpoint uses the CPU-specific + * set routine which will assign a breakpoint number. + * ====================================================================== */ + +void bedbug405_do_break (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + long addr = 0; /* Address to break at */ + int which_bp; /* Breakpoint number */ + + /* -------------------------------------------------- */ + + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + + /* Turn off a breakpoint */ + + if (strcmp (argv[1], "off") == 0) { + if (bug_ctx.hw_debug_enabled == 0) { + printf ("No breakpoints enabled\n"); + return; + } + + which_bp = simple_strtoul (argv[2], NULL, 10); + + if (bug_ctx.clear) + (*bug_ctx.clear) (which_bp); + + printf ("Breakpoint %d removed\n", which_bp); + return; + } + + /* Show a list of breakpoints */ + + if (strcmp (argv[1], "show") == 0) { + for (which_bp = 1; which_bp <= MAX_BREAK_POINTS; ++which_bp) { + + switch (which_bp) { + case 1: + addr = GET_IAC1 (); + break; + case 2: + addr = GET_IAC2 (); + break; + case 3: + addr = GET_IAC3 (); + break; + case 4: + addr = GET_IAC4 (); + break; + } + + printf ("Breakpoint [%d]: ", which_bp); + if (addr == 0) + printf ("NOT SET\n"); + else + disppc ((unsigned char *) addr, 0, 1, bedbug_puts, + F_RADHEX); + } + return; + } + + /* Set a breakpoint at the address */ + + if (!isdigit (argv[1][0])) { + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + + addr = simple_strtoul (argv[1], NULL, 16) & 0xfffffffc; + + if ((bug_ctx.set) && (which_bp = (*bug_ctx.set) (0, addr)) > 0) { + printf ("Breakpoint [%d]: ", which_bp); + disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX); + } + + return; +} /* bedbug405_do_break */ + + + +/* ====================================================================== + * Handle a breakpoint. First determine which breakpoint was hit by + * looking at the DeBug Status Register (DBSR), clear the breakpoint + * and enter a mini main loop. Stay in the loop until the stopped flag + * in the debug context is cleared. + * ====================================================================== */ + +void bedbug405_break_isr (struct pt_regs *regs) +{ + unsigned long dbsr_val; /* Value of the DBSR */ + unsigned long addr = 0; /* Address stopped at */ + + /* -------------------------------------------------- */ + + dbsr_val = GET_DBSR (); + + if (dbsr_val & DBSR_IA1) { + bug_ctx.current_bp = 1; + addr = GET_IAC1 (); + SET_DBSR (DBSR_IA1); /* Write a 1 to clear */ + } else if (dbsr_val & DBSR_IA2) { + bug_ctx.current_bp = 2; + addr = GET_IAC2 (); + SET_DBSR (DBSR_IA2); /* Write a 1 to clear */ + } else if (dbsr_val & DBSR_IA3) { + bug_ctx.current_bp = 3; + addr = GET_IAC3 (); + SET_DBSR (DBSR_IA3); /* Write a 1 to clear */ + } else if (dbsr_val & DBSR_IA4) { + bug_ctx.current_bp = 4; + addr = GET_IAC4 (); + SET_DBSR (DBSR_IA4); /* Write a 1 to clear */ + } + + bedbug_main_loop (addr, regs); + return; +} /* bedbug405_break_isr */ + + + +/* ====================================================================== + * Look through all of the hardware breakpoints available to see if one + * is unused. + * ====================================================================== */ + +int bedbug405_find_empty (void) +{ + /* -------------------------------------------------- */ + + if (GET_IAC1 () == 0) + return 1; + + if (GET_IAC2 () == 0) + return 2; + + if (GET_IAC3 () == 0) + return 3; + + if (GET_IAC4 () == 0) + return 4; + + return 0; +} /* bedbug405_find_empty */ + + + +/* ====================================================================== + * Set a breakpoint. If 'which_bp' is zero then find an unused breakpoint + * number, otherwise reassign the given breakpoint. If hardware debugging + * is not enabled, then turn it on via the MSR and DBCR0. Set the break + * address in the appropriate IACx register and enable proper address + * beakpoint in DBCR0. + * ====================================================================== */ + +int bedbug405_set (int which_bp, unsigned long addr) +{ + /* -------------------------------------------------- */ + + /* Only look if which_bp == 0, else use which_bp */ + if ((bug_ctx.find_empty) && (!which_bp) && + (which_bp = (*bug_ctx.find_empty) ()) == 0) { + printf ("All breakpoints in use\n"); + return 0; + } + + if (which_bp < 1 || which_bp > MAX_BREAK_POINTS) { + printf ("Invalid break point # %d\n", which_bp); + return 0; + } + + if (!bug_ctx.hw_debug_enabled) { + SET_MSR (GET_MSR () | 0x200); /* set MSR[ DE ] */ + SET_DBCR0 (GET_DBCR0 () | DBCR0_IDM); + bug_ctx.hw_debug_enabled = 1; + } + + switch (which_bp) { + case 1: + SET_IAC1 (addr); + SET_DBCR0 (GET_DBCR0 () | DBCR0_IA1); + break; + + case 2: + SET_IAC2 (addr); + SET_DBCR0 (GET_DBCR0 () | DBCR0_IA2); + break; + + case 3: + SET_IAC3 (addr); + SET_DBCR0 (GET_DBCR0 () | DBCR0_IA3); + break; + + case 4: + SET_IAC4 (addr); + SET_DBCR0 (GET_DBCR0 () | DBCR0_IA4); + break; + } + + return which_bp; +} /* bedbug405_set */ + + + +/* ====================================================================== + * Disable a specific breakoint by setting the appropriate IACx register + * to zero and claring the instruction address breakpoint in DBCR0. + * ====================================================================== */ + +int bedbug405_clear (int which_bp) +{ + /* -------------------------------------------------- */ + + if (which_bp < 1 || which_bp > MAX_BREAK_POINTS) { + printf ("Invalid break point # (%d)\n", which_bp); + return -1; + } + + switch (which_bp) { + case 1: + SET_IAC1 (0); + SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA1); + break; + + case 2: + SET_IAC2 (0); + SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA2); + break; + + case 3: + SET_IAC3 (0); + SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA3); + break; + + case 4: + SET_IAC4 (0); + SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA4); + break; + } + + return 0; +} /* bedbug405_clear */ + + +/* ====================================================================== */ +#endif |