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