uboot/cmd/bedbug.c
<<
>>
Prefs
   1/*
   2 * BedBug Functions
   3 */
   4
   5#include <common.h>
   6#include <cli.h>
   7#include <command.h>
   8#include <console.h>
   9#include <linux/ctype.h>
  10#include <net.h>
  11#include <bedbug/type.h>
  12#include <bedbug/bedbug.h>
  13#include <bedbug/regs.h>
  14#include <bedbug/ppc.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18extern void show_regs __P ((struct pt_regs *));
  19extern int run_command __P ((const char *, int));
  20
  21ulong dis_last_addr = 0;        /* Last address disassembled   */
  22ulong dis_last_len = 20;        /* Default disassembler length */
  23CPU_DEBUG_CTX bug_ctx;          /* Bedbug context structure    */
  24
  25
  26/* ======================================================================
  27 * U-Boot's puts function does not append a newline, so the bedbug stuff
  28 * will use this for the output of the dis/assembler.
  29 * ====================================================================== */
  30
  31int bedbug_puts (const char *str)
  32{
  33        /* -------------------------------------------------- */
  34
  35        printf ("%s\r\n", str);
  36        return 0;
  37}                               /* bedbug_puts */
  38
  39
  40
  41/* ======================================================================
  42 * Initialize the bug_ctx structure used by the bedbug debugger.  This is
  43 * specific to the CPU since each has different debug registers and
  44 * settings.
  45 * ====================================================================== */
  46
  47void bedbug_init (void)
  48{
  49        /* -------------------------------------------------- */
  50
  51#if defined(CONFIG_4xx)
  52        void bedbug405_init (void);
  53
  54        bedbug405_init ();
  55#elif defined(CONFIG_8xx)
  56        void bedbug860_init (void);
  57
  58        bedbug860_init ();
  59#endif
  60
  61#if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)
  62        /* Processors that are 603e core based */
  63        void bedbug603e_init (void);
  64
  65        bedbug603e_init ();
  66#endif
  67
  68        return;
  69}                               /* bedbug_init */
  70
  71
  72
  73/* ======================================================================
  74 * Entry point from the interpreter to the disassembler.  Repeated calls
  75 * will resume from the last disassembled address.
  76 * ====================================================================== */
  77int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  78{
  79        ulong addr;             /* Address to start disassembly from    */
  80        ulong len;              /* # of instructions to disassemble     */
  81
  82        /* -------------------------------------------------- */
  83
  84        /* Setup to go from the last address if none is given */
  85        addr = dis_last_addr;
  86        len = dis_last_len;
  87
  88        if (argc < 2)
  89                return CMD_RET_USAGE;
  90
  91        if ((flag & CMD_FLAG_REPEAT) == 0) {
  92                /* New command */
  93                addr = simple_strtoul (argv[1], NULL, 16);
  94
  95                /* If an extra param is given then it is the length */
  96                if (argc > 2)
  97                        len = simple_strtoul (argv[2], NULL, 16);
  98        }
  99
 100        /* Run the disassembler */
 101        disppc ((unsigned char *) addr, 0, len, bedbug_puts, F_RADHEX);
 102
 103        dis_last_addr = addr + (len * 4);
 104        dis_last_len = len;
 105        return 0;
 106}                               /* do_bedbug_dis */
 107
 108U_BOOT_CMD (ds, 3, 1, do_bedbug_dis,
 109            "disassemble memory",
 110            "ds <address> [# instructions]");
 111
 112/* ======================================================================
 113 * Entry point from the interpreter to the assembler.  Assembles
 114 * instructions in consecutive memory locations until a '.' (period) is
 115 * entered on a line by itself.
 116 * ====================================================================== */
 117int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 118{
 119        long mem_addr;          /* Address to assemble into     */
 120        unsigned long instr;    /* Machine code for text        */
 121        char prompt[15];        /* Prompt string for user input */
 122        int asm_err;            /* Error code from the assembler */
 123
 124        /* -------------------------------------------------- */
 125        int rcode = 0;
 126
 127        if (argc < 2)
 128                return CMD_RET_USAGE;
 129
 130        printf ("\nEnter '.' when done\n");
 131        mem_addr = simple_strtoul (argv[1], NULL, 16);
 132
 133        while (1) {
 134                putc ('\n');
 135                disppc ((unsigned char *) mem_addr, 0, 1, bedbug_puts,
 136                        F_RADHEX);
 137
 138                sprintf (prompt, "%08lx:    ", mem_addr);
 139                cli_readline(prompt);
 140
 141                if (console_buffer[0] && strcmp (console_buffer, ".")) {
 142                        if ((instr =
 143                             asmppc (mem_addr, console_buffer,
 144                                     &asm_err)) != 0) {
 145                                *(unsigned long *) mem_addr = instr;
 146                                mem_addr += 4;
 147                        } else {
 148                                printf ("*** Error: %s ***\n",
 149                                        asm_error_str (asm_err));
 150                                rcode = 1;
 151                        }
 152                } else {
 153                        break;
 154                }
 155        }
 156        return rcode;
 157}                               /* do_bedbug_asm */
 158
 159U_BOOT_CMD (as, 2, 0, do_bedbug_asm,
 160            "assemble memory", "as <address>");
 161
 162/* ======================================================================
 163 * Used to set a break point from the interpreter.  Simply calls into the
 164 * CPU-specific break point set routine.
 165 * ====================================================================== */
 166
 167int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 168{
 169        /* -------------------------------------------------- */
 170        if (bug_ctx.do_break)
 171                (*bug_ctx.do_break) (cmdtp, flag, argc, argv);
 172        return 0;
 173
 174}                               /* do_bedbug_break */
 175
 176U_BOOT_CMD (break, 3, 0, do_bedbug_break,
 177            "set or clear a breakpoint",
 178            " - Set or clear a breakpoint\n"
 179            "break <address> - Break at an address\n"
 180            "break off <bp#> - Disable breakpoint.\n"
 181            "break show      - List breakpoints.");
 182
 183/* ======================================================================
 184 * Called from the debug interrupt routine.  Simply calls the CPU-specific
 185 * breakpoint handling routine.
 186 * ====================================================================== */
 187
 188void do_bedbug_breakpoint (struct pt_regs *regs)
 189{
 190        /* -------------------------------------------------- */
 191
 192        if (bug_ctx.break_isr)
 193                (*bug_ctx.break_isr) (regs);
 194
 195        return;
 196}                               /* do_bedbug_breakpoint */
 197
 198
 199
 200/* ======================================================================
 201 * Called from the CPU-specific breakpoint handling routine.  Enter a
 202 * mini main loop until the stopped flag is cleared from the breakpoint
 203 * context.
 204 *
 205 * This handles the parts of the debugger that are common to all CPU's.
 206 * ====================================================================== */
 207
 208void bedbug_main_loop (unsigned long addr, struct pt_regs *regs)
 209{
 210        int len;                /* Length of command line */
 211        int flag;               /* Command flags          */
 212        int rc = 0;             /* Result from run_command */
 213        char prompt_str[20];    /* Prompt string          */
 214        static char lastcommand[CONFIG_SYS_CBSIZE] = { 0 };     /* previous command */
 215        /* -------------------------------------------------- */
 216
 217        if (bug_ctx.clear)
 218                (*bug_ctx.clear) (bug_ctx.current_bp);
 219
 220        printf ("Breakpoint %d: ", bug_ctx.current_bp);
 221        disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX);
 222
 223        bug_ctx.stopped = 1;
 224        bug_ctx.regs = regs;
 225
 226        sprintf (prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp);
 227
 228        /* A miniature main loop */
 229        while (bug_ctx.stopped) {
 230                len = cli_readline(prompt_str);
 231
 232                flag = 0;       /* assume no special flags for now */
 233
 234                if (len > 0)
 235                        strcpy (lastcommand, console_buffer);
 236                else if (len == 0)
 237                        flag |= CMD_FLAG_REPEAT;
 238
 239                if (len == -1)
 240                        printf ("<INTERRUPT>\n");
 241                else
 242                        rc = run_command_repeatable(lastcommand, flag);
 243
 244                if (rc <= 0) {
 245                        /* invalid command or not repeatable, forget it */
 246                        lastcommand[0] = 0;
 247                }
 248        }
 249
 250        bug_ctx.regs = NULL;
 251        bug_ctx.current_bp = 0;
 252
 253        return;
 254}                               /* bedbug_main_loop */
 255
 256
 257
 258/* ======================================================================
 259 * Interpreter command to continue from a breakpoint.  Just clears the
 260 * stopped flag in the context so that the breakpoint routine will
 261 * return.
 262 * ====================================================================== */
 263int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 264{
 265        /* -------------------------------------------------- */
 266
 267        if (!bug_ctx.stopped) {
 268                printf ("Not at a breakpoint\n");
 269                return 1;
 270        }
 271
 272        bug_ctx.stopped = 0;
 273        return 0;
 274}                               /* do_bedbug_continue */
 275
 276U_BOOT_CMD (continue, 1, 0, do_bedbug_continue,
 277            "continue from a breakpoint",
 278            "");
 279
 280/* ======================================================================
 281 * Interpreter command to continue to the next instruction, stepping into
 282 * subroutines.  Works by calling the find_next_addr() routine to compute
 283 * the address passes control to the CPU-specific set breakpoint routine
 284 * for the current breakpoint number.
 285 * ====================================================================== */
 286int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 287{
 288        unsigned long addr;     /* Address to stop at */
 289
 290        /* -------------------------------------------------- */
 291
 292        if (!bug_ctx.stopped) {
 293                printf ("Not at a breakpoint\n");
 294                return 1;
 295        }
 296
 297        if (!find_next_address((unsigned char *) &addr, false, bug_ctx.regs))
 298                return 1;
 299
 300        if (bug_ctx.set)
 301                (*bug_ctx.set) (bug_ctx.current_bp, addr);
 302
 303        bug_ctx.stopped = 0;
 304        return 0;
 305}                               /* do_bedbug_step */
 306
 307U_BOOT_CMD (step, 1, 1, do_bedbug_step,
 308            "single step execution.",
 309            "");
 310
 311/* ======================================================================
 312 * Interpreter command to continue to the next instruction, stepping over
 313 * subroutines.  Works by calling the find_next_addr() routine to compute
 314 * the address passes control to the CPU-specific set breakpoint routine
 315 * for the current breakpoint number.
 316 * ====================================================================== */
 317int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 318{
 319        unsigned long addr;     /* Address to stop at */
 320
 321        /* -------------------------------------------------- */
 322
 323        if (!bug_ctx.stopped) {
 324                printf ("Not at a breakpoint\n");
 325                return 1;
 326        }
 327
 328        if (!find_next_address((unsigned char *) &addr, true, bug_ctx.regs))
 329                return 1;
 330
 331        if (bug_ctx.set)
 332                (*bug_ctx.set) (bug_ctx.current_bp, addr);
 333
 334        bug_ctx.stopped = 0;
 335        return 0;
 336}                               /* do_bedbug_next */
 337
 338U_BOOT_CMD (next, 1, 1, do_bedbug_next,
 339            "single step execution, stepping over subroutines.",
 340            "");
 341
 342/* ======================================================================
 343 * Interpreter command to print the current stack.  This assumes an EABI
 344 * architecture, so it starts with GPR R1 and works back up the stack.
 345 * ====================================================================== */
 346int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 347{
 348        unsigned long sp;       /* Stack pointer                */
 349        unsigned long func;     /* LR from stack                */
 350        int depth;              /* Stack iteration level        */
 351        int skip = 1;           /* Flag to skip the first entry */
 352        unsigned long top;      /* Top of memory address        */
 353
 354        /* -------------------------------------------------- */
 355
 356        if (!bug_ctx.stopped) {
 357                printf ("Not at a breakpoint\n");
 358                return 1;
 359        }
 360
 361        top = gd->bd->bi_memstart + gd->bd->bi_memsize;
 362        depth = 0;
 363
 364        printf ("Depth     PC\n");
 365        printf ("-----  --------\n");
 366        printf ("%5d  %08lx\n", depth++, bug_ctx.regs->nip);
 367
 368        sp = bug_ctx.regs->gpr[1];
 369        func = *(unsigned long *) (sp + 4);
 370
 371        while ((func < top) && (sp < top)) {
 372                if (!skip)
 373                        printf ("%5d  %08lx\n", depth++, func);
 374                else
 375                        --skip;
 376
 377                sp = *(unsigned long *) sp;
 378                func = *(unsigned long *) (sp + 4);
 379        }
 380        return 0;
 381}                               /* do_bedbug_stack */
 382
 383U_BOOT_CMD (where, 1, 1, do_bedbug_stack,
 384            "Print the running stack.",
 385            "");
 386
 387/* ======================================================================
 388 * Interpreter command to dump the registers.  Calls the CPU-specific
 389 * show registers routine.
 390 * ====================================================================== */
 391int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 392{
 393        /* -------------------------------------------------- */
 394
 395        if (!bug_ctx.stopped) {
 396                printf ("Not at a breakpoint\n");
 397                return 1;
 398        }
 399
 400        show_regs (bug_ctx.regs);
 401        return 0;
 402}                               /* do_bedbug_rdump */
 403
 404U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump,
 405            "Show registers.", "");
 406/* ====================================================================== */
 407
 408
 409/*
 410 * Copyright (c) 2001 William L. Pitts
 411 * All rights reserved.
 412 *
 413 * Redistribution and use in source and binary forms are freely
 414 * permitted provided that the above copyright notice and this
 415 * paragraph and the following disclaimer are duplicated in all
 416 * such forms.
 417 *
 418 * This software is provided "AS IS" and without any express or
 419 * implied warranties, including, without limitation, the implied
 420 * warranties of merchantability and fitness for a particular
 421 * purpose.
 422 */
 423