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>
27 #include <linux/nmi.h>
28 #include <linux/ctype.h>
30 #include <asm/ptrace.h>
31 #include <asm/string.h>
33 #include <asm/machdep.h>
35 #include <asm/processor.h>
36 #include <asm/pgtable.h>
38 #include <asm/mmu_context.h>
39 #include <asm/cputable.h>
41 #include <asm/sstep.h>
42 #include <asm/irq_regs.h>
44 #include <asm/spu_priv1.h>
45 #include <asm/setjmp.h>
47 #include <asm/debug.h>
48 #include <asm/hw_breakpoint.h>
51 #include <asm/hvcall.h>
55 #if defined(CONFIG_PPC_SPLPAR)
56 #include <asm/plpar_wrappers.h>
58 static inline long plapr_set_ciabr(unsigned long ciabr
) {return 0; };
65 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
66 static unsigned long xmon_taken
= 1;
67 static int xmon_owner
;
71 #endif /* CONFIG_SMP */
73 static unsigned long in_xmon __read_mostly
= 0;
75 static unsigned long adrs
;
77 #define MAX_DUMP (128 * 1024)
78 static unsigned long ndump
= 64;
79 static unsigned long nidump
= 16;
80 static unsigned long ncsum
= 4096;
82 static char tmpstr
[128];
84 static long bus_error_jmp
[JMP_BUF_LEN
];
85 static int catch_memory_errors
;
86 static long *xmon_fault_jmp
[NR_CPUS
];
88 /* Breakpoint stuff */
90 unsigned long address
;
91 unsigned int instr
[2];
97 /* Bits in bpt.enabled */
103 static struct bpt bpts
[NBPTS
];
104 static struct bpt dabr
;
105 static struct bpt
*iabr
;
106 static unsigned bpinstr
= 0x7fe00008; /* trap */
108 #define BP_NUM(bp) ((bp) - bpts + 1)
111 static int cmds(struct pt_regs
*);
112 static int mread(unsigned long, void *, int);
113 static int mwrite(unsigned long, void *, int);
114 static int handle_fault(struct pt_regs
*);
115 static void byterev(unsigned char *, int);
116 static void memex(void);
117 static int bsesc(void);
118 static void dump(void);
119 static void prdump(unsigned long, long);
120 static int ppc_inst_dump(unsigned long, long, int);
121 static void dump_log_buf(void);
122 static void backtrace(struct pt_regs
*);
123 static void excprint(struct pt_regs
*);
124 static void prregs(struct pt_regs
*);
125 static void memops(int);
126 static void memlocate(void);
127 static void memzcan(void);
128 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
130 int scanhex(unsigned long *valp
);
131 static void scannl(void);
132 static int hexdigit(int);
133 void getstring(char *, int);
134 static void flush_input(void);
135 static int inchar(void);
136 static void take_input(char *);
137 static unsigned long read_spr(int);
138 static void write_spr(int, unsigned long);
139 static void super_regs(void);
140 static void remove_bpts(void);
141 static void insert_bpts(void);
142 static void remove_cpu_bpts(void);
143 static void insert_cpu_bpts(void);
144 static struct bpt
*at_breakpoint(unsigned long pc
);
145 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
146 static int do_step(struct pt_regs
*);
147 static void bpt_cmds(void);
148 static void cacheflush(void);
149 static int cpu_cmd(void);
150 static void csum(void);
151 static void bootcmds(void);
152 static void proccall(void);
153 void dump_segments(void);
154 static void symbol_lookup(void);
155 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
157 static void xmon_print_symbol(unsigned long address
, const char *mid
,
159 static const char *getvecname(unsigned long vec
);
161 static int do_spu_cmd(void);
164 static void dump_tlb_44x(void);
166 #ifdef CONFIG_PPC_BOOK3E
167 static void dump_tlb_book3e(void);
170 static int xmon_no_auto_backtrace
;
172 extern void xmon_enter(void);
173 extern void xmon_leave(void);
181 #ifdef __LITTLE_ENDIAN__
182 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
184 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
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"
207 dp[#] dump paca for current cpu, or cpu #\n\
208 dpa dump paca for all possible cpus\n"
211 dr dump stream of raw bytes\n\
212 e print exception information\n\
214 la lookup symbol+offset of specified address\n\
215 ls lookup address of specified symbol\n\
216 m examine/change memory\n\
217 mm move a block of memory\n\
218 ms set a block of memory\n\
219 md compare two blocks of memory\n\
220 ml locate a block of memory\n\
221 mz zero a block of memory\n\
222 mi show information about memory allocation\n\
223 p call a procedure\n\
226 #ifdef CONFIG_SPU_BASE
227 " ss stop execution on all spus\n\
228 sr restore execution on stopped spus\n\
229 sf # dump spu fields for spu # (in hex)\n\
230 sd # dump spu local store for spu # (in hex)\n\
231 sdi # disassemble spu local store for spu # (in hex)\n"
233 " S print special registers\n\
235 x exit monitor and recover\n\
236 X exit monitor and dont recover\n"
237 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
238 " u dump segment table or SLB\n"
239 #elif defined(CONFIG_PPC_STD_MMU_32)
240 " u dump segment registers\n"
241 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
249 static struct pt_regs
*xmon_regs
;
251 static inline void sync(void)
253 asm volatile("sync; isync");
256 static inline void store_inst(void *p
)
258 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
261 static inline void cflush(void *p
)
263 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
266 static inline void cinval(void *p
)
268 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
272 * write_ciabr() - write the CIABR SPR
273 * @ciabr: The value to write.
275 * This function writes a value to the CIARB register either directly
276 * through mtspr instruction if the kernel is in HV privilege mode or
277 * call a hypervisor function to achieve the same in case the kernel
278 * is in supervisor privilege mode.
280 static void write_ciabr(unsigned long ciabr
)
282 if (!cpu_has_feature(CPU_FTR_ARCH_207S
))
285 if (cpu_has_feature(CPU_FTR_HVMODE
)) {
286 mtspr(SPRN_CIABR
, ciabr
);
289 plapr_set_ciabr(ciabr
);
293 * set_ciabr() - set the CIABR
294 * @addr: The value to set.
296 * This function sets the correct privilege value into the the HW
297 * breakpoint address before writing it up in the CIABR register.
299 static void set_ciabr(unsigned long addr
)
303 if (cpu_has_feature(CPU_FTR_HVMODE
))
304 addr
|= CIABR_PRIV_HYPER
;
306 addr
|= CIABR_PRIV_SUPER
;
311 * Disable surveillance (the service processor watchdog function)
312 * while we are in xmon.
313 * XXX we should re-enable it when we leave. :)
315 #define SURVEILLANCE_TOKEN 9000
317 static inline void disable_surveillance(void)
319 #ifdef CONFIG_PPC_PSERIES
320 /* Since this can't be a module, args should end up below 4GB. */
321 static struct rtas_args args
;
324 * At this point we have got all the cpus we can into
325 * xmon, so there is hopefully no other cpu calling RTAS
326 * at the moment, even though we don't take rtas.lock.
327 * If we did try to take rtas.lock there would be a
328 * real possibility of deadlock.
330 args
.token
= rtas_token("set-indicator");
331 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
333 args
.token
= cpu_to_be32(args
.token
);
334 args
.nargs
= cpu_to_be32(3);
335 args
.nret
= cpu_to_be32(1);
336 args
.rets
= &args
.args
[3];
337 args
.args
[0] = cpu_to_be32(SURVEILLANCE_TOKEN
);
340 enter_rtas(__pa(&args
));
341 #endif /* CONFIG_PPC_PSERIES */
345 static int xmon_speaker
;
347 static void get_output_lock(void)
349 int me
= smp_processor_id() + 0x100;
350 int last_speaker
= 0, prev
;
353 if (xmon_speaker
== me
)
357 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
358 if (last_speaker
== 0)
362 * Wait a full second for the lock, we might be on a slow
363 * console, but check every 100us.
366 while (xmon_speaker
== last_speaker
) {
372 /* hostile takeover */
373 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
374 if (prev
== last_speaker
)
381 static void release_output_lock(void)
386 int cpus_are_in_xmon(void)
388 return !cpumask_empty(&cpus_in_xmon
);
392 static inline int unrecoverable_excp(struct pt_regs
*regs
)
394 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
395 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
398 return ((regs
->msr
& MSR_RI
) == 0);
402 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
406 long recurse_jmp
[JMP_BUF_LEN
];
407 unsigned long offset
;
412 unsigned long timeout
;
415 local_irq_save(flags
);
418 bp
= in_breakpoint_table(regs
->nip
, &offset
);
420 regs
->nip
= bp
->address
+ offset
;
421 atomic_dec(&bp
->ref_count
);
427 cpu
= smp_processor_id();
428 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
431 printf("cpu 0x%x: Exception %lx %s in xmon, "
432 "returning to main loop\n",
433 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
434 release_output_lock();
435 longjmp(xmon_fault_jmp
[cpu
], 1);
438 if (setjmp(recurse_jmp
) != 0) {
439 if (!in_xmon
|| !xmon_gate
) {
441 printf("xmon: WARNING: bad recursive fault "
442 "on cpu 0x%x\n", cpu
);
443 release_output_lock();
446 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
450 xmon_fault_jmp
[cpu
] = recurse_jmp
;
453 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
))
454 bp
= at_breakpoint(regs
->nip
);
455 if (bp
|| unrecoverable_excp(regs
))
462 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
464 xmon_print_symbol(regs
->nip
, " ", ")\n");
466 if (unrecoverable_excp(regs
))
467 printf("WARNING: exception is not recoverable, "
469 release_output_lock();
472 cpumask_set_cpu(cpu
, &cpus_in_xmon
);
476 while (secondary
&& !xmon_gate
) {
480 secondary
= test_and_set_bit(0, &in_xmon
);
485 if (!secondary
&& !xmon_gate
) {
486 /* we are the first cpu to come in */
487 /* interrupt other cpu(s) */
488 int ncpus
= num_online_cpus();
493 smp_send_debugger_break();
494 /* wait for other cpus to come in */
495 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
496 if (cpumask_weight(&cpus_in_xmon
) >= ncpus
)
502 disable_surveillance();
503 /* for breakpoint or single step, print the current instr. */
504 if (bp
|| TRAP(regs
) == 0xd00)
505 ppc_inst_dump(regs
->nip
, 1, 0);
506 printf("enter ? for help\n");
515 if (cpu
== xmon_owner
) {
516 if (!test_and_set_bit(0, &xmon_taken
)) {
521 while (cpu
== xmon_owner
)
535 /* have switched to some other cpu */
540 cpumask_clear_cpu(cpu
, &cpus_in_xmon
);
541 xmon_fault_jmp
[cpu
] = NULL
;
543 /* UP is simple... */
545 printf("Exception %lx %s in xmon, returning to main loop\n",
546 regs
->trap
, getvecname(TRAP(regs
)));
547 longjmp(xmon_fault_jmp
[0], 1);
549 if (setjmp(recurse_jmp
) == 0) {
550 xmon_fault_jmp
[0] = recurse_jmp
;
554 bp
= at_breakpoint(regs
->nip
);
556 printf("Stopped at breakpoint %lx (", BP_NUM(bp
));
557 xmon_print_symbol(regs
->nip
, " ", ")\n");
559 if (unrecoverable_excp(regs
))
560 printf("WARNING: exception is not recoverable, "
563 disable_surveillance();
564 /* for breakpoint or single step, print the current instr. */
565 if (bp
|| TRAP(regs
) == 0xd00)
566 ppc_inst_dump(regs
->nip
, 1, 0);
567 printf("enter ? for help\n");
577 if (regs
->msr
& MSR_DE
) {
578 bp
= at_breakpoint(regs
->nip
);
580 regs
->nip
= (unsigned long) &bp
->instr
[0];
581 atomic_inc(&bp
->ref_count
);
585 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
586 bp
= at_breakpoint(regs
->nip
);
588 int stepped
= emulate_step(regs
, bp
->instr
[0]);
590 regs
->nip
= (unsigned long) &bp
->instr
[0];
591 atomic_inc(&bp
->ref_count
);
592 } else if (stepped
< 0) {
593 printf("Couldn't single-step %s instruction\n",
594 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
601 touch_nmi_watchdog();
602 local_irq_restore(flags
);
604 return cmd
!= 'X' && cmd
!= EOF
;
607 int xmon(struct pt_regs
*excp
)
612 ppc_save_regs(®s
);
616 return xmon_core(excp
, 0);
620 irqreturn_t
xmon_irq(int irq
, void *d
)
623 local_irq_save(flags
);
624 printf("Keyboard interrupt\n");
625 xmon(get_irq_regs());
626 local_irq_restore(flags
);
630 static int xmon_bpt(struct pt_regs
*regs
)
633 unsigned long offset
;
635 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
638 /* Are we at the trap at bp->instr[1] for some bp? */
639 bp
= in_breakpoint_table(regs
->nip
, &offset
);
640 if (bp
!= NULL
&& offset
== 4) {
641 regs
->nip
= bp
->address
+ 4;
642 atomic_dec(&bp
->ref_count
);
646 /* Are we at a breakpoint? */
647 bp
= at_breakpoint(regs
->nip
);
656 static int xmon_sstep(struct pt_regs
*regs
)
664 static int xmon_break_match(struct pt_regs
*regs
)
666 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
668 if (dabr
.enabled
== 0)
674 static int xmon_iabr_match(struct pt_regs
*regs
)
676 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
684 static int xmon_ipi(struct pt_regs
*regs
)
687 if (in_xmon
&& !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon
))
693 static int xmon_fault_handler(struct pt_regs
*regs
)
696 unsigned long offset
;
698 if (in_xmon
&& catch_memory_errors
)
699 handle_fault(regs
); /* doesn't return */
701 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
702 bp
= in_breakpoint_table(regs
->nip
, &offset
);
704 regs
->nip
= bp
->address
+ offset
;
705 atomic_dec(&bp
->ref_count
);
712 static struct bpt
*at_breakpoint(unsigned long pc
)
718 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
719 if (bp
->enabled
&& pc
== bp
->address
)
724 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
728 off
= nip
- (unsigned long) bpts
;
729 if (off
>= sizeof(bpts
))
731 off
%= sizeof(struct bpt
);
732 if (off
!= offsetof(struct bpt
, instr
[0])
733 && off
!= offsetof(struct bpt
, instr
[1]))
735 *offp
= off
- offsetof(struct bpt
, instr
[0]);
736 return (struct bpt
*) (nip
- off
);
739 static struct bpt
*new_breakpoint(unsigned long a
)
744 bp
= at_breakpoint(a
);
748 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
749 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
751 bp
->instr
[1] = bpinstr
;
752 store_inst(&bp
->instr
[1]);
757 printf("Sorry, no free breakpoints. Please clear one first.\n");
761 static void insert_bpts(void)
767 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
768 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) == 0)
770 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
771 printf("Couldn't read instruction at %lx, "
772 "disabling breakpoint there\n", bp
->address
);
776 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
777 printf("Breakpoint at %lx is on an mtmsrd or rfid "
778 "instruction, disabling it\n", bp
->address
);
782 store_inst(&bp
->instr
[0]);
783 if (bp
->enabled
& BP_CIABR
)
785 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
786 printf("Couldn't write instruction at %lx, "
787 "disabling breakpoint there\n", bp
->address
);
788 bp
->enabled
&= ~BP_TRAP
;
791 store_inst((void *)bp
->address
);
795 static void insert_cpu_bpts(void)
797 struct arch_hw_breakpoint brk
;
800 brk
.address
= dabr
.address
;
801 brk
.type
= (dabr
.enabled
& HW_BRK_TYPE_DABR
) | HW_BRK_TYPE_PRIV_ALL
;
803 __set_breakpoint(&brk
);
807 set_ciabr(iabr
->address
);
810 static void remove_bpts(void)
817 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
818 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) != BP_TRAP
)
820 if (mread(bp
->address
, &instr
, 4) == 4
822 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
823 printf("Couldn't remove breakpoint at %lx\n",
826 store_inst((void *)bp
->address
);
830 static void remove_cpu_bpts(void)
832 hw_breakpoint_disable();
836 /* Command interpreting routine */
837 static char *last_cmd
;
840 cmds(struct pt_regs
*excp
)
847 if (!xmon_no_auto_backtrace
) {
848 xmon_no_auto_backtrace
= 1;
849 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
854 printf("%x:", smp_processor_id());
855 #endif /* CONFIG_SMP */
861 if (last_cmd
== NULL
)
863 take_input(last_cmd
);
897 prregs(excp
); /* print regs */
912 if (do_spu_cmd() == 0)
921 printf(" <no input ...>\n");
925 xmon_puts(help_string
);
943 #ifdef CONFIG_PPC_STD_MMU
947 #elif defined(CONFIG_44x)
951 #elif defined(CONFIG_PPC_BOOK3E)
957 printf("Unrecognized command: ");
959 if (' ' < cmd
&& cmd
<= '~')
962 printf("\\x%x", cmd
);
964 } while (cmd
!= '\n');
965 printf(" (type ? for help)\n");
972 static int do_step(struct pt_regs
*regs
)
975 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
980 * Step a single instruction.
981 * Some instructions we emulate, others we execute with MSR_SE set.
983 static int do_step(struct pt_regs
*regs
)
988 /* check we are in 64-bit kernel mode, translation enabled */
989 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
990 if (mread(regs
->nip
, &instr
, 4) == 4) {
991 stepped
= emulate_step(regs
, instr
);
993 printf("Couldn't single-step %s instruction\n",
994 (IS_RFID(instr
)? "rfid": "mtmsrd"));
998 regs
->trap
= 0xd00 | (regs
->trap
& 1);
999 printf("stepped to ");
1000 xmon_print_symbol(regs
->nip
, " ", "\n");
1001 ppc_inst_dump(regs
->nip
, 1, 0);
1006 regs
->msr
|= MSR_SE
;
1011 static void bootcmds(void)
1017 ppc_md
.restart(NULL
);
1018 else if (cmd
== 'h')
1020 else if (cmd
== 'p')
1025 static int cpu_cmd(void)
1028 unsigned long cpu
, first_cpu
, last_cpu
;
1031 if (!scanhex(&cpu
)) {
1032 /* print cpus waiting or in xmon */
1033 printf("cpus stopped:");
1034 last_cpu
= first_cpu
= NR_CPUS
;
1035 for_each_possible_cpu(cpu
) {
1036 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1037 if (cpu
== last_cpu
+ 1) {
1040 if (last_cpu
!= first_cpu
)
1041 printf("-0x%lx", last_cpu
);
1042 last_cpu
= first_cpu
= cpu
;
1043 printf(" 0x%lx", cpu
);
1047 if (last_cpu
!= first_cpu
)
1048 printf("-0x%lx", last_cpu
);
1052 /* try to switch to cpu specified */
1053 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1054 printf("cpu 0x%x isn't in xmon\n", cpu
);
1061 while (!xmon_taken
) {
1062 if (--timeout
== 0) {
1063 if (test_and_set_bit(0, &xmon_taken
))
1065 /* take control back */
1067 xmon_owner
= smp_processor_id();
1068 printf("cpu 0x%x didn't take control\n", cpu
);
1076 #endif /* CONFIG_SMP */
1079 static unsigned short fcstab
[256] = {
1080 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1081 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1082 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1083 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1084 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1085 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1086 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1087 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1088 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1089 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1090 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1091 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1092 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1093 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1094 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1095 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1096 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1097 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1098 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1099 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1100 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1101 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1102 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1103 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1104 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1105 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1106 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1107 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1108 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1109 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1110 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1111 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1114 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1123 if (!scanhex(&adrs
))
1125 if (!scanhex(&ncsum
))
1128 for (i
= 0; i
< ncsum
; ++i
) {
1129 if (mread(adrs
+i
, &v
, 1) == 0) {
1130 printf("csum stopped at "REG
"\n", adrs
+i
);
1135 printf("%x\n", fcs
);
1139 * Check if this is a suitable place to put a breakpoint.
1141 static long check_bp_loc(unsigned long addr
)
1146 if (!is_kernel_addr(addr
)) {
1147 printf("Breakpoints may only be placed at kernel addresses\n");
1150 if (!mread(addr
, &instr
, sizeof(instr
))) {
1151 printf("Can't read instruction at address %lx\n", addr
);
1154 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1155 printf("Breakpoints may not be placed on mtmsrd or rfid "
1162 static char *breakpoint_help_string
=
1163 "Breakpoint command usage:\n"
1164 "b show breakpoints\n"
1165 "b <addr> [cnt] set breakpoint at given instr addr\n"
1166 "bc clear all breakpoints\n"
1167 "bc <n/addr> clear breakpoint number n or at addr\n"
1168 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1169 "bd <addr> [cnt] set hardware data breakpoint\n"
1179 const char badaddr
[] = "Only kernel addresses are permitted "
1180 "for breakpoints\n";
1185 case 'd': /* bd - hardware data breakpoint */
1190 else if (cmd
== 'w')
1196 if (scanhex(&dabr
.address
)) {
1197 if (!is_kernel_addr(dabr
.address
)) {
1201 dabr
.address
&= ~HW_BRK_TYPE_DABR
;
1202 dabr
.enabled
= mode
| BP_DABR
;
1206 case 'i': /* bi - hardware instr breakpoint */
1207 if (!cpu_has_feature(CPU_FTR_ARCH_207S
)) {
1208 printf("Hardware instruction breakpoint "
1209 "not supported on this cpu\n");
1213 iabr
->enabled
&= ~BP_CIABR
;
1218 if (!check_bp_loc(a
))
1220 bp
= new_breakpoint(a
);
1222 bp
->enabled
|= BP_CIABR
;
1230 /* clear all breakpoints */
1231 for (i
= 0; i
< NBPTS
; ++i
)
1232 bpts
[i
].enabled
= 0;
1235 printf("All breakpoints cleared\n");
1239 if (a
<= NBPTS
&& a
>= 1) {
1240 /* assume a breakpoint number */
1241 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1243 /* assume a breakpoint address */
1244 bp
= at_breakpoint(a
);
1246 printf("No breakpoint at %lx\n", a
);
1251 printf("Cleared breakpoint %lx (", BP_NUM(bp
));
1252 xmon_print_symbol(bp
->address
, " ", ")\n");
1260 printf(breakpoint_help_string
);
1265 /* print all breakpoints */
1266 printf(" type address\n");
1268 printf(" data "REG
" [", dabr
.address
);
1269 if (dabr
.enabled
& 1)
1271 if (dabr
.enabled
& 2)
1275 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1278 printf("%2x %s ", BP_NUM(bp
),
1279 (bp
->enabled
& BP_CIABR
) ? "inst": "trap");
1280 xmon_print_symbol(bp
->address
, " ", "\n");
1285 if (!check_bp_loc(a
))
1287 bp
= new_breakpoint(a
);
1289 bp
->enabled
|= BP_TRAP
;
1294 /* Very cheap human name for vector lookup. */
1296 const char *getvecname(unsigned long vec
)
1301 case 0x100: ret
= "(System Reset)"; break;
1302 case 0x200: ret
= "(Machine Check)"; break;
1303 case 0x300: ret
= "(Data Access)"; break;
1304 case 0x380: ret
= "(Data SLB Access)"; break;
1305 case 0x400: ret
= "(Instruction Access)"; break;
1306 case 0x480: ret
= "(Instruction SLB Access)"; break;
1307 case 0x500: ret
= "(Hardware Interrupt)"; break;
1308 case 0x600: ret
= "(Alignment)"; break;
1309 case 0x700: ret
= "(Program Check)"; break;
1310 case 0x800: ret
= "(FPU Unavailable)"; break;
1311 case 0x900: ret
= "(Decrementer)"; break;
1312 case 0x980: ret
= "(Hypervisor Decrementer)"; break;
1313 case 0xa00: ret
= "(Doorbell)"; break;
1314 case 0xc00: ret
= "(System Call)"; break;
1315 case 0xd00: ret
= "(Single Step)"; break;
1316 case 0xe40: ret
= "(Emulation Assist)"; break;
1317 case 0xe60: ret
= "(HMI)"; break;
1318 case 0xe80: ret
= "(Hypervisor Doorbell)"; break;
1319 case 0xf00: ret
= "(Performance Monitor)"; break;
1320 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1321 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1322 case 0x1500: ret
= "(Denormalisation)"; break;
1323 case 0x1700: ret
= "(Altivec Assist)"; break;
1329 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1330 unsigned long *endp
)
1332 unsigned long size
, offset
;
1335 *startp
= *endp
= 0;
1338 if (setjmp(bus_error_jmp
) == 0) {
1339 catch_memory_errors
= 1;
1341 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1343 *startp
= pc
- offset
;
1344 *endp
= pc
- offset
+ size
;
1348 catch_memory_errors
= 0;
1351 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1352 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1354 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1357 int max_to_print
= 64;
1359 unsigned long newsp
;
1360 unsigned long marker
;
1361 struct pt_regs regs
;
1363 while (max_to_print
--) {
1364 if (sp
< PAGE_OFFSET
) {
1366 printf("SP (%lx) is in userspace\n", sp
);
1370 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1371 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1372 printf("Couldn't read stack frame at %lx\n", sp
);
1377 * For the first stack frame, try to work out if
1378 * LR and/or the saved LR value in the bottommost
1379 * stack frame are valid.
1381 if ((pc
| lr
) != 0) {
1382 unsigned long fnstart
, fnend
;
1383 unsigned long nextip
;
1386 get_function_bounds(pc
, &fnstart
, &fnend
);
1389 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1390 sizeof(unsigned long));
1392 if (lr
< PAGE_OFFSET
1393 || (fnstart
<= lr
&& lr
< fnend
))
1395 } else if (lr
== nextip
) {
1397 } else if (lr
>= PAGE_OFFSET
1398 && !(fnstart
<= lr
&& lr
< fnend
)) {
1399 printf("[link register ] ");
1400 xmon_print_symbol(lr
, " ", "\n");
1403 printf("["REG
"] ", sp
);
1404 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1409 printf("["REG
"] ", sp
);
1410 xmon_print_symbol(ip
, " ", "\n");
1413 /* Look for "regshere" marker to see if this is
1414 an exception frame. */
1415 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1416 && marker
== STACK_FRAME_REGS_MARKER
) {
1417 if (mread(sp
+ STACK_FRAME_OVERHEAD
, ®s
, sizeof(regs
))
1419 printf("Couldn't read registers at %lx\n",
1420 sp
+ STACK_FRAME_OVERHEAD
);
1423 printf("--- Exception: %lx %s at ", regs
.trap
,
1424 getvecname(TRAP(®s
)));
1427 xmon_print_symbol(pc
, " ", "\n");
1437 static void backtrace(struct pt_regs
*excp
)
1442 xmon_show_stack(sp
, 0, 0);
1444 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1448 static void print_bug_trap(struct pt_regs
*regs
)
1451 const struct bug_entry
*bug
;
1454 if (regs
->msr
& MSR_PR
)
1455 return; /* not in kernel */
1456 addr
= regs
->nip
; /* address of trap instruction */
1457 if (addr
< PAGE_OFFSET
)
1459 bug
= find_bug(regs
->nip
);
1462 if (is_warning_bug(bug
))
1465 #ifdef CONFIG_DEBUG_BUGVERBOSE
1466 printf("kernel BUG at %s:%u!\n",
1467 bug
->file
, bug
->line
);
1469 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1471 #endif /* CONFIG_BUG */
1474 static void excprint(struct pt_regs
*fp
)
1479 printf("cpu 0x%x: ", smp_processor_id());
1480 #endif /* CONFIG_SMP */
1483 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1485 xmon_print_symbol(fp
->nip
, ": ", "\n");
1487 printf(" lr: ", fp
->link
);
1488 xmon_print_symbol(fp
->link
, ": ", "\n");
1490 printf(" sp: %lx\n", fp
->gpr
[1]);
1491 printf(" msr: %lx\n", fp
->msr
);
1493 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600 || trap
== 0x200) {
1494 printf(" dar: %lx\n", fp
->dar
);
1496 printf(" dsisr: %lx\n", fp
->dsisr
);
1499 printf(" current = 0x%lx\n", current
);
1501 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1502 local_paca
, local_paca
->soft_enabled
, local_paca
->irq_happened
);
1505 printf(" pid = %ld, comm = %s\n",
1506 current
->pid
, current
->comm
);
1513 static void prregs(struct pt_regs
*fp
)
1517 struct pt_regs regs
;
1519 if (scanhex(&base
)) {
1520 if (setjmp(bus_error_jmp
) == 0) {
1521 catch_memory_errors
= 1;
1523 regs
= *(struct pt_regs
*)base
;
1527 catch_memory_errors
= 0;
1528 printf("*** Error reading registers from "REG
"\n",
1532 catch_memory_errors
= 0;
1537 if (FULL_REGS(fp
)) {
1538 for (n
= 0; n
< 16; ++n
)
1539 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1540 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1542 for (n
= 0; n
< 7; ++n
)
1543 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1544 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1547 for (n
= 0; n
< 32; ++n
) {
1548 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1549 (n
& 3) == 3? "\n": " ");
1550 if (n
== 12 && !FULL_REGS(fp
)) {
1557 xmon_print_symbol(fp
->nip
, " ", "\n");
1558 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1560 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1563 xmon_print_symbol(fp
->link
, " ", "\n");
1564 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1565 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1566 fp
->ctr
, fp
->xer
, fp
->trap
);
1568 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1569 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1572 static void cacheflush(void)
1575 unsigned long nflush
;
1580 scanhex((void *)&adrs
);
1585 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1586 if (setjmp(bus_error_jmp
) == 0) {
1587 catch_memory_errors
= 1;
1591 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1592 cflush((void *) adrs
);
1594 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1595 cinval((void *) adrs
);
1598 /* wait a little while to see if we get a machine check */
1601 catch_memory_errors
= 0;
1604 static unsigned long
1607 unsigned int instrs
[2];
1608 unsigned long (*code
)(void);
1609 unsigned long ret
= -1UL;
1611 unsigned long opd
[3];
1613 opd
[0] = (unsigned long)instrs
;
1616 code
= (unsigned long (*)(void)) opd
;
1618 code
= (unsigned long (*)(void)) instrs
;
1621 /* mfspr r3,n; blr */
1622 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1623 instrs
[1] = 0x4e800020;
1625 store_inst(instrs
+1);
1627 if (setjmp(bus_error_jmp
) == 0) {
1628 catch_memory_errors
= 1;
1634 /* wait a little while to see if we get a machine check */
1643 write_spr(int n
, unsigned long val
)
1645 unsigned int instrs
[2];
1646 unsigned long (*code
)(unsigned long);
1648 unsigned long opd
[3];
1650 opd
[0] = (unsigned long)instrs
;
1653 code
= (unsigned long (*)(unsigned long)) opd
;
1655 code
= (unsigned long (*)(unsigned long)) instrs
;
1658 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1659 instrs
[1] = 0x4e800020;
1661 store_inst(instrs
+1);
1663 if (setjmp(bus_error_jmp
) == 0) {
1664 catch_memory_errors
= 1;
1670 /* wait a little while to see if we get a machine check */
1676 static unsigned long regno
;
1677 extern char exc_prolog
;
1678 extern char dec_exc
;
1680 static void super_regs(void)
1687 unsigned long sp
, toc
;
1688 asm("mr %0,1" : "=r" (sp
) :);
1689 asm("mr %0,2" : "=r" (toc
) :);
1691 printf("msr = "REG
" sprg0= "REG
"\n",
1692 mfmsr(), mfspr(SPRN_SPRG0
));
1693 printf("pvr = "REG
" sprg1= "REG
"\n",
1694 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1695 printf("dec = "REG
" sprg2= "REG
"\n",
1696 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1697 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1698 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1706 val
= read_spr(regno
);
1708 write_spr(regno
, val
);
1711 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1718 * Stuff for reading and writing memory safely
1721 mread(unsigned long adrs
, void *buf
, int size
)
1727 if (setjmp(bus_error_jmp
) == 0) {
1728 catch_memory_errors
= 1;
1734 *(u16
*)q
= *(u16
*)p
;
1737 *(u32
*)q
= *(u32
*)p
;
1740 *(u64
*)q
= *(u64
*)p
;
1743 for( ; n
< size
; ++n
) {
1749 /* wait a little while to see if we get a machine check */
1753 catch_memory_errors
= 0;
1758 mwrite(unsigned long adrs
, void *buf
, int size
)
1764 if (setjmp(bus_error_jmp
) == 0) {
1765 catch_memory_errors
= 1;
1771 *(u16
*)p
= *(u16
*)q
;
1774 *(u32
*)p
= *(u32
*)q
;
1777 *(u64
*)p
= *(u64
*)q
;
1780 for ( ; n
< size
; ++n
) {
1786 /* wait a little while to see if we get a machine check */
1790 printf("*** Error writing address "REG
"\n", adrs
+ n
);
1792 catch_memory_errors
= 0;
1796 static int fault_type
;
1797 static int fault_except
;
1798 static char *fault_chars
[] = { "--", "**", "##" };
1800 static int handle_fault(struct pt_regs
*regs
)
1802 fault_except
= TRAP(regs
);
1803 switch (TRAP(regs
)) {
1815 longjmp(bus_error_jmp
, 1);
1820 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1823 byterev(unsigned char *val
, int size
)
1829 SWAP(val
[0], val
[1], t
);
1832 SWAP(val
[0], val
[3], t
);
1833 SWAP(val
[1], val
[2], t
);
1835 case 8: /* is there really any use for this? */
1836 SWAP(val
[0], val
[7], t
);
1837 SWAP(val
[1], val
[6], t
);
1838 SWAP(val
[2], val
[5], t
);
1839 SWAP(val
[3], val
[4], t
);
1847 static char *memex_help_string
=
1848 "Memory examine command usage:\n"
1849 "m [addr] [flags] examine/change memory\n"
1850 " addr is optional. will start where left off.\n"
1851 " flags may include chars from this set:\n"
1852 " b modify by bytes (default)\n"
1853 " w modify by words (2 byte)\n"
1854 " l modify by longs (4 byte)\n"
1855 " d modify by doubleword (8 byte)\n"
1856 " r toggle reverse byte order mode\n"
1857 " n do not read memory (for i/o spaces)\n"
1858 " . ok to read (default)\n"
1859 "NOTE: flags are saved as defaults\n"
1862 static char *memex_subcmd_help_string
=
1863 "Memory examine subcommands:\n"
1864 " hexval write this val to current location\n"
1865 " 'string' write chars from string to this location\n"
1866 " ' increment address\n"
1867 " ^ decrement address\n"
1868 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1869 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1870 " ` clear no-read flag\n"
1871 " ; stay at this addr\n"
1872 " v change to byte mode\n"
1873 " w change to word (2 byte) mode\n"
1874 " l change to long (4 byte) mode\n"
1875 " u change to doubleword (8 byte) mode\n"
1876 " m addr change current addr\n"
1877 " n toggle no-read flag\n"
1878 " r toggle byte reverse flag\n"
1879 " < count back up count bytes\n"
1880 " > count skip forward count bytes\n"
1881 " x exit this mode\n"
1887 int cmd
, inc
, i
, nslash
;
1889 unsigned char val
[16];
1891 scanhex((void *)&adrs
);
1894 printf(memex_help_string
);
1900 while ((cmd
= skipbl()) != '\n') {
1902 case 'b': size
= 1; break;
1903 case 'w': size
= 2; break;
1904 case 'l': size
= 4; break;
1905 case 'd': size
= 8; break;
1906 case 'r': brev
= !brev
; break;
1907 case 'n': mnoread
= 1; break;
1908 case '.': mnoread
= 0; break;
1917 n
= mread(adrs
, val
, size
);
1918 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1923 for (i
= 0; i
< n
; ++i
)
1924 printf("%.2x", val
[i
]);
1925 for (; i
< size
; ++i
)
1926 printf("%s", fault_chars
[fault_type
]);
1933 for (i
= 0; i
< size
; ++i
)
1934 val
[i
] = n
>> (i
* 8);
1937 mwrite(adrs
, val
, size
);
1950 else if( n
== '\'' )
1952 for (i
= 0; i
< size
; ++i
)
1953 val
[i
] = n
>> (i
* 8);
1956 mwrite(adrs
, val
, size
);
1993 adrs
-= 1 << nslash
;
1997 adrs
+= 1 << nslash
;
2001 adrs
+= 1 << -nslash
;
2005 adrs
-= 1 << -nslash
;
2008 scanhex((void *)&adrs
);
2027 printf(memex_subcmd_help_string
);
2042 case 'n': c
= '\n'; break;
2043 case 'r': c
= '\r'; break;
2044 case 'b': c
= '\b'; break;
2045 case 't': c
= '\t'; break;
2050 static void xmon_rawdump (unsigned long adrs
, long ndump
)
2053 unsigned char temp
[16];
2055 for (n
= ndump
; n
> 0;) {
2057 nr
= mread(adrs
, temp
, r
);
2059 for (m
= 0; m
< r
; ++m
) {
2061 printf("%.2x", temp
[m
]);
2063 printf("%s", fault_chars
[fault_type
]);
2073 static void dump_one_paca(int cpu
)
2075 struct paca_struct
*p
;
2077 if (setjmp(bus_error_jmp
) != 0) {
2078 printf("*** Error dumping paca for cpu 0x%x!\n", cpu
);
2082 catch_memory_errors
= 1;
2087 printf("paca for cpu 0x%x @ %p:\n", cpu
, p
);
2089 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu
) ? "yes" : "no");
2090 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu
) ? "yes" : "no");
2091 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu
) ? "yes" : "no");
2093 #define DUMP(paca, name, format) \
2094 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2095 offsetof(struct paca_struct, name));
2097 DUMP(p
, lock_token
, "x");
2098 DUMP(p
, paca_index
, "x");
2099 DUMP(p
, kernel_toc
, "lx");
2100 DUMP(p
, kernelbase
, "lx");
2101 DUMP(p
, kernel_msr
, "lx");
2102 DUMP(p
, emergency_sp
, "p");
2103 #ifdef CONFIG_PPC_BOOK3S_64
2104 DUMP(p
, mc_emergency_sp
, "p");
2105 DUMP(p
, in_mce
, "x");
2107 DUMP(p
, data_offset
, "lx");
2108 DUMP(p
, hw_cpu_id
, "x");
2109 DUMP(p
, cpu_start
, "x");
2110 DUMP(p
, kexec_state
, "x");
2111 DUMP(p
, __current
, "p");
2112 DUMP(p
, kstack
, "lx");
2113 DUMP(p
, stab_rr
, "lx");
2114 DUMP(p
, saved_r1
, "lx");
2115 DUMP(p
, trap_save
, "x");
2116 DUMP(p
, soft_enabled
, "x");
2117 DUMP(p
, irq_happened
, "x");
2118 DUMP(p
, io_sync
, "x");
2119 DUMP(p
, irq_work_pending
, "x");
2120 DUMP(p
, nap_state_lost
, "x");
2124 catch_memory_errors
= 0;
2128 static void dump_all_pacas(void)
2132 if (num_possible_cpus() == 0) {
2133 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2137 for_each_possible_cpu(cpu
)
2141 static void dump_pacas(void)
2152 termch
= c
; /* Put c back, it wasn't 'a' */
2157 dump_one_paca(xmon_owner
);
2175 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2177 scanhex((void *)&adrs
);
2184 else if (nidump
> MAX_DUMP
)
2186 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2188 } else if (c
== 'l') {
2190 } else if (c
== 'r') {
2194 xmon_rawdump(adrs
, ndump
);
2201 else if (ndump
> MAX_DUMP
)
2203 prdump(adrs
, ndump
);
2210 prdump(unsigned long adrs
, long ndump
)
2212 long n
, m
, c
, r
, nr
;
2213 unsigned char temp
[16];
2215 for (n
= ndump
; n
> 0;) {
2219 nr
= mread(adrs
, temp
, r
);
2221 for (m
= 0; m
< r
; ++m
) {
2222 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2225 printf("%.2x", temp
[m
]);
2227 printf("%s", fault_chars
[fault_type
]);
2229 for (; m
< 16; ++m
) {
2230 if ((m
& (sizeof(long) - 1)) == 0)
2235 for (m
= 0; m
< r
; ++m
) {
2238 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2251 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2254 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2255 instruction_dump_func dump_func
)
2258 unsigned long first_adr
;
2259 unsigned long inst
, last_inst
= 0;
2260 unsigned char val
[4];
2263 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2264 nr
= mread(adr
, val
, 4);
2267 const char *x
= fault_chars
[fault_type
];
2268 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2272 inst
= GETWORD(val
);
2273 if (adr
> first_adr
&& inst
== last_inst
) {
2283 printf(REG
" %.8x", adr
, inst
);
2285 dump_func(inst
, adr
);
2288 return adr
- first_adr
;
2292 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2294 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2298 print_address(unsigned long addr
)
2300 xmon_print_symbol(addr
, "\t# ", "");
2306 struct kmsg_dumper dumper
= { .active
= 1 };
2307 unsigned char buf
[128];
2310 if (setjmp(bus_error_jmp
) != 0) {
2311 printf("Error dumping printk buffer!\n");
2315 catch_memory_errors
= 1;
2318 kmsg_dump_rewind_nolock(&dumper
);
2319 while (kmsg_dump_get_line_nolock(&dumper
, false, buf
, sizeof(buf
), &len
)) {
2325 /* wait a little while to see if we get a machine check */
2327 catch_memory_errors
= 0;
2331 * Memory operations - move, set, print differences
2333 static unsigned long mdest
; /* destination address */
2334 static unsigned long msrc
; /* source address */
2335 static unsigned long mval
; /* byte value to set memory to */
2336 static unsigned long mcount
; /* # bytes to affect */
2337 static unsigned long mdiffs
; /* max # differences to print */
2342 scanhex((void *)&mdest
);
2343 if( termch
!= '\n' )
2345 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2346 if( termch
!= '\n' )
2348 scanhex((void *)&mcount
);
2351 memmove((void *)mdest
, (void *)msrc
, mcount
);
2354 memset((void *)mdest
, mval
, mcount
);
2357 if( termch
!= '\n' )
2359 scanhex((void *)&mdiffs
);
2360 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2366 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2371 for( n
= nb
; n
> 0; --n
)
2372 if( *p1
++ != *p2
++ )
2373 if( ++prt
<= maxpr
)
2374 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2375 p1
[-1], p2
- 1, p2
[-1]);
2377 printf("Total of %d differences\n", prt
);
2380 static unsigned mend
;
2381 static unsigned mask
;
2387 unsigned char val
[4];
2390 scanhex((void *)&mdest
);
2391 if (termch
!= '\n') {
2393 scanhex((void *)&mend
);
2394 if (termch
!= '\n') {
2396 scanhex((void *)&mval
);
2398 if (termch
!= '\n') termch
= 0;
2399 scanhex((void *)&mask
);
2403 for (a
= mdest
; a
< mend
; a
+= 4) {
2404 if (mread(a
, val
, 4) == 4
2405 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2406 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2413 static unsigned long mskip
= 0x1000;
2414 static unsigned long mlim
= 0xffffffff;
2424 if (termch
!= '\n') termch
= 0;
2426 if (termch
!= '\n') termch
= 0;
2429 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2430 ok
= mread(a
, &v
, 1);
2432 printf("%.8x .. ", a
);
2433 } else if (!ok
&& ook
)
2434 printf("%.8x\n", a
- mskip
);
2440 printf("%.8x\n", a
- mskip
);
2443 static void proccall(void)
2445 unsigned long args
[8];
2448 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2449 unsigned long, unsigned long, unsigned long,
2450 unsigned long, unsigned long, unsigned long);
2453 if (!scanhex(&adrs
))
2457 for (i
= 0; i
< 8; ++i
)
2459 for (i
= 0; i
< 8; ++i
) {
2460 if (!scanhex(&args
[i
]) || termch
== '\n')
2464 func
= (callfunc_t
) adrs
;
2466 if (setjmp(bus_error_jmp
) == 0) {
2467 catch_memory_errors
= 1;
2469 ret
= func(args
[0], args
[1], args
[2], args
[3],
2470 args
[4], args
[5], args
[6], args
[7]);
2472 printf("return value is 0x%lx\n", ret
);
2474 printf("*** %x exception occurred\n", fault_except
);
2476 catch_memory_errors
= 0;
2479 /* Input scanning routines */
2490 while( c
== ' ' || c
== '\t' )
2496 static char *regnames
[N_PTREGS
] = {
2497 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2498 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2499 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2500 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2501 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2507 "trap", "dar", "dsisr", "res"
2511 scanhex(unsigned long *vp
)
2518 /* parse register name */
2522 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2531 for (i
= 0; i
< N_PTREGS
; ++i
) {
2532 if (strcmp(regnames
[i
], regname
) == 0) {
2533 if (xmon_regs
== NULL
) {
2534 printf("regs not available\n");
2537 *vp
= ((unsigned long *)xmon_regs
)[i
];
2541 printf("invalid register name '%%%s'\n", regname
);
2545 /* skip leading "0x" if any */
2559 } else if (c
== '$') {
2561 for (i
=0; i
<63; i
++) {
2563 if (isspace(c
) || c
== '\0') {
2571 if (setjmp(bus_error_jmp
) == 0) {
2572 catch_memory_errors
= 1;
2574 *vp
= kallsyms_lookup_name(tmpstr
);
2577 catch_memory_errors
= 0;
2579 printf("unknown symbol '%s'\n", tmpstr
);
2612 static int hexdigit(int c
)
2614 if( '0' <= c
&& c
<= '9' )
2616 if( 'A' <= c
&& c
<= 'F' )
2617 return c
- ('A' - 10);
2618 if( 'a' <= c
&& c
<= 'f' )
2619 return c
- ('a' - 10);
2624 getstring(char *s
, int size
)
2635 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2640 static char line
[256];
2641 static char *lineptr
;
2652 if (lineptr
== NULL
|| *lineptr
== 0) {
2653 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2663 take_input(char *str
)
2672 int type
= inchar();
2674 static char tmp
[64];
2679 xmon_print_symbol(addr
, ": ", "\n");
2684 if (setjmp(bus_error_jmp
) == 0) {
2685 catch_memory_errors
= 1;
2687 addr
= kallsyms_lookup_name(tmp
);
2689 printf("%s: %lx\n", tmp
, addr
);
2691 printf("Symbol '%s' not found.\n", tmp
);
2694 catch_memory_errors
= 0;
2701 /* Print an address in numeric and symbolic form (if possible) */
2702 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2706 const char *name
= NULL
;
2707 unsigned long offset
, size
;
2709 printf(REG
, address
);
2710 if (setjmp(bus_error_jmp
) == 0) {
2711 catch_memory_errors
= 1;
2713 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2716 /* wait a little while to see if we get a machine check */
2720 catch_memory_errors
= 0;
2723 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2725 printf(" [%s]", modname
);
2727 printf("%s", after
);
2730 #ifdef CONFIG_PPC_BOOK3S_64
2731 void dump_segments(void)
2734 unsigned long esid
,vsid
,valid
;
2737 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2739 for (i
= 0; i
< mmu_slb_size
; i
++) {
2740 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2741 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2742 valid
= (esid
& SLB_ESID_V
);
2743 if (valid
| esid
| vsid
) {
2744 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2746 llp
= vsid
& SLB_VSID_LLP
;
2747 if (vsid
& SLB_VSID_B_1T
) {
2748 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2750 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2753 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2755 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2765 #ifdef CONFIG_PPC_STD_MMU_32
2766 void dump_segments(void)
2771 for (i
= 0; i
< 16; ++i
)
2772 printf(" %x", mfsrin(i
));
2778 static void dump_tlb_44x(void)
2782 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2783 unsigned long w0
,w1
,w2
;
2784 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2785 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2786 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2787 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2788 if (w0
& PPC44x_TLB_VALID
) {
2789 printf("V %08x -> %01x%08x %c%c%c%c%c",
2790 w0
& PPC44x_TLB_EPN_MASK
,
2791 w1
& PPC44x_TLB_ERPN_MASK
,
2792 w1
& PPC44x_TLB_RPN_MASK
,
2793 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2794 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2795 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2796 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2797 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2802 #endif /* CONFIG_44x */
2804 #ifdef CONFIG_PPC_BOOK3E
2805 static void dump_tlb_book3e(void)
2807 u32 mmucfg
, pidmask
, lpidmask
;
2809 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
2811 static const char *pgsz_names
[] = {
2846 /* Gather some infos about the MMU */
2847 mmucfg
= mfspr(SPRN_MMUCFG
);
2848 mmu_version
= (mmucfg
& 3) + 1;
2849 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
2850 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
2851 lpidsz
= (mmucfg
>> 24) & 0xf;
2852 rasz
= (mmucfg
>> 16) & 0x7f;
2853 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
2855 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2856 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
2857 pidmask
= (1ul << pidsz
) - 1;
2858 lpidmask
= (1ul << lpidsz
) - 1;
2859 ramask
= (1ull << rasz
) - 1;
2861 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
2863 int nent
, assoc
, new_cc
= 1;
2864 printf("TLB %d:\n------\n", tlb
);
2867 tlbcfg
= mfspr(SPRN_TLB0CFG
);
2870 tlbcfg
= mfspr(SPRN_TLB1CFG
);
2873 tlbcfg
= mfspr(SPRN_TLB2CFG
);
2876 tlbcfg
= mfspr(SPRN_TLB3CFG
);
2879 printf("Unsupported TLB number !\n");
2882 nent
= tlbcfg
& 0xfff;
2883 assoc
= (tlbcfg
>> 24) & 0xff;
2884 for (i
= 0; i
< nent
; i
++) {
2885 u32 mas0
= MAS0_TLBSEL(tlb
);
2886 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
2889 int esel
= i
, cc
= i
;
2897 mas0
|= MAS0_ESEL(esel
);
2898 mtspr(SPRN_MAS0
, mas0
);
2899 mtspr(SPRN_MAS1
, mas1
);
2900 mtspr(SPRN_MAS2
, mas2
);
2901 asm volatile("tlbre 0,0,0" : : : "memory");
2902 mas1
= mfspr(SPRN_MAS1
);
2903 mas2
= mfspr(SPRN_MAS2
);
2904 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
2905 if (assoc
&& (i
% assoc
) == 0)
2907 if (!(mas1
& MAS1_VALID
))
2910 printf("%04x- ", i
);
2912 printf("%04x-%c", cc
, 'A' + esel
);
2914 printf(" |%c", 'A' + esel
);
2916 printf(" %016llx %04x %s %c%c AS%c",
2918 (mas1
>> 16) & 0x3fff,
2919 pgsz_names
[(mas1
>> 7) & 0x1f],
2920 mas1
& MAS1_IND
? 'I' : ' ',
2921 mas1
& MAS1_IPROT
? 'P' : ' ',
2922 mas1
& MAS1_TS
? '1' : '0');
2923 printf(" %c%c%c%c%c%c%c",
2924 mas2
& MAS2_X0
? 'a' : ' ',
2925 mas2
& MAS2_X1
? 'v' : ' ',
2926 mas2
& MAS2_W
? 'w' : ' ',
2927 mas2
& MAS2_I
? 'i' : ' ',
2928 mas2
& MAS2_M
? 'm' : ' ',
2929 mas2
& MAS2_G
? 'g' : ' ',
2930 mas2
& MAS2_E
? 'e' : ' ');
2931 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
2932 if (mas1
& MAS1_IND
)
2934 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
2936 printf(" U%c%c%c S%c%c%c\n",
2937 mas7_mas3
& MAS3_UX
? 'x' : ' ',
2938 mas7_mas3
& MAS3_UW
? 'w' : ' ',
2939 mas7_mas3
& MAS3_UR
? 'r' : ' ',
2940 mas7_mas3
& MAS3_SX
? 'x' : ' ',
2941 mas7_mas3
& MAS3_SW
? 'w' : ' ',
2942 mas7_mas3
& MAS3_SR
? 'r' : ' ');
2946 #endif /* CONFIG_PPC_BOOK3E */
2948 static void xmon_init(int enable
)
2952 __debugger_ipi
= xmon_ipi
;
2953 __debugger_bpt
= xmon_bpt
;
2954 __debugger_sstep
= xmon_sstep
;
2955 __debugger_iabr_match
= xmon_iabr_match
;
2956 __debugger_break_match
= xmon_break_match
;
2957 __debugger_fault_handler
= xmon_fault_handler
;
2960 __debugger_ipi
= NULL
;
2961 __debugger_bpt
= NULL
;
2962 __debugger_sstep
= NULL
;
2963 __debugger_iabr_match
= NULL
;
2964 __debugger_break_match
= NULL
;
2965 __debugger_fault_handler
= NULL
;
2969 #ifdef CONFIG_MAGIC_SYSRQ
2970 static void sysrq_handle_xmon(int key
)
2972 /* ensure xmon is enabled */
2974 debugger(get_irq_regs());
2977 static struct sysrq_key_op sysrq_xmon_op
= {
2978 .handler
= sysrq_handle_xmon
,
2979 .help_msg
= "xmon(x)",
2980 .action_msg
= "Entering xmon",
2983 static int __init
setup_xmon_sysrq(void)
2985 register_sysrq_key('x', &sysrq_xmon_op
);
2988 __initcall(setup_xmon_sysrq
);
2989 #endif /* CONFIG_MAGIC_SYSRQ */
2991 static int __initdata xmon_early
, xmon_off
;
2993 static int __init
early_parse_xmon(char *p
)
2995 if (!p
|| strncmp(p
, "early", 5) == 0) {
2996 /* just "xmon" is equivalent to "xmon=early" */
2999 } else if (strncmp(p
, "on", 2) == 0)
3001 else if (strncmp(p
, "off", 3) == 0)
3003 else if (strncmp(p
, "nobt", 4) == 0)
3004 xmon_no_auto_backtrace
= 1;
3010 early_param("xmon", early_parse_xmon
);
3012 void __init
xmon_setup(void)
3014 #ifdef CONFIG_XMON_DEFAULT
3022 #ifdef CONFIG_SPU_BASE
3026 u64 saved_mfc_sr1_RW
;
3027 u32 saved_spu_runcntl_RW
;
3028 unsigned long dump_addr
;
3032 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3034 static struct spu_info spu_info
[XMON_NUM_SPUS
];
3036 void xmon_register_spus(struct list_head
*list
)
3040 list_for_each_entry(spu
, list
, full_list
) {
3041 if (spu
->number
>= XMON_NUM_SPUS
) {
3046 spu_info
[spu
->number
].spu
= spu
;
3047 spu_info
[spu
->number
].stopped_ok
= 0;
3048 spu_info
[spu
->number
].dump_addr
= (unsigned long)
3049 spu_info
[spu
->number
].spu
->local_store
;
3053 static void stop_spus(void)
3059 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3060 if (!spu_info
[i
].spu
)
3063 if (setjmp(bus_error_jmp
) == 0) {
3064 catch_memory_errors
= 1;
3067 spu
= spu_info
[i
].spu
;
3069 spu_info
[i
].saved_spu_runcntl_RW
=
3070 in_be32(&spu
->problem
->spu_runcntl_RW
);
3072 tmp
= spu_mfc_sr1_get(spu
);
3073 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
3075 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
3076 spu_mfc_sr1_set(spu
, tmp
);
3081 spu_info
[i
].stopped_ok
= 1;
3083 printf("Stopped spu %.2d (was %s)\n", i
,
3084 spu_info
[i
].saved_spu_runcntl_RW
?
3085 "running" : "stopped");
3087 catch_memory_errors
= 0;
3088 printf("*** Error stopping spu %.2d\n", i
);
3090 catch_memory_errors
= 0;
3094 static void restart_spus(void)
3099 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3100 if (!spu_info
[i
].spu
)
3103 if (!spu_info
[i
].stopped_ok
) {
3104 printf("*** Error, spu %d was not successfully stopped"
3105 ", not restarting\n", i
);
3109 if (setjmp(bus_error_jmp
) == 0) {
3110 catch_memory_errors
= 1;
3113 spu
= spu_info
[i
].spu
;
3114 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
3115 out_be32(&spu
->problem
->spu_runcntl_RW
,
3116 spu_info
[i
].saved_spu_runcntl_RW
);
3121 printf("Restarted spu %.2d\n", i
);
3123 catch_memory_errors
= 0;
3124 printf("*** Error restarting spu %.2d\n", i
);
3126 catch_memory_errors
= 0;
3130 #define DUMP_WIDTH 23
3131 #define DUMP_VALUE(format, field, value) \
3133 if (setjmp(bus_error_jmp) == 0) { \
3134 catch_memory_errors = 1; \
3136 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3141 catch_memory_errors = 0; \
3142 printf(" %-*s = *** Error reading field.\n", \
3143 DUMP_WIDTH, #field); \
3145 catch_memory_errors = 0; \
3148 #define DUMP_FIELD(obj, format, field) \
3149 DUMP_VALUE(format, field, obj->field)
3151 static void dump_spu_fields(struct spu
*spu
)
3153 printf("Dumping spu fields at address %p:\n", spu
);
3155 DUMP_FIELD(spu
, "0x%x", number
);
3156 DUMP_FIELD(spu
, "%s", name
);
3157 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3158 DUMP_FIELD(spu
, "0x%p", local_store
);
3159 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3160 DUMP_FIELD(spu
, "0x%x", node
);
3161 DUMP_FIELD(spu
, "0x%lx", flags
);
3162 DUMP_FIELD(spu
, "%d", class_0_pending
);
3163 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
3164 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
3165 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
3166 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
3167 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
3168 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
3169 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3170 DUMP_FIELD(spu
, "%d", pid
);
3171 DUMP_FIELD(spu
, "0x%p", mm
);
3172 DUMP_FIELD(spu
, "0x%p", ctx
);
3173 DUMP_FIELD(spu
, "0x%p", rq
);
3174 DUMP_FIELD(spu
, "0x%p", timestamp
);
3175 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3176 DUMP_FIELD(spu
, "0x%p", problem
);
3177 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3178 in_be32(&spu
->problem
->spu_runcntl_RW
));
3179 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3180 in_be32(&spu
->problem
->spu_status_R
));
3181 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3182 in_be32(&spu
->problem
->spu_npc_RW
));
3183 DUMP_FIELD(spu
, "0x%p", priv2
);
3184 DUMP_FIELD(spu
, "0x%p", pdata
);
3188 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3190 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3193 static void dump_spu_ls(unsigned long num
, int subcmd
)
3195 unsigned long offset
, addr
, ls_addr
;
3197 if (setjmp(bus_error_jmp
) == 0) {
3198 catch_memory_errors
= 1;
3200 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3204 catch_memory_errors
= 0;
3205 printf("*** Error: accessing spu info for spu %d\n", num
);
3208 catch_memory_errors
= 0;
3210 if (scanhex(&offset
))
3211 addr
= ls_addr
+ offset
;
3213 addr
= spu_info
[num
].dump_addr
;
3215 if (addr
>= ls_addr
+ LS_SIZE
) {
3216 printf("*** Error: address outside of local store\n");
3222 addr
+= spu_inst_dump(addr
, 16, 1);
3232 spu_info
[num
].dump_addr
= addr
;
3235 static int do_spu_cmd(void)
3237 static unsigned long num
= 0;
3238 int cmd
, subcmd
= 0;
3250 if (isxdigit(subcmd
) || subcmd
== '\n')
3254 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3255 printf("*** Error: invalid spu number\n");
3261 dump_spu_fields(spu_info
[num
].spu
);
3264 dump_spu_ls(num
, subcmd
);
3275 #else /* ! CONFIG_SPU_BASE */
3276 static int do_spu_cmd(void)