⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bedbug_860.c.svn-base

📁 PowerPC850系列的產品開機程式uboot是linuxOS BASED的程式碼
💻 SVN-BASE
字号:
/* * 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 2extern 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -