2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/smp.h>
17 #include <linux/reboot.h>
18 #include <linux/delay.h>
19 #include <linux/kallsyms.h>
20 #include <linux/kmsg_dump.h>
21 #include <linux/cpumask.h>
22 #include <linux/export.h>
23 #include <linux/sysrq.h>
24 #include <linux/interrupt.h>
25 #include <linux/irq.h>
26 #include <linux/bug.h>
28 #include <asm/ptrace.h>
29 #include <asm/string.h>
31 #include <asm/machdep.h>
33 #include <asm/processor.h>
34 #include <asm/pgtable.h>
36 #include <asm/mmu_context.h>
37 #include <asm/cputable.h>
39 #include <asm/sstep.h>
40 #include <asm/irq_regs.h>
42 #include <asm/spu_priv1.h>
43 #include <asm/setjmp.h>
45 #include <asm/debug.h>
46 #include <asm/hw_breakpoint.h>
49 #include <asm/hvcall.h>
57 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
58 static unsigned long xmon_taken = 1;
59 static int xmon_owner;
63 #endif /* CONFIG_SMP */
65 static unsigned long in_xmon __read_mostly = 0;
67 static unsigned long adrs;
69 #define MAX_DUMP (128 * 1024)
70 static unsigned long ndump = 64;
71 static unsigned long nidump = 16;
72 static unsigned long ncsum = 4096;
74 static char tmpstr[128];
76 static long bus_error_jmp[JMP_BUF_LEN];
77 static int catch_memory_errors;
78 static long *xmon_fault_jmp[NR_CPUS];
80 /* Breakpoint stuff */
82 unsigned long address;
83 unsigned int instr[2];
89 /* Bits in bpt.enabled */
90 #define BP_IABR_TE 1 /* IABR translation enabled */
96 static struct bpt bpts[NBPTS];
97 static struct bpt dabr;
98 static struct bpt *iabr;
99 static unsigned bpinstr = 0x7fe00008; /* trap */
101 #define BP_NUM(bp) ((bp) - bpts + 1)
104 static int cmds(struct pt_regs *);
105 static int mread(unsigned long, void *, int);
106 static int mwrite(unsigned long, void *, int);
107 static int handle_fault(struct pt_regs *);
108 static void byterev(unsigned char *, int);
109 static void memex(void);
110 static int bsesc(void);
111 static void dump(void);
112 static void prdump(unsigned long, long);
113 static int ppc_inst_dump(unsigned long, long, int);
114 static void dump_log_buf(void);
115 static void backtrace(struct pt_regs *);
116 static void excprint(struct pt_regs *);
117 static void prregs(struct pt_regs *);
118 static void memops(int);
119 static void memlocate(void);
120 static void memzcan(void);
121 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
123 int scanhex(unsigned long *valp);
124 static void scannl(void);
125 static int hexdigit(int);
126 void getstring(char *, int);
127 static void flush_input(void);
128 static int inchar(void);
129 static void take_input(char *);
130 static unsigned long read_spr(int);
131 static void write_spr(int, unsigned long);
132 static void super_regs(void);
133 static void remove_bpts(void);
134 static void insert_bpts(void);
135 static void remove_cpu_bpts(void);
136 static void insert_cpu_bpts(void);
137 static struct bpt *at_breakpoint(unsigned long pc);
138 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
139 static int do_step(struct pt_regs *);
140 static void bpt_cmds(void);
141 static void cacheflush(void);
142 static int cpu_cmd(void);
143 static void csum(void);
144 static void bootcmds(void);
145 static void proccall(void);
146 void dump_segments(void);
147 static void symbol_lookup(void);
148 static void xmon_show_stack(unsigned long sp, unsigned long lr,
150 static void xmon_print_symbol(unsigned long address, const char *mid,
152 static const char *getvecname(unsigned long vec);
154 static int do_spu_cmd(void);
157 static void dump_tlb_44x(void);
159 #ifdef CONFIG_PPC_BOOK3E
160 static void dump_tlb_book3e(void);
163 static int xmon_no_auto_backtrace;
165 extern void xmon_enter(void);
166 extern void xmon_leave(void);
174 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
176 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
177 || ('a' <= (c) && (c) <= 'f') \
178 || ('A' <= (c) && (c) <= 'F'))
179 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
180 || ('a' <= (c) && (c) <= 'z') \
181 || ('A' <= (c) && (c) <= 'Z'))
182 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
184 static char *help_string = "\
186 b show breakpoints\n\
187 bd set data breakpoint\n\
188 bi set instruction breakpoint\n\
189 bc clear breakpoint\n"
192 c print cpus stopped in xmon\n\
193 c# try to switch to cpu number h (in hex)\n"
198 di dump instructions\n\
199 df dump float values\n\
200 dd dump double values\n\
201 dl dump the kernel log buffer\n"
204 dp[#] dump paca for current cpu, or cpu #\n\
205 dpa dump paca for all possible cpus\n"
208 dr dump stream of raw bytes\n\
209 e print exception information\n\
211 la lookup symbol+offset of specified address\n\
212 ls lookup address of specified symbol\n\
213 m examine/change memory\n\
214 mm move a block of memory\n\
215 ms set a block of memory\n\
216 md compare two blocks of memory\n\
217 ml locate a block of memory\n\
218 mz zero a block of memory\n\
219 mi show information about memory allocation\n\
220 p call a procedure\n\
223 #ifdef CONFIG_SPU_BASE
224 " ss stop execution on all spus\n\
225 sr restore execution on stopped spus\n\
226 sf # dump spu fields for spu # (in hex)\n\
227 sd # dump spu local store for spu # (in hex)\n\
228 sdi # disassemble spu local store for spu # (in hex)\n"
230 " S print special registers\n\
232 x exit monitor and recover\n\
233 X exit monitor and dont recover\n"
234 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
235 " u dump segment table or SLB\n"
236 #elif defined(CONFIG_PPC_STD_MMU_32)
237 " u dump segment registers\n"
238 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
246 static struct pt_regs *xmon_regs;
248 static inline void sync(void)
250 asm volatile("sync; isync");
253 static inline void store_inst(void *p)
255 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
258 static inline void cflush(void *p)
260 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
263 static inline void cinval(void *p)
265 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
269 * Disable surveillance (the service processor watchdog function)
270 * while we are in xmon.
271 * XXX we should re-enable it when we leave. :)
273 #define SURVEILLANCE_TOKEN 9000
275 static inline void disable_surveillance(void)
277 #ifdef CONFIG_PPC_PSERIES
278 /* Since this can't be a module, args should end up below 4GB. */
279 static struct rtas_args args;
282 * At this point we have got all the cpus we can into
283 * xmon, so there is hopefully no other cpu calling RTAS
284 * at the moment, even though we don't take rtas.lock.
285 * If we did try to take rtas.lock there would be a
286 * real possibility of deadlock.
288 args.token = rtas_token("set-indicator");
289 if (args.token == RTAS_UNKNOWN_SERVICE)
293 args.rets = &args.args[3];
294 args.args[0] = SURVEILLANCE_TOKEN;
297 enter_rtas(__pa(&args));
298 #endif /* CONFIG_PPC_PSERIES */
302 static int xmon_speaker;
304 static void get_output_lock(void)
306 int me = smp_processor_id() + 0x100;
307 int last_speaker = 0, prev;
310 if (xmon_speaker == me)
314 last_speaker = cmpxchg(&xmon_speaker, 0, me);
315 if (last_speaker == 0)
319 * Wait a full second for the lock, we might be on a slow
320 * console, but check every 100us.
323 while (xmon_speaker == last_speaker) {
329 /* hostile takeover */
330 prev = cmpxchg(&xmon_speaker, last_speaker, me);
331 if (prev == last_speaker)
338 static void release_output_lock(void)
343 int cpus_are_in_xmon(void)
345 return !cpumask_empty(&cpus_in_xmon);
349 static inline int unrecoverable_excp(struct pt_regs *regs)
351 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
352 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
355 return ((regs->msr & MSR_RI) == 0);
359 static int xmon_core(struct pt_regs *regs, int fromipi)
363 long recurse_jmp[JMP_BUF_LEN];
364 unsigned long offset;
369 unsigned long timeout;
372 local_irq_save(flags);
374 bp = in_breakpoint_table(regs->nip, &offset);
376 regs->nip = bp->address + offset;
377 atomic_dec(&bp->ref_count);
383 cpu = smp_processor_id();
384 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
387 printf("cpu 0x%x: Exception %lx %s in xmon, "
388 "returning to main loop\n",
389 cpu, regs->trap, getvecname(TRAP(regs)));
390 release_output_lock();
391 longjmp(xmon_fault_jmp[cpu], 1);
394 if (setjmp(recurse_jmp) != 0) {
395 if (!in_xmon || !xmon_gate) {
397 printf("xmon: WARNING: bad recursive fault "
398 "on cpu 0x%x\n", cpu);
399 release_output_lock();
402 secondary = !(xmon_taken && cpu == xmon_owner);
406 xmon_fault_jmp[cpu] = recurse_jmp;
409 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
410 bp = at_breakpoint(regs->nip);
411 if (bp || unrecoverable_excp(regs))
418 printf("cpu 0x%x stopped at breakpoint 0x%x (",
420 xmon_print_symbol(regs->nip, " ", ")\n");
422 if (unrecoverable_excp(regs))
423 printf("WARNING: exception is not recoverable, "
425 release_output_lock();
428 cpumask_set_cpu(cpu, &cpus_in_xmon);
432 while (secondary && !xmon_gate) {
436 secondary = test_and_set_bit(0, &in_xmon);
441 if (!secondary && !xmon_gate) {
442 /* we are the first cpu to come in */
443 /* interrupt other cpu(s) */
444 int ncpus = num_online_cpus();
449 smp_send_debugger_break();
450 /* wait for other cpus to come in */
451 for (timeout = 100000000; timeout != 0; --timeout) {
452 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
458 disable_surveillance();
459 /* for breakpoint or single step, print the current instr. */
460 if (bp || TRAP(regs) == 0xd00)
461 ppc_inst_dump(regs->nip, 1, 0);
462 printf("enter ? for help\n");
471 if (cpu == xmon_owner) {
472 if (!test_and_set_bit(0, &xmon_taken)) {
477 while (cpu == xmon_owner)
491 /* have switched to some other cpu */
496 cpumask_clear_cpu(cpu, &cpus_in_xmon);
497 xmon_fault_jmp[cpu] = NULL;
499 /* UP is simple... */
501 printf("Exception %lx %s in xmon, returning to main loop\n",
502 regs->trap, getvecname(TRAP(regs)));
503 longjmp(xmon_fault_jmp[0], 1);
505 if (setjmp(recurse_jmp) == 0) {
506 xmon_fault_jmp[0] = recurse_jmp;
510 bp = at_breakpoint(regs->nip);
512 printf("Stopped at breakpoint %x (", BP_NUM(bp));
513 xmon_print_symbol(regs->nip, " ", ")\n");
515 if (unrecoverable_excp(regs))
516 printf("WARNING: exception is not recoverable, "
519 disable_surveillance();
520 /* for breakpoint or single step, print the current instr. */
521 if (bp || TRAP(regs) == 0xd00)
522 ppc_inst_dump(regs->nip, 1, 0);
523 printf("enter ? for help\n");
533 if (regs->msr & MSR_DE) {
534 bp = at_breakpoint(regs->nip);
536 regs->nip = (unsigned long) &bp->instr[0];
537 atomic_inc(&bp->ref_count);
541 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
542 bp = at_breakpoint(regs->nip);
544 int stepped = emulate_step(regs, bp->instr[0]);
546 regs->nip = (unsigned long) &bp->instr[0];
547 atomic_inc(&bp->ref_count);
548 } else if (stepped < 0) {
549 printf("Couldn't single-step %s instruction\n",
550 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
557 local_irq_restore(flags);
559 return cmd != 'X' && cmd != EOF;
562 int xmon(struct pt_regs *excp)
567 ppc_save_regs(®s);
571 return xmon_core(excp, 0);
575 irqreturn_t xmon_irq(int irq, void *d)
578 local_irq_save(flags);
579 printf("Keyboard interrupt\n");
580 xmon(get_irq_regs());
581 local_irq_restore(flags);
585 static int xmon_bpt(struct pt_regs *regs)
588 unsigned long offset;
590 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
593 /* Are we at the trap at bp->instr[1] for some bp? */
594 bp = in_breakpoint_table(regs->nip, &offset);
595 if (bp != NULL && offset == 4) {
596 regs->nip = bp->address + 4;
597 atomic_dec(&bp->ref_count);
601 /* Are we at a breakpoint? */
602 bp = at_breakpoint(regs->nip);
611 static int xmon_sstep(struct pt_regs *regs)
619 static int xmon_break_match(struct pt_regs *regs)
621 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
623 if (dabr.enabled == 0)
629 static int xmon_iabr_match(struct pt_regs *regs)
631 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
639 static int xmon_ipi(struct pt_regs *regs)
642 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
648 static int xmon_fault_handler(struct pt_regs *regs)
651 unsigned long offset;
653 if (in_xmon && catch_memory_errors)
654 handle_fault(regs); /* doesn't return */
656 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
657 bp = in_breakpoint_table(regs->nip, &offset);
659 regs->nip = bp->address + offset;
660 atomic_dec(&bp->ref_count);
667 static struct bpt *at_breakpoint(unsigned long pc)
673 for (i = 0; i < NBPTS; ++i, ++bp)
674 if (bp->enabled && pc == bp->address)
679 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
683 off = nip - (unsigned long) bpts;
684 if (off >= sizeof(bpts))
686 off %= sizeof(struct bpt);
687 if (off != offsetof(struct bpt, instr[0])
688 && off != offsetof(struct bpt, instr[1]))
690 *offp = off - offsetof(struct bpt, instr[0]);
691 return (struct bpt *) (nip - off);
694 static struct bpt *new_breakpoint(unsigned long a)
699 bp = at_breakpoint(a);
703 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
704 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
706 bp->instr[1] = bpinstr;
707 store_inst(&bp->instr[1]);
712 printf("Sorry, no free breakpoints. Please clear one first.\n");
716 static void insert_bpts(void)
722 for (i = 0; i < NBPTS; ++i, ++bp) {
723 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
725 if (mread(bp->address, &bp->instr[0], 4) != 4) {
726 printf("Couldn't read instruction at %lx, "
727 "disabling breakpoint there\n", bp->address);
731 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
732 printf("Breakpoint at %lx is on an mtmsrd or rfid "
733 "instruction, disabling it\n", bp->address);
737 store_inst(&bp->instr[0]);
738 if (bp->enabled & BP_IABR)
740 if (mwrite(bp->address, &bpinstr, 4) != 4) {
741 printf("Couldn't write instruction at %lx, "
742 "disabling breakpoint there\n", bp->address);
743 bp->enabled &= ~BP_TRAP;
746 store_inst((void *)bp->address);
750 static void insert_cpu_bpts(void)
752 struct arch_hw_breakpoint brk;
755 brk.address = dabr.address;
756 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
758 set_breakpoint(&brk);
760 if (iabr && cpu_has_feature(CPU_FTR_IABR))
761 mtspr(SPRN_IABR, iabr->address
762 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
765 static void remove_bpts(void)
772 for (i = 0; i < NBPTS; ++i, ++bp) {
773 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
775 if (mread(bp->address, &instr, 4) == 4
777 && mwrite(bp->address, &bp->instr, 4) != 4)
778 printf("Couldn't remove breakpoint at %lx\n",
781 store_inst((void *)bp->address);
785 static void remove_cpu_bpts(void)
787 hw_breakpoint_disable();
788 if (cpu_has_feature(CPU_FTR_IABR))
792 /* Command interpreting routine */
793 static char *last_cmd;
796 cmds(struct pt_regs *excp)
803 if (!xmon_no_auto_backtrace) {
804 xmon_no_auto_backtrace = 1;
805 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
810 printf("%x:", smp_processor_id());
811 #endif /* CONFIG_SMP */
817 if (last_cmd == NULL)
819 take_input(last_cmd);
853 prregs(excp); /* print regs */
868 if (do_spu_cmd() == 0)
877 printf(" <no input ...>\n");
881 xmon_puts(help_string);
899 #ifdef CONFIG_PPC_STD_MMU
903 #elif defined(CONFIG_4xx)
907 #elif defined(CONFIG_PPC_BOOK3E)
913 printf("Unrecognized command: ");
915 if (' ' < cmd && cmd <= '~')
918 printf("\\x%x", cmd);
920 } while (cmd != '\n');
921 printf(" (type ? for help)\n");
928 static int do_step(struct pt_regs *regs)
931 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
936 * Step a single instruction.
937 * Some instructions we emulate, others we execute with MSR_SE set.
939 static int do_step(struct pt_regs *regs)
944 /* check we are in 64-bit kernel mode, translation enabled */
945 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
946 if (mread(regs->nip, &instr, 4) == 4) {
947 stepped = emulate_step(regs, instr);
949 printf("Couldn't single-step %s instruction\n",
950 (IS_RFID(instr)? "rfid": "mtmsrd"));
954 regs->trap = 0xd00 | (regs->trap & 1);
955 printf("stepped to ");
956 xmon_print_symbol(regs->nip, " ", "\n");
957 ppc_inst_dump(regs->nip, 1, 0);
967 static void bootcmds(void)
973 ppc_md.restart(NULL);
980 static int cpu_cmd(void)
983 unsigned long cpu, first_cpu, last_cpu;
986 if (!scanhex(&cpu)) {
987 /* print cpus waiting or in xmon */
988 printf("cpus stopped:");
989 last_cpu = first_cpu = NR_CPUS;
990 for_each_possible_cpu(cpu) {
991 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
992 if (cpu == last_cpu + 1) {
995 if (last_cpu != first_cpu)
996 printf("-%lx", last_cpu);
997 last_cpu = first_cpu = cpu;
1002 if (last_cpu != first_cpu)
1003 printf("-%lx", last_cpu);
1007 /* try to switch to cpu specified */
1008 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1009 printf("cpu 0x%x isn't in xmon\n", cpu);
1016 while (!xmon_taken) {
1017 if (--timeout == 0) {
1018 if (test_and_set_bit(0, &xmon_taken))
1020 /* take control back */
1022 xmon_owner = smp_processor_id();
1023 printf("cpu %u didn't take control\n", cpu);
1031 #endif /* CONFIG_SMP */
1034 static unsigned short fcstab[256] = {
1035 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1036 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1037 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1038 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1039 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1040 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1041 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1042 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1043 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1044 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1045 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1046 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1047 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1048 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1049 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1050 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1051 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1052 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1053 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1054 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1055 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1056 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1057 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1058 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1059 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1060 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1061 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1062 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1063 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1064 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1065 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1066 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1069 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1078 if (!scanhex(&adrs))
1080 if (!scanhex(&ncsum))
1083 for (i = 0; i < ncsum; ++i) {
1084 if (mread(adrs+i, &v, 1) == 0) {
1085 printf("csum stopped at %x\n", adrs+i);
1090 printf("%x\n", fcs);
1094 * Check if this is a suitable place to put a breakpoint.
1096 static long check_bp_loc(unsigned long addr)
1101 if (!is_kernel_addr(addr)) {
1102 printf("Breakpoints may only be placed at kernel addresses\n");
1105 if (!mread(addr, &instr, sizeof(instr))) {
1106 printf("Can't read instruction at address %lx\n", addr);
1109 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1110 printf("Breakpoints may not be placed on mtmsrd or rfid "
1117 static char *breakpoint_help_string =
1118 "Breakpoint command usage:\n"
1119 "b show breakpoints\n"
1120 "b <addr> [cnt] set breakpoint at given instr addr\n"
1121 "bc clear all breakpoints\n"
1122 "bc <n/addr> clear breakpoint number n or at addr\n"
1123 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1124 "bd <addr> [cnt] set hardware data breakpoint\n"
1134 const char badaddr[] = "Only kernel addresses are permitted "
1135 "for breakpoints\n";
1140 case 'd': /* bd - hardware data breakpoint */
1145 else if (cmd == 'w')
1151 if (scanhex(&dabr.address)) {
1152 if (!is_kernel_addr(dabr.address)) {
1156 dabr.address &= ~HW_BRK_TYPE_DABR;
1157 dabr.enabled = mode | BP_DABR;
1161 case 'i': /* bi - hardware instr breakpoint */
1162 if (!cpu_has_feature(CPU_FTR_IABR)) {
1163 printf("Hardware instruction breakpoint "
1164 "not supported on this cpu\n");
1168 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1173 if (!check_bp_loc(a))
1175 bp = new_breakpoint(a);
1177 bp->enabled |= BP_IABR | BP_IABR_TE;
1185 /* clear all breakpoints */
1186 for (i = 0; i < NBPTS; ++i)
1187 bpts[i].enabled = 0;
1190 printf("All breakpoints cleared\n");
1194 if (a <= NBPTS && a >= 1) {
1195 /* assume a breakpoint number */
1196 bp = &bpts[a-1]; /* bp nums are 1 based */
1198 /* assume a breakpoint address */
1199 bp = at_breakpoint(a);
1201 printf("No breakpoint at %x\n", a);
1206 printf("Cleared breakpoint %x (", BP_NUM(bp));
1207 xmon_print_symbol(bp->address, " ", ")\n");
1215 printf(breakpoint_help_string);
1220 /* print all breakpoints */
1221 printf(" type address\n");
1223 printf(" data "REG" [", dabr.address);
1224 if (dabr.enabled & 1)
1226 if (dabr.enabled & 2)
1230 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1233 printf("%2x %s ", BP_NUM(bp),
1234 (bp->enabled & BP_IABR)? "inst": "trap");
1235 xmon_print_symbol(bp->address, " ", "\n");
1240 if (!check_bp_loc(a))
1242 bp = new_breakpoint(a);
1244 bp->enabled |= BP_TRAP;
1249 /* Very cheap human name for vector lookup. */
1251 const char *getvecname(unsigned long vec)
1256 case 0x100: ret = "(System Reset)"; break;
1257 case 0x200: ret = "(Machine Check)"; break;
1258 case 0x300: ret = "(Data Access)"; break;
1259 case 0x380: ret = "(Data SLB Access)"; break;
1260 case 0x400: ret = "(Instruction Access)"; break;
1261 case 0x480: ret = "(Instruction SLB Access)"; break;
1262 case 0x500: ret = "(Hardware Interrupt)"; break;
1263 case 0x600: ret = "(Alignment)"; break;
1264 case 0x700: ret = "(Program Check)"; break;
1265 case 0x800: ret = "(FPU Unavailable)"; break;
1266 case 0x900: ret = "(Decrementer)"; break;
1267 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1268 case 0xa00: ret = "(Doorbell)"; break;
1269 case 0xc00: ret = "(System Call)"; break;
1270 case 0xd00: ret = "(Single Step)"; break;
1271 case 0xe40: ret = "(Emulation Assist)"; break;
1272 case 0xe60: ret = "(HMI)"; break;
1273 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1274 case 0xf00: ret = "(Performance Monitor)"; break;
1275 case 0xf20: ret = "(Altivec Unavailable)"; break;
1276 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1277 case 0x1500: ret = "(Denormalisation)"; break;
1278 case 0x1700: ret = "(Altivec Assist)"; break;
1284 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1285 unsigned long *endp)
1287 unsigned long size, offset;
1290 *startp = *endp = 0;
1293 if (setjmp(bus_error_jmp) == 0) {
1294 catch_memory_errors = 1;
1296 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1298 *startp = pc - offset;
1299 *endp = pc - offset + size;
1303 catch_memory_errors = 0;
1306 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1307 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1309 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1312 int max_to_print = 64;
1314 unsigned long newsp;
1315 unsigned long marker;
1316 struct pt_regs regs;
1318 while (max_to_print--) {
1319 if (sp < PAGE_OFFSET) {
1321 printf("SP (%lx) is in userspace\n", sp);
1325 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1326 || !mread(sp, &newsp, sizeof(unsigned long))) {
1327 printf("Couldn't read stack frame at %lx\n", sp);
1332 * For the first stack frame, try to work out if
1333 * LR and/or the saved LR value in the bottommost
1334 * stack frame are valid.
1336 if ((pc | lr) != 0) {
1337 unsigned long fnstart, fnend;
1338 unsigned long nextip;
1341 get_function_bounds(pc, &fnstart, &fnend);
1344 mread(newsp + LRSAVE_OFFSET, &nextip,
1345 sizeof(unsigned long));
1347 if (lr < PAGE_OFFSET
1348 || (fnstart <= lr && lr < fnend))
1350 } else if (lr == nextip) {
1352 } else if (lr >= PAGE_OFFSET
1353 && !(fnstart <= lr && lr < fnend)) {
1354 printf("[link register ] ");
1355 xmon_print_symbol(lr, " ", "\n");
1358 printf("["REG"] ", sp);
1359 xmon_print_symbol(ip, " ", " (unreliable)\n");
1364 printf("["REG"] ", sp);
1365 xmon_print_symbol(ip, " ", "\n");
1368 /* Look for "regshere" marker to see if this is
1369 an exception frame. */
1370 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1371 && marker == STACK_FRAME_REGS_MARKER) {
1372 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1374 printf("Couldn't read registers at %lx\n",
1375 sp + STACK_FRAME_OVERHEAD);
1378 printf("--- Exception: %lx %s at ", regs.trap,
1379 getvecname(TRAP(®s)));
1382 xmon_print_symbol(pc, " ", "\n");
1392 static void backtrace(struct pt_regs *excp)
1397 xmon_show_stack(sp, 0, 0);
1399 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1403 static void print_bug_trap(struct pt_regs *regs)
1406 const struct bug_entry *bug;
1409 if (regs->msr & MSR_PR)
1410 return; /* not in kernel */
1411 addr = regs->nip; /* address of trap instruction */
1412 if (addr < PAGE_OFFSET)
1414 bug = find_bug(regs->nip);
1417 if (is_warning_bug(bug))
1420 #ifdef CONFIG_DEBUG_BUGVERBOSE
1421 printf("kernel BUG at %s:%u!\n",
1422 bug->file, bug->line);
1424 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1426 #endif /* CONFIG_BUG */
1429 static void excprint(struct pt_regs *fp)
1434 printf("cpu 0x%x: ", smp_processor_id());
1435 #endif /* CONFIG_SMP */
1438 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1440 xmon_print_symbol(fp->nip, ": ", "\n");
1442 printf(" lr: ", fp->link);
1443 xmon_print_symbol(fp->link, ": ", "\n");
1445 printf(" sp: %lx\n", fp->gpr[1]);
1446 printf(" msr: %lx\n", fp->msr);
1448 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1449 printf(" dar: %lx\n", fp->dar);
1451 printf(" dsisr: %lx\n", fp->dsisr);
1454 printf(" current = 0x%lx\n", current);
1456 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1457 local_paca, local_paca->soft_enabled, local_paca->irq_happened);
1460 printf(" pid = %ld, comm = %s\n",
1461 current->pid, current->comm);
1468 static void prregs(struct pt_regs *fp)
1472 struct pt_regs regs;
1474 if (scanhex(&base)) {
1475 if (setjmp(bus_error_jmp) == 0) {
1476 catch_memory_errors = 1;
1478 regs = *(struct pt_regs *)base;
1482 catch_memory_errors = 0;
1483 printf("*** Error reading registers from "REG"\n",
1487 catch_memory_errors = 0;
1492 if (FULL_REGS(fp)) {
1493 for (n = 0; n < 16; ++n)
1494 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1495 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1497 for (n = 0; n < 7; ++n)
1498 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1499 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1502 for (n = 0; n < 32; ++n) {
1503 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1504 (n & 3) == 3? "\n": " ");
1505 if (n == 12 && !FULL_REGS(fp)) {
1512 xmon_print_symbol(fp->nip, " ", "\n");
1513 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1515 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1518 xmon_print_symbol(fp->link, " ", "\n");
1519 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1520 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1521 fp->ctr, fp->xer, fp->trap);
1523 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1524 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1527 static void cacheflush(void)
1530 unsigned long nflush;
1535 scanhex((void *)&adrs);
1540 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1541 if (setjmp(bus_error_jmp) == 0) {
1542 catch_memory_errors = 1;
1546 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1547 cflush((void *) adrs);
1549 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1550 cinval((void *) adrs);
1553 /* wait a little while to see if we get a machine check */
1556 catch_memory_errors = 0;
1559 static unsigned long
1562 unsigned int instrs[2];
1563 unsigned long (*code)(void);
1564 unsigned long ret = -1UL;
1566 unsigned long opd[3];
1568 opd[0] = (unsigned long)instrs;
1571 code = (unsigned long (*)(void)) opd;
1573 code = (unsigned long (*)(void)) instrs;
1576 /* mfspr r3,n; blr */
1577 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1578 instrs[1] = 0x4e800020;
1580 store_inst(instrs+1);
1582 if (setjmp(bus_error_jmp) == 0) {
1583 catch_memory_errors = 1;
1589 /* wait a little while to see if we get a machine check */
1598 write_spr(int n, unsigned long val)
1600 unsigned int instrs[2];
1601 unsigned long (*code)(unsigned long);
1603 unsigned long opd[3];
1605 opd[0] = (unsigned long)instrs;
1608 code = (unsigned long (*)(unsigned long)) opd;
1610 code = (unsigned long (*)(unsigned long)) instrs;
1613 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1614 instrs[1] = 0x4e800020;
1616 store_inst(instrs+1);
1618 if (setjmp(bus_error_jmp) == 0) {
1619 catch_memory_errors = 1;
1625 /* wait a little while to see if we get a machine check */
1631 static unsigned long regno;
1632 extern char exc_prolog;
1633 extern char dec_exc;
1635 static void super_regs(void)
1642 unsigned long sp, toc;
1643 asm("mr %0,1" : "=r" (sp) :);
1644 asm("mr %0,2" : "=r" (toc) :);
1646 printf("msr = "REG" sprg0= "REG"\n",
1647 mfmsr(), mfspr(SPRN_SPRG0));
1648 printf("pvr = "REG" sprg1= "REG"\n",
1649 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1650 printf("dec = "REG" sprg2= "REG"\n",
1651 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1652 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1653 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1661 val = read_spr(regno);
1663 write_spr(regno, val);
1666 printf("spr %lx = %lx\n", regno, read_spr(regno));
1673 * Stuff for reading and writing memory safely
1676 mread(unsigned long adrs, void *buf, int size)
1682 if (setjmp(bus_error_jmp) == 0) {
1683 catch_memory_errors = 1;
1689 *(u16 *)q = *(u16 *)p;
1692 *(u32 *)q = *(u32 *)p;
1695 *(u64 *)q = *(u64 *)p;
1698 for( ; n < size; ++n) {
1704 /* wait a little while to see if we get a machine check */
1708 catch_memory_errors = 0;
1713 mwrite(unsigned long adrs, void *buf, int size)
1719 if (setjmp(bus_error_jmp) == 0) {
1720 catch_memory_errors = 1;
1726 *(u16 *)p = *(u16 *)q;
1729 *(u32 *)p = *(u32 *)q;
1732 *(u64 *)p = *(u64 *)q;
1735 for ( ; n < size; ++n) {
1741 /* wait a little while to see if we get a machine check */
1745 printf("*** Error writing address %x\n", adrs + n);
1747 catch_memory_errors = 0;
1751 static int fault_type;
1752 static int fault_except;
1753 static char *fault_chars[] = { "--", "**", "##" };
1755 static int handle_fault(struct pt_regs *regs)
1757 fault_except = TRAP(regs);
1758 switch (TRAP(regs)) {
1770 longjmp(bus_error_jmp, 1);
1775 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1778 byterev(unsigned char *val, int size)
1784 SWAP(val[0], val[1], t);
1787 SWAP(val[0], val[3], t);
1788 SWAP(val[1], val[2], t);
1790 case 8: /* is there really any use for this? */
1791 SWAP(val[0], val[7], t);
1792 SWAP(val[1], val[6], t);
1793 SWAP(val[2], val[5], t);
1794 SWAP(val[3], val[4], t);
1802 static char *memex_help_string =
1803 "Memory examine command usage:\n"
1804 "m [addr] [flags] examine/change memory\n"
1805 " addr is optional. will start where left off.\n"
1806 " flags may include chars from this set:\n"
1807 " b modify by bytes (default)\n"
1808 " w modify by words (2 byte)\n"
1809 " l modify by longs (4 byte)\n"
1810 " d modify by doubleword (8 byte)\n"
1811 " r toggle reverse byte order mode\n"
1812 " n do not read memory (for i/o spaces)\n"
1813 " . ok to read (default)\n"
1814 "NOTE: flags are saved as defaults\n"
1817 static char *memex_subcmd_help_string =
1818 "Memory examine subcommands:\n"
1819 " hexval write this val to current location\n"
1820 " 'string' write chars from string to this location\n"
1821 " ' increment address\n"
1822 " ^ decrement address\n"
1823 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1824 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1825 " ` clear no-read flag\n"
1826 " ; stay at this addr\n"
1827 " v change to byte mode\n"
1828 " w change to word (2 byte) mode\n"
1829 " l change to long (4 byte) mode\n"
1830 " u change to doubleword (8 byte) mode\n"
1831 " m addr change current addr\n"
1832 " n toggle no-read flag\n"
1833 " r toggle byte reverse flag\n"
1834 " < count back up count bytes\n"
1835 " > count skip forward count bytes\n"
1836 " x exit this mode\n"
1842 int cmd, inc, i, nslash;
1844 unsigned char val[16];
1846 scanhex((void *)&adrs);
1849 printf(memex_help_string);
1855 while ((cmd = skipbl()) != '\n') {
1857 case 'b': size = 1; break;
1858 case 'w': size = 2; break;
1859 case 'l': size = 4; break;
1860 case 'd': size = 8; break;
1861 case 'r': brev = !brev; break;
1862 case 'n': mnoread = 1; break;
1863 case '.': mnoread = 0; break;
1872 n = mread(adrs, val, size);
1873 printf(REG"%c", adrs, brev? 'r': ' ');
1878 for (i = 0; i < n; ++i)
1879 printf("%.2x", val[i]);
1880 for (; i < size; ++i)
1881 printf("%s", fault_chars[fault_type]);
1888 for (i = 0; i < size; ++i)
1889 val[i] = n >> (i * 8);
1892 mwrite(adrs, val, size);
1905 else if( n == '\'' )
1907 for (i = 0; i < size; ++i)
1908 val[i] = n >> (i * 8);
1911 mwrite(adrs, val, size);
1948 adrs -= 1 << nslash;
1952 adrs += 1 << nslash;
1956 adrs += 1 << -nslash;
1960 adrs -= 1 << -nslash;
1963 scanhex((void *)&adrs);
1982 printf(memex_subcmd_help_string);
1997 case 'n': c = '\n'; break;
1998 case 'r': c = '\r'; break;
1999 case 'b': c = '\b'; break;
2000 case 't': c = '\t'; break;
2005 static void xmon_rawdump (unsigned long adrs, long ndump)
2008 unsigned char temp[16];
2010 for (n = ndump; n > 0;) {
2012 nr = mread(adrs, temp, r);
2014 for (m = 0; m < r; ++m) {
2016 printf("%.2x", temp[m]);
2018 printf("%s", fault_chars[fault_type]);
2028 static void dump_one_paca(int cpu)
2030 struct paca_struct *p;
2032 if (setjmp(bus_error_jmp) != 0) {
2033 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2037 catch_memory_errors = 1;
2042 printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2044 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
2045 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
2046 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
2048 #define DUMP(paca, name, format) \
2049 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2050 offsetof(struct paca_struct, name));
2052 DUMP(p, lock_token, "x");
2053 DUMP(p, paca_index, "x");
2054 DUMP(p, kernel_toc, "lx");
2055 DUMP(p, kernelbase, "lx");
2056 DUMP(p, kernel_msr, "lx");
2057 #ifdef CONFIG_PPC_STD_MMU_64
2058 DUMP(p, stab_real, "lx");
2059 DUMP(p, stab_addr, "lx");
2061 DUMP(p, emergency_sp, "p");
2062 #ifdef CONFIG_PPC_BOOK3S_64
2063 DUMP(p, mc_emergency_sp, "p");
2064 DUMP(p, in_mce, "x");
2066 DUMP(p, data_offset, "lx");
2067 DUMP(p, hw_cpu_id, "x");
2068 DUMP(p, cpu_start, "x");
2069 DUMP(p, kexec_state, "x");
2070 DUMP(p, __current, "p");
2071 DUMP(p, kstack, "lx");
2072 DUMP(p, stab_rr, "lx");
2073 DUMP(p, saved_r1, "lx");
2074 DUMP(p, trap_save, "x");
2075 DUMP(p, soft_enabled, "x");
2076 DUMP(p, irq_happened, "x");
2077 DUMP(p, io_sync, "x");
2078 DUMP(p, irq_work_pending, "x");
2079 DUMP(p, nap_state_lost, "x");
2083 catch_memory_errors = 0;
2087 static void dump_all_pacas(void)
2091 if (num_possible_cpus() == 0) {
2092 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2096 for_each_possible_cpu(cpu)
2100 static void dump_pacas(void)
2111 termch = c; /* Put c back, it wasn't 'a' */
2116 dump_one_paca(xmon_owner);
2120 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2121 || ('a' <= (c) && (c) <= 'f') \
2122 || ('A' <= (c) && (c) <= 'F'))
2137 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2139 scanhex((void *)&adrs);
2146 else if (nidump > MAX_DUMP)
2148 adrs += ppc_inst_dump(adrs, nidump, 1);
2150 } else if (c == 'l') {
2152 } else if (c == 'r') {
2156 xmon_rawdump(adrs, ndump);
2163 else if (ndump > MAX_DUMP)
2165 prdump(adrs, ndump);
2172 prdump(unsigned long adrs, long ndump)
2174 long n, m, c, r, nr;
2175 unsigned char temp[16];
2177 for (n = ndump; n > 0;) {
2181 nr = mread(adrs, temp, r);
2183 for (m = 0; m < r; ++m) {
2184 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2187 printf("%.2x", temp[m]);
2189 printf("%s", fault_chars[fault_type]);
2191 for (; m < 16; ++m) {
2192 if ((m & (sizeof(long) - 1)) == 0)
2197 for (m = 0; m < r; ++m) {
2200 putchar(' ' <= c && c <= '~'? c: '.');
2213 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2216 generic_inst_dump(unsigned long adr, long count, int praddr,
2217 instruction_dump_func dump_func)
2220 unsigned long first_adr;
2221 unsigned long inst, last_inst = 0;
2222 unsigned char val[4];
2225 for (first_adr = adr; count > 0; --count, adr += 4) {
2226 nr = mread(adr, val, 4);
2229 const char *x = fault_chars[fault_type];
2230 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2234 inst = GETWORD(val);
2235 if (adr > first_adr && inst == last_inst) {
2245 printf(REG" %.8x", adr, inst);
2247 dump_func(inst, adr);
2250 return adr - first_adr;
2254 ppc_inst_dump(unsigned long adr, long count, int praddr)
2256 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2260 print_address(unsigned long addr)
2262 xmon_print_symbol(addr, "\t# ", "");
2268 struct kmsg_dumper dumper = { .active = 1 };
2269 unsigned char buf[128];
2272 if (setjmp(bus_error_jmp) != 0) {
2273 printf("Error dumping printk buffer!\n");
2277 catch_memory_errors = 1;
2280 kmsg_dump_rewind_nolock(&dumper);
2281 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2287 /* wait a little while to see if we get a machine check */
2289 catch_memory_errors = 0;
2293 * Memory operations - move, set, print differences
2295 static unsigned long mdest; /* destination address */
2296 static unsigned long msrc; /* source address */
2297 static unsigned long mval; /* byte value to set memory to */
2298 static unsigned long mcount; /* # bytes to affect */
2299 static unsigned long mdiffs; /* max # differences to print */
2304 scanhex((void *)&mdest);
2305 if( termch != '\n' )
2307 scanhex((void *)(cmd == 's'? &mval: &msrc));
2308 if( termch != '\n' )
2310 scanhex((void *)&mcount);
2313 memmove((void *)mdest, (void *)msrc, mcount);
2316 memset((void *)mdest, mval, mcount);
2319 if( termch != '\n' )
2321 scanhex((void *)&mdiffs);
2322 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2328 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2333 for( n = nb; n > 0; --n )
2334 if( *p1++ != *p2++ )
2335 if( ++prt <= maxpr )
2336 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2337 p1[-1], p2 - 1, p2[-1]);
2339 printf("Total of %d differences\n", prt);
2342 static unsigned mend;
2343 static unsigned mask;
2349 unsigned char val[4];
2352 scanhex((void *)&mdest);
2353 if (termch != '\n') {
2355 scanhex((void *)&mend);
2356 if (termch != '\n') {
2358 scanhex((void *)&mval);
2360 if (termch != '\n') termch = 0;
2361 scanhex((void *)&mask);
2365 for (a = mdest; a < mend; a += 4) {
2366 if (mread(a, val, 4) == 4
2367 && ((GETWORD(val) ^ mval) & mask) == 0) {
2368 printf("%.16x: %.16x\n", a, GETWORD(val));
2375 static unsigned long mskip = 0x1000;
2376 static unsigned long mlim = 0xffffffff;
2386 if (termch != '\n') termch = 0;
2388 if (termch != '\n') termch = 0;
2391 for (a = mdest; a < mlim; a += mskip) {
2392 ok = mread(a, &v, 1);
2394 printf("%.8x .. ", a);
2395 } else if (!ok && ook)
2396 printf("%.8x\n", a - mskip);
2402 printf("%.8x\n", a - mskip);
2405 static void proccall(void)
2407 unsigned long args[8];
2410 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2411 unsigned long, unsigned long, unsigned long,
2412 unsigned long, unsigned long, unsigned long);
2415 if (!scanhex(&adrs))
2419 for (i = 0; i < 8; ++i)
2421 for (i = 0; i < 8; ++i) {
2422 if (!scanhex(&args[i]) || termch == '\n')
2426 func = (callfunc_t) adrs;
2428 if (setjmp(bus_error_jmp) == 0) {
2429 catch_memory_errors = 1;
2431 ret = func(args[0], args[1], args[2], args[3],
2432 args[4], args[5], args[6], args[7]);
2434 printf("return value is %x\n", ret);
2436 printf("*** %x exception occurred\n", fault_except);
2438 catch_memory_errors = 0;
2441 /* Input scanning routines */
2452 while( c == ' ' || c == '\t' )
2458 static char *regnames[N_PTREGS] = {
2459 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2460 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2461 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2462 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2463 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2469 "trap", "dar", "dsisr", "res"
2473 scanhex(unsigned long *vp)
2480 /* parse register name */
2484 for (i = 0; i < sizeof(regname) - 1; ++i) {
2493 for (i = 0; i < N_PTREGS; ++i) {
2494 if (strcmp(regnames[i], regname) == 0) {
2495 if (xmon_regs == NULL) {
2496 printf("regs not available\n");
2499 *vp = ((unsigned long *)xmon_regs)[i];
2503 printf("invalid register name '%%%s'\n", regname);
2507 /* skip leading "0x" if any */
2521 } else if (c == '$') {
2523 for (i=0; i<63; i++) {
2533 if (setjmp(bus_error_jmp) == 0) {
2534 catch_memory_errors = 1;
2536 *vp = kallsyms_lookup_name(tmpstr);
2539 catch_memory_errors = 0;
2541 printf("unknown symbol '%s'\n", tmpstr);
2574 static int hexdigit(int c)
2576 if( '0' <= c && c <= '9' )
2578 if( 'A' <= c && c <= 'F' )
2579 return c - ('A' - 10);
2580 if( 'a' <= c && c <= 'f' )
2581 return c - ('a' - 10);
2586 getstring(char *s, int size)
2597 } while( c != ' ' && c != '\t' && c != '\n' );
2602 static char line[256];
2603 static char *lineptr;
2614 if (lineptr == NULL || *lineptr == 0) {
2615 if (xmon_gets(line, sizeof(line)) == NULL) {
2625 take_input(char *str)
2634 int type = inchar();
2636 static char tmp[64];
2641 xmon_print_symbol(addr, ": ", "\n");
2646 if (setjmp(bus_error_jmp) == 0) {
2647 catch_memory_errors = 1;
2649 addr = kallsyms_lookup_name(tmp);
2651 printf("%s: %lx\n", tmp, addr);
2653 printf("Symbol '%s' not found.\n", tmp);
2656 catch_memory_errors = 0;
2663 /* Print an address in numeric and symbolic form (if possible) */
2664 static void xmon_print_symbol(unsigned long address, const char *mid,
2668 const char *name = NULL;
2669 unsigned long offset, size;
2671 printf(REG, address);
2672 if (setjmp(bus_error_jmp) == 0) {
2673 catch_memory_errors = 1;
2675 name = kallsyms_lookup(address, &size, &offset, &modname,
2678 /* wait a little while to see if we get a machine check */
2682 catch_memory_errors = 0;
2685 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2687 printf(" [%s]", modname);
2689 printf("%s", after);
2692 #ifdef CONFIG_PPC_BOOK3S_64
2693 static void dump_slb(void)
2696 unsigned long esid,vsid,valid;
2699 printf("SLB contents of cpu %x\n", smp_processor_id());
2701 for (i = 0; i < mmu_slb_size; i++) {
2702 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2703 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2704 valid = (esid & SLB_ESID_V);
2705 if (valid | esid | vsid) {
2706 printf("%02d %016lx %016lx", i, esid, vsid);
2708 llp = vsid & SLB_VSID_LLP;
2709 if (vsid & SLB_VSID_B_1T) {
2710 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2712 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2715 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2717 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2726 static void dump_stab(void)
2729 unsigned long *tmp = (unsigned long *)local_paca->stab_addr;
2731 printf("Segment table contents of cpu %x\n", smp_processor_id());
2733 for (i = 0; i < PAGE_SIZE/16; i++) {
2740 printf("%03d %016lx ", i, a);
2741 printf("%016lx\n", b);
2746 void dump_segments(void)
2748 if (mmu_has_feature(MMU_FTR_SLB))
2755 #ifdef CONFIG_PPC_STD_MMU_32
2756 void dump_segments(void)
2761 for (i = 0; i < 16; ++i)
2762 printf(" %x", mfsrin(i));
2768 static void dump_tlb_44x(void)
2772 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2773 unsigned long w0,w1,w2;
2774 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2775 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2776 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2777 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2778 if (w0 & PPC44x_TLB_VALID) {
2779 printf("V %08x -> %01x%08x %c%c%c%c%c",
2780 w0 & PPC44x_TLB_EPN_MASK,
2781 w1 & PPC44x_TLB_ERPN_MASK,
2782 w1 & PPC44x_TLB_RPN_MASK,
2783 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2784 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2785 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2786 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2787 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2792 #endif /* CONFIG_44x */
2794 #ifdef CONFIG_PPC_BOOK3E
2795 static void dump_tlb_book3e(void)
2797 u32 mmucfg, pidmask, lpidmask;
2799 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2801 static const char *pgsz_names[] = {
2836 /* Gather some infos about the MMU */
2837 mmucfg = mfspr(SPRN_MMUCFG);
2838 mmu_version = (mmucfg & 3) + 1;
2839 ntlbs = ((mmucfg >> 2) & 3) + 1;
2840 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2841 lpidsz = (mmucfg >> 24) & 0xf;
2842 rasz = (mmucfg >> 16) & 0x7f;
2843 if ((mmu_version > 1) && (mmucfg & 0x10000))
2845 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2846 mmu_version, ntlbs, pidsz, lpidsz, rasz);
2847 pidmask = (1ul << pidsz) - 1;
2848 lpidmask = (1ul << lpidsz) - 1;
2849 ramask = (1ull << rasz) - 1;
2851 for (tlb = 0; tlb < ntlbs; tlb++) {
2853 int nent, assoc, new_cc = 1;
2854 printf("TLB %d:\n------\n", tlb);
2857 tlbcfg = mfspr(SPRN_TLB0CFG);
2860 tlbcfg = mfspr(SPRN_TLB1CFG);
2863 tlbcfg = mfspr(SPRN_TLB2CFG);
2866 tlbcfg = mfspr(SPRN_TLB3CFG);
2869 printf("Unsupported TLB number !\n");
2872 nent = tlbcfg & 0xfff;
2873 assoc = (tlbcfg >> 24) & 0xff;
2874 for (i = 0; i < nent; i++) {
2875 u32 mas0 = MAS0_TLBSEL(tlb);
2876 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2879 int esel = i, cc = i;
2887 mas0 |= MAS0_ESEL(esel);
2888 mtspr(SPRN_MAS0, mas0);
2889 mtspr(SPRN_MAS1, mas1);
2890 mtspr(SPRN_MAS2, mas2);
2891 asm volatile("tlbre 0,0,0" : : : "memory");
2892 mas1 = mfspr(SPRN_MAS1);
2893 mas2 = mfspr(SPRN_MAS2);
2894 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2895 if (assoc && (i % assoc) == 0)
2897 if (!(mas1 & MAS1_VALID))
2900 printf("%04x- ", i);
2902 printf("%04x-%c", cc, 'A' + esel);
2904 printf(" |%c", 'A' + esel);
2906 printf(" %016llx %04x %s %c%c AS%c",
2908 (mas1 >> 16) & 0x3fff,
2909 pgsz_names[(mas1 >> 7) & 0x1f],
2910 mas1 & MAS1_IND ? 'I' : ' ',
2911 mas1 & MAS1_IPROT ? 'P' : ' ',
2912 mas1 & MAS1_TS ? '1' : '0');
2913 printf(" %c%c%c%c%c%c%c",
2914 mas2 & MAS2_X0 ? 'a' : ' ',
2915 mas2 & MAS2_X1 ? 'v' : ' ',
2916 mas2 & MAS2_W ? 'w' : ' ',
2917 mas2 & MAS2_I ? 'i' : ' ',
2918 mas2 & MAS2_M ? 'm' : ' ',
2919 mas2 & MAS2_G ? 'g' : ' ',
2920 mas2 & MAS2_E ? 'e' : ' ');
2921 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
2922 if (mas1 & MAS1_IND)
2924 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
2926 printf(" U%c%c%c S%c%c%c\n",
2927 mas7_mas3 & MAS3_UX ? 'x' : ' ',
2928 mas7_mas3 & MAS3_UW ? 'w' : ' ',
2929 mas7_mas3 & MAS3_UR ? 'r' : ' ',
2930 mas7_mas3 & MAS3_SX ? 'x' : ' ',
2931 mas7_mas3 & MAS3_SW ? 'w' : ' ',
2932 mas7_mas3 & MAS3_SR ? 'r' : ' ');
2936 #endif /* CONFIG_PPC_BOOK3E */
2938 static void xmon_init(int enable)
2942 __debugger_ipi = xmon_ipi;
2943 __debugger_bpt = xmon_bpt;
2944 __debugger_sstep = xmon_sstep;
2945 __debugger_iabr_match = xmon_iabr_match;
2946 __debugger_break_match = xmon_break_match;
2947 __debugger_fault_handler = xmon_fault_handler;
2950 __debugger_ipi = NULL;
2951 __debugger_bpt = NULL;
2952 __debugger_sstep = NULL;
2953 __debugger_iabr_match = NULL;
2954 __debugger_break_match = NULL;
2955 __debugger_fault_handler = NULL;
2959 #ifdef CONFIG_MAGIC_SYSRQ
2960 static void sysrq_handle_xmon(int key)
2962 /* ensure xmon is enabled */
2964 debugger(get_irq_regs());
2967 static struct sysrq_key_op sysrq_xmon_op = {
2968 .handler = sysrq_handle_xmon,
2969 .help_msg = "xmon(x)",
2970 .action_msg = "Entering xmon",
2973 static int __init setup_xmon_sysrq(void)
2975 register_sysrq_key('x', &sysrq_xmon_op);
2978 __initcall(setup_xmon_sysrq);
2979 #endif /* CONFIG_MAGIC_SYSRQ */
2981 static int __initdata xmon_early, xmon_off;
2983 static int __init early_parse_xmon(char *p)
2985 if (!p || strncmp(p, "early", 5) == 0) {
2986 /* just "xmon" is equivalent to "xmon=early" */
2989 } else if (strncmp(p, "on", 2) == 0)
2991 else if (strncmp(p, "off", 3) == 0)
2993 else if (strncmp(p, "nobt", 4) == 0)
2994 xmon_no_auto_backtrace = 1;
3000 early_param("xmon", early_parse_xmon);
3002 void __init xmon_setup(void)
3004 #ifdef CONFIG_XMON_DEFAULT
3012 #ifdef CONFIG_SPU_BASE
3016 u64 saved_mfc_sr1_RW;
3017 u32 saved_spu_runcntl_RW;
3018 unsigned long dump_addr;
3022 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3024 static struct spu_info spu_info[XMON_NUM_SPUS];
3026 void xmon_register_spus(struct list_head *list)
3030 list_for_each_entry(spu, list, full_list) {
3031 if (spu->number >= XMON_NUM_SPUS) {
3036 spu_info[spu->number].spu = spu;
3037 spu_info[spu->number].stopped_ok = 0;
3038 spu_info[spu->number].dump_addr = (unsigned long)
3039 spu_info[spu->number].spu->local_store;
3043 static void stop_spus(void)
3049 for (i = 0; i < XMON_NUM_SPUS; i++) {
3050 if (!spu_info[i].spu)
3053 if (setjmp(bus_error_jmp) == 0) {
3054 catch_memory_errors = 1;
3057 spu = spu_info[i].spu;
3059 spu_info[i].saved_spu_runcntl_RW =
3060 in_be32(&spu->problem->spu_runcntl_RW);
3062 tmp = spu_mfc_sr1_get(spu);
3063 spu_info[i].saved_mfc_sr1_RW = tmp;
3065 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3066 spu_mfc_sr1_set(spu, tmp);
3071 spu_info[i].stopped_ok = 1;
3073 printf("Stopped spu %.2d (was %s)\n", i,
3074 spu_info[i].saved_spu_runcntl_RW ?
3075 "running" : "stopped");
3077 catch_memory_errors = 0;
3078 printf("*** Error stopping spu %.2d\n", i);
3080 catch_memory_errors = 0;
3084 static void restart_spus(void)
3089 for (i = 0; i < XMON_NUM_SPUS; i++) {
3090 if (!spu_info[i].spu)
3093 if (!spu_info[i].stopped_ok) {
3094 printf("*** Error, spu %d was not successfully stopped"
3095 ", not restarting\n", i);
3099 if (setjmp(bus_error_jmp) == 0) {
3100 catch_memory_errors = 1;
3103 spu = spu_info[i].spu;
3104 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3105 out_be32(&spu->problem->spu_runcntl_RW,
3106 spu_info[i].saved_spu_runcntl_RW);
3111 printf("Restarted spu %.2d\n", i);
3113 catch_memory_errors = 0;
3114 printf("*** Error restarting spu %.2d\n", i);
3116 catch_memory_errors = 0;
3120 #define DUMP_WIDTH 23
3121 #define DUMP_VALUE(format, field, value) \
3123 if (setjmp(bus_error_jmp) == 0) { \
3124 catch_memory_errors = 1; \
3126 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3131 catch_memory_errors = 0; \
3132 printf(" %-*s = *** Error reading field.\n", \
3133 DUMP_WIDTH, #field); \
3135 catch_memory_errors = 0; \
3138 #define DUMP_FIELD(obj, format, field) \
3139 DUMP_VALUE(format, field, obj->field)
3141 static void dump_spu_fields(struct spu *spu)
3143 printf("Dumping spu fields at address %p:\n", spu);
3145 DUMP_FIELD(spu, "0x%x", number);
3146 DUMP_FIELD(spu, "%s", name);
3147 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3148 DUMP_FIELD(spu, "0x%p", local_store);
3149 DUMP_FIELD(spu, "0x%lx", ls_size);
3150 DUMP_FIELD(spu, "0x%x", node);
3151 DUMP_FIELD(spu, "0x%lx", flags);
3152 DUMP_FIELD(spu, "%d", class_0_pending);
3153 DUMP_FIELD(spu, "0x%lx", class_0_dar);
3154 DUMP_FIELD(spu, "0x%lx", class_1_dar);
3155 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3156 DUMP_FIELD(spu, "0x%lx", irqs[0]);
3157 DUMP_FIELD(spu, "0x%lx", irqs[1]);
3158 DUMP_FIELD(spu, "0x%lx", irqs[2]);
3159 DUMP_FIELD(spu, "0x%x", slb_replace);
3160 DUMP_FIELD(spu, "%d", pid);
3161 DUMP_FIELD(spu, "0x%p", mm);
3162 DUMP_FIELD(spu, "0x%p", ctx);
3163 DUMP_FIELD(spu, "0x%p", rq);
3164 DUMP_FIELD(spu, "0x%p", timestamp);
3165 DUMP_FIELD(spu, "0x%lx", problem_phys);
3166 DUMP_FIELD(spu, "0x%p", problem);
3167 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3168 in_be32(&spu->problem->spu_runcntl_RW));
3169 DUMP_VALUE("0x%x", problem->spu_status_R,
3170 in_be32(&spu->problem->spu_status_R));
3171 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3172 in_be32(&spu->problem->spu_npc_RW));
3173 DUMP_FIELD(spu, "0x%p", priv2);
3174 DUMP_FIELD(spu, "0x%p", pdata);
3178 spu_inst_dump(unsigned long adr, long count, int praddr)
3180 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3183 static void dump_spu_ls(unsigned long num, int subcmd)
3185 unsigned long offset, addr, ls_addr;
3187 if (setjmp(bus_error_jmp) == 0) {
3188 catch_memory_errors = 1;
3190 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3194 catch_memory_errors = 0;
3195 printf("*** Error: accessing spu info for spu %d\n", num);
3198 catch_memory_errors = 0;
3200 if (scanhex(&offset))
3201 addr = ls_addr + offset;
3203 addr = spu_info[num].dump_addr;
3205 if (addr >= ls_addr + LS_SIZE) {
3206 printf("*** Error: address outside of local store\n");
3212 addr += spu_inst_dump(addr, 16, 1);
3222 spu_info[num].dump_addr = addr;
3225 static int do_spu_cmd(void)
3227 static unsigned long num = 0;
3228 int cmd, subcmd = 0;
3240 if (isxdigit(subcmd) || subcmd == '\n')
3244 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3245 printf("*** Error: invalid spu number\n");
3251 dump_spu_fields(spu_info[num].spu);
3254 dump_spu_ls(num, subcmd);
3265 #else /* ! CONFIG_SPU_BASE */
3266 static int do_spu_cmd(void)