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.
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/sched/signal.h>
17 #include <linux/smp.h>
19 #include <linux/reboot.h>
20 #include <linux/delay.h>
21 #include <linux/kallsyms.h>
22 #include <linux/kmsg_dump.h>
23 #include <linux/cpumask.h>
24 #include <linux/export.h>
25 #include <linux/sysrq.h>
26 #include <linux/interrupt.h>
27 #include <linux/irq.h>
28 #include <linux/bug.h>
29 #include <linux/nmi.h>
30 #include <linux/ctype.h>
31 #include <linux/highmem.h>
33 #include <asm/debugfs.h>
34 #include <asm/ptrace.h>
36 #include <asm/string.h>
38 #include <asm/machdep.h>
40 #include <asm/processor.h>
41 #include <asm/pgtable.h>
43 #include <asm/mmu_context.h>
44 #include <asm/cputable.h>
46 #include <asm/sstep.h>
47 #include <asm/irq_regs.h>
49 #include <asm/spu_priv1.h>
50 #include <asm/setjmp.h>
52 #include <asm/debug.h>
53 #include <asm/hw_breakpoint.h>
56 #include <asm/firmware.h>
57 #include <asm/code-patching.h>
60 #include <asm/hvcall.h>
64 #if defined(CONFIG_PPC_SPLPAR)
65 #include <asm/plpar_wrappers.h>
67 static inline long plapr_set_ciabr(unsigned long ciabr
) {return 0; };
74 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
75 static unsigned long xmon_taken
= 1;
76 static int xmon_owner
;
80 #endif /* CONFIG_SMP */
82 static unsigned long in_xmon __read_mostly
= 0;
83 static int xmon_on
= IS_ENABLED(CONFIG_XMON_DEFAULT
);
85 static unsigned long adrs
;
87 #define MAX_DUMP (128 * 1024)
88 static unsigned long ndump
= 64;
89 static unsigned long nidump
= 16;
90 static unsigned long ncsum
= 4096;
92 static char tmpstr
[128];
93 static int tracing_enabled
;
95 static long bus_error_jmp
[JMP_BUF_LEN
];
96 static int catch_memory_errors
;
97 static int catch_spr_faults
;
98 static long *xmon_fault_jmp
[NR_CPUS
];
100 /* Breakpoint stuff */
102 unsigned long address
;
103 unsigned int instr
[2];
109 /* Bits in bpt.enabled */
115 static struct bpt bpts
[NBPTS
];
116 static struct bpt dabr
;
117 static struct bpt
*iabr
;
118 static unsigned bpinstr
= 0x7fe00008; /* trap */
120 #define BP_NUM(bp) ((bp) - bpts + 1)
123 static int cmds(struct pt_regs
*);
124 static int mread(unsigned long, void *, int);
125 static int mwrite(unsigned long, void *, int);
126 static int handle_fault(struct pt_regs
*);
127 static void byterev(unsigned char *, int);
128 static void memex(void);
129 static int bsesc(void);
130 static void dump(void);
131 static void show_pte(unsigned long);
132 static void prdump(unsigned long, long);
133 static int ppc_inst_dump(unsigned long, long, int);
134 static void dump_log_buf(void);
136 #ifdef CONFIG_PPC_POWERNV
137 static void dump_opal_msglog(void);
139 static inline void dump_opal_msglog(void)
141 printf("Machine is not running OPAL firmware.\n");
145 static void backtrace(struct pt_regs
*);
146 static void excprint(struct pt_regs
*);
147 static void prregs(struct pt_regs
*);
148 static void memops(int);
149 static void memlocate(void);
150 static void memzcan(void);
151 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
153 int scanhex(unsigned long *valp
);
154 static void scannl(void);
155 static int hexdigit(int);
156 void getstring(char *, int);
157 static void flush_input(void);
158 static int inchar(void);
159 static void take_input(char *);
160 static int read_spr(int, unsigned long *);
161 static void write_spr(int, unsigned long);
162 static void super_regs(void);
163 static void remove_bpts(void);
164 static void insert_bpts(void);
165 static void remove_cpu_bpts(void);
166 static void insert_cpu_bpts(void);
167 static struct bpt
*at_breakpoint(unsigned long pc
);
168 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
169 static int do_step(struct pt_regs
*);
170 static void bpt_cmds(void);
171 static void cacheflush(void);
172 static int cpu_cmd(void);
173 static void csum(void);
174 static void bootcmds(void);
175 static void proccall(void);
176 static void show_tasks(void);
177 void dump_segments(void);
178 static void symbol_lookup(void);
179 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
181 static void xmon_print_symbol(unsigned long address
, const char *mid
,
183 static const char *getvecname(unsigned long vec
);
185 static int do_spu_cmd(void);
188 static void dump_tlb_44x(void);
190 #ifdef CONFIG_PPC_BOOK3E
191 static void dump_tlb_book3e(void);
200 #ifdef __LITTLE_ENDIAN__
201 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
203 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
206 static char *help_string
= "\
208 b show breakpoints\n\
209 bd set data breakpoint\n\
210 bi set instruction breakpoint\n\
211 bc clear breakpoint\n"
214 c print cpus stopped in xmon\n\
215 c# try to switch to cpu number h (in hex)\n"
220 d1 dump 1 byte values\n\
221 d2 dump 2 byte values\n\
222 d4 dump 4 byte values\n\
223 d8 dump 8 byte values\n\
224 di dump instructions\n\
225 df dump float values\n\
226 dd dump double values\n\
227 dl dump the kernel log buffer\n"
228 #ifdef CONFIG_PPC_POWERNV
230 do dump the OPAL message log\n"
234 dp[#] dump paca for current cpu, or cpu #\n\
235 dpa dump paca for all possible cpus\n"
238 dr dump stream of raw bytes\n\
239 dv dump virtual address translation \n\
240 dt dump the tracing buffers (uses printk)\n\
241 dtc dump the tracing buffers for current CPU (uses printk)\n\
243 #ifdef CONFIG_PPC_POWERNV
244 " dx# dump xive on CPU #\n\
245 dxi# dump xive irq state #\n\
246 dxa dump xive on all CPUs\n"
248 " e print exception information\n\
250 la lookup symbol+offset of specified address\n\
251 ls lookup address of specified symbol\n\
252 m examine/change memory\n\
253 mm move a block of memory\n\
254 ms set a block of memory\n\
255 md compare two blocks of memory\n\
256 ml locate a block of memory\n\
257 mz zero a block of memory\n\
258 mi show information about memory allocation\n\
259 p call a procedure\n\
260 P list processes/tasks\n\
263 #ifdef CONFIG_SPU_BASE
264 " ss stop execution on all spus\n\
265 sr restore execution on stopped spus\n\
266 sf # dump spu fields for spu # (in hex)\n\
267 sd # dump spu local store for spu # (in hex)\n\
268 sdi # disassemble spu local store for spu # (in hex)\n"
270 " S print special registers\n\
273 Sw #v write v to SPR #\n\
275 x exit monitor and recover\n\
276 X exit monitor and don't recover\n"
277 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
278 " u dump segment table or SLB\n"
279 #elif defined(CONFIG_PPC_STD_MMU_32)
280 " u dump segment registers\n"
281 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
284 " U show uptime information\n"
286 " # n limit output to n lines per page (for dp, dpa, dl)\n"
291 static struct pt_regs
*xmon_regs
;
293 static inline void sync(void)
295 asm volatile("sync; isync");
298 static inline void store_inst(void *p
)
300 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
303 static inline void cflush(void *p
)
305 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
308 static inline void cinval(void *p
)
310 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
314 * write_ciabr() - write the CIABR SPR
315 * @ciabr: The value to write.
317 * This function writes a value to the CIARB register either directly
318 * through mtspr instruction if the kernel is in HV privilege mode or
319 * call a hypervisor function to achieve the same in case the kernel
320 * is in supervisor privilege mode.
322 static void write_ciabr(unsigned long ciabr
)
324 if (!cpu_has_feature(CPU_FTR_ARCH_207S
))
327 if (cpu_has_feature(CPU_FTR_HVMODE
)) {
328 mtspr(SPRN_CIABR
, ciabr
);
331 plapr_set_ciabr(ciabr
);
335 * set_ciabr() - set the CIABR
336 * @addr: The value to set.
338 * This function sets the correct privilege value into the the HW
339 * breakpoint address before writing it up in the CIABR register.
341 static void set_ciabr(unsigned long addr
)
345 if (cpu_has_feature(CPU_FTR_HVMODE
))
346 addr
|= CIABR_PRIV_HYPER
;
348 addr
|= CIABR_PRIV_SUPER
;
353 * Disable surveillance (the service processor watchdog function)
354 * while we are in xmon.
355 * XXX we should re-enable it when we leave. :)
357 #define SURVEILLANCE_TOKEN 9000
359 static inline void disable_surveillance(void)
361 #ifdef CONFIG_PPC_PSERIES
362 /* Since this can't be a module, args should end up below 4GB. */
363 static struct rtas_args args
;
367 * At this point we have got all the cpus we can into
368 * xmon, so there is hopefully no other cpu calling RTAS
369 * at the moment, even though we don't take rtas.lock.
370 * If we did try to take rtas.lock there would be a
371 * real possibility of deadlock.
373 token
= rtas_token("set-indicator");
374 if (token
== RTAS_UNKNOWN_SERVICE
)
377 rtas_call_unlocked(&args
, token
, 3, 1, NULL
, SURVEILLANCE_TOKEN
, 0, 0);
379 #endif /* CONFIG_PPC_PSERIES */
383 static int xmon_speaker
;
385 static void get_output_lock(void)
387 int me
= smp_processor_id() + 0x100;
388 int last_speaker
= 0, prev
;
391 if (xmon_speaker
== me
)
395 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
396 if (last_speaker
== 0)
400 * Wait a full second for the lock, we might be on a slow
401 * console, but check every 100us.
404 while (xmon_speaker
== last_speaker
) {
410 /* hostile takeover */
411 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
412 if (prev
== last_speaker
)
419 static void release_output_lock(void)
424 int cpus_are_in_xmon(void)
426 return !cpumask_empty(&cpus_in_xmon
);
429 static bool wait_for_other_cpus(int ncpus
)
431 unsigned long timeout
;
433 /* We wait for 2s, which is a metric "little while" */
434 for (timeout
= 20000; timeout
!= 0; --timeout
) {
435 if (cpumask_weight(&cpus_in_xmon
) >= ncpus
)
443 #endif /* CONFIG_SMP */
445 static inline int unrecoverable_excp(struct pt_regs
*regs
)
447 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
448 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
451 return ((regs
->msr
& MSR_RI
) == 0);
455 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
459 long recurse_jmp
[JMP_BUF_LEN
];
460 unsigned long offset
;
467 local_irq_save(flags
);
470 tracing_enabled
= tracing_is_on();
473 bp
= in_breakpoint_table(regs
->nip
, &offset
);
475 regs
->nip
= bp
->address
+ offset
;
476 atomic_dec(&bp
->ref_count
);
482 cpu
= smp_processor_id();
483 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
485 * We catch SPR read/write faults here because the 0x700, 0xf60
486 * etc. handlers don't call debugger_fault_handler().
488 if (catch_spr_faults
)
489 longjmp(bus_error_jmp
, 1);
492 printf("cpu 0x%x: Exception %lx %s in xmon, "
493 "returning to main loop\n",
494 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
495 release_output_lock();
496 longjmp(xmon_fault_jmp
[cpu
], 1);
499 if (setjmp(recurse_jmp
) != 0) {
500 if (!in_xmon
|| !xmon_gate
) {
502 printf("xmon: WARNING: bad recursive fault "
503 "on cpu 0x%x\n", cpu
);
504 release_output_lock();
507 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
511 xmon_fault_jmp
[cpu
] = recurse_jmp
;
514 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
))
515 bp
= at_breakpoint(regs
->nip
);
516 if (bp
|| unrecoverable_excp(regs
))
523 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
525 xmon_print_symbol(regs
->nip
, " ", ")\n");
527 if (unrecoverable_excp(regs
))
528 printf("WARNING: exception is not recoverable, "
530 release_output_lock();
533 cpumask_set_cpu(cpu
, &cpus_in_xmon
);
538 while (secondary
&& !xmon_gate
) {
544 secondary
= test_and_set_bit(0, &in_xmon
);
547 touch_nmi_watchdog();
551 if (!secondary
&& !xmon_gate
) {
552 /* we are the first cpu to come in */
553 /* interrupt other cpu(s) */
554 int ncpus
= num_online_cpus();
560 * A system reset (trap == 0x100) can be triggered on
561 * all CPUs, so when we come in via 0x100 try waiting
562 * for the other CPUs to come in before we send the
563 * debugger break (IPI). This is similar to
564 * crash_kexec_secondary().
566 if (TRAP(regs
) != 0x100 || !wait_for_other_cpus(ncpus
))
567 smp_send_debugger_break();
569 wait_for_other_cpus(ncpus
);
572 disable_surveillance();
573 /* for breakpoint or single step, print the current instr. */
574 if (bp
|| TRAP(regs
) == 0xd00)
575 ppc_inst_dump(regs
->nip
, 1, 0);
576 printf("enter ? for help\n");
580 touch_nmi_watchdog();
587 if (cpu
== xmon_owner
) {
588 if (!test_and_set_bit(0, &xmon_taken
)) {
594 while (cpu
== xmon_owner
)
598 touch_nmi_watchdog();
609 /* have switched to some other cpu */
614 cpumask_clear_cpu(cpu
, &cpus_in_xmon
);
615 xmon_fault_jmp
[cpu
] = NULL
;
617 /* UP is simple... */
619 printf("Exception %lx %s in xmon, returning to main loop\n",
620 regs
->trap
, getvecname(TRAP(regs
)));
621 longjmp(xmon_fault_jmp
[0], 1);
623 if (setjmp(recurse_jmp
) == 0) {
624 xmon_fault_jmp
[0] = recurse_jmp
;
628 bp
= at_breakpoint(regs
->nip
);
630 printf("Stopped at breakpoint %lx (", BP_NUM(bp
));
631 xmon_print_symbol(regs
->nip
, " ", ")\n");
633 if (unrecoverable_excp(regs
))
634 printf("WARNING: exception is not recoverable, "
637 disable_surveillance();
638 /* for breakpoint or single step, print the current instr. */
639 if (bp
|| TRAP(regs
) == 0xd00)
640 ppc_inst_dump(regs
->nip
, 1, 0);
641 printf("enter ? for help\n");
651 if (regs
->msr
& MSR_DE
) {
652 bp
= at_breakpoint(regs
->nip
);
654 regs
->nip
= (unsigned long) &bp
->instr
[0];
655 atomic_inc(&bp
->ref_count
);
659 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
660 bp
= at_breakpoint(regs
->nip
);
662 int stepped
= emulate_step(regs
, bp
->instr
[0]);
664 regs
->nip
= (unsigned long) &bp
->instr
[0];
665 atomic_inc(&bp
->ref_count
);
666 } else if (stepped
< 0) {
667 printf("Couldn't single-step %s instruction\n",
668 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
675 touch_nmi_watchdog();
676 local_irq_restore(flags
);
678 return cmd
!= 'X' && cmd
!= EOF
;
681 int xmon(struct pt_regs
*excp
)
686 ppc_save_regs(®s
);
690 return xmon_core(excp
, 0);
694 irqreturn_t
xmon_irq(int irq
, void *d
)
697 local_irq_save(flags
);
698 printf("Keyboard interrupt\n");
699 xmon(get_irq_regs());
700 local_irq_restore(flags
);
704 static int xmon_bpt(struct pt_regs
*regs
)
707 unsigned long offset
;
709 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
712 /* Are we at the trap at bp->instr[1] for some bp? */
713 bp
= in_breakpoint_table(regs
->nip
, &offset
);
714 if (bp
!= NULL
&& offset
== 4) {
715 regs
->nip
= bp
->address
+ 4;
716 atomic_dec(&bp
->ref_count
);
720 /* Are we at a breakpoint? */
721 bp
= at_breakpoint(regs
->nip
);
730 static int xmon_sstep(struct pt_regs
*regs
)
738 static int xmon_break_match(struct pt_regs
*regs
)
740 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
742 if (dabr
.enabled
== 0)
748 static int xmon_iabr_match(struct pt_regs
*regs
)
750 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
758 static int xmon_ipi(struct pt_regs
*regs
)
761 if (in_xmon
&& !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon
))
767 static int xmon_fault_handler(struct pt_regs
*regs
)
770 unsigned long offset
;
772 if (in_xmon
&& catch_memory_errors
)
773 handle_fault(regs
); /* doesn't return */
775 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
776 bp
= in_breakpoint_table(regs
->nip
, &offset
);
778 regs
->nip
= bp
->address
+ offset
;
779 atomic_dec(&bp
->ref_count
);
786 static struct bpt
*at_breakpoint(unsigned long pc
)
792 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
793 if (bp
->enabled
&& pc
== bp
->address
)
798 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
802 off
= nip
- (unsigned long) bpts
;
803 if (off
>= sizeof(bpts
))
805 off
%= sizeof(struct bpt
);
806 if (off
!= offsetof(struct bpt
, instr
[0])
807 && off
!= offsetof(struct bpt
, instr
[1]))
809 *offp
= off
- offsetof(struct bpt
, instr
[0]);
810 return (struct bpt
*) (nip
- off
);
813 static struct bpt
*new_breakpoint(unsigned long a
)
818 bp
= at_breakpoint(a
);
822 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
823 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
825 bp
->instr
[1] = bpinstr
;
826 store_inst(&bp
->instr
[1]);
831 printf("Sorry, no free breakpoints. Please clear one first.\n");
835 static void insert_bpts(void)
841 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
842 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) == 0)
844 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
845 printf("Couldn't read instruction at %lx, "
846 "disabling breakpoint there\n", bp
->address
);
850 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
851 printf("Breakpoint at %lx is on an mtmsrd or rfid "
852 "instruction, disabling it\n", bp
->address
);
856 store_inst(&bp
->instr
[0]);
857 if (bp
->enabled
& BP_CIABR
)
859 if (patch_instruction((unsigned int *)bp
->address
,
861 printf("Couldn't write instruction at %lx, "
862 "disabling breakpoint there\n", bp
->address
);
863 bp
->enabled
&= ~BP_TRAP
;
866 store_inst((void *)bp
->address
);
870 static void insert_cpu_bpts(void)
872 struct arch_hw_breakpoint brk
;
875 brk
.address
= dabr
.address
;
876 brk
.type
= (dabr
.enabled
& HW_BRK_TYPE_DABR
) | HW_BRK_TYPE_PRIV_ALL
;
878 __set_breakpoint(&brk
);
882 set_ciabr(iabr
->address
);
885 static void remove_bpts(void)
892 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
893 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) != BP_TRAP
)
895 if (mread(bp
->address
, &instr
, 4) == 4
897 && patch_instruction(
898 (unsigned int *)bp
->address
, bp
->instr
[0]) != 0)
899 printf("Couldn't remove breakpoint at %lx\n",
902 store_inst((void *)bp
->address
);
906 static void remove_cpu_bpts(void)
908 hw_breakpoint_disable();
912 /* Based on uptime_proc_show(). */
916 struct timespec uptime
;
918 if (setjmp(bus_error_jmp
) == 0) {
919 catch_memory_errors
= 1;
922 get_monotonic_boottime(&uptime
);
923 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime
.tv_sec
,
924 ((unsigned long)uptime
.tv_nsec
/ (NSEC_PER_SEC
/100)));
929 catch_memory_errors
= 0;
932 static void set_lpp_cmd(void)
936 if (!scanhex(&lpp
)) {
937 printf("Invalid number.\n");
940 xmon_set_pagination_lpp(lpp
);
942 /* Command interpreting routine */
943 static char *last_cmd
;
946 cmds(struct pt_regs
*excp
)
953 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
957 printf("%x:", smp_processor_id());
958 #endif /* CONFIG_SMP */
964 if (last_cmd
== NULL
)
966 take_input(last_cmd
);
1000 prregs(excp
); /* print regs */
1015 if (do_spu_cmd() == 0)
1022 if (tracing_enabled
)
1026 printf(" <no input ...>\n");
1030 xmon_puts(help_string
);
1054 #ifdef CONFIG_PPC_STD_MMU
1058 #elif defined(CONFIG_44x)
1062 #elif defined(CONFIG_PPC_BOOK3E)
1071 printf("Unrecognized command: ");
1073 if (' ' < cmd
&& cmd
<= '~')
1076 printf("\\x%x", cmd
);
1078 } while (cmd
!= '\n');
1079 printf(" (type ? for help)\n");
1086 static int do_step(struct pt_regs
*regs
)
1088 regs
->msr
|= MSR_DE
;
1089 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
1094 * Step a single instruction.
1095 * Some instructions we emulate, others we execute with MSR_SE set.
1097 static int do_step(struct pt_regs
*regs
)
1102 /* check we are in 64-bit kernel mode, translation enabled */
1103 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
1104 if (mread(regs
->nip
, &instr
, 4) == 4) {
1105 stepped
= emulate_step(regs
, instr
);
1107 printf("Couldn't single-step %s instruction\n",
1108 (IS_RFID(instr
)? "rfid": "mtmsrd"));
1112 regs
->trap
= 0xd00 | (regs
->trap
& 1);
1113 printf("stepped to ");
1114 xmon_print_symbol(regs
->nip
, " ", "\n");
1115 ppc_inst_dump(regs
->nip
, 1, 0);
1120 regs
->msr
|= MSR_SE
;
1125 static void bootcmds(void)
1131 ppc_md
.restart(NULL
);
1132 else if (cmd
== 'h')
1134 else if (cmd
== 'p')
1139 static int cpu_cmd(void)
1142 unsigned long cpu
, first_cpu
, last_cpu
;
1145 if (!scanhex(&cpu
)) {
1146 /* print cpus waiting or in xmon */
1147 printf("cpus stopped:");
1148 last_cpu
= first_cpu
= NR_CPUS
;
1149 for_each_possible_cpu(cpu
) {
1150 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1151 if (cpu
== last_cpu
+ 1) {
1154 if (last_cpu
!= first_cpu
)
1155 printf("-0x%lx", last_cpu
);
1156 last_cpu
= first_cpu
= cpu
;
1157 printf(" 0x%lx", cpu
);
1161 if (last_cpu
!= first_cpu
)
1162 printf("-0x%lx", last_cpu
);
1166 /* try to switch to cpu specified */
1167 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1168 printf("cpu 0x%x isn't in xmon\n", cpu
);
1175 while (!xmon_taken
) {
1176 if (--timeout
== 0) {
1177 if (test_and_set_bit(0, &xmon_taken
))
1179 /* take control back */
1181 xmon_owner
= smp_processor_id();
1182 printf("cpu 0x%x didn't take control\n", cpu
);
1190 #endif /* CONFIG_SMP */
1193 static unsigned short fcstab
[256] = {
1194 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1195 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1196 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1197 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1198 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1199 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1200 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1201 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1202 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1203 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1204 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1205 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1206 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1207 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1208 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1209 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1210 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1211 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1212 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1213 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1214 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1215 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1216 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1217 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1218 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1219 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1220 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1221 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1222 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1223 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1224 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1225 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1228 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1237 if (!scanhex(&adrs
))
1239 if (!scanhex(&ncsum
))
1242 for (i
= 0; i
< ncsum
; ++i
) {
1243 if (mread(adrs
+i
, &v
, 1) == 0) {
1244 printf("csum stopped at "REG
"\n", adrs
+i
);
1249 printf("%x\n", fcs
);
1253 * Check if this is a suitable place to put a breakpoint.
1255 static long check_bp_loc(unsigned long addr
)
1260 if (!is_kernel_addr(addr
)) {
1261 printf("Breakpoints may only be placed at kernel addresses\n");
1264 if (!mread(addr
, &instr
, sizeof(instr
))) {
1265 printf("Can't read instruction at address %lx\n", addr
);
1268 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1269 printf("Breakpoints may not be placed on mtmsrd or rfid "
1276 static char *breakpoint_help_string
=
1277 "Breakpoint command usage:\n"
1278 "b show breakpoints\n"
1279 "b <addr> [cnt] set breakpoint at given instr addr\n"
1280 "bc clear all breakpoints\n"
1281 "bc <n/addr> clear breakpoint number n or at addr\n"
1282 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1283 "bd <addr> [cnt] set hardware data breakpoint\n"
1296 #ifndef CONFIG_PPC_8xx
1297 static const char badaddr
[] = "Only kernel addresses are permitted for breakpoints\n";
1299 case 'd': /* bd - hardware data breakpoint */
1304 else if (cmd
== 'w')
1310 if (scanhex(&dabr
.address
)) {
1311 if (!is_kernel_addr(dabr
.address
)) {
1315 dabr
.address
&= ~HW_BRK_TYPE_DABR
;
1316 dabr
.enabled
= mode
| BP_DABR
;
1320 case 'i': /* bi - hardware instr breakpoint */
1321 if (!cpu_has_feature(CPU_FTR_ARCH_207S
)) {
1322 printf("Hardware instruction breakpoint "
1323 "not supported on this cpu\n");
1327 iabr
->enabled
&= ~BP_CIABR
;
1332 if (!check_bp_loc(a
))
1334 bp
= new_breakpoint(a
);
1336 bp
->enabled
|= BP_CIABR
;
1344 /* clear all breakpoints */
1345 for (i
= 0; i
< NBPTS
; ++i
)
1346 bpts
[i
].enabled
= 0;
1349 printf("All breakpoints cleared\n");
1353 if (a
<= NBPTS
&& a
>= 1) {
1354 /* assume a breakpoint number */
1355 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1357 /* assume a breakpoint address */
1358 bp
= at_breakpoint(a
);
1360 printf("No breakpoint at %lx\n", a
);
1365 printf("Cleared breakpoint %lx (", BP_NUM(bp
));
1366 xmon_print_symbol(bp
->address
, " ", ")\n");
1374 printf(breakpoint_help_string
);
1379 /* print all breakpoints */
1380 printf(" type address\n");
1382 printf(" data "REG
" [", dabr
.address
);
1383 if (dabr
.enabled
& 1)
1385 if (dabr
.enabled
& 2)
1389 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1392 printf("%2x %s ", BP_NUM(bp
),
1393 (bp
->enabled
& BP_CIABR
) ? "inst": "trap");
1394 xmon_print_symbol(bp
->address
, " ", "\n");
1399 if (!check_bp_loc(a
))
1401 bp
= new_breakpoint(a
);
1403 bp
->enabled
|= BP_TRAP
;
1408 /* Very cheap human name for vector lookup. */
1410 const char *getvecname(unsigned long vec
)
1415 case 0x100: ret
= "(System Reset)"; break;
1416 case 0x200: ret
= "(Machine Check)"; break;
1417 case 0x300: ret
= "(Data Access)"; break;
1419 if (radix_enabled())
1420 ret
= "(Data Access Out of Range)";
1422 ret
= "(Data SLB Access)";
1424 case 0x400: ret
= "(Instruction Access)"; break;
1426 if (radix_enabled())
1427 ret
= "(Instruction Access Out of Range)";
1429 ret
= "(Instruction SLB Access)";
1431 case 0x500: ret
= "(Hardware Interrupt)"; break;
1432 case 0x600: ret
= "(Alignment)"; break;
1433 case 0x700: ret
= "(Program Check)"; break;
1434 case 0x800: ret
= "(FPU Unavailable)"; break;
1435 case 0x900: ret
= "(Decrementer)"; break;
1436 case 0x980: ret
= "(Hypervisor Decrementer)"; break;
1437 case 0xa00: ret
= "(Doorbell)"; break;
1438 case 0xc00: ret
= "(System Call)"; break;
1439 case 0xd00: ret
= "(Single Step)"; break;
1440 case 0xe40: ret
= "(Emulation Assist)"; break;
1441 case 0xe60: ret
= "(HMI)"; break;
1442 case 0xe80: ret
= "(Hypervisor Doorbell)"; break;
1443 case 0xf00: ret
= "(Performance Monitor)"; break;
1444 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1445 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1446 case 0x1500: ret
= "(Denormalisation)"; break;
1447 case 0x1700: ret
= "(Altivec Assist)"; break;
1453 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1454 unsigned long *endp
)
1456 unsigned long size
, offset
;
1459 *startp
= *endp
= 0;
1462 if (setjmp(bus_error_jmp
) == 0) {
1463 catch_memory_errors
= 1;
1465 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1467 *startp
= pc
- offset
;
1468 *endp
= pc
- offset
+ size
;
1472 catch_memory_errors
= 0;
1475 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1476 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1478 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1481 int max_to_print
= 64;
1483 unsigned long newsp
;
1484 unsigned long marker
;
1485 struct pt_regs regs
;
1487 while (max_to_print
--) {
1488 if (!is_kernel_addr(sp
)) {
1490 printf("SP (%lx) is in userspace\n", sp
);
1494 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1495 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1496 printf("Couldn't read stack frame at %lx\n", sp
);
1501 * For the first stack frame, try to work out if
1502 * LR and/or the saved LR value in the bottommost
1503 * stack frame are valid.
1505 if ((pc
| lr
) != 0) {
1506 unsigned long fnstart
, fnend
;
1507 unsigned long nextip
;
1510 get_function_bounds(pc
, &fnstart
, &fnend
);
1513 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1514 sizeof(unsigned long));
1516 if (!is_kernel_addr(lr
)
1517 || (fnstart
<= lr
&& lr
< fnend
))
1519 } else if (lr
== nextip
) {
1521 } else if (is_kernel_addr(lr
)
1522 && !(fnstart
<= lr
&& lr
< fnend
)) {
1523 printf("[link register ] ");
1524 xmon_print_symbol(lr
, " ", "\n");
1527 printf("["REG
"] ", sp
);
1528 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1533 printf("["REG
"] ", sp
);
1534 xmon_print_symbol(ip
, " ", "\n");
1537 /* Look for "regshere" marker to see if this is
1538 an exception frame. */
1539 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1540 && marker
== STACK_FRAME_REGS_MARKER
) {
1541 if (mread(sp
+ STACK_FRAME_OVERHEAD
, ®s
, sizeof(regs
))
1543 printf("Couldn't read registers at %lx\n",
1544 sp
+ STACK_FRAME_OVERHEAD
);
1547 printf("--- Exception: %lx %s at ", regs
.trap
,
1548 getvecname(TRAP(®s
)));
1551 xmon_print_symbol(pc
, " ", "\n");
1561 static void backtrace(struct pt_regs
*excp
)
1566 xmon_show_stack(sp
, 0, 0);
1568 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1572 static void print_bug_trap(struct pt_regs
*regs
)
1575 const struct bug_entry
*bug
;
1578 if (regs
->msr
& MSR_PR
)
1579 return; /* not in kernel */
1580 addr
= regs
->nip
; /* address of trap instruction */
1581 if (!is_kernel_addr(addr
))
1583 bug
= find_bug(regs
->nip
);
1586 if (is_warning_bug(bug
))
1589 #ifdef CONFIG_DEBUG_BUGVERBOSE
1590 printf("kernel BUG at %s:%u!\n",
1591 bug
->file
, bug
->line
);
1593 printf("kernel BUG at %px!\n", (void *)bug
->bug_addr
);
1595 #endif /* CONFIG_BUG */
1598 static void excprint(struct pt_regs
*fp
)
1603 printf("cpu 0x%x: ", smp_processor_id());
1604 #endif /* CONFIG_SMP */
1607 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1609 xmon_print_symbol(fp
->nip
, ": ", "\n");
1611 printf(" lr: ", fp
->link
);
1612 xmon_print_symbol(fp
->link
, ": ", "\n");
1614 printf(" sp: %lx\n", fp
->gpr
[1]);
1615 printf(" msr: %lx\n", fp
->msr
);
1617 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600 || trap
== 0x200) {
1618 printf(" dar: %lx\n", fp
->dar
);
1620 printf(" dsisr: %lx\n", fp
->dsisr
);
1623 printf(" current = 0x%lx\n", current
);
1625 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1626 local_paca
, local_paca
->soft_enabled
, local_paca
->irq_happened
);
1629 printf(" pid = %ld, comm = %s\n",
1630 current
->pid
, current
->comm
);
1636 printf(linux_banner
);
1639 static void prregs(struct pt_regs
*fp
)
1643 struct pt_regs regs
;
1645 if (scanhex(&base
)) {
1646 if (setjmp(bus_error_jmp
) == 0) {
1647 catch_memory_errors
= 1;
1649 regs
= *(struct pt_regs
*)base
;
1653 catch_memory_errors
= 0;
1654 printf("*** Error reading registers from "REG
"\n",
1658 catch_memory_errors
= 0;
1663 if (FULL_REGS(fp
)) {
1664 for (n
= 0; n
< 16; ++n
)
1665 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1666 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1668 for (n
= 0; n
< 7; ++n
)
1669 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1670 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1673 for (n
= 0; n
< 32; ++n
) {
1674 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1675 (n
& 3) == 3? "\n": " ");
1676 if (n
== 12 && !FULL_REGS(fp
)) {
1683 xmon_print_symbol(fp
->nip
, " ", "\n");
1684 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1686 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1689 xmon_print_symbol(fp
->link
, " ", "\n");
1690 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1691 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1692 fp
->ctr
, fp
->xer
, fp
->trap
);
1694 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1695 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1698 static void cacheflush(void)
1701 unsigned long nflush
;
1706 scanhex((void *)&adrs
);
1711 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1712 if (setjmp(bus_error_jmp
) == 0) {
1713 catch_memory_errors
= 1;
1717 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1718 cflush((void *) adrs
);
1720 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1721 cinval((void *) adrs
);
1724 /* wait a little while to see if we get a machine check */
1727 catch_memory_errors
= 0;
1730 extern unsigned long xmon_mfspr(int spr
, unsigned long default_value
);
1731 extern void xmon_mtspr(int spr
, unsigned long value
);
1734 read_spr(int n
, unsigned long *vp
)
1736 unsigned long ret
= -1UL;
1739 if (setjmp(bus_error_jmp
) == 0) {
1740 catch_spr_faults
= 1;
1743 ret
= xmon_mfspr(n
, *vp
);
1749 catch_spr_faults
= 0;
1755 write_spr(int n
, unsigned long val
)
1757 if (setjmp(bus_error_jmp
) == 0) {
1758 catch_spr_faults
= 1;
1765 printf("SPR 0x%03x (%4d) Faulted during write\n", n
, n
);
1767 catch_spr_faults
= 0;
1770 static void dump_206_sprs(void)
1773 if (!cpu_has_feature(CPU_FTR_ARCH_206
))
1776 /* Actually some of these pre-date 2.06, but whatevs */
1778 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8x\n",
1779 mfspr(SPRN_SRR0
), mfspr(SPRN_SRR1
), mfspr(SPRN_DSISR
));
1780 printf("dscr = %.16lx ppr = %.16lx pir = %.8x\n",
1781 mfspr(SPRN_DSCR
), mfspr(SPRN_PPR
), mfspr(SPRN_PIR
));
1782 printf("amr = %.16lx uamor = %.16lx\n",
1783 mfspr(SPRN_AMR
), mfspr(SPRN_UAMOR
));
1785 if (!(mfmsr() & MSR_HV
))
1788 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8x\n",
1789 mfspr(SPRN_SDR1
), mfspr(SPRN_HDAR
), mfspr(SPRN_HDSISR
));
1790 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
1791 mfspr(SPRN_HSRR0
), mfspr(SPRN_HSRR1
), mfspr(SPRN_HDEC
));
1792 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8x\n",
1793 mfspr(SPRN_LPCR
), mfspr(SPRN_PCR
), mfspr(SPRN_LPID
));
1794 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
1795 mfspr(SPRN_HSPRG0
), mfspr(SPRN_HSPRG1
), mfspr(SPRN_AMOR
));
1796 printf("dabr = %.16lx dabrx = %.16lx\n",
1797 mfspr(SPRN_DABR
), mfspr(SPRN_DABRX
));
1801 static void dump_207_sprs(void)
1806 if (!cpu_has_feature(CPU_FTR_ARCH_207S
))
1809 printf("dpdes = %.16lx tir = %.16lx cir = %.8x\n",
1810 mfspr(SPRN_DPDES
), mfspr(SPRN_TIR
), mfspr(SPRN_CIR
));
1812 printf("fscr = %.16lx tar = %.16lx pspb = %.8x\n",
1813 mfspr(SPRN_FSCR
), mfspr(SPRN_TAR
), mfspr(SPRN_PSPB
));
1817 /* Only if TM has been enabled in the kernel */
1818 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
1819 mfspr(SPRN_TFHAR
), mfspr(SPRN_TFIAR
),
1820 mfspr(SPRN_TEXASR
));
1823 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
1824 mfspr(SPRN_MMCR0
), mfspr(SPRN_MMCR1
), mfspr(SPRN_MMCR2
));
1825 printf("pmc1 = %.8x pmc2 = %.8x pmc3 = %.8x pmc4 = %.8x\n",
1826 mfspr(SPRN_PMC1
), mfspr(SPRN_PMC2
),
1827 mfspr(SPRN_PMC3
), mfspr(SPRN_PMC4
));
1828 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8x\n",
1829 mfspr(SPRN_MMCRA
), mfspr(SPRN_SIAR
), mfspr(SPRN_PMC5
));
1830 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8x\n",
1831 mfspr(SPRN_SDAR
), mfspr(SPRN_SIER
), mfspr(SPRN_PMC6
));
1832 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
1833 mfspr(SPRN_EBBHR
), mfspr(SPRN_EBBRR
), mfspr(SPRN_BESCR
));
1834 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR
));
1836 if (!(msr
& MSR_HV
))
1839 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
1840 mfspr(SPRN_HFSCR
), mfspr(SPRN_DHDES
), mfspr(SPRN_RPR
));
1841 printf("dawr = %.16lx dawrx = %.16lx ciabr = %.16lx\n",
1842 mfspr(SPRN_DAWR
), mfspr(SPRN_DAWRX
), mfspr(SPRN_CIABR
));
1846 static void dump_300_sprs(void)
1849 bool hv
= mfmsr() & MSR_HV
;
1851 if (!cpu_has_feature(CPU_FTR_ARCH_300
))
1854 printf("pidr = %.16lx tidr = %.16lx\n",
1855 mfspr(SPRN_PID
), mfspr(SPRN_TIDR
));
1856 printf("asdr = %.16lx psscr = %.16lx\n",
1857 mfspr(SPRN_ASDR
), hv
? mfspr(SPRN_PSSCR
)
1858 : mfspr(SPRN_PSSCR_PR
));
1863 printf("ptcr = %.16lx\n",
1868 static void dump_one_spr(int spr
, bool show_unimplemented
)
1873 if (!read_spr(spr
, &val
)) {
1874 printf("SPR 0x%03x (%4d) Faulted during read\n", spr
, spr
);
1878 if (val
== 0xdeadbeef) {
1879 /* Looks like read was a nop, confirm */
1881 if (!read_spr(spr
, &val
)) {
1882 printf("SPR 0x%03x (%4d) Faulted during read\n", spr
, spr
);
1886 if (val
== 0x0badcafe) {
1887 if (show_unimplemented
)
1888 printf("SPR 0x%03x (%4d) Unimplemented\n", spr
, spr
);
1893 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr
, spr
, val
);
1896 static void super_regs(void)
1898 static unsigned long regno
;
1906 unsigned long sp
, toc
;
1907 asm("mr %0,1" : "=r" (sp
) :);
1908 asm("mr %0,2" : "=r" (toc
) :);
1910 printf("msr = "REG
" sprg0 = "REG
"\n",
1911 mfmsr(), mfspr(SPRN_SPRG0
));
1912 printf("pvr = "REG
" sprg1 = "REG
"\n",
1913 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1914 printf("dec = "REG
" sprg2 = "REG
"\n",
1915 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1916 printf("sp = "REG
" sprg3 = "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1917 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1929 read_spr(regno
, &val
);
1931 write_spr(regno
, val
);
1932 dump_one_spr(regno
, true);
1937 dump_one_spr(regno
, true);
1941 for (spr
= 1; spr
< 1024; ++spr
)
1942 dump_one_spr(spr
, false);
1950 * Stuff for reading and writing memory safely
1953 mread(unsigned long adrs
, void *buf
, int size
)
1959 if (setjmp(bus_error_jmp
) == 0) {
1960 catch_memory_errors
= 1;
1966 *(u16
*)q
= *(u16
*)p
;
1969 *(u32
*)q
= *(u32
*)p
;
1972 *(u64
*)q
= *(u64
*)p
;
1975 for( ; n
< size
; ++n
) {
1981 /* wait a little while to see if we get a machine check */
1985 catch_memory_errors
= 0;
1990 mwrite(unsigned long adrs
, void *buf
, int size
)
1996 if (setjmp(bus_error_jmp
) == 0) {
1997 catch_memory_errors
= 1;
2003 *(u16
*)p
= *(u16
*)q
;
2006 *(u32
*)p
= *(u32
*)q
;
2009 *(u64
*)p
= *(u64
*)q
;
2012 for ( ; n
< size
; ++n
) {
2018 /* wait a little while to see if we get a machine check */
2022 printf("*** Error writing address "REG
"\n", adrs
+ n
);
2024 catch_memory_errors
= 0;
2028 static int fault_type
;
2029 static int fault_except
;
2030 static char *fault_chars
[] = { "--", "**", "##" };
2032 static int handle_fault(struct pt_regs
*regs
)
2034 fault_except
= TRAP(regs
);
2035 switch (TRAP(regs
)) {
2047 longjmp(bus_error_jmp
, 1);
2052 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2055 byterev(unsigned char *val
, int size
)
2061 SWAP(val
[0], val
[1], t
);
2064 SWAP(val
[0], val
[3], t
);
2065 SWAP(val
[1], val
[2], t
);
2067 case 8: /* is there really any use for this? */
2068 SWAP(val
[0], val
[7], t
);
2069 SWAP(val
[1], val
[6], t
);
2070 SWAP(val
[2], val
[5], t
);
2071 SWAP(val
[3], val
[4], t
);
2079 static char *memex_help_string
=
2080 "Memory examine command usage:\n"
2081 "m [addr] [flags] examine/change memory\n"
2082 " addr is optional. will start where left off.\n"
2083 " flags may include chars from this set:\n"
2084 " b modify by bytes (default)\n"
2085 " w modify by words (2 byte)\n"
2086 " l modify by longs (4 byte)\n"
2087 " d modify by doubleword (8 byte)\n"
2088 " r toggle reverse byte order mode\n"
2089 " n do not read memory (for i/o spaces)\n"
2090 " . ok to read (default)\n"
2091 "NOTE: flags are saved as defaults\n"
2094 static char *memex_subcmd_help_string
=
2095 "Memory examine subcommands:\n"
2096 " hexval write this val to current location\n"
2097 " 'string' write chars from string to this location\n"
2098 " ' increment address\n"
2099 " ^ decrement address\n"
2100 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2101 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2102 " ` clear no-read flag\n"
2103 " ; stay at this addr\n"
2104 " v change to byte mode\n"
2105 " w change to word (2 byte) mode\n"
2106 " l change to long (4 byte) mode\n"
2107 " u change to doubleword (8 byte) mode\n"
2108 " m addr change current addr\n"
2109 " n toggle no-read flag\n"
2110 " r toggle byte reverse flag\n"
2111 " < count back up count bytes\n"
2112 " > count skip forward count bytes\n"
2113 " x exit this mode\n"
2119 int cmd
, inc
, i
, nslash
;
2121 unsigned char val
[16];
2123 scanhex((void *)&adrs
);
2126 printf(memex_help_string
);
2132 while ((cmd
= skipbl()) != '\n') {
2134 case 'b': size
= 1; break;
2135 case 'w': size
= 2; break;
2136 case 'l': size
= 4; break;
2137 case 'd': size
= 8; break;
2138 case 'r': brev
= !brev
; break;
2139 case 'n': mnoread
= 1; break;
2140 case '.': mnoread
= 0; break;
2149 n
= mread(adrs
, val
, size
);
2150 printf(REG
"%c", adrs
, brev
? 'r': ' ');
2155 for (i
= 0; i
< n
; ++i
)
2156 printf("%.2x", val
[i
]);
2157 for (; i
< size
; ++i
)
2158 printf("%s", fault_chars
[fault_type
]);
2165 for (i
= 0; i
< size
; ++i
)
2166 val
[i
] = n
>> (i
* 8);
2169 mwrite(adrs
, val
, size
);
2182 else if( n
== '\'' )
2184 for (i
= 0; i
< size
; ++i
)
2185 val
[i
] = n
>> (i
* 8);
2188 mwrite(adrs
, val
, size
);
2224 adrs
-= 1 << nslash
;
2228 adrs
+= 1 << nslash
;
2232 adrs
+= 1 << -nslash
;
2236 adrs
-= 1 << -nslash
;
2239 scanhex((void *)&adrs
);
2258 printf(memex_subcmd_help_string
);
2273 case 'n': c
= '\n'; break;
2274 case 'r': c
= '\r'; break;
2275 case 'b': c
= '\b'; break;
2276 case 't': c
= '\t'; break;
2281 static void xmon_rawdump (unsigned long adrs
, long ndump
)
2284 unsigned char temp
[16];
2286 for (n
= ndump
; n
> 0;) {
2288 nr
= mread(adrs
, temp
, r
);
2290 for (m
= 0; m
< r
; ++m
) {
2292 printf("%.2x", temp
[m
]);
2294 printf("%s", fault_chars
[fault_type
]);
2303 static void dump_tracing(void)
2309 ftrace_dump(DUMP_ORIG
);
2311 ftrace_dump(DUMP_ALL
);
2315 static void dump_one_paca(int cpu
)
2317 struct paca_struct
*p
;
2318 #ifdef CONFIG_PPC_BOOK3S_64
2322 if (setjmp(bus_error_jmp
) != 0) {
2323 printf("*** Error dumping paca for cpu 0x%x!\n", cpu
);
2327 catch_memory_errors
= 1;
2332 printf("paca for cpu 0x%x @ %px:\n", cpu
, p
);
2334 printf(" %-*s = %s\n", 20, "possible", cpu_possible(cpu
) ? "yes" : "no");
2335 printf(" %-*s = %s\n", 20, "present", cpu_present(cpu
) ? "yes" : "no");
2336 printf(" %-*s = %s\n", 20, "online", cpu_online(cpu
) ? "yes" : "no");
2338 #define DUMP(paca, name, format) \
2339 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 20, #name, 18, paca->name, \
2340 offsetof(struct paca_struct, name));
2342 DUMP(p
, lock_token
, "x");
2343 DUMP(p
, paca_index
, "x");
2344 DUMP(p
, kernel_toc
, "lx");
2345 DUMP(p
, kernelbase
, "lx");
2346 DUMP(p
, kernel_msr
, "lx");
2347 DUMP(p
, emergency_sp
, "p");
2348 #ifdef CONFIG_PPC_BOOK3S_64
2349 DUMP(p
, nmi_emergency_sp
, "p");
2350 DUMP(p
, mc_emergency_sp
, "p");
2351 DUMP(p
, in_nmi
, "x");
2352 DUMP(p
, in_mce
, "x");
2353 DUMP(p
, hmi_event_available
, "x");
2355 DUMP(p
, data_offset
, "lx");
2356 DUMP(p
, hw_cpu_id
, "x");
2357 DUMP(p
, cpu_start
, "x");
2358 DUMP(p
, kexec_state
, "x");
2359 #ifdef CONFIG_PPC_BOOK3S_64
2360 for (i
= 0; i
< SLB_NUM_BOLTED
; i
++) {
2363 if (!p
->slb_shadow_ptr
)
2366 esid
= be64_to_cpu(p
->slb_shadow_ptr
->save_area
[i
].esid
);
2367 vsid
= be64_to_cpu(p
->slb_shadow_ptr
->save_area
[i
].vsid
);
2370 printf(" slb_shadow[%d]: = 0x%016lx 0x%016lx\n",
2374 DUMP(p
, vmalloc_sllp
, "x");
2375 DUMP(p
, slb_cache_ptr
, "x");
2376 for (i
= 0; i
< SLB_CACHE_ENTRIES
; i
++)
2377 printf(" slb_cache[%d]: = 0x%016lx\n", i
, p
->slb_cache
[i
]);
2379 DUMP(p
, dscr_default
, "llx");
2380 #ifdef CONFIG_PPC_BOOK3E
2382 DUMP(p
, kernel_pgd
, "p");
2383 DUMP(p
, tcd_ptr
, "p");
2384 DUMP(p
, mc_kstack
, "p");
2385 DUMP(p
, crit_kstack
, "p");
2386 DUMP(p
, dbg_kstack
, "p");
2388 DUMP(p
, __current
, "p");
2389 DUMP(p
, kstack
, "lx");
2390 printf(" kstack_base = 0x%016lx\n", p
->kstack
& ~(THREAD_SIZE
- 1));
2391 DUMP(p
, stab_rr
, "lx");
2392 DUMP(p
, saved_r1
, "lx");
2393 DUMP(p
, trap_save
, "x");
2394 DUMP(p
, soft_enabled
, "x");
2395 DUMP(p
, irq_happened
, "x");
2396 DUMP(p
, io_sync
, "x");
2397 DUMP(p
, irq_work_pending
, "x");
2398 DUMP(p
, nap_state_lost
, "x");
2399 DUMP(p
, sprg_vdso
, "llx");
2401 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2402 DUMP(p
, tm_scratch
, "llx");
2405 #ifdef CONFIG_PPC_POWERNV
2406 DUMP(p
, core_idle_state_ptr
, "p");
2407 DUMP(p
, thread_idle_state
, "x");
2408 DUMP(p
, thread_mask
, "x");
2409 DUMP(p
, subcore_sibling_mask
, "x");
2412 DUMP(p
, accounting
.utime
, "llx");
2413 DUMP(p
, accounting
.stime
, "llx");
2414 DUMP(p
, accounting
.utime_scaled
, "llx");
2415 DUMP(p
, accounting
.starttime
, "llx");
2416 DUMP(p
, accounting
.starttime_user
, "llx");
2417 DUMP(p
, accounting
.startspurr
, "llx");
2418 DUMP(p
, accounting
.utime_sspurr
, "llx");
2419 DUMP(p
, accounting
.steal_time
, "llx");
2422 catch_memory_errors
= 0;
2426 static void dump_all_pacas(void)
2430 if (num_possible_cpus() == 0) {
2431 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2435 for_each_possible_cpu(cpu
)
2439 static void dump_pacas(void)
2450 termch
= c
; /* Put c back, it wasn't 'a' */
2455 dump_one_paca(xmon_owner
);
2459 #ifdef CONFIG_PPC_POWERNV
2460 static void dump_one_xive(int cpu
)
2462 unsigned int hwid
= get_hard_smp_processor_id(cpu
);
2464 opal_xive_dump(XIVE_DUMP_TM_HYP
, hwid
);
2465 opal_xive_dump(XIVE_DUMP_TM_POOL
, hwid
);
2466 opal_xive_dump(XIVE_DUMP_TM_OS
, hwid
);
2467 opal_xive_dump(XIVE_DUMP_TM_USER
, hwid
);
2468 opal_xive_dump(XIVE_DUMP_VP
, hwid
);
2469 opal_xive_dump(XIVE_DUMP_EMU_STATE
, hwid
);
2471 if (setjmp(bus_error_jmp
) != 0) {
2472 catch_memory_errors
= 0;
2473 printf("*** Error dumping xive on cpu %d\n", cpu
);
2477 catch_memory_errors
= 1;
2479 xmon_xive_do_dump(cpu
);
2482 catch_memory_errors
= 0;
2485 static void dump_all_xives(void)
2489 if (num_possible_cpus() == 0) {
2490 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2494 for_each_possible_cpu(cpu
)
2498 static void dump_one_xive_irq(u32 num
)
2505 rc
= opal_xive_get_irq_config(num
, &vp
, &prio
, &lirq
);
2506 xmon_printf("IRQ 0x%x config: vp=0x%llx prio=%d lirq=0x%x (rc=%lld)\n",
2507 num
, be64_to_cpu(vp
), prio
, be32_to_cpu(lirq
), rc
);
2510 static void dump_xives(void)
2515 if (!xive_enabled()) {
2516 printf("Xive disabled on this system\n");
2524 } else if (c
== 'i') {
2526 dump_one_xive_irq(num
);
2530 termch
= c
; /* Put c back, it wasn't 'a' */
2535 dump_one_xive(xmon_owner
);
2537 #endif /* CONFIG_PPC_POWERNV */
2539 static void dump_by_size(unsigned long addr
, long count
, int size
)
2541 unsigned char temp
[16];
2545 count
= ALIGN(count
, 16);
2547 for (i
= 0; i
< count
; i
+= 16, addr
+= 16) {
2550 if (mread(addr
, temp
, 16) != 16) {
2551 printf("\nFaulted reading %d bytes from 0x"REG
"\n", 16, addr
);
2555 for (j
= 0; j
< 16; j
+= size
) {
2558 case 1: val
= temp
[j
]; break;
2559 case 2: val
= *(u16
*)&temp
[j
]; break;
2560 case 4: val
= *(u32
*)&temp
[j
]; break;
2561 case 8: val
= *(u64
*)&temp
[j
]; break;
2565 printf("%0*lx", size
* 2, val
);
2574 static char last
[] = { "d?\n" };
2581 xmon_start_pagination();
2583 xmon_end_pagination();
2587 #ifdef CONFIG_PPC_POWERNV
2589 xmon_start_pagination();
2591 xmon_end_pagination();
2604 scanhex((void *)&adrs
);
2611 else if (nidump
> MAX_DUMP
)
2613 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2615 } else if (c
== 'l') {
2617 } else if (c
== 'o') {
2619 } else if (c
== 'v') {
2620 /* dump virtual to physical translation */
2622 } else if (c
== 'r') {
2626 xmon_rawdump(adrs
, ndump
);
2633 else if (ndump
> MAX_DUMP
)
2641 ndump
= ALIGN(ndump
, 16);
2642 dump_by_size(adrs
, ndump
, c
- '0');
2647 prdump(adrs
, ndump
);
2656 prdump(unsigned long adrs
, long ndump
)
2658 long n
, m
, c
, r
, nr
;
2659 unsigned char temp
[16];
2661 for (n
= ndump
; n
> 0;) {
2665 nr
= mread(adrs
, temp
, r
);
2667 for (m
= 0; m
< r
; ++m
) {
2668 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2671 printf("%.2x", temp
[m
]);
2673 printf("%s", fault_chars
[fault_type
]);
2675 for (; m
< 16; ++m
) {
2676 if ((m
& (sizeof(long) - 1)) == 0)
2681 for (m
= 0; m
< r
; ++m
) {
2684 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2697 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2700 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2701 instruction_dump_func dump_func
)
2704 unsigned long first_adr
;
2705 unsigned long inst
, last_inst
= 0;
2706 unsigned char val
[4];
2709 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2710 nr
= mread(adr
, val
, 4);
2713 const char *x
= fault_chars
[fault_type
];
2714 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2718 inst
= GETWORD(val
);
2719 if (adr
> first_adr
&& inst
== last_inst
) {
2729 printf(REG
" %.8x", adr
, inst
);
2731 dump_func(inst
, adr
);
2734 return adr
- first_adr
;
2738 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2740 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2744 print_address(unsigned long addr
)
2746 xmon_print_symbol(addr
, "\t# ", "");
2752 struct kmsg_dumper dumper
= { .active
= 1 };
2753 unsigned char buf
[128];
2756 if (setjmp(bus_error_jmp
) != 0) {
2757 printf("Error dumping printk buffer!\n");
2761 catch_memory_errors
= 1;
2764 kmsg_dump_rewind_nolock(&dumper
);
2765 xmon_start_pagination();
2766 while (kmsg_dump_get_line_nolock(&dumper
, false, buf
, sizeof(buf
), &len
)) {
2770 xmon_end_pagination();
2773 /* wait a little while to see if we get a machine check */
2775 catch_memory_errors
= 0;
2778 #ifdef CONFIG_PPC_POWERNV
2779 static void dump_opal_msglog(void)
2781 unsigned char buf
[128];
2785 if (!firmware_has_feature(FW_FEATURE_OPAL
)) {
2786 printf("Machine is not running OPAL firmware.\n");
2790 if (setjmp(bus_error_jmp
) != 0) {
2791 printf("Error dumping OPAL msglog!\n");
2795 catch_memory_errors
= 1;
2798 xmon_start_pagination();
2799 while ((res
= opal_msglog_copy(buf
, pos
, sizeof(buf
) - 1))) {
2801 printf("Error dumping OPAL msglog! Error: %zd\n", res
);
2808 xmon_end_pagination();
2811 /* wait a little while to see if we get a machine check */
2813 catch_memory_errors
= 0;
2818 * Memory operations - move, set, print differences
2820 static unsigned long mdest
; /* destination address */
2821 static unsigned long msrc
; /* source address */
2822 static unsigned long mval
; /* byte value to set memory to */
2823 static unsigned long mcount
; /* # bytes to affect */
2824 static unsigned long mdiffs
; /* max # differences to print */
2829 scanhex((void *)&mdest
);
2830 if( termch
!= '\n' )
2832 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2833 if( termch
!= '\n' )
2835 scanhex((void *)&mcount
);
2838 memmove((void *)mdest
, (void *)msrc
, mcount
);
2841 memset((void *)mdest
, mval
, mcount
);
2844 if( termch
!= '\n' )
2846 scanhex((void *)&mdiffs
);
2847 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2853 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2858 for( n
= nb
; n
> 0; --n
)
2859 if( *p1
++ != *p2
++ )
2860 if( ++prt
<= maxpr
)
2861 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2862 p1
[-1], p2
- 1, p2
[-1]);
2864 printf("Total of %d differences\n", prt
);
2867 static unsigned mend
;
2868 static unsigned mask
;
2874 unsigned char val
[4];
2877 scanhex((void *)&mdest
);
2878 if (termch
!= '\n') {
2880 scanhex((void *)&mend
);
2881 if (termch
!= '\n') {
2883 scanhex((void *)&mval
);
2885 if (termch
!= '\n') termch
= 0;
2886 scanhex((void *)&mask
);
2890 for (a
= mdest
; a
< mend
; a
+= 4) {
2891 if (mread(a
, val
, 4) == 4
2892 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2893 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2900 static unsigned long mskip
= 0x1000;
2901 static unsigned long mlim
= 0xffffffff;
2911 if (termch
!= '\n') termch
= 0;
2913 if (termch
!= '\n') termch
= 0;
2916 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2917 ok
= mread(a
, &v
, 1);
2919 printf("%.8x .. ", a
);
2920 } else if (!ok
&& ook
)
2921 printf("%.8x\n", a
- mskip
);
2927 printf("%.8x\n", a
- mskip
);
2930 static void show_task(struct task_struct
*tsk
)
2935 * Cloned from kdb_task_state_char(), which is not entirely
2936 * appropriate for calling from xmon. This could be moved
2937 * to a common, generic, routine used by both.
2939 state
= (tsk
->state
== 0) ? 'R' :
2940 (tsk
->state
< 0) ? 'U' :
2941 (tsk
->state
& TASK_UNINTERRUPTIBLE
) ? 'D' :
2942 (tsk
->state
& TASK_STOPPED
) ? 'T' :
2943 (tsk
->state
& TASK_TRACED
) ? 'C' :
2944 (tsk
->exit_state
& EXIT_ZOMBIE
) ? 'Z' :
2945 (tsk
->exit_state
& EXIT_DEAD
) ? 'E' :
2946 (tsk
->state
& TASK_INTERRUPTIBLE
) ? 'S' : '?';
2948 printf("%px %016lx %6d %6d %c %2d %s\n", tsk
,
2950 tsk
->pid
, tsk
->parent
->pid
,
2951 state
, task_thread_info(tsk
)->cpu
,
2955 #ifdef CONFIG_PPC_BOOK3S_64
2956 void format_pte(void *ptep
, unsigned long pte
)
2958 printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep
, pte
);
2959 printf("Maps physical address = 0x%016lx\n", pte
& PTE_RPN_MASK
);
2961 printf("Flags = %s%s%s%s%s\n",
2962 (pte
& _PAGE_ACCESSED
) ? "Accessed " : "",
2963 (pte
& _PAGE_DIRTY
) ? "Dirty " : "",
2964 (pte
& _PAGE_READ
) ? "Read " : "",
2965 (pte
& _PAGE_WRITE
) ? "Write " : "",
2966 (pte
& _PAGE_EXEC
) ? "Exec " : "");
2969 static void show_pte(unsigned long addr
)
2971 unsigned long tskv
= 0;
2972 struct task_struct
*tsk
= NULL
;
2973 struct mm_struct
*mm
;
2974 pgd_t
*pgdp
, *pgdir
;
2979 if (!scanhex(&tskv
))
2982 tsk
= (struct task_struct
*)tskv
;
2987 mm
= tsk
->active_mm
;
2989 if (setjmp(bus_error_jmp
) != 0) {
2990 catch_memory_errors
= 0;
2991 printf("*** Error dumping pte for task %px\n", tsk
);
2995 catch_memory_errors
= 1;
2998 if (mm
== &init_mm
) {
2999 pgdp
= pgd_offset_k(addr
);
3000 pgdir
= pgd_offset_k(0);
3002 pgdp
= pgd_offset(mm
, addr
);
3003 pgdir
= pgd_offset(mm
, 0);
3006 if (pgd_none(*pgdp
)) {
3007 printf("no linux page table for address\n");
3011 printf("pgd @ 0x%016lx\n", pgdir
);
3013 if (pgd_huge(*pgdp
)) {
3014 format_pte(pgdp
, pgd_val(*pgdp
));
3017 printf("pgdp @ 0x%016lx = 0x%016lx\n", pgdp
, pgd_val(*pgdp
));
3019 pudp
= pud_offset(pgdp
, addr
);
3021 if (pud_none(*pudp
)) {
3022 printf("No valid PUD\n");
3026 if (pud_huge(*pudp
)) {
3027 format_pte(pudp
, pud_val(*pudp
));
3031 printf("pudp @ 0x%016lx = 0x%016lx\n", pudp
, pud_val(*pudp
));
3033 pmdp
= pmd_offset(pudp
, addr
);
3035 if (pmd_none(*pmdp
)) {
3036 printf("No valid PMD\n");
3040 if (pmd_huge(*pmdp
)) {
3041 format_pte(pmdp
, pmd_val(*pmdp
));
3044 printf("pmdp @ 0x%016lx = 0x%016lx\n", pmdp
, pmd_val(*pmdp
));
3046 ptep
= pte_offset_map(pmdp
, addr
);
3047 if (pte_none(*ptep
)) {
3048 printf("no valid PTE\n");
3052 format_pte(ptep
, pte_val(*ptep
));
3056 catch_memory_errors
= 0;
3059 static void show_pte(unsigned long addr
)
3061 printf("show_pte not yet implemented\n");
3063 #endif /* CONFIG_PPC_BOOK3S_64 */
3065 static void show_tasks(void)
3068 struct task_struct
*tsk
= NULL
;
3070 printf(" task_struct ->thread.ksp PID PPID S P CMD\n");
3073 tsk
= (struct task_struct
*)tskv
;
3075 if (setjmp(bus_error_jmp
) != 0) {
3076 catch_memory_errors
= 0;
3077 printf("*** Error dumping task %px\n", tsk
);
3081 catch_memory_errors
= 1;
3087 for_each_process(tsk
)
3092 catch_memory_errors
= 0;
3095 static void proccall(void)
3097 unsigned long args
[8];
3100 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
3101 unsigned long, unsigned long, unsigned long,
3102 unsigned long, unsigned long, unsigned long);
3105 if (!scanhex(&adrs
))
3109 for (i
= 0; i
< 8; ++i
)
3111 for (i
= 0; i
< 8; ++i
) {
3112 if (!scanhex(&args
[i
]) || termch
== '\n')
3116 func
= (callfunc_t
) adrs
;
3118 if (setjmp(bus_error_jmp
) == 0) {
3119 catch_memory_errors
= 1;
3121 ret
= func(args
[0], args
[1], args
[2], args
[3],
3122 args
[4], args
[5], args
[6], args
[7]);
3124 printf("return value is 0x%lx\n", ret
);
3126 printf("*** %x exception occurred\n", fault_except
);
3128 catch_memory_errors
= 0;
3131 /* Input scanning routines */
3142 while( c
== ' ' || c
== '\t' )
3148 static char *regnames
[N_PTREGS
] = {
3149 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3150 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3151 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3152 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3153 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3159 "trap", "dar", "dsisr", "res"
3163 scanhex(unsigned long *vp
)
3170 /* parse register name */
3174 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
3183 for (i
= 0; i
< N_PTREGS
; ++i
) {
3184 if (strcmp(regnames
[i
], regname
) == 0) {
3185 if (xmon_regs
== NULL
) {
3186 printf("regs not available\n");
3189 *vp
= ((unsigned long *)xmon_regs
)[i
];
3193 printf("invalid register name '%%%s'\n", regname
);
3197 /* skip leading "0x" if any */
3211 } else if (c
== '$') {
3213 for (i
=0; i
<63; i
++) {
3215 if (isspace(c
) || c
== '\0') {
3223 if (setjmp(bus_error_jmp
) == 0) {
3224 catch_memory_errors
= 1;
3226 *vp
= kallsyms_lookup_name(tmpstr
);
3229 catch_memory_errors
= 0;
3231 printf("unknown symbol '%s'\n", tmpstr
);
3264 static int hexdigit(int c
)
3266 if( '0' <= c
&& c
<= '9' )
3268 if( 'A' <= c
&& c
<= 'F' )
3269 return c
- ('A' - 10);
3270 if( 'a' <= c
&& c
<= 'f' )
3271 return c
- ('a' - 10);
3276 getstring(char *s
, int size
)
3287 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
3292 static char line
[256];
3293 static char *lineptr
;
3304 if (lineptr
== NULL
|| *lineptr
== 0) {
3305 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
3315 take_input(char *str
)
3324 int type
= inchar();
3326 static char tmp
[64];
3331 xmon_print_symbol(addr
, ": ", "\n");
3336 if (setjmp(bus_error_jmp
) == 0) {
3337 catch_memory_errors
= 1;
3339 addr
= kallsyms_lookup_name(tmp
);
3341 printf("%s: %lx\n", tmp
, addr
);
3343 printf("Symbol '%s' not found.\n", tmp
);
3346 catch_memory_errors
= 0;
3353 /* Print an address in numeric and symbolic form (if possible) */
3354 static void xmon_print_symbol(unsigned long address
, const char *mid
,
3358 const char *name
= NULL
;
3359 unsigned long offset
, size
;
3361 printf(REG
, address
);
3362 if (setjmp(bus_error_jmp
) == 0) {
3363 catch_memory_errors
= 1;
3365 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
3368 /* wait a little while to see if we get a machine check */
3372 catch_memory_errors
= 0;
3375 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
3377 printf(" [%s]", modname
);
3379 printf("%s", after
);
3382 #ifdef CONFIG_PPC_BOOK3S_64
3383 void dump_segments(void)
3386 unsigned long esid
,vsid
;
3389 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3391 for (i
= 0; i
< mmu_slb_size
; i
++) {
3392 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
3393 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
3398 printf("%02d %016lx %016lx", i
, esid
, vsid
);
3400 if (!(esid
& SLB_ESID_V
)) {
3405 llp
= vsid
& SLB_VSID_LLP
;
3406 if (vsid
& SLB_VSID_B_1T
) {
3407 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3409 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
3412 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3414 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
3421 #ifdef CONFIG_PPC_STD_MMU_32
3422 void dump_segments(void)
3427 for (i
= 0; i
< 16; ++i
)
3428 printf(" %x", mfsrin(i
));
3434 static void dump_tlb_44x(void)
3438 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
3439 unsigned long w0
,w1
,w2
;
3440 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
3441 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
3442 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
3443 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
3444 if (w0
& PPC44x_TLB_VALID
) {
3445 printf("V %08x -> %01x%08x %c%c%c%c%c",
3446 w0
& PPC44x_TLB_EPN_MASK
,
3447 w1
& PPC44x_TLB_ERPN_MASK
,
3448 w1
& PPC44x_TLB_RPN_MASK
,
3449 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
3450 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
3451 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
3452 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
3453 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
3458 #endif /* CONFIG_44x */
3460 #ifdef CONFIG_PPC_BOOK3E
3461 static void dump_tlb_book3e(void)
3463 u32 mmucfg
, pidmask
, lpidmask
;
3465 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
3467 static const char *pgsz_names
[] = {
3502 /* Gather some infos about the MMU */
3503 mmucfg
= mfspr(SPRN_MMUCFG
);
3504 mmu_version
= (mmucfg
& 3) + 1;
3505 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
3506 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
3507 lpidsz
= (mmucfg
>> 24) & 0xf;
3508 rasz
= (mmucfg
>> 16) & 0x7f;
3509 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
3511 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3512 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
3513 pidmask
= (1ul << pidsz
) - 1;
3514 lpidmask
= (1ul << lpidsz
) - 1;
3515 ramask
= (1ull << rasz
) - 1;
3517 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
3519 int nent
, assoc
, new_cc
= 1;
3520 printf("TLB %d:\n------\n", tlb
);
3523 tlbcfg
= mfspr(SPRN_TLB0CFG
);
3526 tlbcfg
= mfspr(SPRN_TLB1CFG
);
3529 tlbcfg
= mfspr(SPRN_TLB2CFG
);
3532 tlbcfg
= mfspr(SPRN_TLB3CFG
);
3535 printf("Unsupported TLB number !\n");
3538 nent
= tlbcfg
& 0xfff;
3539 assoc
= (tlbcfg
>> 24) & 0xff;
3540 for (i
= 0; i
< nent
; i
++) {
3541 u32 mas0
= MAS0_TLBSEL(tlb
);
3542 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
3545 int esel
= i
, cc
= i
;
3553 mas0
|= MAS0_ESEL(esel
);
3554 mtspr(SPRN_MAS0
, mas0
);
3555 mtspr(SPRN_MAS1
, mas1
);
3556 mtspr(SPRN_MAS2
, mas2
);
3557 asm volatile("tlbre 0,0,0" : : : "memory");
3558 mas1
= mfspr(SPRN_MAS1
);
3559 mas2
= mfspr(SPRN_MAS2
);
3560 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
3561 if (assoc
&& (i
% assoc
) == 0)
3563 if (!(mas1
& MAS1_VALID
))
3566 printf("%04x- ", i
);
3568 printf("%04x-%c", cc
, 'A' + esel
);
3570 printf(" |%c", 'A' + esel
);
3572 printf(" %016llx %04x %s %c%c AS%c",
3574 (mas1
>> 16) & 0x3fff,
3575 pgsz_names
[(mas1
>> 7) & 0x1f],
3576 mas1
& MAS1_IND
? 'I' : ' ',
3577 mas1
& MAS1_IPROT
? 'P' : ' ',
3578 mas1
& MAS1_TS
? '1' : '0');
3579 printf(" %c%c%c%c%c%c%c",
3580 mas2
& MAS2_X0
? 'a' : ' ',
3581 mas2
& MAS2_X1
? 'v' : ' ',
3582 mas2
& MAS2_W
? 'w' : ' ',
3583 mas2
& MAS2_I
? 'i' : ' ',
3584 mas2
& MAS2_M
? 'm' : ' ',
3585 mas2
& MAS2_G
? 'g' : ' ',
3586 mas2
& MAS2_E
? 'e' : ' ');
3587 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
3588 if (mas1
& MAS1_IND
)
3590 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
3592 printf(" U%c%c%c S%c%c%c\n",
3593 mas7_mas3
& MAS3_UX
? 'x' : ' ',
3594 mas7_mas3
& MAS3_UW
? 'w' : ' ',
3595 mas7_mas3
& MAS3_UR
? 'r' : ' ',
3596 mas7_mas3
& MAS3_SX
? 'x' : ' ',
3597 mas7_mas3
& MAS3_SW
? 'w' : ' ',
3598 mas7_mas3
& MAS3_SR
? 'r' : ' ');
3602 #endif /* CONFIG_PPC_BOOK3E */
3604 static void xmon_init(int enable
)
3608 __debugger_ipi
= xmon_ipi
;
3609 __debugger_bpt
= xmon_bpt
;
3610 __debugger_sstep
= xmon_sstep
;
3611 __debugger_iabr_match
= xmon_iabr_match
;
3612 __debugger_break_match
= xmon_break_match
;
3613 __debugger_fault_handler
= xmon_fault_handler
;
3616 __debugger_ipi
= NULL
;
3617 __debugger_bpt
= NULL
;
3618 __debugger_sstep
= NULL
;
3619 __debugger_iabr_match
= NULL
;
3620 __debugger_break_match
= NULL
;
3621 __debugger_fault_handler
= NULL
;
3625 #ifdef CONFIG_MAGIC_SYSRQ
3626 static void sysrq_handle_xmon(int key
)
3628 /* ensure xmon is enabled */
3630 debugger(get_irq_regs());
3635 static struct sysrq_key_op sysrq_xmon_op
= {
3636 .handler
= sysrq_handle_xmon
,
3637 .help_msg
= "xmon(x)",
3638 .action_msg
= "Entering xmon",
3641 static int __init
setup_xmon_sysrq(void)
3643 register_sysrq_key('x', &sysrq_xmon_op
);
3646 device_initcall(setup_xmon_sysrq
);
3647 #endif /* CONFIG_MAGIC_SYSRQ */
3649 #ifdef CONFIG_DEBUG_FS
3650 static int xmon_dbgfs_set(void *data
, u64 val
)
3658 static int xmon_dbgfs_get(void *data
, u64
*val
)
3664 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops
, xmon_dbgfs_get
,
3665 xmon_dbgfs_set
, "%llu\n");
3667 static int __init
setup_xmon_dbgfs(void)
3669 debugfs_create_file("xmon", 0600, powerpc_debugfs_root
, NULL
,
3673 device_initcall(setup_xmon_dbgfs
);
3674 #endif /* CONFIG_DEBUG_FS */
3676 static int xmon_early __initdata
;
3678 static int __init
early_parse_xmon(char *p
)
3680 if (!p
|| strncmp(p
, "early", 5) == 0) {
3681 /* just "xmon" is equivalent to "xmon=early" */
3685 } else if (strncmp(p
, "on", 2) == 0) {
3688 } else if (strncmp(p
, "off", 3) == 0)
3695 early_param("xmon", early_parse_xmon
);
3697 void __init
xmon_setup(void)
3705 #ifdef CONFIG_SPU_BASE
3709 u64 saved_mfc_sr1_RW
;
3710 u32 saved_spu_runcntl_RW
;
3711 unsigned long dump_addr
;
3715 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3717 static struct spu_info spu_info
[XMON_NUM_SPUS
];
3719 void xmon_register_spus(struct list_head
*list
)
3723 list_for_each_entry(spu
, list
, full_list
) {
3724 if (spu
->number
>= XMON_NUM_SPUS
) {
3729 spu_info
[spu
->number
].spu
= spu
;
3730 spu_info
[spu
->number
].stopped_ok
= 0;
3731 spu_info
[spu
->number
].dump_addr
= (unsigned long)
3732 spu_info
[spu
->number
].spu
->local_store
;
3736 static void stop_spus(void)
3742 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3743 if (!spu_info
[i
].spu
)
3746 if (setjmp(bus_error_jmp
) == 0) {
3747 catch_memory_errors
= 1;
3750 spu
= spu_info
[i
].spu
;
3752 spu_info
[i
].saved_spu_runcntl_RW
=
3753 in_be32(&spu
->problem
->spu_runcntl_RW
);
3755 tmp
= spu_mfc_sr1_get(spu
);
3756 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
3758 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
3759 spu_mfc_sr1_set(spu
, tmp
);
3764 spu_info
[i
].stopped_ok
= 1;
3766 printf("Stopped spu %.2d (was %s)\n", i
,
3767 spu_info
[i
].saved_spu_runcntl_RW
?
3768 "running" : "stopped");
3770 catch_memory_errors
= 0;
3771 printf("*** Error stopping spu %.2d\n", i
);
3773 catch_memory_errors
= 0;
3777 static void restart_spus(void)
3782 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3783 if (!spu_info
[i
].spu
)
3786 if (!spu_info
[i
].stopped_ok
) {
3787 printf("*** Error, spu %d was not successfully stopped"
3788 ", not restarting\n", i
);
3792 if (setjmp(bus_error_jmp
) == 0) {
3793 catch_memory_errors
= 1;
3796 spu
= spu_info
[i
].spu
;
3797 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
3798 out_be32(&spu
->problem
->spu_runcntl_RW
,
3799 spu_info
[i
].saved_spu_runcntl_RW
);
3804 printf("Restarted spu %.2d\n", i
);
3806 catch_memory_errors
= 0;
3807 printf("*** Error restarting spu %.2d\n", i
);
3809 catch_memory_errors
= 0;
3813 #define DUMP_WIDTH 23
3814 #define DUMP_VALUE(format, field, value) \
3816 if (setjmp(bus_error_jmp) == 0) { \
3817 catch_memory_errors = 1; \
3819 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3824 catch_memory_errors = 0; \
3825 printf(" %-*s = *** Error reading field.\n", \
3826 DUMP_WIDTH, #field); \
3828 catch_memory_errors = 0; \
3831 #define DUMP_FIELD(obj, format, field) \
3832 DUMP_VALUE(format, field, obj->field)
3834 static void dump_spu_fields(struct spu
*spu
)
3836 printf("Dumping spu fields at address %p:\n", spu
);
3838 DUMP_FIELD(spu
, "0x%x", number
);
3839 DUMP_FIELD(spu
, "%s", name
);
3840 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3841 DUMP_FIELD(spu
, "0x%p", local_store
);
3842 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3843 DUMP_FIELD(spu
, "0x%x", node
);
3844 DUMP_FIELD(spu
, "0x%lx", flags
);
3845 DUMP_FIELD(spu
, "%d", class_0_pending
);
3846 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
3847 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
3848 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
3849 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
3850 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
3851 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
3852 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3853 DUMP_FIELD(spu
, "%d", pid
);
3854 DUMP_FIELD(spu
, "0x%p", mm
);
3855 DUMP_FIELD(spu
, "0x%p", ctx
);
3856 DUMP_FIELD(spu
, "0x%p", rq
);
3857 DUMP_FIELD(spu
, "0x%p", timestamp
);
3858 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3859 DUMP_FIELD(spu
, "0x%p", problem
);
3860 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3861 in_be32(&spu
->problem
->spu_runcntl_RW
));
3862 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3863 in_be32(&spu
->problem
->spu_status_R
));
3864 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3865 in_be32(&spu
->problem
->spu_npc_RW
));
3866 DUMP_FIELD(spu
, "0x%p", priv2
);
3867 DUMP_FIELD(spu
, "0x%p", pdata
);
3871 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3873 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3876 static void dump_spu_ls(unsigned long num
, int subcmd
)
3878 unsigned long offset
, addr
, ls_addr
;
3880 if (setjmp(bus_error_jmp
) == 0) {
3881 catch_memory_errors
= 1;
3883 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3887 catch_memory_errors
= 0;
3888 printf("*** Error: accessing spu info for spu %d\n", num
);
3891 catch_memory_errors
= 0;
3893 if (scanhex(&offset
))
3894 addr
= ls_addr
+ offset
;
3896 addr
= spu_info
[num
].dump_addr
;
3898 if (addr
>= ls_addr
+ LS_SIZE
) {
3899 printf("*** Error: address outside of local store\n");
3905 addr
+= spu_inst_dump(addr
, 16, 1);
3915 spu_info
[num
].dump_addr
= addr
;
3918 static int do_spu_cmd(void)
3920 static unsigned long num
= 0;
3921 int cmd
, subcmd
= 0;
3933 if (isxdigit(subcmd
) || subcmd
== '\n')
3937 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3938 printf("*** Error: invalid spu number\n");
3944 dump_spu_fields(spu_info
[num
].spu
);
3947 dump_spu_ls(num
, subcmd
);
3958 #else /* ! CONFIG_SPU_BASE */
3959 static int do_spu_cmd(void)