/*
 * Bedbug Functions specific to the MPC603e core
 */

#include <common.h>
#include <command.h>
#include <linux/ctype.h>
#include <bedbug/type.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 )
    {
      puts ( "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 )
	puts ( "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 )
  {
    puts ( "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 )
  {
    puts ( "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
