]> git.ipfire.org Git - people/ms/u-boot.git/blob - common/cmd_bedbug.c
correct a syntax typo in at91_matrix.h
[people/ms/u-boot.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 extern void show_regs __P ((struct pt_regs *));
17 extern int run_command __P ((const char *, int));
18 extern char console_buffer[];
19
20 ulong dis_last_addr = 0; /* Last address disassembled */
21 ulong dis_last_len = 20; /* Default disassembler length */
22 CPU_DEBUG_CTX bug_ctx; /* Bedbug context structure */
23 \f
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
30 int bedbug_puts (const char *str)
31 {
32 /* -------------------------------------------------- */
33
34 printf ("%s\r\n", str);
35 return 0;
36 } /* bedbug_puts */
37 \f
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
46 void 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 \f
70
71
72 /* ======================================================================
73 * Entry point from the interpreter to the disassembler. Repeated calls
74 * will resume from the last disassembled address.
75 * ====================================================================== */
76 int 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
109 U_BOOT_CMD (ds, 3, 1, do_bedbug_dis,
110 "disassemble memory",
111 "ds <address> [# instructions]");
112 \f
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 * ====================================================================== */
118 int 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
162 U_BOOT_CMD (as, 2, 0, do_bedbug_asm,
163 "assemble memory", "as <address>");
164 \f
165 /* ======================================================================
166 * Used to set a break point from the interpreter. Simply calls into the
167 * CPU-specific break point set routine.
168 * ====================================================================== */
169
170 int 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
179 U_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 \f
186 /* ======================================================================
187 * Called from the debug interrupt routine. Simply calls the CPU-specific
188 * breakpoint handling routine.
189 * ====================================================================== */
190
191 void 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 \f
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
211 void 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 \f
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 * ====================================================================== */
266 int 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
279 U_BOOT_CMD (continue, 1, 0, do_bedbug_continue,
280 "continue from a breakpoint",
281 "");
282 \f
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 * ====================================================================== */
289 int 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
310 U_BOOT_CMD (step, 1, 1, do_bedbug_step,
311 "single step execution.",
312 "");
313 \f
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 * ====================================================================== */
320 int 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
341 U_BOOT_CMD (next, 1, 1, do_bedbug_next,
342 "single step execution, stepping over subroutines.",
343 "");
344 \f
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 * ====================================================================== */
349 int 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
386 U_BOOT_CMD (where, 1, 1, do_bedbug_stack,
387 "Print the running stack.",
388 "");
389 \f
390 /* ======================================================================
391 * Interpreter command to dump the registers. Calls the CPU-specific
392 * show registers routine.
393 * ====================================================================== */
394 int 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
407 U_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 */