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