/*
 * Bedbug Functions specific to the MPC860 chip
 */

#include <common.h>
#include <command.h>
#include <linux/ctype.h>
#include <bedbug/bedbug.h>
#include <bedbug/regs.h>
#include <bedbug/ppc.h>
#include <bedbug/type.h>

#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) && defined(CONFIG_8xx)

#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
