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/cpumask.h>
21 #include <linux/export.h>
22 #include <linux/sysrq.h>
23 #include <linux/interrupt.h>
24 #include <linux/irq.h>
25 #include <linux/bug.h>
27 #include <asm/ptrace.h>
28 #include <asm/string.h>
30 #include <asm/machdep.h>
32 #include <asm/processor.h>
33 #include <asm/pgtable.h>
35 #include <asm/mmu_context.h>
36 #include <asm/cputable.h>
38 #include <asm/sstep.h>
39 #include <asm/irq_regs.h>
41 #include <asm/spu_priv1.h>
42 #include <asm/firmware.h>
43 #include <asm/setjmp.h>
47 #include <asm/hvcall.h>
54 #define scanhex xmon_scanhex
55 #define skipbl xmon_skipbl
58 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
59 static unsigned long xmon_taken
= 1;
60 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);
169 #define REGS_PER_LINE 4
170 #define LAST_VOLATILE 13
173 #define REGS_PER_LINE 8
174 #define LAST_VOLATILE 12
177 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
179 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
180 || ('a' <= (c) && (c) <= 'f') \
181 || ('A' <= (c) && (c) <= 'F'))
182 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
183 || ('a' <= (c) && (c) <= 'z') \
184 || ('A' <= (c) && (c) <= 'Z'))
185 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
187 static char *help_string
= "\
189 b show breakpoints\n\
190 bd set data breakpoint\n\
191 bi set instruction breakpoint\n\
192 bc clear breakpoint\n"
195 c print cpus stopped in xmon\n\
196 c# try to switch to cpu number h (in hex)\n"
201 di dump instructions\n\
202 df dump float values\n\
203 dd dump double values\n\
204 dl dump the kernel log buffer\n\
205 dr dump stream of raw bytes\n\
206 e print exception information\n\
208 la lookup symbol+offset of specified address\n\
209 ls lookup address of specified symbol\n\
210 m examine/change memory\n\
211 mm move a block of memory\n\
212 ms set a block of memory\n\
213 md compare two blocks of memory\n\
214 ml locate a block of memory\n\
215 mz zero a block of memory\n\
216 mi show information about memory allocation\n\
217 p call a procedure\n\
220 #ifdef CONFIG_SPU_BASE
221 " ss stop execution on all spus\n\
222 sr restore execution on stopped spus\n\
223 sf # dump spu fields for spu # (in hex)\n\
224 sd # dump spu local store for spu # (in hex)\n\
225 sdi # disassemble spu local store for spu # (in hex)\n"
227 " S print special registers\n\
229 x exit monitor and recover\n\
230 X exit monitor and dont recover\n"
232 " u dump segment table or SLB\n"
234 #ifdef CONFIG_PPC_STD_MMU_32
235 " u dump segment registers\n"
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
)
344 /* We have no MSR_RI bit on 4xx, 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));
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
894 #ifdef CONFIG_PPC_BOOK3E
900 printf("Unrecognized command: ");
902 if (' ' < cmd
&& cmd
<= '~')
905 printf("\\x%x", cmd
);
907 } while (cmd
!= '\n');
908 printf(" (type ? for help)\n");
915 static int do_step(struct pt_regs
*regs
)
918 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
923 * Step a single instruction.
924 * Some instructions we emulate, others we execute with MSR_SE set.
926 static int do_step(struct pt_regs
*regs
)
931 /* check we are in 64-bit kernel mode, translation enabled */
932 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
933 if (mread(regs
->nip
, &instr
, 4) == 4) {
934 stepped
= emulate_step(regs
, instr
);
936 printf("Couldn't single-step %s instruction\n",
937 (IS_RFID(instr
)? "rfid": "mtmsrd"));
941 regs
->trap
= 0xd00 | (regs
->trap
& 1);
942 printf("stepped to ");
943 xmon_print_symbol(regs
->nip
, " ", "\n");
944 ppc_inst_dump(regs
->nip
, 1, 0);
954 static void bootcmds(void)
960 ppc_md
.restart(NULL
);
967 static int cpu_cmd(void)
974 if (!scanhex(&cpu
)) {
975 /* print cpus waiting or in xmon */
976 printf("cpus stopped:");
978 for (cpu
= 0; cpu
< NR_CPUS
; ++cpu
) {
979 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
985 printf("-%x", cpu
- 1);
990 printf("-%x", NR_CPUS
- 1);
994 /* try to switch to cpu specified */
995 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
996 printf("cpu 0x%x isn't in xmon\n", cpu
);
1003 while (!xmon_taken
) {
1004 if (--timeout
== 0) {
1005 if (test_and_set_bit(0, &xmon_taken
))
1007 /* take control back */
1009 xmon_owner
= smp_processor_id();
1010 printf("cpu %u didn't take control\n", cpu
);
1018 #endif /* CONFIG_SMP */
1021 static unsigned short fcstab
[256] = {
1022 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1023 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1024 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1025 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1026 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1027 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1028 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1029 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1030 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1031 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1032 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1033 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1034 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1035 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1036 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1037 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1038 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1039 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1040 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1041 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1042 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1043 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1044 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1045 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1046 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1047 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1048 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1049 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1050 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1051 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1052 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1053 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1056 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1065 if (!scanhex(&adrs
))
1067 if (!scanhex(&ncsum
))
1070 for (i
= 0; i
< ncsum
; ++i
) {
1071 if (mread(adrs
+i
, &v
, 1) == 0) {
1072 printf("csum stopped at %x\n", adrs
+i
);
1077 printf("%x\n", fcs
);
1081 * Check if this is a suitable place to put a breakpoint.
1083 static long check_bp_loc(unsigned long addr
)
1088 if (!is_kernel_addr(addr
)) {
1089 printf("Breakpoints may only be placed at kernel addresses\n");
1092 if (!mread(addr
, &instr
, sizeof(instr
))) {
1093 printf("Can't read instruction at address %lx\n", addr
);
1096 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1097 printf("Breakpoints may not be placed on mtmsrd or rfid "
1104 static char *breakpoint_help_string
=
1105 "Breakpoint command usage:\n"
1106 "b show breakpoints\n"
1107 "b <addr> [cnt] set breakpoint at given instr addr\n"
1108 "bc clear all breakpoints\n"
1109 "bc <n/addr> clear breakpoint number n or at addr\n"
1110 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1111 "bd <addr> [cnt] set hardware data breakpoint\n"
1121 const char badaddr
[] = "Only kernel addresses are permitted "
1122 "for breakpoints\n";
1127 case 'd': /* bd - hardware data breakpoint */
1132 else if (cmd
== 'w')
1138 if (scanhex(&dabr
.address
)) {
1139 if (!is_kernel_addr(dabr
.address
)) {
1144 dabr
.enabled
= mode
| BP_DABR
;
1148 case 'i': /* bi - hardware instr breakpoint */
1149 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1150 printf("Hardware instruction breakpoint "
1151 "not supported on this cpu\n");
1155 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1160 if (!check_bp_loc(a
))
1162 bp
= new_breakpoint(a
);
1164 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1172 /* clear all breakpoints */
1173 for (i
= 0; i
< NBPTS
; ++i
)
1174 bpts
[i
].enabled
= 0;
1177 printf("All breakpoints cleared\n");
1181 if (a
<= NBPTS
&& a
>= 1) {
1182 /* assume a breakpoint number */
1183 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1185 /* assume a breakpoint address */
1186 bp
= at_breakpoint(a
);
1188 printf("No breakpoint at %x\n", a
);
1193 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1194 xmon_print_symbol(bp
->address
, " ", ")\n");
1202 printf(breakpoint_help_string
);
1207 /* print all breakpoints */
1208 printf(" type address\n");
1210 printf(" data "REG
" [", dabr
.address
);
1211 if (dabr
.enabled
& 1)
1213 if (dabr
.enabled
& 2)
1217 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1220 printf("%2x %s ", BP_NUM(bp
),
1221 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1222 xmon_print_symbol(bp
->address
, " ", "\n");
1227 if (!check_bp_loc(a
))
1229 bp
= new_breakpoint(a
);
1231 bp
->enabled
|= BP_TRAP
;
1236 /* Very cheap human name for vector lookup. */
1238 const char *getvecname(unsigned long vec
)
1243 case 0x100: ret
= "(System Reset)"; break;
1244 case 0x200: ret
= "(Machine Check)"; break;
1245 case 0x300: ret
= "(Data Access)"; break;
1246 case 0x380: ret
= "(Data SLB Access)"; break;
1247 case 0x400: ret
= "(Instruction Access)"; break;
1248 case 0x480: ret
= "(Instruction SLB Access)"; break;
1249 case 0x500: ret
= "(Hardware Interrupt)"; break;
1250 case 0x600: ret
= "(Alignment)"; break;
1251 case 0x700: ret
= "(Program Check)"; break;
1252 case 0x800: ret
= "(FPU Unavailable)"; break;
1253 case 0x900: ret
= "(Decrementer)"; break;
1254 case 0xc00: ret
= "(System Call)"; break;
1255 case 0xd00: ret
= "(Single Step)"; break;
1256 case 0xf00: ret
= "(Performance Monitor)"; break;
1257 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1258 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1264 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1265 unsigned long *endp
)
1267 unsigned long size
, offset
;
1270 *startp
= *endp
= 0;
1273 if (setjmp(bus_error_jmp
) == 0) {
1274 catch_memory_errors
= 1;
1276 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1278 *startp
= pc
- offset
;
1279 *endp
= pc
- offset
+ size
;
1283 catch_memory_errors
= 0;
1286 static int xmon_depth_to_print
= 64;
1288 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1289 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1291 #ifdef __powerpc64__
1292 #define REGS_OFFSET 0x70
1294 #define REGS_OFFSET 16
1297 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1301 unsigned long newsp
;
1302 unsigned long marker
;
1304 struct pt_regs regs
;
1307 if (sp
< PAGE_OFFSET
) {
1309 printf("SP (%lx) is in userspace\n", sp
);
1313 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1314 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1315 printf("Couldn't read stack frame at %lx\n", sp
);
1320 * For the first stack frame, try to work out if
1321 * LR and/or the saved LR value in the bottommost
1322 * stack frame are valid.
1324 if ((pc
| lr
) != 0) {
1325 unsigned long fnstart
, fnend
;
1326 unsigned long nextip
;
1329 get_function_bounds(pc
, &fnstart
, &fnend
);
1332 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1333 sizeof(unsigned long));
1335 if (lr
< PAGE_OFFSET
1336 || (fnstart
<= lr
&& lr
< fnend
))
1338 } else if (lr
== nextip
) {
1340 } else if (lr
>= PAGE_OFFSET
1341 && !(fnstart
<= lr
&& lr
< fnend
)) {
1342 printf("[link register ] ");
1343 xmon_print_symbol(lr
, " ", "\n");
1346 printf("["REG
"] ", sp
);
1347 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1352 printf("["REG
"] ", sp
);
1353 xmon_print_symbol(ip
, " ", "\n");
1356 /* Look for "regshere" marker to see if this is
1357 an exception frame. */
1358 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1359 && marker
== STACK_FRAME_REGS_MARKER
) {
1360 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1362 printf("Couldn't read registers at %lx\n",
1366 printf("--- Exception: %lx %s at ", regs
.trap
,
1367 getvecname(TRAP(®s
)));
1370 xmon_print_symbol(pc
, " ", "\n");
1377 } while (count
++ < xmon_depth_to_print
);
1380 static void backtrace(struct pt_regs
*excp
)
1385 xmon_show_stack(sp
, 0, 0);
1387 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1391 static void print_bug_trap(struct pt_regs
*regs
)
1394 const struct bug_entry
*bug
;
1397 if (regs
->msr
& MSR_PR
)
1398 return; /* not in kernel */
1399 addr
= regs
->nip
; /* address of trap instruction */
1400 if (addr
< PAGE_OFFSET
)
1402 bug
= find_bug(regs
->nip
);
1405 if (is_warning_bug(bug
))
1408 #ifdef CONFIG_DEBUG_BUGVERBOSE
1409 printf("kernel BUG at %s:%u!\n",
1410 bug
->file
, bug
->line
);
1412 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1414 #endif /* CONFIG_BUG */
1417 static void excprint(struct pt_regs
*fp
)
1422 printf("cpu 0x%x: ", smp_processor_id());
1423 #endif /* CONFIG_SMP */
1426 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1428 xmon_print_symbol(fp
->nip
, ": ", "\n");
1430 printf(" lr: ", fp
->link
);
1431 xmon_print_symbol(fp
->link
, ": ", "\n");
1433 printf(" sp: %lx\n", fp
->gpr
[1]);
1434 printf(" msr: %lx\n", fp
->msr
);
1436 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1437 printf(" dar: %lx\n", fp
->dar
);
1439 printf(" dsisr: %lx\n", fp
->dsisr
);
1442 printf(" current = 0x%lx\n", current
);
1444 printf(" paca = 0x%lx\n", get_paca());
1447 printf(" pid = %ld, comm = %s\n",
1448 current
->pid
, current
->comm
);
1455 static void prregs(struct pt_regs
*fp
)
1459 struct pt_regs regs
;
1461 if (scanhex(&base
)) {
1462 if (setjmp(bus_error_jmp
) == 0) {
1463 catch_memory_errors
= 1;
1465 regs
= *(struct pt_regs
*)base
;
1469 catch_memory_errors
= 0;
1470 printf("*** Error reading registers from "REG
"\n",
1474 catch_memory_errors
= 0;
1479 if (FULL_REGS(fp
)) {
1480 for (n
= 0; n
< 16; ++n
)
1481 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1482 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1484 for (n
= 0; n
< 7; ++n
)
1485 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1486 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1489 for (n
= 0; n
< 32; ++n
) {
1490 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1491 (n
& 3) == 3? "\n": " ");
1492 if (n
== 12 && !FULL_REGS(fp
)) {
1499 xmon_print_symbol(fp
->nip
, " ", "\n");
1500 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1502 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1505 xmon_print_symbol(fp
->link
, " ", "\n");
1506 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1507 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1508 fp
->ctr
, fp
->xer
, fp
->trap
);
1510 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1511 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1514 static void cacheflush(void)
1517 unsigned long nflush
;
1522 scanhex((void *)&adrs
);
1527 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1528 if (setjmp(bus_error_jmp
) == 0) {
1529 catch_memory_errors
= 1;
1533 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1534 cflush((void *) adrs
);
1536 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1537 cinval((void *) adrs
);
1540 /* wait a little while to see if we get a machine check */
1543 catch_memory_errors
= 0;
1546 static unsigned long
1549 unsigned int instrs
[2];
1550 unsigned long (*code
)(void);
1551 unsigned long ret
= -1UL;
1553 unsigned long opd
[3];
1555 opd
[0] = (unsigned long)instrs
;
1558 code
= (unsigned long (*)(void)) opd
;
1560 code
= (unsigned long (*)(void)) instrs
;
1563 /* mfspr r3,n; blr */
1564 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1565 instrs
[1] = 0x4e800020;
1567 store_inst(instrs
+1);
1569 if (setjmp(bus_error_jmp
) == 0) {
1570 catch_memory_errors
= 1;
1576 /* wait a little while to see if we get a machine check */
1585 write_spr(int n
, unsigned long val
)
1587 unsigned int instrs
[2];
1588 unsigned long (*code
)(unsigned long);
1590 unsigned long opd
[3];
1592 opd
[0] = (unsigned long)instrs
;
1595 code
= (unsigned long (*)(unsigned long)) opd
;
1597 code
= (unsigned long (*)(unsigned long)) instrs
;
1600 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1601 instrs
[1] = 0x4e800020;
1603 store_inst(instrs
+1);
1605 if (setjmp(bus_error_jmp
) == 0) {
1606 catch_memory_errors
= 1;
1612 /* wait a little while to see if we get a machine check */
1618 static unsigned long regno
;
1619 extern char exc_prolog
;
1620 extern char dec_exc
;
1622 static void super_regs(void)
1629 unsigned long sp
, toc
;
1630 asm("mr %0,1" : "=r" (sp
) :);
1631 asm("mr %0,2" : "=r" (toc
) :);
1633 printf("msr = "REG
" sprg0= "REG
"\n",
1634 mfmsr(), mfspr(SPRN_SPRG0
));
1635 printf("pvr = "REG
" sprg1= "REG
"\n",
1636 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1637 printf("dec = "REG
" sprg2= "REG
"\n",
1638 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1639 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1640 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1641 #ifdef CONFIG_PPC_ISERIES
1642 if (firmware_has_feature(FW_FEATURE_ISERIES
)) {
1643 struct paca_struct
*ptrPaca
;
1644 struct lppaca
*ptrLpPaca
;
1646 /* Dump out relevant Paca data areas. */
1648 ptrPaca
= get_paca();
1650 printf(" Local Processor Control Area (LpPaca): \n");
1651 ptrLpPaca
= ptrPaca
->lppaca_ptr
;
1652 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1653 ptrLpPaca
->saved_srr0
, ptrLpPaca
->saved_srr1
);
1654 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1655 ptrLpPaca
->saved_gpr3
, ptrLpPaca
->saved_gpr4
);
1656 printf(" Saved Gpr5=%.16lx \n",
1657 ptrLpPaca
->gpr5_dword
.saved_gpr5
);
1667 val
= read_spr(regno
);
1669 write_spr(regno
, val
);
1672 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1679 * Stuff for reading and writing memory safely
1682 mread(unsigned long adrs
, void *buf
, int size
)
1688 if (setjmp(bus_error_jmp
) == 0) {
1689 catch_memory_errors
= 1;
1695 *(u16
*)q
= *(u16
*)p
;
1698 *(u32
*)q
= *(u32
*)p
;
1701 *(u64
*)q
= *(u64
*)p
;
1704 for( ; n
< size
; ++n
) {
1710 /* wait a little while to see if we get a machine check */
1714 catch_memory_errors
= 0;
1719 mwrite(unsigned long adrs
, void *buf
, int size
)
1725 if (setjmp(bus_error_jmp
) == 0) {
1726 catch_memory_errors
= 1;
1732 *(u16
*)p
= *(u16
*)q
;
1735 *(u32
*)p
= *(u32
*)q
;
1738 *(u64
*)p
= *(u64
*)q
;
1741 for ( ; n
< size
; ++n
) {
1747 /* wait a little while to see if we get a machine check */
1751 printf("*** Error writing address %x\n", adrs
+ n
);
1753 catch_memory_errors
= 0;
1757 static int fault_type
;
1758 static int fault_except
;
1759 static char *fault_chars
[] = { "--", "**", "##" };
1761 static int handle_fault(struct pt_regs
*regs
)
1763 fault_except
= TRAP(regs
);
1764 switch (TRAP(regs
)) {
1776 longjmp(bus_error_jmp
, 1);
1781 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1784 byterev(unsigned char *val
, int size
)
1790 SWAP(val
[0], val
[1], t
);
1793 SWAP(val
[0], val
[3], t
);
1794 SWAP(val
[1], val
[2], t
);
1796 case 8: /* is there really any use for this? */
1797 SWAP(val
[0], val
[7], t
);
1798 SWAP(val
[1], val
[6], t
);
1799 SWAP(val
[2], val
[5], t
);
1800 SWAP(val
[3], val
[4], t
);
1808 static char *memex_help_string
=
1809 "Memory examine command usage:\n"
1810 "m [addr] [flags] examine/change memory\n"
1811 " addr is optional. will start where left off.\n"
1812 " flags may include chars from this set:\n"
1813 " b modify by bytes (default)\n"
1814 " w modify by words (2 byte)\n"
1815 " l modify by longs (4 byte)\n"
1816 " d modify by doubleword (8 byte)\n"
1817 " r toggle reverse byte order mode\n"
1818 " n do not read memory (for i/o spaces)\n"
1819 " . ok to read (default)\n"
1820 "NOTE: flags are saved as defaults\n"
1823 static char *memex_subcmd_help_string
=
1824 "Memory examine subcommands:\n"
1825 " hexval write this val to current location\n"
1826 " 'string' write chars from string to this location\n"
1827 " ' increment address\n"
1828 " ^ decrement address\n"
1829 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1830 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1831 " ` clear no-read flag\n"
1832 " ; stay at this addr\n"
1833 " v change to byte mode\n"
1834 " w change to word (2 byte) mode\n"
1835 " l change to long (4 byte) mode\n"
1836 " u change to doubleword (8 byte) mode\n"
1837 " m addr change current addr\n"
1838 " n toggle no-read flag\n"
1839 " r toggle byte reverse flag\n"
1840 " < count back up count bytes\n"
1841 " > count skip forward count bytes\n"
1842 " x exit this mode\n"
1848 int cmd
, inc
, i
, nslash
;
1850 unsigned char val
[16];
1852 scanhex((void *)&adrs
);
1855 printf(memex_help_string
);
1861 while ((cmd
= skipbl()) != '\n') {
1863 case 'b': size
= 1; break;
1864 case 'w': size
= 2; break;
1865 case 'l': size
= 4; break;
1866 case 'd': size
= 8; break;
1867 case 'r': brev
= !brev
; break;
1868 case 'n': mnoread
= 1; break;
1869 case '.': mnoread
= 0; break;
1878 n
= mread(adrs
, val
, size
);
1879 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1884 for (i
= 0; i
< n
; ++i
)
1885 printf("%.2x", val
[i
]);
1886 for (; i
< size
; ++i
)
1887 printf("%s", fault_chars
[fault_type
]);
1894 for (i
= 0; i
< size
; ++i
)
1895 val
[i
] = n
>> (i
* 8);
1898 mwrite(adrs
, val
, size
);
1911 else if( n
== '\'' )
1913 for (i
= 0; i
< size
; ++i
)
1914 val
[i
] = n
>> (i
* 8);
1917 mwrite(adrs
, val
, size
);
1954 adrs
-= 1 << nslash
;
1958 adrs
+= 1 << nslash
;
1962 adrs
+= 1 << -nslash
;
1966 adrs
-= 1 << -nslash
;
1969 scanhex((void *)&adrs
);
1988 printf(memex_subcmd_help_string
);
2003 case 'n': c
= '\n'; break;
2004 case 'r': c
= '\r'; break;
2005 case 'b': c
= '\b'; break;
2006 case 't': c
= '\t'; break;
2011 static void xmon_rawdump (unsigned long adrs
, long ndump
)
2014 unsigned char temp
[16];
2016 for (n
= ndump
; n
> 0;) {
2018 nr
= mread(adrs
, temp
, r
);
2020 for (m
= 0; m
< r
; ++m
) {
2022 printf("%.2x", temp
[m
]);
2024 printf("%s", fault_chars
[fault_type
]);
2033 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2034 || ('a' <= (c) && (c) <= 'f') \
2035 || ('A' <= (c) && (c) <= 'F'))
2042 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2044 scanhex((void *)&adrs
);
2051 else if (nidump
> MAX_DUMP
)
2053 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2055 } else if (c
== 'l') {
2057 } else if (c
== 'r') {
2061 xmon_rawdump(adrs
, ndump
);
2068 else if (ndump
> MAX_DUMP
)
2070 prdump(adrs
, ndump
);
2077 prdump(unsigned long adrs
, long ndump
)
2079 long n
, m
, c
, r
, nr
;
2080 unsigned char temp
[16];
2082 for (n
= ndump
; n
> 0;) {
2086 nr
= mread(adrs
, temp
, r
);
2088 for (m
= 0; m
< r
; ++m
) {
2089 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2092 printf("%.2x", temp
[m
]);
2094 printf("%s", fault_chars
[fault_type
]);
2096 for (; m
< 16; ++m
) {
2097 if ((m
& (sizeof(long) - 1)) == 0)
2102 for (m
= 0; m
< r
; ++m
) {
2105 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2118 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2121 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2122 instruction_dump_func dump_func
)
2125 unsigned long first_adr
;
2126 unsigned long inst
, last_inst
= 0;
2127 unsigned char val
[4];
2130 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2131 nr
= mread(adr
, val
, 4);
2134 const char *x
= fault_chars
[fault_type
];
2135 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2139 inst
= GETWORD(val
);
2140 if (adr
> first_adr
&& inst
== last_inst
) {
2150 printf(REG
" %.8x", adr
, inst
);
2152 dump_func(inst
, adr
);
2155 return adr
- first_adr
;
2159 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2161 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2165 print_address(unsigned long addr
)
2167 xmon_print_symbol(addr
, "\t# ", "");
2173 const unsigned long size
= 128;
2174 unsigned long end
, addr
;
2175 unsigned char buf
[size
+ 1];
2180 if (setjmp(bus_error_jmp
) != 0) {
2181 printf("Unable to lookup symbol __log_buf!\n");
2185 catch_memory_errors
= 1;
2187 addr
= kallsyms_lookup_name("__log_buf");
2190 printf("Symbol __log_buf not found!\n");
2192 end
= addr
+ (1 << CONFIG_LOG_BUF_SHIFT
);
2193 while (addr
< end
) {
2194 if (! mread(addr
, buf
, size
)) {
2195 printf("Can't read memory at address 0x%lx\n", addr
);
2201 if (strlen(buf
) < size
)
2209 /* wait a little while to see if we get a machine check */
2211 catch_memory_errors
= 0;
2215 * Memory operations - move, set, print differences
2217 static unsigned long mdest
; /* destination address */
2218 static unsigned long msrc
; /* source address */
2219 static unsigned long mval
; /* byte value to set memory to */
2220 static unsigned long mcount
; /* # bytes to affect */
2221 static unsigned long mdiffs
; /* max # differences to print */
2226 scanhex((void *)&mdest
);
2227 if( termch
!= '\n' )
2229 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2230 if( termch
!= '\n' )
2232 scanhex((void *)&mcount
);
2235 memmove((void *)mdest
, (void *)msrc
, mcount
);
2238 memset((void *)mdest
, mval
, mcount
);
2241 if( termch
!= '\n' )
2243 scanhex((void *)&mdiffs
);
2244 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2250 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2255 for( n
= nb
; n
> 0; --n
)
2256 if( *p1
++ != *p2
++ )
2257 if( ++prt
<= maxpr
)
2258 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2259 p1
[-1], p2
- 1, p2
[-1]);
2261 printf("Total of %d differences\n", prt
);
2264 static unsigned mend
;
2265 static unsigned mask
;
2271 unsigned char val
[4];
2274 scanhex((void *)&mdest
);
2275 if (termch
!= '\n') {
2277 scanhex((void *)&mend
);
2278 if (termch
!= '\n') {
2280 scanhex((void *)&mval
);
2282 if (termch
!= '\n') termch
= 0;
2283 scanhex((void *)&mask
);
2287 for (a
= mdest
; a
< mend
; a
+= 4) {
2288 if (mread(a
, val
, 4) == 4
2289 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2290 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2297 static unsigned long mskip
= 0x1000;
2298 static unsigned long mlim
= 0xffffffff;
2308 if (termch
!= '\n') termch
= 0;
2310 if (termch
!= '\n') termch
= 0;
2313 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2314 ok
= mread(a
, &v
, 1);
2316 printf("%.8x .. ", a
);
2317 } else if (!ok
&& ook
)
2318 printf("%.8x\n", a
- mskip
);
2324 printf("%.8x\n", a
- mskip
);
2327 static void proccall(void)
2329 unsigned long args
[8];
2332 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2333 unsigned long, unsigned long, unsigned long,
2334 unsigned long, unsigned long, unsigned long);
2337 if (!scanhex(&adrs
))
2341 for (i
= 0; i
< 8; ++i
)
2343 for (i
= 0; i
< 8; ++i
) {
2344 if (!scanhex(&args
[i
]) || termch
== '\n')
2348 func
= (callfunc_t
) adrs
;
2350 if (setjmp(bus_error_jmp
) == 0) {
2351 catch_memory_errors
= 1;
2353 ret
= func(args
[0], args
[1], args
[2], args
[3],
2354 args
[4], args
[5], args
[6], args
[7]);
2356 printf("return value is %x\n", ret
);
2358 printf("*** %x exception occurred\n", fault_except
);
2360 catch_memory_errors
= 0;
2363 /* Input scanning routines */
2374 while( c
== ' ' || c
== '\t' )
2380 static char *regnames
[N_PTREGS
] = {
2381 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2382 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2383 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2384 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2385 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2391 "trap", "dar", "dsisr", "res"
2395 scanhex(unsigned long *vp
)
2402 /* parse register name */
2406 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2415 for (i
= 0; i
< N_PTREGS
; ++i
) {
2416 if (strcmp(regnames
[i
], regname
) == 0) {
2417 if (xmon_regs
== NULL
) {
2418 printf("regs not available\n");
2421 *vp
= ((unsigned long *)xmon_regs
)[i
];
2425 printf("invalid register name '%%%s'\n", regname
);
2429 /* skip leading "0x" if any */
2443 } else if (c
== '$') {
2445 for (i
=0; i
<63; i
++) {
2455 if (setjmp(bus_error_jmp
) == 0) {
2456 catch_memory_errors
= 1;
2458 *vp
= kallsyms_lookup_name(tmpstr
);
2461 catch_memory_errors
= 0;
2463 printf("unknown symbol '%s'\n", tmpstr
);
2496 static int hexdigit(int c
)
2498 if( '0' <= c
&& c
<= '9' )
2500 if( 'A' <= c
&& c
<= 'F' )
2501 return c
- ('A' - 10);
2502 if( 'a' <= c
&& c
<= 'f' )
2503 return c
- ('a' - 10);
2508 getstring(char *s
, int size
)
2519 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2524 static char line
[256];
2525 static char *lineptr
;
2536 if (lineptr
== NULL
|| *lineptr
== 0) {
2537 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2547 take_input(char *str
)
2556 int type
= inchar();
2558 static char tmp
[64];
2563 xmon_print_symbol(addr
, ": ", "\n");
2568 if (setjmp(bus_error_jmp
) == 0) {
2569 catch_memory_errors
= 1;
2571 addr
= kallsyms_lookup_name(tmp
);
2573 printf("%s: %lx\n", tmp
, addr
);
2575 printf("Symbol '%s' not found.\n", tmp
);
2578 catch_memory_errors
= 0;
2585 /* Print an address in numeric and symbolic form (if possible) */
2586 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2590 const char *name
= NULL
;
2591 unsigned long offset
, size
;
2593 printf(REG
, address
);
2594 if (setjmp(bus_error_jmp
) == 0) {
2595 catch_memory_errors
= 1;
2597 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2600 /* wait a little while to see if we get a machine check */
2604 catch_memory_errors
= 0;
2607 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2609 printf(" [%s]", modname
);
2611 printf("%s", after
);
2614 #ifdef CONFIG_PPC_BOOK3S_64
2615 static void dump_slb(void)
2618 unsigned long esid
,vsid
,valid
;
2621 printf("SLB contents of cpu %x\n", smp_processor_id());
2623 for (i
= 0; i
< mmu_slb_size
; i
++) {
2624 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2625 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2626 valid
= (esid
& SLB_ESID_V
);
2627 if (valid
| esid
| vsid
) {
2628 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2630 llp
= vsid
& SLB_VSID_LLP
;
2631 if (vsid
& SLB_VSID_B_1T
) {
2632 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2634 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2637 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2639 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2648 static void dump_stab(void)
2651 unsigned long *tmp
= (unsigned long *)get_paca()->stab_addr
;
2653 printf("Segment table contents of cpu %x\n", smp_processor_id());
2655 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2662 printf("%03d %016lx ", i
, a
);
2663 printf("%016lx\n", b
);
2668 void dump_segments(void)
2670 if (mmu_has_feature(MMU_FTR_SLB
))
2677 #ifdef CONFIG_PPC_STD_MMU_32
2678 void dump_segments(void)
2683 for (i
= 0; i
< 16; ++i
)
2684 printf(" %x", mfsrin(i
));
2690 static void dump_tlb_44x(void)
2694 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2695 unsigned long w0
,w1
,w2
;
2696 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2697 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2698 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2699 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2700 if (w0
& PPC44x_TLB_VALID
) {
2701 printf("V %08x -> %01x%08x %c%c%c%c%c",
2702 w0
& PPC44x_TLB_EPN_MASK
,
2703 w1
& PPC44x_TLB_ERPN_MASK
,
2704 w1
& PPC44x_TLB_RPN_MASK
,
2705 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2706 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2707 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2708 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2709 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2714 #endif /* CONFIG_44x */
2716 #ifdef CONFIG_PPC_BOOK3E
2717 static void dump_tlb_book3e(void)
2719 u32 mmucfg
, pidmask
, lpidmask
;
2721 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
2723 static const char *pgsz_names
[] = {
2758 /* Gather some infos about the MMU */
2759 mmucfg
= mfspr(SPRN_MMUCFG
);
2760 mmu_version
= (mmucfg
& 3) + 1;
2761 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
2762 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
2763 lpidsz
= (mmucfg
>> 24) & 0xf;
2764 rasz
= (mmucfg
>> 16) & 0x7f;
2765 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
2767 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2768 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
2769 pidmask
= (1ul << pidsz
) - 1;
2770 lpidmask
= (1ul << lpidsz
) - 1;
2771 ramask
= (1ull << rasz
) - 1;
2773 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
2775 int nent
, assoc
, new_cc
= 1;
2776 printf("TLB %d:\n------\n", tlb
);
2779 tlbcfg
= mfspr(SPRN_TLB0CFG
);
2782 tlbcfg
= mfspr(SPRN_TLB1CFG
);
2785 tlbcfg
= mfspr(SPRN_TLB2CFG
);
2788 tlbcfg
= mfspr(SPRN_TLB3CFG
);
2791 printf("Unsupported TLB number !\n");
2794 nent
= tlbcfg
& 0xfff;
2795 assoc
= (tlbcfg
>> 24) & 0xff;
2796 for (i
= 0; i
< nent
; i
++) {
2797 u32 mas0
= MAS0_TLBSEL(tlb
);
2798 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
2801 int esel
= i
, cc
= i
;
2809 mas0
|= MAS0_ESEL(esel
);
2810 mtspr(SPRN_MAS0
, mas0
);
2811 mtspr(SPRN_MAS1
, mas1
);
2812 mtspr(SPRN_MAS2
, mas2
);
2813 asm volatile("tlbre 0,0,0" : : : "memory");
2814 mas1
= mfspr(SPRN_MAS1
);
2815 mas2
= mfspr(SPRN_MAS2
);
2816 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
2817 if (assoc
&& (i
% assoc
) == 0)
2819 if (!(mas1
& MAS1_VALID
))
2822 printf("%04x- ", i
);
2824 printf("%04x-%c", cc
, 'A' + esel
);
2826 printf(" |%c", 'A' + esel
);
2828 printf(" %016llx %04x %s %c%c AS%c",
2830 (mas1
>> 16) & 0x3fff,
2831 pgsz_names
[(mas1
>> 7) & 0x1f],
2832 mas1
& MAS1_IND
? 'I' : ' ',
2833 mas1
& MAS1_IPROT
? 'P' : ' ',
2834 mas1
& MAS1_TS
? '1' : '0');
2835 printf(" %c%c%c%c%c%c%c",
2836 mas2
& MAS2_X0
? 'a' : ' ',
2837 mas2
& MAS2_X1
? 'v' : ' ',
2838 mas2
& MAS2_W
? 'w' : ' ',
2839 mas2
& MAS2_I
? 'i' : ' ',
2840 mas2
& MAS2_M
? 'm' : ' ',
2841 mas2
& MAS2_G
? 'g' : ' ',
2842 mas2
& MAS2_E
? 'e' : ' ');
2843 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
2844 if (mas1
& MAS1_IND
)
2846 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
2848 printf(" U%c%c%c S%c%c%c\n",
2849 mas7_mas3
& MAS3_UX
? 'x' : ' ',
2850 mas7_mas3
& MAS3_UW
? 'w' : ' ',
2851 mas7_mas3
& MAS3_UR
? 'r' : ' ',
2852 mas7_mas3
& MAS3_SX
? 'x' : ' ',
2853 mas7_mas3
& MAS3_SW
? 'w' : ' ',
2854 mas7_mas3
& MAS3_SR
? 'r' : ' ');
2858 #endif /* CONFIG_PPC_BOOK3E */
2860 static void xmon_init(int enable
)
2862 #ifdef CONFIG_PPC_ISERIES
2863 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2868 __debugger_ipi
= xmon_ipi
;
2869 __debugger_bpt
= xmon_bpt
;
2870 __debugger_sstep
= xmon_sstep
;
2871 __debugger_iabr_match
= xmon_iabr_match
;
2872 __debugger_dabr_match
= xmon_dabr_match
;
2873 __debugger_fault_handler
= xmon_fault_handler
;
2876 __debugger_ipi
= NULL
;
2877 __debugger_bpt
= NULL
;
2878 __debugger_sstep
= NULL
;
2879 __debugger_iabr_match
= NULL
;
2880 __debugger_dabr_match
= NULL
;
2881 __debugger_fault_handler
= NULL
;
2886 #ifdef CONFIG_MAGIC_SYSRQ
2887 static void sysrq_handle_xmon(int key
)
2889 /* ensure xmon is enabled */
2891 debugger(get_irq_regs());
2894 static struct sysrq_key_op sysrq_xmon_op
= {
2895 .handler
= sysrq_handle_xmon
,
2897 .action_msg
= "Entering xmon",
2900 static int __init
setup_xmon_sysrq(void)
2902 #ifdef CONFIG_PPC_ISERIES
2903 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2906 register_sysrq_key('x', &sysrq_xmon_op
);
2909 __initcall(setup_xmon_sysrq
);
2910 #endif /* CONFIG_MAGIC_SYSRQ */
2912 static int __initdata xmon_early
, xmon_off
;
2914 static int __init
early_parse_xmon(char *p
)
2916 if (!p
|| strncmp(p
, "early", 5) == 0) {
2917 /* just "xmon" is equivalent to "xmon=early" */
2920 } else if (strncmp(p
, "on", 2) == 0)
2922 else if (strncmp(p
, "off", 3) == 0)
2924 else if (strncmp(p
, "nobt", 4) == 0)
2925 xmon_no_auto_backtrace
= 1;
2931 early_param("xmon", early_parse_xmon
);
2933 void __init
xmon_setup(void)
2935 #ifdef CONFIG_XMON_DEFAULT
2943 #ifdef CONFIG_SPU_BASE
2947 u64 saved_mfc_sr1_RW
;
2948 u32 saved_spu_runcntl_RW
;
2949 unsigned long dump_addr
;
2953 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2955 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2957 void xmon_register_spus(struct list_head
*list
)
2961 list_for_each_entry(spu
, list
, full_list
) {
2962 if (spu
->number
>= XMON_NUM_SPUS
) {
2967 spu_info
[spu
->number
].spu
= spu
;
2968 spu_info
[spu
->number
].stopped_ok
= 0;
2969 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2970 spu_info
[spu
->number
].spu
->local_store
;
2974 static void stop_spus(void)
2980 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2981 if (!spu_info
[i
].spu
)
2984 if (setjmp(bus_error_jmp
) == 0) {
2985 catch_memory_errors
= 1;
2988 spu
= spu_info
[i
].spu
;
2990 spu_info
[i
].saved_spu_runcntl_RW
=
2991 in_be32(&spu
->problem
->spu_runcntl_RW
);
2993 tmp
= spu_mfc_sr1_get(spu
);
2994 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2996 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2997 spu_mfc_sr1_set(spu
, tmp
);
3002 spu_info
[i
].stopped_ok
= 1;
3004 printf("Stopped spu %.2d (was %s)\n", i
,
3005 spu_info
[i
].saved_spu_runcntl_RW
?
3006 "running" : "stopped");
3008 catch_memory_errors
= 0;
3009 printf("*** Error stopping spu %.2d\n", i
);
3011 catch_memory_errors
= 0;
3015 static void restart_spus(void)
3020 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3021 if (!spu_info
[i
].spu
)
3024 if (!spu_info
[i
].stopped_ok
) {
3025 printf("*** Error, spu %d was not successfully stopped"
3026 ", not restarting\n", i
);
3030 if (setjmp(bus_error_jmp
) == 0) {
3031 catch_memory_errors
= 1;
3034 spu
= spu_info
[i
].spu
;
3035 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
3036 out_be32(&spu
->problem
->spu_runcntl_RW
,
3037 spu_info
[i
].saved_spu_runcntl_RW
);
3042 printf("Restarted spu %.2d\n", i
);
3044 catch_memory_errors
= 0;
3045 printf("*** Error restarting spu %.2d\n", i
);
3047 catch_memory_errors
= 0;
3051 #define DUMP_WIDTH 23
3052 #define DUMP_VALUE(format, field, value) \
3054 if (setjmp(bus_error_jmp) == 0) { \
3055 catch_memory_errors = 1; \
3057 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3062 catch_memory_errors = 0; \
3063 printf(" %-*s = *** Error reading field.\n", \
3064 DUMP_WIDTH, #field); \
3066 catch_memory_errors = 0; \
3069 #define DUMP_FIELD(obj, format, field) \
3070 DUMP_VALUE(format, field, obj->field)
3072 static void dump_spu_fields(struct spu
*spu
)
3074 printf("Dumping spu fields at address %p:\n", spu
);
3076 DUMP_FIELD(spu
, "0x%x", number
);
3077 DUMP_FIELD(spu
, "%s", name
);
3078 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3079 DUMP_FIELD(spu
, "0x%p", local_store
);
3080 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3081 DUMP_FIELD(spu
, "0x%x", node
);
3082 DUMP_FIELD(spu
, "0x%lx", flags
);
3083 DUMP_FIELD(spu
, "%d", class_0_pending
);
3084 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
3085 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
3086 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
3087 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
3088 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
3089 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
3090 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3091 DUMP_FIELD(spu
, "%d", pid
);
3092 DUMP_FIELD(spu
, "0x%p", mm
);
3093 DUMP_FIELD(spu
, "0x%p", ctx
);
3094 DUMP_FIELD(spu
, "0x%p", rq
);
3095 DUMP_FIELD(spu
, "0x%p", timestamp
);
3096 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3097 DUMP_FIELD(spu
, "0x%p", problem
);
3098 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3099 in_be32(&spu
->problem
->spu_runcntl_RW
));
3100 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3101 in_be32(&spu
->problem
->spu_status_R
));
3102 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3103 in_be32(&spu
->problem
->spu_npc_RW
));
3104 DUMP_FIELD(spu
, "0x%p", priv2
);
3105 DUMP_FIELD(spu
, "0x%p", pdata
);
3109 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3111 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3114 static void dump_spu_ls(unsigned long num
, int subcmd
)
3116 unsigned long offset
, addr
, ls_addr
;
3118 if (setjmp(bus_error_jmp
) == 0) {
3119 catch_memory_errors
= 1;
3121 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3125 catch_memory_errors
= 0;
3126 printf("*** Error: accessing spu info for spu %d\n", num
);
3129 catch_memory_errors
= 0;
3131 if (scanhex(&offset
))
3132 addr
= ls_addr
+ offset
;
3134 addr
= spu_info
[num
].dump_addr
;
3136 if (addr
>= ls_addr
+ LS_SIZE
) {
3137 printf("*** Error: address outside of local store\n");
3143 addr
+= spu_inst_dump(addr
, 16, 1);
3153 spu_info
[num
].dump_addr
= addr
;
3156 static int do_spu_cmd(void)
3158 static unsigned long num
= 0;
3159 int cmd
, subcmd
= 0;
3171 if (isxdigit(subcmd
) || subcmd
== '\n')
3175 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3176 printf("*** Error: invalid spu number\n");
3182 dump_spu_fields(spu_info
[num
].spu
);
3185 dump_spu_ls(num
, subcmd
);
3196 #else /* ! CONFIG_SPU_BASE */
3197 static int do_spu_cmd(void)