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 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");
520 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
521 bp
= at_breakpoint(regs
->nip
);
523 int stepped
= emulate_step(regs
, bp
->instr
[0]);
525 regs
->nip
= (unsigned long) &bp
->instr
[0];
526 atomic_inc(&bp
->ref_count
);
527 } else if (stepped
< 0) {
528 printf("Couldn't single-step %s instruction\n",
529 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
536 local_irq_restore(flags
);
538 return cmd
!= 'X' && cmd
!= EOF
;
541 int xmon(struct pt_regs
*excp
)
546 ppc_save_regs(®s
);
550 return xmon_core(excp
, 0);
554 irqreturn_t
xmon_irq(int irq
, void *d
)
557 local_irq_save(flags
);
558 printf("Keyboard interrupt\n");
559 xmon(get_irq_regs());
560 local_irq_restore(flags
);
564 static int xmon_bpt(struct pt_regs
*regs
)
567 unsigned long offset
;
569 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
572 /* Are we at the trap at bp->instr[1] for some bp? */
573 bp
= in_breakpoint_table(regs
->nip
, &offset
);
574 if (bp
!= NULL
&& offset
== 4) {
575 regs
->nip
= bp
->address
+ 4;
576 atomic_dec(&bp
->ref_count
);
580 /* Are we at a breakpoint? */
581 bp
= at_breakpoint(regs
->nip
);
590 static int xmon_sstep(struct pt_regs
*regs
)
598 static int xmon_dabr_match(struct pt_regs
*regs
)
600 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
602 if (dabr
.enabled
== 0)
608 static int xmon_iabr_match(struct pt_regs
*regs
)
610 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
618 static int xmon_ipi(struct pt_regs
*regs
)
621 if (in_xmon
&& !cpu_isset(smp_processor_id(), cpus_in_xmon
))
627 static int xmon_fault_handler(struct pt_regs
*regs
)
630 unsigned long offset
;
632 if (in_xmon
&& catch_memory_errors
)
633 handle_fault(regs
); /* doesn't return */
635 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
636 bp
= in_breakpoint_table(regs
->nip
, &offset
);
638 regs
->nip
= bp
->address
+ offset
;
639 atomic_dec(&bp
->ref_count
);
646 static struct bpt
*at_breakpoint(unsigned long pc
)
652 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
653 if (bp
->enabled
&& pc
== bp
->address
)
658 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
662 off
= nip
- (unsigned long) bpts
;
663 if (off
>= sizeof(bpts
))
665 off
%= sizeof(struct bpt
);
666 if (off
!= offsetof(struct bpt
, instr
[0])
667 && off
!= offsetof(struct bpt
, instr
[1]))
669 *offp
= off
- offsetof(struct bpt
, instr
[0]);
670 return (struct bpt
*) (nip
- off
);
673 static struct bpt
*new_breakpoint(unsigned long a
)
678 bp
= at_breakpoint(a
);
682 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
683 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
685 bp
->instr
[1] = bpinstr
;
686 store_inst(&bp
->instr
[1]);
691 printf("Sorry, no free breakpoints. Please clear one first.\n");
695 static void insert_bpts(void)
701 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
702 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
704 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
705 printf("Couldn't read instruction at %lx, "
706 "disabling breakpoint there\n", bp
->address
);
710 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
711 printf("Breakpoint at %lx is on an mtmsrd or rfid "
712 "instruction, disabling it\n", bp
->address
);
716 store_inst(&bp
->instr
[0]);
717 if (bp
->enabled
& BP_IABR
)
719 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
720 printf("Couldn't write instruction at %lx, "
721 "disabling breakpoint there\n", bp
->address
);
722 bp
->enabled
&= ~BP_TRAP
;
725 store_inst((void *)bp
->address
);
729 static void insert_cpu_bpts(void)
732 set_dabr(dabr
.address
| (dabr
.enabled
& 7));
733 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
734 mtspr(SPRN_IABR
, iabr
->address
735 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
738 static void remove_bpts(void)
745 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
746 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
748 if (mread(bp
->address
, &instr
, 4) == 4
750 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
751 printf("Couldn't remove breakpoint at %lx\n",
754 store_inst((void *)bp
->address
);
758 static void remove_cpu_bpts(void)
761 if (cpu_has_feature(CPU_FTR_IABR
))
765 /* Command interpreting routine */
766 static char *last_cmd
;
769 cmds(struct pt_regs
*excp
)
776 if (!xmon_no_auto_backtrace
) {
777 xmon_no_auto_backtrace
= 1;
778 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
783 printf("%x:", smp_processor_id());
784 #endif /* CONFIG_SMP */
790 if (last_cmd
== NULL
)
792 take_input(last_cmd
);
826 prregs(excp
); /* print regs */
841 if (do_spu_cmd() == 0)
850 printf(" <no input ...>\n");
854 xmon_puts(help_string
);
872 #ifdef CONFIG_PPC_STD_MMU
883 printf("Unrecognized command: ");
885 if (' ' < cmd
&& cmd
<= '~')
888 printf("\\x%x", cmd
);
890 } while (cmd
!= '\n');
891 printf(" (type ? for help)\n");
898 * Step a single instruction.
899 * Some instructions we emulate, others we execute with MSR_SE set.
901 static int do_step(struct pt_regs
*regs
)
906 /* check we are in 64-bit kernel mode, translation enabled */
907 if ((regs
->msr
& (MSR_SF
|MSR_PR
|MSR_IR
)) == (MSR_SF
|MSR_IR
)) {
908 if (mread(regs
->nip
, &instr
, 4) == 4) {
909 stepped
= emulate_step(regs
, instr
);
911 printf("Couldn't single-step %s instruction\n",
912 (IS_RFID(instr
)? "rfid": "mtmsrd"));
916 regs
->trap
= 0xd00 | (regs
->trap
& 1);
917 printf("stepped to ");
918 xmon_print_symbol(regs
->nip
, " ", "\n");
919 ppc_inst_dump(regs
->nip
, 1, 0);
928 static void bootcmds(void)
934 ppc_md
.restart(NULL
);
941 static int cpu_cmd(void)
948 if (!scanhex(&cpu
)) {
949 /* print cpus waiting or in xmon */
950 printf("cpus stopped:");
952 for (cpu
= 0; cpu
< NR_CPUS
; ++cpu
) {
953 if (cpu_isset(cpu
, cpus_in_xmon
)) {
959 printf("-%x", cpu
- 1);
964 printf("-%x", NR_CPUS
- 1);
968 /* try to switch to cpu specified */
969 if (!cpu_isset(cpu
, cpus_in_xmon
)) {
970 printf("cpu 0x%x isn't in xmon\n", cpu
);
977 while (!xmon_taken
) {
978 if (--timeout
== 0) {
979 if (test_and_set_bit(0, &xmon_taken
))
981 /* take control back */
983 xmon_owner
= smp_processor_id();
984 printf("cpu %u didn't take control\n", cpu
);
992 #endif /* CONFIG_SMP */
995 static unsigned short fcstab
[256] = {
996 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
997 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
998 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
999 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1000 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1001 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1002 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1003 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1004 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1005 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1006 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1007 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1008 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1009 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1010 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1011 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1012 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1013 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1014 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1015 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1016 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1017 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1018 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1019 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1020 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1021 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1022 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1023 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1024 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1025 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1026 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1027 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1030 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1039 if (!scanhex(&adrs
))
1041 if (!scanhex(&ncsum
))
1044 for (i
= 0; i
< ncsum
; ++i
) {
1045 if (mread(adrs
+i
, &v
, 1) == 0) {
1046 printf("csum stopped at %x\n", adrs
+i
);
1051 printf("%x\n", fcs
);
1055 * Check if this is a suitable place to put a breakpoint.
1057 static long check_bp_loc(unsigned long addr
)
1062 if (!is_kernel_addr(addr
)) {
1063 printf("Breakpoints may only be placed at kernel addresses\n");
1066 if (!mread(addr
, &instr
, sizeof(instr
))) {
1067 printf("Can't read instruction at address %lx\n", addr
);
1070 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1071 printf("Breakpoints may not be placed on mtmsrd or rfid "
1078 static char *breakpoint_help_string
=
1079 "Breakpoint command usage:\n"
1080 "b show breakpoints\n"
1081 "b <addr> [cnt] set breakpoint at given instr addr\n"
1082 "bc clear all breakpoints\n"
1083 "bc <n/addr> clear breakpoint number n or at addr\n"
1084 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1085 "bd <addr> [cnt] set hardware data breakpoint\n"
1095 const char badaddr
[] = "Only kernel addresses are permitted "
1096 "for breakpoints\n";
1101 case 'd': /* bd - hardware data breakpoint */
1106 else if (cmd
== 'w')
1112 if (scanhex(&dabr
.address
)) {
1113 if (!is_kernel_addr(dabr
.address
)) {
1118 dabr
.enabled
= mode
| BP_DABR
;
1122 case 'i': /* bi - hardware instr breakpoint */
1123 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1124 printf("Hardware instruction breakpoint "
1125 "not supported on this cpu\n");
1129 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1134 if (!check_bp_loc(a
))
1136 bp
= new_breakpoint(a
);
1138 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1146 /* clear all breakpoints */
1147 for (i
= 0; i
< NBPTS
; ++i
)
1148 bpts
[i
].enabled
= 0;
1151 printf("All breakpoints cleared\n");
1155 if (a
<= NBPTS
&& a
>= 1) {
1156 /* assume a breakpoint number */
1157 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1159 /* assume a breakpoint address */
1160 bp
= at_breakpoint(a
);
1162 printf("No breakpoint at %x\n", a
);
1167 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1168 xmon_print_symbol(bp
->address
, " ", ")\n");
1176 printf(breakpoint_help_string
);
1181 /* print all breakpoints */
1182 printf(" type address\n");
1184 printf(" data "REG
" [", dabr
.address
);
1185 if (dabr
.enabled
& 1)
1187 if (dabr
.enabled
& 2)
1191 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1194 printf("%2x %s ", BP_NUM(bp
),
1195 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1196 xmon_print_symbol(bp
->address
, " ", "\n");
1201 if (!check_bp_loc(a
))
1203 bp
= new_breakpoint(a
);
1205 bp
->enabled
|= BP_TRAP
;
1210 /* Very cheap human name for vector lookup. */
1212 const char *getvecname(unsigned long vec
)
1217 case 0x100: ret
= "(System Reset)"; break;
1218 case 0x200: ret
= "(Machine Check)"; break;
1219 case 0x300: ret
= "(Data Access)"; break;
1220 case 0x380: ret
= "(Data SLB Access)"; break;
1221 case 0x400: ret
= "(Instruction Access)"; break;
1222 case 0x480: ret
= "(Instruction SLB Access)"; break;
1223 case 0x500: ret
= "(Hardware Interrupt)"; break;
1224 case 0x600: ret
= "(Alignment)"; break;
1225 case 0x700: ret
= "(Program Check)"; break;
1226 case 0x800: ret
= "(FPU Unavailable)"; break;
1227 case 0x900: ret
= "(Decrementer)"; break;
1228 case 0xc00: ret
= "(System Call)"; break;
1229 case 0xd00: ret
= "(Single Step)"; break;
1230 case 0xf00: ret
= "(Performance Monitor)"; break;
1231 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1232 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1238 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1239 unsigned long *endp
)
1241 unsigned long size
, offset
;
1244 *startp
= *endp
= 0;
1247 if (setjmp(bus_error_jmp
) == 0) {
1248 catch_memory_errors
= 1;
1250 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1252 *startp
= pc
- offset
;
1253 *endp
= pc
- offset
+ size
;
1257 catch_memory_errors
= 0;
1260 static int xmon_depth_to_print
= 64;
1262 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1263 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1265 #ifdef __powerpc64__
1266 #define REGS_OFFSET 0x70
1268 #define REGS_OFFSET 16
1271 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1275 unsigned long newsp
;
1276 unsigned long marker
;
1278 struct pt_regs regs
;
1281 if (sp
< PAGE_OFFSET
) {
1283 printf("SP (%lx) is in userspace\n", sp
);
1287 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1288 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1289 printf("Couldn't read stack frame at %lx\n", sp
);
1294 * For the first stack frame, try to work out if
1295 * LR and/or the saved LR value in the bottommost
1296 * stack frame are valid.
1298 if ((pc
| lr
) != 0) {
1299 unsigned long fnstart
, fnend
;
1300 unsigned long nextip
;
1303 get_function_bounds(pc
, &fnstart
, &fnend
);
1306 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1307 sizeof(unsigned long));
1309 if (lr
< PAGE_OFFSET
1310 || (fnstart
<= lr
&& lr
< fnend
))
1312 } else if (lr
== nextip
) {
1314 } else if (lr
>= PAGE_OFFSET
1315 && !(fnstart
<= lr
&& lr
< fnend
)) {
1316 printf("[link register ] ");
1317 xmon_print_symbol(lr
, " ", "\n");
1320 printf("["REG
"] ", sp
);
1321 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1326 printf("["REG
"] ", sp
);
1327 xmon_print_symbol(ip
, " ", "\n");
1330 /* Look for "regshere" marker to see if this is
1331 an exception frame. */
1332 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1333 && marker
== STACK_FRAME_REGS_MARKER
) {
1334 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1336 printf("Couldn't read registers at %lx\n",
1340 printf("--- Exception: %lx %s at ", regs
.trap
,
1341 getvecname(TRAP(®s
)));
1344 xmon_print_symbol(pc
, " ", "\n");
1351 } while (count
++ < xmon_depth_to_print
);
1354 static void backtrace(struct pt_regs
*excp
)
1359 xmon_show_stack(sp
, 0, 0);
1361 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1365 static void print_bug_trap(struct pt_regs
*regs
)
1368 const struct bug_entry
*bug
;
1371 if (regs
->msr
& MSR_PR
)
1372 return; /* not in kernel */
1373 addr
= regs
->nip
; /* address of trap instruction */
1374 if (addr
< PAGE_OFFSET
)
1376 bug
= find_bug(regs
->nip
);
1379 if (is_warning_bug(bug
))
1382 #ifdef CONFIG_DEBUG_BUGVERBOSE
1383 printf("kernel BUG at %s:%u!\n",
1384 bug
->file
, bug
->line
);
1386 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1388 #endif /* CONFIG_BUG */
1391 static void excprint(struct pt_regs
*fp
)
1396 printf("cpu 0x%x: ", smp_processor_id());
1397 #endif /* CONFIG_SMP */
1400 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1402 xmon_print_symbol(fp
->nip
, ": ", "\n");
1404 printf(" lr: ", fp
->link
);
1405 xmon_print_symbol(fp
->link
, ": ", "\n");
1407 printf(" sp: %lx\n", fp
->gpr
[1]);
1408 printf(" msr: %lx\n", fp
->msr
);
1410 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1411 printf(" dar: %lx\n", fp
->dar
);
1413 printf(" dsisr: %lx\n", fp
->dsisr
);
1416 printf(" current = 0x%lx\n", current
);
1418 printf(" paca = 0x%lx\n", get_paca());
1421 printf(" pid = %ld, comm = %s\n",
1422 current
->pid
, current
->comm
);
1429 static void prregs(struct pt_regs
*fp
)
1433 struct pt_regs regs
;
1435 if (scanhex(&base
)) {
1436 if (setjmp(bus_error_jmp
) == 0) {
1437 catch_memory_errors
= 1;
1439 regs
= *(struct pt_regs
*)base
;
1443 catch_memory_errors
= 0;
1444 printf("*** Error reading registers from "REG
"\n",
1448 catch_memory_errors
= 0;
1453 if (FULL_REGS(fp
)) {
1454 for (n
= 0; n
< 16; ++n
)
1455 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1456 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1458 for (n
= 0; n
< 7; ++n
)
1459 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1460 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1463 for (n
= 0; n
< 32; ++n
) {
1464 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1465 (n
& 3) == 3? "\n": " ");
1466 if (n
== 12 && !FULL_REGS(fp
)) {
1473 xmon_print_symbol(fp
->nip
, " ", "\n");
1475 xmon_print_symbol(fp
->link
, " ", "\n");
1476 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1477 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1478 fp
->ctr
, fp
->xer
, fp
->trap
);
1480 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1481 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1484 static void cacheflush(void)
1487 unsigned long nflush
;
1492 scanhex((void *)&adrs
);
1497 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1498 if (setjmp(bus_error_jmp
) == 0) {
1499 catch_memory_errors
= 1;
1503 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1504 cflush((void *) adrs
);
1506 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1507 cinval((void *) adrs
);
1510 /* wait a little while to see if we get a machine check */
1513 catch_memory_errors
= 0;
1516 static unsigned long
1519 unsigned int instrs
[2];
1520 unsigned long (*code
)(void);
1521 unsigned long ret
= -1UL;
1523 unsigned long opd
[3];
1525 opd
[0] = (unsigned long)instrs
;
1528 code
= (unsigned long (*)(void)) opd
;
1530 code
= (unsigned long (*)(void)) instrs
;
1533 /* mfspr r3,n; blr */
1534 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1535 instrs
[1] = 0x4e800020;
1537 store_inst(instrs
+1);
1539 if (setjmp(bus_error_jmp
) == 0) {
1540 catch_memory_errors
= 1;
1546 /* wait a little while to see if we get a machine check */
1555 write_spr(int n
, unsigned long val
)
1557 unsigned int instrs
[2];
1558 unsigned long (*code
)(unsigned long);
1560 unsigned long opd
[3];
1562 opd
[0] = (unsigned long)instrs
;
1565 code
= (unsigned long (*)(unsigned long)) opd
;
1567 code
= (unsigned long (*)(unsigned long)) instrs
;
1570 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1571 instrs
[1] = 0x4e800020;
1573 store_inst(instrs
+1);
1575 if (setjmp(bus_error_jmp
) == 0) {
1576 catch_memory_errors
= 1;
1582 /* wait a little while to see if we get a machine check */
1588 static unsigned long regno
;
1589 extern char exc_prolog
;
1590 extern char dec_exc
;
1592 static void super_regs(void)
1599 unsigned long sp
, toc
;
1600 asm("mr %0,1" : "=r" (sp
) :);
1601 asm("mr %0,2" : "=r" (toc
) :);
1603 printf("msr = "REG
" sprg0= "REG
"\n",
1604 mfmsr(), mfspr(SPRN_SPRG0
));
1605 printf("pvr = "REG
" sprg1= "REG
"\n",
1606 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1607 printf("dec = "REG
" sprg2= "REG
"\n",
1608 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1609 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1610 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1611 #ifdef CONFIG_PPC_ISERIES
1612 if (firmware_has_feature(FW_FEATURE_ISERIES
)) {
1613 struct paca_struct
*ptrPaca
;
1614 struct lppaca
*ptrLpPaca
;
1616 /* Dump out relevant Paca data areas. */
1618 ptrPaca
= get_paca();
1620 printf(" Local Processor Control Area (LpPaca): \n");
1621 ptrLpPaca
= ptrPaca
->lppaca_ptr
;
1622 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1623 ptrLpPaca
->saved_srr0
, ptrLpPaca
->saved_srr1
);
1624 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1625 ptrLpPaca
->saved_gpr3
, ptrLpPaca
->saved_gpr4
);
1626 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca
->saved_gpr5
);
1636 val
= read_spr(regno
);
1638 write_spr(regno
, val
);
1641 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1648 * Stuff for reading and writing memory safely
1651 mread(unsigned long adrs
, void *buf
, int size
)
1657 if (setjmp(bus_error_jmp
) == 0) {
1658 catch_memory_errors
= 1;
1664 *(u16
*)q
= *(u16
*)p
;
1667 *(u32
*)q
= *(u32
*)p
;
1670 *(u64
*)q
= *(u64
*)p
;
1673 for( ; n
< size
; ++n
) {
1679 /* wait a little while to see if we get a machine check */
1683 catch_memory_errors
= 0;
1688 mwrite(unsigned long adrs
, void *buf
, int size
)
1694 if (setjmp(bus_error_jmp
) == 0) {
1695 catch_memory_errors
= 1;
1701 *(u16
*)p
= *(u16
*)q
;
1704 *(u32
*)p
= *(u32
*)q
;
1707 *(u64
*)p
= *(u64
*)q
;
1710 for ( ; n
< size
; ++n
) {
1716 /* wait a little while to see if we get a machine check */
1720 printf("*** Error writing address %x\n", adrs
+ n
);
1722 catch_memory_errors
= 0;
1726 static int fault_type
;
1727 static int fault_except
;
1728 static char *fault_chars
[] = { "--", "**", "##" };
1730 static int handle_fault(struct pt_regs
*regs
)
1732 fault_except
= TRAP(regs
);
1733 switch (TRAP(regs
)) {
1745 longjmp(bus_error_jmp
, 1);
1750 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1753 byterev(unsigned char *val
, int size
)
1759 SWAP(val
[0], val
[1], t
);
1762 SWAP(val
[0], val
[3], t
);
1763 SWAP(val
[1], val
[2], t
);
1765 case 8: /* is there really any use for this? */
1766 SWAP(val
[0], val
[7], t
);
1767 SWAP(val
[1], val
[6], t
);
1768 SWAP(val
[2], val
[5], t
);
1769 SWAP(val
[3], val
[4], t
);
1777 static char *memex_help_string
=
1778 "Memory examine command usage:\n"
1779 "m [addr] [flags] examine/change memory\n"
1780 " addr is optional. will start where left off.\n"
1781 " flags may include chars from this set:\n"
1782 " b modify by bytes (default)\n"
1783 " w modify by words (2 byte)\n"
1784 " l modify by longs (4 byte)\n"
1785 " d modify by doubleword (8 byte)\n"
1786 " r toggle reverse byte order mode\n"
1787 " n do not read memory (for i/o spaces)\n"
1788 " . ok to read (default)\n"
1789 "NOTE: flags are saved as defaults\n"
1792 static char *memex_subcmd_help_string
=
1793 "Memory examine subcommands:\n"
1794 " hexval write this val to current location\n"
1795 " 'string' write chars from string to this location\n"
1796 " ' increment address\n"
1797 " ^ decrement address\n"
1798 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1799 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1800 " ` clear no-read flag\n"
1801 " ; stay at this addr\n"
1802 " v change to byte mode\n"
1803 " w change to word (2 byte) mode\n"
1804 " l change to long (4 byte) mode\n"
1805 " u change to doubleword (8 byte) mode\n"
1806 " m addr change current addr\n"
1807 " n toggle no-read flag\n"
1808 " r toggle byte reverse flag\n"
1809 " < count back up count bytes\n"
1810 " > count skip forward count bytes\n"
1811 " x exit this mode\n"
1817 int cmd
, inc
, i
, nslash
;
1819 unsigned char val
[16];
1821 scanhex((void *)&adrs
);
1824 printf(memex_help_string
);
1830 while ((cmd
= skipbl()) != '\n') {
1832 case 'b': size
= 1; break;
1833 case 'w': size
= 2; break;
1834 case 'l': size
= 4; break;
1835 case 'd': size
= 8; break;
1836 case 'r': brev
= !brev
; break;
1837 case 'n': mnoread
= 1; break;
1838 case '.': mnoread
= 0; break;
1847 n
= mread(adrs
, val
, size
);
1848 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1853 for (i
= 0; i
< n
; ++i
)
1854 printf("%.2x", val
[i
]);
1855 for (; i
< size
; ++i
)
1856 printf("%s", fault_chars
[fault_type
]);
1863 for (i
= 0; i
< size
; ++i
)
1864 val
[i
] = n
>> (i
* 8);
1867 mwrite(adrs
, val
, size
);
1880 else if( n
== '\'' )
1882 for (i
= 0; i
< size
; ++i
)
1883 val
[i
] = n
>> (i
* 8);
1886 mwrite(adrs
, val
, size
);
1923 adrs
-= 1 << nslash
;
1927 adrs
+= 1 << nslash
;
1931 adrs
+= 1 << -nslash
;
1935 adrs
-= 1 << -nslash
;
1938 scanhex((void *)&adrs
);
1957 printf(memex_subcmd_help_string
);
1972 case 'n': c
= '\n'; break;
1973 case 'r': c
= '\r'; break;
1974 case 'b': c
= '\b'; break;
1975 case 't': c
= '\t'; break;
1980 static void xmon_rawdump (unsigned long adrs
, long ndump
)
1983 unsigned char temp
[16];
1985 for (n
= ndump
; n
> 0;) {
1987 nr
= mread(adrs
, temp
, r
);
1989 for (m
= 0; m
< r
; ++m
) {
1991 printf("%.2x", temp
[m
]);
1993 printf("%s", fault_chars
[fault_type
]);
2002 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2003 || ('a' <= (c) && (c) <= 'f') \
2004 || ('A' <= (c) && (c) <= 'F'))
2011 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2013 scanhex((void *)&adrs
);
2020 else if (nidump
> MAX_DUMP
)
2022 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2024 } else if (c
== 'l') {
2026 } else if (c
== 'r') {
2030 xmon_rawdump(adrs
, ndump
);
2037 else if (ndump
> MAX_DUMP
)
2039 prdump(adrs
, ndump
);
2046 prdump(unsigned long adrs
, long ndump
)
2048 long n
, m
, c
, r
, nr
;
2049 unsigned char temp
[16];
2051 for (n
= ndump
; n
> 0;) {
2055 nr
= mread(adrs
, temp
, r
);
2057 for (m
= 0; m
< r
; ++m
) {
2058 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2061 printf("%.2x", temp
[m
]);
2063 printf("%s", fault_chars
[fault_type
]);
2065 for (; m
< 16; ++m
) {
2066 if ((m
& (sizeof(long) - 1)) == 0)
2071 for (m
= 0; m
< r
; ++m
) {
2074 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2087 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2090 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2091 instruction_dump_func dump_func
)
2094 unsigned long first_adr
;
2095 unsigned long inst
, last_inst
= 0;
2096 unsigned char val
[4];
2099 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2100 nr
= mread(adr
, val
, 4);
2103 const char *x
= fault_chars
[fault_type
];
2104 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2108 inst
= GETWORD(val
);
2109 if (adr
> first_adr
&& inst
== last_inst
) {
2119 printf(REG
" %.8x", adr
, inst
);
2121 dump_func(inst
, adr
);
2124 return adr
- first_adr
;
2128 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2130 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2134 print_address(unsigned long addr
)
2136 xmon_print_symbol(addr
, "\t# ", "");
2142 const unsigned long size
= 128;
2143 unsigned long end
, addr
;
2144 unsigned char buf
[size
+ 1];
2149 if (setjmp(bus_error_jmp
) != 0) {
2150 printf("Unable to lookup symbol __log_buf!\n");
2154 catch_memory_errors
= 1;
2156 addr
= kallsyms_lookup_name("__log_buf");
2159 printf("Symbol __log_buf not found!\n");
2161 end
= addr
+ (1 << CONFIG_LOG_BUF_SHIFT
);
2162 while (addr
< end
) {
2163 if (! mread(addr
, buf
, size
)) {
2164 printf("Can't read memory at address 0x%lx\n", addr
);
2170 if (strlen(buf
) < size
)
2178 /* wait a little while to see if we get a machine check */
2180 catch_memory_errors
= 0;
2184 * Memory operations - move, set, print differences
2186 static unsigned long mdest
; /* destination address */
2187 static unsigned long msrc
; /* source address */
2188 static unsigned long mval
; /* byte value to set memory to */
2189 static unsigned long mcount
; /* # bytes to affect */
2190 static unsigned long mdiffs
; /* max # differences to print */
2195 scanhex((void *)&mdest
);
2196 if( termch
!= '\n' )
2198 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2199 if( termch
!= '\n' )
2201 scanhex((void *)&mcount
);
2204 memmove((void *)mdest
, (void *)msrc
, mcount
);
2207 memset((void *)mdest
, mval
, mcount
);
2210 if( termch
!= '\n' )
2212 scanhex((void *)&mdiffs
);
2213 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2219 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2224 for( n
= nb
; n
> 0; --n
)
2225 if( *p1
++ != *p2
++ )
2226 if( ++prt
<= maxpr
)
2227 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2228 p1
[-1], p2
- 1, p2
[-1]);
2230 printf("Total of %d differences\n", prt
);
2233 static unsigned mend
;
2234 static unsigned mask
;
2240 unsigned char val
[4];
2243 scanhex((void *)&mdest
);
2244 if (termch
!= '\n') {
2246 scanhex((void *)&mend
);
2247 if (termch
!= '\n') {
2249 scanhex((void *)&mval
);
2251 if (termch
!= '\n') termch
= 0;
2252 scanhex((void *)&mask
);
2256 for (a
= mdest
; a
< mend
; a
+= 4) {
2257 if (mread(a
, val
, 4) == 4
2258 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2259 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2266 static unsigned long mskip
= 0x1000;
2267 static unsigned long mlim
= 0xffffffff;
2277 if (termch
!= '\n') termch
= 0;
2279 if (termch
!= '\n') termch
= 0;
2282 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2283 ok
= mread(a
, &v
, 1);
2285 printf("%.8x .. ", a
);
2286 } else if (!ok
&& ook
)
2287 printf("%.8x\n", a
- mskip
);
2293 printf("%.8x\n", a
- mskip
);
2296 static void proccall(void)
2298 unsigned long args
[8];
2301 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2302 unsigned long, unsigned long, unsigned long,
2303 unsigned long, unsigned long, unsigned long);
2306 if (!scanhex(&adrs
))
2310 for (i
= 0; i
< 8; ++i
)
2312 for (i
= 0; i
< 8; ++i
) {
2313 if (!scanhex(&args
[i
]) || termch
== '\n')
2317 func
= (callfunc_t
) adrs
;
2319 if (setjmp(bus_error_jmp
) == 0) {
2320 catch_memory_errors
= 1;
2322 ret
= func(args
[0], args
[1], args
[2], args
[3],
2323 args
[4], args
[5], args
[6], args
[7]);
2325 printf("return value is %x\n", ret
);
2327 printf("*** %x exception occurred\n", fault_except
);
2329 catch_memory_errors
= 0;
2332 /* Input scanning routines */
2343 while( c
== ' ' || c
== '\t' )
2349 static char *regnames
[N_PTREGS
] = {
2350 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2351 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2352 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2353 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2354 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2360 "trap", "dar", "dsisr", "res"
2364 scanhex(unsigned long *vp
)
2371 /* parse register name */
2375 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2384 for (i
= 0; i
< N_PTREGS
; ++i
) {
2385 if (strcmp(regnames
[i
], regname
) == 0) {
2386 if (xmon_regs
== NULL
) {
2387 printf("regs not available\n");
2390 *vp
= ((unsigned long *)xmon_regs
)[i
];
2394 printf("invalid register name '%%%s'\n", regname
);
2398 /* skip leading "0x" if any */
2412 } else if (c
== '$') {
2414 for (i
=0; i
<63; i
++) {
2424 if (setjmp(bus_error_jmp
) == 0) {
2425 catch_memory_errors
= 1;
2427 *vp
= kallsyms_lookup_name(tmpstr
);
2430 catch_memory_errors
= 0;
2432 printf("unknown symbol '%s'\n", tmpstr
);
2465 static int hexdigit(int c
)
2467 if( '0' <= c
&& c
<= '9' )
2469 if( 'A' <= c
&& c
<= 'F' )
2470 return c
- ('A' - 10);
2471 if( 'a' <= c
&& c
<= 'f' )
2472 return c
- ('a' - 10);
2477 getstring(char *s
, int size
)
2488 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2493 static char line
[256];
2494 static char *lineptr
;
2505 if (lineptr
== NULL
|| *lineptr
== 0) {
2506 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2516 take_input(char *str
)
2525 int type
= inchar();
2527 static char tmp
[64];
2532 xmon_print_symbol(addr
, ": ", "\n");
2537 if (setjmp(bus_error_jmp
) == 0) {
2538 catch_memory_errors
= 1;
2540 addr
= kallsyms_lookup_name(tmp
);
2542 printf("%s: %lx\n", tmp
, addr
);
2544 printf("Symbol '%s' not found.\n", tmp
);
2547 catch_memory_errors
= 0;
2554 /* Print an address in numeric and symbolic form (if possible) */
2555 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2559 const char *name
= NULL
;
2560 unsigned long offset
, size
;
2562 printf(REG
, address
);
2563 if (setjmp(bus_error_jmp
) == 0) {
2564 catch_memory_errors
= 1;
2566 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2569 /* wait a little while to see if we get a machine check */
2573 catch_memory_errors
= 0;
2576 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2578 printf(" [%s]", modname
);
2580 printf("%s", after
);
2583 #ifdef CONFIG_PPC_BOOK3S_64
2584 static void dump_slb(void)
2587 unsigned long esid
,vsid
,valid
;
2590 printf("SLB contents of cpu %x\n", smp_processor_id());
2592 for (i
= 0; i
< mmu_slb_size
; i
++) {
2593 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2594 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2595 valid
= (esid
& SLB_ESID_V
);
2596 if (valid
| esid
| vsid
) {
2597 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2599 llp
= vsid
& SLB_VSID_LLP
;
2600 if (vsid
& SLB_VSID_B_1T
) {
2601 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2603 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2606 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2608 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2617 static void dump_stab(void)
2620 unsigned long *tmp
= (unsigned long *)get_paca()->stab_addr
;
2622 printf("Segment table contents of cpu %x\n", smp_processor_id());
2624 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2631 printf("%03d %016lx ", i
, a
);
2632 printf("%016lx\n", b
);
2637 void dump_segments(void)
2639 if (cpu_has_feature(CPU_FTR_SLB
))
2646 #ifdef CONFIG_PPC_STD_MMU_32
2647 void dump_segments(void)
2652 for (i
= 0; i
< 16; ++i
)
2653 printf(" %x", mfsrin(i
));
2659 static void dump_tlb_44x(void)
2663 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2664 unsigned long w0
,w1
,w2
;
2665 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2666 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2667 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2668 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2669 if (w0
& PPC44x_TLB_VALID
) {
2670 printf("V %08x -> %01x%08x %c%c%c%c%c",
2671 w0
& PPC44x_TLB_EPN_MASK
,
2672 w1
& PPC44x_TLB_ERPN_MASK
,
2673 w1
& PPC44x_TLB_RPN_MASK
,
2674 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2675 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2676 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2677 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2678 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2683 #endif /* CONFIG_44x */
2685 static void xmon_init(int enable
)
2687 #ifdef CONFIG_PPC_ISERIES
2688 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2693 __debugger_ipi
= xmon_ipi
;
2694 __debugger_bpt
= xmon_bpt
;
2695 __debugger_sstep
= xmon_sstep
;
2696 __debugger_iabr_match
= xmon_iabr_match
;
2697 __debugger_dabr_match
= xmon_dabr_match
;
2698 __debugger_fault_handler
= xmon_fault_handler
;
2701 __debugger_ipi
= NULL
;
2702 __debugger_bpt
= NULL
;
2703 __debugger_sstep
= NULL
;
2704 __debugger_iabr_match
= NULL
;
2705 __debugger_dabr_match
= NULL
;
2706 __debugger_fault_handler
= NULL
;
2711 #ifdef CONFIG_MAGIC_SYSRQ
2712 static void sysrq_handle_xmon(int key
, struct tty_struct
*tty
)
2714 /* ensure xmon is enabled */
2716 debugger(get_irq_regs());
2719 static struct sysrq_key_op sysrq_xmon_op
=
2721 .handler
= sysrq_handle_xmon
,
2723 .action_msg
= "Entering xmon",
2726 static int __init
setup_xmon_sysrq(void)
2728 #ifdef CONFIG_PPC_ISERIES
2729 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2732 register_sysrq_key('x', &sysrq_xmon_op
);
2735 __initcall(setup_xmon_sysrq
);
2736 #endif /* CONFIG_MAGIC_SYSRQ */
2738 static int __initdata xmon_early
, xmon_off
;
2740 static int __init
early_parse_xmon(char *p
)
2742 if (!p
|| strncmp(p
, "early", 5) == 0) {
2743 /* just "xmon" is equivalent to "xmon=early" */
2746 } else if (strncmp(p
, "on", 2) == 0)
2748 else if (strncmp(p
, "off", 3) == 0)
2750 else if (strncmp(p
, "nobt", 4) == 0)
2751 xmon_no_auto_backtrace
= 1;
2757 early_param("xmon", early_parse_xmon
);
2759 void __init
xmon_setup(void)
2761 #ifdef CONFIG_XMON_DEFAULT
2769 #ifdef CONFIG_SPU_BASE
2773 u64 saved_mfc_sr1_RW
;
2774 u32 saved_spu_runcntl_RW
;
2775 unsigned long dump_addr
;
2779 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2781 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2783 void xmon_register_spus(struct list_head
*list
)
2787 list_for_each_entry(spu
, list
, full_list
) {
2788 if (spu
->number
>= XMON_NUM_SPUS
) {
2793 spu_info
[spu
->number
].spu
= spu
;
2794 spu_info
[spu
->number
].stopped_ok
= 0;
2795 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2796 spu_info
[spu
->number
].spu
->local_store
;
2800 static void stop_spus(void)
2806 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2807 if (!spu_info
[i
].spu
)
2810 if (setjmp(bus_error_jmp
) == 0) {
2811 catch_memory_errors
= 1;
2814 spu
= spu_info
[i
].spu
;
2816 spu_info
[i
].saved_spu_runcntl_RW
=
2817 in_be32(&spu
->problem
->spu_runcntl_RW
);
2819 tmp
= spu_mfc_sr1_get(spu
);
2820 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2822 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2823 spu_mfc_sr1_set(spu
, tmp
);
2828 spu_info
[i
].stopped_ok
= 1;
2830 printf("Stopped spu %.2d (was %s)\n", i
,
2831 spu_info
[i
].saved_spu_runcntl_RW
?
2832 "running" : "stopped");
2834 catch_memory_errors
= 0;
2835 printf("*** Error stopping spu %.2d\n", i
);
2837 catch_memory_errors
= 0;
2841 static void restart_spus(void)
2846 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2847 if (!spu_info
[i
].spu
)
2850 if (!spu_info
[i
].stopped_ok
) {
2851 printf("*** Error, spu %d was not successfully stopped"
2852 ", not restarting\n", i
);
2856 if (setjmp(bus_error_jmp
) == 0) {
2857 catch_memory_errors
= 1;
2860 spu
= spu_info
[i
].spu
;
2861 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
2862 out_be32(&spu
->problem
->spu_runcntl_RW
,
2863 spu_info
[i
].saved_spu_runcntl_RW
);
2868 printf("Restarted spu %.2d\n", i
);
2870 catch_memory_errors
= 0;
2871 printf("*** Error restarting spu %.2d\n", i
);
2873 catch_memory_errors
= 0;
2877 #define DUMP_WIDTH 23
2878 #define DUMP_VALUE(format, field, value) \
2880 if (setjmp(bus_error_jmp) == 0) { \
2881 catch_memory_errors = 1; \
2883 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2888 catch_memory_errors = 0; \
2889 printf(" %-*s = *** Error reading field.\n", \
2890 DUMP_WIDTH, #field); \
2892 catch_memory_errors = 0; \
2895 #define DUMP_FIELD(obj, format, field) \
2896 DUMP_VALUE(format, field, obj->field)
2898 static void dump_spu_fields(struct spu
*spu
)
2900 printf("Dumping spu fields at address %p:\n", spu
);
2902 DUMP_FIELD(spu
, "0x%x", number
);
2903 DUMP_FIELD(spu
, "%s", name
);
2904 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
2905 DUMP_FIELD(spu
, "0x%p", local_store
);
2906 DUMP_FIELD(spu
, "0x%lx", ls_size
);
2907 DUMP_FIELD(spu
, "0x%x", node
);
2908 DUMP_FIELD(spu
, "0x%lx", flags
);
2909 DUMP_FIELD(spu
, "%d", class_0_pending
);
2910 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
2911 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
2912 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
2913 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
2914 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
2915 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
2916 DUMP_FIELD(spu
, "0x%x", slb_replace
);
2917 DUMP_FIELD(spu
, "%d", pid
);
2918 DUMP_FIELD(spu
, "0x%p", mm
);
2919 DUMP_FIELD(spu
, "0x%p", ctx
);
2920 DUMP_FIELD(spu
, "0x%p", rq
);
2921 DUMP_FIELD(spu
, "0x%p", timestamp
);
2922 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
2923 DUMP_FIELD(spu
, "0x%p", problem
);
2924 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
2925 in_be32(&spu
->problem
->spu_runcntl_RW
));
2926 DUMP_VALUE("0x%x", problem
->spu_status_R
,
2927 in_be32(&spu
->problem
->spu_status_R
));
2928 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
2929 in_be32(&spu
->problem
->spu_npc_RW
));
2930 DUMP_FIELD(spu
, "0x%p", priv2
);
2931 DUMP_FIELD(spu
, "0x%p", pdata
);
2935 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
2937 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
2940 static void dump_spu_ls(unsigned long num
, int subcmd
)
2942 unsigned long offset
, addr
, ls_addr
;
2944 if (setjmp(bus_error_jmp
) == 0) {
2945 catch_memory_errors
= 1;
2947 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
2951 catch_memory_errors
= 0;
2952 printf("*** Error: accessing spu info for spu %d\n", num
);
2955 catch_memory_errors
= 0;
2957 if (scanhex(&offset
))
2958 addr
= ls_addr
+ offset
;
2960 addr
= spu_info
[num
].dump_addr
;
2962 if (addr
>= ls_addr
+ LS_SIZE
) {
2963 printf("*** Error: address outside of local store\n");
2969 addr
+= spu_inst_dump(addr
, 16, 1);
2979 spu_info
[num
].dump_addr
= addr
;
2982 static int do_spu_cmd(void)
2984 static unsigned long num
= 0;
2985 int cmd
, subcmd
= 0;
2997 if (isxdigit(subcmd
) || subcmd
== '\n')
3001 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3002 printf("*** Error: invalid spu number\n");
3008 dump_spu_fields(spu_info
[num
].spu
);
3011 dump_spu_ls(num
, subcmd
);
3022 #else /* ! CONFIG_SPU_BASE */
3023 static int do_spu_cmd(void)