2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/smp.h>
17 #include <linux/reboot.h>
18 #include <linux/delay.h>
19 #include <linux/kallsyms.h>
20 #include <linux/kmsg_dump.h>
21 #include <linux/cpumask.h>
22 #include <linux/export.h>
23 #include <linux/sysrq.h>
24 #include <linux/interrupt.h>
25 #include <linux/irq.h>
26 #include <linux/bug.h>
28 #include <asm/ptrace.h>
29 #include <asm/string.h>
31 #include <asm/machdep.h>
33 #include <asm/processor.h>
34 #include <asm/pgtable.h>
36 #include <asm/mmu_context.h>
37 #include <asm/cputable.h>
39 #include <asm/sstep.h>
40 #include <asm/irq_regs.h>
42 #include <asm/spu_priv1.h>
43 #include <asm/setjmp.h>
45 #include <asm/debug.h>
48 #include <asm/hvcall.h>
56 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
57 static unsigned long xmon_taken
= 1;
58 static int xmon_owner
;
62 #endif /* CONFIG_SMP */
64 static unsigned long in_xmon __read_mostly
= 0;
66 static unsigned long adrs
;
68 #define MAX_DUMP (128 * 1024)
69 static unsigned long ndump
= 64;
70 static unsigned long nidump
= 16;
71 static unsigned long ncsum
= 4096;
73 static char tmpstr
[128];
75 static long bus_error_jmp
[JMP_BUF_LEN
];
76 static int catch_memory_errors
;
77 static long *xmon_fault_jmp
[NR_CPUS
];
79 /* Breakpoint stuff */
81 unsigned long address
;
82 unsigned int instr
[2];
88 /* Bits in bpt.enabled */
89 #define BP_IABR_TE 1 /* IABR translation enabled */
95 static struct bpt bpts
[NBPTS
];
96 static struct bpt dabr
;
97 static struct bpt
*iabr
;
98 static unsigned bpinstr
= 0x7fe00008; /* trap */
100 #define BP_NUM(bp) ((bp) - bpts + 1)
103 static int cmds(struct pt_regs
*);
104 static int mread(unsigned long, void *, int);
105 static int mwrite(unsigned long, void *, int);
106 static int handle_fault(struct pt_regs
*);
107 static void byterev(unsigned char *, int);
108 static void memex(void);
109 static int bsesc(void);
110 static void dump(void);
111 static void prdump(unsigned long, long);
112 static int ppc_inst_dump(unsigned long, long, int);
113 static void dump_log_buf(void);
114 static void backtrace(struct pt_regs
*);
115 static void excprint(struct pt_regs
*);
116 static void prregs(struct pt_regs
*);
117 static void memops(int);
118 static void memlocate(void);
119 static void memzcan(void);
120 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
122 int scanhex(unsigned long *valp
);
123 static void scannl(void);
124 static int hexdigit(int);
125 void getstring(char *, int);
126 static void flush_input(void);
127 static int inchar(void);
128 static void take_input(char *);
129 static unsigned long read_spr(int);
130 static void write_spr(int, unsigned long);
131 static void super_regs(void);
132 static void remove_bpts(void);
133 static void insert_bpts(void);
134 static void remove_cpu_bpts(void);
135 static void insert_cpu_bpts(void);
136 static struct bpt
*at_breakpoint(unsigned long pc
);
137 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
138 static int do_step(struct pt_regs
*);
139 static void bpt_cmds(void);
140 static void cacheflush(void);
141 static int cpu_cmd(void);
142 static void csum(void);
143 static void bootcmds(void);
144 static void proccall(void);
145 void dump_segments(void);
146 static void symbol_lookup(void);
147 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
149 static void xmon_print_symbol(unsigned long address
, const char *mid
,
151 static const char *getvecname(unsigned long vec
);
153 static int do_spu_cmd(void);
156 static void dump_tlb_44x(void);
158 #ifdef CONFIG_PPC_BOOK3E
159 static void dump_tlb_book3e(void);
162 static int xmon_no_auto_backtrace
;
164 extern void xmon_enter(void);
165 extern void xmon_leave(void);
173 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
175 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
176 || ('a' <= (c) && (c) <= 'f') \
177 || ('A' <= (c) && (c) <= 'F'))
178 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
179 || ('a' <= (c) && (c) <= 'z') \
180 || ('A' <= (c) && (c) <= 'Z'))
181 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
183 static char *help_string
= "\
185 b show breakpoints\n\
186 bd set data breakpoint\n\
187 bi set instruction breakpoint\n\
188 bc clear breakpoint\n"
191 c print cpus stopped in xmon\n\
192 c# try to switch to cpu number h (in hex)\n"
197 di dump instructions\n\
198 df dump float values\n\
199 dd dump double values\n\
200 dl dump the kernel log buffer\n"
203 dp[#] dump paca for current cpu, or cpu #\n\
204 dpa dump paca for all possible cpus\n"
207 dr dump stream of raw bytes\n\
208 e print exception information\n\
210 la lookup symbol+offset of specified address\n\
211 ls lookup address of specified symbol\n\
212 m examine/change memory\n\
213 mm move a block of memory\n\
214 ms set a block of memory\n\
215 md compare two blocks of memory\n\
216 ml locate a block of memory\n\
217 mz zero a block of memory\n\
218 mi show information about memory allocation\n\
219 p call a procedure\n\
222 #ifdef CONFIG_SPU_BASE
223 " ss stop execution on all spus\n\
224 sr restore execution on stopped spus\n\
225 sf # dump spu fields for spu # (in hex)\n\
226 sd # dump spu local store for spu # (in hex)\n\
227 sdi # disassemble spu local store for spu # (in hex)\n"
229 " S print special registers\n\
231 x exit monitor and recover\n\
232 X exit monitor and dont recover\n"
233 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
234 " u dump segment table or SLB\n"
235 #elif defined(CONFIG_PPC_STD_MMU_32)
236 " u dump segment registers\n"
237 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
245 static struct pt_regs
*xmon_regs
;
247 static inline void sync(void)
249 asm volatile("sync; isync");
252 static inline void store_inst(void *p
)
254 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
257 static inline void cflush(void *p
)
259 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
262 static inline void cinval(void *p
)
264 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
268 * Disable surveillance (the service processor watchdog function)
269 * while we are in xmon.
270 * XXX we should re-enable it when we leave. :)
272 #define SURVEILLANCE_TOKEN 9000
274 static inline void disable_surveillance(void)
276 #ifdef CONFIG_PPC_PSERIES
277 /* Since this can't be a module, args should end up below 4GB. */
278 static struct rtas_args args
;
281 * At this point we have got all the cpus we can into
282 * xmon, so there is hopefully no other cpu calling RTAS
283 * at the moment, even though we don't take rtas.lock.
284 * If we did try to take rtas.lock there would be a
285 * real possibility of deadlock.
287 args
.token
= rtas_token("set-indicator");
288 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
292 args
.rets
= &args
.args
[3];
293 args
.args
[0] = SURVEILLANCE_TOKEN
;
296 enter_rtas(__pa(&args
));
297 #endif /* CONFIG_PPC_PSERIES */
301 static int xmon_speaker
;
303 static void get_output_lock(void)
305 int me
= smp_processor_id() + 0x100;
306 int last_speaker
= 0, prev
;
309 if (xmon_speaker
== me
)
312 if (xmon_speaker
== 0) {
313 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
314 if (last_speaker
== 0)
318 while (xmon_speaker
== last_speaker
) {
321 /* hostile takeover */
322 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
323 if (prev
== last_speaker
)
330 static void release_output_lock(void)
335 int cpus_are_in_xmon(void)
337 return !cpumask_empty(&cpus_in_xmon
);
341 static inline int unrecoverable_excp(struct pt_regs
*regs
)
343 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
344 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
347 return ((regs
->msr
& MSR_RI
) == 0);
351 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
355 long recurse_jmp
[JMP_BUF_LEN
];
356 unsigned long offset
;
361 unsigned long timeout
;
364 local_irq_save(flags
);
366 bp
= in_breakpoint_table(regs
->nip
, &offset
);
368 regs
->nip
= bp
->address
+ offset
;
369 atomic_dec(&bp
->ref_count
);
375 cpu
= smp_processor_id();
376 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
379 printf("cpu 0x%x: Exception %lx %s in xmon, "
380 "returning to main loop\n",
381 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
382 release_output_lock();
383 longjmp(xmon_fault_jmp
[cpu
], 1);
386 if (setjmp(recurse_jmp
) != 0) {
387 if (!in_xmon
|| !xmon_gate
) {
389 printf("xmon: WARNING: bad recursive fault "
390 "on cpu 0x%x\n", cpu
);
391 release_output_lock();
394 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
398 xmon_fault_jmp
[cpu
] = recurse_jmp
;
399 cpumask_set_cpu(cpu
, &cpus_in_xmon
);
402 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
))
403 bp
= at_breakpoint(regs
->nip
);
404 if (bp
|| unrecoverable_excp(regs
))
411 printf("cpu 0x%x stopped at breakpoint 0x%x (",
413 xmon_print_symbol(regs
->nip
, " ", ")\n");
415 if (unrecoverable_excp(regs
))
416 printf("WARNING: exception is not recoverable, "
418 release_output_lock();
423 while (secondary
&& !xmon_gate
) {
427 secondary
= test_and_set_bit(0, &in_xmon
);
432 if (!secondary
&& !xmon_gate
) {
433 /* we are the first cpu to come in */
434 /* interrupt other cpu(s) */
435 int ncpus
= num_online_cpus();
440 smp_send_debugger_break();
441 /* wait for other cpus to come in */
442 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
443 if (cpumask_weight(&cpus_in_xmon
) >= ncpus
)
449 disable_surveillance();
450 /* for breakpoint or single step, print the current instr. */
451 if (bp
|| TRAP(regs
) == 0xd00)
452 ppc_inst_dump(regs
->nip
, 1, 0);
453 printf("enter ? for help\n");
462 if (cpu
== xmon_owner
) {
463 if (!test_and_set_bit(0, &xmon_taken
)) {
468 while (cpu
== xmon_owner
)
482 /* have switched to some other cpu */
487 cpumask_clear_cpu(cpu
, &cpus_in_xmon
);
488 xmon_fault_jmp
[cpu
] = NULL
;
490 /* UP is simple... */
492 printf("Exception %lx %s in xmon, returning to main loop\n",
493 regs
->trap
, getvecname(TRAP(regs
)));
494 longjmp(xmon_fault_jmp
[0], 1);
496 if (setjmp(recurse_jmp
) == 0) {
497 xmon_fault_jmp
[0] = recurse_jmp
;
501 bp
= at_breakpoint(regs
->nip
);
503 printf("Stopped at breakpoint %x (", BP_NUM(bp
));
504 xmon_print_symbol(regs
->nip
, " ", ")\n");
506 if (unrecoverable_excp(regs
))
507 printf("WARNING: exception is not recoverable, "
510 disable_surveillance();
511 /* for breakpoint or single step, print the current instr. */
512 if (bp
|| TRAP(regs
) == 0xd00)
513 ppc_inst_dump(regs
->nip
, 1, 0);
514 printf("enter ? for help\n");
524 if (regs
->msr
& MSR_DE
) {
525 bp
= at_breakpoint(regs
->nip
);
527 regs
->nip
= (unsigned long) &bp
->instr
[0];
528 atomic_inc(&bp
->ref_count
);
532 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
533 bp
= at_breakpoint(regs
->nip
);
535 int stepped
= emulate_step(regs
, bp
->instr
[0]);
537 regs
->nip
= (unsigned long) &bp
->instr
[0];
538 atomic_inc(&bp
->ref_count
);
539 } else if (stepped
< 0) {
540 printf("Couldn't single-step %s instruction\n",
541 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
548 local_irq_restore(flags
);
550 return cmd
!= 'X' && cmd
!= EOF
;
553 int xmon(struct pt_regs
*excp
)
558 ppc_save_regs(®s
);
562 return xmon_core(excp
, 0);
566 irqreturn_t
xmon_irq(int irq
, void *d
)
569 local_irq_save(flags
);
570 printf("Keyboard interrupt\n");
571 xmon(get_irq_regs());
572 local_irq_restore(flags
);
576 static int xmon_bpt(struct pt_regs
*regs
)
579 unsigned long offset
;
581 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
584 /* Are we at the trap at bp->instr[1] for some bp? */
585 bp
= in_breakpoint_table(regs
->nip
, &offset
);
586 if (bp
!= NULL
&& offset
== 4) {
587 regs
->nip
= bp
->address
+ 4;
588 atomic_dec(&bp
->ref_count
);
592 /* Are we at a breakpoint? */
593 bp
= at_breakpoint(regs
->nip
);
602 static int xmon_sstep(struct pt_regs
*regs
)
610 static int xmon_dabr_match(struct pt_regs
*regs
)
612 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
614 if (dabr
.enabled
== 0)
620 static int xmon_iabr_match(struct pt_regs
*regs
)
622 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
630 static int xmon_ipi(struct pt_regs
*regs
)
633 if (in_xmon
&& !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon
))
639 static int xmon_fault_handler(struct pt_regs
*regs
)
642 unsigned long offset
;
644 if (in_xmon
&& catch_memory_errors
)
645 handle_fault(regs
); /* doesn't return */
647 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
648 bp
= in_breakpoint_table(regs
->nip
, &offset
);
650 regs
->nip
= bp
->address
+ offset
;
651 atomic_dec(&bp
->ref_count
);
658 static struct bpt
*at_breakpoint(unsigned long pc
)
664 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
665 if (bp
->enabled
&& pc
== bp
->address
)
670 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
674 off
= nip
- (unsigned long) bpts
;
675 if (off
>= sizeof(bpts
))
677 off
%= sizeof(struct bpt
);
678 if (off
!= offsetof(struct bpt
, instr
[0])
679 && off
!= offsetof(struct bpt
, instr
[1]))
681 *offp
= off
- offsetof(struct bpt
, instr
[0]);
682 return (struct bpt
*) (nip
- off
);
685 static struct bpt
*new_breakpoint(unsigned long a
)
690 bp
= at_breakpoint(a
);
694 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
695 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
697 bp
->instr
[1] = bpinstr
;
698 store_inst(&bp
->instr
[1]);
703 printf("Sorry, no free breakpoints. Please clear one first.\n");
707 static void insert_bpts(void)
713 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
714 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
716 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
717 printf("Couldn't read instruction at %lx, "
718 "disabling breakpoint there\n", bp
->address
);
722 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
723 printf("Breakpoint at %lx is on an mtmsrd or rfid "
724 "instruction, disabling it\n", bp
->address
);
728 store_inst(&bp
->instr
[0]);
729 if (bp
->enabled
& BP_IABR
)
731 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
732 printf("Couldn't write instruction at %lx, "
733 "disabling breakpoint there\n", bp
->address
);
734 bp
->enabled
&= ~BP_TRAP
;
737 store_inst((void *)bp
->address
);
741 static void insert_cpu_bpts(void)
744 set_dabr(dabr
.address
| (dabr
.enabled
& 7), DABRX_ALL
);
745 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
746 mtspr(SPRN_IABR
, iabr
->address
747 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
750 static void remove_bpts(void)
757 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
758 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
760 if (mread(bp
->address
, &instr
, 4) == 4
762 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
763 printf("Couldn't remove breakpoint at %lx\n",
766 store_inst((void *)bp
->address
);
770 static void remove_cpu_bpts(void)
773 if (cpu_has_feature(CPU_FTR_IABR
))
777 /* Command interpreting routine */
778 static char *last_cmd
;
781 cmds(struct pt_regs
*excp
)
788 if (!xmon_no_auto_backtrace
) {
789 xmon_no_auto_backtrace
= 1;
790 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
795 printf("%x:", smp_processor_id());
796 #endif /* CONFIG_SMP */
802 if (last_cmd
== NULL
)
804 take_input(last_cmd
);
838 prregs(excp
); /* print regs */
853 if (do_spu_cmd() == 0)
862 printf(" <no input ...>\n");
866 xmon_puts(help_string
);
884 #ifdef CONFIG_PPC_STD_MMU
888 #elif defined(CONFIG_4xx)
892 #elif defined(CONFIG_PPC_BOOK3E)
898 printf("Unrecognized command: ");
900 if (' ' < cmd
&& cmd
<= '~')
903 printf("\\x%x", cmd
);
905 } while (cmd
!= '\n');
906 printf(" (type ? for help)\n");
913 static int do_step(struct pt_regs
*regs
)
916 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
921 * Step a single instruction.
922 * Some instructions we emulate, others we execute with MSR_SE set.
924 static int do_step(struct pt_regs
*regs
)
929 /* check we are in 64-bit kernel mode, translation enabled */
930 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
931 if (mread(regs
->nip
, &instr
, 4) == 4) {
932 stepped
= emulate_step(regs
, instr
);
934 printf("Couldn't single-step %s instruction\n",
935 (IS_RFID(instr
)? "rfid": "mtmsrd"));
939 regs
->trap
= 0xd00 | (regs
->trap
& 1);
940 printf("stepped to ");
941 xmon_print_symbol(regs
->nip
, " ", "\n");
942 ppc_inst_dump(regs
->nip
, 1, 0);
952 static void bootcmds(void)
958 ppc_md
.restart(NULL
);
965 static int cpu_cmd(void)
972 if (!scanhex(&cpu
)) {
973 /* print cpus waiting or in xmon */
974 printf("cpus stopped:");
976 for_each_possible_cpu(cpu
) {
977 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
983 printf("-%x", cpu
- 1);
988 printf("-%x", NR_CPUS
- 1);
992 /* try to switch to cpu specified */
993 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
994 printf("cpu 0x%x isn't in xmon\n", cpu
);
1001 while (!xmon_taken
) {
1002 if (--timeout
== 0) {
1003 if (test_and_set_bit(0, &xmon_taken
))
1005 /* take control back */
1007 xmon_owner
= smp_processor_id();
1008 printf("cpu %u didn't take control\n", cpu
);
1016 #endif /* CONFIG_SMP */
1019 static unsigned short fcstab
[256] = {
1020 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1021 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1022 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1023 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1024 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1025 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1026 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1027 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1028 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1029 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1030 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1031 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1032 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1033 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1034 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1035 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1036 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1037 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1038 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1039 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1040 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1041 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1042 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1043 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1044 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1045 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1046 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1047 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1048 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1049 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1050 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1051 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1054 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1063 if (!scanhex(&adrs
))
1065 if (!scanhex(&ncsum
))
1068 for (i
= 0; i
< ncsum
; ++i
) {
1069 if (mread(adrs
+i
, &v
, 1) == 0) {
1070 printf("csum stopped at %x\n", adrs
+i
);
1075 printf("%x\n", fcs
);
1079 * Check if this is a suitable place to put a breakpoint.
1081 static long check_bp_loc(unsigned long addr
)
1086 if (!is_kernel_addr(addr
)) {
1087 printf("Breakpoints may only be placed at kernel addresses\n");
1090 if (!mread(addr
, &instr
, sizeof(instr
))) {
1091 printf("Can't read instruction at address %lx\n", addr
);
1094 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1095 printf("Breakpoints may not be placed on mtmsrd or rfid "
1102 static char *breakpoint_help_string
=
1103 "Breakpoint command usage:\n"
1104 "b show breakpoints\n"
1105 "b <addr> [cnt] set breakpoint at given instr addr\n"
1106 "bc clear all breakpoints\n"
1107 "bc <n/addr> clear breakpoint number n or at addr\n"
1108 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1109 "bd <addr> [cnt] set hardware data breakpoint\n"
1119 const char badaddr
[] = "Only kernel addresses are permitted "
1120 "for breakpoints\n";
1125 case 'd': /* bd - hardware data breakpoint */
1130 else if (cmd
== 'w')
1136 if (scanhex(&dabr
.address
)) {
1137 if (!is_kernel_addr(dabr
.address
)) {
1142 dabr
.enabled
= mode
| BP_DABR
;
1146 case 'i': /* bi - hardware instr breakpoint */
1147 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1148 printf("Hardware instruction breakpoint "
1149 "not supported on this cpu\n");
1153 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1158 if (!check_bp_loc(a
))
1160 bp
= new_breakpoint(a
);
1162 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1170 /* clear all breakpoints */
1171 for (i
= 0; i
< NBPTS
; ++i
)
1172 bpts
[i
].enabled
= 0;
1175 printf("All breakpoints cleared\n");
1179 if (a
<= NBPTS
&& a
>= 1) {
1180 /* assume a breakpoint number */
1181 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1183 /* assume a breakpoint address */
1184 bp
= at_breakpoint(a
);
1186 printf("No breakpoint at %x\n", a
);
1191 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1192 xmon_print_symbol(bp
->address
, " ", ")\n");
1200 printf(breakpoint_help_string
);
1205 /* print all breakpoints */
1206 printf(" type address\n");
1208 printf(" data "REG
" [", dabr
.address
);
1209 if (dabr
.enabled
& 1)
1211 if (dabr
.enabled
& 2)
1215 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1218 printf("%2x %s ", BP_NUM(bp
),
1219 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1220 xmon_print_symbol(bp
->address
, " ", "\n");
1225 if (!check_bp_loc(a
))
1227 bp
= new_breakpoint(a
);
1229 bp
->enabled
|= BP_TRAP
;
1234 /* Very cheap human name for vector lookup. */
1236 const char *getvecname(unsigned long vec
)
1241 case 0x100: ret
= "(System Reset)"; break;
1242 case 0x200: ret
= "(Machine Check)"; break;
1243 case 0x300: ret
= "(Data Access)"; break;
1244 case 0x380: ret
= "(Data SLB Access)"; break;
1245 case 0x400: ret
= "(Instruction Access)"; break;
1246 case 0x480: ret
= "(Instruction SLB Access)"; break;
1247 case 0x500: ret
= "(Hardware Interrupt)"; break;
1248 case 0x600: ret
= "(Alignment)"; break;
1249 case 0x700: ret
= "(Program Check)"; break;
1250 case 0x800: ret
= "(FPU Unavailable)"; break;
1251 case 0x900: ret
= "(Decrementer)"; break;
1252 case 0xc00: ret
= "(System Call)"; break;
1253 case 0xd00: ret
= "(Single Step)"; break;
1254 case 0xf00: ret
= "(Performance Monitor)"; break;
1255 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1256 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1262 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1263 unsigned long *endp
)
1265 unsigned long size
, offset
;
1268 *startp
= *endp
= 0;
1271 if (setjmp(bus_error_jmp
) == 0) {
1272 catch_memory_errors
= 1;
1274 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1276 *startp
= pc
- offset
;
1277 *endp
= pc
- offset
+ size
;
1281 catch_memory_errors
= 0;
1284 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1285 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1287 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1290 int max_to_print
= 64;
1292 unsigned long newsp
;
1293 unsigned long marker
;
1294 struct pt_regs regs
;
1296 while (max_to_print
--) {
1297 if (sp
< PAGE_OFFSET
) {
1299 printf("SP (%lx) is in userspace\n", sp
);
1303 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1304 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1305 printf("Couldn't read stack frame at %lx\n", sp
);
1310 * For the first stack frame, try to work out if
1311 * LR and/or the saved LR value in the bottommost
1312 * stack frame are valid.
1314 if ((pc
| lr
) != 0) {
1315 unsigned long fnstart
, fnend
;
1316 unsigned long nextip
;
1319 get_function_bounds(pc
, &fnstart
, &fnend
);
1322 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1323 sizeof(unsigned long));
1325 if (lr
< PAGE_OFFSET
1326 || (fnstart
<= lr
&& lr
< fnend
))
1328 } else if (lr
== nextip
) {
1330 } else if (lr
>= PAGE_OFFSET
1331 && !(fnstart
<= lr
&& lr
< fnend
)) {
1332 printf("[link register ] ");
1333 xmon_print_symbol(lr
, " ", "\n");
1336 printf("["REG
"] ", sp
);
1337 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1342 printf("["REG
"] ", sp
);
1343 xmon_print_symbol(ip
, " ", "\n");
1346 /* Look for "regshere" marker to see if this is
1347 an exception frame. */
1348 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1349 && marker
== STACK_FRAME_REGS_MARKER
) {
1350 if (mread(sp
+ STACK_FRAME_OVERHEAD
, ®s
, sizeof(regs
))
1352 printf("Couldn't read registers at %lx\n",
1353 sp
+ STACK_FRAME_OVERHEAD
);
1356 printf("--- Exception: %lx %s at ", regs
.trap
,
1357 getvecname(TRAP(®s
)));
1360 xmon_print_symbol(pc
, " ", "\n");
1370 static void backtrace(struct pt_regs
*excp
)
1375 xmon_show_stack(sp
, 0, 0);
1377 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1381 static void print_bug_trap(struct pt_regs
*regs
)
1384 const struct bug_entry
*bug
;
1387 if (regs
->msr
& MSR_PR
)
1388 return; /* not in kernel */
1389 addr
= regs
->nip
; /* address of trap instruction */
1390 if (addr
< PAGE_OFFSET
)
1392 bug
= find_bug(regs
->nip
);
1395 if (is_warning_bug(bug
))
1398 #ifdef CONFIG_DEBUG_BUGVERBOSE
1399 printf("kernel BUG at %s:%u!\n",
1400 bug
->file
, bug
->line
);
1402 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1404 #endif /* CONFIG_BUG */
1407 static void excprint(struct pt_regs
*fp
)
1412 printf("cpu 0x%x: ", smp_processor_id());
1413 #endif /* CONFIG_SMP */
1416 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1418 xmon_print_symbol(fp
->nip
, ": ", "\n");
1420 printf(" lr: ", fp
->link
);
1421 xmon_print_symbol(fp
->link
, ": ", "\n");
1423 printf(" sp: %lx\n", fp
->gpr
[1]);
1424 printf(" msr: %lx\n", fp
->msr
);
1426 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1427 printf(" dar: %lx\n", fp
->dar
);
1429 printf(" dsisr: %lx\n", fp
->dsisr
);
1432 printf(" current = 0x%lx\n", current
);
1434 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1435 local_paca
, local_paca
->soft_enabled
, local_paca
->irq_happened
);
1438 printf(" pid = %ld, comm = %s\n",
1439 current
->pid
, current
->comm
);
1446 static void prregs(struct pt_regs
*fp
)
1450 struct pt_regs regs
;
1452 if (scanhex(&base
)) {
1453 if (setjmp(bus_error_jmp
) == 0) {
1454 catch_memory_errors
= 1;
1456 regs
= *(struct pt_regs
*)base
;
1460 catch_memory_errors
= 0;
1461 printf("*** Error reading registers from "REG
"\n",
1465 catch_memory_errors
= 0;
1470 if (FULL_REGS(fp
)) {
1471 for (n
= 0; n
< 16; ++n
)
1472 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1473 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1475 for (n
= 0; n
< 7; ++n
)
1476 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1477 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1480 for (n
= 0; n
< 32; ++n
) {
1481 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1482 (n
& 3) == 3? "\n": " ");
1483 if (n
== 12 && !FULL_REGS(fp
)) {
1490 xmon_print_symbol(fp
->nip
, " ", "\n");
1491 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1493 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1496 xmon_print_symbol(fp
->link
, " ", "\n");
1497 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1498 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1499 fp
->ctr
, fp
->xer
, fp
->trap
);
1501 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1502 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1505 static void cacheflush(void)
1508 unsigned long nflush
;
1513 scanhex((void *)&adrs
);
1518 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1519 if (setjmp(bus_error_jmp
) == 0) {
1520 catch_memory_errors
= 1;
1524 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1525 cflush((void *) adrs
);
1527 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1528 cinval((void *) adrs
);
1531 /* wait a little while to see if we get a machine check */
1534 catch_memory_errors
= 0;
1537 static unsigned long
1540 unsigned int instrs
[2];
1541 unsigned long (*code
)(void);
1542 unsigned long ret
= -1UL;
1544 unsigned long opd
[3];
1546 opd
[0] = (unsigned long)instrs
;
1549 code
= (unsigned long (*)(void)) opd
;
1551 code
= (unsigned long (*)(void)) instrs
;
1554 /* mfspr r3,n; blr */
1555 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1556 instrs
[1] = 0x4e800020;
1558 store_inst(instrs
+1);
1560 if (setjmp(bus_error_jmp
) == 0) {
1561 catch_memory_errors
= 1;
1567 /* wait a little while to see if we get a machine check */
1576 write_spr(int n
, unsigned long val
)
1578 unsigned int instrs
[2];
1579 unsigned long (*code
)(unsigned long);
1581 unsigned long opd
[3];
1583 opd
[0] = (unsigned long)instrs
;
1586 code
= (unsigned long (*)(unsigned long)) opd
;
1588 code
= (unsigned long (*)(unsigned long)) instrs
;
1591 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1592 instrs
[1] = 0x4e800020;
1594 store_inst(instrs
+1);
1596 if (setjmp(bus_error_jmp
) == 0) {
1597 catch_memory_errors
= 1;
1603 /* wait a little while to see if we get a machine check */
1609 static unsigned long regno
;
1610 extern char exc_prolog
;
1611 extern char dec_exc
;
1613 static void super_regs(void)
1620 unsigned long sp
, toc
;
1621 asm("mr %0,1" : "=r" (sp
) :);
1622 asm("mr %0,2" : "=r" (toc
) :);
1624 printf("msr = "REG
" sprg0= "REG
"\n",
1625 mfmsr(), mfspr(SPRN_SPRG0
));
1626 printf("pvr = "REG
" sprg1= "REG
"\n",
1627 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1628 printf("dec = "REG
" sprg2= "REG
"\n",
1629 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1630 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1631 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1639 val
= read_spr(regno
);
1641 write_spr(regno
, val
);
1644 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1651 * Stuff for reading and writing memory safely
1654 mread(unsigned long adrs
, void *buf
, int size
)
1660 if (setjmp(bus_error_jmp
) == 0) {
1661 catch_memory_errors
= 1;
1667 *(u16
*)q
= *(u16
*)p
;
1670 *(u32
*)q
= *(u32
*)p
;
1673 *(u64
*)q
= *(u64
*)p
;
1676 for( ; n
< size
; ++n
) {
1682 /* wait a little while to see if we get a machine check */
1686 catch_memory_errors
= 0;
1691 mwrite(unsigned long adrs
, void *buf
, int size
)
1697 if (setjmp(bus_error_jmp
) == 0) {
1698 catch_memory_errors
= 1;
1704 *(u16
*)p
= *(u16
*)q
;
1707 *(u32
*)p
= *(u32
*)q
;
1710 *(u64
*)p
= *(u64
*)q
;
1713 for ( ; n
< size
; ++n
) {
1719 /* wait a little while to see if we get a machine check */
1723 printf("*** Error writing address %x\n", adrs
+ n
);
1725 catch_memory_errors
= 0;
1729 static int fault_type
;
1730 static int fault_except
;
1731 static char *fault_chars
[] = { "--", "**", "##" };
1733 static int handle_fault(struct pt_regs
*regs
)
1735 fault_except
= TRAP(regs
);
1736 switch (TRAP(regs
)) {
1748 longjmp(bus_error_jmp
, 1);
1753 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1756 byterev(unsigned char *val
, int size
)
1762 SWAP(val
[0], val
[1], t
);
1765 SWAP(val
[0], val
[3], t
);
1766 SWAP(val
[1], val
[2], t
);
1768 case 8: /* is there really any use for this? */
1769 SWAP(val
[0], val
[7], t
);
1770 SWAP(val
[1], val
[6], t
);
1771 SWAP(val
[2], val
[5], t
);
1772 SWAP(val
[3], val
[4], t
);
1780 static char *memex_help_string
=
1781 "Memory examine command usage:\n"
1782 "m [addr] [flags] examine/change memory\n"
1783 " addr is optional. will start where left off.\n"
1784 " flags may include chars from this set:\n"
1785 " b modify by bytes (default)\n"
1786 " w modify by words (2 byte)\n"
1787 " l modify by longs (4 byte)\n"
1788 " d modify by doubleword (8 byte)\n"
1789 " r toggle reverse byte order mode\n"
1790 " n do not read memory (for i/o spaces)\n"
1791 " . ok to read (default)\n"
1792 "NOTE: flags are saved as defaults\n"
1795 static char *memex_subcmd_help_string
=
1796 "Memory examine subcommands:\n"
1797 " hexval write this val to current location\n"
1798 " 'string' write chars from string to this location\n"
1799 " ' increment address\n"
1800 " ^ decrement address\n"
1801 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1802 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1803 " ` clear no-read flag\n"
1804 " ; stay at this addr\n"
1805 " v change to byte mode\n"
1806 " w change to word (2 byte) mode\n"
1807 " l change to long (4 byte) mode\n"
1808 " u change to doubleword (8 byte) mode\n"
1809 " m addr change current addr\n"
1810 " n toggle no-read flag\n"
1811 " r toggle byte reverse flag\n"
1812 " < count back up count bytes\n"
1813 " > count skip forward count bytes\n"
1814 " x exit this mode\n"
1820 int cmd
, inc
, i
, nslash
;
1822 unsigned char val
[16];
1824 scanhex((void *)&adrs
);
1827 printf(memex_help_string
);
1833 while ((cmd
= skipbl()) != '\n') {
1835 case 'b': size
= 1; break;
1836 case 'w': size
= 2; break;
1837 case 'l': size
= 4; break;
1838 case 'd': size
= 8; break;
1839 case 'r': brev
= !brev
; break;
1840 case 'n': mnoread
= 1; break;
1841 case '.': mnoread
= 0; break;
1850 n
= mread(adrs
, val
, size
);
1851 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1856 for (i
= 0; i
< n
; ++i
)
1857 printf("%.2x", val
[i
]);
1858 for (; i
< size
; ++i
)
1859 printf("%s", fault_chars
[fault_type
]);
1866 for (i
= 0; i
< size
; ++i
)
1867 val
[i
] = n
>> (i
* 8);
1870 mwrite(adrs
, val
, size
);
1883 else if( n
== '\'' )
1885 for (i
= 0; i
< size
; ++i
)
1886 val
[i
] = n
>> (i
* 8);
1889 mwrite(adrs
, val
, size
);
1926 adrs
-= 1 << nslash
;
1930 adrs
+= 1 << nslash
;
1934 adrs
+= 1 << -nslash
;
1938 adrs
-= 1 << -nslash
;
1941 scanhex((void *)&adrs
);
1960 printf(memex_subcmd_help_string
);
1975 case 'n': c
= '\n'; break;
1976 case 'r': c
= '\r'; break;
1977 case 'b': c
= '\b'; break;
1978 case 't': c
= '\t'; break;
1983 static void xmon_rawdump (unsigned long adrs
, long ndump
)
1986 unsigned char temp
[16];
1988 for (n
= ndump
; n
> 0;) {
1990 nr
= mread(adrs
, temp
, r
);
1992 for (m
= 0; m
< r
; ++m
) {
1994 printf("%.2x", temp
[m
]);
1996 printf("%s", fault_chars
[fault_type
]);
2006 static void dump_one_paca(int cpu
)
2008 struct paca_struct
*p
;
2010 if (setjmp(bus_error_jmp
) != 0) {
2011 printf("*** Error dumping paca for cpu 0x%x!\n", cpu
);
2015 catch_memory_errors
= 1;
2020 printf("paca for cpu 0x%x @ %p:\n", cpu
, p
);
2022 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu
) ? "yes" : "no");
2023 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu
) ? "yes" : "no");
2024 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu
) ? "yes" : "no");
2026 #define DUMP(paca, name, format) \
2027 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2028 offsetof(struct paca_struct, name));
2030 DUMP(p
, lock_token
, "x");
2031 DUMP(p
, paca_index
, "x");
2032 DUMP(p
, kernel_toc
, "lx");
2033 DUMP(p
, kernelbase
, "lx");
2034 DUMP(p
, kernel_msr
, "lx");
2035 #ifdef CONFIG_PPC_STD_MMU_64
2036 DUMP(p
, stab_real
, "lx");
2037 DUMP(p
, stab_addr
, "lx");
2039 DUMP(p
, emergency_sp
, "p");
2040 DUMP(p
, data_offset
, "lx");
2041 DUMP(p
, hw_cpu_id
, "x");
2042 DUMP(p
, cpu_start
, "x");
2043 DUMP(p
, kexec_state
, "x");
2044 DUMP(p
, __current
, "p");
2045 DUMP(p
, kstack
, "lx");
2046 DUMP(p
, stab_rr
, "lx");
2047 DUMP(p
, saved_r1
, "lx");
2048 DUMP(p
, trap_save
, "x");
2049 DUMP(p
, soft_enabled
, "x");
2050 DUMP(p
, irq_happened
, "x");
2051 DUMP(p
, io_sync
, "x");
2052 DUMP(p
, irq_work_pending
, "x");
2053 DUMP(p
, nap_state_lost
, "x");
2057 catch_memory_errors
= 0;
2061 static void dump_all_pacas(void)
2065 if (num_possible_cpus() == 0) {
2066 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2070 for_each_possible_cpu(cpu
)
2074 static void dump_pacas(void)
2085 termch
= c
; /* Put c back, it wasn't 'a' */
2090 dump_one_paca(xmon_owner
);
2094 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2095 || ('a' <= (c) && (c) <= 'f') \
2096 || ('A' <= (c) && (c) <= 'F'))
2111 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2113 scanhex((void *)&adrs
);
2120 else if (nidump
> MAX_DUMP
)
2122 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2124 } else if (c
== 'l') {
2126 } else if (c
== 'r') {
2130 xmon_rawdump(adrs
, ndump
);
2137 else if (ndump
> MAX_DUMP
)
2139 prdump(adrs
, ndump
);
2146 prdump(unsigned long adrs
, long ndump
)
2148 long n
, m
, c
, r
, nr
;
2149 unsigned char temp
[16];
2151 for (n
= ndump
; n
> 0;) {
2155 nr
= mread(adrs
, temp
, r
);
2157 for (m
= 0; m
< r
; ++m
) {
2158 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2161 printf("%.2x", temp
[m
]);
2163 printf("%s", fault_chars
[fault_type
]);
2165 for (; m
< 16; ++m
) {
2166 if ((m
& (sizeof(long) - 1)) == 0)
2171 for (m
= 0; m
< r
; ++m
) {
2174 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2187 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2190 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2191 instruction_dump_func dump_func
)
2194 unsigned long first_adr
;
2195 unsigned long inst
, last_inst
= 0;
2196 unsigned char val
[4];
2199 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2200 nr
= mread(adr
, val
, 4);
2203 const char *x
= fault_chars
[fault_type
];
2204 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2208 inst
= GETWORD(val
);
2209 if (adr
> first_adr
&& inst
== last_inst
) {
2219 printf(REG
" %.8x", adr
, inst
);
2221 dump_func(inst
, adr
);
2224 return adr
- first_adr
;
2228 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2230 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2234 print_address(unsigned long addr
)
2236 xmon_print_symbol(addr
, "\t# ", "");
2242 struct kmsg_dumper dumper
= { .active
= 1 };
2243 unsigned char buf
[128];
2246 if (setjmp(bus_error_jmp
) != 0) {
2247 printf("Error dumping printk buffer!\n");
2251 catch_memory_errors
= 1;
2254 kmsg_dump_rewind_nolock(&dumper
);
2255 while (kmsg_dump_get_line_nolock(&dumper
, false, buf
, sizeof(buf
), &len
)) {
2261 /* wait a little while to see if we get a machine check */
2263 catch_memory_errors
= 0;
2267 * Memory operations - move, set, print differences
2269 static unsigned long mdest
; /* destination address */
2270 static unsigned long msrc
; /* source address */
2271 static unsigned long mval
; /* byte value to set memory to */
2272 static unsigned long mcount
; /* # bytes to affect */
2273 static unsigned long mdiffs
; /* max # differences to print */
2278 scanhex((void *)&mdest
);
2279 if( termch
!= '\n' )
2281 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2282 if( termch
!= '\n' )
2284 scanhex((void *)&mcount
);
2287 memmove((void *)mdest
, (void *)msrc
, mcount
);
2290 memset((void *)mdest
, mval
, mcount
);
2293 if( termch
!= '\n' )
2295 scanhex((void *)&mdiffs
);
2296 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2302 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2307 for( n
= nb
; n
> 0; --n
)
2308 if( *p1
++ != *p2
++ )
2309 if( ++prt
<= maxpr
)
2310 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2311 p1
[-1], p2
- 1, p2
[-1]);
2313 printf("Total of %d differences\n", prt
);
2316 static unsigned mend
;
2317 static unsigned mask
;
2323 unsigned char val
[4];
2326 scanhex((void *)&mdest
);
2327 if (termch
!= '\n') {
2329 scanhex((void *)&mend
);
2330 if (termch
!= '\n') {
2332 scanhex((void *)&mval
);
2334 if (termch
!= '\n') termch
= 0;
2335 scanhex((void *)&mask
);
2339 for (a
= mdest
; a
< mend
; a
+= 4) {
2340 if (mread(a
, val
, 4) == 4
2341 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2342 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2349 static unsigned long mskip
= 0x1000;
2350 static unsigned long mlim
= 0xffffffff;
2360 if (termch
!= '\n') termch
= 0;
2362 if (termch
!= '\n') termch
= 0;
2365 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2366 ok
= mread(a
, &v
, 1);
2368 printf("%.8x .. ", a
);
2369 } else if (!ok
&& ook
)
2370 printf("%.8x\n", a
- mskip
);
2376 printf("%.8x\n", a
- mskip
);
2379 static void proccall(void)
2381 unsigned long args
[8];
2384 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2385 unsigned long, unsigned long, unsigned long,
2386 unsigned long, unsigned long, unsigned long);
2389 if (!scanhex(&adrs
))
2393 for (i
= 0; i
< 8; ++i
)
2395 for (i
= 0; i
< 8; ++i
) {
2396 if (!scanhex(&args
[i
]) || termch
== '\n')
2400 func
= (callfunc_t
) adrs
;
2402 if (setjmp(bus_error_jmp
) == 0) {
2403 catch_memory_errors
= 1;
2405 ret
= func(args
[0], args
[1], args
[2], args
[3],
2406 args
[4], args
[5], args
[6], args
[7]);
2408 printf("return value is %x\n", ret
);
2410 printf("*** %x exception occurred\n", fault_except
);
2412 catch_memory_errors
= 0;
2415 /* Input scanning routines */
2426 while( c
== ' ' || c
== '\t' )
2432 static char *regnames
[N_PTREGS
] = {
2433 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2434 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2435 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2436 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2437 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2443 "trap", "dar", "dsisr", "res"
2447 scanhex(unsigned long *vp
)
2454 /* parse register name */
2458 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2467 for (i
= 0; i
< N_PTREGS
; ++i
) {
2468 if (strcmp(regnames
[i
], regname
) == 0) {
2469 if (xmon_regs
== NULL
) {
2470 printf("regs not available\n");
2473 *vp
= ((unsigned long *)xmon_regs
)[i
];
2477 printf("invalid register name '%%%s'\n", regname
);
2481 /* skip leading "0x" if any */
2495 } else if (c
== '$') {
2497 for (i
=0; i
<63; i
++) {
2507 if (setjmp(bus_error_jmp
) == 0) {
2508 catch_memory_errors
= 1;
2510 *vp
= kallsyms_lookup_name(tmpstr
);
2513 catch_memory_errors
= 0;
2515 printf("unknown symbol '%s'\n", tmpstr
);
2548 static int hexdigit(int c
)
2550 if( '0' <= c
&& c
<= '9' )
2552 if( 'A' <= c
&& c
<= 'F' )
2553 return c
- ('A' - 10);
2554 if( 'a' <= c
&& c
<= 'f' )
2555 return c
- ('a' - 10);
2560 getstring(char *s
, int size
)
2571 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2576 static char line
[256];
2577 static char *lineptr
;
2588 if (lineptr
== NULL
|| *lineptr
== 0) {
2589 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2599 take_input(char *str
)
2608 int type
= inchar();
2610 static char tmp
[64];
2615 xmon_print_symbol(addr
, ": ", "\n");
2620 if (setjmp(bus_error_jmp
) == 0) {
2621 catch_memory_errors
= 1;
2623 addr
= kallsyms_lookup_name(tmp
);
2625 printf("%s: %lx\n", tmp
, addr
);
2627 printf("Symbol '%s' not found.\n", tmp
);
2630 catch_memory_errors
= 0;
2637 /* Print an address in numeric and symbolic form (if possible) */
2638 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2642 const char *name
= NULL
;
2643 unsigned long offset
, size
;
2645 printf(REG
, address
);
2646 if (setjmp(bus_error_jmp
) == 0) {
2647 catch_memory_errors
= 1;
2649 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2652 /* wait a little while to see if we get a machine check */
2656 catch_memory_errors
= 0;
2659 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2661 printf(" [%s]", modname
);
2663 printf("%s", after
);
2666 #ifdef CONFIG_PPC_BOOK3S_64
2667 static void dump_slb(void)
2670 unsigned long esid
,vsid
,valid
;
2673 printf("SLB contents of cpu %x\n", smp_processor_id());
2675 for (i
= 0; i
< mmu_slb_size
; i
++) {
2676 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2677 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2678 valid
= (esid
& SLB_ESID_V
);
2679 if (valid
| esid
| vsid
) {
2680 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2682 llp
= vsid
& SLB_VSID_LLP
;
2683 if (vsid
& SLB_VSID_B_1T
) {
2684 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2686 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2689 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2691 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2700 static void dump_stab(void)
2703 unsigned long *tmp
= (unsigned long *)local_paca
->stab_addr
;
2705 printf("Segment table contents of cpu %x\n", smp_processor_id());
2707 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2714 printf("%03d %016lx ", i
, a
);
2715 printf("%016lx\n", b
);
2720 void dump_segments(void)
2722 if (mmu_has_feature(MMU_FTR_SLB
))
2729 #ifdef CONFIG_PPC_STD_MMU_32
2730 void dump_segments(void)
2735 for (i
= 0; i
< 16; ++i
)
2736 printf(" %x", mfsrin(i
));
2742 static void dump_tlb_44x(void)
2746 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2747 unsigned long w0
,w1
,w2
;
2748 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2749 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2750 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2751 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2752 if (w0
& PPC44x_TLB_VALID
) {
2753 printf("V %08x -> %01x%08x %c%c%c%c%c",
2754 w0
& PPC44x_TLB_EPN_MASK
,
2755 w1
& PPC44x_TLB_ERPN_MASK
,
2756 w1
& PPC44x_TLB_RPN_MASK
,
2757 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2758 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2759 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2760 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2761 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2766 #endif /* CONFIG_44x */
2768 #ifdef CONFIG_PPC_BOOK3E
2769 static void dump_tlb_book3e(void)
2771 u32 mmucfg
, pidmask
, lpidmask
;
2773 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
2775 static const char *pgsz_names
[] = {
2810 /* Gather some infos about the MMU */
2811 mmucfg
= mfspr(SPRN_MMUCFG
);
2812 mmu_version
= (mmucfg
& 3) + 1;
2813 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
2814 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
2815 lpidsz
= (mmucfg
>> 24) & 0xf;
2816 rasz
= (mmucfg
>> 16) & 0x7f;
2817 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
2819 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2820 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
2821 pidmask
= (1ul << pidsz
) - 1;
2822 lpidmask
= (1ul << lpidsz
) - 1;
2823 ramask
= (1ull << rasz
) - 1;
2825 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
2827 int nent
, assoc
, new_cc
= 1;
2828 printf("TLB %d:\n------\n", tlb
);
2831 tlbcfg
= mfspr(SPRN_TLB0CFG
);
2834 tlbcfg
= mfspr(SPRN_TLB1CFG
);
2837 tlbcfg
= mfspr(SPRN_TLB2CFG
);
2840 tlbcfg
= mfspr(SPRN_TLB3CFG
);
2843 printf("Unsupported TLB number !\n");
2846 nent
= tlbcfg
& 0xfff;
2847 assoc
= (tlbcfg
>> 24) & 0xff;
2848 for (i
= 0; i
< nent
; i
++) {
2849 u32 mas0
= MAS0_TLBSEL(tlb
);
2850 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
2853 int esel
= i
, cc
= i
;
2861 mas0
|= MAS0_ESEL(esel
);
2862 mtspr(SPRN_MAS0
, mas0
);
2863 mtspr(SPRN_MAS1
, mas1
);
2864 mtspr(SPRN_MAS2
, mas2
);
2865 asm volatile("tlbre 0,0,0" : : : "memory");
2866 mas1
= mfspr(SPRN_MAS1
);
2867 mas2
= mfspr(SPRN_MAS2
);
2868 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
2869 if (assoc
&& (i
% assoc
) == 0)
2871 if (!(mas1
& MAS1_VALID
))
2874 printf("%04x- ", i
);
2876 printf("%04x-%c", cc
, 'A' + esel
);
2878 printf(" |%c", 'A' + esel
);
2880 printf(" %016llx %04x %s %c%c AS%c",
2882 (mas1
>> 16) & 0x3fff,
2883 pgsz_names
[(mas1
>> 7) & 0x1f],
2884 mas1
& MAS1_IND
? 'I' : ' ',
2885 mas1
& MAS1_IPROT
? 'P' : ' ',
2886 mas1
& MAS1_TS
? '1' : '0');
2887 printf(" %c%c%c%c%c%c%c",
2888 mas2
& MAS2_X0
? 'a' : ' ',
2889 mas2
& MAS2_X1
? 'v' : ' ',
2890 mas2
& MAS2_W
? 'w' : ' ',
2891 mas2
& MAS2_I
? 'i' : ' ',
2892 mas2
& MAS2_M
? 'm' : ' ',
2893 mas2
& MAS2_G
? 'g' : ' ',
2894 mas2
& MAS2_E
? 'e' : ' ');
2895 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
2896 if (mas1
& MAS1_IND
)
2898 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
2900 printf(" U%c%c%c S%c%c%c\n",
2901 mas7_mas3
& MAS3_UX
? 'x' : ' ',
2902 mas7_mas3
& MAS3_UW
? 'w' : ' ',
2903 mas7_mas3
& MAS3_UR
? 'r' : ' ',
2904 mas7_mas3
& MAS3_SX
? 'x' : ' ',
2905 mas7_mas3
& MAS3_SW
? 'w' : ' ',
2906 mas7_mas3
& MAS3_SR
? 'r' : ' ');
2910 #endif /* CONFIG_PPC_BOOK3E */
2912 static void xmon_init(int enable
)
2916 __debugger_ipi
= xmon_ipi
;
2917 __debugger_bpt
= xmon_bpt
;
2918 __debugger_sstep
= xmon_sstep
;
2919 __debugger_iabr_match
= xmon_iabr_match
;
2920 __debugger_dabr_match
= xmon_dabr_match
;
2921 __debugger_fault_handler
= xmon_fault_handler
;
2924 __debugger_ipi
= NULL
;
2925 __debugger_bpt
= NULL
;
2926 __debugger_sstep
= NULL
;
2927 __debugger_iabr_match
= NULL
;
2928 __debugger_dabr_match
= NULL
;
2929 __debugger_fault_handler
= NULL
;
2933 #ifdef CONFIG_MAGIC_SYSRQ
2934 static void sysrq_handle_xmon(int key
)
2936 /* ensure xmon is enabled */
2938 debugger(get_irq_regs());
2941 static struct sysrq_key_op sysrq_xmon_op
= {
2942 .handler
= sysrq_handle_xmon
,
2944 .action_msg
= "Entering xmon",
2947 static int __init
setup_xmon_sysrq(void)
2949 register_sysrq_key('x', &sysrq_xmon_op
);
2952 __initcall(setup_xmon_sysrq
);
2953 #endif /* CONFIG_MAGIC_SYSRQ */
2955 static int __initdata xmon_early
, xmon_off
;
2957 static int __init
early_parse_xmon(char *p
)
2959 if (!p
|| strncmp(p
, "early", 5) == 0) {
2960 /* just "xmon" is equivalent to "xmon=early" */
2963 } else if (strncmp(p
, "on", 2) == 0)
2965 else if (strncmp(p
, "off", 3) == 0)
2967 else if (strncmp(p
, "nobt", 4) == 0)
2968 xmon_no_auto_backtrace
= 1;
2974 early_param("xmon", early_parse_xmon
);
2976 void __init
xmon_setup(void)
2978 #ifdef CONFIG_XMON_DEFAULT
2986 #ifdef CONFIG_SPU_BASE
2990 u64 saved_mfc_sr1_RW
;
2991 u32 saved_spu_runcntl_RW
;
2992 unsigned long dump_addr
;
2996 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2998 static struct spu_info spu_info
[XMON_NUM_SPUS
];
3000 void xmon_register_spus(struct list_head
*list
)
3004 list_for_each_entry(spu
, list
, full_list
) {
3005 if (spu
->number
>= XMON_NUM_SPUS
) {
3010 spu_info
[spu
->number
].spu
= spu
;
3011 spu_info
[spu
->number
].stopped_ok
= 0;
3012 spu_info
[spu
->number
].dump_addr
= (unsigned long)
3013 spu_info
[spu
->number
].spu
->local_store
;
3017 static void stop_spus(void)
3023 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3024 if (!spu_info
[i
].spu
)
3027 if (setjmp(bus_error_jmp
) == 0) {
3028 catch_memory_errors
= 1;
3031 spu
= spu_info
[i
].spu
;
3033 spu_info
[i
].saved_spu_runcntl_RW
=
3034 in_be32(&spu
->problem
->spu_runcntl_RW
);
3036 tmp
= spu_mfc_sr1_get(spu
);
3037 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
3039 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
3040 spu_mfc_sr1_set(spu
, tmp
);
3045 spu_info
[i
].stopped_ok
= 1;
3047 printf("Stopped spu %.2d (was %s)\n", i
,
3048 spu_info
[i
].saved_spu_runcntl_RW
?
3049 "running" : "stopped");
3051 catch_memory_errors
= 0;
3052 printf("*** Error stopping spu %.2d\n", i
);
3054 catch_memory_errors
= 0;
3058 static void restart_spus(void)
3063 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3064 if (!spu_info
[i
].spu
)
3067 if (!spu_info
[i
].stopped_ok
) {
3068 printf("*** Error, spu %d was not successfully stopped"
3069 ", not restarting\n", i
);
3073 if (setjmp(bus_error_jmp
) == 0) {
3074 catch_memory_errors
= 1;
3077 spu
= spu_info
[i
].spu
;
3078 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
3079 out_be32(&spu
->problem
->spu_runcntl_RW
,
3080 spu_info
[i
].saved_spu_runcntl_RW
);
3085 printf("Restarted spu %.2d\n", i
);
3087 catch_memory_errors
= 0;
3088 printf("*** Error restarting spu %.2d\n", i
);
3090 catch_memory_errors
= 0;
3094 #define DUMP_WIDTH 23
3095 #define DUMP_VALUE(format, field, value) \
3097 if (setjmp(bus_error_jmp) == 0) { \
3098 catch_memory_errors = 1; \
3100 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3105 catch_memory_errors = 0; \
3106 printf(" %-*s = *** Error reading field.\n", \
3107 DUMP_WIDTH, #field); \
3109 catch_memory_errors = 0; \
3112 #define DUMP_FIELD(obj, format, field) \
3113 DUMP_VALUE(format, field, obj->field)
3115 static void dump_spu_fields(struct spu
*spu
)
3117 printf("Dumping spu fields at address %p:\n", spu
);
3119 DUMP_FIELD(spu
, "0x%x", number
);
3120 DUMP_FIELD(spu
, "%s", name
);
3121 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3122 DUMP_FIELD(spu
, "0x%p", local_store
);
3123 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3124 DUMP_FIELD(spu
, "0x%x", node
);
3125 DUMP_FIELD(spu
, "0x%lx", flags
);
3126 DUMP_FIELD(spu
, "%d", class_0_pending
);
3127 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
3128 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
3129 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
3130 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
3131 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
3132 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
3133 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3134 DUMP_FIELD(spu
, "%d", pid
);
3135 DUMP_FIELD(spu
, "0x%p", mm
);
3136 DUMP_FIELD(spu
, "0x%p", ctx
);
3137 DUMP_FIELD(spu
, "0x%p", rq
);
3138 DUMP_FIELD(spu
, "0x%p", timestamp
);
3139 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3140 DUMP_FIELD(spu
, "0x%p", problem
);
3141 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3142 in_be32(&spu
->problem
->spu_runcntl_RW
));
3143 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3144 in_be32(&spu
->problem
->spu_status_R
));
3145 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3146 in_be32(&spu
->problem
->spu_npc_RW
));
3147 DUMP_FIELD(spu
, "0x%p", priv2
);
3148 DUMP_FIELD(spu
, "0x%p", pdata
);
3152 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3154 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3157 static void dump_spu_ls(unsigned long num
, int subcmd
)
3159 unsigned long offset
, addr
, ls_addr
;
3161 if (setjmp(bus_error_jmp
) == 0) {
3162 catch_memory_errors
= 1;
3164 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3168 catch_memory_errors
= 0;
3169 printf("*** Error: accessing spu info for spu %d\n", num
);
3172 catch_memory_errors
= 0;
3174 if (scanhex(&offset
))
3175 addr
= ls_addr
+ offset
;
3177 addr
= spu_info
[num
].dump_addr
;
3179 if (addr
>= ls_addr
+ LS_SIZE
) {
3180 printf("*** Error: address outside of local store\n");
3186 addr
+= spu_inst_dump(addr
, 16, 1);
3196 spu_info
[num
].dump_addr
= addr
;
3199 static int do_spu_cmd(void)
3201 static unsigned long num
= 0;
3202 int cmd
, subcmd
= 0;
3214 if (isxdigit(subcmd
) || subcmd
== '\n')
3218 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3219 printf("*** Error: invalid spu number\n");
3225 dump_spu_fields(spu_info
[num
].spu
);
3228 dump_spu_ls(num
, subcmd
);
3239 #else /* ! CONFIG_SPU_BASE */
3240 static int do_spu_cmd(void)