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/plpar_wrappers.h>
45 #include <asm/cputable.h>
47 #include <asm/sstep.h>
48 #include <asm/irq_regs.h>
50 #include <asm/spu_priv1.h>
51 #include <asm/setjmp.h>
53 #include <asm/debug.h>
54 #include <asm/hw_breakpoint.h>
57 #include <asm/firmware.h>
58 #include <asm/code-patching.h>
59 #include <asm/sections.h>
62 #include <asm/hvcall.h>
70 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
71 static unsigned long xmon_taken
= 1;
72 static int xmon_owner
;
76 #endif /* CONFIG_SMP */
78 #ifdef CONFIG_PPC_PSERIES
79 static int set_indicator_token
= RTAS_UNKNOWN_SERVICE
;
81 static unsigned long in_xmon __read_mostly
= 0;
82 static int xmon_on
= IS_ENABLED(CONFIG_XMON_DEFAULT
);
84 static unsigned long adrs
;
86 #define MAX_DUMP (128 * 1024)
87 static unsigned long ndump
= 64;
88 static unsigned long nidump
= 16;
89 static unsigned long ncsum
= 4096;
91 static char tmpstr
[128];
92 static int tracing_enabled
;
94 static long bus_error_jmp
[JMP_BUF_LEN
];
95 static int catch_memory_errors
;
96 static int catch_spr_faults
;
97 static long *xmon_fault_jmp
[NR_CPUS
];
99 /* Breakpoint stuff */
101 unsigned long address
;
102 unsigned int instr
[2];
108 /* Bits in bpt.enabled */
114 static struct bpt bpts
[NBPTS
];
115 static struct bpt dabr
;
116 static struct bpt
*iabr
;
117 static unsigned bpinstr
= 0x7fe00008; /* trap */
119 #define BP_NUM(bp) ((bp) - bpts + 1)
122 static int cmds(struct pt_regs
*);
123 static int mread(unsigned long, void *, int);
124 static int mwrite(unsigned long, void *, int);
125 static int handle_fault(struct pt_regs
*);
126 static void byterev(unsigned char *, int);
127 static void memex(void);
128 static int bsesc(void);
129 static void dump(void);
130 static void show_pte(unsigned long);
131 static void prdump(unsigned long, long);
132 static int ppc_inst_dump(unsigned long, long, int);
133 static void dump_log_buf(void);
135 #ifdef CONFIG_PPC_POWERNV
136 static void dump_opal_msglog(void);
138 static inline void dump_opal_msglog(void)
140 printf("Machine is not running OPAL firmware.\n");
144 static void backtrace(struct pt_regs
*);
145 static void excprint(struct pt_regs
*);
146 static void prregs(struct pt_regs
*);
147 static void memops(int);
148 static void memlocate(void);
149 static void memzcan(void);
150 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
152 int scanhex(unsigned long *valp
);
153 static void scannl(void);
154 static int hexdigit(int);
155 void getstring(char *, int);
156 static void flush_input(void);
157 static int inchar(void);
158 static void take_input(char *);
159 static int read_spr(int, unsigned long *);
160 static void write_spr(int, unsigned long);
161 static void super_regs(void);
162 static void remove_bpts(void);
163 static void insert_bpts(void);
164 static void remove_cpu_bpts(void);
165 static void insert_cpu_bpts(void);
166 static struct bpt
*at_breakpoint(unsigned long pc
);
167 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
168 static int do_step(struct pt_regs
*);
169 static void bpt_cmds(void);
170 static void cacheflush(void);
171 static int cpu_cmd(void);
172 static void csum(void);
173 static void bootcmds(void);
174 static void proccall(void);
175 static void show_tasks(void);
176 void dump_segments(void);
177 static void symbol_lookup(void);
178 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
180 static void xmon_print_symbol(unsigned long address
, const char *mid
,
182 static const char *getvecname(unsigned long vec
);
184 static int do_spu_cmd(void);
187 static void dump_tlb_44x(void);
189 #ifdef CONFIG_PPC_BOOK3E
190 static void dump_tlb_book3e(void);
199 #ifdef __LITTLE_ENDIAN__
200 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
202 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
205 static char *help_string
= "\
207 b show breakpoints\n\
208 bd set data breakpoint\n\
209 bi set instruction breakpoint\n\
210 bc clear breakpoint\n"
213 c print cpus stopped in xmon\n\
214 c# try to switch to cpu number h (in hex)\n"
219 d1 dump 1 byte values\n\
220 d2 dump 2 byte values\n\
221 d4 dump 4 byte values\n\
222 d8 dump 8 byte values\n\
223 di dump instructions\n\
224 df dump float values\n\
225 dd dump double values\n\
226 dl dump the kernel log buffer\n"
227 #ifdef CONFIG_PPC_POWERNV
229 do dump the OPAL message log\n"
233 dp[#] dump paca for current cpu, or cpu #\n\
234 dpa dump paca for all possible cpus\n"
237 dr dump stream of raw bytes\n\
238 dv dump virtual address translation \n\
239 dt dump the tracing buffers (uses printk)\n\
240 dtc dump the tracing buffers for current CPU (uses printk)\n\
242 #ifdef CONFIG_PPC_POWERNV
243 " dx# dump xive on CPU #\n\
244 dxi# dump xive irq state #\n\
245 dxa dump xive on all CPUs\n"
247 " e print exception information\n\
249 la lookup symbol+offset of specified address\n\
250 ls lookup address of specified symbol\n\
251 lp s [#] lookup address of percpu symbol s for current cpu, or cpu #\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_BOOK3S_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 plpar_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
;
366 * At this point we have got all the cpus we can into
367 * xmon, so there is hopefully no other cpu calling RTAS
368 * at the moment, even though we don't take rtas.lock.
369 * If we did try to take rtas.lock there would be a
370 * real possibility of deadlock.
372 if (set_indicator_token
== RTAS_UNKNOWN_SERVICE
)
375 rtas_call_unlocked(&args
, set_indicator_token
, 3, 1, NULL
,
376 SURVEILLANCE_TOKEN
, 0, 0);
378 #endif /* CONFIG_PPC_PSERIES */
382 static int xmon_speaker
;
384 static void get_output_lock(void)
386 int me
= smp_processor_id() + 0x100;
387 int last_speaker
= 0, prev
;
390 if (xmon_speaker
== me
)
394 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
395 if (last_speaker
== 0)
399 * Wait a full second for the lock, we might be on a slow
400 * console, but check every 100us.
403 while (xmon_speaker
== last_speaker
) {
409 /* hostile takeover */
410 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
411 if (prev
== last_speaker
)
418 static void release_output_lock(void)
423 int cpus_are_in_xmon(void)
425 return !cpumask_empty(&cpus_in_xmon
);
428 static bool wait_for_other_cpus(int ncpus
)
430 unsigned long timeout
;
432 /* We wait for 2s, which is a metric "little while" */
433 for (timeout
= 20000; timeout
!= 0; --timeout
) {
434 if (cpumask_weight(&cpus_in_xmon
) >= ncpus
)
442 #endif /* CONFIG_SMP */
444 static inline int unrecoverable_excp(struct pt_regs
*regs
)
446 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
447 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
450 return ((regs
->msr
& MSR_RI
) == 0);
454 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
458 long recurse_jmp
[JMP_BUF_LEN
];
459 unsigned long offset
;
466 local_irq_save(flags
);
469 tracing_enabled
= tracing_is_on();
472 bp
= in_breakpoint_table(regs
->nip
, &offset
);
474 regs
->nip
= bp
->address
+ offset
;
475 atomic_dec(&bp
->ref_count
);
481 cpu
= smp_processor_id();
482 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
484 * We catch SPR read/write faults here because the 0x700, 0xf60
485 * etc. handlers don't call debugger_fault_handler().
487 if (catch_spr_faults
)
488 longjmp(bus_error_jmp
, 1);
491 printf("cpu 0x%x: Exception %lx %s in xmon, "
492 "returning to main loop\n",
493 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
494 release_output_lock();
495 longjmp(xmon_fault_jmp
[cpu
], 1);
498 if (setjmp(recurse_jmp
) != 0) {
499 if (!in_xmon
|| !xmon_gate
) {
501 printf("xmon: WARNING: bad recursive fault "
502 "on cpu 0x%x\n", cpu
);
503 release_output_lock();
506 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
510 xmon_fault_jmp
[cpu
] = recurse_jmp
;
513 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
))
514 bp
= at_breakpoint(regs
->nip
);
515 if (bp
|| unrecoverable_excp(regs
))
522 printf("cpu 0x%x stopped at breakpoint 0x%tx (",
524 xmon_print_symbol(regs
->nip
, " ", ")\n");
526 if (unrecoverable_excp(regs
))
527 printf("WARNING: exception is not recoverable, "
529 release_output_lock();
532 cpumask_set_cpu(cpu
, &cpus_in_xmon
);
537 while (secondary
&& !xmon_gate
) {
543 secondary
= test_and_set_bit(0, &in_xmon
);
546 touch_nmi_watchdog();
550 if (!secondary
&& !xmon_gate
) {
551 /* we are the first cpu to come in */
552 /* interrupt other cpu(s) */
553 int ncpus
= num_online_cpus();
559 * A system reset (trap == 0x100) can be triggered on
560 * all CPUs, so when we come in via 0x100 try waiting
561 * for the other CPUs to come in before we send the
562 * debugger break (IPI). This is similar to
563 * crash_kexec_secondary().
565 if (TRAP(regs
) != 0x100 || !wait_for_other_cpus(ncpus
))
566 smp_send_debugger_break();
568 wait_for_other_cpus(ncpus
);
571 disable_surveillance();
572 /* for breakpoint or single step, print the current instr. */
573 if (bp
|| TRAP(regs
) == 0xd00)
574 ppc_inst_dump(regs
->nip
, 1, 0);
575 printf("enter ? for help\n");
579 touch_nmi_watchdog();
586 if (cpu
== xmon_owner
) {
587 if (!test_and_set_bit(0, &xmon_taken
)) {
593 while (cpu
== xmon_owner
)
597 touch_nmi_watchdog();
608 /* have switched to some other cpu */
613 cpumask_clear_cpu(cpu
, &cpus_in_xmon
);
614 xmon_fault_jmp
[cpu
] = NULL
;
616 /* UP is simple... */
618 printf("Exception %lx %s in xmon, returning to main loop\n",
619 regs
->trap
, getvecname(TRAP(regs
)));
620 longjmp(xmon_fault_jmp
[0], 1);
622 if (setjmp(recurse_jmp
) == 0) {
623 xmon_fault_jmp
[0] = recurse_jmp
;
627 bp
= at_breakpoint(regs
->nip
);
629 printf("Stopped at breakpoint %tx (", BP_NUM(bp
));
630 xmon_print_symbol(regs
->nip
, " ", ")\n");
632 if (unrecoverable_excp(regs
))
633 printf("WARNING: exception is not recoverable, "
636 disable_surveillance();
637 /* for breakpoint or single step, print the current instr. */
638 if (bp
|| TRAP(regs
) == 0xd00)
639 ppc_inst_dump(regs
->nip
, 1, 0);
640 printf("enter ? for help\n");
650 if (regs
->msr
& MSR_DE
) {
651 bp
= at_breakpoint(regs
->nip
);
653 regs
->nip
= (unsigned long) &bp
->instr
[0];
654 atomic_inc(&bp
->ref_count
);
658 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
659 bp
= at_breakpoint(regs
->nip
);
661 int stepped
= emulate_step(regs
, bp
->instr
[0]);
663 regs
->nip
= (unsigned long) &bp
->instr
[0];
664 atomic_inc(&bp
->ref_count
);
665 } else if (stepped
< 0) {
666 printf("Couldn't single-step %s instruction\n",
667 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
674 touch_nmi_watchdog();
675 local_irq_restore(flags
);
677 return cmd
!= 'X' && cmd
!= EOF
;
680 int xmon(struct pt_regs
*excp
)
685 ppc_save_regs(®s
);
689 return xmon_core(excp
, 0);
693 irqreturn_t
xmon_irq(int irq
, void *d
)
696 local_irq_save(flags
);
697 printf("Keyboard interrupt\n");
698 xmon(get_irq_regs());
699 local_irq_restore(flags
);
703 static int xmon_bpt(struct pt_regs
*regs
)
706 unsigned long offset
;
708 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
711 /* Are we at the trap at bp->instr[1] for some bp? */
712 bp
= in_breakpoint_table(regs
->nip
, &offset
);
713 if (bp
!= NULL
&& offset
== 4) {
714 regs
->nip
= bp
->address
+ 4;
715 atomic_dec(&bp
->ref_count
);
719 /* Are we at a breakpoint? */
720 bp
= at_breakpoint(regs
->nip
);
729 static int xmon_sstep(struct pt_regs
*regs
)
737 static int xmon_break_match(struct pt_regs
*regs
)
739 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
741 if (dabr
.enabled
== 0)
747 static int xmon_iabr_match(struct pt_regs
*regs
)
749 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
757 static int xmon_ipi(struct pt_regs
*regs
)
760 if (in_xmon
&& !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon
))
766 static int xmon_fault_handler(struct pt_regs
*regs
)
769 unsigned long offset
;
771 if (in_xmon
&& catch_memory_errors
)
772 handle_fault(regs
); /* doesn't return */
774 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
775 bp
= in_breakpoint_table(regs
->nip
, &offset
);
777 regs
->nip
= bp
->address
+ offset
;
778 atomic_dec(&bp
->ref_count
);
785 /* Force enable xmon if not already enabled */
786 static inline void force_enable_xmon(void)
788 /* Enable xmon hooks if needed */
790 printf("xmon: Enabling debugger hooks\n");
795 static struct bpt
*at_breakpoint(unsigned long pc
)
801 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
802 if (bp
->enabled
&& pc
== bp
->address
)
807 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
811 off
= nip
- (unsigned long) bpts
;
812 if (off
>= sizeof(bpts
))
814 off
%= sizeof(struct bpt
);
815 if (off
!= offsetof(struct bpt
, instr
[0])
816 && off
!= offsetof(struct bpt
, instr
[1]))
818 *offp
= off
- offsetof(struct bpt
, instr
[0]);
819 return (struct bpt
*) (nip
- off
);
822 static struct bpt
*new_breakpoint(unsigned long a
)
827 bp
= at_breakpoint(a
);
831 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
832 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
834 bp
->instr
[1] = bpinstr
;
835 store_inst(&bp
->instr
[1]);
840 printf("Sorry, no free breakpoints. Please clear one first.\n");
844 static void insert_bpts(void)
850 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
851 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) == 0)
853 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
854 printf("Couldn't read instruction at %lx, "
855 "disabling breakpoint there\n", bp
->address
);
859 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
860 printf("Breakpoint at %lx is on an mtmsrd or rfid "
861 "instruction, disabling it\n", bp
->address
);
865 store_inst(&bp
->instr
[0]);
866 if (bp
->enabled
& BP_CIABR
)
868 if (patch_instruction((unsigned int *)bp
->address
,
870 printf("Couldn't write instruction at %lx, "
871 "disabling breakpoint there\n", bp
->address
);
872 bp
->enabled
&= ~BP_TRAP
;
875 store_inst((void *)bp
->address
);
879 static void insert_cpu_bpts(void)
881 struct arch_hw_breakpoint brk
;
884 brk
.address
= dabr
.address
;
885 brk
.type
= (dabr
.enabled
& HW_BRK_TYPE_DABR
) | HW_BRK_TYPE_PRIV_ALL
;
887 __set_breakpoint(&brk
);
891 set_ciabr(iabr
->address
);
894 static void remove_bpts(void)
901 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
902 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) != BP_TRAP
)
904 if (mread(bp
->address
, &instr
, 4) == 4
906 && patch_instruction(
907 (unsigned int *)bp
->address
, bp
->instr
[0]) != 0)
908 printf("Couldn't remove breakpoint at %lx\n",
911 store_inst((void *)bp
->address
);
915 static void remove_cpu_bpts(void)
917 hw_breakpoint_disable();
921 /* Based on uptime_proc_show(). */
925 struct timespec64 uptime
;
927 if (setjmp(bus_error_jmp
) == 0) {
928 catch_memory_errors
= 1;
931 ktime_get_coarse_boottime_ts64(&uptime
);
932 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime
.tv_sec
,
933 ((unsigned long)uptime
.tv_nsec
/ (NSEC_PER_SEC
/100)));
938 catch_memory_errors
= 0;
941 static void set_lpp_cmd(void)
945 if (!scanhex(&lpp
)) {
946 printf("Invalid number.\n");
949 xmon_set_pagination_lpp(lpp
);
951 /* Command interpreting routine */
952 static char *last_cmd
;
955 cmds(struct pt_regs
*excp
)
962 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
966 printf("%x:", smp_processor_id());
967 #endif /* CONFIG_SMP */
973 if (last_cmd
== NULL
)
975 take_input(last_cmd
);
1009 prregs(excp
); /* print regs */
1024 if (do_spu_cmd() == 0)
1031 if (tracing_enabled
)
1035 printf(" <no input ...>\n");
1039 xmon_puts(help_string
);
1063 #ifdef CONFIG_PPC_BOOK3S
1067 #elif defined(CONFIG_44x)
1071 #elif defined(CONFIG_PPC_BOOK3E)
1080 printf("Unrecognized command: ");
1082 if (' ' < cmd
&& cmd
<= '~')
1085 printf("\\x%x", cmd
);
1087 } while (cmd
!= '\n');
1088 printf(" (type ? for help)\n");
1095 static int do_step(struct pt_regs
*regs
)
1097 regs
->msr
|= MSR_DE
;
1098 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
1103 * Step a single instruction.
1104 * Some instructions we emulate, others we execute with MSR_SE set.
1106 static int do_step(struct pt_regs
*regs
)
1111 force_enable_xmon();
1112 /* check we are in 64-bit kernel mode, translation enabled */
1113 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
1114 if (mread(regs
->nip
, &instr
, 4) == 4) {
1115 stepped
= emulate_step(regs
, instr
);
1117 printf("Couldn't single-step %s instruction\n",
1118 (IS_RFID(instr
)? "rfid": "mtmsrd"));
1122 regs
->trap
= 0xd00 | (regs
->trap
& 1);
1123 printf("stepped to ");
1124 xmon_print_symbol(regs
->nip
, " ", "\n");
1125 ppc_inst_dump(regs
->nip
, 1, 0);
1130 regs
->msr
|= MSR_SE
;
1135 static void bootcmds(void)
1141 ppc_md
.restart(NULL
);
1142 else if (cmd
== 'h')
1144 else if (cmd
== 'p')
1149 static int cpu_cmd(void)
1152 unsigned long cpu
, first_cpu
, last_cpu
;
1155 if (!scanhex(&cpu
)) {
1156 /* print cpus waiting or in xmon */
1157 printf("cpus stopped:");
1158 last_cpu
= first_cpu
= NR_CPUS
;
1159 for_each_possible_cpu(cpu
) {
1160 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1161 if (cpu
== last_cpu
+ 1) {
1164 if (last_cpu
!= first_cpu
)
1165 printf("-0x%lx", last_cpu
);
1166 last_cpu
= first_cpu
= cpu
;
1167 printf(" 0x%lx", cpu
);
1171 if (last_cpu
!= first_cpu
)
1172 printf("-0x%lx", last_cpu
);
1176 /* try to switch to cpu specified */
1177 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1178 printf("cpu 0x%lx isn't in xmon\n", cpu
);
1180 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu
);
1181 xmon_show_stack(paca_ptrs
[cpu
]->saved_r1
, 0, 0);
1189 while (!xmon_taken
) {
1190 if (--timeout
== 0) {
1191 if (test_and_set_bit(0, &xmon_taken
))
1193 /* take control back */
1195 xmon_owner
= smp_processor_id();
1196 printf("cpu 0x%lx didn't take control\n", cpu
);
1204 #endif /* CONFIG_SMP */
1207 static unsigned short fcstab
[256] = {
1208 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1209 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1210 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1211 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1212 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1213 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1214 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1215 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1216 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1217 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1218 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1219 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1220 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1221 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1222 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1223 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1224 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1225 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1226 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1227 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1228 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1229 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1230 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1231 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1232 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1233 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1234 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1235 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1236 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1237 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1238 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1239 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1242 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1251 if (!scanhex(&adrs
))
1253 if (!scanhex(&ncsum
))
1256 for (i
= 0; i
< ncsum
; ++i
) {
1257 if (mread(adrs
+i
, &v
, 1) == 0) {
1258 printf("csum stopped at "REG
"\n", adrs
+i
);
1263 printf("%x\n", fcs
);
1267 * Check if this is a suitable place to put a breakpoint.
1269 static long check_bp_loc(unsigned long addr
)
1274 if (!is_kernel_addr(addr
)) {
1275 printf("Breakpoints may only be placed at kernel addresses\n");
1278 if (!mread(addr
, &instr
, sizeof(instr
))) {
1279 printf("Can't read instruction at address %lx\n", addr
);
1282 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1283 printf("Breakpoints may not be placed on mtmsrd or rfid "
1290 static char *breakpoint_help_string
=
1291 "Breakpoint command usage:\n"
1292 "b show breakpoints\n"
1293 "b <addr> [cnt] set breakpoint at given instr addr\n"
1294 "bc clear all breakpoints\n"
1295 "bc <n/addr> clear breakpoint number n or at addr\n"
1296 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1297 "bd <addr> [cnt] set hardware data breakpoint\n"
1310 #ifndef CONFIG_PPC_8xx
1311 static const char badaddr
[] = "Only kernel addresses are permitted for breakpoints\n";
1313 case 'd': /* bd - hardware data breakpoint */
1314 if (!ppc_breakpoint_available()) {
1315 printf("Hardware data breakpoint not supported on this cpu\n");
1322 else if (cmd
== 'w')
1328 if (scanhex(&dabr
.address
)) {
1329 if (!is_kernel_addr(dabr
.address
)) {
1333 dabr
.address
&= ~HW_BRK_TYPE_DABR
;
1334 dabr
.enabled
= mode
| BP_DABR
;
1337 force_enable_xmon();
1340 case 'i': /* bi - hardware instr breakpoint */
1341 if (!cpu_has_feature(CPU_FTR_ARCH_207S
)) {
1342 printf("Hardware instruction breakpoint "
1343 "not supported on this cpu\n");
1347 iabr
->enabled
&= ~BP_CIABR
;
1352 if (!check_bp_loc(a
))
1354 bp
= new_breakpoint(a
);
1356 bp
->enabled
|= BP_CIABR
;
1358 force_enable_xmon();
1365 /* clear all breakpoints */
1366 for (i
= 0; i
< NBPTS
; ++i
)
1367 bpts
[i
].enabled
= 0;
1370 printf("All breakpoints cleared\n");
1374 if (a
<= NBPTS
&& a
>= 1) {
1375 /* assume a breakpoint number */
1376 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1378 /* assume a breakpoint address */
1379 bp
= at_breakpoint(a
);
1381 printf("No breakpoint at %lx\n", a
);
1386 printf("Cleared breakpoint %tx (", BP_NUM(bp
));
1387 xmon_print_symbol(bp
->address
, " ", ")\n");
1395 printf(breakpoint_help_string
);
1400 /* print all breakpoints */
1401 printf(" type address\n");
1403 printf(" data "REG
" [", dabr
.address
);
1404 if (dabr
.enabled
& 1)
1406 if (dabr
.enabled
& 2)
1410 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1413 printf("%tx %s ", BP_NUM(bp
),
1414 (bp
->enabled
& BP_CIABR
) ? "inst": "trap");
1415 xmon_print_symbol(bp
->address
, " ", "\n");
1420 if (!check_bp_loc(a
))
1422 bp
= new_breakpoint(a
);
1424 bp
->enabled
|= BP_TRAP
;
1425 force_enable_xmon();
1431 /* Very cheap human name for vector lookup. */
1433 const char *getvecname(unsigned long vec
)
1438 case 0x100: ret
= "(System Reset)"; break;
1439 case 0x200: ret
= "(Machine Check)"; break;
1440 case 0x300: ret
= "(Data Access)"; break;
1442 if (radix_enabled())
1443 ret
= "(Data Access Out of Range)";
1445 ret
= "(Data SLB Access)";
1447 case 0x400: ret
= "(Instruction Access)"; break;
1449 if (radix_enabled())
1450 ret
= "(Instruction Access Out of Range)";
1452 ret
= "(Instruction SLB Access)";
1454 case 0x500: ret
= "(Hardware Interrupt)"; break;
1455 case 0x600: ret
= "(Alignment)"; break;
1456 case 0x700: ret
= "(Program Check)"; break;
1457 case 0x800: ret
= "(FPU Unavailable)"; break;
1458 case 0x900: ret
= "(Decrementer)"; break;
1459 case 0x980: ret
= "(Hypervisor Decrementer)"; break;
1460 case 0xa00: ret
= "(Doorbell)"; break;
1461 case 0xc00: ret
= "(System Call)"; break;
1462 case 0xd00: ret
= "(Single Step)"; break;
1463 case 0xe40: ret
= "(Emulation Assist)"; break;
1464 case 0xe60: ret
= "(HMI)"; break;
1465 case 0xe80: ret
= "(Hypervisor Doorbell)"; break;
1466 case 0xf00: ret
= "(Performance Monitor)"; break;
1467 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1468 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1469 case 0x1500: ret
= "(Denormalisation)"; break;
1470 case 0x1700: ret
= "(Altivec Assist)"; break;
1476 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1477 unsigned long *endp
)
1479 unsigned long size
, offset
;
1482 *startp
= *endp
= 0;
1485 if (setjmp(bus_error_jmp
) == 0) {
1486 catch_memory_errors
= 1;
1488 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1490 *startp
= pc
- offset
;
1491 *endp
= pc
- offset
+ size
;
1495 catch_memory_errors
= 0;
1498 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1499 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1501 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1504 int max_to_print
= 64;
1506 unsigned long newsp
;
1507 unsigned long marker
;
1508 struct pt_regs regs
;
1510 while (max_to_print
--) {
1511 if (!is_kernel_addr(sp
)) {
1513 printf("SP (%lx) is in userspace\n", sp
);
1517 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1518 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1519 printf("Couldn't read stack frame at %lx\n", sp
);
1524 * For the first stack frame, try to work out if
1525 * LR and/or the saved LR value in the bottommost
1526 * stack frame are valid.
1528 if ((pc
| lr
) != 0) {
1529 unsigned long fnstart
, fnend
;
1530 unsigned long nextip
;
1533 get_function_bounds(pc
, &fnstart
, &fnend
);
1536 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1537 sizeof(unsigned long));
1539 if (!is_kernel_addr(lr
)
1540 || (fnstart
<= lr
&& lr
< fnend
))
1542 } else if (lr
== nextip
) {
1544 } else if (is_kernel_addr(lr
)
1545 && !(fnstart
<= lr
&& lr
< fnend
)) {
1546 printf("[link register ] ");
1547 xmon_print_symbol(lr
, " ", "\n");
1550 printf("["REG
"] ", sp
);
1551 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1556 printf("["REG
"] ", sp
);
1557 xmon_print_symbol(ip
, " ", "\n");
1560 /* Look for "regshere" marker to see if this is
1561 an exception frame. */
1562 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1563 && marker
== STACK_FRAME_REGS_MARKER
) {
1564 if (mread(sp
+ STACK_FRAME_OVERHEAD
, ®s
, sizeof(regs
))
1566 printf("Couldn't read registers at %lx\n",
1567 sp
+ STACK_FRAME_OVERHEAD
);
1570 printf("--- Exception: %lx %s at ", regs
.trap
,
1571 getvecname(TRAP(®s
)));
1574 xmon_print_symbol(pc
, " ", "\n");
1584 static void backtrace(struct pt_regs
*excp
)
1589 xmon_show_stack(sp
, 0, 0);
1591 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1595 static void print_bug_trap(struct pt_regs
*regs
)
1598 const struct bug_entry
*bug
;
1601 if (regs
->msr
& MSR_PR
)
1602 return; /* not in kernel */
1603 addr
= regs
->nip
; /* address of trap instruction */
1604 if (!is_kernel_addr(addr
))
1606 bug
= find_bug(regs
->nip
);
1609 if (is_warning_bug(bug
))
1612 #ifdef CONFIG_DEBUG_BUGVERBOSE
1613 printf("kernel BUG at %s:%u!\n",
1614 bug
->file
, bug
->line
);
1616 printf("kernel BUG at %px!\n", (void *)bug
->bug_addr
);
1618 #endif /* CONFIG_BUG */
1621 static void excprint(struct pt_regs
*fp
)
1626 printf("cpu 0x%x: ", smp_processor_id());
1627 #endif /* CONFIG_SMP */
1630 printf("Vector: %lx %s at [%px]\n", fp
->trap
, getvecname(trap
), fp
);
1632 xmon_print_symbol(fp
->nip
, ": ", "\n");
1635 xmon_print_symbol(fp
->link
, ": ", "\n");
1637 printf(" sp: %lx\n", fp
->gpr
[1]);
1638 printf(" msr: %lx\n", fp
->msr
);
1640 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600 || trap
== 0x200) {
1641 printf(" dar: %lx\n", fp
->dar
);
1643 printf(" dsisr: %lx\n", fp
->dsisr
);
1646 printf(" current = 0x%px\n", current
);
1648 printf(" paca = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1649 local_paca
, local_paca
->irq_soft_mask
, local_paca
->irq_happened
);
1652 printf(" pid = %d, comm = %s\n",
1653 current
->pid
, current
->comm
);
1659 printf(linux_banner
);
1662 static void prregs(struct pt_regs
*fp
)
1666 struct pt_regs regs
;
1668 if (scanhex(&base
)) {
1669 if (setjmp(bus_error_jmp
) == 0) {
1670 catch_memory_errors
= 1;
1672 regs
= *(struct pt_regs
*)base
;
1676 catch_memory_errors
= 0;
1677 printf("*** Error reading registers from "REG
"\n",
1681 catch_memory_errors
= 0;
1686 if (FULL_REGS(fp
)) {
1687 for (n
= 0; n
< 16; ++n
)
1688 printf("R%.2d = "REG
" R%.2d = "REG
"\n",
1689 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1691 for (n
= 0; n
< 7; ++n
)
1692 printf("R%.2d = "REG
" R%.2d = "REG
"\n",
1693 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1696 for (n
= 0; n
< 32; ++n
) {
1697 printf("R%.2d = %.8lx%s", n
, fp
->gpr
[n
],
1698 (n
& 3) == 3? "\n": " ");
1699 if (n
== 12 && !FULL_REGS(fp
)) {
1706 xmon_print_symbol(fp
->nip
, " ", "\n");
1707 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1709 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1712 xmon_print_symbol(fp
->link
, " ", "\n");
1713 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1714 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1715 fp
->ctr
, fp
->xer
, fp
->trap
);
1717 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1718 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1721 static void cacheflush(void)
1724 unsigned long nflush
;
1729 scanhex((void *)&adrs
);
1734 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1735 if (setjmp(bus_error_jmp
) == 0) {
1736 catch_memory_errors
= 1;
1740 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1741 cflush((void *) adrs
);
1743 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1744 cinval((void *) adrs
);
1747 /* wait a little while to see if we get a machine check */
1750 catch_memory_errors
= 0;
1753 extern unsigned long xmon_mfspr(int spr
, unsigned long default_value
);
1754 extern void xmon_mtspr(int spr
, unsigned long value
);
1757 read_spr(int n
, unsigned long *vp
)
1759 unsigned long ret
= -1UL;
1762 if (setjmp(bus_error_jmp
) == 0) {
1763 catch_spr_faults
= 1;
1766 ret
= xmon_mfspr(n
, *vp
);
1772 catch_spr_faults
= 0;
1778 write_spr(int n
, unsigned long val
)
1780 if (setjmp(bus_error_jmp
) == 0) {
1781 catch_spr_faults
= 1;
1788 printf("SPR 0x%03x (%4d) Faulted during write\n", n
, n
);
1790 catch_spr_faults
= 0;
1793 static void dump_206_sprs(void)
1796 if (!cpu_has_feature(CPU_FTR_ARCH_206
))
1799 /* Actually some of these pre-date 2.06, but whatevs */
1801 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
1802 mfspr(SPRN_SRR0
), mfspr(SPRN_SRR1
), mfspr(SPRN_DSISR
));
1803 printf("dscr = %.16lx ppr = %.16lx pir = %.8lx\n",
1804 mfspr(SPRN_DSCR
), mfspr(SPRN_PPR
), mfspr(SPRN_PIR
));
1805 printf("amr = %.16lx uamor = %.16lx\n",
1806 mfspr(SPRN_AMR
), mfspr(SPRN_UAMOR
));
1808 if (!(mfmsr() & MSR_HV
))
1811 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8lx\n",
1812 mfspr(SPRN_SDR1
), mfspr(SPRN_HDAR
), mfspr(SPRN_HDSISR
));
1813 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
1814 mfspr(SPRN_HSRR0
), mfspr(SPRN_HSRR1
), mfspr(SPRN_HDEC
));
1815 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8lx\n",
1816 mfspr(SPRN_LPCR
), mfspr(SPRN_PCR
), mfspr(SPRN_LPID
));
1817 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
1818 mfspr(SPRN_HSPRG0
), mfspr(SPRN_HSPRG1
), mfspr(SPRN_AMOR
));
1819 printf("dabr = %.16lx dabrx = %.16lx\n",
1820 mfspr(SPRN_DABR
), mfspr(SPRN_DABRX
));
1824 static void dump_207_sprs(void)
1829 if (!cpu_has_feature(CPU_FTR_ARCH_207S
))
1832 printf("dpdes = %.16lx tir = %.16lx cir = %.8lx\n",
1833 mfspr(SPRN_DPDES
), mfspr(SPRN_TIR
), mfspr(SPRN_CIR
));
1835 printf("fscr = %.16lx tar = %.16lx pspb = %.8lx\n",
1836 mfspr(SPRN_FSCR
), mfspr(SPRN_TAR
), mfspr(SPRN_PSPB
));
1840 /* Only if TM has been enabled in the kernel */
1841 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
1842 mfspr(SPRN_TFHAR
), mfspr(SPRN_TFIAR
),
1843 mfspr(SPRN_TEXASR
));
1846 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
1847 mfspr(SPRN_MMCR0
), mfspr(SPRN_MMCR1
), mfspr(SPRN_MMCR2
));
1848 printf("pmc1 = %.8lx pmc2 = %.8lx pmc3 = %.8lx pmc4 = %.8lx\n",
1849 mfspr(SPRN_PMC1
), mfspr(SPRN_PMC2
),
1850 mfspr(SPRN_PMC3
), mfspr(SPRN_PMC4
));
1851 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8lx\n",
1852 mfspr(SPRN_MMCRA
), mfspr(SPRN_SIAR
), mfspr(SPRN_PMC5
));
1853 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8lx\n",
1854 mfspr(SPRN_SDAR
), mfspr(SPRN_SIER
), mfspr(SPRN_PMC6
));
1855 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
1856 mfspr(SPRN_EBBHR
), mfspr(SPRN_EBBRR
), mfspr(SPRN_BESCR
));
1857 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR
));
1859 if (!(msr
& MSR_HV
))
1862 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
1863 mfspr(SPRN_HFSCR
), mfspr(SPRN_DHDES
), mfspr(SPRN_RPR
));
1864 printf("dawr = %.16lx dawrx = %.16lx ciabr = %.16lx\n",
1865 mfspr(SPRN_DAWR
), mfspr(SPRN_DAWRX
), mfspr(SPRN_CIABR
));
1869 static void dump_300_sprs(void)
1872 bool hv
= mfmsr() & MSR_HV
;
1874 if (!cpu_has_feature(CPU_FTR_ARCH_300
))
1877 printf("pidr = %.16lx tidr = %.16lx\n",
1878 mfspr(SPRN_PID
), mfspr(SPRN_TIDR
));
1879 printf("asdr = %.16lx psscr = %.16lx\n",
1880 mfspr(SPRN_ASDR
), hv
? mfspr(SPRN_PSSCR
)
1881 : mfspr(SPRN_PSSCR_PR
));
1886 printf("ptcr = %.16lx\n",
1891 static void dump_one_spr(int spr
, bool show_unimplemented
)
1896 if (!read_spr(spr
, &val
)) {
1897 printf("SPR 0x%03x (%4d) Faulted during read\n", spr
, spr
);
1901 if (val
== 0xdeadbeef) {
1902 /* Looks like read was a nop, confirm */
1904 if (!read_spr(spr
, &val
)) {
1905 printf("SPR 0x%03x (%4d) Faulted during read\n", spr
, spr
);
1909 if (val
== 0x0badcafe) {
1910 if (show_unimplemented
)
1911 printf("SPR 0x%03x (%4d) Unimplemented\n", spr
, spr
);
1916 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr
, spr
, val
);
1919 static void super_regs(void)
1921 static unsigned long regno
;
1929 unsigned long sp
, toc
;
1930 asm("mr %0,1" : "=r" (sp
) :);
1931 asm("mr %0,2" : "=r" (toc
) :);
1933 printf("msr = "REG
" sprg0 = "REG
"\n",
1934 mfmsr(), mfspr(SPRN_SPRG0
));
1935 printf("pvr = "REG
" sprg1 = "REG
"\n",
1936 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1937 printf("dec = "REG
" sprg2 = "REG
"\n",
1938 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1939 printf("sp = "REG
" sprg3 = "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1940 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1952 read_spr(regno
, &val
);
1954 write_spr(regno
, val
);
1955 dump_one_spr(regno
, true);
1960 dump_one_spr(regno
, true);
1964 for (spr
= 1; spr
< 1024; ++spr
)
1965 dump_one_spr(spr
, false);
1973 * Stuff for reading and writing memory safely
1976 mread(unsigned long adrs
, void *buf
, int size
)
1982 if (setjmp(bus_error_jmp
) == 0) {
1983 catch_memory_errors
= 1;
1989 *(u16
*)q
= *(u16
*)p
;
1992 *(u32
*)q
= *(u32
*)p
;
1995 *(u64
*)q
= *(u64
*)p
;
1998 for( ; n
< size
; ++n
) {
2004 /* wait a little while to see if we get a machine check */
2008 catch_memory_errors
= 0;
2013 mwrite(unsigned long adrs
, void *buf
, int size
)
2019 if (setjmp(bus_error_jmp
) == 0) {
2020 catch_memory_errors
= 1;
2026 *(u16
*)p
= *(u16
*)q
;
2029 *(u32
*)p
= *(u32
*)q
;
2032 *(u64
*)p
= *(u64
*)q
;
2035 for ( ; n
< size
; ++n
) {
2041 /* wait a little while to see if we get a machine check */
2045 printf("*** Error writing address "REG
"\n", adrs
+ n
);
2047 catch_memory_errors
= 0;
2051 static int fault_type
;
2052 static int fault_except
;
2053 static char *fault_chars
[] = { "--", "**", "##" };
2055 static int handle_fault(struct pt_regs
*regs
)
2057 fault_except
= TRAP(regs
);
2058 switch (TRAP(regs
)) {
2070 longjmp(bus_error_jmp
, 1);
2075 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2078 byterev(unsigned char *val
, int size
)
2084 SWAP(val
[0], val
[1], t
);
2087 SWAP(val
[0], val
[3], t
);
2088 SWAP(val
[1], val
[2], t
);
2090 case 8: /* is there really any use for this? */
2091 SWAP(val
[0], val
[7], t
);
2092 SWAP(val
[1], val
[6], t
);
2093 SWAP(val
[2], val
[5], t
);
2094 SWAP(val
[3], val
[4], t
);
2102 static char *memex_help_string
=
2103 "Memory examine command usage:\n"
2104 "m [addr] [flags] examine/change memory\n"
2105 " addr is optional. will start where left off.\n"
2106 " flags may include chars from this set:\n"
2107 " b modify by bytes (default)\n"
2108 " w modify by words (2 byte)\n"
2109 " l modify by longs (4 byte)\n"
2110 " d modify by doubleword (8 byte)\n"
2111 " r toggle reverse byte order mode\n"
2112 " n do not read memory (for i/o spaces)\n"
2113 " . ok to read (default)\n"
2114 "NOTE: flags are saved as defaults\n"
2117 static char *memex_subcmd_help_string
=
2118 "Memory examine subcommands:\n"
2119 " hexval write this val to current location\n"
2120 " 'string' write chars from string to this location\n"
2121 " ' increment address\n"
2122 " ^ decrement address\n"
2123 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2124 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2125 " ` clear no-read flag\n"
2126 " ; stay at this addr\n"
2127 " v change to byte mode\n"
2128 " w change to word (2 byte) mode\n"
2129 " l change to long (4 byte) mode\n"
2130 " u change to doubleword (8 byte) mode\n"
2131 " m addr change current addr\n"
2132 " n toggle no-read flag\n"
2133 " r toggle byte reverse flag\n"
2134 " < count back up count bytes\n"
2135 " > count skip forward count bytes\n"
2136 " x exit this mode\n"
2142 int cmd
, inc
, i
, nslash
;
2144 unsigned char val
[16];
2146 scanhex((void *)&adrs
);
2149 printf(memex_help_string
);
2155 while ((cmd
= skipbl()) != '\n') {
2157 case 'b': size
= 1; break;
2158 case 'w': size
= 2; break;
2159 case 'l': size
= 4; break;
2160 case 'd': size
= 8; break;
2161 case 'r': brev
= !brev
; break;
2162 case 'n': mnoread
= 1; break;
2163 case '.': mnoread
= 0; break;
2172 n
= mread(adrs
, val
, size
);
2173 printf(REG
"%c", adrs
, brev
? 'r': ' ');
2178 for (i
= 0; i
< n
; ++i
)
2179 printf("%.2x", val
[i
]);
2180 for (; i
< size
; ++i
)
2181 printf("%s", fault_chars
[fault_type
]);
2188 for (i
= 0; i
< size
; ++i
)
2189 val
[i
] = n
>> (i
* 8);
2192 mwrite(adrs
, val
, size
);
2205 else if( n
== '\'' )
2207 for (i
= 0; i
< size
; ++i
)
2208 val
[i
] = n
>> (i
* 8);
2211 mwrite(adrs
, val
, size
);
2247 adrs
-= 1 << nslash
;
2251 adrs
+= 1 << nslash
;
2255 adrs
+= 1 << -nslash
;
2259 adrs
-= 1 << -nslash
;
2262 scanhex((void *)&adrs
);
2281 printf(memex_subcmd_help_string
);
2296 case 'n': c
= '\n'; break;
2297 case 'r': c
= '\r'; break;
2298 case 'b': c
= '\b'; break;
2299 case 't': c
= '\t'; break;
2304 static void xmon_rawdump (unsigned long adrs
, long ndump
)
2307 unsigned char temp
[16];
2309 for (n
= ndump
; n
> 0;) {
2311 nr
= mread(adrs
, temp
, r
);
2313 for (m
= 0; m
< r
; ++m
) {
2315 printf("%.2x", temp
[m
]);
2317 printf("%s", fault_chars
[fault_type
]);
2326 static void dump_tracing(void)
2332 ftrace_dump(DUMP_ORIG
);
2334 ftrace_dump(DUMP_ALL
);
2338 static void dump_one_paca(int cpu
)
2340 struct paca_struct
*p
;
2341 #ifdef CONFIG_PPC_BOOK3S_64
2345 if (setjmp(bus_error_jmp
) != 0) {
2346 printf("*** Error dumping paca for cpu 0x%x!\n", cpu
);
2350 catch_memory_errors
= 1;
2355 printf("paca for cpu 0x%x @ %px:\n", cpu
, p
);
2357 printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu
) ? "yes" : "no");
2358 printf(" %-*s = %s\n", 25, "present", cpu_present(cpu
) ? "yes" : "no");
2359 printf(" %-*s = %s\n", 25, "online", cpu_online(cpu
) ? "yes" : "no");
2361 #define DUMP(paca, name, format) \
2362 printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2363 offsetof(struct paca_struct, name));
2365 DUMP(p
, lock_token
, "%#-*x");
2366 DUMP(p
, paca_index
, "%#-*x");
2367 DUMP(p
, kernel_toc
, "%#-*llx");
2368 DUMP(p
, kernelbase
, "%#-*llx");
2369 DUMP(p
, kernel_msr
, "%#-*llx");
2370 DUMP(p
, emergency_sp
, "%-*px");
2371 #ifdef CONFIG_PPC_BOOK3S_64
2372 DUMP(p
, nmi_emergency_sp
, "%-*px");
2373 DUMP(p
, mc_emergency_sp
, "%-*px");
2374 DUMP(p
, in_nmi
, "%#-*x");
2375 DUMP(p
, in_mce
, "%#-*x");
2376 DUMP(p
, hmi_event_available
, "%#-*x");
2378 DUMP(p
, data_offset
, "%#-*llx");
2379 DUMP(p
, hw_cpu_id
, "%#-*x");
2380 DUMP(p
, cpu_start
, "%#-*x");
2381 DUMP(p
, kexec_state
, "%#-*x");
2382 #ifdef CONFIG_PPC_BOOK3S_64
2383 if (!early_radix_enabled()) {
2384 for (i
= 0; i
< SLB_NUM_BOLTED
; i
++) {
2387 if (!p
->slb_shadow_ptr
)
2390 esid
= be64_to_cpu(p
->slb_shadow_ptr
->save_area
[i
].esid
);
2391 vsid
= be64_to_cpu(p
->slb_shadow_ptr
->save_area
[i
].vsid
);
2394 printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2395 22, "slb_shadow", i
, esid
, vsid
);
2398 DUMP(p
, vmalloc_sllp
, "%#-*x");
2399 DUMP(p
, stab_rr
, "%#-*x");
2400 DUMP(p
, slb_used_bitmap
, "%#-*x");
2401 DUMP(p
, slb_kern_bitmap
, "%#-*x");
2403 if (!early_cpu_has_feature(CPU_FTR_ARCH_300
)) {
2404 DUMP(p
, slb_cache_ptr
, "%#-*x");
2405 for (i
= 0; i
< SLB_CACHE_ENTRIES
; i
++)
2406 printf(" %-*s[%d] = 0x%016x\n",
2407 22, "slb_cache", i
, p
->slb_cache
[i
]);
2411 DUMP(p
, rfi_flush_fallback_area
, "%-*px");
2413 DUMP(p
, dscr_default
, "%#-*llx");
2414 #ifdef CONFIG_PPC_BOOK3E
2415 DUMP(p
, pgd
, "%-*px");
2416 DUMP(p
, kernel_pgd
, "%-*px");
2417 DUMP(p
, tcd_ptr
, "%-*px");
2418 DUMP(p
, mc_kstack
, "%-*px");
2419 DUMP(p
, crit_kstack
, "%-*px");
2420 DUMP(p
, dbg_kstack
, "%-*px");
2422 DUMP(p
, __current
, "%-*px");
2423 DUMP(p
, kstack
, "%#-*llx");
2424 printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p
->kstack
& ~(THREAD_SIZE
- 1));
2425 #ifdef CONFIG_STACKPROTECTOR
2426 DUMP(p
, canary
, "%#-*lx");
2428 DUMP(p
, saved_r1
, "%#-*llx");
2429 DUMP(p
, trap_save
, "%#-*x");
2430 DUMP(p
, irq_soft_mask
, "%#-*x");
2431 DUMP(p
, irq_happened
, "%#-*x");
2432 DUMP(p
, io_sync
, "%#-*x");
2433 DUMP(p
, irq_work_pending
, "%#-*x");
2434 DUMP(p
, nap_state_lost
, "%#-*x");
2435 DUMP(p
, sprg_vdso
, "%#-*llx");
2437 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2438 DUMP(p
, tm_scratch
, "%#-*llx");
2441 #ifdef CONFIG_PPC_POWERNV
2442 DUMP(p
, core_idle_state_ptr
, "%-*px");
2443 DUMP(p
, thread_idle_state
, "%#-*x");
2444 DUMP(p
, thread_mask
, "%#-*x");
2445 DUMP(p
, subcore_sibling_mask
, "%#-*x");
2446 DUMP(p
, requested_psscr
, "%#-*llx");
2447 DUMP(p
, stop_sprs
.pid
, "%#-*llx");
2448 DUMP(p
, stop_sprs
.ldbar
, "%#-*llx");
2449 DUMP(p
, stop_sprs
.fscr
, "%#-*llx");
2450 DUMP(p
, stop_sprs
.hfscr
, "%#-*llx");
2451 DUMP(p
, stop_sprs
.mmcr1
, "%#-*llx");
2452 DUMP(p
, stop_sprs
.mmcr2
, "%#-*llx");
2453 DUMP(p
, stop_sprs
.mmcra
, "%#-*llx");
2454 DUMP(p
, dont_stop
.counter
, "%#-*x");
2457 DUMP(p
, accounting
.utime
, "%#-*lx");
2458 DUMP(p
, accounting
.stime
, "%#-*lx");
2459 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2460 DUMP(p
, accounting
.utime_scaled
, "%#-*lx");
2462 DUMP(p
, accounting
.starttime
, "%#-*lx");
2463 DUMP(p
, accounting
.starttime_user
, "%#-*lx");
2464 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2465 DUMP(p
, accounting
.startspurr
, "%#-*lx");
2466 DUMP(p
, accounting
.utime_sspurr
, "%#-*lx");
2468 DUMP(p
, accounting
.steal_time
, "%#-*lx");
2471 catch_memory_errors
= 0;
2475 static void dump_all_pacas(void)
2479 if (num_possible_cpus() == 0) {
2480 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2484 for_each_possible_cpu(cpu
)
2488 static void dump_pacas(void)
2499 termch
= c
; /* Put c back, it wasn't 'a' */
2504 dump_one_paca(xmon_owner
);
2508 #ifdef CONFIG_PPC_POWERNV
2509 static void dump_one_xive(int cpu
)
2511 unsigned int hwid
= get_hard_smp_processor_id(cpu
);
2513 opal_xive_dump(XIVE_DUMP_TM_HYP
, hwid
);
2514 opal_xive_dump(XIVE_DUMP_TM_POOL
, hwid
);
2515 opal_xive_dump(XIVE_DUMP_TM_OS
, hwid
);
2516 opal_xive_dump(XIVE_DUMP_TM_USER
, hwid
);
2517 opal_xive_dump(XIVE_DUMP_VP
, hwid
);
2518 opal_xive_dump(XIVE_DUMP_EMU_STATE
, hwid
);
2520 if (setjmp(bus_error_jmp
) != 0) {
2521 catch_memory_errors
= 0;
2522 printf("*** Error dumping xive on cpu %d\n", cpu
);
2526 catch_memory_errors
= 1;
2528 xmon_xive_do_dump(cpu
);
2531 catch_memory_errors
= 0;
2534 static void dump_all_xives(void)
2538 if (num_possible_cpus() == 0) {
2539 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2543 for_each_possible_cpu(cpu
)
2547 static void dump_one_xive_irq(u32 num
)
2554 rc
= opal_xive_get_irq_config(num
, &vp
, &prio
, &lirq
);
2555 xmon_printf("IRQ 0x%x config: vp=0x%llx prio=%d lirq=0x%x (rc=%lld)\n",
2556 num
, be64_to_cpu(vp
), prio
, be32_to_cpu(lirq
), rc
);
2559 static void dump_xives(void)
2564 if (!xive_enabled()) {
2565 printf("Xive disabled on this system\n");
2573 } else if (c
== 'i') {
2575 dump_one_xive_irq(num
);
2579 termch
= c
; /* Put c back, it wasn't 'a' */
2584 dump_one_xive(xmon_owner
);
2586 #endif /* CONFIG_PPC_POWERNV */
2588 static void dump_by_size(unsigned long addr
, long count
, int size
)
2590 unsigned char temp
[16];
2594 count
= ALIGN(count
, 16);
2596 for (i
= 0; i
< count
; i
+= 16, addr
+= 16) {
2599 if (mread(addr
, temp
, 16) != 16) {
2600 printf("\nFaulted reading %d bytes from 0x"REG
"\n", 16, addr
);
2604 for (j
= 0; j
< 16; j
+= size
) {
2607 case 1: val
= temp
[j
]; break;
2608 case 2: val
= *(u16
*)&temp
[j
]; break;
2609 case 4: val
= *(u32
*)&temp
[j
]; break;
2610 case 8: val
= *(u64
*)&temp
[j
]; break;
2614 printf("%0*llx", size
* 2, val
);
2623 static char last
[] = { "d?\n" };
2630 xmon_start_pagination();
2632 xmon_end_pagination();
2636 #ifdef CONFIG_PPC_POWERNV
2638 xmon_start_pagination();
2640 xmon_end_pagination();
2653 scanhex((void *)&adrs
);
2660 else if (nidump
> MAX_DUMP
)
2662 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2664 } else if (c
== 'l') {
2666 } else if (c
== 'o') {
2668 } else if (c
== 'v') {
2669 /* dump virtual to physical translation */
2671 } else if (c
== 'r') {
2675 xmon_rawdump(adrs
, ndump
);
2682 else if (ndump
> MAX_DUMP
)
2690 ndump
= ALIGN(ndump
, 16);
2691 dump_by_size(adrs
, ndump
, c
- '0');
2696 prdump(adrs
, ndump
);
2705 prdump(unsigned long adrs
, long ndump
)
2707 long n
, m
, c
, r
, nr
;
2708 unsigned char temp
[16];
2710 for (n
= ndump
; n
> 0;) {
2714 nr
= mread(adrs
, temp
, r
);
2716 for (m
= 0; m
< r
; ++m
) {
2717 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2720 printf("%.2x", temp
[m
]);
2722 printf("%s", fault_chars
[fault_type
]);
2724 for (; m
< 16; ++m
) {
2725 if ((m
& (sizeof(long) - 1)) == 0)
2730 for (m
= 0; m
< r
; ++m
) {
2733 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2746 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2749 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2750 instruction_dump_func dump_func
)
2753 unsigned long first_adr
;
2754 unsigned int inst
, last_inst
= 0;
2755 unsigned char val
[4];
2758 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2759 nr
= mread(adr
, val
, 4);
2762 const char *x
= fault_chars
[fault_type
];
2763 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2767 inst
= GETWORD(val
);
2768 if (adr
> first_adr
&& inst
== last_inst
) {
2778 printf(REG
" %.8x", adr
, inst
);
2780 dump_func(inst
, adr
);
2783 return adr
- first_adr
;
2787 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2789 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2793 print_address(unsigned long addr
)
2795 xmon_print_symbol(addr
, "\t# ", "");
2801 struct kmsg_dumper dumper
= { .active
= 1 };
2802 unsigned char buf
[128];
2805 if (setjmp(bus_error_jmp
) != 0) {
2806 printf("Error dumping printk buffer!\n");
2810 catch_memory_errors
= 1;
2813 kmsg_dump_rewind_nolock(&dumper
);
2814 xmon_start_pagination();
2815 while (kmsg_dump_get_line_nolock(&dumper
, false, buf
, sizeof(buf
), &len
)) {
2819 xmon_end_pagination();
2822 /* wait a little while to see if we get a machine check */
2824 catch_memory_errors
= 0;
2827 #ifdef CONFIG_PPC_POWERNV
2828 static void dump_opal_msglog(void)
2830 unsigned char buf
[128];
2834 if (!firmware_has_feature(FW_FEATURE_OPAL
)) {
2835 printf("Machine is not running OPAL firmware.\n");
2839 if (setjmp(bus_error_jmp
) != 0) {
2840 printf("Error dumping OPAL msglog!\n");
2844 catch_memory_errors
= 1;
2847 xmon_start_pagination();
2848 while ((res
= opal_msglog_copy(buf
, pos
, sizeof(buf
) - 1))) {
2850 printf("Error dumping OPAL msglog! Error: %zd\n", res
);
2857 xmon_end_pagination();
2860 /* wait a little while to see if we get a machine check */
2862 catch_memory_errors
= 0;
2867 * Memory operations - move, set, print differences
2869 static unsigned long mdest
; /* destination address */
2870 static unsigned long msrc
; /* source address */
2871 static unsigned long mval
; /* byte value to set memory to */
2872 static unsigned long mcount
; /* # bytes to affect */
2873 static unsigned long mdiffs
; /* max # differences to print */
2878 scanhex((void *)&mdest
);
2879 if( termch
!= '\n' )
2881 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2882 if( termch
!= '\n' )
2884 scanhex((void *)&mcount
);
2887 memmove((void *)mdest
, (void *)msrc
, mcount
);
2890 memset((void *)mdest
, mval
, mcount
);
2893 if( termch
!= '\n' )
2895 scanhex((void *)&mdiffs
);
2896 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2902 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2907 for( n
= nb
; n
> 0; --n
)
2908 if( *p1
++ != *p2
++ )
2909 if( ++prt
<= maxpr
)
2910 printf("%px %.2x # %px %.2x\n", p1
- 1,
2911 p1
[-1], p2
- 1, p2
[-1]);
2913 printf("Total of %d differences\n", prt
);
2916 static unsigned mend
;
2917 static unsigned mask
;
2923 unsigned char val
[4];
2926 scanhex((void *)&mdest
);
2927 if (termch
!= '\n') {
2929 scanhex((void *)&mend
);
2930 if (termch
!= '\n') {
2932 scanhex((void *)&mval
);
2934 if (termch
!= '\n') termch
= 0;
2935 scanhex((void *)&mask
);
2939 for (a
= mdest
; a
< mend
; a
+= 4) {
2940 if (mread(a
, val
, 4) == 4
2941 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2942 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2949 static unsigned long mskip
= 0x1000;
2950 static unsigned long mlim
= 0xffffffff;
2960 if (termch
!= '\n') termch
= 0;
2962 if (termch
!= '\n') termch
= 0;
2965 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2966 ok
= mread(a
, &v
, 1);
2968 printf("%.8x .. ", a
);
2969 } else if (!ok
&& ook
)
2970 printf("%.8lx\n", a
- mskip
);
2976 printf("%.8lx\n", a
- mskip
);
2979 static void show_task(struct task_struct
*tsk
)
2984 * Cloned from kdb_task_state_char(), which is not entirely
2985 * appropriate for calling from xmon. This could be moved
2986 * to a common, generic, routine used by both.
2988 state
= (tsk
->state
== 0) ? 'R' :
2989 (tsk
->state
< 0) ? 'U' :
2990 (tsk
->state
& TASK_UNINTERRUPTIBLE
) ? 'D' :
2991 (tsk
->state
& TASK_STOPPED
) ? 'T' :
2992 (tsk
->state
& TASK_TRACED
) ? 'C' :
2993 (tsk
->exit_state
& EXIT_ZOMBIE
) ? 'Z' :
2994 (tsk
->exit_state
& EXIT_DEAD
) ? 'E' :
2995 (tsk
->state
& TASK_INTERRUPTIBLE
) ? 'S' : '?';
2997 printf("%px %016lx %6d %6d %c %2d %s\n", tsk
,
2999 tsk
->pid
, rcu_dereference(tsk
->parent
)->pid
,
3000 state
, task_thread_info(tsk
)->cpu
,
3004 #ifdef CONFIG_PPC_BOOK3S_64
3005 static void format_pte(void *ptep
, unsigned long pte
)
3007 pte_t entry
= __pte(pte
);
3009 printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep
, pte
);
3010 printf("Maps physical address = 0x%016lx\n", pte
& PTE_RPN_MASK
);
3012 printf("Flags = %s%s%s%s%s\n",
3013 pte_young(entry
) ? "Accessed " : "",
3014 pte_dirty(entry
) ? "Dirty " : "",
3015 pte_read(entry
) ? "Read " : "",
3016 pte_write(entry
) ? "Write " : "",
3017 pte_exec(entry
) ? "Exec " : "");
3020 static void show_pte(unsigned long addr
)
3022 unsigned long tskv
= 0;
3023 struct task_struct
*tsk
= NULL
;
3024 struct mm_struct
*mm
;
3025 pgd_t
*pgdp
, *pgdir
;
3030 if (!scanhex(&tskv
))
3033 tsk
= (struct task_struct
*)tskv
;
3038 mm
= tsk
->active_mm
;
3040 if (setjmp(bus_error_jmp
) != 0) {
3041 catch_memory_errors
= 0;
3042 printf("*** Error dumping pte for task %px\n", tsk
);
3046 catch_memory_errors
= 1;
3049 if (mm
== &init_mm
) {
3050 pgdp
= pgd_offset_k(addr
);
3051 pgdir
= pgd_offset_k(0);
3053 pgdp
= pgd_offset(mm
, addr
);
3054 pgdir
= pgd_offset(mm
, 0);
3057 if (pgd_none(*pgdp
)) {
3058 printf("no linux page table for address\n");
3062 printf("pgd @ 0x%px\n", pgdir
);
3064 if (pgd_huge(*pgdp
)) {
3065 format_pte(pgdp
, pgd_val(*pgdp
));
3068 printf("pgdp @ 0x%px = 0x%016lx\n", pgdp
, pgd_val(*pgdp
));
3070 pudp
= pud_offset(pgdp
, addr
);
3072 if (pud_none(*pudp
)) {
3073 printf("No valid PUD\n");
3077 if (pud_huge(*pudp
)) {
3078 format_pte(pudp
, pud_val(*pudp
));
3082 printf("pudp @ 0x%px = 0x%016lx\n", pudp
, pud_val(*pudp
));
3084 pmdp
= pmd_offset(pudp
, addr
);
3086 if (pmd_none(*pmdp
)) {
3087 printf("No valid PMD\n");
3091 if (pmd_huge(*pmdp
)) {
3092 format_pte(pmdp
, pmd_val(*pmdp
));
3095 printf("pmdp @ 0x%px = 0x%016lx\n", pmdp
, pmd_val(*pmdp
));
3097 ptep
= pte_offset_map(pmdp
, addr
);
3098 if (pte_none(*ptep
)) {
3099 printf("no valid PTE\n");
3103 format_pte(ptep
, pte_val(*ptep
));
3107 catch_memory_errors
= 0;
3110 static void show_pte(unsigned long addr
)
3112 printf("show_pte not yet implemented\n");
3114 #endif /* CONFIG_PPC_BOOK3S_64 */
3116 static void show_tasks(void)
3119 struct task_struct
*tsk
= NULL
;
3121 printf(" task_struct ->thread.ksp PID PPID S P CMD\n");
3124 tsk
= (struct task_struct
*)tskv
;
3126 if (setjmp(bus_error_jmp
) != 0) {
3127 catch_memory_errors
= 0;
3128 printf("*** Error dumping task %px\n", tsk
);
3132 catch_memory_errors
= 1;
3138 for_each_process(tsk
)
3143 catch_memory_errors
= 0;
3146 static void proccall(void)
3148 unsigned long args
[8];
3151 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
3152 unsigned long, unsigned long, unsigned long,
3153 unsigned long, unsigned long, unsigned long);
3156 if (!scanhex(&adrs
))
3160 for (i
= 0; i
< 8; ++i
)
3162 for (i
= 0; i
< 8; ++i
) {
3163 if (!scanhex(&args
[i
]) || termch
== '\n')
3167 func
= (callfunc_t
) adrs
;
3169 if (setjmp(bus_error_jmp
) == 0) {
3170 catch_memory_errors
= 1;
3172 ret
= func(args
[0], args
[1], args
[2], args
[3],
3173 args
[4], args
[5], args
[6], args
[7]);
3175 printf("return value is 0x%lx\n", ret
);
3177 printf("*** %x exception occurred\n", fault_except
);
3179 catch_memory_errors
= 0;
3182 /* Input scanning routines */
3193 while( c
== ' ' || c
== '\t' )
3199 static const char *regnames
[N_PTREGS
] = {
3200 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3201 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3202 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3203 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3204 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3210 "trap", "dar", "dsisr", "res"
3214 scanhex(unsigned long *vp
)
3221 /* parse register name */
3225 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
3234 i
= match_string(regnames
, N_PTREGS
, regname
);
3236 printf("invalid register name '%%%s'\n", regname
);
3239 if (xmon_regs
== NULL
) {
3240 printf("regs not available\n");
3243 *vp
= ((unsigned long *)xmon_regs
)[i
];
3247 /* skip leading "0x" if any */
3261 } else if (c
== '$') {
3263 for (i
=0; i
<63; i
++) {
3265 if (isspace(c
) || c
== '\0') {
3273 if (setjmp(bus_error_jmp
) == 0) {
3274 catch_memory_errors
= 1;
3276 *vp
= kallsyms_lookup_name(tmpstr
);
3279 catch_memory_errors
= 0;
3281 printf("unknown symbol '%s'\n", tmpstr
);
3314 static int hexdigit(int c
)
3316 if( '0' <= c
&& c
<= '9' )
3318 if( 'A' <= c
&& c
<= 'F' )
3319 return c
- ('A' - 10);
3320 if( 'a' <= c
&& c
<= 'f' )
3321 return c
- ('a' - 10);
3326 getstring(char *s
, int size
)
3337 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
3342 static char line
[256];
3343 static char *lineptr
;
3354 if (lineptr
== NULL
|| *lineptr
== 0) {
3355 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
3365 take_input(char *str
)
3374 int type
= inchar();
3375 unsigned long addr
, cpu
;
3376 void __percpu
*ptr
= NULL
;
3377 static char tmp
[64];
3382 xmon_print_symbol(addr
, ": ", "\n");
3387 if (setjmp(bus_error_jmp
) == 0) {
3388 catch_memory_errors
= 1;
3390 addr
= kallsyms_lookup_name(tmp
);
3392 printf("%s: %lx\n", tmp
, addr
);
3394 printf("Symbol '%s' not found.\n", tmp
);
3397 catch_memory_errors
= 0;
3402 if (setjmp(bus_error_jmp
) == 0) {
3403 catch_memory_errors
= 1;
3405 ptr
= (void __percpu
*)kallsyms_lookup_name(tmp
);
3410 ptr
>= (void __percpu
*)__per_cpu_start
&&
3411 ptr
< (void __percpu
*)__per_cpu_end
)
3413 if (scanhex(&cpu
) && cpu
< num_possible_cpus()) {
3414 addr
= (unsigned long)per_cpu_ptr(ptr
, cpu
);
3416 cpu
= raw_smp_processor_id();
3417 addr
= (unsigned long)this_cpu_ptr(ptr
);
3420 printf("%s for cpu 0x%lx: %lx\n", tmp
, cpu
, addr
);
3422 printf("Percpu symbol '%s' not found.\n", tmp
);
3425 catch_memory_errors
= 0;
3432 /* Print an address in numeric and symbolic form (if possible) */
3433 static void xmon_print_symbol(unsigned long address
, const char *mid
,
3437 const char *name
= NULL
;
3438 unsigned long offset
, size
;
3440 printf(REG
, address
);
3441 if (setjmp(bus_error_jmp
) == 0) {
3442 catch_memory_errors
= 1;
3444 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
3447 /* wait a little while to see if we get a machine check */
3451 catch_memory_errors
= 0;
3454 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
3456 printf(" [%s]", modname
);
3458 printf("%s", after
);
3461 #ifdef CONFIG_PPC_BOOK3S_64
3462 void dump_segments(void)
3465 unsigned long esid
,vsid
;
3468 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3470 for (i
= 0; i
< mmu_slb_size
; i
++) {
3471 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
3472 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
3477 printf("%02d %016lx %016lx", i
, esid
, vsid
);
3479 if (!(esid
& SLB_ESID_V
)) {
3484 llp
= vsid
& SLB_VSID_LLP
;
3485 if (vsid
& SLB_VSID_B_1T
) {
3486 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3488 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
3491 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3493 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
3500 #ifdef CONFIG_PPC_BOOK3S_32
3501 void dump_segments(void)
3506 for (i
= 0; i
< 16; ++i
)
3507 printf(" %x", mfsrin(i
<< 28));
3513 static void dump_tlb_44x(void)
3517 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
3518 unsigned long w0
,w1
,w2
;
3519 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
3520 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
3521 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
3522 printf("[%02x] %08lx %08lx %08lx ", i
, w0
, w1
, w2
);
3523 if (w0
& PPC44x_TLB_VALID
) {
3524 printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3525 w0
& PPC44x_TLB_EPN_MASK
,
3526 w1
& PPC44x_TLB_ERPN_MASK
,
3527 w1
& PPC44x_TLB_RPN_MASK
,
3528 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
3529 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
3530 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
3531 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
3532 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
3537 #endif /* CONFIG_44x */
3539 #ifdef CONFIG_PPC_BOOK3E
3540 static void dump_tlb_book3e(void)
3542 u32 mmucfg
, pidmask
, lpidmask
;
3544 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
3546 static const char *pgsz_names
[] = {
3581 /* Gather some infos about the MMU */
3582 mmucfg
= mfspr(SPRN_MMUCFG
);
3583 mmu_version
= (mmucfg
& 3) + 1;
3584 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
3585 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
3586 lpidsz
= (mmucfg
>> 24) & 0xf;
3587 rasz
= (mmucfg
>> 16) & 0x7f;
3588 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
3590 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3591 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
3592 pidmask
= (1ul << pidsz
) - 1;
3593 lpidmask
= (1ul << lpidsz
) - 1;
3594 ramask
= (1ull << rasz
) - 1;
3596 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
3598 int nent
, assoc
, new_cc
= 1;
3599 printf("TLB %d:\n------\n", tlb
);
3602 tlbcfg
= mfspr(SPRN_TLB0CFG
);
3605 tlbcfg
= mfspr(SPRN_TLB1CFG
);
3608 tlbcfg
= mfspr(SPRN_TLB2CFG
);
3611 tlbcfg
= mfspr(SPRN_TLB3CFG
);
3614 printf("Unsupported TLB number !\n");
3617 nent
= tlbcfg
& 0xfff;
3618 assoc
= (tlbcfg
>> 24) & 0xff;
3619 for (i
= 0; i
< nent
; i
++) {
3620 u32 mas0
= MAS0_TLBSEL(tlb
);
3621 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
3624 int esel
= i
, cc
= i
;
3632 mas0
|= MAS0_ESEL(esel
);
3633 mtspr(SPRN_MAS0
, mas0
);
3634 mtspr(SPRN_MAS1
, mas1
);
3635 mtspr(SPRN_MAS2
, mas2
);
3636 asm volatile("tlbre 0,0,0" : : : "memory");
3637 mas1
= mfspr(SPRN_MAS1
);
3638 mas2
= mfspr(SPRN_MAS2
);
3639 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
3640 if (assoc
&& (i
% assoc
) == 0)
3642 if (!(mas1
& MAS1_VALID
))
3645 printf("%04x- ", i
);
3647 printf("%04x-%c", cc
, 'A' + esel
);
3649 printf(" |%c", 'A' + esel
);
3651 printf(" %016llx %04x %s %c%c AS%c",
3653 (mas1
>> 16) & 0x3fff,
3654 pgsz_names
[(mas1
>> 7) & 0x1f],
3655 mas1
& MAS1_IND
? 'I' : ' ',
3656 mas1
& MAS1_IPROT
? 'P' : ' ',
3657 mas1
& MAS1_TS
? '1' : '0');
3658 printf(" %c%c%c%c%c%c%c",
3659 mas2
& MAS2_X0
? 'a' : ' ',
3660 mas2
& MAS2_X1
? 'v' : ' ',
3661 mas2
& MAS2_W
? 'w' : ' ',
3662 mas2
& MAS2_I
? 'i' : ' ',
3663 mas2
& MAS2_M
? 'm' : ' ',
3664 mas2
& MAS2_G
? 'g' : ' ',
3665 mas2
& MAS2_E
? 'e' : ' ');
3666 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
3667 if (mas1
& MAS1_IND
)
3669 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
3671 printf(" U%c%c%c S%c%c%c\n",
3672 mas7_mas3
& MAS3_UX
? 'x' : ' ',
3673 mas7_mas3
& MAS3_UW
? 'w' : ' ',
3674 mas7_mas3
& MAS3_UR
? 'r' : ' ',
3675 mas7_mas3
& MAS3_SX
? 'x' : ' ',
3676 mas7_mas3
& MAS3_SW
? 'w' : ' ',
3677 mas7_mas3
& MAS3_SR
? 'r' : ' ');
3681 #endif /* CONFIG_PPC_BOOK3E */
3683 static void xmon_init(int enable
)
3687 __debugger_ipi
= xmon_ipi
;
3688 __debugger_bpt
= xmon_bpt
;
3689 __debugger_sstep
= xmon_sstep
;
3690 __debugger_iabr_match
= xmon_iabr_match
;
3691 __debugger_break_match
= xmon_break_match
;
3692 __debugger_fault_handler
= xmon_fault_handler
;
3694 #ifdef CONFIG_PPC_PSERIES
3696 * Get the token here to avoid trying to get a lock
3697 * during the crash, causing a deadlock.
3699 set_indicator_token
= rtas_token("set-indicator");
3703 __debugger_ipi
= NULL
;
3704 __debugger_bpt
= NULL
;
3705 __debugger_sstep
= NULL
;
3706 __debugger_iabr_match
= NULL
;
3707 __debugger_break_match
= NULL
;
3708 __debugger_fault_handler
= NULL
;
3712 #ifdef CONFIG_MAGIC_SYSRQ
3713 static void sysrq_handle_xmon(int key
)
3715 /* ensure xmon is enabled */
3717 debugger(get_irq_regs());
3722 static struct sysrq_key_op sysrq_xmon_op
= {
3723 .handler
= sysrq_handle_xmon
,
3724 .help_msg
= "xmon(x)",
3725 .action_msg
= "Entering xmon",
3728 static int __init
setup_xmon_sysrq(void)
3730 register_sysrq_key('x', &sysrq_xmon_op
);
3733 device_initcall(setup_xmon_sysrq
);
3734 #endif /* CONFIG_MAGIC_SYSRQ */
3736 #ifdef CONFIG_DEBUG_FS
3737 static void clear_all_bpt(void)
3741 /* clear/unpatch all breakpoints */
3745 /* Disable all breakpoints */
3746 for (i
= 0; i
< NBPTS
; ++i
)
3747 bpts
[i
].enabled
= 0;
3749 /* Clear any data or iabr breakpoints */
3750 if (iabr
|| dabr
.enabled
) {
3755 printf("xmon: All breakpoints cleared\n");
3758 static int xmon_dbgfs_set(void *data
, u64 val
)
3763 /* make sure all breakpoints removed when disabling */
3769 static int xmon_dbgfs_get(void *data
, u64
*val
)
3775 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops
, xmon_dbgfs_get
,
3776 xmon_dbgfs_set
, "%llu\n");
3778 static int __init
setup_xmon_dbgfs(void)
3780 debugfs_create_file("xmon", 0600, powerpc_debugfs_root
, NULL
,
3784 device_initcall(setup_xmon_dbgfs
);
3785 #endif /* CONFIG_DEBUG_FS */
3787 static int xmon_early __initdata
;
3789 static int __init
early_parse_xmon(char *p
)
3791 if (!p
|| strncmp(p
, "early", 5) == 0) {
3792 /* just "xmon" is equivalent to "xmon=early" */
3796 } else if (strncmp(p
, "on", 2) == 0) {
3799 } else if (strncmp(p
, "off", 3) == 0)
3806 early_param("xmon", early_parse_xmon
);
3808 void __init
xmon_setup(void)
3816 #ifdef CONFIG_SPU_BASE
3820 u64 saved_mfc_sr1_RW
;
3821 u32 saved_spu_runcntl_RW
;
3822 unsigned long dump_addr
;
3826 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3828 static struct spu_info spu_info
[XMON_NUM_SPUS
];
3830 void xmon_register_spus(struct list_head
*list
)
3834 list_for_each_entry(spu
, list
, full_list
) {
3835 if (spu
->number
>= XMON_NUM_SPUS
) {
3840 spu_info
[spu
->number
].spu
= spu
;
3841 spu_info
[spu
->number
].stopped_ok
= 0;
3842 spu_info
[spu
->number
].dump_addr
= (unsigned long)
3843 spu_info
[spu
->number
].spu
->local_store
;
3847 static void stop_spus(void)
3853 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3854 if (!spu_info
[i
].spu
)
3857 if (setjmp(bus_error_jmp
) == 0) {
3858 catch_memory_errors
= 1;
3861 spu
= spu_info
[i
].spu
;
3863 spu_info
[i
].saved_spu_runcntl_RW
=
3864 in_be32(&spu
->problem
->spu_runcntl_RW
);
3866 tmp
= spu_mfc_sr1_get(spu
);
3867 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
3869 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
3870 spu_mfc_sr1_set(spu
, tmp
);
3875 spu_info
[i
].stopped_ok
= 1;
3877 printf("Stopped spu %.2d (was %s)\n", i
,
3878 spu_info
[i
].saved_spu_runcntl_RW
?
3879 "running" : "stopped");
3881 catch_memory_errors
= 0;
3882 printf("*** Error stopping spu %.2d\n", i
);
3884 catch_memory_errors
= 0;
3888 static void restart_spus(void)
3893 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3894 if (!spu_info
[i
].spu
)
3897 if (!spu_info
[i
].stopped_ok
) {
3898 printf("*** Error, spu %d was not successfully stopped"
3899 ", not restarting\n", i
);
3903 if (setjmp(bus_error_jmp
) == 0) {
3904 catch_memory_errors
= 1;
3907 spu
= spu_info
[i
].spu
;
3908 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
3909 out_be32(&spu
->problem
->spu_runcntl_RW
,
3910 spu_info
[i
].saved_spu_runcntl_RW
);
3915 printf("Restarted spu %.2d\n", i
);
3917 catch_memory_errors
= 0;
3918 printf("*** Error restarting spu %.2d\n", i
);
3920 catch_memory_errors
= 0;
3924 #define DUMP_WIDTH 23
3925 #define DUMP_VALUE(format, field, value) \
3927 if (setjmp(bus_error_jmp) == 0) { \
3928 catch_memory_errors = 1; \
3930 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3935 catch_memory_errors = 0; \
3936 printf(" %-*s = *** Error reading field.\n", \
3937 DUMP_WIDTH, #field); \
3939 catch_memory_errors = 0; \
3942 #define DUMP_FIELD(obj, format, field) \
3943 DUMP_VALUE(format, field, obj->field)
3945 static void dump_spu_fields(struct spu
*spu
)
3947 printf("Dumping spu fields at address %p:\n", spu
);
3949 DUMP_FIELD(spu
, "0x%x", number
);
3950 DUMP_FIELD(spu
, "%s", name
);
3951 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3952 DUMP_FIELD(spu
, "0x%p", local_store
);
3953 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3954 DUMP_FIELD(spu
, "0x%x", node
);
3955 DUMP_FIELD(spu
, "0x%lx", flags
);
3956 DUMP_FIELD(spu
, "%llu", class_0_pending
);
3957 DUMP_FIELD(spu
, "0x%llx", class_0_dar
);
3958 DUMP_FIELD(spu
, "0x%llx", class_1_dar
);
3959 DUMP_FIELD(spu
, "0x%llx", class_1_dsisr
);
3960 DUMP_FIELD(spu
, "0x%x", irqs
[0]);
3961 DUMP_FIELD(spu
, "0x%x", irqs
[1]);
3962 DUMP_FIELD(spu
, "0x%x", irqs
[2]);
3963 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3964 DUMP_FIELD(spu
, "%d", pid
);
3965 DUMP_FIELD(spu
, "0x%p", mm
);
3966 DUMP_FIELD(spu
, "0x%p", ctx
);
3967 DUMP_FIELD(spu
, "0x%p", rq
);
3968 DUMP_FIELD(spu
, "0x%llx", timestamp
);
3969 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3970 DUMP_FIELD(spu
, "0x%p", problem
);
3971 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3972 in_be32(&spu
->problem
->spu_runcntl_RW
));
3973 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3974 in_be32(&spu
->problem
->spu_status_R
));
3975 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3976 in_be32(&spu
->problem
->spu_npc_RW
));
3977 DUMP_FIELD(spu
, "0x%p", priv2
);
3978 DUMP_FIELD(spu
, "0x%p", pdata
);
3982 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3984 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3987 static void dump_spu_ls(unsigned long num
, int subcmd
)
3989 unsigned long offset
, addr
, ls_addr
;
3991 if (setjmp(bus_error_jmp
) == 0) {
3992 catch_memory_errors
= 1;
3994 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3998 catch_memory_errors
= 0;
3999 printf("*** Error: accessing spu info for spu %ld\n", num
);
4002 catch_memory_errors
= 0;
4004 if (scanhex(&offset
))
4005 addr
= ls_addr
+ offset
;
4007 addr
= spu_info
[num
].dump_addr
;
4009 if (addr
>= ls_addr
+ LS_SIZE
) {
4010 printf("*** Error: address outside of local store\n");
4016 addr
+= spu_inst_dump(addr
, 16, 1);
4026 spu_info
[num
].dump_addr
= addr
;
4029 static int do_spu_cmd(void)
4031 static unsigned long num
= 0;
4032 int cmd
, subcmd
= 0;
4044 if (isxdigit(subcmd
) || subcmd
== '\n')
4049 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
4050 printf("*** Error: invalid spu number\n");
4056 dump_spu_fields(spu_info
[num
].spu
);
4059 dump_spu_ls(num
, subcmd
);
4070 #else /* ! CONFIG_SPU_BASE */
4071 static int do_spu_cmd(void)