2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/smp.h>
17 #include <linux/reboot.h>
18 #include <linux/delay.h>
19 #include <linux/kallsyms.h>
20 #include <linux/cpumask.h>
21 #include <linux/module.h>
22 #include <linux/sysrq.h>
23 #include <linux/interrupt.h>
24 #include <linux/irq.h>
25 #include <linux/bug.h>
27 #include <asm/ptrace.h>
28 #include <asm/string.h>
30 #include <asm/machdep.h>
32 #include <asm/processor.h>
33 #include <asm/pgtable.h>
35 #include <asm/mmu_context.h>
36 #include <asm/cputable.h>
38 #include <asm/sstep.h>
39 #include <asm/irq_regs.h>
41 #include <asm/spu_priv1.h>
42 #include <asm/firmware.h>
43 #include <asm/setjmp.h>
47 #include <asm/hvcall.h>
54 #define scanhex xmon_scanhex
55 #define skipbl xmon_skipbl
58 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
59 static unsigned long xmon_taken
= 1;
60 static int xmon_owner
;
62 #endif /* CONFIG_SMP */
64 static unsigned long in_xmon
= 0;
66 static unsigned long adrs
;
68 #define MAX_DUMP (128 * 1024)
69 static unsigned long ndump
= 64;
70 static unsigned long nidump
= 16;
71 static unsigned long ncsum
= 4096;
73 static char tmpstr
[128];
75 static long bus_error_jmp
[JMP_BUF_LEN
];
76 static int catch_memory_errors
;
77 static long *xmon_fault_jmp
[NR_CPUS
];
79 /* Breakpoint stuff */
81 unsigned long address
;
82 unsigned int instr
[2];
88 /* Bits in bpt.enabled */
89 #define BP_IABR_TE 1 /* IABR translation enabled */
95 static struct bpt bpts
[NBPTS
];
96 static struct bpt dabr
;
97 static struct bpt
*iabr
;
98 static unsigned bpinstr
= 0x7fe00008; /* trap */
100 #define BP_NUM(bp) ((bp) - bpts + 1)
103 static int cmds(struct pt_regs
*);
104 static int mread(unsigned long, void *, int);
105 static int mwrite(unsigned long, void *, int);
106 static int handle_fault(struct pt_regs
*);
107 static void byterev(unsigned char *, int);
108 static void memex(void);
109 static int bsesc(void);
110 static void dump(void);
111 static void prdump(unsigned long, long);
112 static int ppc_inst_dump(unsigned long, long, int);
113 static void backtrace(struct pt_regs
*);
114 static void excprint(struct pt_regs
*);
115 static void prregs(struct pt_regs
*);
116 static void memops(int);
117 static void memlocate(void);
118 static void memzcan(void);
119 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
121 int scanhex(unsigned long *valp
);
122 static void scannl(void);
123 static int hexdigit(int);
124 void getstring(char *, int);
125 static void flush_input(void);
126 static int inchar(void);
127 static void take_input(char *);
128 static unsigned long read_spr(int);
129 static void write_spr(int, unsigned long);
130 static void super_regs(void);
131 static void remove_bpts(void);
132 static void insert_bpts(void);
133 static void remove_cpu_bpts(void);
134 static void insert_cpu_bpts(void);
135 static struct bpt
*at_breakpoint(unsigned long pc
);
136 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
137 static int do_step(struct pt_regs
*);
138 static void bpt_cmds(void);
139 static void cacheflush(void);
140 static int cpu_cmd(void);
141 static void csum(void);
142 static void bootcmds(void);
143 static void proccall(void);
144 void dump_segments(void);
145 static void symbol_lookup(void);
146 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
148 static void xmon_print_symbol(unsigned long address
, const char *mid
,
150 static const char *getvecname(unsigned long vec
);
152 static int do_spu_cmd(void);
155 static void dump_tlb_44x(void);
158 static int xmon_no_auto_backtrace
;
160 extern void xmon_enter(void);
161 extern void xmon_leave(void);
165 #define REGS_PER_LINE 4
166 #define LAST_VOLATILE 13
169 #define REGS_PER_LINE 8
170 #define LAST_VOLATILE 12
173 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
175 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
176 || ('a' <= (c) && (c) <= 'f') \
177 || ('A' <= (c) && (c) <= 'F'))
178 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
179 || ('a' <= (c) && (c) <= 'z') \
180 || ('A' <= (c) && (c) <= 'Z'))
181 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
183 static char *help_string
= "\
185 b show breakpoints\n\
186 bd set data breakpoint\n\
187 bi set instruction breakpoint\n\
188 bc clear breakpoint\n"
191 c print cpus stopped in xmon\n\
192 c# try to switch to cpu number h (in hex)\n"
197 di dump instructions\n\
198 df dump float values\n\
199 dd dump double values\n\
200 dr dump stream of raw bytes\n\
201 e print exception information\n\
203 la lookup symbol+offset of specified address\n\
204 ls lookup address of specified symbol\n\
205 m examine/change memory\n\
206 mm move a block of memory\n\
207 ms set a block of memory\n\
208 md compare two blocks of memory\n\
209 ml locate a block of memory\n\
210 mz zero a block of memory\n\
211 mi show information about memory allocation\n\
212 p call a procedure\n\
215 #ifdef CONFIG_SPU_BASE
216 " ss stop execution on all spus\n\
217 sr restore execution on stopped spus\n\
218 sf # dump spu fields for spu # (in hex)\n\
219 sd # dump spu local store for spu # (in hex)\n\
220 sdi # disassemble spu local store for spu # (in hex)\n"
222 " S print special registers\n\
224 x exit monitor and recover\n\
225 X exit monitor and dont recover\n"
227 " u dump segment table or SLB\n"
229 #ifdef CONFIG_PPC_STD_MMU_32
230 " u dump segment registers\n"
240 static struct pt_regs
*xmon_regs
;
242 static inline void sync(void)
244 asm volatile("sync; isync");
247 static inline void store_inst(void *p
)
249 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
252 static inline void cflush(void *p
)
254 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
257 static inline void cinval(void *p
)
259 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
263 * Disable surveillance (the service processor watchdog function)
264 * while we are in xmon.
265 * XXX we should re-enable it when we leave. :)
267 #define SURVEILLANCE_TOKEN 9000
269 static inline void disable_surveillance(void)
271 #ifdef CONFIG_PPC_PSERIES
272 /* Since this can't be a module, args should end up below 4GB. */
273 static struct rtas_args args
;
276 * At this point we have got all the cpus we can into
277 * xmon, so there is hopefully no other cpu calling RTAS
278 * at the moment, even though we don't take rtas.lock.
279 * If we did try to take rtas.lock there would be a
280 * real possibility of deadlock.
282 args
.token
= rtas_token("set-indicator");
283 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
287 args
.rets
= &args
.args
[3];
288 args
.args
[0] = SURVEILLANCE_TOKEN
;
291 enter_rtas(__pa(&args
));
292 #endif /* CONFIG_PPC_PSERIES */
296 static int xmon_speaker
;
298 static void get_output_lock(void)
300 int me
= smp_processor_id() + 0x100;
301 int last_speaker
= 0, prev
;
304 if (xmon_speaker
== me
)
307 if (xmon_speaker
== 0) {
308 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
309 if (last_speaker
== 0)
313 while (xmon_speaker
== last_speaker
) {
316 /* hostile takeover */
317 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
318 if (prev
== last_speaker
)
325 static void release_output_lock(void)
330 int cpus_are_in_xmon(void)
332 return !cpus_empty(cpus_in_xmon
);
336 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
340 long recurse_jmp
[JMP_BUF_LEN
];
341 unsigned long offset
;
346 unsigned long timeout
;
349 local_irq_save(flags
);
351 bp
= in_breakpoint_table(regs
->nip
, &offset
);
353 regs
->nip
= bp
->address
+ offset
;
354 atomic_dec(&bp
->ref_count
);
360 cpu
= smp_processor_id();
361 if (cpu_isset(cpu
, cpus_in_xmon
)) {
364 printf("cpu 0x%x: Exception %lx %s in xmon, "
365 "returning to main loop\n",
366 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
367 release_output_lock();
368 longjmp(xmon_fault_jmp
[cpu
], 1);
371 if (setjmp(recurse_jmp
) != 0) {
372 if (!in_xmon
|| !xmon_gate
) {
374 printf("xmon: WARNING: bad recursive fault "
375 "on cpu 0x%x\n", cpu
);
376 release_output_lock();
379 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
383 xmon_fault_jmp
[cpu
] = recurse_jmp
;
384 cpu_set(cpu
, cpus_in_xmon
);
387 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
))
388 bp
= at_breakpoint(regs
->nip
);
389 if (bp
|| (regs
->msr
& MSR_RI
) == 0)
396 printf("cpu 0x%x stopped at breakpoint 0x%x (",
398 xmon_print_symbol(regs
->nip
, " ", ")\n");
400 if ((regs
->msr
& MSR_RI
) == 0)
401 printf("WARNING: exception is not recoverable, "
403 release_output_lock();
408 while (secondary
&& !xmon_gate
) {
412 secondary
= test_and_set_bit(0, &in_xmon
);
417 if (!secondary
&& !xmon_gate
) {
418 /* we are the first cpu to come in */
419 /* interrupt other cpu(s) */
420 int ncpus
= num_online_cpus();
425 smp_send_debugger_break(MSG_ALL_BUT_SELF
);
426 /* wait for other cpus to come in */
427 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
428 if (cpus_weight(cpus_in_xmon
) >= ncpus
)
434 disable_surveillance();
435 /* for breakpoint or single step, print the current instr. */
436 if (bp
|| TRAP(regs
) == 0xd00)
437 ppc_inst_dump(regs
->nip
, 1, 0);
438 printf("enter ? for help\n");
447 if (cpu
== xmon_owner
) {
448 if (!test_and_set_bit(0, &xmon_taken
)) {
453 while (cpu
== xmon_owner
)
467 /* have switched to some other cpu */
472 cpu_clear(cpu
, cpus_in_xmon
);
473 xmon_fault_jmp
[cpu
] = NULL
;
475 /* UP is simple... */
477 printf("Exception %lx %s in xmon, returning to main loop\n",
478 regs
->trap
, getvecname(TRAP(regs
)));
479 longjmp(xmon_fault_jmp
[0], 1);
481 if (setjmp(recurse_jmp
) == 0) {
482 xmon_fault_jmp
[0] = recurse_jmp
;
486 bp
= at_breakpoint(regs
->nip
);
488 printf("Stopped at breakpoint %x (", BP_NUM(bp
));
489 xmon_print_symbol(regs
->nip
, " ", ")\n");
491 if ((regs
->msr
& MSR_RI
) == 0)
492 printf("WARNING: exception is not recoverable, "
495 disable_surveillance();
496 /* for breakpoint or single step, print the current instr. */
497 if (bp
|| TRAP(regs
) == 0xd00)
498 ppc_inst_dump(regs
->nip
, 1, 0);
499 printf("enter ? for help\n");
508 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
509 bp
= at_breakpoint(regs
->nip
);
511 int stepped
= emulate_step(regs
, bp
->instr
[0]);
513 regs
->nip
= (unsigned long) &bp
->instr
[0];
514 atomic_inc(&bp
->ref_count
);
515 } else if (stepped
< 0) {
516 printf("Couldn't single-step %s instruction\n",
517 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
524 local_irq_restore(flags
);
526 return cmd
!= 'X' && cmd
!= EOF
;
529 int xmon(struct pt_regs
*excp
)
534 ppc_save_regs(®s
);
538 return xmon_core(excp
, 0);
542 irqreturn_t
xmon_irq(int irq
, void *d
)
545 local_irq_save(flags
);
546 printf("Keyboard interrupt\n");
547 xmon(get_irq_regs());
548 local_irq_restore(flags
);
552 static int xmon_bpt(struct pt_regs
*regs
)
555 unsigned long offset
;
557 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
560 /* Are we at the trap at bp->instr[1] for some bp? */
561 bp
= in_breakpoint_table(regs
->nip
, &offset
);
562 if (bp
!= NULL
&& offset
== 4) {
563 regs
->nip
= bp
->address
+ 4;
564 atomic_dec(&bp
->ref_count
);
568 /* Are we at a breakpoint? */
569 bp
= at_breakpoint(regs
->nip
);
578 static int xmon_sstep(struct pt_regs
*regs
)
586 static int xmon_dabr_match(struct pt_regs
*regs
)
588 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
590 if (dabr
.enabled
== 0)
596 static int xmon_iabr_match(struct pt_regs
*regs
)
598 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
606 static int xmon_ipi(struct pt_regs
*regs
)
609 if (in_xmon
&& !cpu_isset(smp_processor_id(), cpus_in_xmon
))
615 static int xmon_fault_handler(struct pt_regs
*regs
)
618 unsigned long offset
;
620 if (in_xmon
&& catch_memory_errors
)
621 handle_fault(regs
); /* doesn't return */
623 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
624 bp
= in_breakpoint_table(regs
->nip
, &offset
);
626 regs
->nip
= bp
->address
+ offset
;
627 atomic_dec(&bp
->ref_count
);
634 static struct bpt
*at_breakpoint(unsigned long pc
)
640 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
641 if (bp
->enabled
&& pc
== bp
->address
)
646 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
650 off
= nip
- (unsigned long) bpts
;
651 if (off
>= sizeof(bpts
))
653 off
%= sizeof(struct bpt
);
654 if (off
!= offsetof(struct bpt
, instr
[0])
655 && off
!= offsetof(struct bpt
, instr
[1]))
657 *offp
= off
- offsetof(struct bpt
, instr
[0]);
658 return (struct bpt
*) (nip
- off
);
661 static struct bpt
*new_breakpoint(unsigned long a
)
666 bp
= at_breakpoint(a
);
670 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
671 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
673 bp
->instr
[1] = bpinstr
;
674 store_inst(&bp
->instr
[1]);
679 printf("Sorry, no free breakpoints. Please clear one first.\n");
683 static void insert_bpts(void)
689 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
690 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
692 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
693 printf("Couldn't read instruction at %lx, "
694 "disabling breakpoint there\n", bp
->address
);
698 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
699 printf("Breakpoint at %lx is on an mtmsrd or rfid "
700 "instruction, disabling it\n", bp
->address
);
704 store_inst(&bp
->instr
[0]);
705 if (bp
->enabled
& BP_IABR
)
707 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
708 printf("Couldn't write instruction at %lx, "
709 "disabling breakpoint there\n", bp
->address
);
710 bp
->enabled
&= ~BP_TRAP
;
713 store_inst((void *)bp
->address
);
717 static void insert_cpu_bpts(void)
720 set_dabr(dabr
.address
| (dabr
.enabled
& 7));
721 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
722 mtspr(SPRN_IABR
, iabr
->address
723 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
726 static void remove_bpts(void)
733 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
734 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
736 if (mread(bp
->address
, &instr
, 4) == 4
738 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
739 printf("Couldn't remove breakpoint at %lx\n",
742 store_inst((void *)bp
->address
);
746 static void remove_cpu_bpts(void)
749 if (cpu_has_feature(CPU_FTR_IABR
))
753 /* Command interpreting routine */
754 static char *last_cmd
;
757 cmds(struct pt_regs
*excp
)
764 if (!xmon_no_auto_backtrace
) {
765 xmon_no_auto_backtrace
= 1;
766 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
771 printf("%x:", smp_processor_id());
772 #endif /* CONFIG_SMP */
778 if (last_cmd
== NULL
)
780 take_input(last_cmd
);
814 prregs(excp
); /* print regs */
829 if (do_spu_cmd() == 0)
838 printf(" <no input ...>\n");
842 xmon_puts(help_string
);
860 #ifdef CONFIG_PPC_STD_MMU
871 printf("Unrecognized command: ");
873 if (' ' < cmd
&& cmd
<= '~')
876 printf("\\x%x", cmd
);
878 } while (cmd
!= '\n');
879 printf(" (type ? for help)\n");
886 * Step a single instruction.
887 * Some instructions we emulate, others we execute with MSR_SE set.
889 static int do_step(struct pt_regs
*regs
)
894 /* check we are in 64-bit kernel mode, translation enabled */
895 if ((regs
->msr
& (MSR_SF
|MSR_PR
|MSR_IR
)) == (MSR_SF
|MSR_IR
)) {
896 if (mread(regs
->nip
, &instr
, 4) == 4) {
897 stepped
= emulate_step(regs
, instr
);
899 printf("Couldn't single-step %s instruction\n",
900 (IS_RFID(instr
)? "rfid": "mtmsrd"));
904 regs
->trap
= 0xd00 | (regs
->trap
& 1);
905 printf("stepped to ");
906 xmon_print_symbol(regs
->nip
, " ", "\n");
907 ppc_inst_dump(regs
->nip
, 1, 0);
916 static void bootcmds(void)
922 ppc_md
.restart(NULL
);
929 static int cpu_cmd(void)
936 if (!scanhex(&cpu
)) {
937 /* print cpus waiting or in xmon */
938 printf("cpus stopped:");
940 for (cpu
= 0; cpu
< NR_CPUS
; ++cpu
) {
941 if (cpu_isset(cpu
, cpus_in_xmon
)) {
947 printf("-%x", cpu
- 1);
952 printf("-%x", NR_CPUS
- 1);
956 /* try to switch to cpu specified */
957 if (!cpu_isset(cpu
, cpus_in_xmon
)) {
958 printf("cpu 0x%x isn't in xmon\n", cpu
);
965 while (!xmon_taken
) {
966 if (--timeout
== 0) {
967 if (test_and_set_bit(0, &xmon_taken
))
969 /* take control back */
971 xmon_owner
= smp_processor_id();
972 printf("cpu %u didn't take control\n", cpu
);
980 #endif /* CONFIG_SMP */
983 static unsigned short fcstab
[256] = {
984 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
985 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
986 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
987 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
988 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
989 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
990 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
991 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
992 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
993 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
994 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
995 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
996 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
997 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
998 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
999 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1000 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1001 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1002 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1003 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1004 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1005 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1006 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1007 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1008 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1009 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1010 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1011 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1012 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1013 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1014 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1015 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1018 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1027 if (!scanhex(&adrs
))
1029 if (!scanhex(&ncsum
))
1032 for (i
= 0; i
< ncsum
; ++i
) {
1033 if (mread(adrs
+i
, &v
, 1) == 0) {
1034 printf("csum stopped at %x\n", adrs
+i
);
1039 printf("%x\n", fcs
);
1043 * Check if this is a suitable place to put a breakpoint.
1045 static long check_bp_loc(unsigned long addr
)
1050 if (!is_kernel_addr(addr
)) {
1051 printf("Breakpoints may only be placed at kernel addresses\n");
1054 if (!mread(addr
, &instr
, sizeof(instr
))) {
1055 printf("Can't read instruction at address %lx\n", addr
);
1058 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1059 printf("Breakpoints may not be placed on mtmsrd or rfid "
1066 static char *breakpoint_help_string
=
1067 "Breakpoint command usage:\n"
1068 "b show breakpoints\n"
1069 "b <addr> [cnt] set breakpoint at given instr addr\n"
1070 "bc clear all breakpoints\n"
1071 "bc <n/addr> clear breakpoint number n or at addr\n"
1072 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1073 "bd <addr> [cnt] set hardware data breakpoint\n"
1083 const char badaddr
[] = "Only kernel addresses are permitted "
1084 "for breakpoints\n";
1089 case 'd': /* bd - hardware data breakpoint */
1094 else if (cmd
== 'w')
1100 if (scanhex(&dabr
.address
)) {
1101 if (!is_kernel_addr(dabr
.address
)) {
1106 dabr
.enabled
= mode
| BP_DABR
;
1110 case 'i': /* bi - hardware instr breakpoint */
1111 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1112 printf("Hardware instruction breakpoint "
1113 "not supported on this cpu\n");
1117 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1122 if (!check_bp_loc(a
))
1124 bp
= new_breakpoint(a
);
1126 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1134 /* clear all breakpoints */
1135 for (i
= 0; i
< NBPTS
; ++i
)
1136 bpts
[i
].enabled
= 0;
1139 printf("All breakpoints cleared\n");
1143 if (a
<= NBPTS
&& a
>= 1) {
1144 /* assume a breakpoint number */
1145 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1147 /* assume a breakpoint address */
1148 bp
= at_breakpoint(a
);
1150 printf("No breakpoint at %x\n", a
);
1155 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1156 xmon_print_symbol(bp
->address
, " ", ")\n");
1164 printf(breakpoint_help_string
);
1169 /* print all breakpoints */
1170 printf(" type address\n");
1172 printf(" data "REG
" [", dabr
.address
);
1173 if (dabr
.enabled
& 1)
1175 if (dabr
.enabled
& 2)
1179 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1182 printf("%2x %s ", BP_NUM(bp
),
1183 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1184 xmon_print_symbol(bp
->address
, " ", "\n");
1189 if (!check_bp_loc(a
))
1191 bp
= new_breakpoint(a
);
1193 bp
->enabled
|= BP_TRAP
;
1198 /* Very cheap human name for vector lookup. */
1200 const char *getvecname(unsigned long vec
)
1205 case 0x100: ret
= "(System Reset)"; break;
1206 case 0x200: ret
= "(Machine Check)"; break;
1207 case 0x300: ret
= "(Data Access)"; break;
1208 case 0x380: ret
= "(Data SLB Access)"; break;
1209 case 0x400: ret
= "(Instruction Access)"; break;
1210 case 0x480: ret
= "(Instruction SLB Access)"; break;
1211 case 0x500: ret
= "(Hardware Interrupt)"; break;
1212 case 0x600: ret
= "(Alignment)"; break;
1213 case 0x700: ret
= "(Program Check)"; break;
1214 case 0x800: ret
= "(FPU Unavailable)"; break;
1215 case 0x900: ret
= "(Decrementer)"; break;
1216 case 0xc00: ret
= "(System Call)"; break;
1217 case 0xd00: ret
= "(Single Step)"; break;
1218 case 0xf00: ret
= "(Performance Monitor)"; break;
1219 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1220 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1226 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1227 unsigned long *endp
)
1229 unsigned long size
, offset
;
1232 *startp
= *endp
= 0;
1235 if (setjmp(bus_error_jmp
) == 0) {
1236 catch_memory_errors
= 1;
1238 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1240 *startp
= pc
- offset
;
1241 *endp
= pc
- offset
+ size
;
1245 catch_memory_errors
= 0;
1248 static int xmon_depth_to_print
= 64;
1250 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1251 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1253 #ifdef __powerpc64__
1254 #define REGS_OFFSET 0x70
1256 #define REGS_OFFSET 16
1259 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1263 unsigned long newsp
;
1264 unsigned long marker
;
1266 struct pt_regs regs
;
1269 if (sp
< PAGE_OFFSET
) {
1271 printf("SP (%lx) is in userspace\n", sp
);
1275 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1276 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1277 printf("Couldn't read stack frame at %lx\n", sp
);
1282 * For the first stack frame, try to work out if
1283 * LR and/or the saved LR value in the bottommost
1284 * stack frame are valid.
1286 if ((pc
| lr
) != 0) {
1287 unsigned long fnstart
, fnend
;
1288 unsigned long nextip
;
1291 get_function_bounds(pc
, &fnstart
, &fnend
);
1294 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1295 sizeof(unsigned long));
1297 if (lr
< PAGE_OFFSET
1298 || (fnstart
<= lr
&& lr
< fnend
))
1300 } else if (lr
== nextip
) {
1302 } else if (lr
>= PAGE_OFFSET
1303 && !(fnstart
<= lr
&& lr
< fnend
)) {
1304 printf("[link register ] ");
1305 xmon_print_symbol(lr
, " ", "\n");
1308 printf("["REG
"] ", sp
);
1309 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1314 printf("["REG
"] ", sp
);
1315 xmon_print_symbol(ip
, " ", "\n");
1318 /* Look for "regshere" marker to see if this is
1319 an exception frame. */
1320 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1321 && marker
== STACK_FRAME_REGS_MARKER
) {
1322 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1324 printf("Couldn't read registers at %lx\n",
1328 printf("--- Exception: %lx %s at ", regs
.trap
,
1329 getvecname(TRAP(®s
)));
1332 xmon_print_symbol(pc
, " ", "\n");
1339 } while (count
++ < xmon_depth_to_print
);
1342 static void backtrace(struct pt_regs
*excp
)
1347 xmon_show_stack(sp
, 0, 0);
1349 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1353 static void print_bug_trap(struct pt_regs
*regs
)
1356 const struct bug_entry
*bug
;
1359 if (regs
->msr
& MSR_PR
)
1360 return; /* not in kernel */
1361 addr
= regs
->nip
; /* address of trap instruction */
1362 if (addr
< PAGE_OFFSET
)
1364 bug
= find_bug(regs
->nip
);
1367 if (is_warning_bug(bug
))
1370 #ifdef CONFIG_DEBUG_BUGVERBOSE
1371 printf("kernel BUG at %s:%u!\n",
1372 bug
->file
, bug
->line
);
1374 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1376 #endif /* CONFIG_BUG */
1379 static void excprint(struct pt_regs
*fp
)
1384 printf("cpu 0x%x: ", smp_processor_id());
1385 #endif /* CONFIG_SMP */
1388 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1390 xmon_print_symbol(fp
->nip
, ": ", "\n");
1392 printf(" lr: ", fp
->link
);
1393 xmon_print_symbol(fp
->link
, ": ", "\n");
1395 printf(" sp: %lx\n", fp
->gpr
[1]);
1396 printf(" msr: %lx\n", fp
->msr
);
1398 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1399 printf(" dar: %lx\n", fp
->dar
);
1401 printf(" dsisr: %lx\n", fp
->dsisr
);
1404 printf(" current = 0x%lx\n", current
);
1406 printf(" paca = 0x%lx\n", get_paca());
1409 printf(" pid = %ld, comm = %s\n",
1410 current
->pid
, current
->comm
);
1417 static void prregs(struct pt_regs
*fp
)
1421 struct pt_regs regs
;
1423 if (scanhex(&base
)) {
1424 if (setjmp(bus_error_jmp
) == 0) {
1425 catch_memory_errors
= 1;
1427 regs
= *(struct pt_regs
*)base
;
1431 catch_memory_errors
= 0;
1432 printf("*** Error reading registers from "REG
"\n",
1436 catch_memory_errors
= 0;
1441 if (FULL_REGS(fp
)) {
1442 for (n
= 0; n
< 16; ++n
)
1443 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1444 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1446 for (n
= 0; n
< 7; ++n
)
1447 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1448 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1451 for (n
= 0; n
< 32; ++n
) {
1452 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1453 (n
& 3) == 3? "\n": " ");
1454 if (n
== 12 && !FULL_REGS(fp
)) {
1461 xmon_print_symbol(fp
->nip
, " ", "\n");
1463 xmon_print_symbol(fp
->link
, " ", "\n");
1464 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1465 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1466 fp
->ctr
, fp
->xer
, fp
->trap
);
1468 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1469 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1472 static void cacheflush(void)
1475 unsigned long nflush
;
1480 scanhex((void *)&adrs
);
1485 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1486 if (setjmp(bus_error_jmp
) == 0) {
1487 catch_memory_errors
= 1;
1491 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1492 cflush((void *) adrs
);
1494 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1495 cinval((void *) adrs
);
1498 /* wait a little while to see if we get a machine check */
1501 catch_memory_errors
= 0;
1504 static unsigned long
1507 unsigned int instrs
[2];
1508 unsigned long (*code
)(void);
1509 unsigned long ret
= -1UL;
1511 unsigned long opd
[3];
1513 opd
[0] = (unsigned long)instrs
;
1516 code
= (unsigned long (*)(void)) opd
;
1518 code
= (unsigned long (*)(void)) instrs
;
1521 /* mfspr r3,n; blr */
1522 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1523 instrs
[1] = 0x4e800020;
1525 store_inst(instrs
+1);
1527 if (setjmp(bus_error_jmp
) == 0) {
1528 catch_memory_errors
= 1;
1534 /* wait a little while to see if we get a machine check */
1543 write_spr(int n
, unsigned long val
)
1545 unsigned int instrs
[2];
1546 unsigned long (*code
)(unsigned long);
1548 unsigned long opd
[3];
1550 opd
[0] = (unsigned long)instrs
;
1553 code
= (unsigned long (*)(unsigned long)) opd
;
1555 code
= (unsigned long (*)(unsigned long)) instrs
;
1558 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1559 instrs
[1] = 0x4e800020;
1561 store_inst(instrs
+1);
1563 if (setjmp(bus_error_jmp
) == 0) {
1564 catch_memory_errors
= 1;
1570 /* wait a little while to see if we get a machine check */
1576 static unsigned long regno
;
1577 extern char exc_prolog
;
1578 extern char dec_exc
;
1580 static void super_regs(void)
1587 unsigned long sp
, toc
;
1588 asm("mr %0,1" : "=r" (sp
) :);
1589 asm("mr %0,2" : "=r" (toc
) :);
1591 printf("msr = "REG
" sprg0= "REG
"\n",
1592 mfmsr(), mfspr(SPRN_SPRG0
));
1593 printf("pvr = "REG
" sprg1= "REG
"\n",
1594 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1595 printf("dec = "REG
" sprg2= "REG
"\n",
1596 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1597 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1598 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1599 #ifdef CONFIG_PPC_ISERIES
1600 if (firmware_has_feature(FW_FEATURE_ISERIES
)) {
1601 struct paca_struct
*ptrPaca
;
1602 struct lppaca
*ptrLpPaca
;
1604 /* Dump out relevant Paca data areas. */
1606 ptrPaca
= get_paca();
1608 printf(" Local Processor Control Area (LpPaca): \n");
1609 ptrLpPaca
= ptrPaca
->lppaca_ptr
;
1610 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1611 ptrLpPaca
->saved_srr0
, ptrLpPaca
->saved_srr1
);
1612 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1613 ptrLpPaca
->saved_gpr3
, ptrLpPaca
->saved_gpr4
);
1614 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca
->saved_gpr5
);
1624 val
= read_spr(regno
);
1626 write_spr(regno
, val
);
1629 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1636 * Stuff for reading and writing memory safely
1639 mread(unsigned long adrs
, void *buf
, int size
)
1645 if (setjmp(bus_error_jmp
) == 0) {
1646 catch_memory_errors
= 1;
1652 *(u16
*)q
= *(u16
*)p
;
1655 *(u32
*)q
= *(u32
*)p
;
1658 *(u64
*)q
= *(u64
*)p
;
1661 for( ; n
< size
; ++n
) {
1667 /* wait a little while to see if we get a machine check */
1671 catch_memory_errors
= 0;
1676 mwrite(unsigned long adrs
, void *buf
, int size
)
1682 if (setjmp(bus_error_jmp
) == 0) {
1683 catch_memory_errors
= 1;
1689 *(u16
*)p
= *(u16
*)q
;
1692 *(u32
*)p
= *(u32
*)q
;
1695 *(u64
*)p
= *(u64
*)q
;
1698 for ( ; n
< size
; ++n
) {
1704 /* wait a little while to see if we get a machine check */
1708 printf("*** Error writing address %x\n", adrs
+ n
);
1710 catch_memory_errors
= 0;
1714 static int fault_type
;
1715 static int fault_except
;
1716 static char *fault_chars
[] = { "--", "**", "##" };
1718 static int handle_fault(struct pt_regs
*regs
)
1720 fault_except
= TRAP(regs
);
1721 switch (TRAP(regs
)) {
1733 longjmp(bus_error_jmp
, 1);
1738 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1741 byterev(unsigned char *val
, int size
)
1747 SWAP(val
[0], val
[1], t
);
1750 SWAP(val
[0], val
[3], t
);
1751 SWAP(val
[1], val
[2], t
);
1753 case 8: /* is there really any use for this? */
1754 SWAP(val
[0], val
[7], t
);
1755 SWAP(val
[1], val
[6], t
);
1756 SWAP(val
[2], val
[5], t
);
1757 SWAP(val
[3], val
[4], t
);
1765 static char *memex_help_string
=
1766 "Memory examine command usage:\n"
1767 "m [addr] [flags] examine/change memory\n"
1768 " addr is optional. will start where left off.\n"
1769 " flags may include chars from this set:\n"
1770 " b modify by bytes (default)\n"
1771 " w modify by words (2 byte)\n"
1772 " l modify by longs (4 byte)\n"
1773 " d modify by doubleword (8 byte)\n"
1774 " r toggle reverse byte order mode\n"
1775 " n do not read memory (for i/o spaces)\n"
1776 " . ok to read (default)\n"
1777 "NOTE: flags are saved as defaults\n"
1780 static char *memex_subcmd_help_string
=
1781 "Memory examine subcommands:\n"
1782 " hexval write this val to current location\n"
1783 " 'string' write chars from string to this location\n"
1784 " ' increment address\n"
1785 " ^ decrement address\n"
1786 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1787 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1788 " ` clear no-read flag\n"
1789 " ; stay at this addr\n"
1790 " v change to byte mode\n"
1791 " w change to word (2 byte) mode\n"
1792 " l change to long (4 byte) mode\n"
1793 " u change to doubleword (8 byte) mode\n"
1794 " m addr change current addr\n"
1795 " n toggle no-read flag\n"
1796 " r toggle byte reverse flag\n"
1797 " < count back up count bytes\n"
1798 " > count skip forward count bytes\n"
1799 " x exit this mode\n"
1805 int cmd
, inc
, i
, nslash
;
1807 unsigned char val
[16];
1809 scanhex((void *)&adrs
);
1812 printf(memex_help_string
);
1818 while ((cmd
= skipbl()) != '\n') {
1820 case 'b': size
= 1; break;
1821 case 'w': size
= 2; break;
1822 case 'l': size
= 4; break;
1823 case 'd': size
= 8; break;
1824 case 'r': brev
= !brev
; break;
1825 case 'n': mnoread
= 1; break;
1826 case '.': mnoread
= 0; break;
1835 n
= mread(adrs
, val
, size
);
1836 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1841 for (i
= 0; i
< n
; ++i
)
1842 printf("%.2x", val
[i
]);
1843 for (; i
< size
; ++i
)
1844 printf("%s", fault_chars
[fault_type
]);
1851 for (i
= 0; i
< size
; ++i
)
1852 val
[i
] = n
>> (i
* 8);
1855 mwrite(adrs
, val
, size
);
1868 else if( n
== '\'' )
1870 for (i
= 0; i
< size
; ++i
)
1871 val
[i
] = n
>> (i
* 8);
1874 mwrite(adrs
, val
, size
);
1911 adrs
-= 1 << nslash
;
1915 adrs
+= 1 << nslash
;
1919 adrs
+= 1 << -nslash
;
1923 adrs
-= 1 << -nslash
;
1926 scanhex((void *)&adrs
);
1945 printf(memex_subcmd_help_string
);
1960 case 'n': c
= '\n'; break;
1961 case 'r': c
= '\r'; break;
1962 case 'b': c
= '\b'; break;
1963 case 't': c
= '\t'; break;
1968 static void xmon_rawdump (unsigned long adrs
, long ndump
)
1971 unsigned char temp
[16];
1973 for (n
= ndump
; n
> 0;) {
1975 nr
= mread(adrs
, temp
, r
);
1977 for (m
= 0; m
< r
; ++m
) {
1979 printf("%.2x", temp
[m
]);
1981 printf("%s", fault_chars
[fault_type
]);
1990 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1991 || ('a' <= (c) && (c) <= 'f') \
1992 || ('A' <= (c) && (c) <= 'F'))
1999 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2001 scanhex((void *)&adrs
);
2008 else if (nidump
> MAX_DUMP
)
2010 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2012 } else if (c
== 'r') {
2016 xmon_rawdump(adrs
, ndump
);
2023 else if (ndump
> MAX_DUMP
)
2025 prdump(adrs
, ndump
);
2032 prdump(unsigned long adrs
, long ndump
)
2034 long n
, m
, c
, r
, nr
;
2035 unsigned char temp
[16];
2037 for (n
= ndump
; n
> 0;) {
2041 nr
= mread(adrs
, temp
, r
);
2043 for (m
= 0; m
< r
; ++m
) {
2044 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2047 printf("%.2x", temp
[m
]);
2049 printf("%s", fault_chars
[fault_type
]);
2051 for (; m
< 16; ++m
) {
2052 if ((m
& (sizeof(long) - 1)) == 0)
2057 for (m
= 0; m
< r
; ++m
) {
2060 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2073 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2076 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2077 instruction_dump_func dump_func
)
2080 unsigned long first_adr
;
2081 unsigned long inst
, last_inst
= 0;
2082 unsigned char val
[4];
2085 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2086 nr
= mread(adr
, val
, 4);
2089 const char *x
= fault_chars
[fault_type
];
2090 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2094 inst
= GETWORD(val
);
2095 if (adr
> first_adr
&& inst
== last_inst
) {
2105 printf(REG
" %.8x", adr
, inst
);
2107 dump_func(inst
, adr
);
2110 return adr
- first_adr
;
2114 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2116 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2120 print_address(unsigned long addr
)
2122 xmon_print_symbol(addr
, "\t# ", "");
2127 * Memory operations - move, set, print differences
2129 static unsigned long mdest
; /* destination address */
2130 static unsigned long msrc
; /* source address */
2131 static unsigned long mval
; /* byte value to set memory to */
2132 static unsigned long mcount
; /* # bytes to affect */
2133 static unsigned long mdiffs
; /* max # differences to print */
2138 scanhex((void *)&mdest
);
2139 if( termch
!= '\n' )
2141 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2142 if( termch
!= '\n' )
2144 scanhex((void *)&mcount
);
2147 memmove((void *)mdest
, (void *)msrc
, mcount
);
2150 memset((void *)mdest
, mval
, mcount
);
2153 if( termch
!= '\n' )
2155 scanhex((void *)&mdiffs
);
2156 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2162 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2167 for( n
= nb
; n
> 0; --n
)
2168 if( *p1
++ != *p2
++ )
2169 if( ++prt
<= maxpr
)
2170 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2171 p1
[-1], p2
- 1, p2
[-1]);
2173 printf("Total of %d differences\n", prt
);
2176 static unsigned mend
;
2177 static unsigned mask
;
2183 unsigned char val
[4];
2186 scanhex((void *)&mdest
);
2187 if (termch
!= '\n') {
2189 scanhex((void *)&mend
);
2190 if (termch
!= '\n') {
2192 scanhex((void *)&mval
);
2194 if (termch
!= '\n') termch
= 0;
2195 scanhex((void *)&mask
);
2199 for (a
= mdest
; a
< mend
; a
+= 4) {
2200 if (mread(a
, val
, 4) == 4
2201 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2202 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2209 static unsigned long mskip
= 0x1000;
2210 static unsigned long mlim
= 0xffffffff;
2220 if (termch
!= '\n') termch
= 0;
2222 if (termch
!= '\n') termch
= 0;
2225 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2226 ok
= mread(a
, &v
, 1);
2228 printf("%.8x .. ", a
);
2229 } else if (!ok
&& ook
)
2230 printf("%.8x\n", a
- mskip
);
2236 printf("%.8x\n", a
- mskip
);
2239 static void proccall(void)
2241 unsigned long args
[8];
2244 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2245 unsigned long, unsigned long, unsigned long,
2246 unsigned long, unsigned long, unsigned long);
2249 if (!scanhex(&adrs
))
2253 for (i
= 0; i
< 8; ++i
)
2255 for (i
= 0; i
< 8; ++i
) {
2256 if (!scanhex(&args
[i
]) || termch
== '\n')
2260 func
= (callfunc_t
) adrs
;
2262 if (setjmp(bus_error_jmp
) == 0) {
2263 catch_memory_errors
= 1;
2265 ret
= func(args
[0], args
[1], args
[2], args
[3],
2266 args
[4], args
[5], args
[6], args
[7]);
2268 printf("return value is %x\n", ret
);
2270 printf("*** %x exception occurred\n", fault_except
);
2272 catch_memory_errors
= 0;
2275 /* Input scanning routines */
2286 while( c
== ' ' || c
== '\t' )
2292 static char *regnames
[N_PTREGS
] = {
2293 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2294 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2295 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2296 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2297 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2303 "trap", "dar", "dsisr", "res"
2307 scanhex(unsigned long *vp
)
2314 /* parse register name */
2318 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2327 for (i
= 0; i
< N_PTREGS
; ++i
) {
2328 if (strcmp(regnames
[i
], regname
) == 0) {
2329 if (xmon_regs
== NULL
) {
2330 printf("regs not available\n");
2333 *vp
= ((unsigned long *)xmon_regs
)[i
];
2337 printf("invalid register name '%%%s'\n", regname
);
2341 /* skip leading "0x" if any */
2355 } else if (c
== '$') {
2357 for (i
=0; i
<63; i
++) {
2367 if (setjmp(bus_error_jmp
) == 0) {
2368 catch_memory_errors
= 1;
2370 *vp
= kallsyms_lookup_name(tmpstr
);
2373 catch_memory_errors
= 0;
2375 printf("unknown symbol '%s'\n", tmpstr
);
2408 static int hexdigit(int c
)
2410 if( '0' <= c
&& c
<= '9' )
2412 if( 'A' <= c
&& c
<= 'F' )
2413 return c
- ('A' - 10);
2414 if( 'a' <= c
&& c
<= 'f' )
2415 return c
- ('a' - 10);
2420 getstring(char *s
, int size
)
2431 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2436 static char line
[256];
2437 static char *lineptr
;
2448 if (lineptr
== NULL
|| *lineptr
== 0) {
2449 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2459 take_input(char *str
)
2468 int type
= inchar();
2470 static char tmp
[64];
2475 xmon_print_symbol(addr
, ": ", "\n");
2480 if (setjmp(bus_error_jmp
) == 0) {
2481 catch_memory_errors
= 1;
2483 addr
= kallsyms_lookup_name(tmp
);
2485 printf("%s: %lx\n", tmp
, addr
);
2487 printf("Symbol '%s' not found.\n", tmp
);
2490 catch_memory_errors
= 0;
2497 /* Print an address in numeric and symbolic form (if possible) */
2498 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2502 const char *name
= NULL
;
2503 unsigned long offset
, size
;
2505 printf(REG
, address
);
2506 if (setjmp(bus_error_jmp
) == 0) {
2507 catch_memory_errors
= 1;
2509 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2512 /* wait a little while to see if we get a machine check */
2516 catch_memory_errors
= 0;
2519 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2521 printf(" [%s]", modname
);
2523 printf("%s", after
);
2527 static void dump_slb(void)
2530 unsigned long esid
,vsid
,valid
;
2533 printf("SLB contents of cpu %x\n", smp_processor_id());
2535 for (i
= 0; i
< mmu_slb_size
; i
++) {
2536 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2537 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2538 valid
= (esid
& SLB_ESID_V
);
2539 if (valid
| esid
| vsid
) {
2540 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2542 llp
= vsid
& SLB_VSID_LLP
;
2543 if (vsid
& SLB_VSID_B_1T
) {
2544 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2546 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2549 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2551 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2560 static void dump_stab(void)
2563 unsigned long *tmp
= (unsigned long *)get_paca()->stab_addr
;
2565 printf("Segment table contents of cpu %x\n", smp_processor_id());
2567 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2574 printf("%03d %016lx ", i
, a
);
2575 printf("%016lx\n", b
);
2580 void dump_segments(void)
2582 if (cpu_has_feature(CPU_FTR_SLB
))
2589 #ifdef CONFIG_PPC_STD_MMU_32
2590 void dump_segments(void)
2595 for (i
= 0; i
< 16; ++i
)
2596 printf(" %x", mfsrin(i
));
2602 static void dump_tlb_44x(void)
2606 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2607 unsigned long w0
,w1
,w2
;
2608 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2609 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2610 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2611 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2612 if (w0
& PPC44x_TLB_VALID
) {
2613 printf("V %08x -> %01x%08x %c%c%c%c%c",
2614 w0
& PPC44x_TLB_EPN_MASK
,
2615 w1
& PPC44x_TLB_ERPN_MASK
,
2616 w1
& PPC44x_TLB_RPN_MASK
,
2617 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2618 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2619 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2620 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2621 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2626 #endif /* CONFIG_44x */
2628 static void xmon_init(int enable
)
2630 #ifdef CONFIG_PPC_ISERIES
2631 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2636 __debugger_ipi
= xmon_ipi
;
2637 __debugger_bpt
= xmon_bpt
;
2638 __debugger_sstep
= xmon_sstep
;
2639 __debugger_iabr_match
= xmon_iabr_match
;
2640 __debugger_dabr_match
= xmon_dabr_match
;
2641 __debugger_fault_handler
= xmon_fault_handler
;
2644 __debugger_ipi
= NULL
;
2645 __debugger_bpt
= NULL
;
2646 __debugger_sstep
= NULL
;
2647 __debugger_iabr_match
= NULL
;
2648 __debugger_dabr_match
= NULL
;
2649 __debugger_fault_handler
= NULL
;
2654 #ifdef CONFIG_MAGIC_SYSRQ
2655 static void sysrq_handle_xmon(int key
, struct tty_struct
*tty
)
2657 /* ensure xmon is enabled */
2659 debugger(get_irq_regs());
2662 static struct sysrq_key_op sysrq_xmon_op
=
2664 .handler
= sysrq_handle_xmon
,
2666 .action_msg
= "Entering xmon",
2669 static int __init
setup_xmon_sysrq(void)
2671 #ifdef CONFIG_PPC_ISERIES
2672 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2675 register_sysrq_key('x', &sysrq_xmon_op
);
2678 __initcall(setup_xmon_sysrq
);
2679 #endif /* CONFIG_MAGIC_SYSRQ */
2681 static int __initdata xmon_early
, xmon_off
;
2683 static int __init
early_parse_xmon(char *p
)
2685 if (!p
|| strncmp(p
, "early", 5) == 0) {
2686 /* just "xmon" is equivalent to "xmon=early" */
2689 } else if (strncmp(p
, "on", 2) == 0)
2691 else if (strncmp(p
, "off", 3) == 0)
2693 else if (strncmp(p
, "nobt", 4) == 0)
2694 xmon_no_auto_backtrace
= 1;
2700 early_param("xmon", early_parse_xmon
);
2702 void __init
xmon_setup(void)
2704 #ifdef CONFIG_XMON_DEFAULT
2712 #ifdef CONFIG_SPU_BASE
2716 u64 saved_mfc_sr1_RW
;
2717 u32 saved_spu_runcntl_RW
;
2718 unsigned long dump_addr
;
2722 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2724 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2726 void xmon_register_spus(struct list_head
*list
)
2730 list_for_each_entry(spu
, list
, full_list
) {
2731 if (spu
->number
>= XMON_NUM_SPUS
) {
2736 spu_info
[spu
->number
].spu
= spu
;
2737 spu_info
[spu
->number
].stopped_ok
= 0;
2738 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2739 spu_info
[spu
->number
].spu
->local_store
;
2743 static void stop_spus(void)
2749 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2750 if (!spu_info
[i
].spu
)
2753 if (setjmp(bus_error_jmp
) == 0) {
2754 catch_memory_errors
= 1;
2757 spu
= spu_info
[i
].spu
;
2759 spu_info
[i
].saved_spu_runcntl_RW
=
2760 in_be32(&spu
->problem
->spu_runcntl_RW
);
2762 tmp
= spu_mfc_sr1_get(spu
);
2763 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2765 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2766 spu_mfc_sr1_set(spu
, tmp
);
2771 spu_info
[i
].stopped_ok
= 1;
2773 printf("Stopped spu %.2d (was %s)\n", i
,
2774 spu_info
[i
].saved_spu_runcntl_RW
?
2775 "running" : "stopped");
2777 catch_memory_errors
= 0;
2778 printf("*** Error stopping spu %.2d\n", i
);
2780 catch_memory_errors
= 0;
2784 static void restart_spus(void)
2789 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2790 if (!spu_info
[i
].spu
)
2793 if (!spu_info
[i
].stopped_ok
) {
2794 printf("*** Error, spu %d was not successfully stopped"
2795 ", not restarting\n", i
);
2799 if (setjmp(bus_error_jmp
) == 0) {
2800 catch_memory_errors
= 1;
2803 spu
= spu_info
[i
].spu
;
2804 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
2805 out_be32(&spu
->problem
->spu_runcntl_RW
,
2806 spu_info
[i
].saved_spu_runcntl_RW
);
2811 printf("Restarted spu %.2d\n", i
);
2813 catch_memory_errors
= 0;
2814 printf("*** Error restarting spu %.2d\n", i
);
2816 catch_memory_errors
= 0;
2820 #define DUMP_WIDTH 23
2821 #define DUMP_VALUE(format, field, value) \
2823 if (setjmp(bus_error_jmp) == 0) { \
2824 catch_memory_errors = 1; \
2826 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2831 catch_memory_errors = 0; \
2832 printf(" %-*s = *** Error reading field.\n", \
2833 DUMP_WIDTH, #field); \
2835 catch_memory_errors = 0; \
2838 #define DUMP_FIELD(obj, format, field) \
2839 DUMP_VALUE(format, field, obj->field)
2841 static void dump_spu_fields(struct spu
*spu
)
2843 printf("Dumping spu fields at address %p:\n", spu
);
2845 DUMP_FIELD(spu
, "0x%x", number
);
2846 DUMP_FIELD(spu
, "%s", name
);
2847 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
2848 DUMP_FIELD(spu
, "0x%p", local_store
);
2849 DUMP_FIELD(spu
, "0x%lx", ls_size
);
2850 DUMP_FIELD(spu
, "0x%x", node
);
2851 DUMP_FIELD(spu
, "0x%lx", flags
);
2852 DUMP_FIELD(spu
, "%d", class_0_pending
);
2853 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
2854 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
2855 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
2856 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
2857 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
2858 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
2859 DUMP_FIELD(spu
, "0x%x", slb_replace
);
2860 DUMP_FIELD(spu
, "%d", pid
);
2861 DUMP_FIELD(spu
, "0x%p", mm
);
2862 DUMP_FIELD(spu
, "0x%p", ctx
);
2863 DUMP_FIELD(spu
, "0x%p", rq
);
2864 DUMP_FIELD(spu
, "0x%p", timestamp
);
2865 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
2866 DUMP_FIELD(spu
, "0x%p", problem
);
2867 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
2868 in_be32(&spu
->problem
->spu_runcntl_RW
));
2869 DUMP_VALUE("0x%x", problem
->spu_status_R
,
2870 in_be32(&spu
->problem
->spu_status_R
));
2871 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
2872 in_be32(&spu
->problem
->spu_npc_RW
));
2873 DUMP_FIELD(spu
, "0x%p", priv2
);
2874 DUMP_FIELD(spu
, "0x%p", pdata
);
2878 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
2880 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
2883 static void dump_spu_ls(unsigned long num
, int subcmd
)
2885 unsigned long offset
, addr
, ls_addr
;
2887 if (setjmp(bus_error_jmp
) == 0) {
2888 catch_memory_errors
= 1;
2890 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
2894 catch_memory_errors
= 0;
2895 printf("*** Error: accessing spu info for spu %d\n", num
);
2898 catch_memory_errors
= 0;
2900 if (scanhex(&offset
))
2901 addr
= ls_addr
+ offset
;
2903 addr
= spu_info
[num
].dump_addr
;
2905 if (addr
>= ls_addr
+ LS_SIZE
) {
2906 printf("*** Error: address outside of local store\n");
2912 addr
+= spu_inst_dump(addr
, 16, 1);
2922 spu_info
[num
].dump_addr
= addr
;
2925 static int do_spu_cmd(void)
2927 static unsigned long num
= 0;
2928 int cmd
, subcmd
= 0;
2940 if (isxdigit(subcmd
) || subcmd
== '\n')
2944 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
2945 printf("*** Error: invalid spu number\n");
2951 dump_spu_fields(spu_info
[num
].spu
);
2954 dump_spu_ls(num
, subcmd
);
2965 #else /* ! CONFIG_SPU_BASE */
2966 static int do_spu_cmd(void)