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>
55 #define scanhex xmon_scanhex
56 #define skipbl xmon_skipbl
59 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
60 static unsigned long xmon_taken
= 1;
61 static int xmon_owner
;
63 #endif /* CONFIG_SMP */
65 static unsigned long in_xmon __read_mostly
= 0;
67 static unsigned long adrs
;
69 #define MAX_DUMP (128 * 1024)
70 static unsigned long ndump
= 64;
71 static unsigned long nidump
= 16;
72 static unsigned long ncsum
= 4096;
74 static char tmpstr
[128];
76 static long bus_error_jmp
[JMP_BUF_LEN
];
77 static int catch_memory_errors
;
78 static long *xmon_fault_jmp
[NR_CPUS
];
80 /* Breakpoint stuff */
82 unsigned long address
;
83 unsigned int instr
[2];
89 /* Bits in bpt.enabled */
90 #define BP_IABR_TE 1 /* IABR translation enabled */
96 static struct bpt bpts
[NBPTS
];
97 static struct bpt dabr
;
98 static struct bpt
*iabr
;
99 static unsigned bpinstr
= 0x7fe00008; /* trap */
101 #define BP_NUM(bp) ((bp) - bpts + 1)
104 static int cmds(struct pt_regs
*);
105 static int mread(unsigned long, void *, int);
106 static int mwrite(unsigned long, void *, int);
107 static int handle_fault(struct pt_regs
*);
108 static void byterev(unsigned char *, int);
109 static void memex(void);
110 static int bsesc(void);
111 static void dump(void);
112 static void prdump(unsigned long, long);
113 static int ppc_inst_dump(unsigned long, long, int);
114 static void dump_log_buf(void);
115 static void backtrace(struct pt_regs
*);
116 static void excprint(struct pt_regs
*);
117 static void prregs(struct pt_regs
*);
118 static void memops(int);
119 static void memlocate(void);
120 static void memzcan(void);
121 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
123 int scanhex(unsigned long *valp
);
124 static void scannl(void);
125 static int hexdigit(int);
126 void getstring(char *, int);
127 static void flush_input(void);
128 static int inchar(void);
129 static void take_input(char *);
130 static unsigned long read_spr(int);
131 static void write_spr(int, unsigned long);
132 static void super_regs(void);
133 static void remove_bpts(void);
134 static void insert_bpts(void);
135 static void remove_cpu_bpts(void);
136 static void insert_cpu_bpts(void);
137 static struct bpt
*at_breakpoint(unsigned long pc
);
138 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
139 static int do_step(struct pt_regs
*);
140 static void bpt_cmds(void);
141 static void cacheflush(void);
142 static int cpu_cmd(void);
143 static void csum(void);
144 static void bootcmds(void);
145 static void proccall(void);
146 void dump_segments(void);
147 static void symbol_lookup(void);
148 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
150 static void xmon_print_symbol(unsigned long address
, const char *mid
,
152 static const char *getvecname(unsigned long vec
);
154 static int do_spu_cmd(void);
157 static void dump_tlb_44x(void);
159 #ifdef CONFIG_PPC_BOOK3E
160 static void dump_tlb_book3e(void);
163 static int xmon_no_auto_backtrace
;
165 extern void xmon_enter(void);
166 extern void xmon_leave(void);
170 #define REGS_PER_LINE 4
171 #define LAST_VOLATILE 13
174 #define REGS_PER_LINE 8
175 #define LAST_VOLATILE 12
178 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
180 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
181 || ('a' <= (c) && (c) <= 'f') \
182 || ('A' <= (c) && (c) <= 'F'))
183 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
184 || ('a' <= (c) && (c) <= 'z') \
185 || ('A' <= (c) && (c) <= 'Z'))
186 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
188 static char *help_string
= "\
190 b show breakpoints\n\
191 bd set data breakpoint\n\
192 bi set instruction breakpoint\n\
193 bc clear breakpoint\n"
196 c print cpus stopped in xmon\n\
197 c# try to switch to cpu number h (in hex)\n"
202 di dump instructions\n\
203 df dump float values\n\
204 dd dump double values\n\
205 dl dump the kernel log buffer\n\
206 dr dump stream of raw bytes\n\
207 e print exception information\n\
209 la lookup symbol+offset of specified address\n\
210 ls lookup address of specified symbol\n\
211 m examine/change memory\n\
212 mm move a block of memory\n\
213 ms set a block of memory\n\
214 md compare two blocks of memory\n\
215 ml locate a block of memory\n\
216 mz zero a block of memory\n\
217 mi show information about memory allocation\n\
218 p call a procedure\n\
221 #ifdef CONFIG_SPU_BASE
222 " ss stop execution on all spus\n\
223 sr restore execution on stopped spus\n\
224 sf # dump spu fields for spu # (in hex)\n\
225 sd # dump spu local store for spu # (in hex)\n\
226 sdi # disassemble spu local store for spu # (in hex)\n"
228 " S print special registers\n\
230 x exit monitor and recover\n\
231 X exit monitor and dont recover\n"
232 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
233 " u dump segment table or SLB\n"
234 #elif defined(CONFIG_PPC_STD_MMU_32)
235 " u dump segment registers\n"
236 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
244 static struct pt_regs
*xmon_regs
;
246 static inline void sync(void)
248 asm volatile("sync; isync");
251 static inline void store_inst(void *p
)
253 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
256 static inline void cflush(void *p
)
258 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
261 static inline void cinval(void *p
)
263 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
267 * Disable surveillance (the service processor watchdog function)
268 * while we are in xmon.
269 * XXX we should re-enable it when we leave. :)
271 #define SURVEILLANCE_TOKEN 9000
273 static inline void disable_surveillance(void)
275 #ifdef CONFIG_PPC_PSERIES
276 /* Since this can't be a module, args should end up below 4GB. */
277 static struct rtas_args args
;
280 * At this point we have got all the cpus we can into
281 * xmon, so there is hopefully no other cpu calling RTAS
282 * at the moment, even though we don't take rtas.lock.
283 * If we did try to take rtas.lock there would be a
284 * real possibility of deadlock.
286 args
.token
= rtas_token("set-indicator");
287 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
291 args
.rets
= &args
.args
[3];
292 args
.args
[0] = SURVEILLANCE_TOKEN
;
295 enter_rtas(__pa(&args
));
296 #endif /* CONFIG_PPC_PSERIES */
300 static int xmon_speaker
;
302 static void get_output_lock(void)
304 int me
= smp_processor_id() + 0x100;
305 int last_speaker
= 0, prev
;
308 if (xmon_speaker
== me
)
311 if (xmon_speaker
== 0) {
312 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
313 if (last_speaker
== 0)
317 while (xmon_speaker
== last_speaker
) {
320 /* hostile takeover */
321 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
322 if (prev
== last_speaker
)
329 static void release_output_lock(void)
334 int cpus_are_in_xmon(void)
336 return !cpumask_empty(&cpus_in_xmon
);
340 static inline int unrecoverable_excp(struct pt_regs
*regs
)
342 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
343 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
346 return ((regs
->msr
& MSR_RI
) == 0);
350 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
354 long recurse_jmp
[JMP_BUF_LEN
];
355 unsigned long offset
;
360 unsigned long timeout
;
363 local_irq_save(flags
);
365 bp
= in_breakpoint_table(regs
->nip
, &offset
);
367 regs
->nip
= bp
->address
+ offset
;
368 atomic_dec(&bp
->ref_count
);
374 cpu
= smp_processor_id();
375 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
378 printf("cpu 0x%x: Exception %lx %s in xmon, "
379 "returning to main loop\n",
380 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
381 release_output_lock();
382 longjmp(xmon_fault_jmp
[cpu
], 1);
385 if (setjmp(recurse_jmp
) != 0) {
386 if (!in_xmon
|| !xmon_gate
) {
388 printf("xmon: WARNING: bad recursive fault "
389 "on cpu 0x%x\n", cpu
);
390 release_output_lock();
393 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
397 xmon_fault_jmp
[cpu
] = recurse_jmp
;
398 cpumask_set_cpu(cpu
, &cpus_in_xmon
);
401 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
))
402 bp
= at_breakpoint(regs
->nip
);
403 if (bp
|| unrecoverable_excp(regs
))
410 printf("cpu 0x%x stopped at breakpoint 0x%x (",
412 xmon_print_symbol(regs
->nip
, " ", ")\n");
414 if (unrecoverable_excp(regs
))
415 printf("WARNING: exception is not recoverable, "
417 release_output_lock();
422 while (secondary
&& !xmon_gate
) {
426 secondary
= test_and_set_bit(0, &in_xmon
);
431 if (!secondary
&& !xmon_gate
) {
432 /* we are the first cpu to come in */
433 /* interrupt other cpu(s) */
434 int ncpus
= num_online_cpus();
439 smp_send_debugger_break();
440 /* wait for other cpus to come in */
441 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
442 if (cpumask_weight(&cpus_in_xmon
) >= ncpus
)
448 disable_surveillance();
449 /* for breakpoint or single step, print the current instr. */
450 if (bp
|| TRAP(regs
) == 0xd00)
451 ppc_inst_dump(regs
->nip
, 1, 0);
452 printf("enter ? for help\n");
461 if (cpu
== xmon_owner
) {
462 if (!test_and_set_bit(0, &xmon_taken
)) {
467 while (cpu
== xmon_owner
)
481 /* have switched to some other cpu */
486 cpumask_clear_cpu(cpu
, &cpus_in_xmon
);
487 xmon_fault_jmp
[cpu
] = NULL
;
489 /* UP is simple... */
491 printf("Exception %lx %s in xmon, returning to main loop\n",
492 regs
->trap
, getvecname(TRAP(regs
)));
493 longjmp(xmon_fault_jmp
[0], 1);
495 if (setjmp(recurse_jmp
) == 0) {
496 xmon_fault_jmp
[0] = recurse_jmp
;
500 bp
= at_breakpoint(regs
->nip
);
502 printf("Stopped at breakpoint %x (", BP_NUM(bp
));
503 xmon_print_symbol(regs
->nip
, " ", ")\n");
505 if (unrecoverable_excp(regs
))
506 printf("WARNING: exception is not recoverable, "
509 disable_surveillance();
510 /* for breakpoint or single step, print the current instr. */
511 if (bp
|| TRAP(regs
) == 0xd00)
512 ppc_inst_dump(regs
->nip
, 1, 0);
513 printf("enter ? for help\n");
523 if (regs
->msr
& MSR_DE
) {
524 bp
= at_breakpoint(regs
->nip
);
526 regs
->nip
= (unsigned long) &bp
->instr
[0];
527 atomic_inc(&bp
->ref_count
);
531 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
532 bp
= at_breakpoint(regs
->nip
);
534 int stepped
= emulate_step(regs
, bp
->instr
[0]);
536 regs
->nip
= (unsigned long) &bp
->instr
[0];
537 atomic_inc(&bp
->ref_count
);
538 } else if (stepped
< 0) {
539 printf("Couldn't single-step %s instruction\n",
540 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
547 local_irq_restore(flags
);
549 return cmd
!= 'X' && cmd
!= EOF
;
552 int xmon(struct pt_regs
*excp
)
557 ppc_save_regs(®s
);
561 return xmon_core(excp
, 0);
565 irqreturn_t
xmon_irq(int irq
, void *d
)
568 local_irq_save(flags
);
569 printf("Keyboard interrupt\n");
570 xmon(get_irq_regs());
571 local_irq_restore(flags
);
575 static int xmon_bpt(struct pt_regs
*regs
)
578 unsigned long offset
;
580 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
583 /* Are we at the trap at bp->instr[1] for some bp? */
584 bp
= in_breakpoint_table(regs
->nip
, &offset
);
585 if (bp
!= NULL
&& offset
== 4) {
586 regs
->nip
= bp
->address
+ 4;
587 atomic_dec(&bp
->ref_count
);
591 /* Are we at a breakpoint? */
592 bp
= at_breakpoint(regs
->nip
);
601 static int xmon_sstep(struct pt_regs
*regs
)
609 static int xmon_dabr_match(struct pt_regs
*regs
)
611 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
613 if (dabr
.enabled
== 0)
619 static int xmon_iabr_match(struct pt_regs
*regs
)
621 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
629 static int xmon_ipi(struct pt_regs
*regs
)
632 if (in_xmon
&& !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon
))
638 static int xmon_fault_handler(struct pt_regs
*regs
)
641 unsigned long offset
;
643 if (in_xmon
&& catch_memory_errors
)
644 handle_fault(regs
); /* doesn't return */
646 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
647 bp
= in_breakpoint_table(regs
->nip
, &offset
);
649 regs
->nip
= bp
->address
+ offset
;
650 atomic_dec(&bp
->ref_count
);
657 static struct bpt
*at_breakpoint(unsigned long pc
)
663 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
664 if (bp
->enabled
&& pc
== bp
->address
)
669 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
673 off
= nip
- (unsigned long) bpts
;
674 if (off
>= sizeof(bpts
))
676 off
%= sizeof(struct bpt
);
677 if (off
!= offsetof(struct bpt
, instr
[0])
678 && off
!= offsetof(struct bpt
, instr
[1]))
680 *offp
= off
- offsetof(struct bpt
, instr
[0]);
681 return (struct bpt
*) (nip
- off
);
684 static struct bpt
*new_breakpoint(unsigned long a
)
689 bp
= at_breakpoint(a
);
693 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
694 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
696 bp
->instr
[1] = bpinstr
;
697 store_inst(&bp
->instr
[1]);
702 printf("Sorry, no free breakpoints. Please clear one first.\n");
706 static void insert_bpts(void)
712 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
713 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
715 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
716 printf("Couldn't read instruction at %lx, "
717 "disabling breakpoint there\n", bp
->address
);
721 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
722 printf("Breakpoint at %lx is on an mtmsrd or rfid "
723 "instruction, disabling it\n", bp
->address
);
727 store_inst(&bp
->instr
[0]);
728 if (bp
->enabled
& BP_IABR
)
730 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
731 printf("Couldn't write instruction at %lx, "
732 "disabling breakpoint there\n", bp
->address
);
733 bp
->enabled
&= ~BP_TRAP
;
736 store_inst((void *)bp
->address
);
740 static void insert_cpu_bpts(void)
743 set_dabr(dabr
.address
| (dabr
.enabled
& 7));
744 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
745 mtspr(SPRN_IABR
, iabr
->address
746 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
749 static void remove_bpts(void)
756 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
757 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
759 if (mread(bp
->address
, &instr
, 4) == 4
761 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
762 printf("Couldn't remove breakpoint at %lx\n",
765 store_inst((void *)bp
->address
);
769 static void remove_cpu_bpts(void)
772 if (cpu_has_feature(CPU_FTR_IABR
))
776 /* Command interpreting routine */
777 static char *last_cmd
;
780 cmds(struct pt_regs
*excp
)
787 if (!xmon_no_auto_backtrace
) {
788 xmon_no_auto_backtrace
= 1;
789 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
794 printf("%x:", smp_processor_id());
795 #endif /* CONFIG_SMP */
801 if (last_cmd
== NULL
)
803 take_input(last_cmd
);
837 prregs(excp
); /* print regs */
852 if (do_spu_cmd() == 0)
861 printf(" <no input ...>\n");
865 xmon_puts(help_string
);
883 #ifdef CONFIG_PPC_STD_MMU
887 #elif defined(CONFIG_4xx)
891 #elif defined(CONFIG_PPC_BOOK3E)
897 printf("Unrecognized command: ");
899 if (' ' < cmd
&& cmd
<= '~')
902 printf("\\x%x", cmd
);
904 } while (cmd
!= '\n');
905 printf(" (type ? for help)\n");
912 static int do_step(struct pt_regs
*regs
)
915 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
920 * Step a single instruction.
921 * Some instructions we emulate, others we execute with MSR_SE set.
923 static int do_step(struct pt_regs
*regs
)
928 /* check we are in 64-bit kernel mode, translation enabled */
929 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
930 if (mread(regs
->nip
, &instr
, 4) == 4) {
931 stepped
= emulate_step(regs
, instr
);
933 printf("Couldn't single-step %s instruction\n",
934 (IS_RFID(instr
)? "rfid": "mtmsrd"));
938 regs
->trap
= 0xd00 | (regs
->trap
& 1);
939 printf("stepped to ");
940 xmon_print_symbol(regs
->nip
, " ", "\n");
941 ppc_inst_dump(regs
->nip
, 1, 0);
951 static void bootcmds(void)
957 ppc_md
.restart(NULL
);
964 static int cpu_cmd(void)
971 if (!scanhex(&cpu
)) {
972 /* print cpus waiting or in xmon */
973 printf("cpus stopped:");
975 for_each_possible_cpu(cpu
) {
976 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
982 printf("-%x", cpu
- 1);
987 printf("-%x", NR_CPUS
- 1);
991 /* try to switch to cpu specified */
992 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
993 printf("cpu 0x%x isn't in xmon\n", cpu
);
1000 while (!xmon_taken
) {
1001 if (--timeout
== 0) {
1002 if (test_and_set_bit(0, &xmon_taken
))
1004 /* take control back */
1006 xmon_owner
= smp_processor_id();
1007 printf("cpu %u didn't take control\n", cpu
);
1015 #endif /* CONFIG_SMP */
1018 static unsigned short fcstab
[256] = {
1019 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1020 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1021 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1022 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1023 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1024 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1025 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1026 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1027 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1028 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1029 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1030 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1031 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1032 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1033 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1034 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1035 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1036 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1037 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1038 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1039 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1040 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1041 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1042 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1043 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1044 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1045 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1046 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1047 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1048 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1049 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1050 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1053 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1062 if (!scanhex(&adrs
))
1064 if (!scanhex(&ncsum
))
1067 for (i
= 0; i
< ncsum
; ++i
) {
1068 if (mread(adrs
+i
, &v
, 1) == 0) {
1069 printf("csum stopped at %x\n", adrs
+i
);
1074 printf("%x\n", fcs
);
1078 * Check if this is a suitable place to put a breakpoint.
1080 static long check_bp_loc(unsigned long addr
)
1085 if (!is_kernel_addr(addr
)) {
1086 printf("Breakpoints may only be placed at kernel addresses\n");
1089 if (!mread(addr
, &instr
, sizeof(instr
))) {
1090 printf("Can't read instruction at address %lx\n", addr
);
1093 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1094 printf("Breakpoints may not be placed on mtmsrd or rfid "
1101 static char *breakpoint_help_string
=
1102 "Breakpoint command usage:\n"
1103 "b show breakpoints\n"
1104 "b <addr> [cnt] set breakpoint at given instr addr\n"
1105 "bc clear all breakpoints\n"
1106 "bc <n/addr> clear breakpoint number n or at addr\n"
1107 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1108 "bd <addr> [cnt] set hardware data breakpoint\n"
1118 const char badaddr
[] = "Only kernel addresses are permitted "
1119 "for breakpoints\n";
1124 case 'd': /* bd - hardware data breakpoint */
1129 else if (cmd
== 'w')
1135 if (scanhex(&dabr
.address
)) {
1136 if (!is_kernel_addr(dabr
.address
)) {
1141 dabr
.enabled
= mode
| BP_DABR
;
1145 case 'i': /* bi - hardware instr breakpoint */
1146 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1147 printf("Hardware instruction breakpoint "
1148 "not supported on this cpu\n");
1152 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1157 if (!check_bp_loc(a
))
1159 bp
= new_breakpoint(a
);
1161 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1169 /* clear all breakpoints */
1170 for (i
= 0; i
< NBPTS
; ++i
)
1171 bpts
[i
].enabled
= 0;
1174 printf("All breakpoints cleared\n");
1178 if (a
<= NBPTS
&& a
>= 1) {
1179 /* assume a breakpoint number */
1180 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1182 /* assume a breakpoint address */
1183 bp
= at_breakpoint(a
);
1185 printf("No breakpoint at %x\n", a
);
1190 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1191 xmon_print_symbol(bp
->address
, " ", ")\n");
1199 printf(breakpoint_help_string
);
1204 /* print all breakpoints */
1205 printf(" type address\n");
1207 printf(" data "REG
" [", dabr
.address
);
1208 if (dabr
.enabled
& 1)
1210 if (dabr
.enabled
& 2)
1214 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1217 printf("%2x %s ", BP_NUM(bp
),
1218 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1219 xmon_print_symbol(bp
->address
, " ", "\n");
1224 if (!check_bp_loc(a
))
1226 bp
= new_breakpoint(a
);
1228 bp
->enabled
|= BP_TRAP
;
1233 /* Very cheap human name for vector lookup. */
1235 const char *getvecname(unsigned long vec
)
1240 case 0x100: ret
= "(System Reset)"; break;
1241 case 0x200: ret
= "(Machine Check)"; break;
1242 case 0x300: ret
= "(Data Access)"; break;
1243 case 0x380: ret
= "(Data SLB Access)"; break;
1244 case 0x400: ret
= "(Instruction Access)"; break;
1245 case 0x480: ret
= "(Instruction SLB Access)"; break;
1246 case 0x500: ret
= "(Hardware Interrupt)"; break;
1247 case 0x600: ret
= "(Alignment)"; break;
1248 case 0x700: ret
= "(Program Check)"; break;
1249 case 0x800: ret
= "(FPU Unavailable)"; break;
1250 case 0x900: ret
= "(Decrementer)"; break;
1251 case 0xc00: ret
= "(System Call)"; break;
1252 case 0xd00: ret
= "(Single Step)"; break;
1253 case 0xf00: ret
= "(Performance Monitor)"; break;
1254 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1255 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1261 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1262 unsigned long *endp
)
1264 unsigned long size
, offset
;
1267 *startp
= *endp
= 0;
1270 if (setjmp(bus_error_jmp
) == 0) {
1271 catch_memory_errors
= 1;
1273 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1275 *startp
= pc
- offset
;
1276 *endp
= pc
- offset
+ size
;
1280 catch_memory_errors
= 0;
1283 static int xmon_depth_to_print
= 64;
1285 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1286 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1288 #ifdef __powerpc64__
1289 #define REGS_OFFSET 0x70
1291 #define REGS_OFFSET 16
1294 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1298 unsigned long newsp
;
1299 unsigned long marker
;
1301 struct pt_regs regs
;
1304 if (sp
< PAGE_OFFSET
) {
1306 printf("SP (%lx) is in userspace\n", sp
);
1310 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1311 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1312 printf("Couldn't read stack frame at %lx\n", sp
);
1317 * For the first stack frame, try to work out if
1318 * LR and/or the saved LR value in the bottommost
1319 * stack frame are valid.
1321 if ((pc
| lr
) != 0) {
1322 unsigned long fnstart
, fnend
;
1323 unsigned long nextip
;
1326 get_function_bounds(pc
, &fnstart
, &fnend
);
1329 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1330 sizeof(unsigned long));
1332 if (lr
< PAGE_OFFSET
1333 || (fnstart
<= lr
&& lr
< fnend
))
1335 } else if (lr
== nextip
) {
1337 } else if (lr
>= PAGE_OFFSET
1338 && !(fnstart
<= lr
&& lr
< fnend
)) {
1339 printf("[link register ] ");
1340 xmon_print_symbol(lr
, " ", "\n");
1343 printf("["REG
"] ", sp
);
1344 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1349 printf("["REG
"] ", sp
);
1350 xmon_print_symbol(ip
, " ", "\n");
1353 /* Look for "regshere" marker to see if this is
1354 an exception frame. */
1355 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1356 && marker
== STACK_FRAME_REGS_MARKER
) {
1357 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1359 printf("Couldn't read registers at %lx\n",
1363 printf("--- Exception: %lx %s at ", regs
.trap
,
1364 getvecname(TRAP(®s
)));
1367 xmon_print_symbol(pc
, " ", "\n");
1374 } while (count
++ < xmon_depth_to_print
);
1377 static void backtrace(struct pt_regs
*excp
)
1382 xmon_show_stack(sp
, 0, 0);
1384 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1388 static void print_bug_trap(struct pt_regs
*regs
)
1391 const struct bug_entry
*bug
;
1394 if (regs
->msr
& MSR_PR
)
1395 return; /* not in kernel */
1396 addr
= regs
->nip
; /* address of trap instruction */
1397 if (addr
< PAGE_OFFSET
)
1399 bug
= find_bug(regs
->nip
);
1402 if (is_warning_bug(bug
))
1405 #ifdef CONFIG_DEBUG_BUGVERBOSE
1406 printf("kernel BUG at %s:%u!\n",
1407 bug
->file
, bug
->line
);
1409 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1411 #endif /* CONFIG_BUG */
1414 static void excprint(struct pt_regs
*fp
)
1419 printf("cpu 0x%x: ", smp_processor_id());
1420 #endif /* CONFIG_SMP */
1423 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1425 xmon_print_symbol(fp
->nip
, ": ", "\n");
1427 printf(" lr: ", fp
->link
);
1428 xmon_print_symbol(fp
->link
, ": ", "\n");
1430 printf(" sp: %lx\n", fp
->gpr
[1]);
1431 printf(" msr: %lx\n", fp
->msr
);
1433 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1434 printf(" dar: %lx\n", fp
->dar
);
1436 printf(" dsisr: %lx\n", fp
->dsisr
);
1439 printf(" current = 0x%lx\n", current
);
1441 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1442 local_paca
, local_paca
->soft_enabled
, local_paca
->irq_happened
);
1445 printf(" pid = %ld, comm = %s\n",
1446 current
->pid
, current
->comm
);
1453 static void prregs(struct pt_regs
*fp
)
1457 struct pt_regs regs
;
1459 if (scanhex(&base
)) {
1460 if (setjmp(bus_error_jmp
) == 0) {
1461 catch_memory_errors
= 1;
1463 regs
= *(struct pt_regs
*)base
;
1467 catch_memory_errors
= 0;
1468 printf("*** Error reading registers from "REG
"\n",
1472 catch_memory_errors
= 0;
1477 if (FULL_REGS(fp
)) {
1478 for (n
= 0; n
< 16; ++n
)
1479 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1480 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1482 for (n
= 0; n
< 7; ++n
)
1483 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1484 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1487 for (n
= 0; n
< 32; ++n
) {
1488 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1489 (n
& 3) == 3? "\n": " ");
1490 if (n
== 12 && !FULL_REGS(fp
)) {
1497 xmon_print_symbol(fp
->nip
, " ", "\n");
1498 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1500 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1503 xmon_print_symbol(fp
->link
, " ", "\n");
1504 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1505 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1506 fp
->ctr
, fp
->xer
, fp
->trap
);
1508 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1509 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1512 static void cacheflush(void)
1515 unsigned long nflush
;
1520 scanhex((void *)&adrs
);
1525 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1526 if (setjmp(bus_error_jmp
) == 0) {
1527 catch_memory_errors
= 1;
1531 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1532 cflush((void *) adrs
);
1534 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1535 cinval((void *) adrs
);
1538 /* wait a little while to see if we get a machine check */
1541 catch_memory_errors
= 0;
1544 static unsigned long
1547 unsigned int instrs
[2];
1548 unsigned long (*code
)(void);
1549 unsigned long ret
= -1UL;
1551 unsigned long opd
[3];
1553 opd
[0] = (unsigned long)instrs
;
1556 code
= (unsigned long (*)(void)) opd
;
1558 code
= (unsigned long (*)(void)) instrs
;
1561 /* mfspr r3,n; blr */
1562 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1563 instrs
[1] = 0x4e800020;
1565 store_inst(instrs
+1);
1567 if (setjmp(bus_error_jmp
) == 0) {
1568 catch_memory_errors
= 1;
1574 /* wait a little while to see if we get a machine check */
1583 write_spr(int n
, unsigned long val
)
1585 unsigned int instrs
[2];
1586 unsigned long (*code
)(unsigned long);
1588 unsigned long opd
[3];
1590 opd
[0] = (unsigned long)instrs
;
1593 code
= (unsigned long (*)(unsigned long)) opd
;
1595 code
= (unsigned long (*)(unsigned long)) instrs
;
1598 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1599 instrs
[1] = 0x4e800020;
1601 store_inst(instrs
+1);
1603 if (setjmp(bus_error_jmp
) == 0) {
1604 catch_memory_errors
= 1;
1610 /* wait a little while to see if we get a machine check */
1616 static unsigned long regno
;
1617 extern char exc_prolog
;
1618 extern char dec_exc
;
1620 static void super_regs(void)
1627 unsigned long sp
, toc
;
1628 asm("mr %0,1" : "=r" (sp
) :);
1629 asm("mr %0,2" : "=r" (toc
) :);
1631 printf("msr = "REG
" sprg0= "REG
"\n",
1632 mfmsr(), mfspr(SPRN_SPRG0
));
1633 printf("pvr = "REG
" sprg1= "REG
"\n",
1634 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1635 printf("dec = "REG
" sprg2= "REG
"\n",
1636 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1637 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1638 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1646 val
= read_spr(regno
);
1648 write_spr(regno
, val
);
1651 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1658 * Stuff for reading and writing memory safely
1661 mread(unsigned long adrs
, void *buf
, int size
)
1667 if (setjmp(bus_error_jmp
) == 0) {
1668 catch_memory_errors
= 1;
1674 *(u16
*)q
= *(u16
*)p
;
1677 *(u32
*)q
= *(u32
*)p
;
1680 *(u64
*)q
= *(u64
*)p
;
1683 for( ; n
< size
; ++n
) {
1689 /* wait a little while to see if we get a machine check */
1693 catch_memory_errors
= 0;
1698 mwrite(unsigned long adrs
, void *buf
, int size
)
1704 if (setjmp(bus_error_jmp
) == 0) {
1705 catch_memory_errors
= 1;
1711 *(u16
*)p
= *(u16
*)q
;
1714 *(u32
*)p
= *(u32
*)q
;
1717 *(u64
*)p
= *(u64
*)q
;
1720 for ( ; n
< size
; ++n
) {
1726 /* wait a little while to see if we get a machine check */
1730 printf("*** Error writing address %x\n", adrs
+ n
);
1732 catch_memory_errors
= 0;
1736 static int fault_type
;
1737 static int fault_except
;
1738 static char *fault_chars
[] = { "--", "**", "##" };
1740 static int handle_fault(struct pt_regs
*regs
)
1742 fault_except
= TRAP(regs
);
1743 switch (TRAP(regs
)) {
1755 longjmp(bus_error_jmp
, 1);
1760 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1763 byterev(unsigned char *val
, int size
)
1769 SWAP(val
[0], val
[1], t
);
1772 SWAP(val
[0], val
[3], t
);
1773 SWAP(val
[1], val
[2], t
);
1775 case 8: /* is there really any use for this? */
1776 SWAP(val
[0], val
[7], t
);
1777 SWAP(val
[1], val
[6], t
);
1778 SWAP(val
[2], val
[5], t
);
1779 SWAP(val
[3], val
[4], t
);
1787 static char *memex_help_string
=
1788 "Memory examine command usage:\n"
1789 "m [addr] [flags] examine/change memory\n"
1790 " addr is optional. will start where left off.\n"
1791 " flags may include chars from this set:\n"
1792 " b modify by bytes (default)\n"
1793 " w modify by words (2 byte)\n"
1794 " l modify by longs (4 byte)\n"
1795 " d modify by doubleword (8 byte)\n"
1796 " r toggle reverse byte order mode\n"
1797 " n do not read memory (for i/o spaces)\n"
1798 " . ok to read (default)\n"
1799 "NOTE: flags are saved as defaults\n"
1802 static char *memex_subcmd_help_string
=
1803 "Memory examine subcommands:\n"
1804 " hexval write this val to current location\n"
1805 " 'string' write chars from string to this location\n"
1806 " ' increment address\n"
1807 " ^ decrement address\n"
1808 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1809 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1810 " ` clear no-read flag\n"
1811 " ; stay at this addr\n"
1812 " v change to byte mode\n"
1813 " w change to word (2 byte) mode\n"
1814 " l change to long (4 byte) mode\n"
1815 " u change to doubleword (8 byte) mode\n"
1816 " m addr change current addr\n"
1817 " n toggle no-read flag\n"
1818 " r toggle byte reverse flag\n"
1819 " < count back up count bytes\n"
1820 " > count skip forward count bytes\n"
1821 " x exit this mode\n"
1827 int cmd
, inc
, i
, nslash
;
1829 unsigned char val
[16];
1831 scanhex((void *)&adrs
);
1834 printf(memex_help_string
);
1840 while ((cmd
= skipbl()) != '\n') {
1842 case 'b': size
= 1; break;
1843 case 'w': size
= 2; break;
1844 case 'l': size
= 4; break;
1845 case 'd': size
= 8; break;
1846 case 'r': brev
= !brev
; break;
1847 case 'n': mnoread
= 1; break;
1848 case '.': mnoread
= 0; break;
1857 n
= mread(adrs
, val
, size
);
1858 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1863 for (i
= 0; i
< n
; ++i
)
1864 printf("%.2x", val
[i
]);
1865 for (; i
< size
; ++i
)
1866 printf("%s", fault_chars
[fault_type
]);
1873 for (i
= 0; i
< size
; ++i
)
1874 val
[i
] = n
>> (i
* 8);
1877 mwrite(adrs
, val
, size
);
1890 else if( n
== '\'' )
1892 for (i
= 0; i
< size
; ++i
)
1893 val
[i
] = n
>> (i
* 8);
1896 mwrite(adrs
, val
, size
);
1933 adrs
-= 1 << nslash
;
1937 adrs
+= 1 << nslash
;
1941 adrs
+= 1 << -nslash
;
1945 adrs
-= 1 << -nslash
;
1948 scanhex((void *)&adrs
);
1967 printf(memex_subcmd_help_string
);
1982 case 'n': c
= '\n'; break;
1983 case 'r': c
= '\r'; break;
1984 case 'b': c
= '\b'; break;
1985 case 't': c
= '\t'; break;
1990 static void xmon_rawdump (unsigned long adrs
, long ndump
)
1993 unsigned char temp
[16];
1995 for (n
= ndump
; n
> 0;) {
1997 nr
= mread(adrs
, temp
, r
);
1999 for (m
= 0; m
< r
; ++m
) {
2001 printf("%.2x", temp
[m
]);
2003 printf("%s", fault_chars
[fault_type
]);
2012 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2013 || ('a' <= (c) && (c) <= 'f') \
2014 || ('A' <= (c) && (c) <= 'F'))
2021 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2023 scanhex((void *)&adrs
);
2030 else if (nidump
> MAX_DUMP
)
2032 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2034 } else if (c
== 'l') {
2036 } else if (c
== 'r') {
2040 xmon_rawdump(adrs
, ndump
);
2047 else if (ndump
> MAX_DUMP
)
2049 prdump(adrs
, ndump
);
2056 prdump(unsigned long adrs
, long ndump
)
2058 long n
, m
, c
, r
, nr
;
2059 unsigned char temp
[16];
2061 for (n
= ndump
; n
> 0;) {
2065 nr
= mread(adrs
, temp
, r
);
2067 for (m
= 0; m
< r
; ++m
) {
2068 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2071 printf("%.2x", temp
[m
]);
2073 printf("%s", fault_chars
[fault_type
]);
2075 for (; m
< 16; ++m
) {
2076 if ((m
& (sizeof(long) - 1)) == 0)
2081 for (m
= 0; m
< r
; ++m
) {
2084 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2097 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2100 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2101 instruction_dump_func dump_func
)
2104 unsigned long first_adr
;
2105 unsigned long inst
, last_inst
= 0;
2106 unsigned char val
[4];
2109 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2110 nr
= mread(adr
, val
, 4);
2113 const char *x
= fault_chars
[fault_type
];
2114 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2118 inst
= GETWORD(val
);
2119 if (adr
> first_adr
&& inst
== last_inst
) {
2129 printf(REG
" %.8x", adr
, inst
);
2131 dump_func(inst
, adr
);
2134 return adr
- first_adr
;
2138 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2140 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2144 print_address(unsigned long addr
)
2146 xmon_print_symbol(addr
, "\t# ", "");
2152 struct kmsg_dumper dumper
= { .active
= 1 };
2153 unsigned char buf
[128];
2156 if (setjmp(bus_error_jmp
) != 0) {
2157 printf("Error dumping printk buffer!\n");
2161 catch_memory_errors
= 1;
2164 kmsg_dump_rewind_nolock(&dumper
);
2165 while (kmsg_dump_get_line_nolock(&dumper
, false, buf
, sizeof(buf
), &len
)) {
2171 /* wait a little while to see if we get a machine check */
2173 catch_memory_errors
= 0;
2177 * Memory operations - move, set, print differences
2179 static unsigned long mdest
; /* destination address */
2180 static unsigned long msrc
; /* source address */
2181 static unsigned long mval
; /* byte value to set memory to */
2182 static unsigned long mcount
; /* # bytes to affect */
2183 static unsigned long mdiffs
; /* max # differences to print */
2188 scanhex((void *)&mdest
);
2189 if( termch
!= '\n' )
2191 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2192 if( termch
!= '\n' )
2194 scanhex((void *)&mcount
);
2197 memmove((void *)mdest
, (void *)msrc
, mcount
);
2200 memset((void *)mdest
, mval
, mcount
);
2203 if( termch
!= '\n' )
2205 scanhex((void *)&mdiffs
);
2206 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2212 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2217 for( n
= nb
; n
> 0; --n
)
2218 if( *p1
++ != *p2
++ )
2219 if( ++prt
<= maxpr
)
2220 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2221 p1
[-1], p2
- 1, p2
[-1]);
2223 printf("Total of %d differences\n", prt
);
2226 static unsigned mend
;
2227 static unsigned mask
;
2233 unsigned char val
[4];
2236 scanhex((void *)&mdest
);
2237 if (termch
!= '\n') {
2239 scanhex((void *)&mend
);
2240 if (termch
!= '\n') {
2242 scanhex((void *)&mval
);
2244 if (termch
!= '\n') termch
= 0;
2245 scanhex((void *)&mask
);
2249 for (a
= mdest
; a
< mend
; a
+= 4) {
2250 if (mread(a
, val
, 4) == 4
2251 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2252 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2259 static unsigned long mskip
= 0x1000;
2260 static unsigned long mlim
= 0xffffffff;
2270 if (termch
!= '\n') termch
= 0;
2272 if (termch
!= '\n') termch
= 0;
2275 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2276 ok
= mread(a
, &v
, 1);
2278 printf("%.8x .. ", a
);
2279 } else if (!ok
&& ook
)
2280 printf("%.8x\n", a
- mskip
);
2286 printf("%.8x\n", a
- mskip
);
2289 static void proccall(void)
2291 unsigned long args
[8];
2294 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2295 unsigned long, unsigned long, unsigned long,
2296 unsigned long, unsigned long, unsigned long);
2299 if (!scanhex(&adrs
))
2303 for (i
= 0; i
< 8; ++i
)
2305 for (i
= 0; i
< 8; ++i
) {
2306 if (!scanhex(&args
[i
]) || termch
== '\n')
2310 func
= (callfunc_t
) adrs
;
2312 if (setjmp(bus_error_jmp
) == 0) {
2313 catch_memory_errors
= 1;
2315 ret
= func(args
[0], args
[1], args
[2], args
[3],
2316 args
[4], args
[5], args
[6], args
[7]);
2318 printf("return value is %x\n", ret
);
2320 printf("*** %x exception occurred\n", fault_except
);
2322 catch_memory_errors
= 0;
2325 /* Input scanning routines */
2336 while( c
== ' ' || c
== '\t' )
2342 static char *regnames
[N_PTREGS
] = {
2343 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2344 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2345 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2346 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2347 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2353 "trap", "dar", "dsisr", "res"
2357 scanhex(unsigned long *vp
)
2364 /* parse register name */
2368 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2377 for (i
= 0; i
< N_PTREGS
; ++i
) {
2378 if (strcmp(regnames
[i
], regname
) == 0) {
2379 if (xmon_regs
== NULL
) {
2380 printf("regs not available\n");
2383 *vp
= ((unsigned long *)xmon_regs
)[i
];
2387 printf("invalid register name '%%%s'\n", regname
);
2391 /* skip leading "0x" if any */
2405 } else if (c
== '$') {
2407 for (i
=0; i
<63; i
++) {
2417 if (setjmp(bus_error_jmp
) == 0) {
2418 catch_memory_errors
= 1;
2420 *vp
= kallsyms_lookup_name(tmpstr
);
2423 catch_memory_errors
= 0;
2425 printf("unknown symbol '%s'\n", tmpstr
);
2458 static int hexdigit(int c
)
2460 if( '0' <= c
&& c
<= '9' )
2462 if( 'A' <= c
&& c
<= 'F' )
2463 return c
- ('A' - 10);
2464 if( 'a' <= c
&& c
<= 'f' )
2465 return c
- ('a' - 10);
2470 getstring(char *s
, int size
)
2481 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2486 static char line
[256];
2487 static char *lineptr
;
2498 if (lineptr
== NULL
|| *lineptr
== 0) {
2499 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2509 take_input(char *str
)
2518 int type
= inchar();
2520 static char tmp
[64];
2525 xmon_print_symbol(addr
, ": ", "\n");
2530 if (setjmp(bus_error_jmp
) == 0) {
2531 catch_memory_errors
= 1;
2533 addr
= kallsyms_lookup_name(tmp
);
2535 printf("%s: %lx\n", tmp
, addr
);
2537 printf("Symbol '%s' not found.\n", tmp
);
2540 catch_memory_errors
= 0;
2547 /* Print an address in numeric and symbolic form (if possible) */
2548 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2552 const char *name
= NULL
;
2553 unsigned long offset
, size
;
2555 printf(REG
, address
);
2556 if (setjmp(bus_error_jmp
) == 0) {
2557 catch_memory_errors
= 1;
2559 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2562 /* wait a little while to see if we get a machine check */
2566 catch_memory_errors
= 0;
2569 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2571 printf(" [%s]", modname
);
2573 printf("%s", after
);
2576 #ifdef CONFIG_PPC_BOOK3S_64
2577 static void dump_slb(void)
2580 unsigned long esid
,vsid
,valid
;
2583 printf("SLB contents of cpu %x\n", smp_processor_id());
2585 for (i
= 0; i
< mmu_slb_size
; i
++) {
2586 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2587 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2588 valid
= (esid
& SLB_ESID_V
);
2589 if (valid
| esid
| vsid
) {
2590 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2592 llp
= vsid
& SLB_VSID_LLP
;
2593 if (vsid
& SLB_VSID_B_1T
) {
2594 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2596 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2599 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2601 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2610 static void dump_stab(void)
2613 unsigned long *tmp
= (unsigned long *)local_paca
->stab_addr
;
2615 printf("Segment table contents of cpu %x\n", smp_processor_id());
2617 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2624 printf("%03d %016lx ", i
, a
);
2625 printf("%016lx\n", b
);
2630 void dump_segments(void)
2632 if (mmu_has_feature(MMU_FTR_SLB
))
2639 #ifdef CONFIG_PPC_STD_MMU_32
2640 void dump_segments(void)
2645 for (i
= 0; i
< 16; ++i
)
2646 printf(" %x", mfsrin(i
));
2652 static void dump_tlb_44x(void)
2656 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2657 unsigned long w0
,w1
,w2
;
2658 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2659 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2660 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2661 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2662 if (w0
& PPC44x_TLB_VALID
) {
2663 printf("V %08x -> %01x%08x %c%c%c%c%c",
2664 w0
& PPC44x_TLB_EPN_MASK
,
2665 w1
& PPC44x_TLB_ERPN_MASK
,
2666 w1
& PPC44x_TLB_RPN_MASK
,
2667 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2668 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2669 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2670 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2671 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2676 #endif /* CONFIG_44x */
2678 #ifdef CONFIG_PPC_BOOK3E
2679 static void dump_tlb_book3e(void)
2681 u32 mmucfg
, pidmask
, lpidmask
;
2683 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
2685 static const char *pgsz_names
[] = {
2720 /* Gather some infos about the MMU */
2721 mmucfg
= mfspr(SPRN_MMUCFG
);
2722 mmu_version
= (mmucfg
& 3) + 1;
2723 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
2724 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
2725 lpidsz
= (mmucfg
>> 24) & 0xf;
2726 rasz
= (mmucfg
>> 16) & 0x7f;
2727 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
2729 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2730 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
2731 pidmask
= (1ul << pidsz
) - 1;
2732 lpidmask
= (1ul << lpidsz
) - 1;
2733 ramask
= (1ull << rasz
) - 1;
2735 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
2737 int nent
, assoc
, new_cc
= 1;
2738 printf("TLB %d:\n------\n", tlb
);
2741 tlbcfg
= mfspr(SPRN_TLB0CFG
);
2744 tlbcfg
= mfspr(SPRN_TLB1CFG
);
2747 tlbcfg
= mfspr(SPRN_TLB2CFG
);
2750 tlbcfg
= mfspr(SPRN_TLB3CFG
);
2753 printf("Unsupported TLB number !\n");
2756 nent
= tlbcfg
& 0xfff;
2757 assoc
= (tlbcfg
>> 24) & 0xff;
2758 for (i
= 0; i
< nent
; i
++) {
2759 u32 mas0
= MAS0_TLBSEL(tlb
);
2760 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
2763 int esel
= i
, cc
= i
;
2771 mas0
|= MAS0_ESEL(esel
);
2772 mtspr(SPRN_MAS0
, mas0
);
2773 mtspr(SPRN_MAS1
, mas1
);
2774 mtspr(SPRN_MAS2
, mas2
);
2775 asm volatile("tlbre 0,0,0" : : : "memory");
2776 mas1
= mfspr(SPRN_MAS1
);
2777 mas2
= mfspr(SPRN_MAS2
);
2778 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
2779 if (assoc
&& (i
% assoc
) == 0)
2781 if (!(mas1
& MAS1_VALID
))
2784 printf("%04x- ", i
);
2786 printf("%04x-%c", cc
, 'A' + esel
);
2788 printf(" |%c", 'A' + esel
);
2790 printf(" %016llx %04x %s %c%c AS%c",
2792 (mas1
>> 16) & 0x3fff,
2793 pgsz_names
[(mas1
>> 7) & 0x1f],
2794 mas1
& MAS1_IND
? 'I' : ' ',
2795 mas1
& MAS1_IPROT
? 'P' : ' ',
2796 mas1
& MAS1_TS
? '1' : '0');
2797 printf(" %c%c%c%c%c%c%c",
2798 mas2
& MAS2_X0
? 'a' : ' ',
2799 mas2
& MAS2_X1
? 'v' : ' ',
2800 mas2
& MAS2_W
? 'w' : ' ',
2801 mas2
& MAS2_I
? 'i' : ' ',
2802 mas2
& MAS2_M
? 'm' : ' ',
2803 mas2
& MAS2_G
? 'g' : ' ',
2804 mas2
& MAS2_E
? 'e' : ' ');
2805 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
2806 if (mas1
& MAS1_IND
)
2808 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
2810 printf(" U%c%c%c S%c%c%c\n",
2811 mas7_mas3
& MAS3_UX
? 'x' : ' ',
2812 mas7_mas3
& MAS3_UW
? 'w' : ' ',
2813 mas7_mas3
& MAS3_UR
? 'r' : ' ',
2814 mas7_mas3
& MAS3_SX
? 'x' : ' ',
2815 mas7_mas3
& MAS3_SW
? 'w' : ' ',
2816 mas7_mas3
& MAS3_SR
? 'r' : ' ');
2820 #endif /* CONFIG_PPC_BOOK3E */
2822 static void xmon_init(int enable
)
2826 __debugger_ipi
= xmon_ipi
;
2827 __debugger_bpt
= xmon_bpt
;
2828 __debugger_sstep
= xmon_sstep
;
2829 __debugger_iabr_match
= xmon_iabr_match
;
2830 __debugger_dabr_match
= xmon_dabr_match
;
2831 __debugger_fault_handler
= xmon_fault_handler
;
2834 __debugger_ipi
= NULL
;
2835 __debugger_bpt
= NULL
;
2836 __debugger_sstep
= NULL
;
2837 __debugger_iabr_match
= NULL
;
2838 __debugger_dabr_match
= NULL
;
2839 __debugger_fault_handler
= NULL
;
2844 #ifdef CONFIG_MAGIC_SYSRQ
2845 static void sysrq_handle_xmon(int key
)
2847 /* ensure xmon is enabled */
2849 debugger(get_irq_regs());
2852 static struct sysrq_key_op sysrq_xmon_op
= {
2853 .handler
= sysrq_handle_xmon
,
2855 .action_msg
= "Entering xmon",
2858 static int __init
setup_xmon_sysrq(void)
2860 register_sysrq_key('x', &sysrq_xmon_op
);
2863 __initcall(setup_xmon_sysrq
);
2864 #endif /* CONFIG_MAGIC_SYSRQ */
2866 static int __initdata xmon_early
, xmon_off
;
2868 static int __init
early_parse_xmon(char *p
)
2870 if (!p
|| strncmp(p
, "early", 5) == 0) {
2871 /* just "xmon" is equivalent to "xmon=early" */
2874 } else if (strncmp(p
, "on", 2) == 0)
2876 else if (strncmp(p
, "off", 3) == 0)
2878 else if (strncmp(p
, "nobt", 4) == 0)
2879 xmon_no_auto_backtrace
= 1;
2885 early_param("xmon", early_parse_xmon
);
2887 void __init
xmon_setup(void)
2889 #ifdef CONFIG_XMON_DEFAULT
2897 #ifdef CONFIG_SPU_BASE
2901 u64 saved_mfc_sr1_RW
;
2902 u32 saved_spu_runcntl_RW
;
2903 unsigned long dump_addr
;
2907 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2909 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2911 void xmon_register_spus(struct list_head
*list
)
2915 list_for_each_entry(spu
, list
, full_list
) {
2916 if (spu
->number
>= XMON_NUM_SPUS
) {
2921 spu_info
[spu
->number
].spu
= spu
;
2922 spu_info
[spu
->number
].stopped_ok
= 0;
2923 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2924 spu_info
[spu
->number
].spu
->local_store
;
2928 static void stop_spus(void)
2934 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2935 if (!spu_info
[i
].spu
)
2938 if (setjmp(bus_error_jmp
) == 0) {
2939 catch_memory_errors
= 1;
2942 spu
= spu_info
[i
].spu
;
2944 spu_info
[i
].saved_spu_runcntl_RW
=
2945 in_be32(&spu
->problem
->spu_runcntl_RW
);
2947 tmp
= spu_mfc_sr1_get(spu
);
2948 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2950 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2951 spu_mfc_sr1_set(spu
, tmp
);
2956 spu_info
[i
].stopped_ok
= 1;
2958 printf("Stopped spu %.2d (was %s)\n", i
,
2959 spu_info
[i
].saved_spu_runcntl_RW
?
2960 "running" : "stopped");
2962 catch_memory_errors
= 0;
2963 printf("*** Error stopping spu %.2d\n", i
);
2965 catch_memory_errors
= 0;
2969 static void restart_spus(void)
2974 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2975 if (!spu_info
[i
].spu
)
2978 if (!spu_info
[i
].stopped_ok
) {
2979 printf("*** Error, spu %d was not successfully stopped"
2980 ", not restarting\n", i
);
2984 if (setjmp(bus_error_jmp
) == 0) {
2985 catch_memory_errors
= 1;
2988 spu
= spu_info
[i
].spu
;
2989 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
2990 out_be32(&spu
->problem
->spu_runcntl_RW
,
2991 spu_info
[i
].saved_spu_runcntl_RW
);
2996 printf("Restarted spu %.2d\n", i
);
2998 catch_memory_errors
= 0;
2999 printf("*** Error restarting spu %.2d\n", i
);
3001 catch_memory_errors
= 0;
3005 #define DUMP_WIDTH 23
3006 #define DUMP_VALUE(format, field, value) \
3008 if (setjmp(bus_error_jmp) == 0) { \
3009 catch_memory_errors = 1; \
3011 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3016 catch_memory_errors = 0; \
3017 printf(" %-*s = *** Error reading field.\n", \
3018 DUMP_WIDTH, #field); \
3020 catch_memory_errors = 0; \
3023 #define DUMP_FIELD(obj, format, field) \
3024 DUMP_VALUE(format, field, obj->field)
3026 static void dump_spu_fields(struct spu
*spu
)
3028 printf("Dumping spu fields at address %p:\n", spu
);
3030 DUMP_FIELD(spu
, "0x%x", number
);
3031 DUMP_FIELD(spu
, "%s", name
);
3032 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3033 DUMP_FIELD(spu
, "0x%p", local_store
);
3034 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3035 DUMP_FIELD(spu
, "0x%x", node
);
3036 DUMP_FIELD(spu
, "0x%lx", flags
);
3037 DUMP_FIELD(spu
, "%d", class_0_pending
);
3038 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
3039 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
3040 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
3041 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
3042 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
3043 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
3044 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3045 DUMP_FIELD(spu
, "%d", pid
);
3046 DUMP_FIELD(spu
, "0x%p", mm
);
3047 DUMP_FIELD(spu
, "0x%p", ctx
);
3048 DUMP_FIELD(spu
, "0x%p", rq
);
3049 DUMP_FIELD(spu
, "0x%p", timestamp
);
3050 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3051 DUMP_FIELD(spu
, "0x%p", problem
);
3052 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3053 in_be32(&spu
->problem
->spu_runcntl_RW
));
3054 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3055 in_be32(&spu
->problem
->spu_status_R
));
3056 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3057 in_be32(&spu
->problem
->spu_npc_RW
));
3058 DUMP_FIELD(spu
, "0x%p", priv2
);
3059 DUMP_FIELD(spu
, "0x%p", pdata
);
3063 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3065 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3068 static void dump_spu_ls(unsigned long num
, int subcmd
)
3070 unsigned long offset
, addr
, ls_addr
;
3072 if (setjmp(bus_error_jmp
) == 0) {
3073 catch_memory_errors
= 1;
3075 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3079 catch_memory_errors
= 0;
3080 printf("*** Error: accessing spu info for spu %d\n", num
);
3083 catch_memory_errors
= 0;
3085 if (scanhex(&offset
))
3086 addr
= ls_addr
+ offset
;
3088 addr
= spu_info
[num
].dump_addr
;
3090 if (addr
>= ls_addr
+ LS_SIZE
) {
3091 printf("*** Error: address outside of local store\n");
3097 addr
+= spu_inst_dump(addr
, 16, 1);
3107 spu_info
[num
].dump_addr
= addr
;
3110 static int do_spu_cmd(void)
3112 static unsigned long num
= 0;
3113 int cmd
, subcmd
= 0;
3125 if (isxdigit(subcmd
) || subcmd
== '\n')
3129 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3130 printf("*** Error: invalid spu number\n");
3136 dump_spu_fields(spu_info
[num
].spu
);
3139 dump_spu_ls(num
, subcmd
);
3150 #else /* ! CONFIG_SPU_BASE */
3151 static int do_spu_cmd(void)