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