/*
 * 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

