Blame view

common/cmd_bedbug.c 12 KB
47d1a6e1e   wdenk   Initial revision
1
2
3
4
5
6
7
8
  /*
   * BedBug Functions
   */
  
  #include <common.h>
  #include <command.h>
  #include <linux/ctype.h>
  #include <net.h>
8bde7f776   wdenk   * Code cleanup:
9
  #include <bedbug/type.h>
47d1a6e1e   wdenk   Initial revision
10
11
12
  #include <bedbug/bedbug.h>
  #include <bedbug/regs.h>
  #include <bedbug/ppc.h>
47d1a6e1e   wdenk   Initial revision
13

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
14
  DECLARE_GLOBAL_DATA_PTR;
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
15
16
  extern void show_regs __P ((struct pt_regs *));
  extern int run_command __P ((const char *, int));
47d1a6e1e   wdenk   Initial revision
17

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
18
19
20
  ulong dis_last_addr = 0;	/* Last address disassembled   */
  ulong dis_last_len = 20;	/* Default disassembler length */
  CPU_DEBUG_CTX bug_ctx;		/* Bedbug context structure    */
47d1a6e1e   wdenk   Initial revision
21
  
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
22

47d1a6e1e   wdenk   Initial revision
23
24
25
26
  /* ======================================================================
   * U-Boot's puts function does not append a newline, so the bedbug stuff
   * will use this for the output of the dis/assembler.
   * ====================================================================== */
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
27
  int bedbug_puts (const char *str)
47d1a6e1e   wdenk   Initial revision
28
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
29
  	/* -------------------------------------------------- */
47d1a6e1e   wdenk   Initial revision
30

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
31
32
33
34
35
  	printf ("%s\r
  ", str);
  	return 0;
  }				/* bedbug_puts */
  
47d1a6e1e   wdenk   Initial revision
36

47d1a6e1e   wdenk   Initial revision
37
38
39
40
41
  /* ======================================================================
   * Initialize the bug_ctx structure used by the bedbug debugger.  This is
   * specific to the CPU since each has different debug registers and
   * settings.
   * ====================================================================== */
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
42
  void bedbug_init (void)
47d1a6e1e   wdenk   Initial revision
43
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
44
  	/* -------------------------------------------------- */
47d1a6e1e   wdenk   Initial revision
45
46
  
  #if defined(CONFIG_4xx)
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
47
48
49
  	void bedbug405_init (void);
  
  	bedbug405_init ();
d126bfbdb   wdenk   Add support for T...
50
  #elif defined(CONFIG_8xx)
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
51
52
53
  	void bedbug860_init (void);
  
  	bedbug860_init ();
47d1a6e1e   wdenk   Initial revision
54
55
56
  #endif
  
  #if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
57
58
  	/* Processors that are 603e core based */
  	void bedbug603e_init (void);
47d1a6e1e   wdenk   Initial revision
59

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
60
  	bedbug603e_init ();
47d1a6e1e   wdenk   Initial revision
61
  #endif
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
62
63
64
  	return;
  }				/* bedbug_init */
  
47d1a6e1e   wdenk   Initial revision
65

47d1a6e1e   wdenk   Initial revision
66
67
68
69
  /* ======================================================================
   * Entry point from the interpreter to the disassembler.  Repeated calls
   * will resume from the last disassembled address.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
70
  int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
71
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
72
73
74
75
76
77
78
79
  	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;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
80
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
81
  		return CMD_RET_USAGE;
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  
  	if ((flag & CMD_FLAG_REPEAT) == 0) {
  		/* New command */
  		addr = simple_strtoul (argv[1], NULL, 16);
  
  		/* If an extra param is given then it is the length */
  		if (argc > 2)
  			len = simple_strtoul (argv[2], NULL, 16);
  	}
  
  	/* 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,
2fb2604d5   Peter Tyser   Command usage cle...
101
  	    "disassemble memory",
a89c33db9   Wolfgang Denk   General help mess...
102
  	    "ds <address> [# instructions]");
47d1a6e1e   wdenk   Initial revision
103
104
105
106
107
108
  
  /* ======================================================================
   * Entry point from the interpreter to the assembler.  Assembles
   * instructions in consecutive memory locations until a '.' (period) is
   * entered on a line by itself.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
109
  int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
110
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
111
112
113
114
115
116
117
  	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;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
118
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
119
  		return CMD_RET_USAGE;
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  
  	printf ("
  Enter '.' when done
  ");
  	mem_addr = simple_strtoul (argv[1], NULL, 16);
  
  	while (1) {
  		putc ('
  ');
  		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 ***
  ",
  					asm_error_str (asm_err));
  				rcode = 1;
  			}
  		} else {
  			break;
  		}
  	}
  	return rcode;
  }				/* do_bedbug_asm */
  
  U_BOOT_CMD (as, 2, 0, do_bedbug_asm,
a89c33db9   Wolfgang Denk   General help mess...
155
  	    "assemble memory", "as <address>");
47d1a6e1e   wdenk   Initial revision
156
157
158
159
160
  
  /* ======================================================================
   * Used to set a break point from the interpreter.  Simply calls into the
   * CPU-specific break point set routine.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
161
  int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
162
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
163
164
165
166
167
168
169
170
  	/* -------------------------------------------------- */
  	if (bug_ctx.do_break)
  		(*bug_ctx.do_break) (cmdtp, flag, argc, argv);
  	return 0;
  
  }				/* do_bedbug_break */
  
  U_BOOT_CMD (break, 3, 0, do_bedbug_break,
2fb2604d5   Peter Tyser   Command usage cle...
171
  	    "set or clear a breakpoint",
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
172
173
174
175
176
177
  	    " - Set or clear a breakpoint
  "
  	    "break <address> - Break at an address
  "
  	    "break off <bp#> - Disable breakpoint.
  "
a89c33db9   Wolfgang Denk   General help mess...
178
  	    "break show      - List breakpoints.");
47d1a6e1e   wdenk   Initial revision
179
180
181
182
183
184
185
186
  
  /* ======================================================================
   * Called from the debug interrupt routine.  Simply calls the CPU-specific
   * breakpoint handling routine.
   * ====================================================================== */
  
  void do_bedbug_breakpoint (struct pt_regs *regs)
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
187
  	/* -------------------------------------------------- */
47d1a6e1e   wdenk   Initial revision
188

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
189
190
  	if (bug_ctx.break_isr)
  		(*bug_ctx.break_isr) (regs);
47d1a6e1e   wdenk   Initial revision
191

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
192
193
194
  	return;
  }				/* do_bedbug_breakpoint */
  
47d1a6e1e   wdenk   Initial revision
195

47d1a6e1e   wdenk   Initial revision
196
197
198
199
200
201
202
  /* ======================================================================
   * Called from the CPU-specific breakpoint handling routine.  Enter a
   * mini main loop until the stopped flag is cleared from the breakpoint
   * context.
   *
   * This handles the parts of the debugger that are common to all CPU's.
   * ====================================================================== */
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
203
  void bedbug_main_loop (unsigned long addr, struct pt_regs *regs)
47d1a6e1e   wdenk   Initial revision
204
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
205
206
207
208
  	int len;		/* Length of command line */
  	int flag;		/* Command flags          */
  	int rc = 0;		/* Result from run_command */
  	char prompt_str[20];	/* Prompt string          */
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
209
  	static char lastcommand[CONFIG_SYS_CBSIZE] = { 0 };	/* previous command */
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
210
  	/* -------------------------------------------------- */
47d1a6e1e   wdenk   Initial revision
211

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
212
213
  	if (bug_ctx.clear)
  		(*bug_ctx.clear) (bug_ctx.current_bp);
47d1a6e1e   wdenk   Initial revision
214

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
215
216
  	printf ("Breakpoint %d: ", bug_ctx.current_bp);
  	disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX);
47d1a6e1e   wdenk   Initial revision
217

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
218
219
  	bug_ctx.stopped = 1;
  	bug_ctx.regs = regs;
47d1a6e1e   wdenk   Initial revision
220

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
221
  	sprintf (prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp);
47d1a6e1e   wdenk   Initial revision
222

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
223
224
225
  	/* A miniature main loop */
  	while (bug_ctx.stopped) {
  		len = readline (prompt_str);
47d1a6e1e   wdenk   Initial revision
226

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
227
  		flag = 0;	/* assume no special flags for now */
47d1a6e1e   wdenk   Initial revision
228

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
229
230
231
232
  		if (len > 0)
  			strcpy (lastcommand, console_buffer);
  		else if (len == 0)
  			flag |= CMD_FLAG_REPEAT;
47d1a6e1e   wdenk   Initial revision
233

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
234
235
236
237
  		if (len == -1)
  			printf ("<INTERRUPT>
  ");
  		else
530715323   Simon Glass   Stop using builti...
238
  			rc = run_command(lastcommand, flag);
47d1a6e1e   wdenk   Initial revision
239

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
240
241
242
243
244
  		if (rc <= 0) {
  			/* invalid command or not repeatable, forget it */
  			lastcommand[0] = 0;
  		}
  	}
47d1a6e1e   wdenk   Initial revision
245

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
246
247
  	bug_ctx.regs = NULL;
  	bug_ctx.current_bp = 0;
47d1a6e1e   wdenk   Initial revision
248

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
249
250
251
  	return;
  }				/* bedbug_main_loop */
  
47d1a6e1e   wdenk   Initial revision
252

47d1a6e1e   wdenk   Initial revision
253
254
255
256
257
  /* ======================================================================
   * Interpreter command to continue from a breakpoint.  Just clears the
   * stopped flag in the context so that the breakpoint routine will
   * return.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
258
  int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
259
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
260
261
262
263
264
265
266
267
268
269
270
271
272
  	/* -------------------------------------------------- */
  
  	if (!bug_ctx.stopped) {
  		printf ("Not at a breakpoint
  ");
  		return 1;
  	}
  
  	bug_ctx.stopped = 0;
  	return 0;
  }				/* do_bedbug_continue */
  
  U_BOOT_CMD (continue, 1, 0, do_bedbug_continue,
2fb2604d5   Peter Tyser   Command usage cle...
273
  	    "continue from a breakpoint",
a89c33db9   Wolfgang Denk   General help mess...
274
  	    "");
47d1a6e1e   wdenk   Initial revision
275
276
277
278
279
280
281
  
  /* ======================================================================
   * 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.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
282
  int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
283
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
284
285
286
287
288
289
290
291
292
  	unsigned long addr;	/* Address to stop at */
  
  	/* -------------------------------------------------- */
  
  	if (!bug_ctx.stopped) {
  		printf ("Not at a breakpoint
  ");
  		return 1;
  	}
472d54605   York Sun   Consolidate bool ...
293
  	if (!find_next_address((unsigned char *) &addr, false, bug_ctx.regs))
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
294
295
296
297
298
299
300
301
302
303
  		return 1;
  
  	if (bug_ctx.set)
  		(*bug_ctx.set) (bug_ctx.current_bp, addr);
  
  	bug_ctx.stopped = 0;
  	return 0;
  }				/* do_bedbug_step */
  
  U_BOOT_CMD (step, 1, 1, do_bedbug_step,
2fb2604d5   Peter Tyser   Command usage cle...
304
  	    "single step execution.",
a89c33db9   Wolfgang Denk   General help mess...
305
  	    "");
47d1a6e1e   wdenk   Initial revision
306
307
308
309
310
311
312
  
  /* ======================================================================
   * 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.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
313
  int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
314
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
315
316
317
318
319
320
321
322
323
  	unsigned long addr;	/* Address to stop at */
  
  	/* -------------------------------------------------- */
  
  	if (!bug_ctx.stopped) {
  		printf ("Not at a breakpoint
  ");
  		return 1;
  	}
472d54605   York Sun   Consolidate bool ...
324
  	if (!find_next_address((unsigned char *) &addr, true, bug_ctx.regs))
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
325
326
327
328
329
330
331
332
333
334
  		return 1;
  
  	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,
2fb2604d5   Peter Tyser   Command usage cle...
335
  	    "single step execution, stepping over subroutines.",
a89c33db9   Wolfgang Denk   General help mess...
336
  	    "");
47d1a6e1e   wdenk   Initial revision
337
338
339
340
341
  
  /* ======================================================================
   * Interpreter command to print the current stack.  This assumes an EABI
   * architecture, so it starts with GPR R1 and works back up the stack.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
342
  int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
343
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  	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
  ");
  		return 1;
  	}
  
  	top = gd->bd->bi_memstart + gd->bd->bi_memsize;
  	depth = 0;
  
  	printf ("Depth     PC
  ");
  	printf ("-----  --------
  ");
  	printf ("%5d  %08lx
  ", 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
  ", 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,
2fb2604d5   Peter Tyser   Command usage cle...
385
  	    "Print the running stack.",
a89c33db9   Wolfgang Denk   General help mess...
386
  	    "");
47d1a6e1e   wdenk   Initial revision
387
388
389
390
391
  
  /* ======================================================================
   * Interpreter command to dump the registers.  Calls the CPU-specific
   * show registers routine.
   * ====================================================================== */
54841ab50   Wolfgang Denk   Make sure that ar...
392
  int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
47d1a6e1e   wdenk   Initial revision
393
  {
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
394
395
396
397
398
399
400
401
402
403
404
405
406
  	/* -------------------------------------------------- */
  
  	if (!bug_ctx.stopped) {
  		printf ("Not at a breakpoint
  ");
  		return 1;
  	}
  
  	show_regs (bug_ctx.regs);
  	return 0;
  }				/* do_bedbug_rdump */
  
  U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump,
a89c33db9   Wolfgang Denk   General help mess...
407
  	    "Show registers.", "");
47d1a6e1e   wdenk   Initial revision
408
  /* ====================================================================== */
47d1a6e1e   wdenk   Initial revision
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  
  
  /*
   * Copyright (c) 2001 William L. Pitts
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms are freely
   * permitted provided that the above copyright notice and this
   * paragraph and the following disclaimer are duplicated in all
   * such forms.
   *
   * This software is provided "AS IS" and without any express or
   * implied warranties, including, without limitation, the implied
   * warranties of merchantability and fitness for a particular
   * purpose.
   */