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