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)
245 " # n limit output to n lines per page (for dp, dpa, dl)\n"
250 static struct pt_regs
*xmon_regs
;
252 static inline void sync(void)
254 asm volatile("sync; isync");
257 static inline void store_inst(void *p
)
259 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
262 static inline void cflush(void *p
)
264 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
267 static inline void cinval(void *p
)
269 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
273 * write_ciabr() - write the CIABR SPR
274 * @ciabr: The value to write.
276 * This function writes a value to the CIARB register either directly
277 * through mtspr instruction if the kernel is in HV privilege mode or
278 * call a hypervisor function to achieve the same in case the kernel
279 * is in supervisor privilege mode.
281 static void write_ciabr(unsigned long ciabr
)
283 if (!cpu_has_feature(CPU_FTR_ARCH_207S
))
286 if (cpu_has_feature(CPU_FTR_HVMODE
)) {
287 mtspr(SPRN_CIABR
, ciabr
);
290 plapr_set_ciabr(ciabr
);
294 * set_ciabr() - set the CIABR
295 * @addr: The value to set.
297 * This function sets the correct privilege value into the the HW
298 * breakpoint address before writing it up in the CIABR register.
300 static void set_ciabr(unsigned long addr
)
304 if (cpu_has_feature(CPU_FTR_HVMODE
))
305 addr
|= CIABR_PRIV_HYPER
;
307 addr
|= CIABR_PRIV_SUPER
;
312 * Disable surveillance (the service processor watchdog function)
313 * while we are in xmon.
314 * XXX we should re-enable it when we leave. :)
316 #define SURVEILLANCE_TOKEN 9000
318 static inline void disable_surveillance(void)
320 #ifdef CONFIG_PPC_PSERIES
321 /* Since this can't be a module, args should end up below 4GB. */
322 static struct rtas_args args
;
325 * At this point we have got all the cpus we can into
326 * xmon, so there is hopefully no other cpu calling RTAS
327 * at the moment, even though we don't take rtas.lock.
328 * If we did try to take rtas.lock there would be a
329 * real possibility of deadlock.
331 args
.token
= rtas_token("set-indicator");
332 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
334 args
.token
= cpu_to_be32(args
.token
);
335 args
.nargs
= cpu_to_be32(3);
336 args
.nret
= cpu_to_be32(1);
337 args
.rets
= &args
.args
[3];
338 args
.args
[0] = cpu_to_be32(SURVEILLANCE_TOKEN
);
341 enter_rtas(__pa(&args
));
342 #endif /* CONFIG_PPC_PSERIES */
346 static int xmon_speaker
;
348 static void get_output_lock(void)
350 int me
= smp_processor_id() + 0x100;
351 int last_speaker
= 0, prev
;
354 if (xmon_speaker
== me
)
358 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
359 if (last_speaker
== 0)
363 * Wait a full second for the lock, we might be on a slow
364 * console, but check every 100us.
367 while (xmon_speaker
== last_speaker
) {
373 /* hostile takeover */
374 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
375 if (prev
== last_speaker
)
382 static void release_output_lock(void)
387 int cpus_are_in_xmon(void)
389 return !cpumask_empty(&cpus_in_xmon
);
393 static inline int unrecoverable_excp(struct pt_regs
*regs
)
395 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
396 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
399 return ((regs
->msr
& MSR_RI
) == 0);
403 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
407 long recurse_jmp
[JMP_BUF_LEN
];
408 unsigned long offset
;
413 unsigned long timeout
;
416 local_irq_save(flags
);
419 bp
= in_breakpoint_table(regs
->nip
, &offset
);
421 regs
->nip
= bp
->address
+ offset
;
422 atomic_dec(&bp
->ref_count
);
428 cpu
= smp_processor_id();
429 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
432 printf("cpu 0x%x: Exception %lx %s in xmon, "
433 "returning to main loop\n",
434 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
435 release_output_lock();
436 longjmp(xmon_fault_jmp
[cpu
], 1);
439 if (setjmp(recurse_jmp
) != 0) {
440 if (!in_xmon
|| !xmon_gate
) {
442 printf("xmon: WARNING: bad recursive fault "
443 "on cpu 0x%x\n", cpu
);
444 release_output_lock();
447 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
451 xmon_fault_jmp
[cpu
] = recurse_jmp
;
454 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
))
455 bp
= at_breakpoint(regs
->nip
);
456 if (bp
|| unrecoverable_excp(regs
))
463 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
465 xmon_print_symbol(regs
->nip
, " ", ")\n");
467 if (unrecoverable_excp(regs
))
468 printf("WARNING: exception is not recoverable, "
470 release_output_lock();
473 cpumask_set_cpu(cpu
, &cpus_in_xmon
);
477 while (secondary
&& !xmon_gate
) {
481 secondary
= test_and_set_bit(0, &in_xmon
);
486 if (!secondary
&& !xmon_gate
) {
487 /* we are the first cpu to come in */
488 /* interrupt other cpu(s) */
489 int ncpus
= num_online_cpus();
494 smp_send_debugger_break();
495 /* wait for other cpus to come in */
496 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
497 if (cpumask_weight(&cpus_in_xmon
) >= ncpus
)
503 disable_surveillance();
504 /* for breakpoint or single step, print the current instr. */
505 if (bp
|| TRAP(regs
) == 0xd00)
506 ppc_inst_dump(regs
->nip
, 1, 0);
507 printf("enter ? for help\n");
516 if (cpu
== xmon_owner
) {
517 if (!test_and_set_bit(0, &xmon_taken
)) {
522 while (cpu
== xmon_owner
)
536 /* have switched to some other cpu */
541 cpumask_clear_cpu(cpu
, &cpus_in_xmon
);
542 xmon_fault_jmp
[cpu
] = NULL
;
544 /* UP is simple... */
546 printf("Exception %lx %s in xmon, returning to main loop\n",
547 regs
->trap
, getvecname(TRAP(regs
)));
548 longjmp(xmon_fault_jmp
[0], 1);
550 if (setjmp(recurse_jmp
) == 0) {
551 xmon_fault_jmp
[0] = recurse_jmp
;
555 bp
= at_breakpoint(regs
->nip
);
557 printf("Stopped at breakpoint %lx (", BP_NUM(bp
));
558 xmon_print_symbol(regs
->nip
, " ", ")\n");
560 if (unrecoverable_excp(regs
))
561 printf("WARNING: exception is not recoverable, "
564 disable_surveillance();
565 /* for breakpoint or single step, print the current instr. */
566 if (bp
|| TRAP(regs
) == 0xd00)
567 ppc_inst_dump(regs
->nip
, 1, 0);
568 printf("enter ? for help\n");
578 if (regs
->msr
& MSR_DE
) {
579 bp
= at_breakpoint(regs
->nip
);
581 regs
->nip
= (unsigned long) &bp
->instr
[0];
582 atomic_inc(&bp
->ref_count
);
586 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
587 bp
= at_breakpoint(regs
->nip
);
589 int stepped
= emulate_step(regs
, bp
->instr
[0]);
591 regs
->nip
= (unsigned long) &bp
->instr
[0];
592 atomic_inc(&bp
->ref_count
);
593 } else if (stepped
< 0) {
594 printf("Couldn't single-step %s instruction\n",
595 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
602 touch_nmi_watchdog();
603 local_irq_restore(flags
);
605 return cmd
!= 'X' && cmd
!= EOF
;
608 int xmon(struct pt_regs
*excp
)
613 ppc_save_regs(®s
);
617 return xmon_core(excp
, 0);
621 irqreturn_t
xmon_irq(int irq
, void *d
)
624 local_irq_save(flags
);
625 printf("Keyboard interrupt\n");
626 xmon(get_irq_regs());
627 local_irq_restore(flags
);
631 static int xmon_bpt(struct pt_regs
*regs
)
634 unsigned long offset
;
636 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
639 /* Are we at the trap at bp->instr[1] for some bp? */
640 bp
= in_breakpoint_table(regs
->nip
, &offset
);
641 if (bp
!= NULL
&& offset
== 4) {
642 regs
->nip
= bp
->address
+ 4;
643 atomic_dec(&bp
->ref_count
);
647 /* Are we at a breakpoint? */
648 bp
= at_breakpoint(regs
->nip
);
657 static int xmon_sstep(struct pt_regs
*regs
)
665 static int xmon_break_match(struct pt_regs
*regs
)
667 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
669 if (dabr
.enabled
== 0)
675 static int xmon_iabr_match(struct pt_regs
*regs
)
677 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
685 static int xmon_ipi(struct pt_regs
*regs
)
688 if (in_xmon
&& !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon
))
694 static int xmon_fault_handler(struct pt_regs
*regs
)
697 unsigned long offset
;
699 if (in_xmon
&& catch_memory_errors
)
700 handle_fault(regs
); /* doesn't return */
702 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
703 bp
= in_breakpoint_table(regs
->nip
, &offset
);
705 regs
->nip
= bp
->address
+ offset
;
706 atomic_dec(&bp
->ref_count
);
713 static struct bpt
*at_breakpoint(unsigned long pc
)
719 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
720 if (bp
->enabled
&& pc
== bp
->address
)
725 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
729 off
= nip
- (unsigned long) bpts
;
730 if (off
>= sizeof(bpts
))
732 off
%= sizeof(struct bpt
);
733 if (off
!= offsetof(struct bpt
, instr
[0])
734 && off
!= offsetof(struct bpt
, instr
[1]))
736 *offp
= off
- offsetof(struct bpt
, instr
[0]);
737 return (struct bpt
*) (nip
- off
);
740 static struct bpt
*new_breakpoint(unsigned long a
)
745 bp
= at_breakpoint(a
);
749 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
750 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
752 bp
->instr
[1] = bpinstr
;
753 store_inst(&bp
->instr
[1]);
758 printf("Sorry, no free breakpoints. Please clear one first.\n");
762 static void insert_bpts(void)
768 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
769 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) == 0)
771 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
772 printf("Couldn't read instruction at %lx, "
773 "disabling breakpoint there\n", bp
->address
);
777 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
778 printf("Breakpoint at %lx is on an mtmsrd or rfid "
779 "instruction, disabling it\n", bp
->address
);
783 store_inst(&bp
->instr
[0]);
784 if (bp
->enabled
& BP_CIABR
)
786 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
787 printf("Couldn't write instruction at %lx, "
788 "disabling breakpoint there\n", bp
->address
);
789 bp
->enabled
&= ~BP_TRAP
;
792 store_inst((void *)bp
->address
);
796 static void insert_cpu_bpts(void)
798 struct arch_hw_breakpoint brk
;
801 brk
.address
= dabr
.address
;
802 brk
.type
= (dabr
.enabled
& HW_BRK_TYPE_DABR
) | HW_BRK_TYPE_PRIV_ALL
;
804 __set_breakpoint(&brk
);
808 set_ciabr(iabr
->address
);
811 static void remove_bpts(void)
818 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
819 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) != BP_TRAP
)
821 if (mread(bp
->address
, &instr
, 4) == 4
823 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
824 printf("Couldn't remove breakpoint at %lx\n",
827 store_inst((void *)bp
->address
);
831 static void remove_cpu_bpts(void)
833 hw_breakpoint_disable();
837 static void set_lpp_cmd(void)
841 if (!scanhex(&lpp
)) {
842 printf("Invalid number.\n");
845 xmon_set_pagination_lpp(lpp
);
847 /* Command interpreting routine */
848 static char *last_cmd
;
851 cmds(struct pt_regs
*excp
)
858 if (!xmon_no_auto_backtrace
) {
859 xmon_no_auto_backtrace
= 1;
860 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
865 printf("%x:", smp_processor_id());
866 #endif /* CONFIG_SMP */
872 if (last_cmd
== NULL
)
874 take_input(last_cmd
);
908 prregs(excp
); /* print regs */
923 if (do_spu_cmd() == 0)
932 printf(" <no input ...>\n");
936 xmon_puts(help_string
);
957 #ifdef CONFIG_PPC_STD_MMU
961 #elif defined(CONFIG_44x)
965 #elif defined(CONFIG_PPC_BOOK3E)
971 printf("Unrecognized command: ");
973 if (' ' < cmd
&& cmd
<= '~')
976 printf("\\x%x", cmd
);
978 } while (cmd
!= '\n');
979 printf(" (type ? for help)\n");
986 static int do_step(struct pt_regs
*regs
)
989 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
994 * Step a single instruction.
995 * Some instructions we emulate, others we execute with MSR_SE set.
997 static int do_step(struct pt_regs
*regs
)
1002 /* check we are in 64-bit kernel mode, translation enabled */
1003 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
1004 if (mread(regs
->nip
, &instr
, 4) == 4) {
1005 stepped
= emulate_step(regs
, instr
);
1007 printf("Couldn't single-step %s instruction\n",
1008 (IS_RFID(instr
)? "rfid": "mtmsrd"));
1012 regs
->trap
= 0xd00 | (regs
->trap
& 1);
1013 printf("stepped to ");
1014 xmon_print_symbol(regs
->nip
, " ", "\n");
1015 ppc_inst_dump(regs
->nip
, 1, 0);
1020 regs
->msr
|= MSR_SE
;
1025 static void bootcmds(void)
1031 ppc_md
.restart(NULL
);
1032 else if (cmd
== 'h')
1034 else if (cmd
== 'p')
1039 static int cpu_cmd(void)
1042 unsigned long cpu
, first_cpu
, last_cpu
;
1045 if (!scanhex(&cpu
)) {
1046 /* print cpus waiting or in xmon */
1047 printf("cpus stopped:");
1048 last_cpu
= first_cpu
= NR_CPUS
;
1049 for_each_possible_cpu(cpu
) {
1050 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1051 if (cpu
== last_cpu
+ 1) {
1054 if (last_cpu
!= first_cpu
)
1055 printf("-0x%lx", last_cpu
);
1056 last_cpu
= first_cpu
= cpu
;
1057 printf(" 0x%lx", cpu
);
1061 if (last_cpu
!= first_cpu
)
1062 printf("-0x%lx", last_cpu
);
1066 /* try to switch to cpu specified */
1067 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1068 printf("cpu 0x%x isn't in xmon\n", cpu
);
1075 while (!xmon_taken
) {
1076 if (--timeout
== 0) {
1077 if (test_and_set_bit(0, &xmon_taken
))
1079 /* take control back */
1081 xmon_owner
= smp_processor_id();
1082 printf("cpu 0x%x didn't take control\n", cpu
);
1090 #endif /* CONFIG_SMP */
1093 static unsigned short fcstab
[256] = {
1094 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1095 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1096 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1097 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1098 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1099 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1100 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1101 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1102 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1103 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1104 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1105 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1106 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1107 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1108 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1109 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1110 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1111 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1112 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1113 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1114 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1115 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1116 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1117 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1118 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1119 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1120 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1121 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1122 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1123 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1124 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1125 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1128 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1137 if (!scanhex(&adrs
))
1139 if (!scanhex(&ncsum
))
1142 for (i
= 0; i
< ncsum
; ++i
) {
1143 if (mread(adrs
+i
, &v
, 1) == 0) {
1144 printf("csum stopped at "REG
"\n", adrs
+i
);
1149 printf("%x\n", fcs
);
1153 * Check if this is a suitable place to put a breakpoint.
1155 static long check_bp_loc(unsigned long addr
)
1160 if (!is_kernel_addr(addr
)) {
1161 printf("Breakpoints may only be placed at kernel addresses\n");
1164 if (!mread(addr
, &instr
, sizeof(instr
))) {
1165 printf("Can't read instruction at address %lx\n", addr
);
1168 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1169 printf("Breakpoints may not be placed on mtmsrd or rfid "
1176 static char *breakpoint_help_string
=
1177 "Breakpoint command usage:\n"
1178 "b show breakpoints\n"
1179 "b <addr> [cnt] set breakpoint at given instr addr\n"
1180 "bc clear all breakpoints\n"
1181 "bc <n/addr> clear breakpoint number n or at addr\n"
1182 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1183 "bd <addr> [cnt] set hardware data breakpoint\n"
1193 const char badaddr
[] = "Only kernel addresses are permitted "
1194 "for breakpoints\n";
1199 case 'd': /* bd - hardware data breakpoint */
1204 else if (cmd
== 'w')
1210 if (scanhex(&dabr
.address
)) {
1211 if (!is_kernel_addr(dabr
.address
)) {
1215 dabr
.address
&= ~HW_BRK_TYPE_DABR
;
1216 dabr
.enabled
= mode
| BP_DABR
;
1220 case 'i': /* bi - hardware instr breakpoint */
1221 if (!cpu_has_feature(CPU_FTR_ARCH_207S
)) {
1222 printf("Hardware instruction breakpoint "
1223 "not supported on this cpu\n");
1227 iabr
->enabled
&= ~BP_CIABR
;
1232 if (!check_bp_loc(a
))
1234 bp
= new_breakpoint(a
);
1236 bp
->enabled
|= BP_CIABR
;
1244 /* clear all breakpoints */
1245 for (i
= 0; i
< NBPTS
; ++i
)
1246 bpts
[i
].enabled
= 0;
1249 printf("All breakpoints cleared\n");
1253 if (a
<= NBPTS
&& a
>= 1) {
1254 /* assume a breakpoint number */
1255 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1257 /* assume a breakpoint address */
1258 bp
= at_breakpoint(a
);
1260 printf("No breakpoint at %lx\n", a
);
1265 printf("Cleared breakpoint %lx (", BP_NUM(bp
));
1266 xmon_print_symbol(bp
->address
, " ", ")\n");
1274 printf(breakpoint_help_string
);
1279 /* print all breakpoints */
1280 printf(" type address\n");
1282 printf(" data "REG
" [", dabr
.address
);
1283 if (dabr
.enabled
& 1)
1285 if (dabr
.enabled
& 2)
1289 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1292 printf("%2x %s ", BP_NUM(bp
),
1293 (bp
->enabled
& BP_CIABR
) ? "inst": "trap");
1294 xmon_print_symbol(bp
->address
, " ", "\n");
1299 if (!check_bp_loc(a
))
1301 bp
= new_breakpoint(a
);
1303 bp
->enabled
|= BP_TRAP
;
1308 /* Very cheap human name for vector lookup. */
1310 const char *getvecname(unsigned long vec
)
1315 case 0x100: ret
= "(System Reset)"; break;
1316 case 0x200: ret
= "(Machine Check)"; break;
1317 case 0x300: ret
= "(Data Access)"; break;
1318 case 0x380: ret
= "(Data SLB Access)"; break;
1319 case 0x400: ret
= "(Instruction Access)"; break;
1320 case 0x480: ret
= "(Instruction SLB Access)"; break;
1321 case 0x500: ret
= "(Hardware Interrupt)"; break;
1322 case 0x600: ret
= "(Alignment)"; break;
1323 case 0x700: ret
= "(Program Check)"; break;
1324 case 0x800: ret
= "(FPU Unavailable)"; break;
1325 case 0x900: ret
= "(Decrementer)"; break;
1326 case 0x980: ret
= "(Hypervisor Decrementer)"; break;
1327 case 0xa00: ret
= "(Doorbell)"; break;
1328 case 0xc00: ret
= "(System Call)"; break;
1329 case 0xd00: ret
= "(Single Step)"; break;
1330 case 0xe40: ret
= "(Emulation Assist)"; break;
1331 case 0xe60: ret
= "(HMI)"; break;
1332 case 0xe80: ret
= "(Hypervisor Doorbell)"; break;
1333 case 0xf00: ret
= "(Performance Monitor)"; break;
1334 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1335 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1336 case 0x1500: ret
= "(Denormalisation)"; break;
1337 case 0x1700: ret
= "(Altivec Assist)"; break;
1343 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1344 unsigned long *endp
)
1346 unsigned long size
, offset
;
1349 *startp
= *endp
= 0;
1352 if (setjmp(bus_error_jmp
) == 0) {
1353 catch_memory_errors
= 1;
1355 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1357 *startp
= pc
- offset
;
1358 *endp
= pc
- offset
+ size
;
1362 catch_memory_errors
= 0;
1365 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1366 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1368 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1371 int max_to_print
= 64;
1373 unsigned long newsp
;
1374 unsigned long marker
;
1375 struct pt_regs regs
;
1377 while (max_to_print
--) {
1378 if (sp
< PAGE_OFFSET
) {
1380 printf("SP (%lx) is in userspace\n", sp
);
1384 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1385 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1386 printf("Couldn't read stack frame at %lx\n", sp
);
1391 * For the first stack frame, try to work out if
1392 * LR and/or the saved LR value in the bottommost
1393 * stack frame are valid.
1395 if ((pc
| lr
) != 0) {
1396 unsigned long fnstart
, fnend
;
1397 unsigned long nextip
;
1400 get_function_bounds(pc
, &fnstart
, &fnend
);
1403 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1404 sizeof(unsigned long));
1406 if (lr
< PAGE_OFFSET
1407 || (fnstart
<= lr
&& lr
< fnend
))
1409 } else if (lr
== nextip
) {
1411 } else if (lr
>= PAGE_OFFSET
1412 && !(fnstart
<= lr
&& lr
< fnend
)) {
1413 printf("[link register ] ");
1414 xmon_print_symbol(lr
, " ", "\n");
1417 printf("["REG
"] ", sp
);
1418 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1423 printf("["REG
"] ", sp
);
1424 xmon_print_symbol(ip
, " ", "\n");
1427 /* Look for "regshere" marker to see if this is
1428 an exception frame. */
1429 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1430 && marker
== STACK_FRAME_REGS_MARKER
) {
1431 if (mread(sp
+ STACK_FRAME_OVERHEAD
, ®s
, sizeof(regs
))
1433 printf("Couldn't read registers at %lx\n",
1434 sp
+ STACK_FRAME_OVERHEAD
);
1437 printf("--- Exception: %lx %s at ", regs
.trap
,
1438 getvecname(TRAP(®s
)));
1441 xmon_print_symbol(pc
, " ", "\n");
1451 static void backtrace(struct pt_regs
*excp
)
1456 xmon_show_stack(sp
, 0, 0);
1458 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1462 static void print_bug_trap(struct pt_regs
*regs
)
1465 const struct bug_entry
*bug
;
1468 if (regs
->msr
& MSR_PR
)
1469 return; /* not in kernel */
1470 addr
= regs
->nip
; /* address of trap instruction */
1471 if (addr
< PAGE_OFFSET
)
1473 bug
= find_bug(regs
->nip
);
1476 if (is_warning_bug(bug
))
1479 #ifdef CONFIG_DEBUG_BUGVERBOSE
1480 printf("kernel BUG at %s:%u!\n",
1481 bug
->file
, bug
->line
);
1483 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1485 #endif /* CONFIG_BUG */
1488 static void excprint(struct pt_regs
*fp
)
1493 printf("cpu 0x%x: ", smp_processor_id());
1494 #endif /* CONFIG_SMP */
1497 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1499 xmon_print_symbol(fp
->nip
, ": ", "\n");
1501 printf(" lr: ", fp
->link
);
1502 xmon_print_symbol(fp
->link
, ": ", "\n");
1504 printf(" sp: %lx\n", fp
->gpr
[1]);
1505 printf(" msr: %lx\n", fp
->msr
);
1507 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600 || trap
== 0x200) {
1508 printf(" dar: %lx\n", fp
->dar
);
1510 printf(" dsisr: %lx\n", fp
->dsisr
);
1513 printf(" current = 0x%lx\n", current
);
1515 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1516 local_paca
, local_paca
->soft_enabled
, local_paca
->irq_happened
);
1519 printf(" pid = %ld, comm = %s\n",
1520 current
->pid
, current
->comm
);
1527 static void prregs(struct pt_regs
*fp
)
1531 struct pt_regs regs
;
1533 if (scanhex(&base
)) {
1534 if (setjmp(bus_error_jmp
) == 0) {
1535 catch_memory_errors
= 1;
1537 regs
= *(struct pt_regs
*)base
;
1541 catch_memory_errors
= 0;
1542 printf("*** Error reading registers from "REG
"\n",
1546 catch_memory_errors
= 0;
1551 if (FULL_REGS(fp
)) {
1552 for (n
= 0; n
< 16; ++n
)
1553 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1554 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1556 for (n
= 0; n
< 7; ++n
)
1557 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1558 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1561 for (n
= 0; n
< 32; ++n
) {
1562 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1563 (n
& 3) == 3? "\n": " ");
1564 if (n
== 12 && !FULL_REGS(fp
)) {
1571 xmon_print_symbol(fp
->nip
, " ", "\n");
1572 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1574 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1577 xmon_print_symbol(fp
->link
, " ", "\n");
1578 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1579 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1580 fp
->ctr
, fp
->xer
, fp
->trap
);
1582 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1583 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1586 static void cacheflush(void)
1589 unsigned long nflush
;
1594 scanhex((void *)&adrs
);
1599 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1600 if (setjmp(bus_error_jmp
) == 0) {
1601 catch_memory_errors
= 1;
1605 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1606 cflush((void *) adrs
);
1608 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1609 cinval((void *) adrs
);
1612 /* wait a little while to see if we get a machine check */
1615 catch_memory_errors
= 0;
1618 static unsigned long
1621 unsigned int instrs
[2];
1622 unsigned long (*code
)(void);
1623 unsigned long ret
= -1UL;
1625 unsigned long opd
[3];
1627 opd
[0] = (unsigned long)instrs
;
1630 code
= (unsigned long (*)(void)) opd
;
1632 code
= (unsigned long (*)(void)) instrs
;
1635 /* mfspr r3,n; blr */
1636 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1637 instrs
[1] = 0x4e800020;
1639 store_inst(instrs
+1);
1641 if (setjmp(bus_error_jmp
) == 0) {
1642 catch_memory_errors
= 1;
1648 /* wait a little while to see if we get a machine check */
1657 write_spr(int n
, unsigned long val
)
1659 unsigned int instrs
[2];
1660 unsigned long (*code
)(unsigned long);
1662 unsigned long opd
[3];
1664 opd
[0] = (unsigned long)instrs
;
1667 code
= (unsigned long (*)(unsigned long)) opd
;
1669 code
= (unsigned long (*)(unsigned long)) instrs
;
1672 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1673 instrs
[1] = 0x4e800020;
1675 store_inst(instrs
+1);
1677 if (setjmp(bus_error_jmp
) == 0) {
1678 catch_memory_errors
= 1;
1684 /* wait a little while to see if we get a machine check */
1690 static unsigned long regno
;
1691 extern char exc_prolog
;
1692 extern char dec_exc
;
1694 static void super_regs(void)
1701 unsigned long sp
, toc
;
1702 asm("mr %0,1" : "=r" (sp
) :);
1703 asm("mr %0,2" : "=r" (toc
) :);
1705 printf("msr = "REG
" sprg0= "REG
"\n",
1706 mfmsr(), mfspr(SPRN_SPRG0
));
1707 printf("pvr = "REG
" sprg1= "REG
"\n",
1708 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1709 printf("dec = "REG
" sprg2= "REG
"\n",
1710 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1711 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1712 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1720 val
= read_spr(regno
);
1722 write_spr(regno
, val
);
1725 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1732 * Stuff for reading and writing memory safely
1735 mread(unsigned long adrs
, void *buf
, int size
)
1741 if (setjmp(bus_error_jmp
) == 0) {
1742 catch_memory_errors
= 1;
1748 *(u16
*)q
= *(u16
*)p
;
1751 *(u32
*)q
= *(u32
*)p
;
1754 *(u64
*)q
= *(u64
*)p
;
1757 for( ; n
< size
; ++n
) {
1763 /* wait a little while to see if we get a machine check */
1767 catch_memory_errors
= 0;
1772 mwrite(unsigned long adrs
, void *buf
, int size
)
1778 if (setjmp(bus_error_jmp
) == 0) {
1779 catch_memory_errors
= 1;
1785 *(u16
*)p
= *(u16
*)q
;
1788 *(u32
*)p
= *(u32
*)q
;
1791 *(u64
*)p
= *(u64
*)q
;
1794 for ( ; n
< size
; ++n
) {
1800 /* wait a little while to see if we get a machine check */
1804 printf("*** Error writing address "REG
"\n", adrs
+ n
);
1806 catch_memory_errors
= 0;
1810 static int fault_type
;
1811 static int fault_except
;
1812 static char *fault_chars
[] = { "--", "**", "##" };
1814 static int handle_fault(struct pt_regs
*regs
)
1816 fault_except
= TRAP(regs
);
1817 switch (TRAP(regs
)) {
1829 longjmp(bus_error_jmp
, 1);
1834 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1837 byterev(unsigned char *val
, int size
)
1843 SWAP(val
[0], val
[1], t
);
1846 SWAP(val
[0], val
[3], t
);
1847 SWAP(val
[1], val
[2], t
);
1849 case 8: /* is there really any use for this? */
1850 SWAP(val
[0], val
[7], t
);
1851 SWAP(val
[1], val
[6], t
);
1852 SWAP(val
[2], val
[5], t
);
1853 SWAP(val
[3], val
[4], t
);
1861 static char *memex_help_string
=
1862 "Memory examine command usage:\n"
1863 "m [addr] [flags] examine/change memory\n"
1864 " addr is optional. will start where left off.\n"
1865 " flags may include chars from this set:\n"
1866 " b modify by bytes (default)\n"
1867 " w modify by words (2 byte)\n"
1868 " l modify by longs (4 byte)\n"
1869 " d modify by doubleword (8 byte)\n"
1870 " r toggle reverse byte order mode\n"
1871 " n do not read memory (for i/o spaces)\n"
1872 " . ok to read (default)\n"
1873 "NOTE: flags are saved as defaults\n"
1876 static char *memex_subcmd_help_string
=
1877 "Memory examine subcommands:\n"
1878 " hexval write this val to current location\n"
1879 " 'string' write chars from string to this location\n"
1880 " ' increment address\n"
1881 " ^ decrement address\n"
1882 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1883 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1884 " ` clear no-read flag\n"
1885 " ; stay at this addr\n"
1886 " v change to byte mode\n"
1887 " w change to word (2 byte) mode\n"
1888 " l change to long (4 byte) mode\n"
1889 " u change to doubleword (8 byte) mode\n"
1890 " m addr change current addr\n"
1891 " n toggle no-read flag\n"
1892 " r toggle byte reverse flag\n"
1893 " < count back up count bytes\n"
1894 " > count skip forward count bytes\n"
1895 " x exit this mode\n"
1901 int cmd
, inc
, i
, nslash
;
1903 unsigned char val
[16];
1905 scanhex((void *)&adrs
);
1908 printf(memex_help_string
);
1914 while ((cmd
= skipbl()) != '\n') {
1916 case 'b': size
= 1; break;
1917 case 'w': size
= 2; break;
1918 case 'l': size
= 4; break;
1919 case 'd': size
= 8; break;
1920 case 'r': brev
= !brev
; break;
1921 case 'n': mnoread
= 1; break;
1922 case '.': mnoread
= 0; break;
1931 n
= mread(adrs
, val
, size
);
1932 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1937 for (i
= 0; i
< n
; ++i
)
1938 printf("%.2x", val
[i
]);
1939 for (; i
< size
; ++i
)
1940 printf("%s", fault_chars
[fault_type
]);
1947 for (i
= 0; i
< size
; ++i
)
1948 val
[i
] = n
>> (i
* 8);
1951 mwrite(adrs
, val
, size
);
1964 else if( n
== '\'' )
1966 for (i
= 0; i
< size
; ++i
)
1967 val
[i
] = n
>> (i
* 8);
1970 mwrite(adrs
, val
, size
);
2006 adrs
-= 1 << nslash
;
2010 adrs
+= 1 << nslash
;
2014 adrs
+= 1 << -nslash
;
2018 adrs
-= 1 << -nslash
;
2021 scanhex((void *)&adrs
);
2040 printf(memex_subcmd_help_string
);
2055 case 'n': c
= '\n'; break;
2056 case 'r': c
= '\r'; break;
2057 case 'b': c
= '\b'; break;
2058 case 't': c
= '\t'; break;
2063 static void xmon_rawdump (unsigned long adrs
, long ndump
)
2066 unsigned char temp
[16];
2068 for (n
= ndump
; n
> 0;) {
2070 nr
= mread(adrs
, temp
, r
);
2072 for (m
= 0; m
< r
; ++m
) {
2074 printf("%.2x", temp
[m
]);
2076 printf("%s", fault_chars
[fault_type
]);
2086 static void dump_one_paca(int cpu
)
2088 struct paca_struct
*p
;
2089 #ifdef CONFIG_PPC_STD_MMU_64
2093 if (setjmp(bus_error_jmp
) != 0) {
2094 printf("*** Error dumping paca for cpu 0x%x!\n", cpu
);
2098 catch_memory_errors
= 1;
2103 printf("paca for cpu 0x%x @ %p:\n", cpu
, p
);
2105 printf(" %-*s = %s\n", 20, "possible", cpu_possible(cpu
) ? "yes" : "no");
2106 printf(" %-*s = %s\n", 20, "present", cpu_present(cpu
) ? "yes" : "no");
2107 printf(" %-*s = %s\n", 20, "online", cpu_online(cpu
) ? "yes" : "no");
2109 #define DUMP(paca, name, format) \
2110 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 20, #name, 18, paca->name, \
2111 offsetof(struct paca_struct, name));
2113 DUMP(p
, lock_token
, "x");
2114 DUMP(p
, paca_index
, "x");
2115 DUMP(p
, kernel_toc
, "lx");
2116 DUMP(p
, kernelbase
, "lx");
2117 DUMP(p
, kernel_msr
, "lx");
2118 DUMP(p
, emergency_sp
, "p");
2119 #ifdef CONFIG_PPC_BOOK3S_64
2120 DUMP(p
, mc_emergency_sp
, "p");
2121 DUMP(p
, in_mce
, "x");
2122 DUMP(p
, hmi_event_available
, "x");
2124 DUMP(p
, data_offset
, "lx");
2125 DUMP(p
, hw_cpu_id
, "x");
2126 DUMP(p
, cpu_start
, "x");
2127 DUMP(p
, kexec_state
, "x");
2128 #ifdef CONFIG_PPC_STD_MMU_64
2129 for (i
= 0; i
< SLB_NUM_BOLTED
; i
++) {
2132 if (!p
->slb_shadow_ptr
)
2135 esid
= be64_to_cpu(p
->slb_shadow_ptr
->save_area
[i
].esid
);
2136 vsid
= be64_to_cpu(p
->slb_shadow_ptr
->save_area
[i
].vsid
);
2139 printf(" slb_shadow[%d]: = 0x%016lx 0x%016lx\n",
2143 DUMP(p
, vmalloc_sllp
, "x");
2144 DUMP(p
, slb_cache_ptr
, "x");
2145 for (i
= 0; i
< SLB_CACHE_ENTRIES
; i
++)
2146 printf(" slb_cache[%d]: = 0x%016lx\n", i
, p
->slb_cache
[i
]);
2148 DUMP(p
, dscr_default
, "llx");
2149 #ifdef CONFIG_PPC_BOOK3E
2151 DUMP(p
, kernel_pgd
, "p");
2152 DUMP(p
, tcd_ptr
, "p");
2153 DUMP(p
, mc_kstack
, "p");
2154 DUMP(p
, crit_kstack
, "p");
2155 DUMP(p
, dbg_kstack
, "p");
2157 DUMP(p
, __current
, "p");
2158 DUMP(p
, kstack
, "lx");
2159 DUMP(p
, stab_rr
, "lx");
2160 DUMP(p
, saved_r1
, "lx");
2161 DUMP(p
, trap_save
, "x");
2162 DUMP(p
, soft_enabled
, "x");
2163 DUMP(p
, irq_happened
, "x");
2164 DUMP(p
, io_sync
, "x");
2165 DUMP(p
, irq_work_pending
, "x");
2166 DUMP(p
, nap_state_lost
, "x");
2167 DUMP(p
, sprg_vdso
, "llx");
2169 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2170 DUMP(p
, tm_scratch
, "llx");
2173 #ifdef CONFIG_PPC_POWERNV
2174 DUMP(p
, core_idle_state_ptr
, "p");
2175 DUMP(p
, thread_idle_state
, "x");
2176 DUMP(p
, thread_mask
, "x");
2177 DUMP(p
, subcore_sibling_mask
, "x");
2180 DUMP(p
, user_time
, "llx");
2181 DUMP(p
, system_time
, "llx");
2182 DUMP(p
, user_time_scaled
, "llx");
2183 DUMP(p
, starttime
, "llx");
2184 DUMP(p
, starttime_user
, "llx");
2185 DUMP(p
, startspurr
, "llx");
2186 DUMP(p
, utime_sspurr
, "llx");
2187 DUMP(p
, stolen_time
, "llx");
2190 catch_memory_errors
= 0;
2194 static void dump_all_pacas(void)
2198 if (num_possible_cpus() == 0) {
2199 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2203 for_each_possible_cpu(cpu
)
2207 static void dump_pacas(void)
2218 termch
= c
; /* Put c back, it wasn't 'a' */
2223 dump_one_paca(xmon_owner
);
2236 xmon_start_pagination();
2238 xmon_end_pagination();
2243 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2245 scanhex((void *)&adrs
);
2252 else if (nidump
> MAX_DUMP
)
2254 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2256 } else if (c
== 'l') {
2258 } else if (c
== 'r') {
2262 xmon_rawdump(adrs
, ndump
);
2269 else if (ndump
> MAX_DUMP
)
2271 prdump(adrs
, ndump
);
2278 prdump(unsigned long adrs
, long ndump
)
2280 long n
, m
, c
, r
, nr
;
2281 unsigned char temp
[16];
2283 for (n
= ndump
; n
> 0;) {
2287 nr
= mread(adrs
, temp
, r
);
2289 for (m
= 0; m
< r
; ++m
) {
2290 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2293 printf("%.2x", temp
[m
]);
2295 printf("%s", fault_chars
[fault_type
]);
2297 for (; m
< 16; ++m
) {
2298 if ((m
& (sizeof(long) - 1)) == 0)
2303 for (m
= 0; m
< r
; ++m
) {
2306 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2319 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2322 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2323 instruction_dump_func dump_func
)
2326 unsigned long first_adr
;
2327 unsigned long inst
, last_inst
= 0;
2328 unsigned char val
[4];
2331 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2332 nr
= mread(adr
, val
, 4);
2335 const char *x
= fault_chars
[fault_type
];
2336 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2340 inst
= GETWORD(val
);
2341 if (adr
> first_adr
&& inst
== last_inst
) {
2351 printf(REG
" %.8x", adr
, inst
);
2353 dump_func(inst
, adr
);
2356 return adr
- first_adr
;
2360 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2362 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2366 print_address(unsigned long addr
)
2368 xmon_print_symbol(addr
, "\t# ", "");
2374 struct kmsg_dumper dumper
= { .active
= 1 };
2375 unsigned char buf
[128];
2378 if (setjmp(bus_error_jmp
) != 0) {
2379 printf("Error dumping printk buffer!\n");
2383 catch_memory_errors
= 1;
2386 kmsg_dump_rewind_nolock(&dumper
);
2387 xmon_start_pagination();
2388 while (kmsg_dump_get_line_nolock(&dumper
, false, buf
, sizeof(buf
), &len
)) {
2392 xmon_end_pagination();
2395 /* wait a little while to see if we get a machine check */
2397 catch_memory_errors
= 0;
2401 * Memory operations - move, set, print differences
2403 static unsigned long mdest
; /* destination address */
2404 static unsigned long msrc
; /* source address */
2405 static unsigned long mval
; /* byte value to set memory to */
2406 static unsigned long mcount
; /* # bytes to affect */
2407 static unsigned long mdiffs
; /* max # differences to print */
2412 scanhex((void *)&mdest
);
2413 if( termch
!= '\n' )
2415 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2416 if( termch
!= '\n' )
2418 scanhex((void *)&mcount
);
2421 memmove((void *)mdest
, (void *)msrc
, mcount
);
2424 memset((void *)mdest
, mval
, mcount
);
2427 if( termch
!= '\n' )
2429 scanhex((void *)&mdiffs
);
2430 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2436 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2441 for( n
= nb
; n
> 0; --n
)
2442 if( *p1
++ != *p2
++ )
2443 if( ++prt
<= maxpr
)
2444 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2445 p1
[-1], p2
- 1, p2
[-1]);
2447 printf("Total of %d differences\n", prt
);
2450 static unsigned mend
;
2451 static unsigned mask
;
2457 unsigned char val
[4];
2460 scanhex((void *)&mdest
);
2461 if (termch
!= '\n') {
2463 scanhex((void *)&mend
);
2464 if (termch
!= '\n') {
2466 scanhex((void *)&mval
);
2468 if (termch
!= '\n') termch
= 0;
2469 scanhex((void *)&mask
);
2473 for (a
= mdest
; a
< mend
; a
+= 4) {
2474 if (mread(a
, val
, 4) == 4
2475 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2476 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2483 static unsigned long mskip
= 0x1000;
2484 static unsigned long mlim
= 0xffffffff;
2494 if (termch
!= '\n') termch
= 0;
2496 if (termch
!= '\n') termch
= 0;
2499 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2500 ok
= mread(a
, &v
, 1);
2502 printf("%.8x .. ", a
);
2503 } else if (!ok
&& ook
)
2504 printf("%.8x\n", a
- mskip
);
2510 printf("%.8x\n", a
- mskip
);
2513 static void proccall(void)
2515 unsigned long args
[8];
2518 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2519 unsigned long, unsigned long, unsigned long,
2520 unsigned long, unsigned long, unsigned long);
2523 if (!scanhex(&adrs
))
2527 for (i
= 0; i
< 8; ++i
)
2529 for (i
= 0; i
< 8; ++i
) {
2530 if (!scanhex(&args
[i
]) || termch
== '\n')
2534 func
= (callfunc_t
) adrs
;
2536 if (setjmp(bus_error_jmp
) == 0) {
2537 catch_memory_errors
= 1;
2539 ret
= func(args
[0], args
[1], args
[2], args
[3],
2540 args
[4], args
[5], args
[6], args
[7]);
2542 printf("return value is 0x%lx\n", ret
);
2544 printf("*** %x exception occurred\n", fault_except
);
2546 catch_memory_errors
= 0;
2549 /* Input scanning routines */
2560 while( c
== ' ' || c
== '\t' )
2566 static char *regnames
[N_PTREGS
] = {
2567 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2568 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2569 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2570 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2571 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2577 "trap", "dar", "dsisr", "res"
2581 scanhex(unsigned long *vp
)
2588 /* parse register name */
2592 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2601 for (i
= 0; i
< N_PTREGS
; ++i
) {
2602 if (strcmp(regnames
[i
], regname
) == 0) {
2603 if (xmon_regs
== NULL
) {
2604 printf("regs not available\n");
2607 *vp
= ((unsigned long *)xmon_regs
)[i
];
2611 printf("invalid register name '%%%s'\n", regname
);
2615 /* skip leading "0x" if any */
2629 } else if (c
== '$') {
2631 for (i
=0; i
<63; i
++) {
2633 if (isspace(c
) || c
== '\0') {
2641 if (setjmp(bus_error_jmp
) == 0) {
2642 catch_memory_errors
= 1;
2644 *vp
= kallsyms_lookup_name(tmpstr
);
2647 catch_memory_errors
= 0;
2649 printf("unknown symbol '%s'\n", tmpstr
);
2682 static int hexdigit(int c
)
2684 if( '0' <= c
&& c
<= '9' )
2686 if( 'A' <= c
&& c
<= 'F' )
2687 return c
- ('A' - 10);
2688 if( 'a' <= c
&& c
<= 'f' )
2689 return c
- ('a' - 10);
2694 getstring(char *s
, int size
)
2705 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2710 static char line
[256];
2711 static char *lineptr
;
2722 if (lineptr
== NULL
|| *lineptr
== 0) {
2723 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2733 take_input(char *str
)
2742 int type
= inchar();
2744 static char tmp
[64];
2749 xmon_print_symbol(addr
, ": ", "\n");
2754 if (setjmp(bus_error_jmp
) == 0) {
2755 catch_memory_errors
= 1;
2757 addr
= kallsyms_lookup_name(tmp
);
2759 printf("%s: %lx\n", tmp
, addr
);
2761 printf("Symbol '%s' not found.\n", tmp
);
2764 catch_memory_errors
= 0;
2771 /* Print an address in numeric and symbolic form (if possible) */
2772 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2776 const char *name
= NULL
;
2777 unsigned long offset
, size
;
2779 printf(REG
, address
);
2780 if (setjmp(bus_error_jmp
) == 0) {
2781 catch_memory_errors
= 1;
2783 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2786 /* wait a little while to see if we get a machine check */
2790 catch_memory_errors
= 0;
2793 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2795 printf(" [%s]", modname
);
2797 printf("%s", after
);
2800 #ifdef CONFIG_PPC_BOOK3S_64
2801 void dump_segments(void)
2804 unsigned long esid
,vsid
;
2807 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2809 for (i
= 0; i
< mmu_slb_size
; i
++) {
2810 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2811 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2813 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2814 if (esid
& SLB_ESID_V
) {
2815 llp
= vsid
& SLB_VSID_LLP
;
2816 if (vsid
& SLB_VSID_B_1T
) {
2817 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2819 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2822 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2824 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2834 #ifdef CONFIG_PPC_STD_MMU_32
2835 void dump_segments(void)
2840 for (i
= 0; i
< 16; ++i
)
2841 printf(" %x", mfsrin(i
));
2847 static void dump_tlb_44x(void)
2851 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2852 unsigned long w0
,w1
,w2
;
2853 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2854 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2855 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2856 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2857 if (w0
& PPC44x_TLB_VALID
) {
2858 printf("V %08x -> %01x%08x %c%c%c%c%c",
2859 w0
& PPC44x_TLB_EPN_MASK
,
2860 w1
& PPC44x_TLB_ERPN_MASK
,
2861 w1
& PPC44x_TLB_RPN_MASK
,
2862 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2863 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2864 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2865 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2866 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2871 #endif /* CONFIG_44x */
2873 #ifdef CONFIG_PPC_BOOK3E
2874 static void dump_tlb_book3e(void)
2876 u32 mmucfg
, pidmask
, lpidmask
;
2878 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
2880 static const char *pgsz_names
[] = {
2915 /* Gather some infos about the MMU */
2916 mmucfg
= mfspr(SPRN_MMUCFG
);
2917 mmu_version
= (mmucfg
& 3) + 1;
2918 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
2919 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
2920 lpidsz
= (mmucfg
>> 24) & 0xf;
2921 rasz
= (mmucfg
>> 16) & 0x7f;
2922 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
2924 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2925 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
2926 pidmask
= (1ul << pidsz
) - 1;
2927 lpidmask
= (1ul << lpidsz
) - 1;
2928 ramask
= (1ull << rasz
) - 1;
2930 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
2932 int nent
, assoc
, new_cc
= 1;
2933 printf("TLB %d:\n------\n", tlb
);
2936 tlbcfg
= mfspr(SPRN_TLB0CFG
);
2939 tlbcfg
= mfspr(SPRN_TLB1CFG
);
2942 tlbcfg
= mfspr(SPRN_TLB2CFG
);
2945 tlbcfg
= mfspr(SPRN_TLB3CFG
);
2948 printf("Unsupported TLB number !\n");
2951 nent
= tlbcfg
& 0xfff;
2952 assoc
= (tlbcfg
>> 24) & 0xff;
2953 for (i
= 0; i
< nent
; i
++) {
2954 u32 mas0
= MAS0_TLBSEL(tlb
);
2955 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
2958 int esel
= i
, cc
= i
;
2966 mas0
|= MAS0_ESEL(esel
);
2967 mtspr(SPRN_MAS0
, mas0
);
2968 mtspr(SPRN_MAS1
, mas1
);
2969 mtspr(SPRN_MAS2
, mas2
);
2970 asm volatile("tlbre 0,0,0" : : : "memory");
2971 mas1
= mfspr(SPRN_MAS1
);
2972 mas2
= mfspr(SPRN_MAS2
);
2973 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
2974 if (assoc
&& (i
% assoc
) == 0)
2976 if (!(mas1
& MAS1_VALID
))
2979 printf("%04x- ", i
);
2981 printf("%04x-%c", cc
, 'A' + esel
);
2983 printf(" |%c", 'A' + esel
);
2985 printf(" %016llx %04x %s %c%c AS%c",
2987 (mas1
>> 16) & 0x3fff,
2988 pgsz_names
[(mas1
>> 7) & 0x1f],
2989 mas1
& MAS1_IND
? 'I' : ' ',
2990 mas1
& MAS1_IPROT
? 'P' : ' ',
2991 mas1
& MAS1_TS
? '1' : '0');
2992 printf(" %c%c%c%c%c%c%c",
2993 mas2
& MAS2_X0
? 'a' : ' ',
2994 mas2
& MAS2_X1
? 'v' : ' ',
2995 mas2
& MAS2_W
? 'w' : ' ',
2996 mas2
& MAS2_I
? 'i' : ' ',
2997 mas2
& MAS2_M
? 'm' : ' ',
2998 mas2
& MAS2_G
? 'g' : ' ',
2999 mas2
& MAS2_E
? 'e' : ' ');
3000 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
3001 if (mas1
& MAS1_IND
)
3003 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
3005 printf(" U%c%c%c S%c%c%c\n",
3006 mas7_mas3
& MAS3_UX
? 'x' : ' ',
3007 mas7_mas3
& MAS3_UW
? 'w' : ' ',
3008 mas7_mas3
& MAS3_UR
? 'r' : ' ',
3009 mas7_mas3
& MAS3_SX
? 'x' : ' ',
3010 mas7_mas3
& MAS3_SW
? 'w' : ' ',
3011 mas7_mas3
& MAS3_SR
? 'r' : ' ');
3015 #endif /* CONFIG_PPC_BOOK3E */
3017 static void xmon_init(int enable
)
3021 __debugger_ipi
= xmon_ipi
;
3022 __debugger_bpt
= xmon_bpt
;
3023 __debugger_sstep
= xmon_sstep
;
3024 __debugger_iabr_match
= xmon_iabr_match
;
3025 __debugger_break_match
= xmon_break_match
;
3026 __debugger_fault_handler
= xmon_fault_handler
;
3029 __debugger_ipi
= NULL
;
3030 __debugger_bpt
= NULL
;
3031 __debugger_sstep
= NULL
;
3032 __debugger_iabr_match
= NULL
;
3033 __debugger_break_match
= NULL
;
3034 __debugger_fault_handler
= NULL
;
3038 #ifdef CONFIG_MAGIC_SYSRQ
3039 static void sysrq_handle_xmon(int key
)
3041 /* ensure xmon is enabled */
3043 debugger(get_irq_regs());
3046 static struct sysrq_key_op sysrq_xmon_op
= {
3047 .handler
= sysrq_handle_xmon
,
3048 .help_msg
= "xmon(x)",
3049 .action_msg
= "Entering xmon",
3052 static int __init
setup_xmon_sysrq(void)
3054 register_sysrq_key('x', &sysrq_xmon_op
);
3057 __initcall(setup_xmon_sysrq
);
3058 #endif /* CONFIG_MAGIC_SYSRQ */
3060 static int __initdata xmon_early
, xmon_off
;
3062 static int __init
early_parse_xmon(char *p
)
3064 if (!p
|| strncmp(p
, "early", 5) == 0) {
3065 /* just "xmon" is equivalent to "xmon=early" */
3068 } else if (strncmp(p
, "on", 2) == 0)
3070 else if (strncmp(p
, "off", 3) == 0)
3072 else if (strncmp(p
, "nobt", 4) == 0)
3073 xmon_no_auto_backtrace
= 1;
3079 early_param("xmon", early_parse_xmon
);
3081 void __init
xmon_setup(void)
3083 #ifdef CONFIG_XMON_DEFAULT
3091 #ifdef CONFIG_SPU_BASE
3095 u64 saved_mfc_sr1_RW
;
3096 u32 saved_spu_runcntl_RW
;
3097 unsigned long dump_addr
;
3101 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3103 static struct spu_info spu_info
[XMON_NUM_SPUS
];
3105 void xmon_register_spus(struct list_head
*list
)
3109 list_for_each_entry(spu
, list
, full_list
) {
3110 if (spu
->number
>= XMON_NUM_SPUS
) {
3115 spu_info
[spu
->number
].spu
= spu
;
3116 spu_info
[spu
->number
].stopped_ok
= 0;
3117 spu_info
[spu
->number
].dump_addr
= (unsigned long)
3118 spu_info
[spu
->number
].spu
->local_store
;
3122 static void stop_spus(void)
3128 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3129 if (!spu_info
[i
].spu
)
3132 if (setjmp(bus_error_jmp
) == 0) {
3133 catch_memory_errors
= 1;
3136 spu
= spu_info
[i
].spu
;
3138 spu_info
[i
].saved_spu_runcntl_RW
=
3139 in_be32(&spu
->problem
->spu_runcntl_RW
);
3141 tmp
= spu_mfc_sr1_get(spu
);
3142 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
3144 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
3145 spu_mfc_sr1_set(spu
, tmp
);
3150 spu_info
[i
].stopped_ok
= 1;
3152 printf("Stopped spu %.2d (was %s)\n", i
,
3153 spu_info
[i
].saved_spu_runcntl_RW
?
3154 "running" : "stopped");
3156 catch_memory_errors
= 0;
3157 printf("*** Error stopping spu %.2d\n", i
);
3159 catch_memory_errors
= 0;
3163 static void restart_spus(void)
3168 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3169 if (!spu_info
[i
].spu
)
3172 if (!spu_info
[i
].stopped_ok
) {
3173 printf("*** Error, spu %d was not successfully stopped"
3174 ", not restarting\n", i
);
3178 if (setjmp(bus_error_jmp
) == 0) {
3179 catch_memory_errors
= 1;
3182 spu
= spu_info
[i
].spu
;
3183 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
3184 out_be32(&spu
->problem
->spu_runcntl_RW
,
3185 spu_info
[i
].saved_spu_runcntl_RW
);
3190 printf("Restarted spu %.2d\n", i
);
3192 catch_memory_errors
= 0;
3193 printf("*** Error restarting spu %.2d\n", i
);
3195 catch_memory_errors
= 0;
3199 #define DUMP_WIDTH 23
3200 #define DUMP_VALUE(format, field, value) \
3202 if (setjmp(bus_error_jmp) == 0) { \
3203 catch_memory_errors = 1; \
3205 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3210 catch_memory_errors = 0; \
3211 printf(" %-*s = *** Error reading field.\n", \
3212 DUMP_WIDTH, #field); \
3214 catch_memory_errors = 0; \
3217 #define DUMP_FIELD(obj, format, field) \
3218 DUMP_VALUE(format, field, obj->field)
3220 static void dump_spu_fields(struct spu
*spu
)
3222 printf("Dumping spu fields at address %p:\n", spu
);
3224 DUMP_FIELD(spu
, "0x%x", number
);
3225 DUMP_FIELD(spu
, "%s", name
);
3226 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3227 DUMP_FIELD(spu
, "0x%p", local_store
);
3228 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3229 DUMP_FIELD(spu
, "0x%x", node
);
3230 DUMP_FIELD(spu
, "0x%lx", flags
);
3231 DUMP_FIELD(spu
, "%d", class_0_pending
);
3232 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
3233 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
3234 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
3235 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
3236 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
3237 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
3238 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3239 DUMP_FIELD(spu
, "%d", pid
);
3240 DUMP_FIELD(spu
, "0x%p", mm
);
3241 DUMP_FIELD(spu
, "0x%p", ctx
);
3242 DUMP_FIELD(spu
, "0x%p", rq
);
3243 DUMP_FIELD(spu
, "0x%p", timestamp
);
3244 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3245 DUMP_FIELD(spu
, "0x%p", problem
);
3246 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3247 in_be32(&spu
->problem
->spu_runcntl_RW
));
3248 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3249 in_be32(&spu
->problem
->spu_status_R
));
3250 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3251 in_be32(&spu
->problem
->spu_npc_RW
));
3252 DUMP_FIELD(spu
, "0x%p", priv2
);
3253 DUMP_FIELD(spu
, "0x%p", pdata
);
3257 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3259 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3262 static void dump_spu_ls(unsigned long num
, int subcmd
)
3264 unsigned long offset
, addr
, ls_addr
;
3266 if (setjmp(bus_error_jmp
) == 0) {
3267 catch_memory_errors
= 1;
3269 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3273 catch_memory_errors
= 0;
3274 printf("*** Error: accessing spu info for spu %d\n", num
);
3277 catch_memory_errors
= 0;
3279 if (scanhex(&offset
))
3280 addr
= ls_addr
+ offset
;
3282 addr
= spu_info
[num
].dump_addr
;
3284 if (addr
>= ls_addr
+ LS_SIZE
) {
3285 printf("*** Error: address outside of local store\n");
3291 addr
+= spu_inst_dump(addr
, 16, 1);
3301 spu_info
[num
].dump_addr
= addr
;
3304 static int do_spu_cmd(void)
3306 static unsigned long num
= 0;
3307 int cmd
, subcmd
= 0;
3319 if (isxdigit(subcmd
) || subcmd
== '\n')
3323 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3324 printf("*** Error: invalid spu number\n");
3330 dump_spu_fields(spu_info
[num
].spu
);
3333 dump_spu_ls(num
, subcmd
);
3344 #else /* ! CONFIG_SPU_BASE */
3345 static int do_spu_cmd(void)