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 __read_mostly
= 0;
66 static unsigned long adrs
;
68 #define MAX_DUMP (128 * 1024)
69 static unsigned long ndump
= 64;
70 static unsigned long nidump
= 16;
71 static unsigned long ncsum
= 4096;
73 static char tmpstr
[128];
75 static long bus_error_jmp
[JMP_BUF_LEN
];
76 static int catch_memory_errors
;
77 static long *xmon_fault_jmp
[NR_CPUS
];
79 /* Breakpoint stuff */
81 unsigned long address
;
82 unsigned int instr
[2];
88 /* Bits in bpt.enabled */
89 #define BP_IABR_TE 1 /* IABR translation enabled */
95 static struct bpt bpts
[NBPTS
];
96 static struct bpt dabr
;
97 static struct bpt
*iabr
;
98 static unsigned bpinstr
= 0x7fe00008; /* trap */
100 #define BP_NUM(bp) ((bp) - bpts + 1)
103 static int cmds(struct pt_regs
*);
104 static int mread(unsigned long, void *, int);
105 static int mwrite(unsigned long, void *, int);
106 static int handle_fault(struct pt_regs
*);
107 static void byterev(unsigned char *, int);
108 static void memex(void);
109 static int bsesc(void);
110 static void dump(void);
111 static void prdump(unsigned long, long);
112 static int ppc_inst_dump(unsigned long, long, int);
113 static void dump_log_buf(void);
114 static void backtrace(struct pt_regs
*);
115 static void excprint(struct pt_regs
*);
116 static void prregs(struct pt_regs
*);
117 static void memops(int);
118 static void memlocate(void);
119 static void memzcan(void);
120 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
122 int scanhex(unsigned long *valp
);
123 static void scannl(void);
124 static int hexdigit(int);
125 void getstring(char *, int);
126 static void flush_input(void);
127 static int inchar(void);
128 static void take_input(char *);
129 static unsigned long read_spr(int);
130 static void write_spr(int, unsigned long);
131 static void super_regs(void);
132 static void remove_bpts(void);
133 static void insert_bpts(void);
134 static void remove_cpu_bpts(void);
135 static void insert_cpu_bpts(void);
136 static struct bpt
*at_breakpoint(unsigned long pc
);
137 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
138 static int do_step(struct pt_regs
*);
139 static void bpt_cmds(void);
140 static void cacheflush(void);
141 static int cpu_cmd(void);
142 static void csum(void);
143 static void bootcmds(void);
144 static void proccall(void);
145 void dump_segments(void);
146 static void symbol_lookup(void);
147 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
149 static void xmon_print_symbol(unsigned long address
, const char *mid
,
151 static const char *getvecname(unsigned long vec
);
153 static int do_spu_cmd(void);
156 static void dump_tlb_44x(void);
159 static int xmon_no_auto_backtrace
;
161 extern void xmon_enter(void);
162 extern void xmon_leave(void);
166 #define REGS_PER_LINE 4
167 #define LAST_VOLATILE 13
170 #define REGS_PER_LINE 8
171 #define LAST_VOLATILE 12
174 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
176 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
177 || ('a' <= (c) && (c) <= 'f') \
178 || ('A' <= (c) && (c) <= 'F'))
179 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
180 || ('a' <= (c) && (c) <= 'z') \
181 || ('A' <= (c) && (c) <= 'Z'))
182 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
184 static char *help_string
= "\
186 b show breakpoints\n\
187 bd set data breakpoint\n\
188 bi set instruction breakpoint\n\
189 bc clear breakpoint\n"
192 c print cpus stopped in xmon\n\
193 c# try to switch to cpu number h (in hex)\n"
198 di dump instructions\n\
199 df dump float values\n\
200 dd dump double values\n\
201 dl dump the kernel log buffer\n\
202 dr dump stream of raw bytes\n\
203 e print exception information\n\
205 la lookup symbol+offset of specified address\n\
206 ls lookup address of specified symbol\n\
207 m examine/change memory\n\
208 mm move a block of memory\n\
209 ms set a block of memory\n\
210 md compare two blocks of memory\n\
211 ml locate a block of memory\n\
212 mz zero a block of memory\n\
213 mi show information about memory allocation\n\
214 p call a procedure\n\
217 #ifdef CONFIG_SPU_BASE
218 " ss stop execution on all spus\n\
219 sr restore execution on stopped spus\n\
220 sf # dump spu fields for spu # (in hex)\n\
221 sd # dump spu local store for spu # (in hex)\n\
222 sdi # disassemble spu local store for spu # (in hex)\n"
224 " S print special registers\n\
226 x exit monitor and recover\n\
227 X exit monitor and dont recover\n"
229 " u dump segment table or SLB\n"
231 #ifdef CONFIG_PPC_STD_MMU_32
232 " u dump segment registers\n"
242 static struct pt_regs
*xmon_regs
;
244 static inline void sync(void)
246 asm volatile("sync; isync");
249 static inline void store_inst(void *p
)
251 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
254 static inline void cflush(void *p
)
256 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
259 static inline void cinval(void *p
)
261 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
265 * Disable surveillance (the service processor watchdog function)
266 * while we are in xmon.
267 * XXX we should re-enable it when we leave. :)
269 #define SURVEILLANCE_TOKEN 9000
271 static inline void disable_surveillance(void)
273 #ifdef CONFIG_PPC_PSERIES
274 /* Since this can't be a module, args should end up below 4GB. */
275 static struct rtas_args args
;
278 * At this point we have got all the cpus we can into
279 * xmon, so there is hopefully no other cpu calling RTAS
280 * at the moment, even though we don't take rtas.lock.
281 * If we did try to take rtas.lock there would be a
282 * real possibility of deadlock.
284 args
.token
= rtas_token("set-indicator");
285 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
289 args
.rets
= &args
.args
[3];
290 args
.args
[0] = SURVEILLANCE_TOKEN
;
293 enter_rtas(__pa(&args
));
294 #endif /* CONFIG_PPC_PSERIES */
298 static int xmon_speaker
;
300 static void get_output_lock(void)
302 int me
= smp_processor_id() + 0x100;
303 int last_speaker
= 0, prev
;
306 if (xmon_speaker
== me
)
309 if (xmon_speaker
== 0) {
310 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
311 if (last_speaker
== 0)
315 while (xmon_speaker
== last_speaker
) {
318 /* hostile takeover */
319 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
320 if (prev
== last_speaker
)
327 static void release_output_lock(void)
332 int cpus_are_in_xmon(void)
334 return !cpus_empty(cpus_in_xmon
);
338 static inline int unrecoverable_excp(struct pt_regs
*regs
)
341 /* We have no MSR_RI bit on 4xx, so we simply return false */
344 return ((regs
->msr
& MSR_RI
) == 0);
348 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
352 long recurse_jmp
[JMP_BUF_LEN
];
353 unsigned long offset
;
358 unsigned long timeout
;
361 local_irq_save(flags
);
363 bp
= in_breakpoint_table(regs
->nip
, &offset
);
365 regs
->nip
= bp
->address
+ offset
;
366 atomic_dec(&bp
->ref_count
);
372 cpu
= smp_processor_id();
373 if (cpu_isset(cpu
, cpus_in_xmon
)) {
376 printf("cpu 0x%x: Exception %lx %s in xmon, "
377 "returning to main loop\n",
378 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
379 release_output_lock();
380 longjmp(xmon_fault_jmp
[cpu
], 1);
383 if (setjmp(recurse_jmp
) != 0) {
384 if (!in_xmon
|| !xmon_gate
) {
386 printf("xmon: WARNING: bad recursive fault "
387 "on cpu 0x%x\n", cpu
);
388 release_output_lock();
391 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
395 xmon_fault_jmp
[cpu
] = recurse_jmp
;
396 cpu_set(cpu
, cpus_in_xmon
);
399 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
))
400 bp
= at_breakpoint(regs
->nip
);
401 if (bp
|| unrecoverable_excp(regs
))
408 printf("cpu 0x%x stopped at breakpoint 0x%x (",
410 xmon_print_symbol(regs
->nip
, " ", ")\n");
412 if (unrecoverable_excp(regs
))
413 printf("WARNING: exception is not recoverable, "
415 release_output_lock();
420 while (secondary
&& !xmon_gate
) {
424 secondary
= test_and_set_bit(0, &in_xmon
);
429 if (!secondary
&& !xmon_gate
) {
430 /* we are the first cpu to come in */
431 /* interrupt other cpu(s) */
432 int ncpus
= num_online_cpus();
437 smp_send_debugger_break(MSG_ALL_BUT_SELF
);
438 /* wait for other cpus to come in */
439 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
440 if (cpus_weight(cpus_in_xmon
) >= ncpus
)
446 disable_surveillance();
447 /* for breakpoint or single step, print the current instr. */
448 if (bp
|| TRAP(regs
) == 0xd00)
449 ppc_inst_dump(regs
->nip
, 1, 0);
450 printf("enter ? for help\n");
459 if (cpu
== xmon_owner
) {
460 if (!test_and_set_bit(0, &xmon_taken
)) {
465 while (cpu
== xmon_owner
)
479 /* have switched to some other cpu */
484 cpu_clear(cpu
, cpus_in_xmon
);
485 xmon_fault_jmp
[cpu
] = NULL
;
487 /* UP is simple... */
489 printf("Exception %lx %s in xmon, returning to main loop\n",
490 regs
->trap
, getvecname(TRAP(regs
)));
491 longjmp(xmon_fault_jmp
[0], 1);
493 if (setjmp(recurse_jmp
) == 0) {
494 xmon_fault_jmp
[0] = recurse_jmp
;
498 bp
= at_breakpoint(regs
->nip
);
500 printf("Stopped at breakpoint %x (", BP_NUM(bp
));
501 xmon_print_symbol(regs
->nip
, " ", ")\n");
503 if (unrecoverable_excp(regs
))
504 printf("WARNING: exception is not recoverable, "
507 disable_surveillance();
508 /* for breakpoint or single step, print the current instr. */
509 if (bp
|| TRAP(regs
) == 0xd00)
510 ppc_inst_dump(regs
->nip
, 1, 0);
511 printf("enter ? for help\n");
521 if (regs
->msr
& MSR_DE
) {
522 bp
= at_breakpoint(regs
->nip
);
524 regs
->nip
= (unsigned long) &bp
->instr
[0];
525 atomic_inc(&bp
->ref_count
);
529 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
530 bp
= at_breakpoint(regs
->nip
);
532 int stepped
= emulate_step(regs
, bp
->instr
[0]);
534 regs
->nip
= (unsigned long) &bp
->instr
[0];
535 atomic_inc(&bp
->ref_count
);
536 } else if (stepped
< 0) {
537 printf("Couldn't single-step %s instruction\n",
538 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
545 local_irq_restore(flags
);
547 return cmd
!= 'X' && cmd
!= EOF
;
550 int xmon(struct pt_regs
*excp
)
555 ppc_save_regs(®s
);
559 return xmon_core(excp
, 0);
563 irqreturn_t
xmon_irq(int irq
, void *d
)
566 local_irq_save(flags
);
567 printf("Keyboard interrupt\n");
568 xmon(get_irq_regs());
569 local_irq_restore(flags
);
573 static int xmon_bpt(struct pt_regs
*regs
)
576 unsigned long offset
;
578 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
581 /* Are we at the trap at bp->instr[1] for some bp? */
582 bp
= in_breakpoint_table(regs
->nip
, &offset
);
583 if (bp
!= NULL
&& offset
== 4) {
584 regs
->nip
= bp
->address
+ 4;
585 atomic_dec(&bp
->ref_count
);
589 /* Are we at a breakpoint? */
590 bp
= at_breakpoint(regs
->nip
);
599 static int xmon_sstep(struct pt_regs
*regs
)
607 static int xmon_dabr_match(struct pt_regs
*regs
)
609 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
611 if (dabr
.enabled
== 0)
617 static int xmon_iabr_match(struct pt_regs
*regs
)
619 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
627 static int xmon_ipi(struct pt_regs
*regs
)
630 if (in_xmon
&& !cpu_isset(smp_processor_id(), cpus_in_xmon
))
636 static int xmon_fault_handler(struct pt_regs
*regs
)
639 unsigned long offset
;
641 if (in_xmon
&& catch_memory_errors
)
642 handle_fault(regs
); /* doesn't return */
644 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
645 bp
= in_breakpoint_table(regs
->nip
, &offset
);
647 regs
->nip
= bp
->address
+ offset
;
648 atomic_dec(&bp
->ref_count
);
655 static struct bpt
*at_breakpoint(unsigned long pc
)
661 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
662 if (bp
->enabled
&& pc
== bp
->address
)
667 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
671 off
= nip
- (unsigned long) bpts
;
672 if (off
>= sizeof(bpts
))
674 off
%= sizeof(struct bpt
);
675 if (off
!= offsetof(struct bpt
, instr
[0])
676 && off
!= offsetof(struct bpt
, instr
[1]))
678 *offp
= off
- offsetof(struct bpt
, instr
[0]);
679 return (struct bpt
*) (nip
- off
);
682 static struct bpt
*new_breakpoint(unsigned long a
)
687 bp
= at_breakpoint(a
);
691 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
692 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
694 bp
->instr
[1] = bpinstr
;
695 store_inst(&bp
->instr
[1]);
700 printf("Sorry, no free breakpoints. Please clear one first.\n");
704 static void insert_bpts(void)
710 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
711 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
713 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
714 printf("Couldn't read instruction at %lx, "
715 "disabling breakpoint there\n", bp
->address
);
719 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
720 printf("Breakpoint at %lx is on an mtmsrd or rfid "
721 "instruction, disabling it\n", bp
->address
);
725 store_inst(&bp
->instr
[0]);
726 if (bp
->enabled
& BP_IABR
)
728 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
729 printf("Couldn't write instruction at %lx, "
730 "disabling breakpoint there\n", bp
->address
);
731 bp
->enabled
&= ~BP_TRAP
;
734 store_inst((void *)bp
->address
);
738 static void insert_cpu_bpts(void)
741 set_dabr(dabr
.address
| (dabr
.enabled
& 7));
742 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
743 mtspr(SPRN_IABR
, iabr
->address
744 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
747 static void remove_bpts(void)
754 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
755 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
757 if (mread(bp
->address
, &instr
, 4) == 4
759 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
760 printf("Couldn't remove breakpoint at %lx\n",
763 store_inst((void *)bp
->address
);
767 static void remove_cpu_bpts(void)
770 if (cpu_has_feature(CPU_FTR_IABR
))
774 /* Command interpreting routine */
775 static char *last_cmd
;
778 cmds(struct pt_regs
*excp
)
785 if (!xmon_no_auto_backtrace
) {
786 xmon_no_auto_backtrace
= 1;
787 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
792 printf("%x:", smp_processor_id());
793 #endif /* CONFIG_SMP */
799 if (last_cmd
== NULL
)
801 take_input(last_cmd
);
835 prregs(excp
); /* print regs */
850 if (do_spu_cmd() == 0)
859 printf(" <no input ...>\n");
863 xmon_puts(help_string
);
881 #ifdef CONFIG_PPC_STD_MMU
892 printf("Unrecognized command: ");
894 if (' ' < cmd
&& cmd
<= '~')
897 printf("\\x%x", cmd
);
899 } while (cmd
!= '\n');
900 printf(" (type ? for help)\n");
907 static int do_step(struct pt_regs
*regs
)
910 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
915 * Step a single instruction.
916 * Some instructions we emulate, others we execute with MSR_SE set.
918 static int do_step(struct pt_regs
*regs
)
923 /* check we are in 64-bit kernel mode, translation enabled */
924 if ((regs
->msr
& (MSR_SF
|MSR_PR
|MSR_IR
)) == (MSR_SF
|MSR_IR
)) {
925 if (mread(regs
->nip
, &instr
, 4) == 4) {
926 stepped
= emulate_step(regs
, instr
);
928 printf("Couldn't single-step %s instruction\n",
929 (IS_RFID(instr
)? "rfid": "mtmsrd"));
933 regs
->trap
= 0xd00 | (regs
->trap
& 1);
934 printf("stepped to ");
935 xmon_print_symbol(regs
->nip
, " ", "\n");
936 ppc_inst_dump(regs
->nip
, 1, 0);
946 static void bootcmds(void)
952 ppc_md
.restart(NULL
);
959 static int cpu_cmd(void)
966 if (!scanhex(&cpu
)) {
967 /* print cpus waiting or in xmon */
968 printf("cpus stopped:");
970 for (cpu
= 0; cpu
< NR_CPUS
; ++cpu
) {
971 if (cpu_isset(cpu
, cpus_in_xmon
)) {
977 printf("-%x", cpu
- 1);
982 printf("-%x", NR_CPUS
- 1);
986 /* try to switch to cpu specified */
987 if (!cpu_isset(cpu
, cpus_in_xmon
)) {
988 printf("cpu 0x%x isn't in xmon\n", cpu
);
995 while (!xmon_taken
) {
996 if (--timeout
== 0) {
997 if (test_and_set_bit(0, &xmon_taken
))
999 /* take control back */
1001 xmon_owner
= smp_processor_id();
1002 printf("cpu %u didn't take control\n", cpu
);
1010 #endif /* CONFIG_SMP */
1013 static unsigned short fcstab
[256] = {
1014 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1015 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1016 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1017 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1018 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1019 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1020 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1021 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1022 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1023 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1024 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1025 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1026 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1027 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1028 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1029 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1030 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1031 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1032 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1033 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1034 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1035 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1036 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1037 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1038 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1039 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1040 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1041 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1042 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1043 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1044 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1045 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1048 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1057 if (!scanhex(&adrs
))
1059 if (!scanhex(&ncsum
))
1062 for (i
= 0; i
< ncsum
; ++i
) {
1063 if (mread(adrs
+i
, &v
, 1) == 0) {
1064 printf("csum stopped at %x\n", adrs
+i
);
1069 printf("%x\n", fcs
);
1073 * Check if this is a suitable place to put a breakpoint.
1075 static long check_bp_loc(unsigned long addr
)
1080 if (!is_kernel_addr(addr
)) {
1081 printf("Breakpoints may only be placed at kernel addresses\n");
1084 if (!mread(addr
, &instr
, sizeof(instr
))) {
1085 printf("Can't read instruction at address %lx\n", addr
);
1088 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1089 printf("Breakpoints may not be placed on mtmsrd or rfid "
1096 static char *breakpoint_help_string
=
1097 "Breakpoint command usage:\n"
1098 "b show breakpoints\n"
1099 "b <addr> [cnt] set breakpoint at given instr addr\n"
1100 "bc clear all breakpoints\n"
1101 "bc <n/addr> clear breakpoint number n or at addr\n"
1102 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1103 "bd <addr> [cnt] set hardware data breakpoint\n"
1113 const char badaddr
[] = "Only kernel addresses are permitted "
1114 "for breakpoints\n";
1119 case 'd': /* bd - hardware data breakpoint */
1124 else if (cmd
== 'w')
1130 if (scanhex(&dabr
.address
)) {
1131 if (!is_kernel_addr(dabr
.address
)) {
1136 dabr
.enabled
= mode
| BP_DABR
;
1140 case 'i': /* bi - hardware instr breakpoint */
1141 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1142 printf("Hardware instruction breakpoint "
1143 "not supported on this cpu\n");
1147 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1152 if (!check_bp_loc(a
))
1154 bp
= new_breakpoint(a
);
1156 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1164 /* clear all breakpoints */
1165 for (i
= 0; i
< NBPTS
; ++i
)
1166 bpts
[i
].enabled
= 0;
1169 printf("All breakpoints cleared\n");
1173 if (a
<= NBPTS
&& a
>= 1) {
1174 /* assume a breakpoint number */
1175 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1177 /* assume a breakpoint address */
1178 bp
= at_breakpoint(a
);
1180 printf("No breakpoint at %x\n", a
);
1185 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1186 xmon_print_symbol(bp
->address
, " ", ")\n");
1194 printf(breakpoint_help_string
);
1199 /* print all breakpoints */
1200 printf(" type address\n");
1202 printf(" data "REG
" [", dabr
.address
);
1203 if (dabr
.enabled
& 1)
1205 if (dabr
.enabled
& 2)
1209 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1212 printf("%2x %s ", BP_NUM(bp
),
1213 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1214 xmon_print_symbol(bp
->address
, " ", "\n");
1219 if (!check_bp_loc(a
))
1221 bp
= new_breakpoint(a
);
1223 bp
->enabled
|= BP_TRAP
;
1228 /* Very cheap human name for vector lookup. */
1230 const char *getvecname(unsigned long vec
)
1235 case 0x100: ret
= "(System Reset)"; break;
1236 case 0x200: ret
= "(Machine Check)"; break;
1237 case 0x300: ret
= "(Data Access)"; break;
1238 case 0x380: ret
= "(Data SLB Access)"; break;
1239 case 0x400: ret
= "(Instruction Access)"; break;
1240 case 0x480: ret
= "(Instruction SLB Access)"; break;
1241 case 0x500: ret
= "(Hardware Interrupt)"; break;
1242 case 0x600: ret
= "(Alignment)"; break;
1243 case 0x700: ret
= "(Program Check)"; break;
1244 case 0x800: ret
= "(FPU Unavailable)"; break;
1245 case 0x900: ret
= "(Decrementer)"; break;
1246 case 0xc00: ret
= "(System Call)"; break;
1247 case 0xd00: ret
= "(Single Step)"; break;
1248 case 0xf00: ret
= "(Performance Monitor)"; break;
1249 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1250 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1256 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1257 unsigned long *endp
)
1259 unsigned long size
, offset
;
1262 *startp
= *endp
= 0;
1265 if (setjmp(bus_error_jmp
) == 0) {
1266 catch_memory_errors
= 1;
1268 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1270 *startp
= pc
- offset
;
1271 *endp
= pc
- offset
+ size
;
1275 catch_memory_errors
= 0;
1278 static int xmon_depth_to_print
= 64;
1280 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1281 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1283 #ifdef __powerpc64__
1284 #define REGS_OFFSET 0x70
1286 #define REGS_OFFSET 16
1289 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1293 unsigned long newsp
;
1294 unsigned long marker
;
1296 struct pt_regs regs
;
1299 if (sp
< PAGE_OFFSET
) {
1301 printf("SP (%lx) is in userspace\n", sp
);
1305 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1306 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1307 printf("Couldn't read stack frame at %lx\n", sp
);
1312 * For the first stack frame, try to work out if
1313 * LR and/or the saved LR value in the bottommost
1314 * stack frame are valid.
1316 if ((pc
| lr
) != 0) {
1317 unsigned long fnstart
, fnend
;
1318 unsigned long nextip
;
1321 get_function_bounds(pc
, &fnstart
, &fnend
);
1324 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1325 sizeof(unsigned long));
1327 if (lr
< PAGE_OFFSET
1328 || (fnstart
<= lr
&& lr
< fnend
))
1330 } else if (lr
== nextip
) {
1332 } else if (lr
>= PAGE_OFFSET
1333 && !(fnstart
<= lr
&& lr
< fnend
)) {
1334 printf("[link register ] ");
1335 xmon_print_symbol(lr
, " ", "\n");
1338 printf("["REG
"] ", sp
);
1339 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1344 printf("["REG
"] ", sp
);
1345 xmon_print_symbol(ip
, " ", "\n");
1348 /* Look for "regshere" marker to see if this is
1349 an exception frame. */
1350 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1351 && marker
== STACK_FRAME_REGS_MARKER
) {
1352 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1354 printf("Couldn't read registers at %lx\n",
1358 printf("--- Exception: %lx %s at ", regs
.trap
,
1359 getvecname(TRAP(®s
)));
1362 xmon_print_symbol(pc
, " ", "\n");
1369 } while (count
++ < xmon_depth_to_print
);
1372 static void backtrace(struct pt_regs
*excp
)
1377 xmon_show_stack(sp
, 0, 0);
1379 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1383 static void print_bug_trap(struct pt_regs
*regs
)
1386 const struct bug_entry
*bug
;
1389 if (regs
->msr
& MSR_PR
)
1390 return; /* not in kernel */
1391 addr
= regs
->nip
; /* address of trap instruction */
1392 if (addr
< PAGE_OFFSET
)
1394 bug
= find_bug(regs
->nip
);
1397 if (is_warning_bug(bug
))
1400 #ifdef CONFIG_DEBUG_BUGVERBOSE
1401 printf("kernel BUG at %s:%u!\n",
1402 bug
->file
, bug
->line
);
1404 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1406 #endif /* CONFIG_BUG */
1409 static void excprint(struct pt_regs
*fp
)
1414 printf("cpu 0x%x: ", smp_processor_id());
1415 #endif /* CONFIG_SMP */
1418 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1420 xmon_print_symbol(fp
->nip
, ": ", "\n");
1422 printf(" lr: ", fp
->link
);
1423 xmon_print_symbol(fp
->link
, ": ", "\n");
1425 printf(" sp: %lx\n", fp
->gpr
[1]);
1426 printf(" msr: %lx\n", fp
->msr
);
1428 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1429 printf(" dar: %lx\n", fp
->dar
);
1431 printf(" dsisr: %lx\n", fp
->dsisr
);
1434 printf(" current = 0x%lx\n", current
);
1436 printf(" paca = 0x%lx\n", get_paca());
1439 printf(" pid = %ld, comm = %s\n",
1440 current
->pid
, current
->comm
);
1447 static void prregs(struct pt_regs
*fp
)
1451 struct pt_regs regs
;
1453 if (scanhex(&base
)) {
1454 if (setjmp(bus_error_jmp
) == 0) {
1455 catch_memory_errors
= 1;
1457 regs
= *(struct pt_regs
*)base
;
1461 catch_memory_errors
= 0;
1462 printf("*** Error reading registers from "REG
"\n",
1466 catch_memory_errors
= 0;
1471 if (FULL_REGS(fp
)) {
1472 for (n
= 0; n
< 16; ++n
)
1473 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1474 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1476 for (n
= 0; n
< 7; ++n
)
1477 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1478 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1481 for (n
= 0; n
< 32; ++n
) {
1482 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1483 (n
& 3) == 3? "\n": " ");
1484 if (n
== 12 && !FULL_REGS(fp
)) {
1491 xmon_print_symbol(fp
->nip
, " ", "\n");
1493 xmon_print_symbol(fp
->link
, " ", "\n");
1494 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1495 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1496 fp
->ctr
, fp
->xer
, fp
->trap
);
1498 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1499 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1502 static void cacheflush(void)
1505 unsigned long nflush
;
1510 scanhex((void *)&adrs
);
1515 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1516 if (setjmp(bus_error_jmp
) == 0) {
1517 catch_memory_errors
= 1;
1521 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1522 cflush((void *) adrs
);
1524 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1525 cinval((void *) adrs
);
1528 /* wait a little while to see if we get a machine check */
1531 catch_memory_errors
= 0;
1534 static unsigned long
1537 unsigned int instrs
[2];
1538 unsigned long (*code
)(void);
1539 unsigned long ret
= -1UL;
1541 unsigned long opd
[3];
1543 opd
[0] = (unsigned long)instrs
;
1546 code
= (unsigned long (*)(void)) opd
;
1548 code
= (unsigned long (*)(void)) instrs
;
1551 /* mfspr r3,n; blr */
1552 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1553 instrs
[1] = 0x4e800020;
1555 store_inst(instrs
+1);
1557 if (setjmp(bus_error_jmp
) == 0) {
1558 catch_memory_errors
= 1;
1564 /* wait a little while to see if we get a machine check */
1573 write_spr(int n
, unsigned long val
)
1575 unsigned int instrs
[2];
1576 unsigned long (*code
)(unsigned long);
1578 unsigned long opd
[3];
1580 opd
[0] = (unsigned long)instrs
;
1583 code
= (unsigned long (*)(unsigned long)) opd
;
1585 code
= (unsigned long (*)(unsigned long)) instrs
;
1588 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1589 instrs
[1] = 0x4e800020;
1591 store_inst(instrs
+1);
1593 if (setjmp(bus_error_jmp
) == 0) {
1594 catch_memory_errors
= 1;
1600 /* wait a little while to see if we get a machine check */
1606 static unsigned long regno
;
1607 extern char exc_prolog
;
1608 extern char dec_exc
;
1610 static void super_regs(void)
1617 unsigned long sp
, toc
;
1618 asm("mr %0,1" : "=r" (sp
) :);
1619 asm("mr %0,2" : "=r" (toc
) :);
1621 printf("msr = "REG
" sprg0= "REG
"\n",
1622 mfmsr(), mfspr(SPRN_SPRG0
));
1623 printf("pvr = "REG
" sprg1= "REG
"\n",
1624 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1625 printf("dec = "REG
" sprg2= "REG
"\n",
1626 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1627 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1628 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1629 #ifdef CONFIG_PPC_ISERIES
1630 if (firmware_has_feature(FW_FEATURE_ISERIES
)) {
1631 struct paca_struct
*ptrPaca
;
1632 struct lppaca
*ptrLpPaca
;
1634 /* Dump out relevant Paca data areas. */
1636 ptrPaca
= get_paca();
1638 printf(" Local Processor Control Area (LpPaca): \n");
1639 ptrLpPaca
= ptrPaca
->lppaca_ptr
;
1640 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1641 ptrLpPaca
->saved_srr0
, ptrLpPaca
->saved_srr1
);
1642 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1643 ptrLpPaca
->saved_gpr3
, ptrLpPaca
->saved_gpr4
);
1644 printf(" Saved Gpr5=%.16lx \n",
1645 ptrLpPaca
->gpr5_dword
.saved_gpr5
);
1655 val
= read_spr(regno
);
1657 write_spr(regno
, val
);
1660 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1667 * Stuff for reading and writing memory safely
1670 mread(unsigned long adrs
, void *buf
, int size
)
1676 if (setjmp(bus_error_jmp
) == 0) {
1677 catch_memory_errors
= 1;
1683 *(u16
*)q
= *(u16
*)p
;
1686 *(u32
*)q
= *(u32
*)p
;
1689 *(u64
*)q
= *(u64
*)p
;
1692 for( ; n
< size
; ++n
) {
1698 /* wait a little while to see if we get a machine check */
1702 catch_memory_errors
= 0;
1707 mwrite(unsigned long adrs
, void *buf
, int size
)
1713 if (setjmp(bus_error_jmp
) == 0) {
1714 catch_memory_errors
= 1;
1720 *(u16
*)p
= *(u16
*)q
;
1723 *(u32
*)p
= *(u32
*)q
;
1726 *(u64
*)p
= *(u64
*)q
;
1729 for ( ; n
< size
; ++n
) {
1735 /* wait a little while to see if we get a machine check */
1739 printf("*** Error writing address %x\n", adrs
+ n
);
1741 catch_memory_errors
= 0;
1745 static int fault_type
;
1746 static int fault_except
;
1747 static char *fault_chars
[] = { "--", "**", "##" };
1749 static int handle_fault(struct pt_regs
*regs
)
1751 fault_except
= TRAP(regs
);
1752 switch (TRAP(regs
)) {
1764 longjmp(bus_error_jmp
, 1);
1769 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1772 byterev(unsigned char *val
, int size
)
1778 SWAP(val
[0], val
[1], t
);
1781 SWAP(val
[0], val
[3], t
);
1782 SWAP(val
[1], val
[2], t
);
1784 case 8: /* is there really any use for this? */
1785 SWAP(val
[0], val
[7], t
);
1786 SWAP(val
[1], val
[6], t
);
1787 SWAP(val
[2], val
[5], t
);
1788 SWAP(val
[3], val
[4], t
);
1796 static char *memex_help_string
=
1797 "Memory examine command usage:\n"
1798 "m [addr] [flags] examine/change memory\n"
1799 " addr is optional. will start where left off.\n"
1800 " flags may include chars from this set:\n"
1801 " b modify by bytes (default)\n"
1802 " w modify by words (2 byte)\n"
1803 " l modify by longs (4 byte)\n"
1804 " d modify by doubleword (8 byte)\n"
1805 " r toggle reverse byte order mode\n"
1806 " n do not read memory (for i/o spaces)\n"
1807 " . ok to read (default)\n"
1808 "NOTE: flags are saved as defaults\n"
1811 static char *memex_subcmd_help_string
=
1812 "Memory examine subcommands:\n"
1813 " hexval write this val to current location\n"
1814 " 'string' write chars from string to this location\n"
1815 " ' increment address\n"
1816 " ^ decrement address\n"
1817 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1818 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1819 " ` clear no-read flag\n"
1820 " ; stay at this addr\n"
1821 " v change to byte mode\n"
1822 " w change to word (2 byte) mode\n"
1823 " l change to long (4 byte) mode\n"
1824 " u change to doubleword (8 byte) mode\n"
1825 " m addr change current addr\n"
1826 " n toggle no-read flag\n"
1827 " r toggle byte reverse flag\n"
1828 " < count back up count bytes\n"
1829 " > count skip forward count bytes\n"
1830 " x exit this mode\n"
1836 int cmd
, inc
, i
, nslash
;
1838 unsigned char val
[16];
1840 scanhex((void *)&adrs
);
1843 printf(memex_help_string
);
1849 while ((cmd
= skipbl()) != '\n') {
1851 case 'b': size
= 1; break;
1852 case 'w': size
= 2; break;
1853 case 'l': size
= 4; break;
1854 case 'd': size
= 8; break;
1855 case 'r': brev
= !brev
; break;
1856 case 'n': mnoread
= 1; break;
1857 case '.': mnoread
= 0; break;
1866 n
= mread(adrs
, val
, size
);
1867 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1872 for (i
= 0; i
< n
; ++i
)
1873 printf("%.2x", val
[i
]);
1874 for (; i
< size
; ++i
)
1875 printf("%s", fault_chars
[fault_type
]);
1882 for (i
= 0; i
< size
; ++i
)
1883 val
[i
] = n
>> (i
* 8);
1886 mwrite(adrs
, val
, size
);
1899 else if( n
== '\'' )
1901 for (i
= 0; i
< size
; ++i
)
1902 val
[i
] = n
>> (i
* 8);
1905 mwrite(adrs
, val
, size
);
1942 adrs
-= 1 << nslash
;
1946 adrs
+= 1 << nslash
;
1950 adrs
+= 1 << -nslash
;
1954 adrs
-= 1 << -nslash
;
1957 scanhex((void *)&adrs
);
1976 printf(memex_subcmd_help_string
);
1991 case 'n': c
= '\n'; break;
1992 case 'r': c
= '\r'; break;
1993 case 'b': c
= '\b'; break;
1994 case 't': c
= '\t'; break;
1999 static void xmon_rawdump (unsigned long adrs
, long ndump
)
2002 unsigned char temp
[16];
2004 for (n
= ndump
; n
> 0;) {
2006 nr
= mread(adrs
, temp
, r
);
2008 for (m
= 0; m
< r
; ++m
) {
2010 printf("%.2x", temp
[m
]);
2012 printf("%s", fault_chars
[fault_type
]);
2021 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2022 || ('a' <= (c) && (c) <= 'f') \
2023 || ('A' <= (c) && (c) <= 'F'))
2030 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2032 scanhex((void *)&adrs
);
2039 else if (nidump
> MAX_DUMP
)
2041 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2043 } else if (c
== 'l') {
2045 } else if (c
== 'r') {
2049 xmon_rawdump(adrs
, ndump
);
2056 else if (ndump
> MAX_DUMP
)
2058 prdump(adrs
, ndump
);
2065 prdump(unsigned long adrs
, long ndump
)
2067 long n
, m
, c
, r
, nr
;
2068 unsigned char temp
[16];
2070 for (n
= ndump
; n
> 0;) {
2074 nr
= mread(adrs
, temp
, r
);
2076 for (m
= 0; m
< r
; ++m
) {
2077 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2080 printf("%.2x", temp
[m
]);
2082 printf("%s", fault_chars
[fault_type
]);
2084 for (; m
< 16; ++m
) {
2085 if ((m
& (sizeof(long) - 1)) == 0)
2090 for (m
= 0; m
< r
; ++m
) {
2093 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2106 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2109 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2110 instruction_dump_func dump_func
)
2113 unsigned long first_adr
;
2114 unsigned long inst
, last_inst
= 0;
2115 unsigned char val
[4];
2118 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2119 nr
= mread(adr
, val
, 4);
2122 const char *x
= fault_chars
[fault_type
];
2123 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2127 inst
= GETWORD(val
);
2128 if (adr
> first_adr
&& inst
== last_inst
) {
2138 printf(REG
" %.8x", adr
, inst
);
2140 dump_func(inst
, adr
);
2143 return adr
- first_adr
;
2147 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2149 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2153 print_address(unsigned long addr
)
2155 xmon_print_symbol(addr
, "\t# ", "");
2161 const unsigned long size
= 128;
2162 unsigned long end
, addr
;
2163 unsigned char buf
[size
+ 1];
2168 if (setjmp(bus_error_jmp
) != 0) {
2169 printf("Unable to lookup symbol __log_buf!\n");
2173 catch_memory_errors
= 1;
2175 addr
= kallsyms_lookup_name("__log_buf");
2178 printf("Symbol __log_buf not found!\n");
2180 end
= addr
+ (1 << CONFIG_LOG_BUF_SHIFT
);
2181 while (addr
< end
) {
2182 if (! mread(addr
, buf
, size
)) {
2183 printf("Can't read memory at address 0x%lx\n", addr
);
2189 if (strlen(buf
) < size
)
2197 /* wait a little while to see if we get a machine check */
2199 catch_memory_errors
= 0;
2203 * Memory operations - move, set, print differences
2205 static unsigned long mdest
; /* destination address */
2206 static unsigned long msrc
; /* source address */
2207 static unsigned long mval
; /* byte value to set memory to */
2208 static unsigned long mcount
; /* # bytes to affect */
2209 static unsigned long mdiffs
; /* max # differences to print */
2214 scanhex((void *)&mdest
);
2215 if( termch
!= '\n' )
2217 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2218 if( termch
!= '\n' )
2220 scanhex((void *)&mcount
);
2223 memmove((void *)mdest
, (void *)msrc
, mcount
);
2226 memset((void *)mdest
, mval
, mcount
);
2229 if( termch
!= '\n' )
2231 scanhex((void *)&mdiffs
);
2232 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2238 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2243 for( n
= nb
; n
> 0; --n
)
2244 if( *p1
++ != *p2
++ )
2245 if( ++prt
<= maxpr
)
2246 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2247 p1
[-1], p2
- 1, p2
[-1]);
2249 printf("Total of %d differences\n", prt
);
2252 static unsigned mend
;
2253 static unsigned mask
;
2259 unsigned char val
[4];
2262 scanhex((void *)&mdest
);
2263 if (termch
!= '\n') {
2265 scanhex((void *)&mend
);
2266 if (termch
!= '\n') {
2268 scanhex((void *)&mval
);
2270 if (termch
!= '\n') termch
= 0;
2271 scanhex((void *)&mask
);
2275 for (a
= mdest
; a
< mend
; a
+= 4) {
2276 if (mread(a
, val
, 4) == 4
2277 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2278 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2285 static unsigned long mskip
= 0x1000;
2286 static unsigned long mlim
= 0xffffffff;
2296 if (termch
!= '\n') termch
= 0;
2298 if (termch
!= '\n') termch
= 0;
2301 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2302 ok
= mread(a
, &v
, 1);
2304 printf("%.8x .. ", a
);
2305 } else if (!ok
&& ook
)
2306 printf("%.8x\n", a
- mskip
);
2312 printf("%.8x\n", a
- mskip
);
2315 static void proccall(void)
2317 unsigned long args
[8];
2320 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2321 unsigned long, unsigned long, unsigned long,
2322 unsigned long, unsigned long, unsigned long);
2325 if (!scanhex(&adrs
))
2329 for (i
= 0; i
< 8; ++i
)
2331 for (i
= 0; i
< 8; ++i
) {
2332 if (!scanhex(&args
[i
]) || termch
== '\n')
2336 func
= (callfunc_t
) adrs
;
2338 if (setjmp(bus_error_jmp
) == 0) {
2339 catch_memory_errors
= 1;
2341 ret
= func(args
[0], args
[1], args
[2], args
[3],
2342 args
[4], args
[5], args
[6], args
[7]);
2344 printf("return value is %x\n", ret
);
2346 printf("*** %x exception occurred\n", fault_except
);
2348 catch_memory_errors
= 0;
2351 /* Input scanning routines */
2362 while( c
== ' ' || c
== '\t' )
2368 static char *regnames
[N_PTREGS
] = {
2369 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2370 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2371 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2372 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2373 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2379 "trap", "dar", "dsisr", "res"
2383 scanhex(unsigned long *vp
)
2390 /* parse register name */
2394 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2403 for (i
= 0; i
< N_PTREGS
; ++i
) {
2404 if (strcmp(regnames
[i
], regname
) == 0) {
2405 if (xmon_regs
== NULL
) {
2406 printf("regs not available\n");
2409 *vp
= ((unsigned long *)xmon_regs
)[i
];
2413 printf("invalid register name '%%%s'\n", regname
);
2417 /* skip leading "0x" if any */
2431 } else if (c
== '$') {
2433 for (i
=0; i
<63; i
++) {
2443 if (setjmp(bus_error_jmp
) == 0) {
2444 catch_memory_errors
= 1;
2446 *vp
= kallsyms_lookup_name(tmpstr
);
2449 catch_memory_errors
= 0;
2451 printf("unknown symbol '%s'\n", tmpstr
);
2484 static int hexdigit(int c
)
2486 if( '0' <= c
&& c
<= '9' )
2488 if( 'A' <= c
&& c
<= 'F' )
2489 return c
- ('A' - 10);
2490 if( 'a' <= c
&& c
<= 'f' )
2491 return c
- ('a' - 10);
2496 getstring(char *s
, int size
)
2507 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2512 static char line
[256];
2513 static char *lineptr
;
2524 if (lineptr
== NULL
|| *lineptr
== 0) {
2525 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2535 take_input(char *str
)
2544 int type
= inchar();
2546 static char tmp
[64];
2551 xmon_print_symbol(addr
, ": ", "\n");
2556 if (setjmp(bus_error_jmp
) == 0) {
2557 catch_memory_errors
= 1;
2559 addr
= kallsyms_lookup_name(tmp
);
2561 printf("%s: %lx\n", tmp
, addr
);
2563 printf("Symbol '%s' not found.\n", tmp
);
2566 catch_memory_errors
= 0;
2573 /* Print an address in numeric and symbolic form (if possible) */
2574 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2578 const char *name
= NULL
;
2579 unsigned long offset
, size
;
2581 printf(REG
, address
);
2582 if (setjmp(bus_error_jmp
) == 0) {
2583 catch_memory_errors
= 1;
2585 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2588 /* wait a little while to see if we get a machine check */
2592 catch_memory_errors
= 0;
2595 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2597 printf(" [%s]", modname
);
2599 printf("%s", after
);
2602 #ifdef CONFIG_PPC_BOOK3S_64
2603 static void dump_slb(void)
2606 unsigned long esid
,vsid
,valid
;
2609 printf("SLB contents of cpu %x\n", smp_processor_id());
2611 for (i
= 0; i
< mmu_slb_size
; i
++) {
2612 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2613 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2614 valid
= (esid
& SLB_ESID_V
);
2615 if (valid
| esid
| vsid
) {
2616 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2618 llp
= vsid
& SLB_VSID_LLP
;
2619 if (vsid
& SLB_VSID_B_1T
) {
2620 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2622 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2625 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2627 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2636 static void dump_stab(void)
2639 unsigned long *tmp
= (unsigned long *)get_paca()->stab_addr
;
2641 printf("Segment table contents of cpu %x\n", smp_processor_id());
2643 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2650 printf("%03d %016lx ", i
, a
);
2651 printf("%016lx\n", b
);
2656 void dump_segments(void)
2658 if (cpu_has_feature(CPU_FTR_SLB
))
2665 #ifdef CONFIG_PPC_STD_MMU_32
2666 void dump_segments(void)
2671 for (i
= 0; i
< 16; ++i
)
2672 printf(" %x", mfsrin(i
));
2678 static void dump_tlb_44x(void)
2682 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2683 unsigned long w0
,w1
,w2
;
2684 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2685 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2686 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2687 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2688 if (w0
& PPC44x_TLB_VALID
) {
2689 printf("V %08x -> %01x%08x %c%c%c%c%c",
2690 w0
& PPC44x_TLB_EPN_MASK
,
2691 w1
& PPC44x_TLB_ERPN_MASK
,
2692 w1
& PPC44x_TLB_RPN_MASK
,
2693 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2694 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2695 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2696 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2697 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2702 #endif /* CONFIG_44x */
2704 static void xmon_init(int enable
)
2706 #ifdef CONFIG_PPC_ISERIES
2707 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2712 __debugger_ipi
= xmon_ipi
;
2713 __debugger_bpt
= xmon_bpt
;
2714 __debugger_sstep
= xmon_sstep
;
2715 __debugger_iabr_match
= xmon_iabr_match
;
2716 __debugger_dabr_match
= xmon_dabr_match
;
2717 __debugger_fault_handler
= xmon_fault_handler
;
2720 __debugger_ipi
= NULL
;
2721 __debugger_bpt
= NULL
;
2722 __debugger_sstep
= NULL
;
2723 __debugger_iabr_match
= NULL
;
2724 __debugger_dabr_match
= NULL
;
2725 __debugger_fault_handler
= NULL
;
2730 #ifdef CONFIG_MAGIC_SYSRQ
2731 static void sysrq_handle_xmon(int key
, struct tty_struct
*tty
)
2733 /* ensure xmon is enabled */
2735 debugger(get_irq_regs());
2738 static struct sysrq_key_op sysrq_xmon_op
=
2740 .handler
= sysrq_handle_xmon
,
2742 .action_msg
= "Entering xmon",
2745 static int __init
setup_xmon_sysrq(void)
2747 #ifdef CONFIG_PPC_ISERIES
2748 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2751 register_sysrq_key('x', &sysrq_xmon_op
);
2754 __initcall(setup_xmon_sysrq
);
2755 #endif /* CONFIG_MAGIC_SYSRQ */
2757 static int __initdata xmon_early
, xmon_off
;
2759 static int __init
early_parse_xmon(char *p
)
2761 if (!p
|| strncmp(p
, "early", 5) == 0) {
2762 /* just "xmon" is equivalent to "xmon=early" */
2765 } else if (strncmp(p
, "on", 2) == 0)
2767 else if (strncmp(p
, "off", 3) == 0)
2769 else if (strncmp(p
, "nobt", 4) == 0)
2770 xmon_no_auto_backtrace
= 1;
2776 early_param("xmon", early_parse_xmon
);
2778 void __init
xmon_setup(void)
2780 #ifdef CONFIG_XMON_DEFAULT
2788 #ifdef CONFIG_SPU_BASE
2792 u64 saved_mfc_sr1_RW
;
2793 u32 saved_spu_runcntl_RW
;
2794 unsigned long dump_addr
;
2798 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2800 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2802 void xmon_register_spus(struct list_head
*list
)
2806 list_for_each_entry(spu
, list
, full_list
) {
2807 if (spu
->number
>= XMON_NUM_SPUS
) {
2812 spu_info
[spu
->number
].spu
= spu
;
2813 spu_info
[spu
->number
].stopped_ok
= 0;
2814 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2815 spu_info
[spu
->number
].spu
->local_store
;
2819 static void stop_spus(void)
2825 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2826 if (!spu_info
[i
].spu
)
2829 if (setjmp(bus_error_jmp
) == 0) {
2830 catch_memory_errors
= 1;
2833 spu
= spu_info
[i
].spu
;
2835 spu_info
[i
].saved_spu_runcntl_RW
=
2836 in_be32(&spu
->problem
->spu_runcntl_RW
);
2838 tmp
= spu_mfc_sr1_get(spu
);
2839 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2841 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2842 spu_mfc_sr1_set(spu
, tmp
);
2847 spu_info
[i
].stopped_ok
= 1;
2849 printf("Stopped spu %.2d (was %s)\n", i
,
2850 spu_info
[i
].saved_spu_runcntl_RW
?
2851 "running" : "stopped");
2853 catch_memory_errors
= 0;
2854 printf("*** Error stopping spu %.2d\n", i
);
2856 catch_memory_errors
= 0;
2860 static void restart_spus(void)
2865 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2866 if (!spu_info
[i
].spu
)
2869 if (!spu_info
[i
].stopped_ok
) {
2870 printf("*** Error, spu %d was not successfully stopped"
2871 ", not restarting\n", i
);
2875 if (setjmp(bus_error_jmp
) == 0) {
2876 catch_memory_errors
= 1;
2879 spu
= spu_info
[i
].spu
;
2880 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
2881 out_be32(&spu
->problem
->spu_runcntl_RW
,
2882 spu_info
[i
].saved_spu_runcntl_RW
);
2887 printf("Restarted spu %.2d\n", i
);
2889 catch_memory_errors
= 0;
2890 printf("*** Error restarting spu %.2d\n", i
);
2892 catch_memory_errors
= 0;
2896 #define DUMP_WIDTH 23
2897 #define DUMP_VALUE(format, field, value) \
2899 if (setjmp(bus_error_jmp) == 0) { \
2900 catch_memory_errors = 1; \
2902 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2907 catch_memory_errors = 0; \
2908 printf(" %-*s = *** Error reading field.\n", \
2909 DUMP_WIDTH, #field); \
2911 catch_memory_errors = 0; \
2914 #define DUMP_FIELD(obj, format, field) \
2915 DUMP_VALUE(format, field, obj->field)
2917 static void dump_spu_fields(struct spu
*spu
)
2919 printf("Dumping spu fields at address %p:\n", spu
);
2921 DUMP_FIELD(spu
, "0x%x", number
);
2922 DUMP_FIELD(spu
, "%s", name
);
2923 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
2924 DUMP_FIELD(spu
, "0x%p", local_store
);
2925 DUMP_FIELD(spu
, "0x%lx", ls_size
);
2926 DUMP_FIELD(spu
, "0x%x", node
);
2927 DUMP_FIELD(spu
, "0x%lx", flags
);
2928 DUMP_FIELD(spu
, "%d", class_0_pending
);
2929 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
2930 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
2931 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
2932 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
2933 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
2934 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
2935 DUMP_FIELD(spu
, "0x%x", slb_replace
);
2936 DUMP_FIELD(spu
, "%d", pid
);
2937 DUMP_FIELD(spu
, "0x%p", mm
);
2938 DUMP_FIELD(spu
, "0x%p", ctx
);
2939 DUMP_FIELD(spu
, "0x%p", rq
);
2940 DUMP_FIELD(spu
, "0x%p", timestamp
);
2941 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
2942 DUMP_FIELD(spu
, "0x%p", problem
);
2943 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
2944 in_be32(&spu
->problem
->spu_runcntl_RW
));
2945 DUMP_VALUE("0x%x", problem
->spu_status_R
,
2946 in_be32(&spu
->problem
->spu_status_R
));
2947 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
2948 in_be32(&spu
->problem
->spu_npc_RW
));
2949 DUMP_FIELD(spu
, "0x%p", priv2
);
2950 DUMP_FIELD(spu
, "0x%p", pdata
);
2954 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
2956 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
2959 static void dump_spu_ls(unsigned long num
, int subcmd
)
2961 unsigned long offset
, addr
, ls_addr
;
2963 if (setjmp(bus_error_jmp
) == 0) {
2964 catch_memory_errors
= 1;
2966 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
2970 catch_memory_errors
= 0;
2971 printf("*** Error: accessing spu info for spu %d\n", num
);
2974 catch_memory_errors
= 0;
2976 if (scanhex(&offset
))
2977 addr
= ls_addr
+ offset
;
2979 addr
= spu_info
[num
].dump_addr
;
2981 if (addr
>= ls_addr
+ LS_SIZE
) {
2982 printf("*** Error: address outside of local store\n");
2988 addr
+= spu_inst_dump(addr
, 16, 1);
2998 spu_info
[num
].dump_addr
= addr
;
3001 static int do_spu_cmd(void)
3003 static unsigned long num
= 0;
3004 int cmd
, subcmd
= 0;
3016 if (isxdigit(subcmd
) || subcmd
== '\n')
3020 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3021 printf("*** Error: invalid spu number\n");
3027 dump_spu_fields(spu_info
[num
].spu
);
3030 dump_spu_ls(num
, subcmd
);
3041 #else /* ! CONFIG_SPU_BASE */
3042 static int do_spu_cmd(void)