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>
27 #include <linux/nmi.h>
29 #include <asm/ptrace.h>
30 #include <asm/string.h>
32 #include <asm/machdep.h>
34 #include <asm/processor.h>
35 #include <asm/pgtable.h>
37 #include <asm/mmu_context.h>
38 #include <asm/cputable.h>
40 #include <asm/sstep.h>
41 #include <asm/irq_regs.h>
43 #include <asm/spu_priv1.h>
44 #include <asm/setjmp.h>
46 #include <asm/debug.h>
47 #include <asm/hw_breakpoint.h>
50 #include <asm/hvcall.h>
58 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
59 static unsigned long xmon_taken = 1;
60 static int xmon_owner;
64 #endif /* CONFIG_SMP */
66 static unsigned long in_xmon __read_mostly = 0;
68 static unsigned long adrs;
70 #define MAX_DUMP (128 * 1024)
71 static unsigned long ndump = 64;
72 static unsigned long nidump = 16;
73 static unsigned long ncsum = 4096;
75 static char tmpstr[128];
77 static long bus_error_jmp[JMP_BUF_LEN];
78 static int catch_memory_errors;
79 static long *xmon_fault_jmp[NR_CPUS];
81 /* Breakpoint stuff */
83 unsigned long address;
84 unsigned int instr[2];
90 /* Bits in bpt.enabled */
91 #define BP_IABR_TE 1 /* IABR translation enabled */
97 static struct bpt bpts[NBPTS];
98 static struct bpt dabr;
99 static struct bpt *iabr;
100 static unsigned bpinstr = 0x7fe00008; /* trap */
102 #define BP_NUM(bp) ((bp) - bpts + 1)
105 static int cmds(struct pt_regs *);
106 static int mread(unsigned long, void *, int);
107 static int mwrite(unsigned long, void *, int);
108 static int handle_fault(struct pt_regs *);
109 static void byterev(unsigned char *, int);
110 static void memex(void);
111 static int bsesc(void);
112 static void dump(void);
113 static void prdump(unsigned long, long);
114 static int ppc_inst_dump(unsigned long, long, int);
115 static void dump_log_buf(void);
116 static void backtrace(struct pt_regs *);
117 static void excprint(struct pt_regs *);
118 static void prregs(struct pt_regs *);
119 static void memops(int);
120 static void memlocate(void);
121 static void memzcan(void);
122 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
124 int scanhex(unsigned long *valp);
125 static void scannl(void);
126 static int hexdigit(int);
127 void getstring(char *, int);
128 static void flush_input(void);
129 static int inchar(void);
130 static void take_input(char *);
131 static unsigned long read_spr(int);
132 static void write_spr(int, unsigned long);
133 static void super_regs(void);
134 static void remove_bpts(void);
135 static void insert_bpts(void);
136 static void remove_cpu_bpts(void);
137 static void insert_cpu_bpts(void);
138 static struct bpt *at_breakpoint(unsigned long pc);
139 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
140 static int do_step(struct pt_regs *);
141 static void bpt_cmds(void);
142 static void cacheflush(void);
143 static int cpu_cmd(void);
144 static void csum(void);
145 static void bootcmds(void);
146 static void proccall(void);
147 void dump_segments(void);
148 static void symbol_lookup(void);
149 static void xmon_show_stack(unsigned long sp, unsigned long lr,
151 static void xmon_print_symbol(unsigned long address, const char *mid,
153 static const char *getvecname(unsigned long vec);
155 static int do_spu_cmd(void);
158 static void dump_tlb_44x(void);
160 #ifdef CONFIG_PPC_BOOK3E
161 static void dump_tlb_book3e(void);
164 static int xmon_no_auto_backtrace;
166 extern void xmon_enter(void);
167 extern void xmon_leave(void);
175 #ifdef __LITTLE_ENDIAN__
176 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
178 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
181 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
182 || ('a' <= (c) && (c) <= 'f') \
183 || ('A' <= (c) && (c) <= 'F'))
184 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
185 || ('a' <= (c) && (c) <= 'z') \
186 || ('A' <= (c) && (c) <= 'Z'))
187 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
189 static char *help_string = "\
191 b show breakpoints\n\
192 bd set data breakpoint\n\
193 bi set instruction breakpoint\n\
194 bc clear breakpoint\n"
197 c print cpus stopped in xmon\n\
198 c# try to switch to cpu number h (in hex)\n"
203 di dump instructions\n\
204 df dump float values\n\
205 dd dump double values\n\
206 dl dump the kernel log buffer\n"
209 dp[#] dump paca for current cpu, or cpu #\n\
210 dpa dump paca for all possible cpus\n"
213 dr dump stream of raw bytes\n\
214 e print exception information\n\
216 la lookup symbol+offset of specified address\n\
217 ls lookup address of specified symbol\n\
218 m examine/change memory\n\
219 mm move a block of memory\n\
220 ms set a block of memory\n\
221 md compare two blocks of memory\n\
222 ml locate a block of memory\n\
223 mz zero a block of memory\n\
224 mi show information about memory allocation\n\
225 p call a procedure\n\
228 #ifdef CONFIG_SPU_BASE
229 " ss stop execution on all spus\n\
230 sr restore execution on stopped spus\n\
231 sf # dump spu fields for spu # (in hex)\n\
232 sd # dump spu local store for spu # (in hex)\n\
233 sdi # disassemble spu local store for spu # (in hex)\n"
235 " S print special registers\n\
237 x exit monitor and recover\n\
238 X exit monitor and dont recover\n"
239 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
240 " u dump segment table or SLB\n"
241 #elif defined(CONFIG_PPC_STD_MMU_32)
242 " u dump segment registers\n"
243 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
251 static struct pt_regs *xmon_regs;
253 static inline void sync(void)
255 asm volatile("sync; isync");
258 static inline void store_inst(void *p)
260 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
263 static inline void cflush(void *p)
265 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
268 static inline void cinval(void *p)
270 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
274 * Disable surveillance (the service processor watchdog function)
275 * while we are in xmon.
276 * XXX we should re-enable it when we leave. :)
278 #define SURVEILLANCE_TOKEN 9000
280 static inline void disable_surveillance(void)
282 #ifdef CONFIG_PPC_PSERIES
283 /* Since this can't be a module, args should end up below 4GB. */
284 static struct rtas_args args;
287 * At this point we have got all the cpus we can into
288 * xmon, so there is hopefully no other cpu calling RTAS
289 * at the moment, even though we don't take rtas.lock.
290 * If we did try to take rtas.lock there would be a
291 * real possibility of deadlock.
293 args.token = rtas_token("set-indicator");
294 if (args.token == RTAS_UNKNOWN_SERVICE)
296 args.token = cpu_to_be32(args.token);
297 args.nargs = cpu_to_be32(3);
298 args.nret = cpu_to_be32(1);
299 args.rets = &args.args[3];
300 args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN);
303 enter_rtas(__pa(&args));
304 #endif /* CONFIG_PPC_PSERIES */
308 static int xmon_speaker;
310 static void get_output_lock(void)
312 int me = smp_processor_id() + 0x100;
313 int last_speaker = 0, prev;
316 if (xmon_speaker == me)
320 last_speaker = cmpxchg(&xmon_speaker, 0, me);
321 if (last_speaker == 0)
325 * Wait a full second for the lock, we might be on a slow
326 * console, but check every 100us.
329 while (xmon_speaker == last_speaker) {
335 /* hostile takeover */
336 prev = cmpxchg(&xmon_speaker, last_speaker, me);
337 if (prev == last_speaker)
344 static void release_output_lock(void)
349 int cpus_are_in_xmon(void)
351 return !cpumask_empty(&cpus_in_xmon);
355 static inline int unrecoverable_excp(struct pt_regs *regs)
357 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
358 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
361 return ((regs->msr & MSR_RI) == 0);
365 static int xmon_core(struct pt_regs *regs, int fromipi)
369 long recurse_jmp[JMP_BUF_LEN];
370 unsigned long offset;
375 unsigned long timeout;
378 local_irq_save(flags);
381 bp = in_breakpoint_table(regs->nip, &offset);
383 regs->nip = bp->address + offset;
384 atomic_dec(&bp->ref_count);
390 cpu = smp_processor_id();
391 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
394 printf("cpu 0x%x: Exception %lx %s in xmon, "
395 "returning to main loop\n",
396 cpu, regs->trap, getvecname(TRAP(regs)));
397 release_output_lock();
398 longjmp(xmon_fault_jmp[cpu], 1);
401 if (setjmp(recurse_jmp) != 0) {
402 if (!in_xmon || !xmon_gate) {
404 printf("xmon: WARNING: bad recursive fault "
405 "on cpu 0x%x\n", cpu);
406 release_output_lock();
409 secondary = !(xmon_taken && cpu == xmon_owner);
413 xmon_fault_jmp[cpu] = recurse_jmp;
416 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
417 bp = at_breakpoint(regs->nip);
418 if (bp || unrecoverable_excp(regs))
425 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
427 xmon_print_symbol(regs->nip, " ", ")\n");
429 if (unrecoverable_excp(regs))
430 printf("WARNING: exception is not recoverable, "
432 release_output_lock();
435 cpumask_set_cpu(cpu, &cpus_in_xmon);
439 while (secondary && !xmon_gate) {
443 secondary = test_and_set_bit(0, &in_xmon);
448 if (!secondary && !xmon_gate) {
449 /* we are the first cpu to come in */
450 /* interrupt other cpu(s) */
451 int ncpus = num_online_cpus();
456 smp_send_debugger_break();
457 /* wait for other cpus to come in */
458 for (timeout = 100000000; timeout != 0; --timeout) {
459 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
465 disable_surveillance();
466 /* for breakpoint or single step, print the current instr. */
467 if (bp || TRAP(regs) == 0xd00)
468 ppc_inst_dump(regs->nip, 1, 0);
469 printf("enter ? for help\n");
478 if (cpu == xmon_owner) {
479 if (!test_and_set_bit(0, &xmon_taken)) {
484 while (cpu == xmon_owner)
498 /* have switched to some other cpu */
503 cpumask_clear_cpu(cpu, &cpus_in_xmon);
504 xmon_fault_jmp[cpu] = NULL;
506 /* UP is simple... */
508 printf("Exception %lx %s in xmon, returning to main loop\n",
509 regs->trap, getvecname(TRAP(regs)));
510 longjmp(xmon_fault_jmp[0], 1);
512 if (setjmp(recurse_jmp) == 0) {
513 xmon_fault_jmp[0] = recurse_jmp;
517 bp = at_breakpoint(regs->nip);
519 printf("Stopped at breakpoint %lx (", BP_NUM(bp));
520 xmon_print_symbol(regs->nip, " ", ")\n");
522 if (unrecoverable_excp(regs))
523 printf("WARNING: exception is not recoverable, "
526 disable_surveillance();
527 /* for breakpoint or single step, print the current instr. */
528 if (bp || TRAP(regs) == 0xd00)
529 ppc_inst_dump(regs->nip, 1, 0);
530 printf("enter ? for help\n");
540 if (regs->msr & MSR_DE) {
541 bp = at_breakpoint(regs->nip);
543 regs->nip = (unsigned long) &bp->instr[0];
544 atomic_inc(&bp->ref_count);
548 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
549 bp = at_breakpoint(regs->nip);
551 int stepped = emulate_step(regs, bp->instr[0]);
553 regs->nip = (unsigned long) &bp->instr[0];
554 atomic_inc(&bp->ref_count);
555 } else if (stepped < 0) {
556 printf("Couldn't single-step %s instruction\n",
557 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
564 touch_nmi_watchdog();
565 local_irq_restore(flags);
567 return cmd != 'X' && cmd != EOF;
570 int xmon(struct pt_regs *excp)
575 ppc_save_regs(®s);
579 return xmon_core(excp, 0);
583 irqreturn_t xmon_irq(int irq, void *d)
586 local_irq_save(flags);
587 printf("Keyboard interrupt\n");
588 xmon(get_irq_regs());
589 local_irq_restore(flags);
593 static int xmon_bpt(struct pt_regs *regs)
596 unsigned long offset;
598 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
601 /* Are we at the trap at bp->instr[1] for some bp? */
602 bp = in_breakpoint_table(regs->nip, &offset);
603 if (bp != NULL && offset == 4) {
604 regs->nip = bp->address + 4;
605 atomic_dec(&bp->ref_count);
609 /* Are we at a breakpoint? */
610 bp = at_breakpoint(regs->nip);
619 static int xmon_sstep(struct pt_regs *regs)
627 static int xmon_break_match(struct pt_regs *regs)
629 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
631 if (dabr.enabled == 0)
637 static int xmon_iabr_match(struct pt_regs *regs)
639 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
647 static int xmon_ipi(struct pt_regs *regs)
650 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
656 static int xmon_fault_handler(struct pt_regs *regs)
659 unsigned long offset;
661 if (in_xmon && catch_memory_errors)
662 handle_fault(regs); /* doesn't return */
664 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
665 bp = in_breakpoint_table(regs->nip, &offset);
667 regs->nip = bp->address + offset;
668 atomic_dec(&bp->ref_count);
675 static struct bpt *at_breakpoint(unsigned long pc)
681 for (i = 0; i < NBPTS; ++i, ++bp)
682 if (bp->enabled && pc == bp->address)
687 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
691 off = nip - (unsigned long) bpts;
692 if (off >= sizeof(bpts))
694 off %= sizeof(struct bpt);
695 if (off != offsetof(struct bpt, instr[0])
696 && off != offsetof(struct bpt, instr[1]))
698 *offp = off - offsetof(struct bpt, instr[0]);
699 return (struct bpt *) (nip - off);
702 static struct bpt *new_breakpoint(unsigned long a)
707 bp = at_breakpoint(a);
711 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
712 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
714 bp->instr[1] = bpinstr;
715 store_inst(&bp->instr[1]);
720 printf("Sorry, no free breakpoints. Please clear one first.\n");
724 static void insert_bpts(void)
730 for (i = 0; i < NBPTS; ++i, ++bp) {
731 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
733 if (mread(bp->address, &bp->instr[0], 4) != 4) {
734 printf("Couldn't read instruction at %lx, "
735 "disabling breakpoint there\n", bp->address);
739 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
740 printf("Breakpoint at %lx is on an mtmsrd or rfid "
741 "instruction, disabling it\n", bp->address);
745 store_inst(&bp->instr[0]);
746 if (bp->enabled & BP_IABR)
748 if (mwrite(bp->address, &bpinstr, 4) != 4) {
749 printf("Couldn't write instruction at %lx, "
750 "disabling breakpoint there\n", bp->address);
751 bp->enabled &= ~BP_TRAP;
754 store_inst((void *)bp->address);
758 static void insert_cpu_bpts(void)
760 struct arch_hw_breakpoint brk;
763 brk.address = dabr.address;
764 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
766 __set_breakpoint(&brk);
768 if (iabr && cpu_has_feature(CPU_FTR_IABR))
769 mtspr(SPRN_IABR, iabr->address
770 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
773 static void remove_bpts(void)
780 for (i = 0; i < NBPTS; ++i, ++bp) {
781 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
783 if (mread(bp->address, &instr, 4) == 4
785 && mwrite(bp->address, &bp->instr, 4) != 4)
786 printf("Couldn't remove breakpoint at %lx\n",
789 store_inst((void *)bp->address);
793 static void remove_cpu_bpts(void)
795 hw_breakpoint_disable();
796 if (cpu_has_feature(CPU_FTR_IABR))
800 /* Command interpreting routine */
801 static char *last_cmd;
804 cmds(struct pt_regs *excp)
811 if (!xmon_no_auto_backtrace) {
812 xmon_no_auto_backtrace = 1;
813 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
818 printf("%x:", smp_processor_id());
819 #endif /* CONFIG_SMP */
825 if (last_cmd == NULL)
827 take_input(last_cmd);
861 prregs(excp); /* print regs */
876 if (do_spu_cmd() == 0)
885 printf(" <no input ...>\n");
889 xmon_puts(help_string);
907 #ifdef CONFIG_PPC_STD_MMU
911 #elif defined(CONFIG_4xx)
915 #elif defined(CONFIG_PPC_BOOK3E)
921 printf("Unrecognized command: ");
923 if (' ' < cmd && cmd <= '~')
926 printf("\\x%x", cmd);
928 } while (cmd != '\n');
929 printf(" (type ? for help)\n");
936 static int do_step(struct pt_regs *regs)
939 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
944 * Step a single instruction.
945 * Some instructions we emulate, others we execute with MSR_SE set.
947 static int do_step(struct pt_regs *regs)
952 /* check we are in 64-bit kernel mode, translation enabled */
953 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
954 if (mread(regs->nip, &instr, 4) == 4) {
955 stepped = emulate_step(regs, instr);
957 printf("Couldn't single-step %s instruction\n",
958 (IS_RFID(instr)? "rfid": "mtmsrd"));
962 regs->trap = 0xd00 | (regs->trap & 1);
963 printf("stepped to ");
964 xmon_print_symbol(regs->nip, " ", "\n");
965 ppc_inst_dump(regs->nip, 1, 0);
975 static void bootcmds(void)
981 ppc_md.restart(NULL);
988 static int cpu_cmd(void)
991 unsigned long cpu, first_cpu, last_cpu;
994 if (!scanhex(&cpu)) {
995 /* print cpus waiting or in xmon */
996 printf("cpus stopped:");
997 last_cpu = first_cpu = NR_CPUS;
998 for_each_possible_cpu(cpu) {
999 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1000 if (cpu == last_cpu + 1) {
1003 if (last_cpu != first_cpu)
1004 printf("-0x%lx", last_cpu);
1005 last_cpu = first_cpu = cpu;
1006 printf(" 0x%lx", cpu);
1010 if (last_cpu != first_cpu)
1011 printf("-0x%lx", last_cpu);
1015 /* try to switch to cpu specified */
1016 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1017 printf("cpu 0x%x isn't in xmon\n", cpu);
1024 while (!xmon_taken) {
1025 if (--timeout == 0) {
1026 if (test_and_set_bit(0, &xmon_taken))
1028 /* take control back */
1030 xmon_owner = smp_processor_id();
1031 printf("cpu 0x%x didn't take control\n", cpu);
1039 #endif /* CONFIG_SMP */
1042 static unsigned short fcstab[256] = {
1043 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1044 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1045 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1046 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1047 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1048 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1049 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1050 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1051 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1052 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1053 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1054 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1055 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1056 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1057 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1058 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1059 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1060 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1061 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1062 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1063 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1064 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1065 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1066 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1067 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1068 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1069 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1070 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1071 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1072 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1073 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1074 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1077 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1086 if (!scanhex(&adrs))
1088 if (!scanhex(&ncsum))
1091 for (i = 0; i < ncsum; ++i) {
1092 if (mread(adrs+i, &v, 1) == 0) {
1093 printf("csum stopped at "REG"\n", adrs+i);
1098 printf("%x\n", fcs);
1102 * Check if this is a suitable place to put a breakpoint.
1104 static long check_bp_loc(unsigned long addr)
1109 if (!is_kernel_addr(addr)) {
1110 printf("Breakpoints may only be placed at kernel addresses\n");
1113 if (!mread(addr, &instr, sizeof(instr))) {
1114 printf("Can't read instruction at address %lx\n", addr);
1117 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1118 printf("Breakpoints may not be placed on mtmsrd or rfid "
1125 static char *breakpoint_help_string =
1126 "Breakpoint command usage:\n"
1127 "b show breakpoints\n"
1128 "b <addr> [cnt] set breakpoint at given instr addr\n"
1129 "bc clear all breakpoints\n"
1130 "bc <n/addr> clear breakpoint number n or at addr\n"
1131 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1132 "bd <addr> [cnt] set hardware data breakpoint\n"
1142 const char badaddr[] = "Only kernel addresses are permitted "
1143 "for breakpoints\n";
1148 case 'd': /* bd - hardware data breakpoint */
1153 else if (cmd == 'w')
1159 if (scanhex(&dabr.address)) {
1160 if (!is_kernel_addr(dabr.address)) {
1164 dabr.address &= ~HW_BRK_TYPE_DABR;
1165 dabr.enabled = mode | BP_DABR;
1169 case 'i': /* bi - hardware instr breakpoint */
1170 if (!cpu_has_feature(CPU_FTR_IABR)) {
1171 printf("Hardware instruction breakpoint "
1172 "not supported on this cpu\n");
1176 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1181 if (!check_bp_loc(a))
1183 bp = new_breakpoint(a);
1185 bp->enabled |= BP_IABR | BP_IABR_TE;
1193 /* clear all breakpoints */
1194 for (i = 0; i < NBPTS; ++i)
1195 bpts[i].enabled = 0;
1198 printf("All breakpoints cleared\n");
1202 if (a <= NBPTS && a >= 1) {
1203 /* assume a breakpoint number */
1204 bp = &bpts[a-1]; /* bp nums are 1 based */
1206 /* assume a breakpoint address */
1207 bp = at_breakpoint(a);
1209 printf("No breakpoint at %lx\n", a);
1214 printf("Cleared breakpoint %lx (", BP_NUM(bp));
1215 xmon_print_symbol(bp->address, " ", ")\n");
1223 printf(breakpoint_help_string);
1228 /* print all breakpoints */
1229 printf(" type address\n");
1231 printf(" data "REG" [", dabr.address);
1232 if (dabr.enabled & 1)
1234 if (dabr.enabled & 2)
1238 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1241 printf("%2x %s ", BP_NUM(bp),
1242 (bp->enabled & BP_IABR)? "inst": "trap");
1243 xmon_print_symbol(bp->address, " ", "\n");
1248 if (!check_bp_loc(a))
1250 bp = new_breakpoint(a);
1252 bp->enabled |= BP_TRAP;
1257 /* Very cheap human name for vector lookup. */
1259 const char *getvecname(unsigned long vec)
1264 case 0x100: ret = "(System Reset)"; break;
1265 case 0x200: ret = "(Machine Check)"; break;
1266 case 0x300: ret = "(Data Access)"; break;
1267 case 0x380: ret = "(Data SLB Access)"; break;
1268 case 0x400: ret = "(Instruction Access)"; break;
1269 case 0x480: ret = "(Instruction SLB Access)"; break;
1270 case 0x500: ret = "(Hardware Interrupt)"; break;
1271 case 0x600: ret = "(Alignment)"; break;
1272 case 0x700: ret = "(Program Check)"; break;
1273 case 0x800: ret = "(FPU Unavailable)"; break;
1274 case 0x900: ret = "(Decrementer)"; break;
1275 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1276 case 0xa00: ret = "(Doorbell)"; break;
1277 case 0xc00: ret = "(System Call)"; break;
1278 case 0xd00: ret = "(Single Step)"; break;
1279 case 0xe40: ret = "(Emulation Assist)"; break;
1280 case 0xe60: ret = "(HMI)"; break;
1281 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1282 case 0xf00: ret = "(Performance Monitor)"; break;
1283 case 0xf20: ret = "(Altivec Unavailable)"; break;
1284 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1285 case 0x1500: ret = "(Denormalisation)"; break;
1286 case 0x1700: ret = "(Altivec Assist)"; break;
1292 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1293 unsigned long *endp)
1295 unsigned long size, offset;
1298 *startp = *endp = 0;
1301 if (setjmp(bus_error_jmp) == 0) {
1302 catch_memory_errors = 1;
1304 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1306 *startp = pc - offset;
1307 *endp = pc - offset + size;
1311 catch_memory_errors = 0;
1314 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1315 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1317 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1320 int max_to_print = 64;
1322 unsigned long newsp;
1323 unsigned long marker;
1324 struct pt_regs regs;
1326 while (max_to_print--) {
1327 if (sp < PAGE_OFFSET) {
1329 printf("SP (%lx) is in userspace\n", sp);
1333 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1334 || !mread(sp, &newsp, sizeof(unsigned long))) {
1335 printf("Couldn't read stack frame at %lx\n", sp);
1340 * For the first stack frame, try to work out if
1341 * LR and/or the saved LR value in the bottommost
1342 * stack frame are valid.
1344 if ((pc | lr) != 0) {
1345 unsigned long fnstart, fnend;
1346 unsigned long nextip;
1349 get_function_bounds(pc, &fnstart, &fnend);
1352 mread(newsp + LRSAVE_OFFSET, &nextip,
1353 sizeof(unsigned long));
1355 if (lr < PAGE_OFFSET
1356 || (fnstart <= lr && lr < fnend))
1358 } else if (lr == nextip) {
1360 } else if (lr >= PAGE_OFFSET
1361 && !(fnstart <= lr && lr < fnend)) {
1362 printf("[link register ] ");
1363 xmon_print_symbol(lr, " ", "\n");
1366 printf("["REG"] ", sp);
1367 xmon_print_symbol(ip, " ", " (unreliable)\n");
1372 printf("["REG"] ", sp);
1373 xmon_print_symbol(ip, " ", "\n");
1376 /* Look for "regshere" marker to see if this is
1377 an exception frame. */
1378 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1379 && marker == STACK_FRAME_REGS_MARKER) {
1380 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1382 printf("Couldn't read registers at %lx\n",
1383 sp + STACK_FRAME_OVERHEAD);
1386 printf("--- Exception: %lx %s at ", regs.trap,
1387 getvecname(TRAP(®s)));
1390 xmon_print_symbol(pc, " ", "\n");
1400 static void backtrace(struct pt_regs *excp)
1405 xmon_show_stack(sp, 0, 0);
1407 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1411 static void print_bug_trap(struct pt_regs *regs)
1414 const struct bug_entry *bug;
1417 if (regs->msr & MSR_PR)
1418 return; /* not in kernel */
1419 addr = regs->nip; /* address of trap instruction */
1420 if (addr < PAGE_OFFSET)
1422 bug = find_bug(regs->nip);
1425 if (is_warning_bug(bug))
1428 #ifdef CONFIG_DEBUG_BUGVERBOSE
1429 printf("kernel BUG at %s:%u!\n",
1430 bug->file, bug->line);
1432 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1434 #endif /* CONFIG_BUG */
1437 static void excprint(struct pt_regs *fp)
1442 printf("cpu 0x%x: ", smp_processor_id());
1443 #endif /* CONFIG_SMP */
1446 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1448 xmon_print_symbol(fp->nip, ": ", "\n");
1450 printf(" lr: ", fp->link);
1451 xmon_print_symbol(fp->link, ": ", "\n");
1453 printf(" sp: %lx\n", fp->gpr[1]);
1454 printf(" msr: %lx\n", fp->msr);
1456 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1457 printf(" dar: %lx\n", fp->dar);
1459 printf(" dsisr: %lx\n", fp->dsisr);
1462 printf(" current = 0x%lx\n", current);
1464 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1465 local_paca, local_paca->soft_enabled, local_paca->irq_happened);
1468 printf(" pid = %ld, comm = %s\n",
1469 current->pid, current->comm);
1476 static void prregs(struct pt_regs *fp)
1480 struct pt_regs regs;
1482 if (scanhex(&base)) {
1483 if (setjmp(bus_error_jmp) == 0) {
1484 catch_memory_errors = 1;
1486 regs = *(struct pt_regs *)base;
1490 catch_memory_errors = 0;
1491 printf("*** Error reading registers from "REG"\n",
1495 catch_memory_errors = 0;
1500 if (FULL_REGS(fp)) {
1501 for (n = 0; n < 16; ++n)
1502 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1503 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1505 for (n = 0; n < 7; ++n)
1506 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1507 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1510 for (n = 0; n < 32; ++n) {
1511 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1512 (n & 3) == 3? "\n": " ");
1513 if (n == 12 && !FULL_REGS(fp)) {
1520 xmon_print_symbol(fp->nip, " ", "\n");
1521 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1523 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1526 xmon_print_symbol(fp->link, " ", "\n");
1527 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1528 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1529 fp->ctr, fp->xer, fp->trap);
1531 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1532 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1535 static void cacheflush(void)
1538 unsigned long nflush;
1543 scanhex((void *)&adrs);
1548 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1549 if (setjmp(bus_error_jmp) == 0) {
1550 catch_memory_errors = 1;
1554 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1555 cflush((void *) adrs);
1557 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1558 cinval((void *) adrs);
1561 /* wait a little while to see if we get a machine check */
1564 catch_memory_errors = 0;
1567 static unsigned long
1570 unsigned int instrs[2];
1571 unsigned long (*code)(void);
1572 unsigned long ret = -1UL;
1574 unsigned long opd[3];
1576 opd[0] = (unsigned long)instrs;
1579 code = (unsigned long (*)(void)) opd;
1581 code = (unsigned long (*)(void)) instrs;
1584 /* mfspr r3,n; blr */
1585 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1586 instrs[1] = 0x4e800020;
1588 store_inst(instrs+1);
1590 if (setjmp(bus_error_jmp) == 0) {
1591 catch_memory_errors = 1;
1597 /* wait a little while to see if we get a machine check */
1606 write_spr(int n, unsigned long val)
1608 unsigned int instrs[2];
1609 unsigned long (*code)(unsigned long);
1611 unsigned long opd[3];
1613 opd[0] = (unsigned long)instrs;
1616 code = (unsigned long (*)(unsigned long)) opd;
1618 code = (unsigned long (*)(unsigned long)) instrs;
1621 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1622 instrs[1] = 0x4e800020;
1624 store_inst(instrs+1);
1626 if (setjmp(bus_error_jmp) == 0) {
1627 catch_memory_errors = 1;
1633 /* wait a little while to see if we get a machine check */
1639 static unsigned long regno;
1640 extern char exc_prolog;
1641 extern char dec_exc;
1643 static void super_regs(void)
1650 unsigned long sp, toc;
1651 asm("mr %0,1" : "=r" (sp) :);
1652 asm("mr %0,2" : "=r" (toc) :);
1654 printf("msr = "REG" sprg0= "REG"\n",
1655 mfmsr(), mfspr(SPRN_SPRG0));
1656 printf("pvr = "REG" sprg1= "REG"\n",
1657 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1658 printf("dec = "REG" sprg2= "REG"\n",
1659 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1660 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1661 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1669 val = read_spr(regno);
1671 write_spr(regno, val);
1674 printf("spr %lx = %lx\n", regno, read_spr(regno));
1681 * Stuff for reading and writing memory safely
1684 mread(unsigned long adrs, void *buf, int size)
1690 if (setjmp(bus_error_jmp) == 0) {
1691 catch_memory_errors = 1;
1697 *(u16 *)q = *(u16 *)p;
1700 *(u32 *)q = *(u32 *)p;
1703 *(u64 *)q = *(u64 *)p;
1706 for( ; n < size; ++n) {
1712 /* wait a little while to see if we get a machine check */
1716 catch_memory_errors = 0;
1721 mwrite(unsigned long adrs, void *buf, int size)
1727 if (setjmp(bus_error_jmp) == 0) {
1728 catch_memory_errors = 1;
1734 *(u16 *)p = *(u16 *)q;
1737 *(u32 *)p = *(u32 *)q;
1740 *(u64 *)p = *(u64 *)q;
1743 for ( ; n < size; ++n) {
1749 /* wait a little while to see if we get a machine check */
1753 printf("*** Error writing address "REG"\n", adrs + n);
1755 catch_memory_errors = 0;
1759 static int fault_type;
1760 static int fault_except;
1761 static char *fault_chars[] = { "--", "**", "##" };
1763 static int handle_fault(struct pt_regs *regs)
1765 fault_except = TRAP(regs);
1766 switch (TRAP(regs)) {
1778 longjmp(bus_error_jmp, 1);
1783 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1786 byterev(unsigned char *val, int size)
1792 SWAP(val[0], val[1], t);
1795 SWAP(val[0], val[3], t);
1796 SWAP(val[1], val[2], t);
1798 case 8: /* is there really any use for this? */
1799 SWAP(val[0], val[7], t);
1800 SWAP(val[1], val[6], t);
1801 SWAP(val[2], val[5], t);
1802 SWAP(val[3], val[4], t);
1810 static char *memex_help_string =
1811 "Memory examine command usage:\n"
1812 "m [addr] [flags] examine/change memory\n"
1813 " addr is optional. will start where left off.\n"
1814 " flags may include chars from this set:\n"
1815 " b modify by bytes (default)\n"
1816 " w modify by words (2 byte)\n"
1817 " l modify by longs (4 byte)\n"
1818 " d modify by doubleword (8 byte)\n"
1819 " r toggle reverse byte order mode\n"
1820 " n do not read memory (for i/o spaces)\n"
1821 " . ok to read (default)\n"
1822 "NOTE: flags are saved as defaults\n"
1825 static char *memex_subcmd_help_string =
1826 "Memory examine subcommands:\n"
1827 " hexval write this val to current location\n"
1828 " 'string' write chars from string to this location\n"
1829 " ' increment address\n"
1830 " ^ decrement address\n"
1831 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1832 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1833 " ` clear no-read flag\n"
1834 " ; stay at this addr\n"
1835 " v change to byte mode\n"
1836 " w change to word (2 byte) mode\n"
1837 " l change to long (4 byte) mode\n"
1838 " u change to doubleword (8 byte) mode\n"
1839 " m addr change current addr\n"
1840 " n toggle no-read flag\n"
1841 " r toggle byte reverse flag\n"
1842 " < count back up count bytes\n"
1843 " > count skip forward count bytes\n"
1844 " x exit this mode\n"
1850 int cmd, inc, i, nslash;
1852 unsigned char val[16];
1854 scanhex((void *)&adrs);
1857 printf(memex_help_string);
1863 while ((cmd = skipbl()) != '\n') {
1865 case 'b': size = 1; break;
1866 case 'w': size = 2; break;
1867 case 'l': size = 4; break;
1868 case 'd': size = 8; break;
1869 case 'r': brev = !brev; break;
1870 case 'n': mnoread = 1; break;
1871 case '.': mnoread = 0; break;
1880 n = mread(adrs, val, size);
1881 printf(REG"%c", adrs, brev? 'r': ' ');
1886 for (i = 0; i < n; ++i)
1887 printf("%.2x", val[i]);
1888 for (; i < size; ++i)
1889 printf("%s", fault_chars[fault_type]);
1896 for (i = 0; i < size; ++i)
1897 val[i] = n >> (i * 8);
1900 mwrite(adrs, val, size);
1913 else if( n == '\'' )
1915 for (i = 0; i < size; ++i)
1916 val[i] = n >> (i * 8);
1919 mwrite(adrs, val, size);
1956 adrs -= 1 << nslash;
1960 adrs += 1 << nslash;
1964 adrs += 1 << -nslash;
1968 adrs -= 1 << -nslash;
1971 scanhex((void *)&adrs);
1990 printf(memex_subcmd_help_string);
2005 case 'n': c = '\n'; break;
2006 case 'r': c = '\r'; break;
2007 case 'b': c = '\b'; break;
2008 case 't': c = '\t'; break;
2013 static void xmon_rawdump (unsigned long adrs, long ndump)
2016 unsigned char temp[16];
2018 for (n = ndump; n > 0;) {
2020 nr = mread(adrs, temp, r);
2022 for (m = 0; m < r; ++m) {
2024 printf("%.2x", temp[m]);
2026 printf("%s", fault_chars[fault_type]);
2036 static void dump_one_paca(int cpu)
2038 struct paca_struct *p;
2040 if (setjmp(bus_error_jmp) != 0) {
2041 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2045 catch_memory_errors = 1;
2050 printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2052 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
2053 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
2054 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
2056 #define DUMP(paca, name, format) \
2057 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2058 offsetof(struct paca_struct, name));
2060 DUMP(p, lock_token, "x");
2061 DUMP(p, paca_index, "x");
2062 DUMP(p, kernel_toc, "lx");
2063 DUMP(p, kernelbase, "lx");
2064 DUMP(p, kernel_msr, "lx");
2065 DUMP(p, emergency_sp, "p");
2066 #ifdef CONFIG_PPC_BOOK3S_64
2067 DUMP(p, mc_emergency_sp, "p");
2068 DUMP(p, in_mce, "x");
2070 DUMP(p, data_offset, "lx");
2071 DUMP(p, hw_cpu_id, "x");
2072 DUMP(p, cpu_start, "x");
2073 DUMP(p, kexec_state, "x");
2074 DUMP(p, __current, "p");
2075 DUMP(p, kstack, "lx");
2076 DUMP(p, stab_rr, "lx");
2077 DUMP(p, saved_r1, "lx");
2078 DUMP(p, trap_save, "x");
2079 DUMP(p, soft_enabled, "x");
2080 DUMP(p, irq_happened, "x");
2081 DUMP(p, io_sync, "x");
2082 DUMP(p, irq_work_pending, "x");
2083 DUMP(p, nap_state_lost, "x");
2087 catch_memory_errors = 0;
2091 static void dump_all_pacas(void)
2095 if (num_possible_cpus() == 0) {
2096 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2100 for_each_possible_cpu(cpu)
2104 static void dump_pacas(void)
2115 termch = c; /* Put c back, it wasn't 'a' */
2120 dump_one_paca(xmon_owner);
2124 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2125 || ('a' <= (c) && (c) <= 'f') \
2126 || ('A' <= (c) && (c) <= 'F'))
2141 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2143 scanhex((void *)&adrs);
2150 else if (nidump > MAX_DUMP)
2152 adrs += ppc_inst_dump(adrs, nidump, 1);
2154 } else if (c == 'l') {
2156 } else if (c == 'r') {
2160 xmon_rawdump(adrs, ndump);
2167 else if (ndump > MAX_DUMP)
2169 prdump(adrs, ndump);
2176 prdump(unsigned long adrs, long ndump)
2178 long n, m, c, r, nr;
2179 unsigned char temp[16];
2181 for (n = ndump; n > 0;) {
2185 nr = mread(adrs, temp, r);
2187 for (m = 0; m < r; ++m) {
2188 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2191 printf("%.2x", temp[m]);
2193 printf("%s", fault_chars[fault_type]);
2195 for (; m < 16; ++m) {
2196 if ((m & (sizeof(long) - 1)) == 0)
2201 for (m = 0; m < r; ++m) {
2204 putchar(' ' <= c && c <= '~'? c: '.');
2217 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2220 generic_inst_dump(unsigned long adr, long count, int praddr,
2221 instruction_dump_func dump_func)
2224 unsigned long first_adr;
2225 unsigned long inst, last_inst = 0;
2226 unsigned char val[4];
2229 for (first_adr = adr; count > 0; --count, adr += 4) {
2230 nr = mread(adr, val, 4);
2233 const char *x = fault_chars[fault_type];
2234 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2238 inst = GETWORD(val);
2239 if (adr > first_adr && inst == last_inst) {
2249 printf(REG" %.8x", adr, inst);
2251 dump_func(inst, adr);
2254 return adr - first_adr;
2258 ppc_inst_dump(unsigned long adr, long count, int praddr)
2260 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2264 print_address(unsigned long addr)
2266 xmon_print_symbol(addr, "\t# ", "");
2272 struct kmsg_dumper dumper = { .active = 1 };
2273 unsigned char buf[128];
2276 if (setjmp(bus_error_jmp) != 0) {
2277 printf("Error dumping printk buffer!\n");
2281 catch_memory_errors = 1;
2284 kmsg_dump_rewind_nolock(&dumper);
2285 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2291 /* wait a little while to see if we get a machine check */
2293 catch_memory_errors = 0;
2297 * Memory operations - move, set, print differences
2299 static unsigned long mdest; /* destination address */
2300 static unsigned long msrc; /* source address */
2301 static unsigned long mval; /* byte value to set memory to */
2302 static unsigned long mcount; /* # bytes to affect */
2303 static unsigned long mdiffs; /* max # differences to print */
2308 scanhex((void *)&mdest);
2309 if( termch != '\n' )
2311 scanhex((void *)(cmd == 's'? &mval: &msrc));
2312 if( termch != '\n' )
2314 scanhex((void *)&mcount);
2317 memmove((void *)mdest, (void *)msrc, mcount);
2320 memset((void *)mdest, mval, mcount);
2323 if( termch != '\n' )
2325 scanhex((void *)&mdiffs);
2326 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2332 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2337 for( n = nb; n > 0; --n )
2338 if( *p1++ != *p2++ )
2339 if( ++prt <= maxpr )
2340 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2341 p1[-1], p2 - 1, p2[-1]);
2343 printf("Total of %d differences\n", prt);
2346 static unsigned mend;
2347 static unsigned mask;
2353 unsigned char val[4];
2356 scanhex((void *)&mdest);
2357 if (termch != '\n') {
2359 scanhex((void *)&mend);
2360 if (termch != '\n') {
2362 scanhex((void *)&mval);
2364 if (termch != '\n') termch = 0;
2365 scanhex((void *)&mask);
2369 for (a = mdest; a < mend; a += 4) {
2370 if (mread(a, val, 4) == 4
2371 && ((GETWORD(val) ^ mval) & mask) == 0) {
2372 printf("%.16x: %.16x\n", a, GETWORD(val));
2379 static unsigned long mskip = 0x1000;
2380 static unsigned long mlim = 0xffffffff;
2390 if (termch != '\n') termch = 0;
2392 if (termch != '\n') termch = 0;
2395 for (a = mdest; a < mlim; a += mskip) {
2396 ok = mread(a, &v, 1);
2398 printf("%.8x .. ", a);
2399 } else if (!ok && ook)
2400 printf("%.8x\n", a - mskip);
2406 printf("%.8x\n", a - mskip);
2409 static void proccall(void)
2411 unsigned long args[8];
2414 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2415 unsigned long, unsigned long, unsigned long,
2416 unsigned long, unsigned long, unsigned long);
2419 if (!scanhex(&adrs))
2423 for (i = 0; i < 8; ++i)
2425 for (i = 0; i < 8; ++i) {
2426 if (!scanhex(&args[i]) || termch == '\n')
2430 func = (callfunc_t) adrs;
2432 if (setjmp(bus_error_jmp) == 0) {
2433 catch_memory_errors = 1;
2435 ret = func(args[0], args[1], args[2], args[3],
2436 args[4], args[5], args[6], args[7]);
2438 printf("return value is 0x%lx\n", ret);
2440 printf("*** %x exception occurred\n", fault_except);
2442 catch_memory_errors = 0;
2445 /* Input scanning routines */
2456 while( c == ' ' || c == '\t' )
2462 static char *regnames[N_PTREGS] = {
2463 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2464 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2465 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2466 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2467 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2473 "trap", "dar", "dsisr", "res"
2477 scanhex(unsigned long *vp)
2484 /* parse register name */
2488 for (i = 0; i < sizeof(regname) - 1; ++i) {
2497 for (i = 0; i < N_PTREGS; ++i) {
2498 if (strcmp(regnames[i], regname) == 0) {
2499 if (xmon_regs == NULL) {
2500 printf("regs not available\n");
2503 *vp = ((unsigned long *)xmon_regs)[i];
2507 printf("invalid register name '%%%s'\n", regname);
2511 /* skip leading "0x" if any */
2525 } else if (c == '$') {
2527 for (i=0; i<63; i++) {
2537 if (setjmp(bus_error_jmp) == 0) {
2538 catch_memory_errors = 1;
2540 *vp = kallsyms_lookup_name(tmpstr);
2543 catch_memory_errors = 0;
2545 printf("unknown symbol '%s'\n", tmpstr);
2578 static int hexdigit(int c)
2580 if( '0' <= c && c <= '9' )
2582 if( 'A' <= c && c <= 'F' )
2583 return c - ('A' - 10);
2584 if( 'a' <= c && c <= 'f' )
2585 return c - ('a' - 10);
2590 getstring(char *s, int size)
2601 } while( c != ' ' && c != '\t' && c != '\n' );
2606 static char line[256];
2607 static char *lineptr;
2618 if (lineptr == NULL || *lineptr == 0) {
2619 if (xmon_gets(line, sizeof(line)) == NULL) {
2629 take_input(char *str)
2638 int type = inchar();
2640 static char tmp[64];
2645 xmon_print_symbol(addr, ": ", "\n");
2650 if (setjmp(bus_error_jmp) == 0) {
2651 catch_memory_errors = 1;
2653 addr = kallsyms_lookup_name(tmp);
2655 printf("%s: %lx\n", tmp, addr);
2657 printf("Symbol '%s' not found.\n", tmp);
2660 catch_memory_errors = 0;
2667 /* Print an address in numeric and symbolic form (if possible) */
2668 static void xmon_print_symbol(unsigned long address, const char *mid,
2672 const char *name = NULL;
2673 unsigned long offset, size;
2675 printf(REG, address);
2676 if (setjmp(bus_error_jmp) == 0) {
2677 catch_memory_errors = 1;
2679 name = kallsyms_lookup(address, &size, &offset, &modname,
2682 /* wait a little while to see if we get a machine check */
2686 catch_memory_errors = 0;
2689 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2691 printf(" [%s]", modname);
2693 printf("%s", after);
2696 #ifdef CONFIG_PPC_BOOK3S_64
2697 void dump_segments(void)
2700 unsigned long esid,vsid,valid;
2703 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2705 for (i = 0; i < mmu_slb_size; i++) {
2706 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2707 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2708 valid = (esid & SLB_ESID_V);
2709 if (valid | esid | vsid) {
2710 printf("%02d %016lx %016lx", i, esid, vsid);
2712 llp = vsid & SLB_VSID_LLP;
2713 if (vsid & SLB_VSID_B_1T) {
2714 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2716 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2719 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2721 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2731 #ifdef CONFIG_PPC_STD_MMU_32
2732 void dump_segments(void)
2737 for (i = 0; i < 16; ++i)
2738 printf(" %x", mfsrin(i));
2744 static void dump_tlb_44x(void)
2748 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2749 unsigned long w0,w1,w2;
2750 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2751 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2752 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2753 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2754 if (w0 & PPC44x_TLB_VALID) {
2755 printf("V %08x -> %01x%08x %c%c%c%c%c",
2756 w0 & PPC44x_TLB_EPN_MASK,
2757 w1 & PPC44x_TLB_ERPN_MASK,
2758 w1 & PPC44x_TLB_RPN_MASK,
2759 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2760 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2761 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2762 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2763 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2768 #endif /* CONFIG_44x */
2770 #ifdef CONFIG_PPC_BOOK3E
2771 static void dump_tlb_book3e(void)
2773 u32 mmucfg, pidmask, lpidmask;
2775 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2777 static const char *pgsz_names[] = {
2812 /* Gather some infos about the MMU */
2813 mmucfg = mfspr(SPRN_MMUCFG);
2814 mmu_version = (mmucfg & 3) + 1;
2815 ntlbs = ((mmucfg >> 2) & 3) + 1;
2816 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2817 lpidsz = (mmucfg >> 24) & 0xf;
2818 rasz = (mmucfg >> 16) & 0x7f;
2819 if ((mmu_version > 1) && (mmucfg & 0x10000))
2821 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2822 mmu_version, ntlbs, pidsz, lpidsz, rasz);
2823 pidmask = (1ul << pidsz) - 1;
2824 lpidmask = (1ul << lpidsz) - 1;
2825 ramask = (1ull << rasz) - 1;
2827 for (tlb = 0; tlb < ntlbs; tlb++) {
2829 int nent, assoc, new_cc = 1;
2830 printf("TLB %d:\n------\n", tlb);
2833 tlbcfg = mfspr(SPRN_TLB0CFG);
2836 tlbcfg = mfspr(SPRN_TLB1CFG);
2839 tlbcfg = mfspr(SPRN_TLB2CFG);
2842 tlbcfg = mfspr(SPRN_TLB3CFG);
2845 printf("Unsupported TLB number !\n");
2848 nent = tlbcfg & 0xfff;
2849 assoc = (tlbcfg >> 24) & 0xff;
2850 for (i = 0; i < nent; i++) {
2851 u32 mas0 = MAS0_TLBSEL(tlb);
2852 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2855 int esel = i, cc = i;
2863 mas0 |= MAS0_ESEL(esel);
2864 mtspr(SPRN_MAS0, mas0);
2865 mtspr(SPRN_MAS1, mas1);
2866 mtspr(SPRN_MAS2, mas2);
2867 asm volatile("tlbre 0,0,0" : : : "memory");
2868 mas1 = mfspr(SPRN_MAS1);
2869 mas2 = mfspr(SPRN_MAS2);
2870 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2871 if (assoc && (i % assoc) == 0)
2873 if (!(mas1 & MAS1_VALID))
2876 printf("%04x- ", i);
2878 printf("%04x-%c", cc, 'A' + esel);
2880 printf(" |%c", 'A' + esel);
2882 printf(" %016llx %04x %s %c%c AS%c",
2884 (mas1 >> 16) & 0x3fff,
2885 pgsz_names[(mas1 >> 7) & 0x1f],
2886 mas1 & MAS1_IND ? 'I' : ' ',
2887 mas1 & MAS1_IPROT ? 'P' : ' ',
2888 mas1 & MAS1_TS ? '1' : '0');
2889 printf(" %c%c%c%c%c%c%c",
2890 mas2 & MAS2_X0 ? 'a' : ' ',
2891 mas2 & MAS2_X1 ? 'v' : ' ',
2892 mas2 & MAS2_W ? 'w' : ' ',
2893 mas2 & MAS2_I ? 'i' : ' ',
2894 mas2 & MAS2_M ? 'm' : ' ',
2895 mas2 & MAS2_G ? 'g' : ' ',
2896 mas2 & MAS2_E ? 'e' : ' ');
2897 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
2898 if (mas1 & MAS1_IND)
2900 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
2902 printf(" U%c%c%c S%c%c%c\n",
2903 mas7_mas3 & MAS3_UX ? 'x' : ' ',
2904 mas7_mas3 & MAS3_UW ? 'w' : ' ',
2905 mas7_mas3 & MAS3_UR ? 'r' : ' ',
2906 mas7_mas3 & MAS3_SX ? 'x' : ' ',
2907 mas7_mas3 & MAS3_SW ? 'w' : ' ',
2908 mas7_mas3 & MAS3_SR ? 'r' : ' ');
2912 #endif /* CONFIG_PPC_BOOK3E */
2914 static void xmon_init(int enable)
2918 __debugger_ipi = xmon_ipi;
2919 __debugger_bpt = xmon_bpt;
2920 __debugger_sstep = xmon_sstep;
2921 __debugger_iabr_match = xmon_iabr_match;
2922 __debugger_break_match = xmon_break_match;
2923 __debugger_fault_handler = xmon_fault_handler;
2926 __debugger_ipi = NULL;
2927 __debugger_bpt = NULL;
2928 __debugger_sstep = NULL;
2929 __debugger_iabr_match = NULL;
2930 __debugger_break_match = NULL;
2931 __debugger_fault_handler = NULL;
2935 #ifdef CONFIG_MAGIC_SYSRQ
2936 static void sysrq_handle_xmon(int key)
2938 /* ensure xmon is enabled */
2940 debugger(get_irq_regs());
2943 static struct sysrq_key_op sysrq_xmon_op = {
2944 .handler = sysrq_handle_xmon,
2945 .help_msg = "xmon(x)",
2946 .action_msg = "Entering xmon",
2949 static int __init setup_xmon_sysrq(void)
2951 register_sysrq_key('x', &sysrq_xmon_op);
2954 __initcall(setup_xmon_sysrq);
2955 #endif /* CONFIG_MAGIC_SYSRQ */
2957 static int __initdata xmon_early, xmon_off;
2959 static int __init early_parse_xmon(char *p)
2961 if (!p || strncmp(p, "early", 5) == 0) {
2962 /* just "xmon" is equivalent to "xmon=early" */
2965 } else if (strncmp(p, "on", 2) == 0)
2967 else if (strncmp(p, "off", 3) == 0)
2969 else if (strncmp(p, "nobt", 4) == 0)
2970 xmon_no_auto_backtrace = 1;
2976 early_param("xmon", early_parse_xmon);
2978 void __init xmon_setup(void)
2980 #ifdef CONFIG_XMON_DEFAULT
2988 #ifdef CONFIG_SPU_BASE
2992 u64 saved_mfc_sr1_RW;
2993 u32 saved_spu_runcntl_RW;
2994 unsigned long dump_addr;
2998 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3000 static struct spu_info spu_info[XMON_NUM_SPUS];
3002 void xmon_register_spus(struct list_head *list)
3006 list_for_each_entry(spu, list, full_list) {
3007 if (spu->number >= XMON_NUM_SPUS) {
3012 spu_info[spu->number].spu = spu;
3013 spu_info[spu->number].stopped_ok = 0;
3014 spu_info[spu->number].dump_addr = (unsigned long)
3015 spu_info[spu->number].spu->local_store;
3019 static void stop_spus(void)
3025 for (i = 0; i < XMON_NUM_SPUS; i++) {
3026 if (!spu_info[i].spu)
3029 if (setjmp(bus_error_jmp) == 0) {
3030 catch_memory_errors = 1;
3033 spu = spu_info[i].spu;
3035 spu_info[i].saved_spu_runcntl_RW =
3036 in_be32(&spu->problem->spu_runcntl_RW);
3038 tmp = spu_mfc_sr1_get(spu);
3039 spu_info[i].saved_mfc_sr1_RW = tmp;
3041 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3042 spu_mfc_sr1_set(spu, tmp);
3047 spu_info[i].stopped_ok = 1;
3049 printf("Stopped spu %.2d (was %s)\n", i,
3050 spu_info[i].saved_spu_runcntl_RW ?
3051 "running" : "stopped");
3053 catch_memory_errors = 0;
3054 printf("*** Error stopping spu %.2d\n", i);
3056 catch_memory_errors = 0;
3060 static void restart_spus(void)
3065 for (i = 0; i < XMON_NUM_SPUS; i++) {
3066 if (!spu_info[i].spu)
3069 if (!spu_info[i].stopped_ok) {
3070 printf("*** Error, spu %d was not successfully stopped"
3071 ", not restarting\n", i);
3075 if (setjmp(bus_error_jmp) == 0) {
3076 catch_memory_errors = 1;
3079 spu = spu_info[i].spu;
3080 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3081 out_be32(&spu->problem->spu_runcntl_RW,
3082 spu_info[i].saved_spu_runcntl_RW);
3087 printf("Restarted spu %.2d\n", i);
3089 catch_memory_errors = 0;
3090 printf("*** Error restarting spu %.2d\n", i);
3092 catch_memory_errors = 0;
3096 #define DUMP_WIDTH 23
3097 #define DUMP_VALUE(format, field, value) \
3099 if (setjmp(bus_error_jmp) == 0) { \
3100 catch_memory_errors = 1; \
3102 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3107 catch_memory_errors = 0; \
3108 printf(" %-*s = *** Error reading field.\n", \
3109 DUMP_WIDTH, #field); \
3111 catch_memory_errors = 0; \
3114 #define DUMP_FIELD(obj, format, field) \
3115 DUMP_VALUE(format, field, obj->field)
3117 static void dump_spu_fields(struct spu *spu)
3119 printf("Dumping spu fields at address %p:\n", spu);
3121 DUMP_FIELD(spu, "0x%x", number);
3122 DUMP_FIELD(spu, "%s", name);
3123 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3124 DUMP_FIELD(spu, "0x%p", local_store);
3125 DUMP_FIELD(spu, "0x%lx", ls_size);
3126 DUMP_FIELD(spu, "0x%x", node);
3127 DUMP_FIELD(spu, "0x%lx", flags);
3128 DUMP_FIELD(spu, "%d", class_0_pending);
3129 DUMP_FIELD(spu, "0x%lx", class_0_dar);
3130 DUMP_FIELD(spu, "0x%lx", class_1_dar);
3131 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3132 DUMP_FIELD(spu, "0x%lx", irqs[0]);
3133 DUMP_FIELD(spu, "0x%lx", irqs[1]);
3134 DUMP_FIELD(spu, "0x%lx", irqs[2]);
3135 DUMP_FIELD(spu, "0x%x", slb_replace);
3136 DUMP_FIELD(spu, "%d", pid);
3137 DUMP_FIELD(spu, "0x%p", mm);
3138 DUMP_FIELD(spu, "0x%p", ctx);
3139 DUMP_FIELD(spu, "0x%p", rq);
3140 DUMP_FIELD(spu, "0x%p", timestamp);
3141 DUMP_FIELD(spu, "0x%lx", problem_phys);
3142 DUMP_FIELD(spu, "0x%p", problem);
3143 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3144 in_be32(&spu->problem->spu_runcntl_RW));
3145 DUMP_VALUE("0x%x", problem->spu_status_R,
3146 in_be32(&spu->problem->spu_status_R));
3147 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3148 in_be32(&spu->problem->spu_npc_RW));
3149 DUMP_FIELD(spu, "0x%p", priv2);
3150 DUMP_FIELD(spu, "0x%p", pdata);
3154 spu_inst_dump(unsigned long adr, long count, int praddr)
3156 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3159 static void dump_spu_ls(unsigned long num, int subcmd)
3161 unsigned long offset, addr, ls_addr;
3163 if (setjmp(bus_error_jmp) == 0) {
3164 catch_memory_errors = 1;
3166 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3170 catch_memory_errors = 0;
3171 printf("*** Error: accessing spu info for spu %d\n", num);
3174 catch_memory_errors = 0;
3176 if (scanhex(&offset))
3177 addr = ls_addr + offset;
3179 addr = spu_info[num].dump_addr;
3181 if (addr >= ls_addr + LS_SIZE) {
3182 printf("*** Error: address outside of local store\n");
3188 addr += spu_inst_dump(addr, 16, 1);
3198 spu_info[num].dump_addr = addr;
3201 static int do_spu_cmd(void)
3203 static unsigned long num = 0;
3204 int cmd, subcmd = 0;
3216 if (isxdigit(subcmd) || subcmd == '\n')
3220 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3221 printf("*** Error: invalid spu number\n");
3227 dump_spu_fields(spu_info[num].spu);
3230 dump_spu_ls(num, subcmd);
3241 #else /* ! CONFIG_SPU_BASE */
3242 static int do_spu_cmd(void)