]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_bedbug.c
Merge branch 'tx6-bugfix'
[karo-tx-uboot.git] / common / cmd_bedbug.c
index 75b74d50b0690887c4abf4eb569208b4dd95b114..57a8a3f2fe352177fa8edefd629ea7ac57bfb5f7 100644 (file)
  */
 
 #include <common.h>
+#include <cli.h>
 #include <command.h>
 #include <linux/ctype.h>
 #include <net.h>
-
-#include <cmd_bedbug.h>
+#include <bedbug/type.h>
 #include <bedbug/bedbug.h>
 #include <bedbug/regs.h>
 #include <bedbug/ppc.h>
-#include <elf.h>
 
-#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+DECLARE_GLOBAL_DATA_PTR;
 
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
+extern void show_regs __P ((struct pt_regs *));
+extern int run_command __P ((const char *, int));
 
-extern void show_regs __P((struct pt_regs*));
-extern int  run_command __P((const char*, int));
-extern char console_buffer[];
+ulong dis_last_addr = 0;       /* Last address disassembled   */
+ulong dis_last_len = 20;       /* Default disassembler length */
+CPU_DEBUG_CTX bug_ctx;         /* Bedbug context structure    */
 
-ulong        dis_last_addr = 0;        /* Last address disassembled   */
-ulong        dis_last_len = 20;        /* Default disassembler length */
-CPU_DEBUG_CTX bug_ctx;                  /* Bedbug context structure    */
 
-\f
 /* ======================================================================
  * U-Boot's puts function does not append a newline, so the bedbug stuff
  * will use this for the output of the dis/assembler.
  * ====================================================================== */
 
-int bedbug_puts(const char *str)
+int bedbug_puts (const char *str)
 {
-  /* -------------------------------------------------- */
+       /* -------------------------------------------------- */
+
+       printf ("%s\r\n", str);
+       return 0;
+}                              /* bedbug_puts */
 
-  printf( "%s\r\n", str );
-  return 0;
-} /* bedbug_puts */
 
 
-\f
 /* ======================================================================
  * Initialize the bug_ctx structure used by the bedbug debugger.  This is
  * specific to the CPU since each has different debug registers and
  * settings.
  * ====================================================================== */
 
-void bedbug_init( void )
+void bedbug_init (void)
 {
-  /* -------------------------------------------------- */
+       /* -------------------------------------------------- */
 
 #if defined(CONFIG_4xx)
-  void bedbug405_init( void );
-  bedbug405_init();
-#elif defined(CONFIG_MPC860)
-  void bedbug860_init( void );
-  bedbug860_init();
+       void bedbug405_init (void);
+
+       bedbug405_init ();
+#elif defined(CONFIG_8xx)
+       void bedbug860_init (void);
+
+       bedbug860_init ();
 #endif
 
 #if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)
-  /* Processors that are 603e core based */
-  void bedbug603e_init( void );
+       /* Processors that are 603e core based */
+       void bedbug603e_init (void);
 
-  bedbug603e_init();
+       bedbug603e_init ();
 #endif
 
-  return;
-} /* bedbug_init */
+       return;
+}                              /* bedbug_init */
+
 
 
-\f
 /* ======================================================================
  * Entry point from the interpreter to the disassembler.  Repeated calls
  * will resume from the last disassembled address.
  * ====================================================================== */
-int do_bedbug_dis (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-  ulong        addr;   /* Address to start disassembly from    */
-  ulong        len;    /* # of instructions to disassemble     */
-  /* -------------------------------------------------- */
+       ulong addr;             /* Address to start disassembly from    */
+       ulong len;              /* # of instructions to disassemble     */
 
-  /* Setup to go from the last address if none is given */
-  addr = dis_last_addr;
-  len  = dis_last_len;
+       /* -------------------------------------------------- */
 
-  if (argc < 2)
-  {
-    printf ("Usage:\n%s\n", cmdtp->usage);
-    return 1;
-  }
+       /* Setup to go from the last address if none is given */
+       addr = dis_last_addr;
+       len = dis_last_len;
 
-  if(( flag & CMD_FLAG_REPEAT ) == 0 )
-  {
-    /* New command */
-    addr = simple_strtoul( argv[1], NULL, 16 );
+       if (argc < 2)
+               return CMD_RET_USAGE;
 
-    /* If an extra param is given then it is the length */
-    if( argc > 2 )
-      len = simple_strtoul( argv[2], NULL, 16 );
-  }
+       if ((flag & CMD_FLAG_REPEAT) == 0) {
+               /* New command */
+               addr = simple_strtoul (argv[1], NULL, 16);
 
-  /* Run the disassembler */
-  disppc( (unsigned char *)addr, 0, len, bedbug_puts, F_RADHEX );
+               /* If an extra param is given then it is the length */
+               if (argc > 2)
+                       len = simple_strtoul (argv[2], NULL, 16);
+       }
 
-  dis_last_addr = addr + (len * 4);
-  dis_last_len = len;
-  return 0;
-} /* do_bedbug_dis */
+       /* Run the disassembler */
+       disppc ((unsigned char *) addr, 0, len, bedbug_puts, F_RADHEX);
 
+       dis_last_addr = addr + (len * 4);
+       dis_last_len = len;
+       return 0;
+}                              /* do_bedbug_dis */
+
+U_BOOT_CMD (ds, 3, 1, do_bedbug_dis,
+           "disassemble memory",
+           "ds <address> [# instructions]");
 
-\f
 /* ======================================================================
  * Entry point from the interpreter to the assembler.  Assembles
  * instructions in consecutive memory locations until a '.' (period) is
  * entered on a line by itself.
  * ====================================================================== */
-int do_bedbug_asm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-  long         mem_addr;               /* Address to assemble into     */
-  unsigned long instr;                  /* Machine code for text        */
-  char         prompt[ 15 ];           /* Prompt string for user input */
-  int          asm_err;                /* Error code from the assembler*/
-  /* -------------------------------------------------- */
-   int          rcode = 0;
-
-  if (argc < 2)
-  {
-    printf ("Usage:\n%s\n", cmdtp->usage);
-    return 1;
-  }
-
-  printf( "\nEnter '.' when done\n" );
-  mem_addr = simple_strtoul( argv[ 1 ], NULL, 16 );
-
-  while( 1 )
-  {
-    putc( '\n' );
-    disppc( (unsigned char *)mem_addr, 0, 1, bedbug_puts, F_RADHEX );
-
-    sprintf( prompt, "%08lx:    ", mem_addr );
-    readline( prompt );
-
-    if( console_buffer[ 0 ] && strcmp( console_buffer, "." ))
-    {
-      if(( instr = asmppc( mem_addr, console_buffer, &asm_err )) != 0 )
-      {
-       *(unsigned long *)mem_addr = instr;
-       mem_addr += 4;
-      }
-      else
-      {
-       printf( "*** Error: %s ***\n", asm_error_str( asm_err ));
-        rcode = 1;
-      }
-    }
-    else
-    {
-      break;
-    }
-  }
-  return rcode;
-} /* do_bedbug_asm */
-
-
-\f
+       long mem_addr;          /* Address to assemble into     */
+       unsigned long instr;    /* Machine code for text        */
+       char prompt[15];        /* Prompt string for user input */
+       int asm_err;            /* Error code from the assembler */
+
+       /* -------------------------------------------------- */
+       int rcode = 0;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       printf ("\nEnter '.' when done\n");
+       mem_addr = simple_strtoul (argv[1], NULL, 16);
+
+       while (1) {
+               putc ('\n');
+               disppc ((unsigned char *) mem_addr, 0, 1, bedbug_puts,
+                       F_RADHEX);
+
+               sprintf (prompt, "%08lx:    ", mem_addr);
+               cli_readline(prompt);
+
+               if (console_buffer[0] && strcmp (console_buffer, ".")) {
+                       if ((instr =
+                            asmppc (mem_addr, console_buffer,
+                                    &asm_err)) != 0) {
+                               *(unsigned long *) mem_addr = instr;
+                               mem_addr += 4;
+                       } else {
+                               printf ("*** Error: %s ***\n",
+                                       asm_error_str (asm_err));
+                               rcode = 1;
+                       }
+               } else {
+                       break;
+               }
+       }
+       return rcode;
+}                              /* do_bedbug_asm */
+
+U_BOOT_CMD (as, 2, 0, do_bedbug_asm,
+           "assemble memory", "as <address>");
+
 /* ======================================================================
  * Used to set a break point from the interpreter.  Simply calls into the
  * CPU-specific break point set routine.
  * ====================================================================== */
 
-int do_bedbug_break (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-  /* -------------------------------------------------- */
-  if( bug_ctx.do_break )
-    (*bug_ctx.do_break)( cmdtp, flag, argc, argv );
-    return 0;
+       /* -------------------------------------------------- */
+       if (bug_ctx.do_break)
+               (*bug_ctx.do_break) (cmdtp, flag, argc, argv);
+       return 0;
 
-} /* do_bedbug_break */
+}                              /* do_bedbug_break */
 
+U_BOOT_CMD (break, 3, 0, do_bedbug_break,
+           "set or clear a breakpoint",
+           " - Set or clear a breakpoint\n"
+           "break <address> - Break at an address\n"
+           "break off <bp#> - Disable breakpoint.\n"
+           "break show      - List breakpoints.");
 
-\f
 /* ======================================================================
  * Called from the debug interrupt routine.  Simply calls the CPU-specific
  * breakpoint handling routine.
@@ -190,16 +186,16 @@ int do_bedbug_break (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
 void do_bedbug_breakpoint (struct pt_regs *regs)
 {
-  /* -------------------------------------------------- */
+       /* -------------------------------------------------- */
+
+       if (bug_ctx.break_isr)
+               (*bug_ctx.break_isr) (regs);
 
-  if( bug_ctx.break_isr )
-    (*bug_ctx.break_isr)( regs );
+       return;
+}                              /* do_bedbug_breakpoint */
 
-  return;
-} /* do_bedbug_breakpoint */
 
 
-\f
 /* ======================================================================
  * Called from the CPU-specific breakpoint handling routine.  Enter a
  * mini main loop until the stopped flag is cleared from the breakpoint
@@ -208,204 +204,205 @@ void do_bedbug_breakpoint (struct pt_regs *regs)
  * This handles the parts of the debugger that are common to all CPU's.
  * ====================================================================== */
 
-void bedbug_main_loop( unsigned long addr, struct pt_regs *regs )
+void bedbug_main_loop (unsigned long addr, struct pt_regs *regs)
 {
-  int          len;                    /* Length of command line */
-  int           flag;                   /* Command flags          */
-  int           rc = 0;                 /* Result from run_command*/
-  char          prompt_str[ 20 ];       /* Prompt string          */
-  static char   lastcommand[ CFG_CBSIZE ] = {0}; /* previous command */
-  /* -------------------------------------------------- */
+       int len;                /* Length of command line */
+       int flag;               /* Command flags          */
+       int rc = 0;             /* Result from run_command */
+       char prompt_str[20];    /* Prompt string          */
+       static char lastcommand[CONFIG_SYS_CBSIZE] = { 0 };     /* previous command */
+       /* -------------------------------------------------- */
 
-  if( bug_ctx.clear )
-    (*bug_ctx.clear)( bug_ctx.current_bp );
+       if (bug_ctx.clear)
+               (*bug_ctx.clear) (bug_ctx.current_bp);
 
-  printf( "Breakpoint %d: ", bug_ctx.current_bp );
-  disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX );
+       printf ("Breakpoint %d: ", bug_ctx.current_bp);
+       disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX);
 
-  bug_ctx.stopped = 1;
-  bug_ctx.regs = regs;
+       bug_ctx.stopped = 1;
+       bug_ctx.regs = regs;
 
-  sprintf( prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp );
+       sprintf (prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp);
 
-  /* A miniature main loop */
-  while( bug_ctx.stopped )
-  {
-    len = readline( prompt_str );
+       /* A miniature main loop */
+       while (bug_ctx.stopped) {
+               len = cli_readline(prompt_str);
 
-    flag = 0;  /* assume no special flags for now */
+               flag = 0;       /* assume no special flags for now */
 
-    if (len > 0)
-      strcpy( lastcommand, console_buffer );
-    else if( len == 0 )
-      flag |= CMD_FLAG_REPEAT;
+               if (len > 0)
+                       strcpy (lastcommand, console_buffer);
+               else if (len == 0)
+                       flag |= CMD_FLAG_REPEAT;
 
-    if (len == -1)
-      printf ("<INTERRUPT>\n");
-    else
-      rc = run_command( lastcommand, flag );
+               if (len == -1)
+                       printf ("<INTERRUPT>\n");
+               else
+                       rc = run_command_repeatable(lastcommand, flag);
 
-    if (rc <= 0) {
-      /* invalid command or not repeatable, forget it */
-      lastcommand[0] = 0;
-    }
-  }
+               if (rc <= 0) {
+                       /* invalid command or not repeatable, forget it */
+                       lastcommand[0] = 0;
+               }
+       }
 
-  bug_ctx.regs = NULL;
-  bug_ctx.current_bp = 0;
+       bug_ctx.regs = NULL;
+       bug_ctx.current_bp = 0;
+
+       return;
+}                              /* bedbug_main_loop */
 
-  return;
-} /* bedbug_main_loop */
 
 
-\f
 /* ======================================================================
  * Interpreter command to continue from a breakpoint.  Just clears the
  * stopped flag in the context so that the breakpoint routine will
  * return.
  * ====================================================================== */
-int do_bedbug_continue (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-
+int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-  /* -------------------------------------------------- */
+       /* -------------------------------------------------- */
 
-  if( ! bug_ctx.stopped )
-  {
-    printf( "Not at a breakpoint\n" );
-    return 1;
-  }
+       if (!bug_ctx.stopped) {
+               printf ("Not at a breakpoint\n");
+               return 1;
+       }
 
-  bug_ctx.stopped = 0;
-  return 0;
-} /* do_bedbug_continue */
+       bug_ctx.stopped = 0;
+       return 0;
+}                              /* do_bedbug_continue */
 
+U_BOOT_CMD (continue, 1, 0, do_bedbug_continue,
+           "continue from a breakpoint",
+           "");
 
-\f
 /* ======================================================================
  * Interpreter command to continue to the next instruction, stepping into
  * subroutines.  Works by calling the find_next_addr() routine to compute
  * the address passes control to the CPU-specific set breakpoint routine
  * for the current breakpoint number.
  * ====================================================================== */
-int do_bedbug_step (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-  unsigned long addr;   /* Address to stop at */
-  /* -------------------------------------------------- */
+       unsigned long addr;     /* Address to stop at */
+
+       /* -------------------------------------------------- */
 
-  if( ! bug_ctx.stopped )
-  {
-    printf( "Not at a breakpoint\n" );
-    return 1;
-  }
+       if (!bug_ctx.stopped) {
+               printf ("Not at a breakpoint\n");
+               return 1;
+       }
 
-  if( !find_next_address( (unsigned char *)&addr, FALSE, bug_ctx.regs ))
-    return 1;
+       if (!find_next_address((unsigned char *) &addr, false, bug_ctx.regs))
+               return 1;
 
-  if( bug_ctx.set )
-    (*bug_ctx.set)( bug_ctx.current_bp, addr );
+       if (bug_ctx.set)
+               (*bug_ctx.set) (bug_ctx.current_bp, addr);
 
-  bug_ctx.stopped = 0;
-  return 0;
-} /* do_bedbug_step */
+       bug_ctx.stopped = 0;
+       return 0;
+}                              /* do_bedbug_step */
 
+U_BOOT_CMD (step, 1, 1, do_bedbug_step,
+           "single step execution.",
+           "");
 
-\f
 /* ======================================================================
  * Interpreter command to continue to the next instruction, stepping over
  * subroutines.  Works by calling the find_next_addr() routine to compute
  * the address passes control to the CPU-specific set breakpoint routine
  * for the current breakpoint number.
  * ====================================================================== */
-int do_bedbug_next (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-  unsigned long addr;   /* Address to stop at */
-  /* -------------------------------------------------- */
+       unsigned long addr;     /* Address to stop at */
 
-  if( ! bug_ctx.stopped )
-  {
-    printf( "Not at a breakpoint\n" );
-    return 1;
-  }
+       /* -------------------------------------------------- */
 
-  if( !find_next_address( (unsigned char *)&addr, TRUE, bug_ctx.regs ))
-    return 1;
+       if (!bug_ctx.stopped) {
+               printf ("Not at a breakpoint\n");
+               return 1;
+       }
 
-  if( bug_ctx.set )
-    (*bug_ctx.set)( bug_ctx.current_bp, addr );
+       if (!find_next_address((unsigned char *) &addr, true, bug_ctx.regs))
+               return 1;
 
-  bug_ctx.stopped = 0;
-  return 0;
-} /* do_bedbug_next */
+       if (bug_ctx.set)
+               (*bug_ctx.set) (bug_ctx.current_bp, addr);
 
+       bug_ctx.stopped = 0;
+       return 0;
+}                              /* do_bedbug_next */
+
+U_BOOT_CMD (next, 1, 1, do_bedbug_next,
+           "single step execution, stepping over subroutines.",
+           "");
 
-\f
 /* ======================================================================
  * Interpreter command to print the current stack.  This assumes an EABI
  * architecture, so it starts with GPR R1 and works back up the stack.
  * ====================================================================== */
-int do_bedbug_stack (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-       DECLARE_GLOBAL_DATA_PTR;
-
-  unsigned long sp;             /* Stack pointer                */
-  unsigned long func;           /* LR from stack                */
-  int           depth;          /* Stack iteration level        */
-  int           skip = 1;       /* Flag to skip the first entry */
-  unsigned long top;            /* Top of memory address        */
-  /* -------------------------------------------------- */
-
-  if( ! bug_ctx.stopped )
-  {
-    printf( "Not at a breakpoint\n" );
-    return 1;
-  }
-
-  top = gd->bd->bi_memstart + gd->bd->bi_memsize;
-  depth = 0;
-
-  printf( "Depth     PC\n" );
-  printf( "-----  --------\n" );
-  printf( "%5d  %08lx\n", depth++, bug_ctx.regs->nip );
-
-  sp = bug_ctx.regs->gpr[ 1 ];
-  func = *(unsigned long *)(sp+4);
-
-  while(( func < top ) && ( sp < top ))
-  {
-    if( !skip )
-      printf( "%5d  %08lx\n", depth++, func );
-    else
-      --skip;
-
-    sp = *(unsigned long *)sp;
-    func = *(unsigned long *)(sp+4);
-  }
-  return 0;
-} /* do_bedbug_stack */
-
-
-\f
+       unsigned long sp;       /* Stack pointer                */
+       unsigned long func;     /* LR from stack                */
+       int depth;              /* Stack iteration level        */
+       int skip = 1;           /* Flag to skip the first entry */
+       unsigned long top;      /* Top of memory address        */
+
+       /* -------------------------------------------------- */
+
+       if (!bug_ctx.stopped) {
+               printf ("Not at a breakpoint\n");
+               return 1;
+       }
+
+       top = gd->bd->bi_memstart + gd->bd->bi_memsize;
+       depth = 0;
+
+       printf ("Depth     PC\n");
+       printf ("-----  --------\n");
+       printf ("%5d  %08lx\n", depth++, bug_ctx.regs->nip);
+
+       sp = bug_ctx.regs->gpr[1];
+       func = *(unsigned long *) (sp + 4);
+
+       while ((func < top) && (sp < top)) {
+               if (!skip)
+                       printf ("%5d  %08lx\n", depth++, func);
+               else
+                       --skip;
+
+               sp = *(unsigned long *) sp;
+               func = *(unsigned long *) (sp + 4);
+       }
+       return 0;
+}                              /* do_bedbug_stack */
+
+U_BOOT_CMD (where, 1, 1, do_bedbug_stack,
+           "Print the running stack.",
+           "");
+
 /* ======================================================================
  * Interpreter command to dump the registers.  Calls the CPU-specific
  * show registers routine.
  * ====================================================================== */
-int do_bedbug_rdump (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-  /* -------------------------------------------------- */
-
-  if( ! bug_ctx.stopped )
-  {
-    printf( "Not at a breakpoint\n" );
-    return 1;
-  }
+       /* -------------------------------------------------- */
 
-  show_regs( bug_ctx.regs );
-  return 0;
-} /* do_bedbug_rdump */
+       if (!bug_ctx.stopped) {
+               printf ("Not at a breakpoint\n");
+               return 1;
+       }
 
+       show_regs (bug_ctx.regs);
+       return 0;
+}                              /* do_bedbug_rdump */
 
+U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump,
+           "Show registers.", "");
 /* ====================================================================== */
-#endif /* CFG_CMD_BEDBUG */
 
 
 /*