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